HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PlainOldDataType.h
Go to the documentation of this file.
1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2012,
4 // Sony Pictures Imageworks Inc. and
5 // Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // * Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // * Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // * Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic, nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36 
37 #ifndef _Alembic_Util_PlainOldDataType_h_
38 #define _Alembic_Util_PlainOldDataType_h_
39 
41 #include <Alembic/Util/Exception.h>
42 
43 // stdint.h is not in anything prior to Visual Studio 2010
44 #if !defined(_MSC_VER) || _MSC_VER >= 1600
45 #include <stdint.h>
46 #endif
47 
48 namespace Alembic {
49 namespace Util {
50 namespace ALEMBIC_VERSION_NS {
51 
52 //-*****************************************************************************
53 //! Bytes are unsigned chars, by definition.
54 //! We use bytes in Alembic as the name of anonymous storage memory, since
55 //! it is not possible to create arrays of voids.
56 typedef unsigned char byte_t;
57 
58 //-*****************************************************************************
59 //-*****************************************************************************
60 //! BOOLEAN BASE TYPE - since C++ doesn't explicitly demand that bool
61 //! be a given bit depth, but we need it to be here, we make our own
62 //! bool type, which is a bit silly. This is purely for storage reasons.
63 //-*****************************************************************************
64 class bool_t
65 {
66 public:
67  bool_t() : m_byte( 0 ) {}
68 
69  bool_t( bool tf ) : m_byte( static_cast<byte_t>( tf ) ) {}
70  bool_t( byte_t b ) : m_byte( b ) {}
71 
72 
73  //! Using default copy constructor
74  //! ...
75 
76  //! Using default assignment operator
77  //! ...
78 
79  bool_t& operator=( bool tf )
80  {
81  m_byte = static_cast<byte_t>( tf );
82  return *this;
83  }
84 
86  {
87  m_byte = b;
88  return *this;
89  }
90 
91  bool_t operator!( void )
92  {
93  return bool_t( m_byte == 0 );
94  }
95 
96  bool asBool() const { return ( m_byte != 0 ); }
97  operator bool() const { return ( m_byte != 0 ); }
98 
99 private:
100  byte_t m_byte;
101 };
102 
103 //-*****************************************************************************
104 inline bool operator==( const bool_t &a, const bool_t &b )
105 {
106  return a.asBool() == b.asBool();
107 }
108 
109 //-*****************************************************************************
110 inline bool operator==( const bool_t &a, bool b )
111 {
112  return a.asBool() == b;
113 }
114 
115 //-*****************************************************************************
116 inline bool operator==( bool a, const bool_t &b )
117 {
118  return a == b.asBool();
119 }
120 
121 //-*****************************************************************************
122 inline bool operator!=( const bool_t &a, const bool_t &b )
123 {
124  return a.asBool() != b.asBool();
125 }
126 
127 //-*****************************************************************************
128 inline bool operator!=( const bool_t &a, bool b )
129 {
130  return a.asBool() != b;
131 }
132 
133 //-*****************************************************************************
134 inline bool operator!=( bool a, const bool_t &b )
135 {
136  return a != b.asBool();
137 }
138 
139 #if !defined(_MSC_VER)
140 using ::uint8_t;
141 using ::int8_t;
142 using ::uint16_t;
143 using ::int16_t;
144 using ::uint32_t;
145 using ::int32_t;
146 using ::uint64_t;
147 using ::int64_t;
148 #else
149 typedef unsigned char uint8_t;
150 typedef signed char int8_t;
151 typedef unsigned short uint16_t;
152 typedef signed short int16_t;
153 typedef unsigned int uint32_t;
154 typedef int int32_t;
155 typedef unsigned long long uint64_t;
156 typedef long long int64_t;
157 #endif
158 
159 typedef half float16_t;
160 typedef float float32_t;
161 typedef double float64_t;
162 
163 //! Last, but not least, standard strings.
164 //! These are CLEARLY not "Plain Old Data Types", however, "strings" are
165 //! such ubiquitous components of programming, and without an enclosing
166 //! structure like std::string, they're so difficult to use from an API
167 //! point of view (call first time to find out length! allocate your own array!
168 //! call second time to get string value!), that I'm going to put my foot down
169 //! and say - from Alembic's point of view, std::string and std::wstring are
170 //! "Kinda Sorta POD types". Please pardon the abuse of the idiom.
171 using std::string;
172 using std::wstring;
173 
174 //-*****************************************************************************
175 //! I'm using explicit names here because the terms 'int', 'short', 'long', etc,
176 //! have different bit-depths on different machine architectures. To avoid
177 //! any ambiguity whatsoever, I'm just making these explicit. End users will
178 //! rarely see these anyway, so it's okay to be a bit pedantic.
179 //!
180 //! These are always represented in the endian-ness of the host machine when
181 //! resident in working memory, but need to have an explicit endian-ness when
182 //! being written out. That's hidden from the user by HDF5.
184 {
185  //! Booleans are difficult to store in arrays in a 'one bit per bool'
186  //! kind of way, so we actually file them as bytes (uint8). But again
187  //! this is entirely hidden from the end user. Implemented via the
188  //! "bool_t" type defined above.
190 
191  //! Char/UChar
194 
195  //! Short/UShort
198 
199  //! Int/UInt
202 
203  //! Long/ULong
206 
207  //! Half/Float/Double
211 
212  //! String Pointer
214 
215  //! Wide String Pointer
217 
218  //! Number of POD
220 
221  //! Unknown
223 };
224 
225 //-*****************************************************************************
226 //-*****************************************************************************
227 //-*****************************************************************************
228 // A little traits class that binds these things together.
229 //-*****************************************************************************
230 //-*****************************************************************************
231 //-*****************************************************************************
232 template <PlainOldDataType PODT, class T > struct PODTraits {};
233 
234 //-*****************************************************************************
235 //! Unfortunately, C++ only allows for static const declaration of constants
236 //! with integral types, not floating. Therefore, we have the whole
237 //! inlined static function for default values.
238 #define DECLARE_TRAITS( PENUM, PTYPE, PNAME, DFLT, PTDEF ) \
239 template <> \
240 struct PODTraits< PENUM , PTYPE > \
241 { \
242  static const PlainOldDataType pod_enum = PENUM ; \
243  typedef PTYPE value_type ; \
244  static const char * name() { return PNAME ; } \
245  static PTYPE default_value() \
246  { return ( DFLT ) ; } \
247  static size_t numBytes() \
248  { return sizeof( PTYPE ) ; } \
249 }; \
250 typedef PODTraits< PENUM , PTYPE > PTDEF
251 
252 //-*****************************************************************************
253 // Actual specialized traits
254 DECLARE_TRAITS( kBooleanPOD, bool_t, "bool_t", false, BooleanPODTraits );
255 DECLARE_TRAITS( kUint8POD, uint8_t, "uint8_t", 0, Uint8PODTraits );
256 DECLARE_TRAITS( kInt8POD, int8_t, "int8_t", 0, Int8PODTraits );
257 DECLARE_TRAITS( kUint16POD, uint16_t, "uint16_t", 0, Uint16PODTraits );
258 DECLARE_TRAITS( kInt16POD, int16_t, "int16_t", 0, Int16PODTraits );
259 DECLARE_TRAITS( kUint32POD, uint32_t, "uint32_t", 0, Uint32PODTraits );
260 DECLARE_TRAITS( kInt32POD, int32_t, "int32_t", 0, Int32PODTraits );
261 DECLARE_TRAITS( kUint64POD, uint64_t, "uint64_t", 0, Uint64PODTraits );
262 DECLARE_TRAITS( kInt64POD, int64_t, "int64_t", 0, Int64PODTraits );
263 DECLARE_TRAITS( kFloat16POD, float16_t, "float16_t", 0, Float16PODTraits );
264 DECLARE_TRAITS( kFloat32POD, float32_t, "float32_t", 0, Float32PODTraits );
265 DECLARE_TRAITS( kFloat64POD, float64_t, "float64_t", 0, Float64PODTraits );
266 DECLARE_TRAITS( kStringPOD, string, "string", "", StringPODTraits );
267 DECLARE_TRAITS( kWstringPOD, wstring, "wstring", L"", WstringPODTraits );
268 
269 #undef DECLARE_TRAITS
270 
271 //-*****************************************************************************
272 //-*****************************************************************************
273 // Okay, now tools for extracting POD Traits from enums and from types.
274 // No easy way to do it from a name.
275 //-*****************************************************************************
276 
277 //-*****************************************************************************
278 //-*****************************************************************************
279 // FROM ENUMS
280 //-*****************************************************************************
281 //-*****************************************************************************
282 template <PlainOldDataType PENUM>
284 
285 //-*****************************************************************************
286 // Actual specializations
287 template <> struct PODTraitsFromEnum<kBooleanPOD> : public BooleanPODTraits {};
288 template <> struct PODTraitsFromEnum<kUint8POD> : public Uint8PODTraits {};
289 template <> struct PODTraitsFromEnum<kInt8POD> : public Int8PODTraits {};
290 template <> struct PODTraitsFromEnum<kUint16POD> : public Uint16PODTraits {};
291 template <> struct PODTraitsFromEnum<kInt16POD> : public Int16PODTraits {};
292 template <> struct PODTraitsFromEnum<kUint32POD> : public Uint32PODTraits {};
293 template <> struct PODTraitsFromEnum<kInt32POD> : public Int32PODTraits {};
294 template <> struct PODTraitsFromEnum<kUint64POD> : public Uint64PODTraits {};
295 template <> struct PODTraitsFromEnum<kInt64POD> : public Int64PODTraits {};
296 template <> struct PODTraitsFromEnum<kFloat16POD> : public Float16PODTraits {};
297 template <> struct PODTraitsFromEnum<kFloat32POD> : public Float32PODTraits {};
298 template <> struct PODTraitsFromEnum<kFloat64POD> : public Float64PODTraits {};
299 template <> struct PODTraitsFromEnum<kStringPOD> : public StringPODTraits {};
300 template <> struct PODTraitsFromEnum<kWstringPOD> : public WstringPODTraits {};
301 
302 //-*****************************************************************************
303 //-*****************************************************************************
304 // FROM TYPES
305 //-*****************************************************************************
306 //-*****************************************************************************
307 template <class PTYPE>
309 
310 //-*****************************************************************************
311 // Actual specializations
312 template <> struct PODTraitsFromType<bool_t> : public BooleanPODTraits {};
313 template <> struct PODTraitsFromType<uint8_t> : public Uint8PODTraits {};
314 template <> struct PODTraitsFromType<int8_t> : public Int8PODTraits {};
315 template <> struct PODTraitsFromType<uint16_t> : public Uint16PODTraits {};
316 template <> struct PODTraitsFromType<int16_t> : public Int16PODTraits {};
317 template <> struct PODTraitsFromType<uint32_t> : public Uint32PODTraits {};
318 template <> struct PODTraitsFromType<int32_t> : public Int32PODTraits {};
319 template <> struct PODTraitsFromType<uint64_t> : public Uint64PODTraits {};
320 template <> struct PODTraitsFromType<int64_t> : public Int64PODTraits {};
321 template <> struct PODTraitsFromType<float16_t> : public Float16PODTraits {};
322 template <> struct PODTraitsFromType<float32_t> : public Float32PODTraits {};
323 template <> struct PODTraitsFromType<float64_t> : public Float64PODTraits {};
324 template <> struct PODTraitsFromType<string> : public StringPODTraits {};
325 template <> struct PODTraitsFromType<wstring> : public WstringPODTraits {};
326 
327 //-*****************************************************************************
328 //-*****************************************************************************
329 // Some runtime stuff, for when templates won't help.
330 //-*****************************************************************************
331 //-*****************************************************************************
332 inline size_t PODNumBytes( PlainOldDataType pod )
333 {
334  switch ( pod )
335  {
336  case kBooleanPOD: return BooleanPODTraits::numBytes();
337  case kUint8POD: return Uint8PODTraits::numBytes();
338  case kInt8POD: return Int8PODTraits::numBytes();
339  case kUint16POD: return Uint16PODTraits::numBytes();
340  case kInt16POD: return Int16PODTraits::numBytes();
341  case kUint32POD: return Uint32PODTraits::numBytes();
342  case kInt32POD: return Int32PODTraits::numBytes();
343  case kUint64POD: return Uint64PODTraits::numBytes();
344  case kInt64POD: return Int64PODTraits::numBytes();
345  case kFloat16POD: return Float16PODTraits::numBytes();
346  case kFloat32POD: return Float32PODTraits::numBytes();
347  case kFloat64POD: return Float64PODTraits::numBytes();
348  case kStringPOD: return StringPODTraits::numBytes();
349  case kWstringPOD: return WstringPODTraits::numBytes();
350  default:
351  // Badness!
352  assert( false );
353  return 0;
354  };
355 }
356 
357 //-*****************************************************************************
358 inline const char *PODName( PlainOldDataType pod )
359 {
360  switch ( pod )
361  {
362  case kBooleanPOD: return BooleanPODTraits::name();
363  case kUint8POD: return Uint8PODTraits::name();
364  case kInt8POD: return Int8PODTraits::name();
365  case kUint16POD: return Uint16PODTraits::name();
366  case kInt16POD: return Int16PODTraits::name();
367  case kUint32POD: return Uint32PODTraits::name();
368  case kInt32POD: return Int32PODTraits::name();
369  case kUint64POD: return Uint64PODTraits::name();
370  case kInt64POD: return Int64PODTraits::name();
371  case kFloat16POD: return Float16PODTraits::name();
372  case kFloat32POD: return Float32PODTraits::name();
373  case kFloat64POD: return Float64PODTraits::name();
374  case kStringPOD: return StringPODTraits::name();
375  case kWstringPOD: return WstringPODTraits::name();
376  default:
377  // Can't throw from here, so just return 0.
378  // assert( false );
379  return "UNKNOWN";
380  // return 0;
381  };
382 }
383 
384 //-*****************************************************************************
386 {
387  if ( n == BooleanPODTraits::name() ) return BooleanPODTraits::pod_enum;
388  else if ( n == Uint8PODTraits::name() ) return Uint8PODTraits::pod_enum;
389  else if ( n == Int8PODTraits::name() ) return Int8PODTraits::pod_enum;
390  else if ( n == Uint16PODTraits::name() ) return Uint16PODTraits::pod_enum;
391  else if ( n == Int16PODTraits::name() ) return Int16PODTraits::pod_enum;
392  else if ( n == Uint32PODTraits::name() ) return Uint32PODTraits::pod_enum;
393  else if ( n == Int32PODTraits::name() ) return Int32PODTraits::pod_enum;
394  else if ( n == Uint64PODTraits::name() ) return Uint64PODTraits::pod_enum;
395  else if ( n == Int64PODTraits::name() ) return Int64PODTraits::pod_enum;
396  else if ( n == Float16PODTraits::name() ) return Float16PODTraits::pod_enum;
397  else if ( n == Float32PODTraits::name() ) return Float32PODTraits::pod_enum;
398  else if ( n == Float64PODTraits::name() ) return Float64PODTraits::pod_enum;
399  else if ( n == StringPODTraits::name() ) return StringPODTraits::pod_enum;
400  else if ( n == WstringPODTraits::name() ) return WstringPODTraits::pod_enum;
401  else return kUnknownPOD;
402 }
403 
404 //-*****************************************************************************
405 //! This actually does work with strings!
406 template <PlainOldDataType POD>
407 inline void PODSetDefaultPOD( void *addr )
408 {
410  value_type *valPtr = reinterpret_cast<value_type*>( addr );
411  if ( valPtr ) { *valPtr = PODTraitsFromEnum<POD>::default_value(); }
412 }
413 
414 //-*****************************************************************************
415 inline void PODSetDefault( PlainOldDataType pod, void *bytes )
416 {
417  switch ( pod )
418  {
419  case kBooleanPOD: PODSetDefaultPOD<kBooleanPOD>( bytes ); return;
420  case kUint8POD: PODSetDefaultPOD<kUint8POD>( bytes ); return;
421  case kInt8POD: PODSetDefaultPOD<kInt8POD>( bytes ); return;
422  case kUint16POD: PODSetDefaultPOD<kUint16POD>( bytes ); return;
423  case kInt16POD: PODSetDefaultPOD<kInt16POD>( bytes ); return;
424  case kUint32POD: PODSetDefaultPOD<kUint32POD>( bytes ); return;
425  case kInt32POD: PODSetDefaultPOD<kInt32POD>( bytes ); return;
426  case kUint64POD: PODSetDefaultPOD<kUint64POD>( bytes ); return;
427  case kInt64POD: PODSetDefaultPOD<kInt64POD>( bytes ); return;
428  case kFloat16POD: PODSetDefaultPOD<kFloat16POD>( bytes ); return;
429  case kFloat32POD: PODSetDefaultPOD<kFloat32POD>( bytes ); return;
430  case kFloat64POD: PODSetDefaultPOD<kFloat64POD>( bytes ); return;
431 
432  // This isn't tremendously valid for the string types. Eeek.
433  case kStringPOD: PODSetDefaultPOD<kStringPOD>( bytes ); return;
434  case kWstringPOD: PODSetDefaultPOD<kWstringPOD>( bytes ); return;
435  default:
436  // Can't throw, but in debug...
437  assert( false );
438  };
439 }
440 
441 } // End namespace ALEMBIC_VERSION_NS
442 
443 using namespace ALEMBIC_VERSION_NS;
444 
445 } // End namespace Util
446 } // End namespace Alembic
447 
448 #endif
449 
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
size_t PODNumBytes(PlainOldDataType pod)
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
uint64 value_type
Definition: GA_PrimCompat.h:29
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
GLdouble n
Definition: glcorearb.h:2007
Header file containing class definition for class Alembic::Util::Exception.
PlainOldDataType PODFromName(const std::string &n)
DECLARE_TRAITS(kBooleanPOD, bool_t,"bool_t", false, BooleanPODTraits)
void PODSetDefaultPOD(void *addr)
This actually does work with strings!
GLuint const GLchar * name
Definition: glcorearb.h:785
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
const char * PODName(PlainOldDataType pod)
void PODSetDefault(PlainOldDataType pod, void *bytes)
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
Definition: half.h:91
#define ALEMBIC_VERSION_NS
Definition: Foundation.h:104