meta  1.4.9
factory.hpp
1 #ifndef META_FACTORY_HPP
2 #define META_FACTORY_HPP
3 
4 
5 #include <tuple>
6 #include <array>
7 #include <cassert>
8 #include <cstddef>
9 #include <utility>
10 #include <functional>
11 #include <type_traits>
12 #include "policy.hpp"
13 #include "meta.hpp"
14 
15 
16 namespace meta {
17 
18 
25 namespace internal {
26 
27 
28 template<typename>
29 struct function_helper;
30 
31 
32 template<typename Ret, typename... Args>
33 struct function_helper<Ret(Args...)> {
34  using return_type = std::remove_cv_t<std::remove_reference_t<Ret>>;
35  using args_type = std::tuple<std::remove_cv_t<std::remove_reference_t<Args>>...>;
36 
37  static constexpr auto size = sizeof...(Args);
38  static constexpr auto is_const = false;
39 
40  static auto arg(typename internal::func_node::size_type index) noexcept {
41  return std::array<type_node *, sizeof...(Args)>{{type_info<Args>::resolve()...}}[index];
42  }
43 };
44 
45 
46 template<typename Ret, typename... Args>
47 struct function_helper<Ret(Args...) const>: function_helper<Ret(Args...)> {
48  static constexpr auto is_const = true;
49 };
50 
51 
52 template<typename Ret, typename... Args, typename Class>
53 constexpr function_helper<Ret(Args...)>
54 to_function_helper(Ret(Class:: *)(Args...));
55 
56 
57 template<typename Ret, typename... Args, typename Class>
58 constexpr function_helper<Ret(Args...) const>
59 to_function_helper(Ret(Class:: *)(Args...) const);
60 
61 
62 template<typename Ret, typename... Args>
63 constexpr function_helper<Ret(Args...)>
64 to_function_helper(Ret(*)(Args...));
65 
66 
67 constexpr void to_function_helper(...);
68 
69 
70 template<typename Candidate>
71 using function_helper_t = decltype(to_function_helper(std::declval<Candidate>()));
72 
73 
74 template<typename Type, typename... Args, std::size_t... Indexes>
75 any construct(any * const args, std::index_sequence<Indexes...>) {
76  [[maybe_unused]] auto direct = std::make_tuple((args+Indexes)->try_cast<Args>()...);
77  any any{};
78 
79  if(((std::get<Indexes>(direct) || (args+Indexes)->convert<Args>()) && ...)) {
80  any = Type{(std::get<Indexes>(direct) ? *std::get<Indexes>(direct) : (args+Indexes)->cast<Args>())...};
81  }
82 
83  return any;
84 }
85 
86 
87 template<bool Const, typename Type, auto Data>
88 bool setter([[maybe_unused]] handle handle, [[maybe_unused]] any index, [[maybe_unused]] any value) {
89  bool accepted = false;
90 
91  if constexpr(!Const) {
92  if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Data)>> || std::is_member_function_pointer_v<decltype(Data)>) {
93  using helper_type = function_helper_t<decltype(Data)>;
94  using data_type = std::tuple_element_t<!std::is_member_function_pointer_v<decltype(Data)>, typename helper_type::args_type>;
95  static_assert(std::is_invocable_v<decltype(Data), Type &, data_type>);
96  auto *clazz = any{handle}.try_cast<Type>();
97  auto *direct = value.try_cast<data_type>();
98 
99  if(clazz && (direct || value.convert<data_type>())) {
100  std::invoke(Data, *clazz, direct ? *direct : value.cast<data_type>());
101  accepted = true;
102  }
103  } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
104  using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
105  static_assert(std::is_invocable_v<decltype(Data), Type *>);
106  auto *clazz = any{handle}.try_cast<Type>();
107 
108  if constexpr(std::is_array_v<data_type>) {
109  using underlying_type = std::remove_extent_t<data_type>;
110  auto *direct = value.try_cast<underlying_type>();
111  auto *idx = index.try_cast<std::size_t>();
112 
113  if(clazz && idx && (direct || value.convert<underlying_type>())) {
114  std::invoke(Data, clazz)[*idx] = direct ? *direct : value.cast<underlying_type>();
115  accepted = true;
116  }
117  } else {
118  auto *direct = value.try_cast<data_type>();
119 
120  if(clazz && (direct || value.convert<data_type>())) {
121  std::invoke(Data, clazz) = (direct ? *direct : value.cast<data_type>());
122  accepted = true;
123  }
124  }
125  } else {
126  static_assert(std::is_pointer_v<decltype(Data)>);
127  using data_type = std::remove_cv_t<std::remove_reference_t<decltype(*Data)>>;
128 
129  if constexpr(std::is_array_v<data_type>) {
130  using underlying_type = std::remove_extent_t<data_type>;
131  auto *direct = value.try_cast<underlying_type>();
132  auto *idx = index.try_cast<std::size_t>();
133 
134  if(idx && (direct || value.convert<underlying_type>())) {
135  (*Data)[*idx] = (direct ? *direct : value.cast<underlying_type>());
136  accepted = true;
137  }
138  } else {
139  auto *direct = value.try_cast<data_type>();
140 
141  if(direct || value.convert<data_type>()) {
142  *Data = (direct ? *direct : value.cast<data_type>());
143  accepted = true;
144  }
145  }
146  }
147  }
148 
149  return accepted;
150 }
151 
152 
153 template<typename Type, auto Data, typename Policy>
154 any getter([[maybe_unused]] handle handle, [[maybe_unused]] any index) {
155  auto dispatch = [](auto &&value) {
156  if constexpr(std::is_same_v<Policy, as_void_t>) {
157  return any{std::in_place_type<void>};
158  } else if constexpr(std::is_same_v<Policy, as_alias_t>) {
159  return any{std::ref(std::forward<decltype(value)>(value))};
160  } else {
161  static_assert(std::is_same_v<Policy, as_is_t>);
162  return any{std::forward<decltype(value)>(value)};
163  }
164  };
165 
166  if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Data)>> || std::is_member_function_pointer_v<decltype(Data)>) {
167  static_assert(std::is_invocable_v<decltype(Data), Type &>);
168  auto *clazz = any{handle}.try_cast<Type>();
169  return clazz ? dispatch(std::invoke(Data, *clazz)) : any{};
170  } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
171  using data_type = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Type>().*Data)>>;
172  static_assert(std::is_invocable_v<decltype(Data), Type *>);
173  auto *clazz = any{handle}.try_cast<Type>();
174 
175  if constexpr(std::is_array_v<data_type>) {
176  auto *idx = index.try_cast<std::size_t>();
177  return (clazz && idx) ? dispatch(std::invoke(Data, clazz)[*idx]) : any{};
178  } else {
179  return clazz ? dispatch(std::invoke(Data, clazz)) : any{};
180  }
181  } else {
182  static_assert(std::is_pointer_v<std::decay_t<decltype(Data)>>);
183 
184  if constexpr(std::is_array_v<std::remove_pointer_t<decltype(Data)>>) {
185  auto *idx = index.try_cast<std::size_t>();
186  return idx ? dispatch((*Data)[*idx]) : any{};
187  } else {
188  return dispatch(*Data);
189  }
190  }
191 }
192 
193 
194 template<typename Type, auto Candidate, typename Policy, std::size_t... Indexes>
195 any invoke([[maybe_unused]] handle handle, any *args, std::index_sequence<Indexes...>) {
196  using helper_type = function_helper_t<decltype(Candidate)>;
197 
198  auto dispatch = [](auto *... args) {
199  if constexpr(std::is_void_v<typename helper_type::return_type> || std::is_same_v<Policy, as_void_t>) {
200  std::invoke(Candidate, *args...);
201  return any{std::in_place_type<void>};
202  } else if constexpr(std::is_same_v<Policy, as_alias_t>) {
203  return any{std::ref(std::invoke(Candidate, *args...))};
204  } else {
205  static_assert(std::is_same_v<Policy, as_is_t>);
206  return any{std::invoke(Candidate, *args...)};
207  }
208  };
209 
210  [[maybe_unused]] const auto direct = std::make_tuple([](meta::any *any, auto *instance) {
211  using arg_type = std::remove_reference_t<decltype(*instance)>;
212 
213  if(!instance && any->convert<arg_type>()) {
214  instance = any->try_cast<arg_type>();
215  }
216 
217  return instance;
218  }(args+Indexes, (args+Indexes)->try_cast<std::tuple_element_t<Indexes, typename helper_type::args_type>>())...);
219 
220  if constexpr(std::is_function_v<std::remove_pointer_t<decltype(Candidate)>>) {
221  return (std::get<Indexes>(direct) && ...) ? dispatch(std::get<Indexes>(direct)...) : any{};
222  } else {
223  auto *clazz = any{handle}.try_cast<Type>();
224  return (clazz && (std::get<Indexes>(direct) && ...)) ? dispatch(clazz, std::get<Indexes>(direct)...) : any{};
225  }
226 }
227 
228 
229 }
230 
231 
248 template<typename Type>
249 class factory {
250  template<typename Node>
251  bool duplicate(const std::size_t identifier, const Node *node) noexcept {
252  return node && (node->identifier == identifier || duplicate(identifier, node->next));
253  }
254 
255  bool duplicate(const any &key, const internal::prop_node *node) noexcept {
256  return node && (node->key() == key || duplicate(key, node->next));
257  }
258 
259  template<typename>
260  internal::prop_node * properties() {
261  return nullptr;
262  }
263 
264  template<typename Owner, typename Property, typename... Other>
265  internal::prop_node * properties(Property &&property, Other &&... other) {
266  static std::remove_cv_t<std::remove_reference_t<Property>> prop{};
267 
268  static internal::prop_node node{
269  nullptr,
270  []() -> any {
271  return std::as_const(std::get<0>(prop));
272  },
273  []() -> any {
274  return std::as_const(std::get<1>(prop));
275  },
276  []() noexcept -> meta::prop {
277  return &node;
278  }
279  };
280 
281  prop = std::forward<Property>(property);
282  node.next = properties<Owner>(std::forward<Other>(other)...);
283  assert(!duplicate(any{std::get<0>(prop)}, node.next));
284  return &node;
285  }
286 
287  void unregister_prop(internal::prop_node **prop) {
288  while(*prop) {
289  auto *node = *prop;
290  *prop = node->next;
291  node->next = nullptr;
292  }
293  }
294 
295  void unregister_dtor() {
296  if(auto node = internal::type_info<Type>::type->dtor; node) {
297  internal::type_info<Type>::type->dtor = nullptr;
298  *node->underlying = nullptr;
299  }
300  }
301 
302  template<auto Member>
303  auto unregister_all(int)
304  -> decltype((internal::type_info<Type>::type->*Member)->prop, void()) {
305  while(internal::type_info<Type>::type->*Member) {
306  auto node = internal::type_info<Type>::type->*Member;
307  internal::type_info<Type>::type->*Member = node->next;
308  unregister_prop(&node->prop);
309  node->next = nullptr;
310  *node->underlying = nullptr;
311  }
312  }
313 
314  template<auto Member>
315  void unregister_all(char) {
316  while(internal::type_info<Type>::type->*Member) {
317  auto node = internal::type_info<Type>::type->*Member;
318  internal::type_info<Type>::type->*Member = node->next;
319  node->next = nullptr;
320  *node->underlying = nullptr;
321  }
322  }
323 
324 public:
326  factory() noexcept = default;
327 
335  template<typename... Property>
336  factory type(const std::size_t identifier, Property &&... property) noexcept {
337  assert(!internal::type_info<Type>::type);
338  auto *node = internal::type_info<Type>::resolve();
339  node->identifier = identifier;
340  node->next = internal::type_info<>::type;
341  node->prop = properties<Type>(std::forward<Property>(property)...);
342  assert(!duplicate(node->identifier, node->next));
343  internal::type_info<Type>::type = node;
344  internal::type_info<>::type = node;
345 
346  return *this;
347  }
348 
357  template<typename Base>
358  factory base() noexcept {
359  static_assert(std::is_base_of_v<Base, Type>);
360  auto * const type = internal::type_info<Type>::resolve();
361 
362  static internal::base_node node{
363  &internal::type_info<Type>::template base<Base>,
364  type,
365  nullptr,
366  &internal::type_info<Base>::resolve,
367  [](void *instance) noexcept -> void * {
368  return static_cast<Base *>(static_cast<Type *>(instance));
369  },
370  []() noexcept -> meta::base {
371  return &node;
372  }
373  };
374 
375  node.next = type->base;
376  assert((!internal::type_info<Type>::template base<Base>));
377  internal::type_info<Type>::template base<Base> = &node;
378  type->base = &node;
379 
380  return *this;
381  }
382 
392  template<typename To>
393  factory conv() noexcept {
394  static_assert(std::is_convertible_v<Type, To>);
395  auto * const type = internal::type_info<Type>::resolve();
396 
397  static internal::conv_node node{
398  &internal::type_info<Type>::template conv<To>,
399  type,
400  nullptr,
401  &internal::type_info<To>::resolve,
402  [](const void *instance) -> any {
403  return static_cast<To>(*static_cast<const Type *>(instance));
404  },
405  []() noexcept -> meta::conv {
406  return &node;
407  }
408  };
409 
410  node.next = type->conv;
411  assert((!internal::type_info<Type>::template conv<To>));
412  internal::type_info<Type>::template conv<To> = &node;
413  type->conv = &node;
414 
415  return *this;
416  }
417 
430  template<auto Candidate>
431  factory conv() noexcept {
432  using conv_type = std::invoke_result_t<decltype(Candidate), Type &>;
433  auto * const type = internal::type_info<Type>::resolve();
434 
435  static internal::conv_node node{
436  &internal::type_info<Type>::template conv<conv_type>,
437  type,
438  nullptr,
439  &internal::type_info<conv_type>::resolve,
440  [](const void *instance) -> any {
441  return std::invoke(Candidate, *static_cast<const Type *>(instance));
442  },
443  []() noexcept -> meta::conv {
444  return &node;
445  }
446  };
447 
448  node.next = type->conv;
449  assert((!internal::type_info<Type>::template conv<conv_type>));
450  internal::type_info<Type>::template conv<conv_type> = &node;
451  type->conv = &node;
452 
453  return *this;
454  }
455 
471  template<auto Func, typename Policy = as_is_t, typename... Property>
472  factory ctor(Property &&... property) noexcept {
473  using helper_type = internal::function_helper_t<decltype(Func)>;
474  static_assert(std::is_same_v<typename helper_type::return_type, Type>);
475  auto * const type = internal::type_info<Type>::resolve();
476 
477  static internal::ctor_node node{
478  &internal::type_info<Type>::template ctor<typename helper_type::args_type>,
479  type,
480  nullptr,
481  nullptr,
482  helper_type::size,
483  &helper_type::arg,
484  [](any * const any) {
485  return internal::invoke<Type, Func, Policy>({}, any, std::make_index_sequence<helper_type::size>{});
486  },
487  []() noexcept -> meta::ctor {
488  return &node;
489  }
490  };
491 
492  node.next = type->ctor;
493  node.prop = properties<typename helper_type::args_type>(std::forward<Property>(property)...);
494  assert((!internal::type_info<Type>::template ctor<typename helper_type::args_type>));
495  internal::type_info<Type>::template ctor<typename helper_type::args_type> = &node;
496  type->ctor = &node;
497 
498  return *this;
499  }
500 
513  template<typename... Args, typename... Property>
514  factory ctor(Property &&... property) noexcept {
515  using helper_type = internal::function_helper_t<Type(*)(Args...)>;
516  auto * const type = internal::type_info<Type>::resolve();
517 
518  static internal::ctor_node node{
519  &internal::type_info<Type>::template ctor<typename helper_type::args_type>,
520  type,
521  nullptr,
522  nullptr,
523  helper_type::size,
524  &helper_type::arg,
525  [](any * const any) {
526  return internal::construct<Type, std::remove_cv_t<std::remove_reference_t<Args>>...>(any, std::make_index_sequence<helper_type::size>{});
527  },
528  []() noexcept -> meta::ctor {
529  return &node;
530  }
531  };
532 
533  node.next = type->ctor;
534  node.prop = properties<typename helper_type::args_type>(std::forward<Property>(property)...);
535  assert((!internal::type_info<Type>::template ctor<typename helper_type::args_type>));
536  internal::type_info<Type>::template ctor<typename helper_type::args_type> = &node;
537  type->ctor = &node;
538 
539  return *this;
540  }
541 
558  template<auto Func>
559  factory dtor() noexcept {
560  static_assert(std::is_invocable_v<decltype(Func), Type &>);
561  auto * const type = internal::type_info<Type>::resolve();
562 
563  static internal::dtor_node node{
564  &internal::type_info<Type>::template dtor<Func>,
565  type,
566  [](handle handle) {
567  const auto valid = (handle.type() == internal::type_info<Type>::resolve()->clazz());
568 
569  if(valid) {
570  std::invoke(Func, *any{handle}.try_cast<Type>());
571  }
572 
573  return valid;
574  },
575  []() noexcept -> meta::dtor {
576  return &node;
577  }
578  };
579 
580  assert(!internal::type_info<Type>::type->dtor);
581  assert((!internal::type_info<Type>::template dtor<Func>));
582  internal::type_info<Type>::template dtor<Func> = &node;
583  internal::type_info<Type>::type->dtor = &node;
584 
585  return *this;
586  }
587 
603  template<auto Data, typename Policy = as_is_t, typename... Property>
604  factory data(const std::size_t identifier, Property &&... property) noexcept {
605  auto * const type = internal::type_info<Type>::resolve();
606  internal::data_node *curr = nullptr;
607 
608  if constexpr(std::is_same_v<Type, decltype(Data)>) {
609  static_assert(std::is_same_v<Policy, as_is_t>);
610 
611  static internal::data_node node{
612  &internal::type_info<Type>::template data<Data>,
613  {},
614  type,
615  nullptr,
616  nullptr,
617  true,
618  true,
619  &internal::type_info<Type>::resolve,
620  [](handle, any, any) { return false; },
621  [](handle, any) -> any { return Data; },
622  []() noexcept -> meta::data {
623  return &node;
624  }
625  };
626 
627  node.prop = properties<std::integral_constant<Type, Data>>(std::forward<Property>(property)...);
628  curr = &node;
629  } else if constexpr(std::is_member_object_pointer_v<decltype(Data)>) {
630  using data_type = std::remove_reference_t<decltype(std::declval<Type>().*Data)>;
631 
632  static internal::data_node node{
633  &internal::type_info<Type>::template data<Data>,
634  {},
635  type,
636  nullptr,
637  nullptr,
638  std::is_const_v<data_type>,
639  !std::is_member_object_pointer_v<decltype(Data)>,
640  &internal::type_info<data_type>::resolve,
641  &internal::setter<std::is_const_v<data_type>, Type, Data>,
642  &internal::getter<Type, Data, Policy>,
643  []() noexcept -> meta::data {
644  return &node;
645  }
646  };
647 
648  node.prop = properties<std::integral_constant<decltype(Data), Data>>(std::forward<Property>(property)...);
649  curr = &node;
650  } else {
651  static_assert(std::is_pointer_v<std::decay_t<decltype(Data)>>);
652  using data_type = std::remove_pointer_t<std::decay_t<decltype(Data)>>;
653 
654  static internal::data_node node{
655  &internal::type_info<Type>::template data<Data>,
656  {},
657  type,
658  nullptr,
659  nullptr,
660  std::is_const_v<data_type>,
661  !std::is_member_object_pointer_v<decltype(Data)>,
662  &internal::type_info<data_type>::resolve,
663  &internal::setter<std::is_const_v<data_type>, Type, Data>,
664  &internal::getter<Type, Data, Policy>,
665  []() noexcept -> meta::data {
666  return &node;
667  }
668  };
669 
670  node.prop = properties<std::integral_constant<decltype(Data), Data>>(std::forward<Property>(property)...);
671  curr = &node;
672  }
673 
674  curr->identifier = identifier;
675  curr->next = type->data;
676  assert(!duplicate(curr->identifier, curr->next));
677  assert((!internal::type_info<Type>::template data<Data>));
678  internal::type_info<Type>::template data<Data> = curr;
679  type->data = curr;
680 
681  return *this;
682  }
683 
706  template<auto Setter, auto Getter, typename Policy = as_is_t, typename... Property>
707  factory data(const std::size_t identifier, Property &&... property) noexcept {
708  using owner_type = std::tuple<std::integral_constant<decltype(Setter), Setter>, std::integral_constant<decltype(Getter), Getter>>;
709  using underlying_type = std::invoke_result_t<decltype(Getter), Type &>;
710  static_assert(std::is_invocable_v<decltype(Setter), Type &, underlying_type>);
711  auto * const type = internal::type_info<Type>::resolve();
712 
713  static internal::data_node node{
714  &internal::type_info<Type>::template data<Setter, Getter>,
715  {},
716  type,
717  nullptr,
718  nullptr,
719  false,
720  false,
721  &internal::type_info<underlying_type>::resolve,
722  &internal::setter<false, Type, Setter>,
723  &internal::getter<Type, Getter, Policy>,
724  []() noexcept -> meta::data {
725  return &node;
726  }
727  };
728 
729  node.identifier = identifier;
730  node.next = type->data;
731  node.prop = properties<owner_type>(std::forward<Property>(property)...);
732  assert(!duplicate(node.identifier, node.next));
733  assert((!internal::type_info<Type>::template data<Setter, Getter>));
734  internal::type_info<Type>::template data<Setter, Getter> = &node;
735  type->data = &node;
736 
737  return *this;
738  }
739 
755  template<auto Candidate, typename Policy = as_is_t, typename... Property>
756  factory func(const std::size_t identifier, Property &&... property) noexcept {
757  using owner_type = std::integral_constant<decltype(Candidate), Candidate>;
758  using helper_type = internal::function_helper_t<decltype(Candidate)>;
759  auto * const type = internal::type_info<Type>::resolve();
760 
761  static internal::func_node node{
762  &internal::type_info<Type>::template func<Candidate>,
763  {},
764  type,
765  nullptr,
766  nullptr,
767  helper_type::size,
768  helper_type::is_const,
769  !std::is_member_function_pointer_v<decltype(Candidate)>,
770  &internal::type_info<std::conditional_t<std::is_same_v<Policy, as_void_t>, void, typename helper_type::return_type>>::resolve,
771  &helper_type::arg,
772  [](handle handle, any *any) {
773  return internal::invoke<Type, Candidate, Policy>(handle, any, std::make_index_sequence<helper_type::size>{});
774  },
775  []() noexcept -> meta::func {
776  return &node;
777  }
778  };
779 
780  node.identifier = identifier;
781  node.next = type->func;
782  node.prop = properties<owner_type>(std::forward<Property>(property)...);
783  assert(!duplicate(node.identifier, node.next));
784  assert((!internal::type_info<Type>::template func<Candidate>));
785  internal::type_info<Type>::template func<Candidate> = &node;
786  type->func = &node;
787 
788  return *this;
789  }
790 
802  bool unregister() noexcept {
803  const auto registered = internal::type_info<Type>::type;
804 
805  if(registered) {
806  if(auto *curr = internal::type_info<>::type; curr == internal::type_info<Type>::type) {
807  internal::type_info<>::type = internal::type_info<Type>::type->next;
808  } else {
809  while(curr && curr->next != internal::type_info<Type>::type) {
810  curr = curr->next;
811  }
812 
813  if(curr) {
814  curr->next = internal::type_info<Type>::type->next;
815  }
816  }
817 
818  unregister_prop(&internal::type_info<Type>::type->prop);
819  unregister_all<&internal::type_node::base>(0);
820  unregister_all<&internal::type_node::conv>(0);
821  unregister_all<&internal::type_node::ctor>(0);
822  unregister_all<&internal::type_node::data>(0);
823  unregister_all<&internal::type_node::func>(0);
824  unregister_dtor();
825 
826  internal::type_info<Type>::type->identifier = {};
827  internal::type_info<Type>::type->next = nullptr;
828  internal::type_info<Type>::type = nullptr;
829  }
830 
831  return registered;
832  }
833 };
834 
835 
850 template<typename Type, typename... Property>
851 inline factory<Type> reflect(const std::size_t identifier, Property &&... property) noexcept {
852  return factory<Type>{}.type(identifier, std::forward<Property>(property)...);
853 }
854 
855 
867 template<typename Type>
868 inline factory<Type> reflect() noexcept {
869  return factory<Type>{};
870 }
871 
872 
885 template<typename Type>
886 inline bool unregister() noexcept {
887  return factory<Type>{}.unregister();
888 }
889 
890 
896 template<typename Type>
897 inline type resolve() noexcept {
898  return internal::type_info<Type>::resolve()->clazz();
899 }
900 
901 
907 inline type resolve(const std::size_t identifier) noexcept {
908  const auto *curr = internal::find_if([identifier](auto *node) {
909  return node->identifier == identifier;
910  }, internal::type_info<>::type);
911 
912  return curr ? curr->clazz() : type{};
913 }
914 
915 
921 template<typename Op>
922 inline std::enable_if_t<std::is_invocable_v<Op, type>, void>
923 resolve(Op op) noexcept {
924  internal::iterate([op = std::move(op)](auto *node) {
925  op(node->clazz());
926  }, internal::type_info<>::type);
927 }
928 
929 
930 }
931 
932 
933 #endif // META_FACTORY_HPP
type resolve() noexcept
Returns the meta type associated with a given type.
Definition: factory.hpp:897
std::enable_if_t< std::is_invocable_v< Op, meta::base >, void > base(Op op) const noexcept
Iterates all the meta base of a meta type.
Definition: meta.hpp:1668
std::enable_if_t< std::is_invocable_v< Op, meta::func >, void > func(Op op) const noexcept
Iterates all the meta functions of a meta type.
Definition: meta.hpp:1803
factory func(const std::size_t identifier, Property &&... property) noexcept
Assigns a meta funcion to a meta type.
Definition: factory.hpp:756
factory data(const std::size_t identifier, Property &&... property) noexcept
Assigns a meta data to a meta type.
Definition: factory.hpp:604
void conv(Op op) const noexcept
Iterates all the meta conversion functions of a meta type.
Definition: meta.hpp:1700
void ctor(Op op) const noexcept
Iterates all the meta constructors of a meta type.
Definition: meta.hpp:1731
std::enable_if_t< std::is_invocable_v< Op, meta::prop >, void > prop(Op op) const noexcept
Iterates all the properties assigned to a meta data.
Definition: meta.hpp:1301
factory conv() noexcept
Assigns a meta conversion function to a meta type.
Definition: factory.hpp:393
meta::type type() const noexcept
Returns the meta type of the underlying object.
Definition: meta.hpp:1955
Meta constructor object.
Definition: meta.hpp:976
bool unregister() noexcept
Utility function to unregister a type.
Definition: factory.hpp:886
Meta destructor object.
Definition: meta.hpp:1106
Meta property object.
Definition: meta.hpp:756
any convert() const
Tries to convert an instance to a given type and returns it.
Definition: meta.hpp:561
Meta handle object.
Definition: meta.hpp:675
std::enable_if_t< std::is_invocable_v< Op, meta::data >, void > data(Op op) const noexcept
Iterates all the meta data of a meta type.
Definition: meta.hpp:1767
factory ctor(Property &&... property) noexcept
Assigns a meta constructor to a meta type.
Definition: factory.hpp:514
Meta function object.
Definition: meta.hpp:1363
Empty class type used to request the as-is policy.
Definition: policy.hpp:17
meta default namespace.
Definition: factory.hpp:16
A meta factory to be used for reflection purposes.
Definition: factory.hpp:249
factory type(const std::size_t identifier, Property &&... property) noexcept
Extends a meta type by assigning it an identifier and properties.
Definition: factory.hpp:336
Meta data object.
Definition: meta.hpp:1180
factory< Type > reflect(const std::size_t identifier, Property &&... property) noexcept
Utility function to use for reflection.
Definition: factory.hpp:851
Meta conversion function object.
Definition: meta.hpp:901
factory dtor() noexcept
Assigns a meta destructor to a meta type.
Definition: factory.hpp:559
factory ctor(Property &&... property) noexcept
Assigns a meta constructor to a meta type.
Definition: factory.hpp:472
bool unregister() noexcept
Unregisters a meta type and all its parts.
Definition: factory.hpp:802
const Type * try_cast() const noexcept
Tries to cast an instance to a given type.
Definition: meta.hpp:517
Meta type object.
Definition: meta.hpp:1524
Meta any object.
Definition: meta.hpp:299
factory base() noexcept
Assigns a meta base to a meta type.
Definition: factory.hpp:358
factory data(const std::size_t identifier, Property &&... property) noexcept
Assigns a meta data to a meta type by means of its setter and getter.
Definition: factory.hpp:707
Meta base object.
Definition: meta.hpp:826