Skip to content

Instantly share code, notes, and snippets.

@EricWF
Created April 4, 2017 02:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EricWF/554eea08b62148ff56ae84e7d32e1fbb to your computer and use it in GitHub Desktop.
Save EricWF/554eea08b62148ff56ae84e7d32e1fbb to your computer and use it in GitHub Desktop.
// -*- 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