Created
April 4, 2017 02:30
-
-
Save EricWF/554eea08b62148ff56ae84e7d32e1fbb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// -*- C++ -*- | |
//===-------------------------- memory ------------------------------------===// | |
// | |
// The LLVM Compiler Infrastructure | |
// | |
// This file is dual licensed under the MIT and the University of Illinois Open | |
// Source Licenses. See LICENSE.TXT for details. | |
// | |
//===----------------------------------------------------------------------===// | |
#ifndef _LIBCPP_COMPRESSED_PAIR | |
#define _LIBCPP_COMPRESSED_PAIR | |
#include <__config> | |
#include <type_traits> | |
#include <typeinfo> | |
#include <cstddef> | |
#include <cstdint> | |
#include <new> | |
#include <utility> | |
#include <limits> | |
#include <iterator> | |
#include <__functional_base> | |
#include <iosfwd> | |
#include <tuple> | |
#include <stdexcept> | |
#include <cstring> | |
_LIBCPP_BEGIN_NAMESPACE_STD | |
template <class _T1, class _T2, bool = is_same<typename remove_cv<_T1>::type, | |
typename remove_cv<_T2>::type>::value, | |
bool = is_empty<_T1>::value | |
&& !__libcpp_is_final<_T1>::value, | |
bool = is_empty<_T2>::value | |
&& !__libcpp_is_final<_T2>::value | |
> | |
struct __libcpp_compressed_pair_switch; | |
template <class _T1, class _T2, bool IsSame> | |
struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, false> {enum {value = 0};}; | |
template <class _T1, class _T2, bool IsSame> | |
struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, true, false> {enum {value = 1};}; | |
template <class _T1, class _T2, bool IsSame> | |
struct __libcpp_compressed_pair_switch<_T1, _T2, IsSame, false, true> {enum {value = 2};}; | |
template <class _T1, class _T2> | |
struct __libcpp_compressed_pair_switch<_T1, _T2, false, true, true> {enum {value = 3};}; | |
template <class _T1, class _T2> | |
struct __libcpp_compressed_pair_switch<_T1, _T2, true, true, true> {enum {value = 1};}; | |
template <class _T1, class _T2, unsigned = __libcpp_compressed_pair_switch<_T1, _T2>::value> | |
class __libcpp_compressed_pair_imp; | |
template <class _T1, class _T2> | |
class __libcpp_compressed_pair_imp<_T1, _T2, 0> | |
{ | |
private: | |
_T1 __first_; | |
_T2 __second_; | |
public: | |
typedef _T1 _T1_param; | |
typedef _T2 _T2_param; | |
typedef typename remove_reference<_T1>::type& _T1_reference; | |
typedef typename remove_reference<_T2>::type& _T2_reference; | |
typedef const typename remove_reference<_T1>::type& _T1_const_reference; | |
typedef const typename remove_reference<_T2>::type& _T2_const_reference; | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_(), __second_() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1) | |
: __first_(_VSTD::forward<_T1_param>(__t1)), __second_() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2) | |
: __first_(), __second_(_VSTD::forward<_T2_param>(__t2)) {} | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) | |
: __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> | |
_LIBCPP_INLINE_VISIBILITY | |
__libcpp_compressed_pair_imp(piecewise_construct_t, | |
tuple<_Args1...> __first_args, | |
tuple<_Args2...> __second_args, | |
__tuple_indices<_I1...>, | |
__tuple_indices<_I2...>) | |
: __first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...), | |
__second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...) | |
{} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
_LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT {return __first_;} | |
_LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;} | |
_LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT {return __second_;} | |
_LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;} | |
_LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x) | |
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && | |
__is_nothrow_swappable<_T2>::value) | |
{ | |
using _VSTD::swap; | |
swap(__first_, __x.__first_); | |
swap(__second_, __x.__second_); | |
} | |
}; | |
template <class _T1, class _T2> | |
class __libcpp_compressed_pair_imp<_T1, _T2, 1> | |
: private _T1 | |
{ | |
private: | |
_T2 __second_; | |
public: | |
typedef _T1 _T1_param; | |
typedef _T2 _T2_param; | |
typedef _T1& _T1_reference; | |
typedef typename remove_reference<_T2>::type& _T2_reference; | |
typedef const _T1& _T1_const_reference; | |
typedef const typename remove_reference<_T2>::type& _T2_const_reference; | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __second_() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1) | |
: _T1(_VSTD::forward<_T1_param>(__t1)), __second_() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2) | |
: __second_(_VSTD::forward<_T2_param>(__t2)) {} | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) | |
: _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> | |
_LIBCPP_INLINE_VISIBILITY | |
__libcpp_compressed_pair_imp(piecewise_construct_t, | |
tuple<_Args1...> __first_args, | |
tuple<_Args2...> __second_args, | |
__tuple_indices<_I1...>, | |
__tuple_indices<_I2...>) | |
: _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...), | |
__second_(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...) | |
{} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
_LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT {return __second_;} | |
_LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return __second_;} | |
_LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x) | |
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && | |
__is_nothrow_swappable<_T2>::value) | |
{ | |
using _VSTD::swap; | |
swap(__second_, __x.__second_); | |
} | |
}; | |
template <class _T1, class _T2> | |
class __libcpp_compressed_pair_imp<_T1, _T2, 2> | |
: private _T2 | |
{ | |
private: | |
_T1 __first_; | |
public: | |
typedef _T1 _T1_param; | |
typedef _T2 _T2_param; | |
typedef typename remove_reference<_T1>::type& _T1_reference; | |
typedef _T2& _T2_reference; | |
typedef const typename remove_reference<_T1>::type& _T1_const_reference; | |
typedef const _T2& _T2_const_reference; | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() : __first_() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1) | |
: __first_(_VSTD::forward<_T1_param>(__t1)) {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2) | |
: _T2(_VSTD::forward<_T2_param>(__t2)), __first_() {} | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) | |
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value && | |
is_nothrow_move_constructible<_T2>::value) | |
: _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> | |
_LIBCPP_INLINE_VISIBILITY | |
__libcpp_compressed_pair_imp(piecewise_construct_t, | |
tuple<_Args1...> __first_args, | |
tuple<_Args2...> __second_args, | |
__tuple_indices<_I1...>, | |
__tuple_indices<_I2...>) | |
: _T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...), | |
__first_(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...) | |
{} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
_LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT {return __first_;} | |
_LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return __first_;} | |
_LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp& __x) | |
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && | |
__is_nothrow_swappable<_T2>::value) | |
{ | |
using _VSTD::swap; | |
swap(__first_, __x.__first_); | |
} | |
}; | |
template <class _T1, class _T2> | |
class __libcpp_compressed_pair_imp<_T1, _T2, 3> | |
: private _T1, | |
private _T2 | |
{ | |
public: | |
typedef _T1 _T1_param; | |
typedef _T2 _T2_param; | |
typedef _T1& _T1_reference; | |
typedef _T2& _T2_reference; | |
typedef const _T1& _T1_const_reference; | |
typedef const _T2& _T2_const_reference; | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T1_param __t1) | |
: _T1(_VSTD::forward<_T1_param>(__t1)) {} | |
_LIBCPP_INLINE_VISIBILITY explicit __libcpp_compressed_pair_imp(_T2_param __t2) | |
: _T2(_VSTD::forward<_T2_param>(__t2)) {} | |
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2) | |
: _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class... _Args1, class... _Args2, size_t... _I1, size_t... _I2> | |
_LIBCPP_INLINE_VISIBILITY | |
__libcpp_compressed_pair_imp(piecewise_construct_t, | |
tuple<_Args1...> __first_args, | |
tuple<_Args2...> __second_args, | |
__tuple_indices<_I1...>, | |
__tuple_indices<_I2...>) | |
: _T1(_VSTD::forward<_Args1>(_VSTD::get<_I1>(__first_args))...), | |
_T2(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...) | |
{} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
_LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return *this;} | |
_LIBCPP_INLINE_VISIBILITY void swap(__libcpp_compressed_pair_imp&) | |
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && | |
__is_nothrow_swappable<_T2>::value) | |
{ | |
} | |
}; | |
template <class _T1, class _T2> | |
class __compressed_pair | |
: private __libcpp_compressed_pair_imp<_T1, _T2> | |
{ | |
typedef __libcpp_compressed_pair_imp<_T1, _T2> base; | |
public: | |
typedef typename base::_T1_param _T1_param; | |
typedef typename base::_T2_param _T2_param; | |
typedef typename base::_T1_reference _T1_reference; | |
typedef typename base::_T2_reference _T2_reference; | |
typedef typename base::_T1_const_reference _T1_const_reference; | |
typedef typename base::_T2_const_reference _T2_const_reference; | |
_LIBCPP_INLINE_VISIBILITY __compressed_pair() {} | |
_LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T1_param __t1) | |
: base(_VSTD::forward<_T1_param>(__t1)) {} | |
_LIBCPP_INLINE_VISIBILITY explicit __compressed_pair(_T2_param __t2) | |
: base(_VSTD::forward<_T2_param>(__t2)) {} | |
_LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2) | |
: base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {} | |
#ifndef _LIBCPP_HAS_NO_VARIADICS | |
template <class... _Args1, class... _Args2> | |
_LIBCPP_INLINE_VISIBILITY | |
__compressed_pair(piecewise_construct_t __pc, tuple<_Args1...> __first_args, | |
tuple<_Args2...> __second_args) | |
: base(__pc, _VSTD::move(__first_args), _VSTD::move(__second_args), | |
typename __make_tuple_indices<sizeof...(_Args1)>::type(), | |
typename __make_tuple_indices<sizeof...(_Args2) >::type()) | |
{} | |
#endif // _LIBCPP_HAS_NO_VARIADICS | |
_LIBCPP_INLINE_VISIBILITY _T1_reference first() _NOEXCEPT {return base::first();} | |
_LIBCPP_INLINE_VISIBILITY _T1_const_reference first() const _NOEXCEPT {return base::first();} | |
_LIBCPP_INLINE_VISIBILITY _T2_reference second() _NOEXCEPT {return base::second();} | |
_LIBCPP_INLINE_VISIBILITY _T2_const_reference second() const _NOEXCEPT {return base::second();} | |
_LIBCPP_INLINE_VISIBILITY void swap(__compressed_pair& __x) | |
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && | |
__is_nothrow_swappable<_T2>::value) | |
{base::swap(__x);} | |
}; | |
template <class _T1, class _T2> | |
inline _LIBCPP_INLINE_VISIBILITY | |
void | |
swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y) | |
_NOEXCEPT_(__is_nothrow_swappable<_T1>::value && | |
__is_nothrow_swappable<_T2>::value) | |
{__x.swap(__y);} | |
_LIBCPP_END_NAMESPACE_STD | |
#endif // _LIBCPP_COMPRESSED_PAIR |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment