brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.5 KiB · 601736a Raw
140 lines · c
1// -*- C++ -*-2//===----------------------------------------------------------------------===//3//4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5// See https://llvm.org/LICENSE.txt for license information.6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7//8//===----------------------------------------------------------------------===//9 10#ifndef _LIBCPP___CXX03___MEMORY_COMPRESSED_PAIR_H11#define _LIBCPP___CXX03___MEMORY_COMPRESSED_PAIR_H12 13#include <__cxx03/__config>14#include <__cxx03/__fwd/tuple.h>15#include <__cxx03/__tuple/tuple_indices.h>16#include <__cxx03/__type_traits/decay.h>17#include <__cxx03/__type_traits/dependent_type.h>18#include <__cxx03/__type_traits/enable_if.h>19#include <__cxx03/__type_traits/is_constructible.h>20#include <__cxx03/__type_traits/is_empty.h>21#include <__cxx03/__type_traits/is_final.h>22#include <__cxx03/__type_traits/is_same.h>23#include <__cxx03/__type_traits/is_swappable.h>24#include <__cxx03/__utility/forward.h>25#include <__cxx03/__utility/move.h>26#include <__cxx03/__utility/piecewise_construct.h>27#include <__cxx03/cstddef>28 29#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)30#  pragma GCC system_header31#endif32 33_LIBCPP_PUSH_MACROS34#include <__cxx03/__undef_macros>35 36_LIBCPP_BEGIN_NAMESPACE_STD37 38// Tag used to default initialize one or both of the pair's elements.39struct __default_init_tag {};40struct __value_init_tag {};41 42template <class _Tp, int _Idx, bool _CanBeEmptyBase = is_empty<_Tp>::value && !__libcpp_is_final<_Tp>::value>43struct __compressed_pair_elem {44  using _ParamT         = _Tp;45  using reference       = _Tp&;46  using const_reference = const _Tp&;47 48  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem(__default_init_tag) {}49  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem(__value_init_tag) : __value_() {}50 51  template <class _Up, __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value, int> = 0>52  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem(_Up&& __u) : __value_(std::forward<_Up>(__u)) {}53 54  _LIBCPP_HIDE_FROM_ABI reference __get() _NOEXCEPT { return __value_; }55  _LIBCPP_HIDE_FROM_ABI const_reference __get() const _NOEXCEPT { return __value_; }56 57private:58  _Tp __value_;59};60 61template <class _Tp, int _Idx>62struct __compressed_pair_elem<_Tp, _Idx, true> : private _Tp {63  using _ParamT         = _Tp;64  using reference       = _Tp&;65  using const_reference = const _Tp&;66  using __value_type    = _Tp;67 68  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem() = default;69  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem(__default_init_tag) {}70  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem(__value_init_tag) : __value_type() {}71 72  template <class _Up, __enable_if_t<!is_same<__compressed_pair_elem, __decay_t<_Up> >::value, int> = 0>73  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair_elem(_Up&& __u) : __value_type(std::forward<_Up>(__u)) {}74 75  _LIBCPP_HIDE_FROM_ABI reference __get() _NOEXCEPT { return *this; }76  _LIBCPP_HIDE_FROM_ABI const_reference __get() const _NOEXCEPT { return *this; }77};78 79template <class _T1, class _T2>80class __compressed_pair : private __compressed_pair_elem<_T1, 0>, private __compressed_pair_elem<_T2, 1> {81public:82  // NOTE: This static assert should never fire because __compressed_pair83  // is *almost never* used in a scenario where it's possible for T1 == T2.84  // (The exception is std::function where it is possible that the function85  //  object and the allocator have the same type).86  static_assert(87      (!is_same<_T1, _T2>::value),88      "__compressed_pair cannot be instantiated when T1 and T2 are the same type; "89      "The current implementation is NOT ABI-compatible with the previous implementation for this configuration");90 91  using _Base1 _LIBCPP_NODEBUG = __compressed_pair_elem<_T1, 0>;92  using _Base2 _LIBCPP_NODEBUG = __compressed_pair_elem<_T2, 1>;93 94  template <bool _Dummy         = true,95            __enable_if_t< __dependent_type<is_default_constructible<_T1>, _Dummy>::value &&96                               __dependent_type<is_default_constructible<_T2>, _Dummy>::value,97                           int> = 0>98  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair() : _Base1(__value_init_tag()), _Base2(__value_init_tag()) {}99 100  template <class _U1, class _U2>101  _LIBCPP_HIDE_FROM_ABI explicit __compressed_pair(_U1&& __t1, _U2&& __t2)102      : _Base1(std::forward<_U1>(__t1)), _Base2(std::forward<_U2>(__t2)) {}103 104  _LIBCPP_HIDE_FROM_ABI typename _Base1::reference first() _NOEXCEPT { return static_cast<_Base1&>(*this).__get(); }105 106  _LIBCPP_HIDE_FROM_ABI typename _Base1::const_reference first() const _NOEXCEPT {107    return static_cast<_Base1 const&>(*this).__get();108  }109 110  _LIBCPP_HIDE_FROM_ABI typename _Base2::reference second() _NOEXCEPT { return static_cast<_Base2&>(*this).__get(); }111 112  _LIBCPP_HIDE_FROM_ABI typename _Base2::const_reference second() const _NOEXCEPT {113    return static_cast<_Base2 const&>(*this).__get();114  }115 116  _LIBCPP_HIDE_FROM_ABI static _Base1* __get_first_base(__compressed_pair* __pair) _NOEXCEPT {117    return static_cast<_Base1*>(__pair);118  }119  _LIBCPP_HIDE_FROM_ABI static _Base2* __get_second_base(__compressed_pair* __pair) _NOEXCEPT {120    return static_cast<_Base2*>(__pair);121  }122 123  _LIBCPP_HIDE_FROM_ABI void swap(__compressed_pair& __x) {124    using std::swap;125    swap(first(), __x.first());126    swap(second(), __x.second());127  }128};129 130template <class _T1, class _T2>131inline _LIBCPP_HIDE_FROM_ABI void swap(__compressed_pair<_T1, _T2>& __x, __compressed_pair<_T1, _T2>& __y) {132  __x.swap(__y);133}134 135_LIBCPP_END_NAMESPACE_STD136 137_LIBCPP_POP_MACROS138 139#endif // _LIBCPP___CXX03___MEMORY_COMPRESSED_PAIR_H140