Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
00033 #define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_
00034
00035 #include <tuple>
00036 #include <type_traits>
00037 #include <utility>
00038
00039 #include "absl/utility/utility.h"
00040
00041 #if defined(_MSC_VER) && !defined(__NVCC__)
00042
00043
00044 #define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases)
00045 #else
00046 #define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
00047 #endif
00048
00049 namespace absl {
00050 namespace container_internal {
00051
00052 template <typename... Ts>
00053 class CompressedTuple;
00054
00055 namespace internal_compressed_tuple {
00056
00057 template <typename D, size_t I>
00058 struct Elem;
00059 template <typename... B, size_t I>
00060 struct Elem<CompressedTuple<B...>, I>
00061 : std::tuple_element<I, std::tuple<B...>> {};
00062 template <typename D, size_t I>
00063 using ElemT = typename Elem<D, I>::type;
00064
00065
00066
00067
00068
00069 template <typename T>
00070 constexpr bool IsFinal() {
00071 #if defined(__clang__) || defined(__GNUC__)
00072 return __is_final(T);
00073 #else
00074 return false;
00075 #endif
00076 }
00077
00078 template <typename T>
00079 constexpr bool ShouldUseBase() {
00080 return std::is_class<T>::value && std::is_empty<T>::value && !IsFinal<T>();
00081 }
00082
00083
00084
00085
00086 template <typename D, size_t I, bool = ShouldUseBase<ElemT<D, I>>()>
00087 struct Storage {
00088 using T = ElemT<D, I>;
00089 T value;
00090 constexpr Storage() = default;
00091 explicit constexpr Storage(T&& v) : value(absl::forward<T>(v)) {}
00092 constexpr const T& get() const& { return value; }
00093 T& get() & { return value; }
00094 constexpr const T&& get() const&& { return absl::move(*this).value; }
00095 T&& get() && { return std::move(*this).value; }
00096 };
00097
00098 template <typename D, size_t I>
00099 struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage<D, I, true>
00100 : ElemT<D, I> {
00101 using T = internal_compressed_tuple::ElemT<D, I>;
00102 constexpr Storage() = default;
00103 explicit constexpr Storage(T&& v) : T(absl::forward<T>(v)) {}
00104 constexpr const T& get() const& { return *this; }
00105 T& get() & { return *this; }
00106 constexpr const T&& get() const&& { return absl::move(*this); }
00107 T&& get() && { return std::move(*this); }
00108 };
00109
00110 template <typename D, typename I>
00111 struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl;
00112
00113 template <typename... Ts, size_t... I>
00114 struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
00115 CompressedTupleImpl<CompressedTuple<Ts...>, absl::index_sequence<I...>>
00116
00117
00118
00119
00120 : Storage<CompressedTuple<Ts...>,
00121 std::integral_constant<size_t, I>::value>... {
00122 constexpr CompressedTupleImpl() = default;
00123 explicit constexpr CompressedTupleImpl(Ts&&... args)
00124 : Storage<CompressedTuple<Ts...>, I>(absl::forward<Ts>(args))... {}
00125 };
00126
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 template <typename... Ts>
00146 class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple
00147 : private internal_compressed_tuple::CompressedTupleImpl<
00148 CompressedTuple<Ts...>, absl::index_sequence_for<Ts...>> {
00149 private:
00150 template <int I>
00151 using ElemT = internal_compressed_tuple::ElemT<CompressedTuple, I>;
00152
00153 public:
00154 constexpr CompressedTuple() = default;
00155 explicit constexpr CompressedTuple(Ts... base)
00156 : CompressedTuple::CompressedTupleImpl(absl::forward<Ts>(base)...) {}
00157
00158 template <int I>
00159 ElemT<I>& get() & {
00160 return internal_compressed_tuple::Storage<CompressedTuple, I>::get();
00161 }
00162
00163 template <int I>
00164 constexpr const ElemT<I>& get() const& {
00165 return internal_compressed_tuple::Storage<CompressedTuple, I>::get();
00166 }
00167
00168 template <int I>
00169 ElemT<I>&& get() && {
00170 return std::move(*this)
00171 .internal_compressed_tuple::template Storage<CompressedTuple, I>::get();
00172 }
00173
00174 template <int I>
00175 constexpr const ElemT<I>&& get() const&& {
00176 return absl::move(*this)
00177 .internal_compressed_tuple::template Storage<CompressedTuple, I>::get();
00178 }
00179 };
00180
00181
00182
00183 template <>
00184 class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {};
00185
00186 }
00187 }
00188
00189 #undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC
00190
00191 #endif // ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_