source: trunk/nv/types.hh @ 214

Last change on this file since 214 was 214, checked in by epyon, 12 years ago
  • types - decomposition, math types go to math, type_traits related to type_traits
  • decoupling of the types.hh dependency from all possible places
File size: 5.5 KB
Line 
1// Copyright (C) 2012 Kornel Kisielewicz
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4
5#ifndef NV_TYPES_HH
6#define NV_TYPES_HH
7
8#include <nv/common.hh>
9#include <nv/math.hh>
10#include <nv/object.hh>
11#include <nv/type_traits.hh>
12#include <typeinfo>
13#include <typeindex>
14#include <utility>
15#include <unordered_map>
16#include <vector>
17#include <string>
18#include <cstddef>
19
20namespace nv
21{
22
23        struct type_entry;
24
25        enum type_flag
26        {
27                TF_POINTER      = 0x01, //!< field is a pointer
28                TF_NOSERIALIZE  = 0x02, //!< ignore during serialization
29                TF_INVISIBLE    = 0x04, //!< field invisible to API
30                TF_READONLY     = 0x08, //!< read only field
31                TF_SIMPLETYPE   = 0x10, //!< raw binary I/O possible
32                TF_OWNED        = 0x20,
33                TF_CONTAINER    = 0x40, //!< is a container
34        };
35
36        struct type_field
37        {
38                std::string      name;          //!< name of the field
39                std::string      type_name;     //!< name of the type of the field
40                const std::type_info* type_inf; //!< typeinfo for later retrieval of type
41                type_entry*      type;          //!< pointer to field type
42                unsigned int     flags;         //!< flags
43                size_t           offset;
44
45                template< typename TOBJECT, typename TFIELD >
46                type_field( const char* aname, TFIELD TOBJECT::*field, typename std::enable_if< is_container<TFIELD>::value, void* >::type = nullptr )
47                : name(aname)
48                        , type_name()
49                        , type_inf( &typeid( typename std::remove_pointer<typename TFIELD::value_type>::type ) )
50                        , type( nullptr )
51                        , flags( 0 )
52                        , offset( offset_of( field ) )
53                {
54                        NV_LOG( LOG_INFO, aname << "-" << offset);
55                        flags = TF_CONTAINER |
56                                ( std::is_pointer<typename TFIELD::value_type>::value ? TF_POINTER : 0 ) |
57                                ( std::is_pod<typename TFIELD::value_type>::value ? TF_SIMPLETYPE : 0 );
58                }
59
60                template< typename TOBJECT, typename TFIELD >
61                type_field( const char* aname, TFIELD TOBJECT::*field, typename std::enable_if< !is_container<TFIELD>::value, void* >::type = nullptr )
62                : name(aname)
63                        , type_name()
64                        , type_inf( &typeid( typename std::remove_pointer<TFIELD>::type ) )
65                        , type( nullptr )
66                        , flags( 0 )
67                        , offset( offset_of( field ) )
68                {
69                        NV_LOG( LOG_INFO, aname << "-" << offset);
70                        flags =
71                                ( std::is_pointer<TFIELD>::value ? TF_POINTER : 0 ) |
72                                ( std::is_pod<TFIELD>::value ? TF_SIMPLETYPE : 0 );
73                }
74
75                type_field& flag( unsigned int f )
76                {
77                        flags |= f;
78                        return *this;
79                }
80        };
81
82        struct type_enum
83        {
84                std::string name;
85                int         value;
86                type_enum( const char* aname, int avalue ) : name(aname), value(avalue) {}
87        };
88
89        struct type_entry
90        {
91                // Function types for the constructor and destructor of registered types
92                typedef void (*constructor_func)(void*);
93                typedef void (*destructor_func)(void*);
94
95                // Parent type database
96                type_database* type_db;
97
98                // Scoped C++ name of the type
99                std::string name;
100
101                // Pointers to the constructor and destructor functions
102                constructor_func constructor;
103                destructor_func  destructor;
104
105                // Result of sizeof(type) operation
106                size_t size;
107
108                // Base type
109                type_entry* base_type;
110
111                // Field list
112                std::vector<type_field> field_list;
113
114                // Enum list
115                std::vector<type_enum> enum_list;
116
117                template <typename TYPE>
118                type_entry& base();
119
120                template <int SIZE>
121                type_entry& fields( type_field (&init_fields)[SIZE] );
122
123                template <int SIZE>
124                type_entry& enums( type_enum (&init_enums)[SIZE] )
125                {
126                        for (int i = 0; i < SIZE; i++)
127                        {
128                                enum_list.push_back( init_enums[i] );
129                        }
130                        return *this;
131                }
132        };
133
134        class type_database
135        {
136        public:
137                template< typename TYPE >
138                type_entry& create_type( const char* name )
139                {
140                        type_entry* i_type = nullptr;
141                        type_name_map::iterator it = m_name_types.find( name );
142                        if ( it != m_name_types.end() )
143                        {
144                                return *(it->second);
145                        }
146                        i_type          = new type_entry;
147                        i_type->type_db = this;
148                        i_type->name    = name;
149                        i_type->size    = sizeof(TYPE);
150
151                        i_type->constructor = construct_object<TYPE>;
152                        i_type->destructor  = destroy_object<TYPE>;
153
154                        m_name_types[name]        = i_type;
155                        m_idx_types[typeid(TYPE)] = i_type;
156                        return *i_type;
157                }
158
159                type_entry* get_type( const std::string name )
160                {
161                        type_name_map::iterator it = m_name_types.find( name );
162                        if ( it != m_name_types.end() )
163                        {
164                                return it->second;
165                        }
166                        return nullptr;
167                }
168
169                type_entry* get_type( const std::type_info& t )
170                {
171                        type_info_map::iterator it = m_idx_types.find( std::type_index(t) );
172                        if ( it != m_idx_types.end() )
173                        {
174                                return it->second;
175                        }
176                        return nullptr;
177                }
178        private:
179                struct compare_type_info {
180                        bool operator ()(const std::type_info* a, const std::type_info* b) const {
181                                return a->before(*b);
182                        }
183                };
184
185                typedef std::unordered_map<std::string, type_entry*>     type_name_map;
186                typedef std::unordered_map<std::type_index, type_entry*> type_info_map;
187                type_name_map m_name_types;
188                type_info_map m_idx_types;
189        };
190   
191    template < typename TYPE >
192    type_entry& type_entry::base()
193    {
194        base_type = type_db->get_type( typeid(TYPE) );
195                return *this;
196    }
197   
198    template <int SIZE>
199    type_entry& type_entry::fields( type_field (&init_fields)[SIZE] )
200    {
201        for (int i = 0; i < SIZE; i++)
202        {
203            type_field f = init_fields[i];
204            f.type = type_db->get_type(*(f.type_inf));
205            f.type_name = f.type->name;
206            field_list.push_back(f);
207        }
208        return *this;
209    }
210
211}
212
213#endif
214
Note: See TracBrowser for help on using the repository browser.