// <scoped_allocator> -*- C++ -*-

// Copyright (C) 2011-2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file include/scoped_allocator
 *  This is a Standard C++ Library header.
 */

#ifndef _SCOPED_ALLOCATOR
#define _SCOPED_ALLOCATOR 1

#pragma GCC system_header

#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else

#include <utility>
#include <tuple>
#include <bits/alloc_traits.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   * @addtogroup allocators
   * @{
   */

  template<typename _Alloc>
    inline auto
    __do_outermost(_Alloc& __a, int) -> decltype(__a.outer_allocator())
    { return __a.outer_allocator(); }

  template<typename _Alloc>
    inline _Alloc&
    __do_outermost(_Alloc& __a, ...)
    { return __a; }

  // TODO: make recursive (see note in 20.12.4/1)
  template<typename _Alloc>
    inline auto
    __outermost(_Alloc& __a)
    -> decltype(__do_outermost(__a, 0))
    { return __do_outermost(__a, 0); }

  template<typename _OuterAlloc, typename... _InnerAllocs>
    class scoped_allocator_adaptor;

  template<typename...> 
    struct __inner_type_impl;

  template<typename _Outer>
    struct __inner_type_impl<_Outer>
    {
      typedef scoped_allocator_adaptor<_Outer> __type;

      __inner_type_impl() = default;
      __inner_type_impl(const __inner_type_impl&) = default;
      __inner_type_impl(__inner_type_impl&&) = default;
      __inner_type_impl& operator=(const __inner_type_impl&) = default;
      __inner_type_impl& operator=(__inner_type_impl&&) = default;
      
      template<typename _Alloc>
      __inner_type_impl(const __inner_type_impl<_Alloc>& __other)
      { }
      
      template<typename _Alloc>
      __inner_type_impl(__inner_type_impl<_Alloc>&& __other)
      { }
      
      __type& 
      _M_get(__type* __p) noexcept { return *__p; }

      const __type& 
      _M_get(const __type* __p) const noexcept { return *__p; }
      
      tuple<> 
      _M_tie() const noexcept { return tuple<>(); }
      
      bool 
      operator==(const __inner_type_impl&) const noexcept
      { return true; }
    };

  template<typename _Outer, typename _InnerHead, typename... _InnerTail>
    struct __inner_type_impl<_Outer, _InnerHead, _InnerTail...>
    {
      typedef scoped_allocator_adaptor<_InnerHead, _InnerTail...> __type;
      
      __inner_type_impl() = default;
      __inner_type_impl(const __inner_type_impl&) = default;
      __inner_type_impl(__inner_type_impl&&) = default;
      __inner_type_impl& operator=(const __inner_type_impl&) = default;
      __inner_type_impl& operator=(__inner_type_impl&&) = default;
      
      template<typename... _Allocs>
      __inner_type_impl(const __inner_type_impl<_Allocs...>& __other)
      : _M_inner(__other._M_inner) { }
      
      template<typename... _Allocs>
      __inner_type_impl(__inner_type_impl<_Allocs...>&& __other)
      : _M_inner(std::move(__other._M_inner)) { }

    template<typename... _Args>
      explicit
      __inner_type_impl(_Args&&... __args)
      : _M_inner(std::forward<_Args>(__args)...) { }

      __type& 
      _M_get(void*) noexcept { return _M_inner; }
      
      const __type& 
      _M_get(const void*) const noexcept { return _M_inner; }
      
      tuple<const _InnerHead&, const _InnerTail&...> 
      _M_tie() const noexcept
      { return _M_inner._M_tie(); }
      
      bool 
      operator==(const __inner_type_impl& __other) const noexcept
      { return _M_inner == __other._M_inner; }
      
    private:
      template<typename...> friend class __inner_type_impl;
      template<typename, typename...> friend class scoped_allocator_adaptor;
      
      __type _M_inner;
    };

  /// Primary class template.
  template<typename _OuterAlloc, typename... _InnerAllocs>
    class scoped_allocator_adaptor
    : public _OuterAlloc
    {
      typedef allocator_traits<_OuterAlloc> __traits;

      typedef __inner_type_impl<_OuterAlloc, _InnerAllocs...> __inner_type;
      __inner_type _M_inner;

      template<typename _Outer, typename... _Inner>
        friend class scoped_allocator_adaptor;

      template<typename...>
        friend class __inner_type_impl;

      tuple<const _OuterAlloc&, const _InnerAllocs&...>
      _M_tie() const noexcept
      { return std::tuple_cat(std::tie(outer_allocator()), _M_inner._M_tie()); }

      template<typename _Alloc>
	using __outermost_type = typename
	  std::decay<decltype(__outermost(std::declval<_Alloc&>()))>::type;

      template<typename _Alloc>
	using __outermost_alloc_traits
	  = allocator_traits<__outermost_type<_Alloc>>;
      
      template<typename _Tp, typename... _Args>
        void 
        _M_construct(__uses_alloc0, _Tp* __p, _Args&&... __args)
        {
	  typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits;
	  _O_traits::construct(__outermost(*this), __p,
			       std::forward<_Args>(__args)...);
        }

      typedef __uses_alloc1<typename __inner_type::__type> __uses_alloc1_;
      typedef __uses_alloc2<typename __inner_type::__type> __uses_alloc2_;

      template<typename _Tp, typename... _Args>
        void 
        _M_construct(__uses_alloc1_, _Tp* __p, _Args&&... __args)
        {
	  typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits;
	  _O_traits::construct(__outermost(*this), __p,
			       allocator_arg, inner_allocator(),
			       std::forward<_Args>(__args)...);
        }

      template<typename _Tp, typename... _Args>
        void 
        _M_construct(__uses_alloc2_, _Tp* __p, _Args&&... __args)
        {
	  typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits;
	  _O_traits::construct(__outermost(*this), __p,
			       std::forward<_Args>(__args)...,
			       inner_allocator());
        }

      template<typename _Alloc>
        static _Alloc
        _S_select_on_copy(const _Alloc& __a)
        {
          typedef allocator_traits<_Alloc> __a_traits;
          return __a_traits::select_on_container_copy_construction(__a);
        }

      template<std::size_t... _Indices>
        scoped_allocator_adaptor(tuple<const _OuterAlloc&,
                                       const _InnerAllocs&...> __refs,
                                 _Index_tuple<_Indices...>)
        : _OuterAlloc(_S_select_on_copy(std::get<0>(__refs))),
          _M_inner(_S_select_on_copy(std::get<_Indices+1>(__refs))...)
        { }

    public:
      typedef _OuterAlloc                       outer_allocator_type;
      typedef typename __inner_type::__type     inner_allocator_type;

      typedef typename __traits::value_type             value_type;
      typedef typename __traits::size_type              size_type;
      typedef typename __traits::difference_type        difference_type;
      typedef typename __traits::pointer                pointer;
      typedef typename __traits::const_pointer          const_pointer;
      typedef typename __traits::void_pointer           void_pointer;
      typedef typename __traits::const_void_pointer     const_void_pointer;

      typedef typename __or_<
	typename __traits::propagate_on_container_copy_assignment,
	typename allocator_traits<_InnerAllocs>::
	  propagate_on_container_copy_assignment...>::type
	  propagate_on_container_copy_assignment;

      typedef typename __or_<
	typename __traits::propagate_on_container_move_assignment,
	typename allocator_traits<_InnerAllocs>::
	  propagate_on_container_move_assignment...>::type
	  propagate_on_container_move_assignment;

      typedef typename __or_<
	typename __traits::propagate_on_container_swap,
	typename allocator_traits<_InnerAllocs>::
	  propagate_on_container_swap...>::type
	  propagate_on_container_swap;

      typedef typename __and_<
	typename __traits::is_always_equal,
	typename allocator_traits<_InnerAllocs>::is_always_equal...>::type
	  is_always_equal;

      template <class _Tp>
        struct rebind
        {
          typedef scoped_allocator_adaptor<
            typename __traits::template rebind_alloc<_Tp>,
            _InnerAllocs...> other;
        };

      scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { }

      template<typename _Outer2>
        scoped_allocator_adaptor(_Outer2&& __outer,
                                 const _InnerAllocs&... __inner)
        : _OuterAlloc(std::forward<_Outer2>(__outer)),
          _M_inner(__inner...)
        { }

      scoped_allocator_adaptor(const scoped_allocator_adaptor& __other)
      : _OuterAlloc(__other.outer_allocator()),
	_M_inner(__other._M_inner)
      { }

      scoped_allocator_adaptor(scoped_allocator_adaptor&& __other)
      : _OuterAlloc(std::move(__other.outer_allocator())),
	_M_inner(std::move(__other._M_inner))
      { }

      template<typename _Outer2>
        scoped_allocator_adaptor(
            const scoped_allocator_adaptor<_Outer2, _InnerAllocs...>& __other)
        : _OuterAlloc(__other.outer_allocator()),
          _M_inner(__other._M_inner)
        { }

      template<typename _Outer2>
        scoped_allocator_adaptor(
            scoped_allocator_adaptor<_Outer2, _InnerAllocs...>&& __other)
        : _OuterAlloc(std::move(__other.outer_allocator())),
          _M_inner(std::move(__other._M_inner))
        { }

      scoped_allocator_adaptor&
      operator=(const scoped_allocator_adaptor&) = default;

      scoped_allocator_adaptor&
      operator=(scoped_allocator_adaptor&&) = default;

      inner_allocator_type& inner_allocator() noexcept
      { return _M_inner._M_get(this); }

      const inner_allocator_type& inner_allocator() const noexcept
      { return _M_inner._M_get(this); }

      outer_allocator_type& outer_allocator() noexcept
      { return static_cast<_OuterAlloc&>(*this); }

      const outer_allocator_type& outer_allocator() const noexcept
      { return static_cast<const _OuterAlloc&>(*this); }

      pointer allocate(size_type __n)
      { return __traits::allocate(outer_allocator(), __n); }

      pointer allocate(size_type __n, const_void_pointer __hint)
      { return __traits::allocate(outer_allocator(), __n, __hint); }

      void deallocate(pointer __p, size_type __n)
      { return __traits::deallocate(outer_allocator(), __p, __n); }

      size_type max_size() const
      { return __traits::max_size(outer_allocator()); }

      template<typename _Tp, typename... _Args>
        void construct(_Tp* __p, _Args&&... __args)
        {
          auto& __inner = inner_allocator();
          auto __use_tag
            = __use_alloc<_Tp, inner_allocator_type, _Args...>(__inner);
          _M_construct(__use_tag, __p, std::forward<_Args>(__args)...);
        }

      template<typename _T1, typename _T2, typename... _Args1,
	       typename... _Args2>
	void
	construct(pair<_T1, _T2>* __p, piecewise_construct_t,
		  tuple<_Args1...> __x, tuple<_Args2...> __y)
	{
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 2203.  wrong argument types for piecewise construction
	  auto& __inner = inner_allocator();
	  auto __x_use_tag
	    = __use_alloc<_T1, inner_allocator_type, _Args1...>(__inner);
	  auto __y_use_tag
	    = __use_alloc<_T2, inner_allocator_type, _Args2...>(__inner);
	  typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits;
	  _O_traits::construct(__outermost(*this), __p, piecewise_construct,
			       _M_construct_p(__x_use_tag, __x),
			       _M_construct_p(__y_use_tag, __y));
	}

      template<typename _T1, typename _T2>
	void
	construct(pair<_T1, _T2>* __p)
	{ construct(__p, piecewise_construct, tuple<>(), tuple<>()); }

      template<typename _T1, typename _T2, typename _Up, typename _Vp>
	void
	construct(pair<_T1, _T2>* __p, _Up&& __u, _Vp&& __v)
	{
	  construct(__p, piecewise_construct,
		    std::forward_as_tuple(std::forward<_Up>(__u)),
		    std::forward_as_tuple(std::forward<_Vp>(__v)));
	}

      template<typename _T1, typename _T2, typename _Up, typename _Vp>
	void
	construct(pair<_T1, _T2>* __p, const pair<_Up, _Vp>& __x)
	{
	  construct(__p, piecewise_construct,
		    std::forward_as_tuple(__x.first),
		    std::forward_as_tuple(__x.second));
	}

      template<typename _T1, typename _T2, typename _Up, typename _Vp>
	void
	construct(pair<_T1, _T2>* __p, pair<_Up, _Vp>&& __x)
	{
	  construct(__p, piecewise_construct,
		    std::forward_as_tuple(std::forward<_Up>(__x.first)),
		    std::forward_as_tuple(std::forward<_Vp>(__x.second)));
	}

      template<typename _Tp>
        void destroy(_Tp* __p)
        {
	  typedef __outermost_alloc_traits<scoped_allocator_adaptor> _O_traits;
	  _O_traits::destroy(__outermost(*this), __p);
	}

      scoped_allocator_adaptor
      select_on_container_copy_construction() const
      {
        typedef typename _Build_index_tuple<sizeof...(_InnerAllocs)>::__type
	    _Indices;
        return scoped_allocator_adaptor(_M_tie(), _Indices());
      }

      template <typename _OutA1, typename _OutA2, typename... _InA>
      friend bool
      operator==(const scoped_allocator_adaptor<_OutA1, _InA...>& __a,
                 const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept;

    private:
      template<typename _Tuple>
	_Tuple&&
	_M_construct_p(__uses_alloc0, _Tuple& __t)
	{ return std::move(__t); }

      template<typename... _Args>
	std::tuple<allocator_arg_t, inner_allocator_type&, _Args...>
	_M_construct_p(__uses_alloc1_, std::tuple<_Args...>& __t)
	{
	  typedef std::tuple<allocator_arg_t, inner_allocator_type&> _Tuple;
	  return std::tuple_cat(_Tuple(allocator_arg, inner_allocator()),
				std::move(__t));
	}

      template<typename... _Args>
	std::tuple<_Args..., inner_allocator_type&>
	_M_construct_p(__uses_alloc2_, std::tuple<_Args...>& __t)
	{
	  typedef std::tuple<inner_allocator_type&> _Tuple;
	  return std::tuple_cat(std::move(__t), _Tuple(inner_allocator()));
	}
    };

  template <typename _OutA1, typename _OutA2, typename... _InA>
    inline bool
    operator==(const scoped_allocator_adaptor<_OutA1, _InA...>& __a,
               const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept
    {
      return __a.outer_allocator() == __b.outer_allocator()
          && __a._M_inner == __b._M_inner;
    }

  template <typename _OutA1, typename _OutA2, typename... _InA>
    inline bool
    operator!=(const scoped_allocator_adaptor<_OutA1, _InA...>& __a,
               const scoped_allocator_adaptor<_OutA2, _InA...>& __b) noexcept
    { return !(__a == __b); }

  /// @}

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // C++11

#endif // _SCOPED_ALLOCATOR
