32 #ifndef BIT_MEMORY_UTILITIES_DETAIL_EBO_STORAGE_HPP 33 #define BIT_MEMORY_UTILITIES_DETAIL_EBO_STORAGE_HPP 35 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 37 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 41 #include <type_traits> 61 template<
typename...Ts>
77 template<std::size_t Idx,
typename...Types>
78 std::tuple_element_t<Idx,std::tuple<Types...>>&
80 template<std::size_t Idx,
typename...Types>
81 std::tuple_element_t<Idx,
const std::tuple<Types...>>&
91 template<
typename T,
typename...Ts>
94 template<
typename T,
typename...Ts>
95 struct is_duplicate<T,T,Ts...> : std::true_type{};
97 template<
typename T,
typename T0,
typename...Ts>
98 struct is_duplicate<T,T0,Ts...> : is_duplicate<T,Ts...>{};
101 struct is_duplicate<T> : std::false_type{};
103 template<
typename T0,
typename...Ts>
105 : std::integral_constant<bool,std::is_class<T0>::value &&
106 std::is_empty<T0>::value &&
107 !std::is_final<T0>::value &&
108 !is_duplicate<T0,Ts...>::value>{};
114 template<std::size_t Idx,
typename T0,
bool CanEbo,
typename...Ts>
115 class ebo_storage_impl;
119 template<std::size_t Idx,
typename T0,
typename T1,
typename...Ts>
120 class ebo_storage_impl<Idx,T0,true,T1,Ts...>
122 public ebo_storage_impl<Idx+1,T1,can_ebo<T1,Ts...>::value, Ts...>
124 using base_type = detail::ebo_storage_impl<Idx+1,T1,can_ebo<T1,Ts...>::value, Ts...>;
131 ebo_storage_impl() =
default;
132 template<
typename Tuple,
typename...Tuples,
typename = std::enable_if_t<!std::is_same<std::decay_t<Tuple>,ebo_storage_impl>::value>>
133 ebo_storage_impl( Tuple&& tuple, Tuples&&...tuples );
134 ebo_storage_impl(
const ebo_storage_impl& other ) =
default;
135 ebo_storage_impl( ebo_storage_impl&& other ) =
default;
139 ebo_storage_impl& operator=(
const ebo_storage_impl& other ) =
default;
140 ebo_storage_impl& operator=( ebo_storage_impl&& other ) =
default;
147 using base_type::get;
149 T0&
get( std::integral_constant<std::size_t,Idx> ) &;
150 const T0&
get( std::integral_constant<std::size_t,Idx> )
const &;
157 template<
typename Tuple, std::size_t...Idxs,
typename...Tuples>
158 ebo_storage_impl( Tuple&& tuple, std::index_sequence<Idxs...>, Tuples&&...tuples );
163 template<std::
size_t Idx,
typename T0>
164 class ebo_storage_impl<Idx,T0,true>
170 ebo_storage_impl() =
default;
171 template<
typename Tuple,
typename = std::enable_if_t<!std::is_same<std::decay_t<Tuple>,ebo_storage_impl>::value>>
172 ebo_storage_impl( Tuple&& tuple );
173 ebo_storage_impl(
const ebo_storage_impl& other ) =
default;
174 ebo_storage_impl( ebo_storage_impl&& other ) =
default;
176 ebo_storage_impl& operator=(
const ebo_storage_impl& other ) =
default;
177 ebo_storage_impl& operator=( ebo_storage_impl&& other ) =
default;
184 T0&
get( std::integral_constant<std::size_t,Idx> ) &;
185 const T0&
get( std::integral_constant<std::size_t,Idx> )
const &;
192 template<
typename Tuple, std::size_t...Idxs>
193 ebo_storage_impl( Tuple&& tuple, std::index_sequence<Idxs...> );
198 template<std::size_t Idx,
typename T0,
typename T1,
typename...Ts>
199 class ebo_storage_impl<Idx,T0,false,T1,Ts...>
200 :
public ebo_storage_impl<Idx+1,T1,can_ebo<T1,Ts...>::value, Ts...>
202 using base_type = detail::ebo_storage_impl<Idx+1,T1,can_ebo<T1,Ts...>::value, Ts...>;
209 ebo_storage_impl() =
default;
210 template<
typename Tuple,
typename...Tuples,
typename = std::enable_if_t<!std::is_same<std::decay_t<Tuple>,ebo_storage_impl>::value>>
211 ebo_storage_impl( Tuple&& tuple, Tuples&&...tuples );
212 ebo_storage_impl(
const ebo_storage_impl& other ) =
default;
213 ebo_storage_impl( ebo_storage_impl&& other ) =
default;
217 ebo_storage_impl& operator=(
const ebo_storage_impl& other ) =
default;
218 ebo_storage_impl& operator=( ebo_storage_impl&& other ) =
default;
225 using base_type::get;
227 T0&
get( std::integral_constant<std::size_t,Idx> ) &;
228 const T0&
get( std::integral_constant<std::size_t,Idx> )
const &;
235 template<
typename Tuple, std::size_t...Idxs,
typename...Tuples>
236 ebo_storage_impl( Tuple&& tuple, std::index_sequence<Idxs...>, Tuples&&...tuples);
248 template<std::
size_t Idx,
typename T0>
249 class ebo_storage_impl<Idx,T0,false>
256 ebo_storage_impl() =
default;
257 template<
typename Tuple,
typename = std::enable_if_t<!std::is_same<std::decay_t<Tuple>,ebo_storage_impl>::value>>
258 ebo_storage_impl( Tuple&& tuple );
259 ebo_storage_impl(
const ebo_storage_impl& other ) =
default;
260 ebo_storage_impl( ebo_storage_impl&& other ) =
default;
264 ebo_storage_impl& operator=(
const ebo_storage_impl& other ) =
default;
265 ebo_storage_impl& operator=( ebo_storage_impl&& other ) =
default;
272 T0&
get( std::integral_constant<std::size_t,Idx> ) &;
273 const T0&
get( std::integral_constant<std::size_t,Idx> )
const &;
280 template<
typename Tuple, std::size_t...Idxs>
281 ebo_storage_impl( Tuple&& tuple, std::index_sequence<Idxs...> );
319 template<
typename T0,
typename...Ts>
321 :
public detail::ebo_storage_impl<0,T0,detail::can_ebo<T0,Ts...>::value,Ts...>
324 using base_type = detail::ebo_storage_impl<0,T0,detail::can_ebo<T0,Ts...>::value,Ts...>;
333 template<
typename...Tuples,
typename = std::enable_if_t<
sizeof...(Ts)+1==
sizeof...(Tuples)>>
351 template<std::size_t Idx,
typename...Types>
352 friend std::tuple_element_t<Idx,std::tuple<Types...>>&
355 template<std::size_t Idx,
typename...Types>
356 friend std::tuple_element_t<Idx,
const std::tuple<Types...>>&
363 #include "detail/ebo_storage.inl"
A utility class used for leveraging empty-base optimization for a generic sequence of types...