15 #ifndef PAAL_COMPONENTS_HPP
16 #define PAAL_COMPONENTS_HPP
24 namespace data_structures {
52 template <
typename Name,
typename Names,
typename Types>
struct type_for_name {
55 typedef typename type_for_name<Name, NewNames, NewTypes>::type type;
59 template <
typename Name,
typename Type,
typename... NamesRest,
60 typename... TypesRest>
79 std::declval<const C>().
template get<Name>())(C::*)()
const> *);
88 template <
typename C>
static long f(...);
96 (
sizeof(f<typename std::decay<T>::type>(
nullptr)) ==
sizeof(char));
118 template <
typename... Unused>
components(
const Unused &...) {}
124 template <
typename Name,
typename Type,
typename... NamesRest,
125 typename... TypesRest>
128 TypesVector<NamesRest...>, TypesVector<TypesRest...>> {
135 template <
typename ComponentName>
137 typename std::enable_if<std::is_same<ComponentName, Name>::value>::type;
147 components(components
const & other)
148 : base(static_cast<base const &>(other)), m_component(other.get<Name>()) {}
153 components(components &other)
154 : base(static_cast<base &>(other)), m_component(other.get<Name>()) {}
157 components(components &&) =
default;
160 components &operator=(components
const & other) {
162 static_cast<base &
>(*this) =
static_cast<base &
>(other);
163 m_component = other.get<Name>();
170 components &operator=(components &other) {
171 static_cast<base &
>(*this) =
static_cast<base &
>(other);
172 m_component = other.get<Name>();
177 components &operator=(components &&) =
default;
190 template <
typename T,
typename... TypesPrefix>
192 :
base(std::forward<TypesPrefix>(types)...),
193 m_component(std::forward<T>(t)) {}
198 template <
typename Comps>
207 template <
typename Comps>
220 template <
typename ComponentName,
typename = is_my_name<ComponentName>>
235 template <
typename ComponentName,
typename = is_my_name<ComponentName>>
252 template <
typename ComponentName,
typename... Args>
253 auto call(Args &&... args)->decltype(std::declval<
254 typename type_for_name<ComponentName, Names, Types>::type>()(
255 std::forward<Args>(args)...)) {
256 return this->
template get<ComponentName>()(std::forward<Args>(args)...);
271 template <
typename ComponentName,
typename... Args>
272 auto call(Args &&... args) const->decltype(std::declval<
274 std::forward<Args>(args)...)) {
275 return this->
template get<ComponentName>()(std::forward<Args>(args)...);
284 template <
typename ComponentName>
286 set(
const typename type_for_name<ComponentName, Names, Types>::type comp) {
287 this->get<ComponentName>() = std::move(comp);
300 template <
typename... NamesSubset,
typename... SomeTypes>
309 static_assert(
sizeof...(NamesSubset) ==
sizeof...(SomeTypes),
310 "Incorrect number of arguments.");
312 comps(std::forward<SomeTypes>(types)...);
319 template <
bool move,
typename A> A move_or_pass_reference(
const A &a) {
324 template <
bool move,
typename A,
325 typename =
typename std::enable_if<!move>::type>
326 const A &move_or_pass_reference(
const A &a) {
331 template <
bool move,
typename A,
332 typename =
typename std::enable_if<!move>::type>
333 A &move_or_pass_reference(A &a) {
341 template <
typename Comps,
342 typename dummy =
typename std::enable_if<
343 has_template_get<Comps, Name>::value,
int>::type>
344 components(Comps &&comps, movable_tag m, dummy d = dummy())
345 : base(std::forward<Comps>(comps), std::move(m)),
349 move_or_pass_reference<!std::is_lvalue_reference<Type>::value>(
350 comps.template get<Name>())) {}
353 template <
typename Comps,
typename dummy =
typename std::enable_if<
354 !has_template_get<Comps, Name>::value>::type>
355 components(Comps &&comps, movable_tag m)
356 : base(std::forward<Comps>(comps), std::move(m)) {}
359 template <
typename Comps,
360 typename dummy =
typename std::enable_if<
361 has_template_get<Comps, Name>::value,
int>::type>
362 components(Comps &&comps, Notmovable_tag m, dummy d = dummy())
363 : base(std::forward<Comps>(comps), std::move(m)),
364 m_component(comps.template get<Name>()) {}
368 template <
typename Comps,
typename dummy =
typename std::enable_if<
369 !has_template_get<Comps, Name>::value>::type>
370 components(Comps &&comps, Notmovable_tag m)
371 : base(std::forward<Comps>(comps), std::move(m)) {}
382 template <
typename Names,
typename Defaults,
typename TypesPrefix>
386 static_assert(TYPES_NR <= N,
"Incrrect number of parameters");
389 static_assert(DEFAULTS_NR + TYPES_NR >= N,
"Incrrect number of parameters");
420 template <
typename Name,
typename Default>
430 template <
typename Vector,
typename NameWithDefault>
struct apply {
442 template <
typename Vector,
typename Name>
struct apply {
447 template <
typename Vector,
typename Name,
typename Default>
458 template <
typename... ComponentNamesWithDefaults>
class components {
474 template <
class T>
struct special_decay {
475 using type =
typename std::decay<T>::type;
483 template <
class T>
struct special_decay<std::reference_wrapper<T>> {
487 template <
class T>
using special_decay_t =
typename special_decay<T>::type;
490 template <
typename... ComponentTypes>
492 Names, Defaults,
TypesVector<ComponentTypes...>>::type;
496 static type<special_decay_t<components>...>
498 return type<special_decay_t<components>...>(
499 std::forward<components>(comps)...);
507 typedef typename remove_n_first<N - DEFAULTS_NR, NamesWithDefaults>::type
511 static_assert(std::is_same<DefaultsTest, Defaults>::value,
512 "Defaults values could be only on subsequent number of last "
518 #endif // PAAL_COMPONENTS_HPP
Tag indicating that given object is movable.
static const bool value
tels if given type has get<Name>() memer function.
Standard fold function implementation.
Computes size of TypesVector.
static type< special_decay_t< components >...> make_components(components &&...comps)
make function for components
Tag indicating that given object is not movable.
static components< Names, Types > make(SomeTypes &&...types)
function creating components class, takes arguments only for assigned Names
This structure can be passed on Names list and represents Name and the default type value...
auto call(Args &&...args) const -> decltype(std::declval< const typename type_for_name< ComponentName, Names, Types >::type >()(std::forward< Args >(args)...))
This function directly calls component. m_component(args) has to be valid expresion const version...
If Name is kth on Names list, returns kth Type.
Meta function takes NameWithDefault and Vector the result is new vector with new Name appended Name...
get_name, gets name for either Name, or NamesWithDefaults struct this is the Name case ...
This is implementation of type vector taking advantage of variadic template. This implementation is N...
auto call(Args &&...args) -> decltype(std::declval< typename type_for_name< ComponentName, Names, Types >::type >()(std::forward< Args >(args)...))
This function directly calls component. m_component(args) has to be valid expresion nonconst version...
push back given val to TypesVector
wraps type to constructible type
Indicates that components constructor is in fact a Copy/Move Constructor.
removes first n elements from given TypesVector
void set(const typename type_for_name< ComponentName, Names, Types >::type comp)
setter for component assigned to Name.
components(T &&t, TypesPrefix &&...types)
constructor takes some number of arguments, This arguments has to be convertible to the same number o...
SFINAE check if the given type has get<Name>() member function.