HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
typedesc.h
Go to the documentation of this file.
1 // Copyright 2008-present Contributors to the OpenImageIO project.
2 // SPDX-License-Identifier: BSD-3-Clause
3 // https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md
4 
5 // clang-format off
6 
7 /// \file
8 /// The TypeDesc class is used to describe simple data types.
9 
10 
11 #pragma once
12 
13 #if defined(_MSC_VER)
14 // Ignore warnings about conditional expressions that always evaluate true
15 // on a given platform but may evaluate differently on another. There's
16 // nothing wrong with such conditionals.
17 # pragma warning(disable : 4127)
18 #endif
19 
20 #include <cmath>
21 #include <cstddef>
22 #include <iostream>
23 #include <limits>
24 
25 #include <OpenImageIO/dassert.h>
26 #include <OpenImageIO/export.h>
29 #include <OpenImageIO/strutil.h>
30 
31 // Define symbols that let client applications determine if newly added
32 // features are supported.
33 #define OIIO_TYPEDESC_VECTOR2 1
34 
35 
36 
38 
39 /////////////////////////////////////////////////////////////////////////////
40 /// A TypeDesc describes simple data types.
41 ///
42 /// It frequently comes up (in my experience, with renderers and image
43 /// handling programs) that you want a way to describe data that is passed
44 /// through APIs through blind pointers. These are some simple classes
45 /// that provide a simple type descriptor system. This is not meant to
46 /// be comprehensive -- for example, there is no provision for structs,
47 /// unions, pointers, const, or 'nested' type definitions. Just simple
48 /// integer and floating point, *common* aggregates such as 3-points,
49 /// and reasonably-lengthed arrays thereof.
50 ///
51 /////////////////////////////////////////////////////////////////////////////
52 
54  /// BASETYPE is a simple enum describing the base data types that
55  /// correspond (mostly) to the C/C++ built-in types.
56  enum BASETYPE {
57  UNKNOWN, ///< unknown type
58  NONE, ///< void/no type
59  UINT8, ///< 8-bit unsigned int values ranging from 0..255,
60  ///< (C/C++ `unsigned char`).
61  UCHAR=UINT8,
62  INT8, ///< 8-bit int values ranging from -128..127,
63  ///< (C/C++ `char`).
64  CHAR=INT8,
65  UINT16, ///< 16-bit int values ranging from 0..65535,
66  ///< (C/C++ `unsigned short`).
67  USHORT=UINT16,
68  INT16, ///< 16-bit int values ranging from -32768..32767,
69  ///< (C/C++ `short`).
70  SHORT=INT16,
71  UINT32, ///< 32-bit unsigned int values (C/C++ `unsigned int`).
72  UINT=UINT32,
73  INT32, ///< signed 32-bit int values (C/C++ `int`).
75  UINT64, ///< 64-bit unsigned int values (C/C++
76  ///< `unsigned long long` on most architectures).
77  ULONGLONG=UINT64,
78  INT64, ///< signed 64-bit int values (C/C++ `long long`
79  ///< on most architectures).
80  LONGLONG=INT64,
81  HALF, ///< 16-bit IEEE floating point values (OpenEXR `half`).
82  FLOAT, ///< 32-bit IEEE floating point values, (C/C++ `float`).
83  DOUBLE, ///< 64-bit IEEE floating point values, (C/C++ `double`).
84  STRING, ///< Character string.
85  PTR, ///< A pointer value.
86  LASTBASE
87  };
88 
89  /// AGGREGATE describes whether our TypeDesc is a simple scalar of one
90  /// of the BASETYPE's, or one of several simple aggregates.
91  ///
92  /// Note that aggregates and arrays are different. A `TypeDesc(FLOAT,3)`
93  /// is an array of three floats, a `TypeDesc(FLOAT,VEC3)` is a single
94  /// 3-component vector comprised of floats, and `TypeDesc(FLOAT,3,VEC3)`
95  /// is an array of 3 vectors, each of which is comprised of 3 floats.
96  enum AGGREGATE {
97  SCALAR = 1, ///< A single scalar value (such as a raw `int` or
98  ///< `float` in C). This is the default.
99  VEC2 = 2, ///< 2 values representing a 2D vector.
100  VEC3 = 3, ///< 3 values representing a 3D vector.
101  VEC4 = 4, ///< 4 values representing a 4D vector.
102  MATRIX33 = 9, ///< 9 values representing a 3x3 matrix.
103  MATRIX44 = 16 ///< 16 values representing a 4x4 matrix.
104  };
105 
106  /// VECSEMANTICS gives hints about what the data represent (for example,
107  /// if a spatial vector quantity should transform as a point, direction
108  /// vector, or surface normal).
110  NOXFORM = 0, ///< No semantic hints.
111  NOSEMANTICS = 0, ///< No semantic hints.
112  COLOR, ///< Color
113  POINT, ///< Point: a spatial location
114  VECTOR, ///< Vector: a spatial direction
115  NORMAL, ///< Normal: a surface normal
116  TIMECODE, ///< indicates an `int[2]` representing the standard
117  ///< 4-byte encoding of an SMPTE timecode.
118  KEYCODE, ///< indicates an `int[7]` representing the standard
119  ///< 28-byte encoding of an SMPTE keycode.
120  RATIONAL ///< A VEC2 representing a rational number `val[0] / val[1]`
121  };
122 
123  unsigned char basetype; ///< C data type at the heart of our type
124  unsigned char aggregate; ///< What kind of AGGREGATE is it?
125  unsigned char vecsemantics; ///< Hint: What does the aggregate represent?
126  unsigned char reserved; ///< Reserved for future expansion
127  int arraylen; ///< Array length, 0 = not array, -1 = unsized
128 
129  /// Construct from a BASETYPE and optional aggregateness, semantics,
130  /// and arrayness.
131  constexpr TypeDesc (BASETYPE btype=UNKNOWN, AGGREGATE agg=SCALAR,
132  VECSEMANTICS semantics=NOSEMANTICS,
133  int arraylen=0) noexcept
134  : basetype(static_cast<unsigned char>(btype)),
135  aggregate(static_cast<unsigned char>(agg)),
136  vecsemantics(static_cast<unsigned char>(semantics)), reserved(0),
137  arraylen(arraylen)
138  { }
139 
140  /// Construct an array of a non-aggregate BASETYPE.
141  constexpr TypeDesc (BASETYPE btype, int arraylen) noexcept
142  : TypeDesc(btype, SCALAR, NOSEMANTICS, arraylen) {}
143 
144  /// Construct an array from BASETYPE, AGGREGATE, and array length,
145  /// with unspecified (or moot) semantic hints.
146  constexpr TypeDesc (BASETYPE btype, AGGREGATE agg, int arraylen) noexcept
147  : TypeDesc(btype, agg, NOSEMANTICS, arraylen) {}
148 
149  /// Construct from a string (e.g., "float[3]"). If no valid
150  /// type could be assembled, set base to UNKNOWN.
151  ///
152  /// Examples:
153  /// ```
154  /// TypeDesc("int") == TypeDesc(TypeDesc::INT) // C++ int32_t
155  /// TypeDesc("float") == TypeDesc(TypeDesc::FLOAT) // C++ float
156  /// TypeDesc("uint16") == TypeDesc(TypeDesc::UINT16) // C++ uint16_t
157  /// TypeDesc("float[4]") == TypeDesc(TypeDesc::FLOAT, 4) // array
158  /// TypeDesc("point") == TypeDesc(TypeDesc::FLOAT,
159  /// TypeDesc::VEC3, TypeDesc::POINT)
160  /// ```
161  ///
162  TypeDesc (string_view typestring);
163 
164  /// Copy constructor.
165  constexpr TypeDesc (const TypeDesc &t) noexcept
166  : basetype(t.basetype), aggregate(t.aggregate),
167  vecsemantics(t.vecsemantics), reserved(0), arraylen(t.arraylen)
168  { }
169 
170 
171  /// Return the name, for printing and whatnot. For example,
172  /// "float", "int[5]", "normal"
173  const char *c_str() const;
174 
175  friend std::ostream& operator<< (std::ostream& o, const TypeDesc& t) {
176  o << t.c_str(); return o;
177  }
178 
179  /// Return the number of elements: 1 if not an array, or the array
180  /// length. Invalid to call this for arrays of undetermined size.
181  OIIO_CONSTEXPR14 size_t numelements () const noexcept {
182  OIIO_DASSERT_MSG (arraylen >= 0, "Called numelements() on TypeDesc "
183  "of array with unspecified length (%d)", arraylen);
184  return (arraylen >= 1 ? arraylen : 1);
185  }
186 
187  /// Return the number of basetype values: the aggregate count multiplied
188  /// by the array length (or 1 if not an array). Invalid to call this
189  /// for arrays of undetermined size.
190  OIIO_CONSTEXPR14 size_t basevalues () const noexcept {
191  return numelements() * aggregate;
192  }
193 
194  /// Does this TypeDesc describe an array?
195  constexpr bool is_array () const noexcept { return (arraylen != 0); }
196 
197  /// Does this TypeDesc describe an array, but whose length is not
198  /// specified?
199  constexpr bool is_unsized_array () const noexcept { return (arraylen < 0); }
200 
201  /// Does this TypeDesc describe an array, whose length is specified?
202  constexpr bool is_sized_array () const noexcept { return (arraylen > 0); }
203 
204  /// Return the size, in bytes, of this type.
205  ///
206  size_t size () const noexcept {
207  OIIO_DASSERT_MSG (arraylen >= 0, "Called size() on TypeDesc "
208  "of array with unspecified length (%d)", arraylen);
209  size_t a = (size_t) (arraylen > 0 ? arraylen : 1);
210  if (sizeof(size_t) > sizeof(int)) {
211  // size_t has plenty of room for this multiplication
212  return a * elementsize();
213  } else {
214  // need overflow protection
215  unsigned long long s = (unsigned long long) a * elementsize();
216  const size_t toobig = std::numeric_limits<size_t>::max();
217  return s < toobig ? (size_t)s : toobig;
218  }
219  }
220 
221  /// Return the type of one element, i.e., strip out the array-ness.
222  ///
223  OIIO_CONSTEXPR14 TypeDesc elementtype () const noexcept {
224  TypeDesc t (*this); t.arraylen = 0; return t;
225  }
226 
227  /// Return the size, in bytes, of one element of this type (that is,
228  /// ignoring whether it's an array).
229  size_t elementsize () const noexcept { return aggregate * basesize(); }
230 
231  /// Return just the underlying C scalar type, i.e., strip out the
232  /// array-ness and the aggregateness.
233  constexpr TypeDesc scalartype() const { return TypeDesc(BASETYPE(basetype)); }
234 
235  /// Return the base type size, i.e., stripped of both array-ness
236  /// and aggregateness.
237  size_t basesize () const noexcept;
238 
239  /// True if it's a floating-point type (versus a fundamentally
240  /// integral type or something else like a string).
241  bool is_floating_point () const noexcept;
242 
243  /// True if it's a signed type that allows for negative values.
244  bool is_signed () const noexcept;
245 
246  /// Shortcut: is it UNKNOWN?
247  constexpr bool is_unknown () const noexcept { return (basetype == UNKNOWN); }
248 
249  /// if (typedesc) is the same as asking whether it's not UNKNOWN.
250  constexpr operator bool () const noexcept { return (basetype != UNKNOWN); }
251 
252  /// Set *this to the type described in the string. Return the
253  /// length of the part of the string that describes the type. If
254  /// no valid type could be assembled, return 0 and do not modify
255  /// *this.
256  size_t fromstring (string_view typestring);
257 
258  /// Compare two TypeDesc values for equality.
259  ///
260  constexpr bool operator== (const TypeDesc &t) const noexcept {
261  return basetype == t.basetype && aggregate == t.aggregate &&
262  vecsemantics == t.vecsemantics && arraylen == t.arraylen;
263  }
264 
265  /// Compare two TypeDesc values for inequality.
266  ///
267  constexpr bool operator!= (const TypeDesc &t) const noexcept { return ! (*this == t); }
268 
269  /// Compare a TypeDesc to a basetype (it's the same if it has the
270  /// same base type and is not an aggregate or an array).
271  friend constexpr bool operator== (const TypeDesc &t, BASETYPE b) noexcept {
272  return (BASETYPE)t.basetype == b && (AGGREGATE)t.aggregate == SCALAR && !t.is_array();
273  }
274  friend constexpr bool operator== (BASETYPE b, const TypeDesc &t) noexcept {
275  return (BASETYPE)t.basetype == b && (AGGREGATE)t.aggregate == SCALAR && !t.is_array();
276  }
277 
278  /// Compare a TypeDesc to a basetype (it's the same if it has the
279  /// same base type and is not an aggregate or an array).
280  friend constexpr bool operator!= (const TypeDesc &t, BASETYPE b) noexcept {
281  return (BASETYPE)t.basetype != b || (AGGREGATE)t.aggregate != SCALAR || t.is_array();
282  }
283  friend constexpr bool operator!= (BASETYPE b, const TypeDesc &t) noexcept {
284  return (BASETYPE)t.basetype != b || (AGGREGATE)t.aggregate != SCALAR || t.is_array();
285  }
286 
287  /// TypeDesc's are equivalent if they are equal, or if their only
288  /// inequality is differing vector semantics.
289  friend constexpr bool equivalent (const TypeDesc &a, const TypeDesc &b) noexcept {
290  return a.basetype == b.basetype && a.aggregate == b.aggregate &&
291  (a.arraylen == b.arraylen || (a.is_unsized_array() && b.is_sized_array())
292  || (a.is_sized_array() && b.is_unsized_array()));
293  }
294  /// Member version of equivalent
295  constexpr bool equivalent (const TypeDesc &b) const noexcept {
296  return this->basetype == b.basetype && this->aggregate == b.aggregate &&
297  (this->arraylen == b.arraylen || (this->is_unsized_array() && b.is_sized_array())
298  || (this->is_sized_array() && b.is_unsized_array()));
299  }
300 
301  /// Is this a 2-vector aggregate (of the given type, float by default)?
302  constexpr bool is_vec2 (BASETYPE b=FLOAT) const noexcept {
303  return this->aggregate == VEC2 && this->basetype == b && !is_array();
304  }
305 
306  /// Is this a 3-vector aggregate (of the given type, float by default)?
307  constexpr bool is_vec3 (BASETYPE b=FLOAT) const noexcept {
308  return this->aggregate == VEC3 && this->basetype == b && !is_array();
309  }
310 
311  /// Is this a 4-vector aggregate (of the given type, float by default)?
312  constexpr bool is_vec4 (BASETYPE b=FLOAT) const noexcept {
313  return this->aggregate == VEC4 && this->basetype == b && !is_array();
314  }
315 
316  /// Demote the type to a non-array
317  ///
318  void unarray (void) noexcept { arraylen = 0; }
319 
320  /// Test for lexicographic 'less', comes in handy for lots of STL
321  /// containers and algorithms.
322  bool operator< (const TypeDesc &x) const noexcept;
323 
324  /// Given base data types of a and b, return a basetype that is a best
325  /// guess for one that can handle both without any loss of range or
326  /// precision.
327  static BASETYPE basetype_merge(TypeDesc a, TypeDesc b);
328 
329  // DEPRECATED(1.8): These static const member functions were mildly
330  // problematic because they required external linkage (and possibly
331  // even static initialization order fiasco) and were a memory reference
332  // that incurred some performance penalty and inability to optimize.
333  // Please instead use the out-of-class constexpr versions below. We
334  // will eventually remove these.
335  static const TypeDesc TypeFloat;
336  static const TypeDesc TypeColor;
337  static const TypeDesc TypeString;
338  static const TypeDesc TypeInt;
339  static const TypeDesc TypeHalf;
340  static const TypeDesc TypePoint;
341  static const TypeDesc TypeVector;
342  static const TypeDesc TypeNormal;
343  static const TypeDesc TypeMatrix;
344  static const TypeDesc TypeMatrix33;
345  static const TypeDesc TypeMatrix44;
346  static const TypeDesc TypeTimeCode;
347  static const TypeDesc TypeKeyCode;
348  static const TypeDesc TypeFloat4;
349  static const TypeDesc TypeRational;
350 };
351 
352 
353 
354 
355 // Static values for commonly used types. Because these are constexpr,
356 // they should incur no runtime construction cost and should optimize nicely
357 // in various ways.
358 static constexpr TypeDesc TypeUnknown (TypeDesc::UNKNOWN);
359 static constexpr TypeDesc TypeFloat (TypeDesc::FLOAT);
360 static constexpr TypeDesc TypeColor (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::COLOR);
361 static constexpr TypeDesc TypePoint (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::POINT);
362 static constexpr TypeDesc TypeVector (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::VECTOR);
363 static constexpr TypeDesc TypeNormal (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::NORMAL);
364 static constexpr TypeDesc TypeMatrix33 (TypeDesc::FLOAT, TypeDesc::MATRIX33);
365 static constexpr TypeDesc TypeMatrix44 (TypeDesc::FLOAT, TypeDesc::MATRIX44);
366 static constexpr TypeDesc TypeMatrix = TypeMatrix44;
367 static constexpr TypeDesc TypeFloat2 (TypeDesc::FLOAT, TypeDesc::VEC2);
368 static constexpr TypeDesc TypeVector2 (TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::VECTOR);
369 static constexpr TypeDesc TypeFloat4 (TypeDesc::FLOAT, TypeDesc::VEC4);
370 static constexpr TypeDesc TypeVector4 = TypeFloat4;
371 static constexpr TypeDesc TypeString (TypeDesc::STRING);
372 static constexpr TypeDesc TypeInt (TypeDesc::INT);
373 static constexpr TypeDesc TypeUInt (TypeDesc::UINT);
374 static constexpr TypeDesc TypeInt32 (TypeDesc::INT);
375 static constexpr TypeDesc TypeUInt32 (TypeDesc::UINT);
376 static constexpr TypeDesc TypeInt16 (TypeDesc::INT16);
377 static constexpr TypeDesc TypeUInt16 (TypeDesc::UINT16);
378 static constexpr TypeDesc TypeInt8 (TypeDesc::INT8);
379 static constexpr TypeDesc TypeUInt8 (TypeDesc::UINT8);
380 static constexpr TypeDesc TypeVector2i(TypeDesc::INT, TypeDesc::VEC2);
381 static constexpr TypeDesc TypeHalf (TypeDesc::HALF);
382 static constexpr TypeDesc TypeTimeCode (TypeDesc::UINT, TypeDesc::SCALAR, TypeDesc::TIMECODE, 2);
383 static constexpr TypeDesc TypeKeyCode (TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::KEYCODE, 7);
384 static constexpr TypeDesc TypeRational(TypeDesc::INT, TypeDesc::VEC2, TypeDesc::RATIONAL);
385 static constexpr TypeDesc TypePointer(TypeDesc::PTR);
386 
387 
388 
389 // DEPRECATED(2.1)
390 OIIO_API
391 std::string tostring (TypeDesc type, const void *data,
392  const char *float_fmt, // E.g. "%g"
393  const char *string_fmt = "%s", // E.g. "\"%s\""
394  const char aggregate_delim[2] = "()", // Both sides of vector
395  const char *aggregate_sep = ",", // E.g. ", "
396  const char array_delim[2] = "{}", // Both sides of array
397  const char *array_sep = ","); // E.g. "; "
398 
399 
400 
401 /// A template mechanism for getting the a base type from C type
402 ///
403 template<typename T> struct BaseTypeFromC {};
404 template<> struct BaseTypeFromC<unsigned char> { static const TypeDesc::BASETYPE value = TypeDesc::UINT8; };
405 template<> struct BaseTypeFromC<char> { static const TypeDesc::BASETYPE value = TypeDesc::INT8; };
406 template<> struct BaseTypeFromC<unsigned short> { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; };
407 template<> struct BaseTypeFromC<short> { static const TypeDesc::BASETYPE value = TypeDesc::INT16; };
408 template<> struct BaseTypeFromC<unsigned int> { static const TypeDesc::BASETYPE value = TypeDesc::UINT; };
409 template<> struct BaseTypeFromC<int> { static const TypeDesc::BASETYPE value = TypeDesc::INT; };
410 template<> struct BaseTypeFromC<unsigned long long> { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; };
411 template<> struct BaseTypeFromC<long long> { static const TypeDesc::BASETYPE value = TypeDesc::INT64; };
412 #ifdef _HALF_H_
413 template<> struct BaseTypeFromC<half> { static const TypeDesc::BASETYPE value = TypeDesc::HALF; };
414 #endif
415 template<> struct BaseTypeFromC<float> { static const TypeDesc::BASETYPE value = TypeDesc::FLOAT; };
416 template<> struct BaseTypeFromC<double> { static const TypeDesc::BASETYPE value = TypeDesc::DOUBLE; };
417 template<> struct BaseTypeFromC<const char*> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
418 template<> struct BaseTypeFromC<char*> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
419 template<> struct BaseTypeFromC<std::string> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
420 template<> struct BaseTypeFromC<string_view> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
421 class ustring;
422 template<> struct BaseTypeFromC<ustring> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
423 template<size_t S> struct BaseTypeFromC<char[S]> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
424 template<size_t S> struct BaseTypeFromC<const char[S]> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
425 
426 
427 /// A template mechanism for getting the TypeDesc from a C type.
428 /// The default for simple types is just the TypeDesc based on BaseTypeFromC.
429 /// But we can specialize more complex types.
430 template<typename T> struct TypeDescFromC { static const constexpr TypeDesc value() { return BaseTypeFromC<T>::value; } };
431 template<> struct TypeDescFromC<int> { static const constexpr TypeDesc value() { return TypeDesc::INT; } };
432 template<> struct TypeDescFromC<float> { static const constexpr TypeDesc value() { return TypeDesc::FLOAT; } };
433 template<size_t S> struct TypeDescFromC<char[S]> { static const constexpr TypeDesc value() { return TypeDesc::STRING; } };
434 template<size_t S> struct TypeDescFromC<const char[S]> { static const constexpr TypeDesc value() { return TypeDesc::STRING; } };
435 #ifdef INCLUDED_IMATHVEC_H
436 template<> struct TypeDescFromC<Imath::V3f> { static const constexpr TypeDesc value() { return TypeVector; } };
437 template<> struct TypeDescFromC<Imath::V2f> { static const constexpr TypeDesc value() { return TypeVector2; } };
438 template<> struct TypeDescFromC<Imath::V4f> { static const constexpr TypeDesc value() { return TypeVector4; } };
439 template<> struct TypeDescFromC<Imath::V2i> { static const constexpr TypeDesc value() { return TypeVector2i; } };
440 #endif
441 #ifdef INCLUDED_IMATHCOLOR_H
442 template<> struct TypeDescFromC<Imath::Color3f> { static const constexpr TypeDesc value() { return TypeColor; } };
443 #endif
444 #ifdef INCLUDED_IMATHMATRIX_H
445 template<> struct TypeDescFromC<Imath::M33f> { static const constexpr TypeDesc value() { return TypeMatrix33; } };
446 template<> struct TypeDescFromC<Imath::M44f> { static const constexpr TypeDesc value() { return TypeMatrix44; } };
447 template<> struct TypeDescFromC<Imath::M33d> { static const constexpr TypeDesc value() { return TypeDesc(TypeDesc::DOUBLE, TypeDesc::MATRIX33); } };
448 template<> struct TypeDescFromC<Imath::M44d> { static const constexpr TypeDesc value() { return TypeDesc(TypeDesc::DOUBLE, TypeDesc::MATRIX44); } };
449 #endif
450 
451 
452 /// A template mechanism for getting C type of TypeDesc::BASETYPE.
453 ///
454 template<int b> struct CType {};
455 template<> struct CType<(int)TypeDesc::UINT8> { typedef unsigned char type; };
456 template<> struct CType<(int)TypeDesc::INT8> { typedef char type; };
457 template<> struct CType<(int)TypeDesc::UINT16> { typedef unsigned short type; };
458 template<> struct CType<(int)TypeDesc::INT16> { typedef short type; };
459 template<> struct CType<(int)TypeDesc::UINT> { typedef unsigned int type; };
460 template<> struct CType<(int)TypeDesc::INT> { typedef int type; };
461 template<> struct CType<(int)TypeDesc::UINT64> { typedef unsigned long long type; };
462 template<> struct CType<(int)TypeDesc::INT64> { typedef long long type; };
463 #ifdef _HALF_H_
464 template<> struct CType<(int)TypeDesc::HALF> { typedef half type; };
465 #endif
466 template<> struct CType<(int)TypeDesc::FLOAT> { typedef float type; };
467 template<> struct CType<(int)TypeDesc::DOUBLE> { typedef double type; };
468 
469 
470 
471 /// Helper class for tostring() that contains a whole bunch of parameters
472 /// that control exactly how all the data types that can be described as
473 /// TypeDesc ought to be formatted as a string. Uses printf-like
474 /// conventions. This will someday be deprecated.
476  // Printf-like formatting specs for int, float, string, pointer data.
477  const char *int_fmt = "%d";
478  const char *float_fmt = "%g";
479  const char *string_fmt = "\"%s\"";
480  const char *ptr_fmt = "%p";
481  // Aggregates are multi-part types, like VEC3, etc. How do we mark the
482  // start, separation between elements, and end?
483  const char *aggregate_begin = "(";
484  const char *aggregate_end = ")";
485  const char *aggregate_sep = ",";
486  // For arrays, how do we mark the start, separation between elements,
487  // and end?
488  const char *array_begin = "{";
489  const char *array_end = "}";
490  const char *array_sep = ",";
491  // Miscellaneous control flags, OR the enum values together.
494  // Reserved space for future expansion without breaking the ABI.
495  const char *uint_fmt = "%u";
496  const char *reserved2 = "";
497  const char *reserved3 = "";
498  bool use_sprintf = true;
499 
500  enum Notation { STDFORMAT };
501 
502  tostring_formatting() = default;
503  tostring_formatting(const char *int_fmt, const char *float_fmt = "%g",
504  const char *string_fmt = "\"%s\"", const char *ptr_fmt = "%p",
505  const char *aggregate_begin = "(", const char *aggregate_end = ")",
506  const char *aggregate_sep = ",", const char *array_begin = "{",
507  const char *array_end = "}", const char *array_sep = ",",
508  int flags = escape_strings,
509  const char *uint_fmt = "%u");
510 
511  // Alternative ctr for std::format notation. You must pass STDFORMAT
512  // as the first argument.
513  tostring_formatting(Notation notation,
514  const char *int_fmt = "{}", const char *uint_fmt = "{}",
515  const char *float_fmt = "{}",
516  const char *string_fmt = "\"{}\"", const char *ptr_fmt = "{}",
517  const char *aggregate_begin = "(", const char *aggregate_end = ")",
518  const char *aggregate_sep = ",", const char *array_begin = "{",
519  const char *array_end = "}", const char *array_sep = ",",
520  int flags = escape_strings);
521 };
522 
523 
524 
525 /// Return a string containing the data values formatted according
526 /// to the type and the optional formatting control arguments. Will be
527 /// deprecated someday as printf formatting falls out of favor.
529 tostring(TypeDesc type, const void* data, const tostring_formatting& fmt = {});
530 
531 
532 
533 /// Given data pointed to by src and described by srctype, copy it to the
534 /// memory pointed to by dst and described by dsttype, and return true if a
535 /// conversion is possible, false if it is not. If the types are equivalent,
536 /// this is a straightforward memory copy. If the types differ, there are
537 /// several non-equivalent type conversions that will nonetheless succeed:
538 /// * If dsttype is a string (and therefore dst points to a ustring or a
539 /// `char*`): it will always succeed, producing a string akin to calling
540 /// `tostring()`.
541 /// * If dsttype is int32 or uint32: other integer types will do their best
542 /// (caveat emptor if you mix signed/unsigned). Also a source string will
543 /// convert to int if and only if its characters form a valid integer.
544 /// * If dsttype is float: inteegers and other float types will do
545 /// their best conversion; strings will convert if and only if their
546 /// characters form a valid float number.
547 OIIO_API bool
548 convert_type(TypeDesc srctype, const void* src,
549  TypeDesc dsttype, void* dst, int n = 1);
550 
551 
553 
554 
555 
556 // Supply a fmtlib compatible custom formatter for TypeDesc.
558 template <>
559 struct formatter<OIIO::TypeDesc> {
560  // Parses format specification
561  // C++14: constexpr auto parse(format_parse_context& ctx) {
562  auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) // c++11
563  {
564  // Get the presentation type, if any. Required to be 's'.
565  auto it = ctx.begin(), end = ctx.end();
566  if (it != end && (*it == 's')) ++it;
567  // Check if reached the end of the range:
568  if (it != end && *it != '}')
569  throw format_error("invalid format");
570  // Return an iterator past the end of the parsed range:
571  return it;
572  }
573 
574  template <typename FormatContext>
575  auto format(const OIIO::TypeDesc& t, FormatContext& ctx) -> decltype(ctx.out()){
576  // C++14: auto format(const point& p, FormatContext& ctx) {
577  // ctx.out() is an output iterator to write to.
578  return format_to(ctx.out(), "{}", t.c_str());
579  }
580 };
16-bit IEEE floating point values (OpenEXR half).
Definition: typedesc.h:81
type
Definition: core.h:977
static const TypeDesc TypeFloat
Definition: typedesc.h:335
const char * aggregate_end
Definition: typedesc.h:484
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1221
A VEC2 representing a rational number val[0] / val[1]
Definition: typedesc.h:120
static const TypeDesc TypeColor
Definition: typedesc.h:336
32-bit IEEE floating point values, (C/C++ float).
Definition: typedesc.h:82
3 values representing a 3D vector.
Definition: typedesc.h:100
constexpr bool equivalent(const TypeDesc &b) const noexcept
Member version of equivalent.
Definition: typedesc.h:295
const char * reserved3
Definition: typedesc.h:497
unknown type
Definition: typedesc.h:57
void/no type
Definition: typedesc.h:58
size_t elementsize() const noexcept
Definition: typedesc.h:229
static const TypeDesc TypeVector
Definition: typedesc.h:341
static const TypeDesc TypeMatrix
Definition: typedesc.h:343
Vector: a spatial direction.
Definition: typedesc.h:114
4 values representing a 4D vector.
Definition: typedesc.h:101
constexpr bool is_vec3(BASETYPE b=FLOAT) const noexcept
Is this a 3-vector aggregate (of the given type, float by default)?
Definition: typedesc.h:307
auto format_to(OutputIt out, const S &format_str, Args &&...args) -> typename std::enable_if< enable, OutputIt >::type
Definition: core.h:2002
constexpr bool is_unsized_array() const noexcept
Definition: typedesc.h:199
static const constexpr TypeDesc value()
Definition: typedesc.h:433
static const TypeDesc TypeHalf
Definition: typedesc.h:339
Character string.
Definition: typedesc.h:84
64-bit IEEE floating point values, (C/C++ double).
Definition: typedesc.h:83
static const TypeDesc TypePoint
Definition: typedesc.h:340
static const TypeDesc TypeRational
Definition: typedesc.h:349
constexpr bool is_vec2(BASETYPE b=FLOAT) const noexcept
Is this a 2-vector aggregate (of the given type, float by default)?
Definition: typedesc.h:302
auto format(const OIIO::TypeDesc &t, FormatContext &ctx) -> decltype(ctx.out())
Definition: typedesc.h:575
unsigned char basetype
C data type at the heart of our type.
Definition: typedesc.h:123
OIIO_API std::string tostring(TypeDesc type, const void *data, const char *float_fmt, const char *string_fmt="%s", const char aggregate_delim[2]="()", const char *aggregate_sep=",", const char array_delim[2]="{}", const char *array_sep=",")
std::integral_constant< bool, std::numeric_limits< T >::is_signed||std::is_same< T, int128_t >::value > is_signed
Definition: format.h:787
GLenum src
Definition: glcorearb.h:1792
String-related utilities, all in namespace Strutil.
unsigned char reserved
Reserved for future expansion.
Definition: typedesc.h:126
GLdouble GLdouble t
Definition: glew.h:1403
constexpr bool is_sized_array() const noexcept
Does this TypeDesc describe an array, whose length is specified?
Definition: typedesc.h:202
#define FMT_END_NAMESPACE
Definition: core.h:198
tostring_formatting()=default
9 values representing a 3x3 matrix.
Definition: typedesc.h:102
GLint GLenum GLint x
Definition: glcorearb.h:408
auto parse(format_parse_context &ctx) -> decltype(ctx.begin())
Definition: typedesc.h:562
std::ostream & operator<<(std::ostream &ostr, const DataType &a)
Definition: DataType.h:133
const char * reserved2
Definition: typedesc.h:496
16 values representing a 4x4 matrix.
Definition: typedesc.h:103
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
constexpr TypeDesc(BASETYPE btype=UNKNOWN, AGGREGATE agg=SCALAR, VECSEMANTICS semantics=NOSEMANTICS, int arraylen=0) noexcept
Definition: typedesc.h:131
2 values representing a 2D vector.
Definition: typedesc.h:99
Point: a spatial location.
Definition: typedesc.h:113
typedef INT(WINAPI *PFNWGLGETGPUINFOAMDPROC)(UINT id
static const TypeDesc TypeKeyCode
Definition: typedesc.h:347
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
static const TypeDesc TypeNormal
Definition: typedesc.h:342
#define OIIO_DASSERT_MSG
Definition: dassert.h:56
size_t size() const noexcept
Definition: typedesc.h:206
static const TypeDesc TypeMatrix44
Definition: typedesc.h:345
MX_GENSHADER_API const TypeDesc * MATRIX44
unsigned char aggregate
What kind of AGGREGATE is it?
Definition: typedesc.h:124
static const TypeDesc TypeTimeCode
Definition: typedesc.h:346
constexpr TypeDesc(const TypeDesc &t) noexcept
Copy constructor.
Definition: typedesc.h:165
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
GLuint GLuint end
Definition: glcorearb.h:474
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
friend constexpr bool equivalent(const TypeDesc &a, const TypeDesc &b) noexcept
Definition: typedesc.h:289
bool operator<(const GU_TetrahedronFacet &a, const GU_TetrahedronFacet &b)
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
static const TypeDesc TypeMatrix33
Definition: typedesc.h:344
void unarray(void) noexcept
Definition: typedesc.h:318
OIIO_CONSTEXPR14 size_t numelements() const noexcept
Definition: typedesc.h:181
GLbitfield flags
Definition: glcorearb.h:1595
const char * string_fmt
Definition: typedesc.h:479
constexpr TypeDesc(BASETYPE btype, AGGREGATE agg, int arraylen) noexcept
Definition: typedesc.h:146
static const TypeDesc TypeString
Definition: typedesc.h:337
Normal: a surface normal.
Definition: typedesc.h:115
signed 32-bit int values (C/C++ int).
Definition: typedesc.h:73
const char * array_end
Definition: typedesc.h:489
constexpr TypeDesc scalartype() const
Definition: typedesc.h:233
static const TypeDesc TypeInt
Definition: typedesc.h:338
GLdouble n
Definition: glcorearb.h:2007
GLboolean * data
Definition: glcorearb.h:130
const char * c_str() const
const char * array_sep
Definition: typedesc.h:490
const char * aggregate_begin
Definition: typedesc.h:483
#define SCALAR(T)
Simplify checking for scalar types.
Definition: GA_Handle.h:412
static const TypeDesc TypeFloat4
Definition: typedesc.h:348
constexpr bool is_vec4(BASETYPE b=FLOAT) const noexcept
Is this a 4-vector aggregate (of the given type, float by default)?
Definition: typedesc.h:312
OIIO_CONSTEXPR14 TypeDesc elementtype() const noexcept
Definition: typedesc.h:223
constexpr bool is_array() const noexcept
Does this TypeDesc describe an array?
Definition: typedesc.h:195
VECSEMANTICS
Definition: typedesc.h:109
OIIO_API bool convert_type(TypeDesc srctype, const void *src, TypeDesc dsttype, void *dst, int n=1)
const char * aggregate_sep
Definition: typedesc.h:485
int arraylen
Array length, 0 = not array, -1 = unsized.
Definition: typedesc.h:127
GLsizei const GLfloat * value
Definition: glcorearb.h:823
const char * float_fmt
Definition: typedesc.h:478
static const constexpr TypeDesc value()
Definition: typedesc.h:430
typedef INT64(WINAPI *PFNWGLSWAPBUFFERSMSCOMLPROC)(HDC hdc
A pointer value.
Definition: typedesc.h:85
const char * uint_fmt
Definition: typedesc.h:495
#define FMT_BEGIN_NAMESPACE
Definition: core.h:203
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
#define const
Definition: zconf.h:214
32-bit unsigned int values (C/C++ unsigned int).
Definition: typedesc.h:71
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
unsigned long long type
Definition: typedesc.h:461
OIIO_CONSTEXPR14 size_t basevalues() const noexcept
Definition: typedesc.h:190
static const constexpr TypeDesc value()
Definition: typedesc.h:431
GLenum GLenum dst
Definition: glcorearb.h:1792
const char * int_fmt
Definition: typedesc.h:477
GLdouble s
Definition: glew.h:1395
static const constexpr TypeDesc value()
Definition: typedesc.h:432
Definition: half.h:91
MX_GENSHADER_API const TypeDesc * MATRIX33
constexpr TypeDesc(BASETYPE btype, int arraylen) noexcept
Construct an array of a non-aggregate BASETYPE.
Definition: typedesc.h:141
unsigned char vecsemantics
Hint: What does the aggregate represent?
Definition: typedesc.h:125
const char * ptr_fmt
Definition: typedesc.h:480
static const constexpr TypeDesc value()
Definition: typedesc.h:434
const char * array_begin
Definition: typedesc.h:488
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93
#define OIIO_API
Definition: export.h:65