Mirror reflection library - Rubber type-erasure utility 0.5.13

rubber/meta_objects.hpp

Go to the documentation of this file.
00001 
00010 #ifndef RUBBER_META_OBJECTS_1103151301_HPP
00011 #define RUBBER_META_OBJECTS_1103151301_HPP
00012 
00013 #include <rubber/config.hpp>
00014 #include <rubber/range.hpp>
00015 #include <rubber/meta_object.hpp>
00016 
00017 #include <cassert>
00018 #include <string>
00019 
00020 RUBBER_NAMESPACE_BEGIN
00021 
00023 
00027 class meta_named_object
00028  : virtual public meta_object
00029 {
00030 private:
00031     std::string _base_name;
00032 public:
00034     template <typename MetaNamedObject>
00035     meta_named_object(MetaNamedObject mo)
00036      : meta_object(mo)
00037      , _base_name(MetaNamedObject::base_name())
00038     { }
00039 
00041     inline std::string base_name(void) const
00042     {
00043         return _base_name;
00044     }
00045 };
00046 
00048 
00052 class meta_scoped_object
00053  : virtual public meta_object
00054 {
00055 private:
00056     aux::return_value<meta_scope>::type (*_get_scope)(void);
00057 public:
00059     template <typename MetaScopedObject>
00060     meta_scoped_object(MetaScopedObject mo)
00061      : meta_object(mo)
00062      , _get_scope(
00063         &wrap_shaped<
00064             typename MetaScopedObject::scope,
00065             meta_scope
00066         >
00067     )
00068     { }
00069 
00070 #ifdef MIRROR_DOCUMENTATION_ONLY
00071 
00072     meta_scope scope(void) const;
00073 #else
00074     inline aux::return_value<meta_scope>::type scope(void) const;
00075 #endif
00076 };
00077 
00079 
00083 class meta_named_scoped_object
00084  : public meta_scoped_object
00085  , public meta_named_object
00086 {
00087 private:
00088     std::string(*_get_full_name)(void);
00089 #if RUBBER_MSNO_WITH_LOCAL_NAME
00090     std::string(*_get_local_name)(void);
00091 #endif
00092 public:
00094     template <typename MetaNamedScopedObject>
00095     meta_named_scoped_object(MetaNamedScopedObject mo)
00096      : meta_object(mo)
00097      , meta_scoped_object(mo)
00098      , meta_named_object(mo)
00099      , _get_full_name(&MetaNamedScopedObject::full_name)
00100 #if RUBBER_MSNO_WITH_LOCAL_NAME
00101      , _get_local_name(&MetaNamedScopedObject::local_name)
00102 #endif
00103     { }
00104 
00106     inline std::string full_name(void) const
00107     {
00108         assert(_get_full_name != nullptr);
00109         return _get_full_name();
00110     }
00111 
00112 #if RUBBER_MSNO_WITH_LOCAL_NAME || MIRROR_DOCUMENTATION_ONLY
00113 
00114 
00123     inline std::string local_name(void) const
00124     {
00125         assert(_get_local_name != nullptr);
00126         return _get_local_name();
00127     }
00128 #endif
00129 };
00130 
00132 
00136 class meta_scope
00137  : virtual public meta_named_scoped_object
00138 {
00139 private:
00140     range_holder<meta_named_scoped_object> _members;
00141 
00142     template <typename MetaScope>
00143     static mirror::members<MetaScope> static_members(
00144         MetaScope,
00145         const mirror::meta_scope_tag&
00146     )
00147     {
00148         return mirror::members<MetaScope>();
00149     }
00150 
00151 #if RUBBER_NO_NAMESPACE_MEMBERS
00152     template <typename MetaNamespace>
00153     static mirror::mp::empty_range static_members(
00154         MetaNamespace,
00155         const mirror::meta_namespace_tag&
00156     )
00157     {
00158         return mirror::mp::empty_range();
00159     }
00160 #endif
00161 public:
00163     template <typename MetaScope>
00164     meta_scope(MetaScope mo)
00165      : meta_object(mo)
00166      , meta_named_scoped_object(mo)
00167      , _members(static_members(mo, mirror::categorize_meta_object(mo)))
00168     { }
00169 
00171     range<meta_named_scoped_object> members(void) const
00172     {
00173         return _members.all();
00174     }
00175 };
00176 
00178 
00182 class meta_namespace
00183  : public meta_scope
00184 {
00185 private:
00186     range_holder<meta_namespace> _namespaces;
00187     range_holder<meta_free_variable> _free_variables;
00188     range_holder<meta_overloaded_functions> _free_functions;
00189 public:
00191     template <typename MetaNamespace>
00192     meta_namespace(MetaNamespace mo)
00193      : meta_object(mo)
00194      , meta_named_scoped_object(mo)
00195      , meta_scope(mo)
00196      , _namespaces(mirror::namespaces<MetaNamespace>())
00197      , _free_variables(mirror::free_variables<MetaNamespace>())
00198      , _free_functions(mirror::free_functions<MetaNamespace>())
00199     { }
00200 
00202     range<meta_namespace> namespaces(void) const
00203     {
00204         return _namespaces.all();
00205     }
00206 
00208     range<meta_free_variable> free_variables(void) const
00209     {
00210         return _free_variables.all();
00211     }
00212 
00214     range<meta_overloaded_functions> free_functions(void) const
00215     {
00216         return _free_functions.all();
00217     }
00218 };
00219 
00221 
00225 class meta_global_scope
00226  : public meta_namespace
00227 {
00228 private:
00229 public:
00231     template <typename MetaGlobalScope>
00232     meta_global_scope(MetaGlobalScope mo)
00233      : meta_object(mo)
00234      , meta_named_scoped_object(mo)
00235      , meta_namespace(mo)
00236     { }
00237 };
00238 
00240 
00244 class meta_type
00245  : virtual public meta_named_scoped_object
00246 {
00247 private:
00248     const std::type_info& _type_id;
00249 
00250     template <typename T>
00251     static const std::size_t get_sizeof(std::false_type)
00252     {
00253         return sizeof(T);
00254     }
00255 
00256     template <typename T>
00257     static const std::size_t get_sizeof(std::true_type)
00258     {
00259         return 0;
00260     }
00261 
00262     template <typename T>
00263     static const std::size_t get_sizeof(void)
00264     {
00265         return get_sizeof<T>(
00266             typename std::is_void<T>::type()
00267         );
00268     }
00269 
00270     std::size_t _size_of;
00271 
00272     range_holder<meta_constructor> _constructors;
00273 
00274     range_holder<meta_container> _containers;
00275 
00276     template <typename T, typename B1, typename B2>
00277     static inline some create(B1, B2)
00278     {
00279         return some();
00280     }
00281 
00282     template <typename T>
00283     static inline some create(std::true_type, std::true_type)
00284     {
00285         return some();
00286         //return some(T());
00287     }
00288 
00289     template <typename OriginalType>
00290     static some call_create(void)
00291     {
00292         return create<OriginalType>(
00293             typename mirror::is_default_constructible<
00294                 OriginalType
00295             >::type(),
00296             typename mirror::is_copy_constructible<
00297                 OriginalType
00298             >::type()
00299         );
00300     }
00301 
00302     some (*_call_create)(void);
00303 
00304 #ifdef RUBBER_META_TYPE_OPERATIONS
00305     template <typename T>
00306     static void call_op(
00307         void(*operation_ptr)(void),
00308         some& value,
00309         some& context,
00310         std::false_type
00311     )
00312     {
00313         if(operation_ptr)
00314         {
00315             assert(!value.empty());
00316             typedef void(*operation_type)(T&, some&);
00317             operation_type operation = operation_type(operation_ptr);
00318             operation(some_cast<T>(value), context);
00319         }
00320     }
00321 
00322     template <typename T>
00323     static void call_op(
00324         void(*operation_ptr)(void),
00325         some& value,
00326         some& context,
00327         std::true_type
00328     )
00329     { }
00330 
00331     template <typename T>
00332     static void call_op(
00333         void(*operation_ptr)(void),
00334         some& value,
00335         some& context
00336     )
00337     {
00338         call_op<T>(
00339             operation_ptr,
00340             value,
00341             context,
00342             typename std::is_void<T>::type()
00343         );
00344     }
00345 
00346     void (*_call_op_mutating)(void(*)(void), some&, some&);
00347     void (*_call_op_const)(void(*)(void), some&, some&);
00348 
00349     struct ti_less_than
00350     {
00351         bool operator()(
00352             const std::type_info* a,
00353             const std::type_info* b
00354         ) const
00355         {
00356             return a->before(*b);
00357         }
00358     };
00359 
00360     typedef std::map<
00361         const std::type_info*,
00362         void(*)(void),
00363         ti_less_than
00364     > operation_map;
00365 
00366     operation_map mutating_operations, const_operations;
00367 
00368     void do_init_mutating_op(
00369         void(*raw_operation_ptr)(void),
00370         const std::type_info& tag
00371     )
00372     {
00373         mutating_operations[&tag] = raw_operation_ptr;
00374     }
00375 
00376     template <typename T>
00377     void do_init_op(
00378         void (*operation_ptr)(T&, some&),
00379         const std::type_info& tag,
00380         std::true_type
00381     )
00382     {
00383         typedef void(*raw)(void);
00384         do_init_mutating_op(raw(operation_ptr), tag);
00385     }
00386 
00387     void do_init_const_op(
00388         void(*raw_operation_ptr)(void),
00389         const std::type_info& tag
00390     )
00391     {
00392         const_operations[&tag] = raw_operation_ptr;
00393     }
00394 
00395     template <typename T>
00396     void do_init_op(
00397         void (*operation_ptr)(const T&, some&),
00398         const std::type_info& tag,
00399         std::false_type
00400     )
00401     {
00402         typedef void(*raw)(void);
00403         do_init_const_op(raw(operation_ptr), tag);
00404     }
00405 
00406     template <typename Tag, typename T>
00407     void init_op(T*, std::true_type)
00408     {
00409         typename Tag::mutating is_mutating;
00410         do_init_op<T>(
00411             &Tag::apply,
00412             typeid(Tag),
00413             is_mutating
00414         );
00415     }
00416 
00417     template <typename Tag, typename T>
00418     void init_op(T*, std::false_type)
00419     { }
00420 
00421     template <typename T>
00422     struct operation_initializer
00423     {
00424         meta_type& that;
00425         T* selector;
00426 
00427         template <typename Op>
00428         void operator()(Op)
00429         {
00430             decltype(Op::available(*selector)) available;
00431             that.init_op<Op>(selector, available);
00432         }
00433     };
00434 
00435     template <typename T>
00436     void init_operations(T* _dummy)
00437     {
00438         operation_initializer<T> init = {*this, _dummy};
00439         mirror::mp::for_each<
00440             mirror::mp::range<
00441                 RUBBER_META_TYPE_OPERATIONS
00442             >
00443         >(init);
00444     }
00445 
00446     void init_operations(void*)
00447     { }
00448 #endif // RUBBER_META_TYPE_OPERATIONS
00449 public:
00451     template <typename MetaType>
00452     meta_type(MetaType mo)
00453      : meta_object(mo)
00454      , meta_named_scoped_object(mo)
00455      , _type_id(typeid(typename MetaType::original_type))
00456      , _size_of(get_sizeof<typename MetaType::original_type>())
00457      , _constructors(mirror::constructors<MetaType>())
00458      , _containers(mirror::containers<MetaType>())
00459      , _call_create(&call_create<typename MetaType::original_type>)
00460 #ifdef RUBBER_META_TYPE_OPERATIONS
00461      , _call_op_mutating(&call_op<typename MetaType::original_type>)
00462      , _call_op_const(&call_op<const typename MetaType::original_type>)
00463     {
00464         init_operations((typename MetaType::original_type*)nullptr);
00465     }
00466 #else  // no RUBBER_META_TYPE_OPERATIONS
00467     { }
00468 #endif // RUBBER_META_TYPE_OPERATIONS
00469 
00471     const std::type_info& typeid_(void) const
00472     {
00473         return _type_id;
00474     }
00475 
00477     std::size_t sizeof_(void) const
00478     {
00479         return _size_of;
00480     }
00481 
00483     range<meta_constructor> constructors(void) const
00484     {
00485         return _constructors.all();
00486     }
00487 
00489 
00493     some create(void) const
00494     {
00495         assert(_call_create != nullptr);
00496         return _call_create();
00497     }
00498 
00500     range<meta_container> containers(void) const
00501     {
00502         return _containers.all();
00503     }
00504 
00505 #ifdef RUBBER_META_TYPE_OPERATIONS
00506     //TODO: docs
00507     template <typename Tag>
00508     bool can_examine_by(void) const
00509     {
00510         return  const_operations.find(&typeid(Tag)) !=
00511             const_operations.end();
00512     }
00513 
00514     void examine_by(
00515         const std::type_info& tag,
00516         some& value,
00517         some& context
00518     ) const
00519     {
00520         assert(_call_op_const != nullptr);
00521         auto op = const_operations.find(&tag);
00522         _call_op_const(op->second, value, context);
00523     }
00524 
00525     template <typename Tag>
00526     void examine_by(some& value, some& context) const
00527     {
00528         examine_by(typeid(Tag), value, context);
00529     }
00530 
00531     template <typename Tag>
00532     void examine_by(some value) const
00533     {
00534         some context;
00535         examine_by(typeid(Tag), value, context);
00536     }
00537 
00538     template <typename Tag>
00539     bool can_modify_by(void) const
00540     {
00541         return  mutating_operations.find(&typeid(Tag)) !=
00542             mutating_operations.end();
00543     }
00544 
00545     void modify_by(
00546         const std::type_info& tag,
00547         some& value,
00548         some& context
00549     )
00550     {
00551         assert(_call_op_mutating != nullptr);
00552         auto op = mutating_operations.find(&tag);
00553         _call_op_mutating(op->second, value, context);
00554     }
00555 
00556     template <typename Tag>
00557     void modify_by(some& value, some& context)
00558     {
00559         modify_by(typeid(Tag), value, context);
00560     }
00561 
00562     template <typename Tag>
00563     void modify_by(some& value)
00564     {
00565         some context;
00566         modify_by(typeid(Tag), value, context);
00567     }
00568 #endif // RUBBER_META_TYPE_OPERATIONS
00569 };
00570 
00572 
00576 class meta_typedef
00577  : public meta_type
00578 {
00579 private:
00580     aux::return_value<meta_type>::type (*_get_type)(void);
00581 public:
00583     template <typename MetaTypedef>
00584     meta_typedef(MetaTypedef mo)
00585      : meta_object(mo)
00586      , meta_named_scoped_object(mo)
00587      , meta_type(mo)
00588      , _get_type(
00589         &wrap_shaped<
00590             typename MetaTypedef::type,
00591             meta_type
00592         >
00593     )
00594     { }
00595 
00596 #ifdef MIRROR_DOCUMENTATION_ONLY
00597 
00598     meta_type type(void) const;
00599 #else
00600     inline aux::return_value<meta_type>::type type(void) const;
00601 #endif
00602 };
00603 
00605 
00609 class meta_type_template
00610  : public meta_named_scoped_object
00611 {
00612 private:
00613 public:
00615     template <typename MetaTypeTemplate>
00616     meta_type_template(MetaTypeTemplate mo)
00617      : meta_object(mo)
00618      , meta_named_scoped_object(mo)
00619     { }
00620 
00621     // TODO
00622 };
00623 
00625 
00629 class meta_templated_type
00630  : virtual public meta_type
00631 {
00632 private:
00633     aux::return_value<meta_type_template>::type (*_get_type_template)(void);
00634 public:
00636     template <typename MetaTemplatedType>
00637     meta_templated_type(MetaTemplatedType mo)
00638      : meta_object(mo)
00639      , meta_named_scoped_object(mo)
00640      , meta_type(mo)
00641      , _get_type_template(
00642         &wrap_shaped<
00643             typename MetaTemplatedType::type_template,
00644             meta_type_template
00645         >
00646     )
00647     { }
00648 
00649 #ifdef MIRROR_DOCUMENTATION_ONLY
00650 
00651     meta_type_template type_template(void) const;
00652 #else
00653     aux::return_value<meta_type_template>::type type_template(void) const;
00654 #endif
00655 };
00656 
00658 
00662 class meta_class
00663  : virtual public meta_type
00664  , public meta_scope
00665 {
00666 private:
00667     specifier _elaborated_type;
00668     range_holder<meta_inheritance> _base_classes;
00669     range_holder<meta_class> _class_layout;
00670     range_holder<meta_member_variable> _member_variables;
00671     range_holder<meta_member_variable> _all_member_variables;
00672     range_holder<meta_member_function> _member_functions;
00673     range_holder<meta_container> _all_containers;
00674 public:
00676     template <typename MetaClass>
00677     meta_class(MetaClass mo)
00678      : meta_object(mo)
00679      , meta_named_scoped_object(mo)
00680      , meta_type(mo)
00681      , meta_scope(mo)
00682      , _elaborated_type(typename MetaClass::elaborated_type())
00683      , _base_classes(mirror::base_classes<MetaClass>())
00684      , _class_layout(mirror::class_layout<MetaClass>())
00685      , _member_variables(mirror::member_variables<MetaClass>())
00686      , _all_member_variables(mirror::all_member_variables<MetaClass>())
00687      , _member_functions(mirror::member_functions<MetaClass>())
00688      , _all_containers(mirror::all_containers<MetaClass>())
00689     { }
00690 
00692     const specifier& elaborated_type(void) const
00693     {
00694         return _elaborated_type;
00695     }
00696 
00698     range<meta_inheritance> base_classes(void) const
00699     {
00700         return _base_classes.all();
00701     }
00702 
00703     range<meta_class> class_layout(void) const
00704     {
00705         return _class_layout.all();
00706     }
00707 
00709     range<meta_member_variable> member_variables(void) const
00710     {
00711         return _member_variables.all();
00712     }
00713 
00715     range<meta_member_variable> all_member_variables(void) const
00716     {
00717         return _all_member_variables.all();
00718     }
00719 
00721     range<meta_member_function> member_functions(void) const
00722     {
00723         return _member_functions.all();
00724     }
00725 
00727     range<meta_container> all_containers(void) const
00728     {
00729         return _all_containers.all();
00730     }
00731 };
00732 
00734 
00738 struct meta_templated_class
00739  : public meta_templated_type
00740  , public meta_class
00741 {
00742 private:
00743 public:
00745     template <typename MetaTemplatedClass>
00746     meta_templated_class(MetaTemplatedClass mo)
00747      : meta_object(mo)
00748      , meta_named_scoped_object(mo)
00749      , meta_type(mo)
00750      , meta_templated_type(mo)
00751      , meta_class(mo)
00752     { }
00753 };
00754 
00756 
00760 class meta_inheritance
00761  : virtual public meta_object
00762 {
00763 private:
00764     specifier _inheritance_type;
00765     specifier _access_type;
00766     aux::return_value<meta_class>::type (*_get_base_class)(void);
00767     aux::return_value<meta_class>::type (*_get_derived_class)(void);
00768 public:
00770     template <typename MetaInheritance>
00771     meta_inheritance(MetaInheritance mo)
00772      : meta_object(mo)
00773      , _inheritance_type(typename MetaInheritance::inheritance_type())
00774      , _access_type(typename MetaInheritance::access_type())
00775      , _get_base_class(
00776         &wrap_shaped<
00777             typename MetaInheritance::base_class,
00778             meta_class
00779         >
00780     ), _get_derived_class(
00781         &wrap_shaped<
00782             typename MetaInheritance::derived_class,
00783             meta_class
00784         >
00785     )
00786     { }
00787 
00789     const specifier& inheritance_type(void) const
00790     {
00791         return _inheritance_type;
00792     }
00793 
00795     const specifier& access_type(void) const
00796     {
00797         return _access_type;
00798     }
00799 
00800 #ifdef MIRROR_DOCUMENTATION_ONLY
00801 
00802     meta_class base_class(void) const;
00803 #else
00804     inline aux::return_value<meta_class>::type base_class(void) const;
00805 #endif
00806 
00807 #ifdef MIRROR_DOCUMENTATION_ONLY
00808 
00809     meta_class derived_class(void) const;
00810 #else
00811     inline aux::return_value<meta_class>::type derived_class(void) const;
00812 #endif
00813 };
00814 
00816 
00820 class meta_enum_value
00821  : public meta_named_scoped_object
00822 {
00823 private:
00824     typedef long long value_type;
00825     value_type _value;
00826 public:
00828     template <typename MetaEnumValue>
00829     meta_enum_value(MetaEnumValue mo)
00830      : meta_object(mo)
00831      , meta_named_scoped_object(mo)
00832      , _value(value_type(MetaEnumValue::value::value))
00833     { }
00834 
00836     value_type value(void) const
00837     {
00838         return _value;
00839     }
00840 };
00841 
00843 
00847 class meta_enum
00848  : public meta_type
00849  , public meta_scope
00850 {
00851 private:
00852     int _size;
00853     range_holder<meta_enum_value> _enum_values;
00854 
00855     typedef long long value_type;
00856 
00857     template <typename MetaEnum>
00858     static value_type get_value(int index)
00859     {
00860         return value_type(MetaEnum::value(index));
00861     }
00862 
00863     value_type (*_get_value)(int);
00864     std::string (*_get_value_name)(int);
00865 
00866     template <typename MetaEnum>
00867     static std::string get_name_by_value(value_type value)
00868     {
00869         return MetaEnum::name_by_value(
00870             typename MetaEnum::original_type(value)
00871         );
00872     }
00873 
00874     std::string (*_get_name_by_value)(value_type);
00875 
00876     template <typename MetaEnum>
00877     static value_type get_value_by_name(const std::string& name)
00878     {
00879         return value_type(MetaEnum::value_by_name(name));
00880     }
00881 
00882     value_type (*_get_value_by_name)(const std::string&);
00883     bool (*_get_has_value_name)(const std::string&);
00884 public:
00886     template <typename MetaEnum>
00887     meta_enum(MetaEnum mo)
00888      : meta_object(mo)
00889      , meta_named_scoped_object(mo)
00890      , meta_type(mo)
00891      , meta_scope(mo)
00892      , _size(MetaEnum::size::value)
00893      , _enum_values(mirror::enum_values<MetaEnum>())
00894      , _get_value(&get_value<MetaEnum>)
00895      , _get_value_name(&MetaEnum::value_name)
00896      , _get_name_by_value(&get_name_by_value<MetaEnum>)
00897      , _get_value_by_name(&get_value_by_name<MetaEnum>)
00898      , _get_has_value_name(&MetaEnum::has_value_name)
00899     { }
00900 
00902     int size(void) const
00903     {
00904         return _size;
00905     }
00906 
00908     range<meta_enum_value> enum_values(void) const
00909     {
00910         return _enum_values.all();
00911     }
00912 
00914     value_type value(int index) const
00915     {
00916         assert(_get_value != nullptr);
00917         return _get_value(index);
00918     }
00919 
00921     std::string value_name(int index) const
00922     {
00923         assert(_get_value_name != nullptr);
00924         return _get_value_name(index);
00925     }
00926 
00928     std::string name_by_value(value_type value) const
00929     {
00930         assert(_get_name_by_value!= nullptr);
00931         return _get_name_by_value(value);
00932     }
00933 
00935     value_type value_by_name(const std::string& name) const
00936     {
00937         assert(_get_value_by_name != nullptr);
00938         return _get_value_by_name(name);
00939     }
00940 
00942     bool has_value_name(const std::string& name) const
00943     {
00944         assert(_get_has_value_name != nullptr);
00945         return _get_has_value_name(name);
00946     }
00947 };
00948 
00950 
00954 class meta_class_member
00955  : public meta_named_scoped_object
00956 {
00957 private:
00958     specifier _access_type;
00959 public:
00961     template <typename MetaClassMember>
00962     meta_class_member(MetaClassMember mo)
00963      : meta_object(mo)
00964      , meta_named_scoped_object(mo)
00965      , _access_type(typename MetaClassMember::access_type())
00966     { }
00967 
00969     const specifier& access_type(void) const
00970     {
00971         return _access_type;
00972     }
00973 
00974 };
00975 
00977 
00981 class meta_variable
00982  : virtual public meta_named_scoped_object
00983 {
00984 private:
00985     specifier _storage_class;
00986     aux::return_value<meta_type>::type (*_get_type)(void);
00987 public:
00989     template <typename MetaVariable>
00990     meta_variable(MetaVariable mo)
00991      : meta_object(mo)
00992      , meta_named_scoped_object(mo)
00993      , _storage_class(typename MetaVariable::storage_class())
00994      , _get_type(
00995         &wrap_shaped<
00996             typename MetaVariable::type,
00997             meta_type
00998         >
00999     )
01000     { }
01001 
01003     const specifier& storage_class(void) const
01004     {
01005         return _storage_class;
01006     }
01007 
01008 #ifdef MIRROR_DOCUMENTATION_ONLY
01009 
01010     meta_type type(void) const;
01011 #else
01012     inline aux::return_value<meta_type>::type type(void) const;
01013 #endif
01014 };
01015 
01017 
01021 class meta_plain_variable
01022  : virtual public meta_variable
01023 {
01024 public:
01026     template <typename MetaPlainVariable>
01027     meta_plain_variable(MetaPlainVariable mo)
01028      : meta_object(mo)
01029      , meta_named_scoped_object(mo)
01030      , meta_variable(mo)
01031     { }
01032 };
01033 
01035 
01039 class meta_free_variable
01040  : virtual public meta_variable
01041 {
01042 private:
01043     template <typename MetaFreeVariable>
01044     static some call_get(void)
01045     {
01046         return some(
01047             MetaFreeVariable::get(),
01048             typename mirror::mp::is_a<
01049                 MetaFreeVariable,
01050                 mirror::meta_plain_variable_tag
01051             >::type()
01052         );
01053     }
01054 
01055     some (*_call_get)(void);
01056 
01057     template <typename MetaFreeVariable>
01058     static void call_set(const some& value)
01059     {
01060         typedef typename MetaFreeVariable::type::original_type type;
01061         MetaFreeVariable::set(some_cast<const type>(value));
01062     }
01063 
01064     void (*_call_set)(const some&);
01065 public:
01067     template <typename MetaFreeVariable>
01068     meta_free_variable(MetaFreeVariable mo)
01069      : meta_object(mo)
01070      , meta_named_scoped_object(mo)
01071      , meta_variable(mo)
01072      , _call_get(&call_get<MetaFreeVariable>)
01073      , _call_set(&call_set<MetaFreeVariable>)
01074     { }
01075 
01077     some get(void) const
01078     {
01079         assert(_call_get != nullptr);
01080         return _call_get();
01081     }
01082 
01084     void set(const some& value) const
01085     {
01086         assert(_call_set != nullptr);
01087         _call_set(value);
01088     }
01089 };
01090 
01092 
01096 class meta_plain_free_variable
01097  : public meta_free_variable
01098  , public meta_plain_variable
01099 {
01100 private:
01101     template <typename MetaPlainFreeVariable>
01102     static raw_ptr call_address(void)
01103     {
01104         return raw_ptr(MetaPlainFreeVariable::address());
01105     }
01106 
01107     raw_ptr (*_call_address)(void);
01108 public:
01110     template <typename MetaPlainFreeVariable>
01111     meta_plain_free_variable(MetaPlainFreeVariable mo)
01112      : meta_object(mo)
01113      , meta_named_scoped_object(mo)
01114      , meta_variable(mo)
01115      , meta_free_variable(mo)
01116      , meta_plain_variable(mo)
01117      , _call_address(&call_address<MetaPlainFreeVariable>)
01118     { }
01119 
01121     raw_ptr address(void) const
01122     {
01123         assert(_call_address != nullptr);
01124         return _call_address();
01125     }
01126 };
01127 
01129 
01133 class meta_member_variable
01134  : virtual public meta_variable
01135  , public meta_class_member
01136 {
01137 private:
01138     template <typename MetaMemberVariable>
01139     static some call_get(const some& parent)
01140     {
01141         typedef typename MetaMemberVariable::scope::original_type
01142             parent_t;
01143         return some(
01144             MetaMemberVariable::get(
01145                 some_cast<const parent_t>(parent)
01146             ),
01147             typename mirror::mp::is_a<
01148                 MetaMemberVariable,
01149                 mirror::meta_plain_variable_tag
01150             >::type()
01151         );
01152     }
01153 
01154     some (*_call_get)(const some& parent);
01155 
01156     template <typename MetaMemberVariable>
01157     static void call_set(some& parent, const some& value)
01158     {
01159         typedef typename MetaMemberVariable::scope::original_type
01160             parent_t;
01161         typedef typename MetaMemberVariable::type::original_type type;
01162         MetaMemberVariable::set(
01163             some_cast<parent_t>(parent),
01164             some_cast<const type>(value)
01165         );
01166     }
01167 
01168     void (*_call_set)(some&, const some&);
01169 public:
01171     template <typename MetaMemberVariable>
01172     meta_member_variable(MetaMemberVariable mo)
01173      : meta_object(mo)
01174      , meta_named_scoped_object(mo)
01175      , meta_variable(mo)
01176      , meta_class_member(mo)
01177      , _call_get(&call_get<MetaMemberVariable>)
01178      , _call_set(&call_set<MetaMemberVariable>)
01179     { }
01180 
01182     some get(const some& parent) const
01183     {
01184         assert(_call_get != nullptr);
01185         return _call_get(parent);
01186     }
01187 
01189     void set(some& parent, const some& value) const
01190     {
01191         assert(_call_set != nullptr);
01192         _call_set(parent, value);
01193     }
01194 };
01195 
01197 
01201 class meta_plain_member_variable
01202  : public meta_member_variable
01203  , public meta_plain_variable
01204 {
01205 private:
01206     template <typename MetaPlainMemberVariable>
01207     static raw_ptr call_address(some& parent)
01208     {
01209         typedef typename MetaPlainMemberVariable::scope::original_type
01210             parent_t;
01211         return raw_ptr(
01212             MetaPlainMemberVariable::address(
01213                 some_cast<parent_t>(parent)
01214             )
01215         );
01216     }
01217 
01218     raw_ptr (*_call_address)(some&);
01219 public:
01221     template <typename MetaPlainMemberVariable>
01222     meta_plain_member_variable(MetaPlainMemberVariable mo)
01223      : meta_object(mo)
01224      , meta_named_scoped_object(mo)
01225      , meta_variable(mo)
01226      , meta_member_variable(mo)
01227      , meta_plain_variable(mo)
01228      , _call_address(&call_address<MetaPlainMemberVariable>)
01229     { }
01230 
01232     raw_ptr address(some& parent) const
01233     {
01234         assert(_call_address != nullptr);
01235         return _call_address(parent);
01236     }
01237 };
01238 
01240 
01244 class meta_parameter
01245  : public meta_variable
01246 {
01247 private:
01248     int _position;
01249 public:
01251     template <typename MetaParameter>
01252     meta_parameter(MetaParameter mo)
01253      : meta_object(mo)
01254      , meta_named_scoped_object(mo)
01255      , meta_variable(mo)
01256      , _position(MetaParameter::position::value)
01257     { }
01258 
01260     int position(void) const
01261     {
01262         return _position;
01263     }
01264 };
01265 
01267 
01271 class meta_function
01272  : public meta_scope
01273 {
01274 private:
01275     aux::return_value<meta_type>::type (*_get_result_type)(void);
01276     range_holder<meta_parameter> _parameters;
01277 public:
01279     template <typename MetaFunction>
01280     meta_function(MetaFunction mo)
01281      : meta_object(mo)
01282      , meta_named_scoped_object(mo)
01283      , meta_scope(mo)
01284      , _get_result_type(
01285         &wrap_shaped<
01286             typename MetaFunction::result_type,
01287             meta_type
01288         >
01289     ), _parameters(mirror::parameters<MetaFunction>())
01290     { }
01291 
01292 #ifdef MIRROR_DOCUMENTATION_ONLY
01293 
01294     meta_type result_type(void) const;
01295 #else
01296     inline aux::return_value<meta_type>::type result_type(void) const;
01297 #endif
01298 
01300     range<meta_parameter> parameters(void) const
01301     {
01302         return _parameters.all();
01303     }
01304 };
01305 
01307 
01311 class meta_constructor
01312  : public meta_function
01313  , public meta_class_member
01314 {
01315 private:
01316 public:
01318     template <typename MetaConstructor>
01319     meta_constructor(MetaConstructor mo)
01320      : meta_object(mo)
01321      , meta_named_scoped_object(mo)
01322      , meta_function(mo)
01323      , meta_class_member(mo)
01324     { }
01325 };
01326 
01328 
01332 class meta_overloaded_functions
01333  : public meta_named_scoped_object
01334 {
01335 private:
01336     range_holder<meta_function> _overloads;
01337 public:
01339     template <typename MetaOverloadedFunctions>
01340     meta_overloaded_functions(MetaOverloadedFunctions mo)
01341      : meta_object(mo)
01342      , meta_named_scoped_object(mo)
01343      , _overloads(mirror::overloads<MetaOverloadedFunctions>())
01344     { }
01345 
01347     range<meta_function> overloads(void) const
01348     {
01349         return _overloads.all();
01350     }
01351 };
01352 
01354 
01358 class meta_member_function
01359  : public meta_function
01360  , public meta_class_member
01361 {
01362 private:
01363     specifier _storage_class;
01364     specifier _constness;
01365 public:
01367     template <typename MetaMemberFunction>
01368     meta_member_function(MetaMemberFunction mo)
01369      : meta_object(mo)
01370      , meta_named_scoped_object(mo)
01371      , meta_function(mo)
01372      , meta_class_member(mo)
01373      , _storage_class(typename MetaMemberFunction::storage_class())
01374      , _constness(typename MetaMemberFunction::constness())
01375     { }
01376 
01378     const specifier& storage_class(void) const
01379     {
01380         return _storage_class;
01381     }
01382 
01384     const specifier& linkage(void) const
01385     {
01386         return _storage_class;
01387     }
01388 
01390     const specifier& constness(void) const
01391     {
01392         return _constness;
01393     }
01394 };
01395 
01397 
01401 class meta_traversal
01402  : public meta_named_object
01403 {
01404 private:
01405 public:
01407     template <typename MetaTraversal>
01408     meta_traversal(MetaTraversal mo)
01409      : meta_object(mo)
01410      , meta_named_object(mo)
01411     { }
01412 
01413     // TODO signature + start
01414 };
01415 
01417 
01421 class meta_locator
01422  : public meta_named_object
01423 {
01424 private:
01425 public:
01427     template <typename MetaLocator>
01428     meta_locator(MetaLocator mo)
01429      : meta_object(mo)
01430      , meta_named_object(mo)
01431     { }
01432 
01433     // TODO signature + go_to
01434 };
01435 
01437 
01441 class meta_inserter
01442  : public meta_named_object
01443 {
01444 private:
01445 public:
01447     template <typename MetaInserter>
01448     meta_inserter(MetaInserter mo)
01449      : meta_object(mo)
01450      , meta_named_object(mo)
01451     { }
01452 
01453     // TODO signature + insert
01454 };
01455 
01457 
01461 class meta_eraser
01462  : public meta_named_object
01463 {
01464 private:
01465 public:
01467     template <typename MetaEraser>
01468     meta_eraser(MetaEraser mo)
01469      : meta_object(mo)
01470      , meta_named_object(mo)
01471     { }
01472 
01473     // TODO signature + erase
01474 };
01475 
01477 
01481 class meta_container
01482  : public meta_scoped_object
01483 {
01484 private:
01485     aux::return_value<meta_type>::type (*_get_element_type)(void);
01486 
01487     aux::return_value<meta_traversal>::type (*_get_default_traversal)(void);
01488 
01489     range_holder<meta_traversal> _traversals;
01490     range_holder<meta_locator> _locators;
01491     range_holder<meta_inserter> _inserters;
01492     range_holder<meta_eraser> _erasers;
01493 public:
01495     template <typename MetaContainer>
01496     meta_container(MetaContainer mo)
01497      : meta_object(mo)
01498      , meta_scoped_object(mo)
01499      , _get_element_type(
01500         &wrap_shaped<
01501             typename MetaContainer::element_type,
01502             meta_type
01503         >
01504     ), _get_default_traversal(
01505         &wrap_shaped<
01506             typename MetaContainer::default_traversal,
01507             meta_traversal
01508         >
01509     ), _traversals(mirror::traversals<MetaContainer>())
01510      , _locators(mirror::locators<MetaContainer>())
01511      , _inserters(mirror::inserters<MetaContainer>())
01512      , _erasers(mirror::erasers<MetaContainer>())
01513     { }
01514 
01515 #ifdef MIRROR_DOCUMENTATION_ONLY
01516 
01517     meta_type element_type(void) const;
01518 #else
01519     inline aux::return_value<meta_type>::type element_type(void) const;
01520 #endif
01521 
01522 #ifdef MIRROR_DOCUMENTATION_ONLY
01523 
01524     meta_traversal default_traversal(void) const;
01525 #else
01526     aux::return_value<meta_traversal>::type default_traversal(void) const
01527     {
01528         assert(_get_default_traversal != nullptr);
01529         return _get_default_traversal();
01530     }
01531 #endif
01532 
01534     range<meta_traversal> traversals(void) const
01535     {
01536         return _traversals.all();
01537     }
01538 
01540     range<meta_locator> locators(void) const
01541     {
01542         return _locators.all();
01543     }
01544 
01546     range<meta_inserter> inserters(void) const
01547     {
01548         return _inserters.all();
01549     }
01550 
01552     range<meta_eraser> erasers(void) const
01553     {
01554         return _erasers.all();
01555     }
01556 };
01557 
01558 aux::return_value<meta_scope>::type
01559 meta_scoped_object::scope(void) const
01560 {
01561     assert(_get_scope != nullptr);
01562     return _get_scope();
01563 }
01564 
01565 
01566 aux::return_value<meta_type>::type
01567 meta_typedef::type(void) const
01568 {
01569     assert(_get_type != nullptr);
01570     return _get_type();
01571 }
01572 
01573 aux::return_value<meta_type_template>::type
01574 meta_templated_type::type_template(void) const
01575 {
01576     assert(_get_type_template != nullptr);
01577     return _get_type_template();
01578 }
01579 
01580 aux::return_value<meta_class>::type
01581 meta_inheritance::base_class(void) const
01582 {
01583     assert(_get_base_class != nullptr);
01584     return _get_base_class();
01585 }
01586 
01587 aux::return_value<meta_class>::type
01588 meta_inheritance::derived_class(void) const
01589 {
01590     assert(_get_derived_class != nullptr);
01591     return _get_derived_class();
01592 }
01593 
01594 aux::return_value<meta_type>::type
01595 meta_variable::type(void) const
01596 {
01597     assert(_get_type != nullptr);
01598     return _get_type();
01599 }
01600 
01601 aux::return_value<meta_type>::type
01602 meta_function::result_type(void) const
01603 {
01604     assert(_get_result_type != nullptr);
01605     return _get_result_type();
01606 }
01607 
01608 aux::return_value<meta_type>::type
01609 meta_container::element_type(void) const
01610 {
01611     assert(_get_element_type != nullptr);
01612     return _get_element_type();
01613 }
01614 
01615 RUBBER_NAMESPACE_END
01616 
01617 #endif //include guard
01618 

Copyright © 2006-2011 Matus Chochlik, University of Zilina, Zilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Fri Dec 16 2011 by Doxygen (version 1.7.3).
Important note: Although the 'boostified' version of Mirror uses the Boost C++ libraries Coding Guidelines and is implemented inside of the boost namespace, it IS NOT an officially reviewed and accepted Boost library. Mirror is being developed with the intention to be submitted for review for inclusion to the Boost C++ libraries.