23namespace sequoia::impl
25 template<
class Excluded,
template<
class>
class TypeToType,
class Fn,
class... Ts>
26 void invoke_filtered(Fn f, Ts... t)
28 invoke_with_specified_args(f, make_filtered_sequence<Excluded, TypeToType, Ts...>{}, t...);
34 template<std::invocable<T> AllocGetter>
37 using type = std::invoke_result_t<AllocGetter, T>;
69 template<
class T, std::invocable<T>... AllocGetters>
70 constexpr static void assign(T& to,
const T& from, [[maybe_unused]] AllocGetters... allocGetters)
72 impl::invoke_filtered<void, impl::type_to_type<T>::template mapper>([&to, &from](
auto... filteredAllocGetters){ assign_filtered(to, from, filteredAllocGetters...); }, allocGetters...);
76 template<
class T, std::invocable<T>... FilteredAllocGetters>
77 constexpr static void assign_filtered(T& to,
const T& from, [[maybe_unused]] FilteredAllocGetters... allocGetters)
79 if constexpr((naive_treatment<T, FilteredAllocGetters>() && ...))
86 static_assert(consistency<T, FilteredAllocGetters...>());
88 T tmp{from, get_allocator(to, from, allocGetters)...};
90 movePropagation{move_propagation<T, FilteredAllocGetters...>()},
91 copyPropagation{copy_propagation<T, FilteredAllocGetters...>()};
93 if constexpr (movePropagation || !copyPropagation)
99 if constexpr(!swap_propagation<T, FilteredAllocGetters...>())
101 to.reset(allocGetters(tmp)...);
109 template<
class T, std::invocable<T> AllocGetter>
110 constexpr static bool naive_treatment() noexcept
112 using allocator = std::invoke_result_t<AllocGetter, T>;
113 return std::allocator_traits<allocator>::is_always_equal::value;
116 template<
class T, std::invocable<T> AllocGetter, std::invocable<T>... AllocGetters>
117 constexpr static bool consistency() noexcept
119 if constexpr(
sizeof...(AllocGetters) > 0)
121 return (consistent<T, AllocGetter, AllocGetters>() && ...);
129 template<
class T, std::invocable<T> AllocGetterL, std::invocable<T> AllocGetterR>
130 constexpr static bool consistent() noexcept
132 return (copy_propagation<T, AllocGetterL>() == copy_propagation<T, AllocGetterR>())
133 && (move_propagation<T, AllocGetterL>() == move_propagation<T, AllocGetterR>())
134 && (swap_propagation<T, AllocGetterL>() == swap_propagation<T, AllocGetterR>());
137 template<
class T,
class AllocGetter>
138 static auto get_allocator(
const T& to,
const T& from, AllocGetter allocGetter)
140 if constexpr(copy_propagation<T, AllocGetter>())
142 return allocGetter(from);
146 return allocGetter(to);
150 template<
class T,
class AllocGetter,
class... AllocGetters>
151 constexpr static bool copy_propagation() noexcept
153 using allocator = std::invoke_result_t<AllocGetter, T>;
154 return std::allocator_traits<allocator>::propagate_on_container_copy_assignment::value
155 || std::allocator_traits<allocator>::is_always_equal::value;
158 template<
class T,
class AllocGetter,
class... AllocGetters>
159 constexpr static bool move_propagation() noexcept
161 using allocator = std::invoke_result_t<AllocGetter, T>;
162 return std::allocator_traits<allocator>::propagate_on_container_move_assignment::value
163 || std::allocator_traits<allocator>::is_always_equal::value;
166 template<
class T,
class AllocGetter,
class... AllocGetters>
167 constexpr static bool swap_propagation() noexcept
169 using allocator = std::invoke_result_t<AllocGetter, T>;
170 return std::allocator_traits<allocator>::propagate_on_container_swap::value
171 || std::allocator_traits<allocator>::is_always_equal::value;
Helper class to assist with copy assignment for allocator-aware types.
Definition: AssignmentUtilities.hpp:67
static constexpr void assign(T &to, const T &from, AllocGetters... allocGetters)
Definition: AssignmentUtilities.hpp:70
Definition: AssignmentUtilities.hpp:36
Definition: AssignmentUtilities.hpp:33