/src/abseil-cpp/absl/container/internal/compressed_tuple.h
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2018 The Abseil Authors. |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | // |
15 | | // Helper class to perform the Empty Base Optimization. |
16 | | // Ts can contain classes and non-classes, empty or not. For the ones that |
17 | | // are empty classes, we perform the optimization. If all types in Ts are empty |
18 | | // classes, then CompressedTuple<Ts...> is itself an empty class. |
19 | | // |
20 | | // To access the members, use member get<N>() function. |
21 | | // |
22 | | // Eg: |
23 | | // absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2, |
24 | | // t3); |
25 | | // assert(value.get<0>() == 7); |
26 | | // T1& t1 = value.get<1>(); |
27 | | // const T2& t2 = value.get<2>(); |
28 | | // ... |
29 | | // |
30 | | // https://en.cppreference.com/w/cpp/language/ebo |
31 | | |
32 | | #ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ |
33 | | #define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ |
34 | | |
35 | | #include <initializer_list> |
36 | | #include <tuple> |
37 | | #include <type_traits> |
38 | | #include <utility> |
39 | | |
40 | | #include "absl/utility/utility.h" |
41 | | |
42 | | #if defined(_MSC_VER) && !defined(__NVCC__) |
43 | | // We need to mark these classes with this declspec to ensure that |
44 | | // CompressedTuple happens. |
45 | | #define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases) |
46 | | #else |
47 | | #define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC |
48 | | #endif |
49 | | |
50 | | namespace absl { |
51 | | ABSL_NAMESPACE_BEGIN |
52 | | namespace container_internal { |
53 | | |
54 | | template <typename... Ts> |
55 | | class CompressedTuple; |
56 | | |
57 | | namespace internal_compressed_tuple { |
58 | | |
59 | | template <typename D, size_t I> |
60 | | struct Elem; |
61 | | template <typename... B, size_t I> |
62 | | struct Elem<CompressedTuple<B...>, I> |
63 | | : std::tuple_element<I, std::tuple<B...>> {}; |
64 | | template <typename D, size_t I> |
65 | | using ElemT = typename Elem<D, I>::type; |
66 | | |
67 | | // We can't use EBCO on other CompressedTuples because that would mean that we |
68 | | // derive from multiple Storage<> instantiations with the same I parameter, |
69 | | // and potentially from multiple identical Storage<> instantiations. So anytime |
70 | | // we use type inheritance rather than encapsulation, we mark |
71 | | // CompressedTupleImpl, to make this easy to detect. |
72 | | struct uses_inheritance {}; |
73 | | |
74 | | template <typename T> |
75 | 0 | constexpr bool ShouldUseBase() { |
76 | 0 | return std::is_class<T>::value && std::is_empty<T>::value && |
77 | 0 | !std::is_final<T>::value && |
78 | 0 | !std::is_base_of<uses_inheritance, T>::value; |
79 | 0 | } Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<std::__1::allocator<absl::str_format_internal::FormatArgImpl> >() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<unsigned long>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<absl::container_internal::CommonFields>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<absl::container_internal::StringHash>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<absl::container_internal::StringEq>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<void (*)(absl::string_view)>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<std::__1::allocator<absl::LogSink*> >() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldUseBase<absl::LogSink**>() |
80 | | |
81 | | // The storage class provides two specializations: |
82 | | // - For empty classes, it stores T as a base class. |
83 | | // - For everything else, it stores T as a member. |
84 | | template <typename T, size_t I, bool UseBase = ShouldUseBase<T>()> |
85 | | struct Storage { |
86 | | T value; |
87 | | constexpr Storage() = default; |
88 | | template <typename V> |
89 | | explicit constexpr Storage(absl::in_place_t, V&& v) |
90 | 3.24M | : value(absl::forward<V>(v)) {} absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::CommonFields, 0ul, false>::Storage<absl::container_internal::CommonFields>(absl::in_place_t, absl::container_internal::CommonFields&&) Line | Count | Source | 90 | 2 | : value(absl::forward<V>(v)) {} |
absl::container_internal::internal_compressed_tuple::Storage<unsigned long, 1ul, false>::Storage<unsigned int>(absl::in_place_t, unsigned int&&) Line | Count | Source | 90 | 3.24M | : value(absl::forward<V>(v)) {} |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<absl::LogSink**, 1ul, false>::Storage<decltype(nullptr)>(absl::in_place_t, decltype(nullptr)&&) |
91 | 6.48M | constexpr const T& get() const& { return value; } absl::container_internal::internal_compressed_tuple::Storage<unsigned long, 1ul, false>::get() const & Line | Count | Source | 91 | 6.48M | constexpr const T& get() const& { return value; } |
absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::CommonFields, 0ul, false>::get() const & Line | Count | Source | 91 | 380 | constexpr const T& get() const& { return value; } |
|
92 | 3.24M | T& get() & { return value; } absl::container_internal::internal_compressed_tuple::Storage<unsigned long, 1ul, false>::get() & Line | Count | Source | 92 | 3.24M | T& get() & { return value; } |
absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::CommonFields, 0ul, false>::get() & Line | Count | Source | 92 | 352 | T& get() & { return value; } |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<void (*)(absl::string_view), 0ul, false>::get() & Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<absl::LogSink**, 1ul, false>::get() & |
93 | | constexpr const T&& get() const&& { return absl::move(*this).value; } |
94 | | T&& get() && { return std::move(*this).value; } |
95 | | }; |
96 | | |
97 | | template <typename T, size_t I> |
98 | | struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage<T, I, true> : T { |
99 | | constexpr Storage() = default; |
100 | | |
101 | | template <typename V> |
102 | | explicit constexpr Storage(absl::in_place_t, V&& v) |
103 | 3.24M | : T(absl::forward<V>(v)) {} absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::StringHash, 1ul, true>::Storage<absl::container_internal::StringHash>(absl::in_place_t, absl::container_internal::StringHash&&) Line | Count | Source | 103 | 2 | : T(absl::forward<V>(v)) {} |
absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::StringEq, 2ul, true>::Storage<absl::container_internal::StringEq>(absl::in_place_t, absl::container_internal::StringEq&&) Line | Count | Source | 103 | 2 | : T(absl::forward<V>(v)) {} |
absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> >, 3ul, true>::Storage<std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >(absl::in_place_t, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> >&&) Line | Count | Source | 103 | 2 | : T(absl::forward<V>(v)) {} |
absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<absl::LogSink*>, 0ul, true>::Storage<std::__1::allocator<absl::LogSink*> >(absl::in_place_t, std::__1::allocator<absl::LogSink*>&&) Line | Count | Source | 103 | 3.24M | : T(absl::forward<V>(v)) {} |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<absl::LogSink*>, 0ul, true>::Storage<std::__1::allocator<absl::LogSink*>&>(absl::in_place_t, std::__1::allocator<absl::LogSink*>&) Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, 0ul, true>::Storage<std::__1::allocator<absl::str_format_internal::FormatArgImpl> const&>(absl::in_place_t, std::__1::allocator<absl::str_format_internal::FormatArgImpl> const&) |
104 | | |
105 | 20 | constexpr const T& get() const& { return *this; } |
106 | 118 | T& get() & { return *this; } Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, 0ul, true>::get() & absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> >, 3ul, true>::get() & Line | Count | Source | 106 | 56 | T& get() & { return *this; } |
absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::StringEq, 2ul, true>::get() & Line | Count | Source | 106 | 20 | T& get() & { return *this; } |
absl::container_internal::internal_compressed_tuple::Storage<absl::container_internal::StringHash, 1ul, true>::get() & Line | Count | Source | 106 | 42 | T& get() & { return *this; } |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Storage<std::__1::allocator<absl::LogSink*>, 0ul, true>::get() & |
107 | | constexpr const T&& get() const&& { return absl::move(*this); } |
108 | | T&& get() && { return std::move(*this); } |
109 | | }; |
110 | | |
111 | | template <typename D, typename I, bool ShouldAnyUseBase> |
112 | | struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl; |
113 | | |
114 | | template <typename... Ts, size_t... I, bool ShouldAnyUseBase> |
115 | | struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl< |
116 | | CompressedTuple<Ts...>, absl::index_sequence<I...>, ShouldAnyUseBase> |
117 | | // We use the dummy identity function through std::integral_constant to |
118 | | // convince MSVC of accepting and expanding I in that context. Without it |
119 | | // you would get: |
120 | | // error C3548: 'I': parameter pack cannot be used in this context |
121 | | : uses_inheritance, |
122 | | Storage<Ts, std::integral_constant<size_t, I>::value>... { |
123 | | constexpr CompressedTupleImpl() = default; |
124 | | template <typename... Vs> |
125 | | explicit constexpr CompressedTupleImpl(absl::in_place_t, Vs&&... args) |
126 | 3.24M | : Storage<Ts, I>(absl::in_place, absl::forward<Vs>(args))... {} absl::container_internal::internal_compressed_tuple::CompressedTupleImpl<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, absl::integer_sequence<unsigned long, 0ul, 1ul, 2ul, 3ul>, true>::CompressedTupleImpl<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >(absl::in_place_t, absl::container_internal::CommonFields&&, absl::container_internal::StringHash&&, absl::container_internal::StringEq&&, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> >&&) Line | Count | Source | 126 | 2 | : Storage<Ts, I>(absl::in_place, absl::forward<Vs>(args))... {} |
absl::container_internal::internal_compressed_tuple::CompressedTupleImpl<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>, absl::integer_sequence<unsigned long, 0ul, 1ul>, true>::CompressedTupleImpl<std::__1::allocator<absl::LogSink*>, unsigned int>(absl::in_place_t, std::__1::allocator<absl::LogSink*>&&, unsigned int&&) Line | Count | Source | 126 | 3.24M | : Storage<Ts, I>(absl::in_place, absl::forward<Vs>(args))... {} |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::CompressedTupleImpl<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, absl::LogSink**>, absl::integer_sequence<unsigned long, 0ul, 1ul>, true>::CompressedTupleImpl<std::__1::allocator<absl::LogSink*>&, decltype(nullptr)>(absl::in_place_t, std::__1::allocator<absl::LogSink*>&, decltype(nullptr)&&) Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::CompressedTupleImpl<absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>, absl::integer_sequence<unsigned long, 0ul, 1ul>, true>::CompressedTupleImpl<std::__1::allocator<absl::str_format_internal::FormatArgImpl> const&, unsigned int>(absl::in_place_t, std::__1::allocator<absl::str_format_internal::FormatArgImpl> const&, unsigned int&&) |
127 | | friend CompressedTuple<Ts...>; |
128 | | }; |
129 | | |
130 | | template <typename... Ts, size_t... I> |
131 | | struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl< |
132 | | CompressedTuple<Ts...>, absl::index_sequence<I...>, false> |
133 | | // We use the dummy identity function as above... |
134 | | : Storage<Ts, std::integral_constant<size_t, I>::value, false>... { |
135 | | constexpr CompressedTupleImpl() = default; |
136 | | template <typename... Vs> |
137 | | explicit constexpr CompressedTupleImpl(absl::in_place_t, Vs&&... args) |
138 | | : Storage<Ts, I, false>(absl::in_place, absl::forward<Vs>(args))... {} |
139 | | friend CompressedTuple<Ts...>; |
140 | | }; |
141 | | |
142 | | std::false_type Or(std::initializer_list<std::false_type>); |
143 | | std::true_type Or(std::initializer_list<bool>); |
144 | | |
145 | | // MSVC requires this to be done separately rather than within the declaration |
146 | | // of CompressedTuple below. |
147 | | template <typename... Ts> |
148 | 0 | constexpr bool ShouldAnyUseBase() { |
149 | 0 | return decltype( |
150 | 0 | Or({std::integral_constant<bool, ShouldUseBase<Ts>()>()...})){}; |
151 | 0 | } Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldAnyUseBase<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldAnyUseBase<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldAnyUseBase<void (*)(absl::string_view)>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldAnyUseBase<std::__1::allocator<absl::LogSink*>, unsigned long>() Unexecuted instantiation: bool absl::container_internal::internal_compressed_tuple::ShouldAnyUseBase<std::__1::allocator<absl::LogSink*>, absl::LogSink**>() |
152 | | |
153 | | template <typename T, typename V> |
154 | | using TupleElementMoveConstructible = |
155 | | typename std::conditional<std::is_reference<T>::value, |
156 | | std::is_convertible<V, T>, |
157 | | std::is_constructible<T, V&&>>::type; |
158 | | |
159 | | template <bool SizeMatches, class T, class... Vs> |
160 | | struct TupleMoveConstructible : std::false_type {}; |
161 | | |
162 | | template <class... Ts, class... Vs> |
163 | | struct TupleMoveConstructible<true, CompressedTuple<Ts...>, Vs...> |
164 | | : std::integral_constant< |
165 | | bool, absl::conjunction< |
166 | | TupleElementMoveConstructible<Ts, Vs&&>...>::value> {}; |
167 | | |
168 | | template <typename T> |
169 | | struct compressed_tuple_size; |
170 | | |
171 | | template <typename... Es> |
172 | | struct compressed_tuple_size<CompressedTuple<Es...>> |
173 | | : public std::integral_constant<std::size_t, sizeof...(Es)> {}; |
174 | | |
175 | | template <class T, class... Vs> |
176 | | struct TupleItemsMoveConstructible |
177 | | : std::integral_constant< |
178 | | bool, TupleMoveConstructible<compressed_tuple_size<T>::value == |
179 | | sizeof...(Vs), |
180 | | T, Vs...>::value> {}; |
181 | | |
182 | | } // namespace internal_compressed_tuple |
183 | | |
184 | | // Helper class to perform the Empty Base Class Optimization. |
185 | | // Ts can contain classes and non-classes, empty or not. For the ones that |
186 | | // are empty classes, we perform the CompressedTuple. If all types in Ts are |
187 | | // empty classes, then CompressedTuple<Ts...> is itself an empty class. (This |
188 | | // does not apply when one or more of those empty classes is itself an empty |
189 | | // CompressedTuple.) |
190 | | // |
191 | | // To access the members, use member .get<N>() function. |
192 | | // |
193 | | // Eg: |
194 | | // absl::container_internal::CompressedTuple<int, T1, T2, T3> value(7, t1, t2, |
195 | | // t3); |
196 | | // assert(value.get<0>() == 7); |
197 | | // T1& t1 = value.get<1>(); |
198 | | // const T2& t2 = value.get<2>(); |
199 | | // ... |
200 | | // |
201 | | // https://en.cppreference.com/w/cpp/language/ebo |
202 | | template <typename... Ts> |
203 | | class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple |
204 | | : private internal_compressed_tuple::CompressedTupleImpl< |
205 | | CompressedTuple<Ts...>, absl::index_sequence_for<Ts...>, |
206 | | internal_compressed_tuple::ShouldAnyUseBase<Ts...>()> { |
207 | | private: |
208 | | template <int I> |
209 | | using ElemT = internal_compressed_tuple::ElemT<CompressedTuple, I>; |
210 | | |
211 | | template <int I> |
212 | | using StorageT = internal_compressed_tuple::Storage<ElemT<I>, I>; |
213 | | |
214 | | public: |
215 | | // There seems to be a bug in MSVC dealing in which using '=default' here will |
216 | | // cause the compiler to ignore the body of other constructors. The work- |
217 | | // around is to explicitly implement the default constructor. |
218 | | #if defined(_MSC_VER) |
219 | | constexpr CompressedTuple() : CompressedTuple::CompressedTupleImpl() {} |
220 | | #else |
221 | | constexpr CompressedTuple() = default; |
222 | | #endif |
223 | | explicit constexpr CompressedTuple(const Ts&... base) |
224 | | : CompressedTuple::CompressedTupleImpl(absl::in_place, base...) {} |
225 | | |
226 | | template <typename First, typename... Vs, |
227 | | absl::enable_if_t< |
228 | | absl::conjunction< |
229 | | // Ensure we are not hiding default copy/move constructors. |
230 | | absl::negation<std::is_same<void(CompressedTuple), |
231 | | void(absl::decay_t<First>)>>, |
232 | | internal_compressed_tuple::TupleItemsMoveConstructible< |
233 | | CompressedTuple<Ts...>, First, Vs...>>::value, |
234 | | bool> = true> |
235 | | explicit constexpr CompressedTuple(First&& first, Vs&&... base) |
236 | | : CompressedTuple::CompressedTupleImpl(absl::in_place, |
237 | | absl::forward<First>(first), |
238 | 3.24M | absl::forward<Vs>(base)...) {} absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> >, true>(absl::container_internal::CommonFields&&, absl::container_internal::StringHash&&, absl::container_internal::StringEq&&, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> >&&) Line | Count | Source | 238 | 2 | absl::forward<Vs>(base)...) {} |
absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned int, true>(std::__1::allocator<absl::LogSink*>&&, unsigned int&&) Line | Count | Source | 238 | 3.24M | absl::forward<Vs>(base)...) {} |
Unexecuted instantiation: absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, absl::LogSink**>::CompressedTuple<std::__1::allocator<absl::LogSink*>&, decltype(nullptr), true>(std::__1::allocator<absl::LogSink*>&, decltype(nullptr)&&) Unexecuted instantiation: absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl> const&, unsigned int, true>(std::__1::allocator<absl::str_format_internal::FormatArgImpl> const&, unsigned int&&) |
239 | | |
240 | | template <int I> |
241 | 3.24M | ElemT<I>& get() & { |
242 | 3.24M | return StorageT<I>::get(); |
243 | 3.24M | } Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>, 1>::type& absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>::get<1>() & Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>, 0>::type& absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>::get<0>() & absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, 3>::type& absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::get<3>() & Line | Count | Source | 241 | 56 | ElemT<I>& get() & { | 242 | 56 | return StorageT<I>::get(); | 243 | 56 | } |
absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, 0>::type& absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::get<0>() & Line | Count | Source | 241 | 352 | ElemT<I>& get() & { | 242 | 352 | return StorageT<I>::get(); | 243 | 352 | } |
absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, 2>::type& absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::get<2>() & Line | Count | Source | 241 | 20 | ElemT<I>& get() & { | 242 | 20 | return StorageT<I>::get(); | 243 | 20 | } |
absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, 1>::type& absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::get<1>() & Line | Count | Source | 241 | 42 | ElemT<I>& get() & { | 242 | 42 | return StorageT<I>::get(); | 243 | 42 | } |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<void (*)(absl::string_view)>, 0>::type& absl::container_internal::CompressedTuple<void (*)(absl::string_view)>::get<0>() & absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>, 1>::type& absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>::get<1>() & Line | Count | Source | 241 | 3.24M | ElemT<I>& get() & { | 242 | 3.24M | return StorageT<I>::get(); | 243 | 3.24M | } |
Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>, 0>::type& absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>::get<0>() & Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, absl::LogSink**>, 0>::type& absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, absl::LogSink**>::get<0>() & Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, absl::LogSink**>, 1>::type& absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, absl::LogSink**>::get<1>() & |
244 | | |
245 | | template <int I> |
246 | 6.48M | constexpr const ElemT<I>& get() const& { |
247 | 6.48M | return StorageT<I>::get(); |
248 | 6.48M | } Unexecuted instantiation: absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>, 1>::type const& absl::container_internal::CompressedTuple<std::__1::allocator<absl::str_format_internal::FormatArgImpl>, unsigned long>::get<1>() const & absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, 0>::type const& absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::get<0>() const & Line | Count | Source | 246 | 380 | constexpr const ElemT<I>& get() const& { | 247 | 380 | return StorageT<I>::get(); | 248 | 380 | } |
absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >, 1>::type const& absl::container_internal::CompressedTuple<absl::container_internal::CommonFields, absl::container_internal::StringHash, absl::container_internal::StringEq, std::__1::allocator<std::__1::pair<absl::string_view const, absl::CommandLineFlag*> > >::get<1>() const & Line | Count | Source | 246 | 20 | constexpr const ElemT<I>& get() const& { | 247 | 20 | return StorageT<I>::get(); | 248 | 20 | } |
absl::container_internal::internal_compressed_tuple::Elem<absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>, 1>::type const& absl::container_internal::CompressedTuple<std::__1::allocator<absl::LogSink*>, unsigned long>::get<1>() const & Line | Count | Source | 246 | 6.48M | constexpr const ElemT<I>& get() const& { | 247 | 6.48M | return StorageT<I>::get(); | 248 | 6.48M | } |
|
249 | | |
250 | | template <int I> |
251 | | ElemT<I>&& get() && { |
252 | | return std::move(*this).StorageT<I>::get(); |
253 | | } |
254 | | |
255 | | template <int I> |
256 | | constexpr const ElemT<I>&& get() const&& { |
257 | | return absl::move(*this).StorageT<I>::get(); |
258 | | } |
259 | | }; |
260 | | |
261 | | // Explicit specialization for a zero-element tuple |
262 | | // (needed to avoid ambiguous overloads for the default constructor). |
263 | | template <> |
264 | | class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {}; |
265 | | |
266 | | } // namespace container_internal |
267 | | ABSL_NAMESPACE_END |
268 | | } // namespace absl |
269 | | |
270 | | #undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC |
271 | | |
272 | | #endif // ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ |