source: trunk/nv/types.hh @ 112

Last change on this file since 112 was 112, checked in by epyon, 12 years ago
  • LLVM C++ fixes part 2
File size: 10.9 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 <glm/glm.hpp>
9#include <nv/common.hh>
10#include <nv/object.hh>
11#include <type_traits>
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        enum datatype
23        {
24                INT,
25                BYTE,
26                SHORT,
27                UINT,
28                UBYTE,
29                USHORT,
30                FLOAT,
31                FLOAT_VECTOR_2,
32                FLOAT_VECTOR_3,
33                FLOAT_VECTOR_4,
34                FLOAT_MATRIX_2,
35                FLOAT_MATRIX_3,
36                FLOAT_MATRIX_4,
37                INT_VECTOR_2,
38                INT_VECTOR_3,
39                INT_VECTOR_4,
40                // unsupported gl conversion, remove?
41                BYTE_VECTOR_2,
42                BYTE_VECTOR_3,
43                BYTE_VECTOR_4,
44        };
45
46        template <typename T>
47        struct datatype_traits
48        {
49                typedef T type;
50                typedef T base_type;
51                static const size_t size = 1;
52        };
53
54        template <typename T>
55        struct datatype_traits< glm::detail::tvec2<T> >
56        {
57                typedef glm::detail::tvec2<T> type;
58                typedef typename type::value_type base_type;
59                static const size_t size = 2;
60        };
61
62        template <typename T>
63        struct datatype_traits< glm::detail::tvec3<T> >
64        {
65                typedef glm::detail::tvec3<T> type;
66                typedef typename type::value_type base_type;
67                static const size_t size = 3;
68        };
69
70        template <typename T>
71        struct datatype_traits< glm::detail::tvec4<T> >
72        {
73                typedef glm::detail::tvec4<T> type;
74                typedef typename type::value_type base_type;
75                static const size_t size = 4;
76        };
77
78        typedef glm::detail::tvec2<sint8> i8vec2;
79        typedef glm::detail::tvec3<sint8> i8vec3;
80        typedef glm::detail::tvec4<sint8> i8vec4;
81
82        typedef glm::vec2 vec2;
83        typedef glm::vec3 vec3;
84        typedef glm::vec4 vec4;
85
86        typedef glm::ivec2 ivec2;
87        typedef glm::ivec3 ivec3;
88        typedef glm::ivec4 ivec4;
89
90        typedef glm::mat2 mat2;
91        typedef glm::mat3 mat3;
92        typedef glm::mat4 mat4;
93
94        template < datatype EnumType > struct enum_to_type {};
95
96        template <> struct enum_to_type< INT >   { typedef int type; };
97        template <> struct enum_to_type< UINT >  { typedef unsigned int type; };
98        template <> struct enum_to_type< SHORT > { typedef short type; };
99        template <> struct enum_to_type< USHORT >{ typedef unsigned short type; };
100        template <> struct enum_to_type< BYTE >  { typedef char type; };
101        template <> struct enum_to_type< UBYTE > { typedef unsigned char type; };
102        template <> struct enum_to_type< FLOAT > { typedef f32 type; };
103
104        template <> struct enum_to_type< FLOAT_VECTOR_2 > { typedef vec2 type; };
105        template <> struct enum_to_type< FLOAT_VECTOR_3 > { typedef vec3 type; };
106        template <> struct enum_to_type< FLOAT_VECTOR_4 > { typedef vec4 type; };
107
108        template <> struct enum_to_type< INT_VECTOR_2 > { typedef ivec2 type; };
109        template <> struct enum_to_type< INT_VECTOR_3 > { typedef ivec3 type; };
110        template <> struct enum_to_type< INT_VECTOR_4 > { typedef ivec4 type; };
111
112        template <> struct enum_to_type< BYTE_VECTOR_2 > { typedef i8vec2 type; };
113        template <> struct enum_to_type< BYTE_VECTOR_3 > { typedef i8vec3 type; };
114        template <> struct enum_to_type< BYTE_VECTOR_4 > { typedef i8vec4 type; };
115
116        template <> struct enum_to_type< FLOAT_MATRIX_2 > { typedef mat2 type; };
117        template <> struct enum_to_type< FLOAT_MATRIX_3 > { typedef mat3 type; };
118        template <> struct enum_to_type< FLOAT_MATRIX_4 > { typedef mat4 type; };
119
120        template < typename TYPE > struct type_to_enum {};
121
122        template <> struct type_to_enum< int >           { static const datatype type = INT; };
123        template <> struct type_to_enum< unsigned int >  { static const datatype type = UINT; };
124        template <> struct type_to_enum< short >         { static const datatype type = SHORT; };
125        template <> struct type_to_enum< unsigned short >{ static const datatype type = USHORT; };
126        template <> struct type_to_enum< char >          { static const datatype type = BYTE; };
127        template <> struct type_to_enum< signed char >   { static const datatype type = BYTE; };
128        template <> struct type_to_enum< unsigned char > { static const datatype type = UBYTE; };
129        template <> struct type_to_enum< f32 > { static const datatype type = FLOAT; };
130
131        template <> struct type_to_enum< vec2 > { static const datatype type = FLOAT_VECTOR_2; };
132        template <> struct type_to_enum< vec3 > { static const datatype type = FLOAT_VECTOR_3; };
133        template <> struct type_to_enum< vec4 > { static const datatype type = FLOAT_VECTOR_4; };
134
135        template <> struct type_to_enum< ivec2 > { static const datatype type = INT_VECTOR_2; };
136        template <> struct type_to_enum< ivec3 > { static const datatype type = INT_VECTOR_3; };
137        template <> struct type_to_enum< ivec4 > { static const datatype type = INT_VECTOR_4; };
138
139        template <> struct type_to_enum< i8vec2 > { static const datatype type = BYTE_VECTOR_2; };
140        template <> struct type_to_enum< i8vec3 > { static const datatype type = BYTE_VECTOR_3; };
141        template <> struct type_to_enum< i8vec4 > { static const datatype type = BYTE_VECTOR_4; };
142
143        template <> struct type_to_enum< mat2 > { static const datatype type = FLOAT_MATRIX_2; };
144        template <> struct type_to_enum< mat3 > { static const datatype type = FLOAT_MATRIX_3; };
145        template <> struct type_to_enum< mat4 > { static const datatype type = FLOAT_MATRIX_4; };
146
147        template<typename T>
148        struct is_container
149        {
150                private:
151                        typedef char                      yes;
152                        typedef struct { char array[2]; } no;
153                        template<typename C> static yes test(typename C::iterator*);
154                        template<typename C> static no  test(...);
155                public:
156                        static const bool value = sizeof(test<T>(0)) == sizeof(yes);
157        };
158
159        template<>
160        struct is_container< std::string > {
161                static const bool value = false;
162        };
163
164        template <typename TYPE> void ConstructObject(void* object)
165        {
166                // Use placement new to call the constructor
167                new (object) TYPE;
168        }
169        template <typename TYPE> void DestructObject(void* object)
170        {
171                // Explicit call of the destructor
172                ((TYPE*)object)->TYPE::~TYPE();
173        }
174   
175        struct type_entry;
176
177        enum type_flag
178        {
179                TF_POINTER      = 0x01, //< field is a pointer
180                TF_NOSERIALIZE  = 0x02, //< ignore during serialization
181                TF_INVISIBLE    = 0x04, //< field invisible to API
182                TF_READONLY     = 0x08, //< read only field
183                TF_SIMPLETYPE   = 0x10, //< raw binary I/O possible
184                TF_OWNED        = 0x20,
185                TF_CONTAINER    = 0x40, //< is a container
186        };
187
188        struct type_field
189        {
190                std::string      name;      //< name of the field
191                std::string      type_name; //< name of the type of the field
192                const std::type_info* type_inf;  //< typeinfo for later retrieval of type
193                type_entry*      type;      //< pointer to field type
194                unsigned int     flags;     //< flags
195                size_t           offset;
196
197                template< typename TOBJECT, typename TFIELD >
198                type_field( const char* name, TFIELD TOBJECT::*field, typename std::enable_if< is_container<TFIELD>::value, void* >::type = nullptr )
199                : name(name)
200                        , type_name()
201                        , type_inf( &typeid( std::remove_pointer<typename TFIELD::value_type>::type ) )
202                        , type( nullptr )
203                        , flags( 0 )
204                        , offset( offset_of( field ) )
205                {
206                        NV_LOG( LOG_INFO, name << "-" << offset);
207                        flags = TF_CONTAINER |
208                                ( std::is_pointer<typename TFIELD::value_type>::value ? TF_POINTER : 0 ) |
209                                ( std::is_pod<typename TFIELD::value_type>::value ? TF_SIMPLETYPE : 0 );
210                }
211
212                template< typename TOBJECT, typename TFIELD >
213                type_field( const char* name, TFIELD TOBJECT::*field, typename std::enable_if< !is_container<TFIELD>::value, void* >::type = nullptr )
214                : name(name)
215                        , type_name()
216                        , type_inf( &typeid( typename std::remove_pointer<TFIELD>::type ) )
217                        , type( nullptr )
218                        , flags( 0 )
219                        , offset( offset_of( field ) )
220                {
221                        NV_LOG( LOG_INFO, name << "-" << offset);
222                        flags =
223                                ( std::is_pointer<TFIELD>::value ? TF_POINTER : 0 ) |
224                                ( std::is_pod<TFIELD>::value ? TF_SIMPLETYPE : 0 );
225                }
226
227                type_field& flag( unsigned int f )
228                {
229                        flags |= f;
230                        return *this;
231                }
232        };
233
234        struct type_enum
235        {
236                std::string name;
237                int         value;
238                type_enum( const char* name, int value ) : name(name), value(value) {}
239        };
240
241        struct type_entry
242        {
243                // Function types for the constructor and destructor of registered types
244                typedef void (*constructor_func)(void*);
245                typedef void (*destructor_func)(void*);
246
247                // Parent type database
248                type_database* type_db;
249
250                // Scoped C++ name of the type
251                std::string name;
252
253                // Pointers to the constructor and destructor functions
254                constructor_func constructor;
255                destructor_func  destructor;
256
257                // Result of sizeof(type) operation
258                size_t size;
259
260                // Base type
261                type_entry* base_type;
262
263                // Field list
264                std::vector<type_field> field_list;
265
266                // Enum list
267                std::vector<type_enum> enum_list;
268
269                template <typename TYPE>
270                type_entry& base();
271
272                template <int SIZE>
273                type_entry& fields( type_field (&init_fields)[SIZE] );
274
275                template <int SIZE>
276                type_entry& enums( type_enum (&init_enums)[SIZE] )
277                {
278                        for (int i = 0; i < SIZE; i++)
279                        {
280                                enum_list.push_back( init_enums[i] );
281                        }
282                        return *this;
283                }
284        };
285
286        class type_database
287        {
288        public:
289                template< typename TYPE >
290                type_entry& create_type( const char* name )
291                {
292                        type_entry* i_type = nullptr;
293                        type_name_map::iterator it = m_name_types.find( name );
294                        if ( it != m_name_types.end() )
295                        {
296                                return *(it->second);
297                        }
298                        i_type          = new type_entry;
299                        i_type->type_db = this;
300                        i_type->name    = name;
301                        i_type->size    = sizeof(TYPE);
302
303                        i_type->constructor = ConstructObject<TYPE>;
304                        i_type->destructor  = DestructObject<TYPE>;
305
306                        m_name_types[name]        = i_type;
307                        m_idx_types[typeid(TYPE)] = i_type;
308                        return *i_type;
309                }
310
311                type_entry* get_type( const std::string name )
312                {
313                        type_name_map::iterator it = m_name_types.find( name );
314                        if ( it != m_name_types.end() )
315                        {
316                                return it->second;
317                        }
318                        return nullptr;
319                }
320
321                type_entry* get_type( const std::type_info& t )
322                {
323                        type_info_map::iterator it = m_idx_types.find( std::type_index(t) );
324                        if ( it != m_idx_types.end() )
325                        {
326                                return it->second;
327                        }
328                        return nullptr;
329                }
330        private:
331                struct compare_type_info {
332                        bool operator ()(const std::type_info* a, const std::type_info* b) const {
333                                return a->before(*b);
334                        }
335                };
336
337                typedef std::unordered_map<std::string, type_entry*>     type_name_map;
338                typedef std::unordered_map<std::type_index, type_entry*> type_info_map;
339                type_name_map m_name_types;
340                type_info_map m_idx_types;
341        };
342   
343    template < typename TYPE >
344    type_entry& type_entry::base()
345    {
346        base_type = type_db->get_type( typeid(TYPE) );
347    }
348   
349    template <int SIZE>
350    type_entry& type_entry::fields( type_field (&init_fields)[SIZE] )
351    {
352        for (int i = 0; i < SIZE; i++)
353        {
354            type_field f = init_fields[i];
355            f.type = type_db->get_type(*(f.type_inf));
356            f.type_name = f.type->name;
357            field_list.push_back(f);
358        }
359        return *this;
360    }
361
362}
363
364#endif
365
Note: See TracBrowser for help on using the repository browser.