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
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 
53 struct OIIO_UTIL_API TypeDesc {
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`).
74  INT=INT32,
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  BOX, ///< A VEC2[2] or VEC3[2] that represents a 2D or 3D bounds (min/max)
122  };
123 
124  unsigned char basetype; ///< C data type at the heart of our type
125  unsigned char aggregate; ///< What kind of AGGREGATE is it?
126  unsigned char vecsemantics; ///< Hint: What does the aggregate represent?
127  unsigned char reserved; ///< Reserved for future expansion
128  int arraylen; ///< Array length, 0 = not array, -1 = unsized
129 
130  /// Construct from a BASETYPE and optional aggregateness, semantics,
131  /// and arrayness.
132  OIIO_HOSTDEVICE constexpr TypeDesc (BASETYPE btype=UNKNOWN, AGGREGATE agg=SCALAR,
133  VECSEMANTICS semantics=NOSEMANTICS,
134  int arraylen=0) noexcept
135  : basetype(static_cast<unsigned char>(btype)),
136  aggregate(static_cast<unsigned char>(agg)),
137  vecsemantics(static_cast<unsigned char>(semantics)), reserved(0),
138  arraylen(arraylen)
139  { }
140 
141  /// Construct an array of a non-aggregate BASETYPE.
142  OIIO_HOSTDEVICE constexpr TypeDesc (BASETYPE btype, int arraylen) noexcept
143  : TypeDesc(btype, SCALAR, NOSEMANTICS, arraylen) {}
144 
145  /// Construct an array from BASETYPE, AGGREGATE, and array length,
146  /// with unspecified (or moot) semantic hints.
147  OIIO_HOSTDEVICE constexpr TypeDesc (BASETYPE btype, AGGREGATE agg, int arraylen) noexcept
148  : TypeDesc(btype, agg, NOSEMANTICS, arraylen) {}
149 
150  /// Construct from a string (e.g., "float[3]"). If no valid
151  /// type could be assembled, set base to UNKNOWN.
152  ///
153  /// Examples:
154  /// ```
155  /// TypeDesc("int") == TypeDesc(TypeDesc::INT) // C++ int32_t
156  /// TypeDesc("float") == TypeDesc(TypeDesc::FLOAT) // C++ float
157  /// TypeDesc("uint16") == TypeDesc(TypeDesc::UINT16) // C++ uint16_t
158  /// TypeDesc("float[4]") == TypeDesc(TypeDesc::FLOAT, 4) // array
159  /// TypeDesc("point") == TypeDesc(TypeDesc::FLOAT,
160  /// TypeDesc::VEC3, TypeDesc::POINT)
161  /// ```
162  ///
163  TypeDesc (string_view typestring);
164 
165  /// Copy constructor.
166  OIIO_HOSTDEVICE constexpr TypeDesc (const TypeDesc &t) noexcept
167  : basetype(t.basetype), aggregate(t.aggregate),
168  vecsemantics(t.vecsemantics), reserved(0), arraylen(t.arraylen)
169  { }
170 
171 
172  /// Return the name, for printing and whatnot. For example,
173  /// "float", "int[5]", "normal"
174  const char *c_str() const;
175 
176  friend std::ostream& operator<< (std::ostream& o, const TypeDesc& t) {
177  o << t.c_str(); return o;
178  }
179 
180  /// Return the number of elements: 1 if not an array, or the array
181  /// length. Invalid to call this for arrays of undetermined size.
183  OIIO_DASSERT_MSG (arraylen >= 0, "Called numelements() on TypeDesc "
184  "of array with unspecified length (%d)", arraylen);
185  return (arraylen >= 1 ? arraylen : 1);
186  }
187 
188  /// Return the number of basetype values: the aggregate count multiplied
189  /// by the array length (or 1 if not an array). Invalid to call this
190  /// for arrays of undetermined size.
192  return numelements() * aggregate;
193  }
194 
195  /// Does this TypeDesc describe an array?
196  OIIO_HOSTDEVICE constexpr bool is_array () const noexcept { return (arraylen != 0); }
197 
198  /// Does this TypeDesc describe an array, but whose length is not
199  /// specified?
200  OIIO_HOSTDEVICE constexpr bool is_unsized_array () const noexcept { return (arraylen < 0); }
201 
202  /// Does this TypeDesc describe an array, whose length is specified?
203  OIIO_HOSTDEVICE constexpr bool is_sized_array () const noexcept { return (arraylen > 0); }
204 
205  /// Return the size, in bytes, of this type.
206  ///
207  OIIO_HOSTDEVICE size_t size () const noexcept {
208  OIIO_DASSERT_MSG (arraylen >= 0, "Called size() on TypeDesc "
209  "of array with unspecified length (%d)", arraylen);
210  size_t a = (size_t) (arraylen > 0 ? arraylen : 1);
211  if (sizeof(size_t) > sizeof(int)) {
212  // size_t has plenty of room for this multiplication
213  return a * elementsize();
214  } else {
215  // need overflow protection
216  unsigned long long s = (unsigned long long) a * elementsize();
217  const size_t toobig = std::numeric_limits<size_t>::max();
218  return s < toobig ? (size_t)s : toobig;
219  }
220  }
221 
222  /// Return the type of one element, i.e., strip out the array-ness.
223  ///
225  TypeDesc t (*this); t.arraylen = 0; return t;
226  }
227 
228  /// Return the size, in bytes, of one element of this type (that is,
229  /// ignoring whether it's an array).
230  OIIO_HOSTDEVICE size_t elementsize () const noexcept { return aggregate * basesize(); }
231 
232  /// Return just the underlying C scalar type, i.e., strip out the
233  /// array-ness and the aggregateness.
234  OIIO_HOSTDEVICE constexpr TypeDesc scalartype() const { return TypeDesc(BASETYPE(basetype)); }
235 
236  /// Return the base type size, i.e., stripped of both array-ness
237  /// and aggregateness.
238  size_t basesize () const noexcept;
239 
240  /// True if it's a floating-point type (versus a fundamentally
241  /// integral type or something else like a string).
242  bool is_floating_point () const noexcept;
243 
244  /// True if it's a signed type that allows for negative values.
245  bool is_signed () const noexcept;
246 
247  /// Shortcut: is it UNKNOWN?
248  OIIO_HOSTDEVICE constexpr bool is_unknown () const noexcept { return (basetype == UNKNOWN); }
249 
250  /// if (typedesc) is the same as asking whether it's not UNKNOWN.
251  OIIO_HOSTDEVICE constexpr operator bool () const noexcept { return (basetype != UNKNOWN); }
252 
253  /// Set *this to the type described in the string. Return the
254  /// length of the part of the string that describes the type. If
255  /// no valid type could be assembled, return 0 and do not modify
256  /// *this.
257  size_t fromstring (string_view typestring);
258 
259  /// Compare two TypeDesc values for equality.
260  ///
261  OIIO_HOSTDEVICE constexpr bool operator== (const TypeDesc &t) const noexcept {
262  return basetype == t.basetype && aggregate == t.aggregate &&
263  vecsemantics == t.vecsemantics && arraylen == t.arraylen;
264  }
265 
266  /// Compare two TypeDesc values for inequality.
267  ///
268  OIIO_HOSTDEVICE constexpr bool operator!= (const TypeDesc &t) const noexcept { return ! (*this == t); }
269 
270  /// Compare a TypeDesc to a basetype (it's the same if it has the
271  /// same base type and is not an aggregate or an array).
272  OIIO_HOSTDEVICE friend constexpr bool operator== (const TypeDesc &t, BASETYPE b) noexcept {
273  return (BASETYPE)t.basetype == b && (AGGREGATE)t.aggregate == SCALAR && !t.is_array();
274  }
275  OIIO_HOSTDEVICE friend constexpr bool operator== (BASETYPE b, const TypeDesc &t) noexcept {
276  return (BASETYPE)t.basetype == b && (AGGREGATE)t.aggregate == SCALAR && !t.is_array();
277  }
278 
279  /// Compare a TypeDesc to a basetype (it's the same if it has the
280  /// same base type and is not an aggregate or an array).
281  OIIO_HOSTDEVICE friend constexpr bool operator!= (const TypeDesc &t, BASETYPE b) noexcept {
282  return (BASETYPE)t.basetype != b || (AGGREGATE)t.aggregate != SCALAR || t.is_array();
283  }
284  OIIO_HOSTDEVICE friend constexpr bool operator!= (BASETYPE b, const TypeDesc &t) noexcept {
285  return (BASETYPE)t.basetype != b || (AGGREGATE)t.aggregate != SCALAR || t.is_array();
286  }
287 
288  /// TypeDesc's are equivalent if they are equal, or if their only
289  /// inequality is differing vector semantics.
290  OIIO_HOSTDEVICE friend constexpr bool equivalent (const TypeDesc &a, const TypeDesc &b) noexcept {
291  return a.basetype == b.basetype && a.aggregate == b.aggregate &&
292  (a.arraylen == b.arraylen || (a.is_unsized_array() && b.is_sized_array())
293  || (a.is_sized_array() && b.is_unsized_array()));
294  }
295  /// Member version of equivalent
296  OIIO_HOSTDEVICE constexpr bool equivalent (const TypeDesc &b) const noexcept {
297  return this->basetype == b.basetype && this->aggregate == b.aggregate &&
298  (this->arraylen == b.arraylen || (this->is_unsized_array() && b.is_sized_array())
299  || (this->is_sized_array() && b.is_unsized_array()));
300  }
301 
302  /// Is this a 2-vector aggregate (of the given type, float by default)?
303  OIIO_HOSTDEVICE constexpr bool is_vec2 (BASETYPE b=FLOAT) const noexcept {
304  return this->aggregate == VEC2 && this->basetype == b && !is_array();
305  }
306 
307  /// Is this a 3-vector aggregate (of the given type, float by default)?
308  OIIO_HOSTDEVICE constexpr bool is_vec3 (BASETYPE b=FLOAT) const noexcept {
309  return this->aggregate == VEC3 && this->basetype == b && !is_array();
310  }
311 
312  /// Is this a 4-vector aggregate (of the given type, float by default)?
313  OIIO_HOSTDEVICE constexpr bool is_vec4 (BASETYPE b=FLOAT) const noexcept {
314  return this->aggregate == VEC4 && this->basetype == b && !is_array();
315  }
316 
317  /// Is this an array of aggregates that represents a 2D bounding box?
318  OIIO_HOSTDEVICE constexpr bool is_box2 (BASETYPE b=FLOAT) const noexcept {
319  return this->aggregate == VEC2 && this->basetype == b && arraylen == 2
320  && this->vecsemantics == BOX;
321  }
322 
323  /// Is this an array of aggregates that represents a 3D bounding box?
324  OIIO_HOSTDEVICE constexpr bool is_box3 (BASETYPE b=FLOAT) const noexcept {
325  return this->aggregate == VEC3 && this->basetype == b && arraylen == 2
326  && this->vecsemantics == BOX;
327  }
328 
329  /// Demote the type to a non-array
330  ///
331  OIIO_HOSTDEVICE void unarray (void) noexcept { arraylen = 0; }
332 
333  /// Test for lexicographic 'less', comes in handy for lots of STL
334  /// containers and algorithms.
335  bool operator< (const TypeDesc &x) const noexcept;
336 
337  /// Given base data types of a and b, return a basetype that is a best
338  /// guess for one that can handle both without any loss of range or
339  /// precision.
340  static BASETYPE basetype_merge(TypeDesc a, TypeDesc b);
341 
342  // DEPRECATED(1.8): These static const member functions were mildly
343  // problematic because they required external linkage (and possibly
344  // even static initialization order fiasco) and were a memory reference
345  // that incurred some performance penalty and inability to optimize.
346  // Please instead use the out-of-class constexpr versions below. We
347  // will eventually remove these.
348 #ifndef OIIO_DOXYGEN
349  static const TypeDesc TypeFloat;
350  static const TypeDesc TypeColor;
351  static const TypeDesc TypeString;
352  static const TypeDesc TypeInt;
353  static const TypeDesc TypeHalf;
354  static const TypeDesc TypePoint;
355  static const TypeDesc TypeVector;
356  static const TypeDesc TypeNormal;
357  static const TypeDesc TypeMatrix;
358  static const TypeDesc TypeMatrix33;
359  static const TypeDesc TypeMatrix44;
360  static const TypeDesc TypeTimeCode;
361  static const TypeDesc TypeKeyCode;
362  static const TypeDesc TypeFloat4;
363  static const TypeDesc TypeRational;
364 #endif
365 };
366 
367 
368 
369 
370 // Static values for commonly used types. Because these are constexpr,
371 // they should incur no runtime construction cost and should optimize nicely
372 // in various ways.
373 static constexpr TypeDesc TypeUnknown (TypeDesc::UNKNOWN);
374 static constexpr TypeDesc TypeFloat (TypeDesc::FLOAT);
375 static constexpr TypeDesc TypeColor (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::COLOR);
376 static constexpr TypeDesc TypePoint (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::POINT);
377 static constexpr TypeDesc TypeVector (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::VECTOR);
378 static constexpr TypeDesc TypeNormal (TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::NORMAL);
379 static constexpr TypeDesc TypeMatrix33 (TypeDesc::FLOAT, TypeDesc::MATRIX33);
380 static constexpr TypeDesc TypeMatrix44 (TypeDesc::FLOAT, TypeDesc::MATRIX44);
381 static constexpr TypeDesc TypeMatrix = TypeMatrix44;
382 static constexpr TypeDesc TypeFloat2 (TypeDesc::FLOAT, TypeDesc::VEC2);
383 static constexpr TypeDesc TypeVector2 (TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::VECTOR);
384 static constexpr TypeDesc TypeFloat4 (TypeDesc::FLOAT, TypeDesc::VEC4);
385 static constexpr TypeDesc TypeVector4 = TypeFloat4;
386 static constexpr TypeDesc TypeString (TypeDesc::STRING);
387 static constexpr TypeDesc TypeInt (TypeDesc::INT);
388 static constexpr TypeDesc TypeUInt (TypeDesc::UINT);
389 static constexpr TypeDesc TypeInt32 (TypeDesc::INT);
390 static constexpr TypeDesc TypeUInt32 (TypeDesc::UINT);
391 static constexpr TypeDesc TypeInt16 (TypeDesc::INT16);
392 static constexpr TypeDesc TypeUInt16 (TypeDesc::UINT16);
393 static constexpr TypeDesc TypeInt8 (TypeDesc::INT8);
394 static constexpr TypeDesc TypeUInt8 (TypeDesc::UINT8);
395 static constexpr TypeDesc TypeInt64 (TypeDesc::INT64);
396 static constexpr TypeDesc TypeUInt64 (TypeDesc::UINT64);
397 static constexpr TypeDesc TypeVector2i(TypeDesc::INT, TypeDesc::VEC2);
398 static constexpr TypeDesc TypeBox2(TypeDesc::FLOAT, TypeDesc::VEC2, TypeDesc::BOX, 2);
399 static constexpr TypeDesc TypeBox3(TypeDesc::FLOAT, TypeDesc::VEC3, TypeDesc::BOX, 2);
400 static constexpr TypeDesc TypeBox2i(TypeDesc::INT, TypeDesc::VEC2, TypeDesc::BOX, 2);
401 static constexpr TypeDesc TypeBox3i(TypeDesc::INT, TypeDesc::VEC3, TypeDesc::BOX, 2);
402 static constexpr TypeDesc TypeHalf (TypeDesc::HALF);
403 static constexpr TypeDesc TypeTimeCode (TypeDesc::UINT, TypeDesc::SCALAR, TypeDesc::TIMECODE, 2);
404 static constexpr TypeDesc TypeKeyCode (TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::KEYCODE, 7);
405 static constexpr TypeDesc TypeRational(TypeDesc::INT, TypeDesc::VEC2, TypeDesc::RATIONAL);
406 static constexpr TypeDesc TypePointer(TypeDesc::PTR);
407 
408 
409 
410 // DEPRECATED(2.1)
412 std::string tostring (TypeDesc type, const void *data,
413  const char *float_fmt, // E.g. "%g"
414  const char *string_fmt = "%s", // E.g. "\"%s\""
415  const char aggregate_delim[2] = "()", // Both sides of vector
416  const char *aggregate_sep = ",", // E.g. ", "
417  const char array_delim[2] = "{}", // Both sides of array
418  const char *array_sep = ","); // E.g. "; "
419 
420 
421 
422 /// A template mechanism for getting the a base type from C type
423 ///
424 template<typename T> struct BaseTypeFromC {};
425 template<> struct BaseTypeFromC<unsigned char> { static const TypeDesc::BASETYPE value = TypeDesc::UINT8; };
426 template<> struct BaseTypeFromC<char> { static const TypeDesc::BASETYPE value = TypeDesc::INT8; };
427 template<> struct BaseTypeFromC<unsigned short> { static const TypeDesc::BASETYPE value = TypeDesc::UINT16; };
428 template<> struct BaseTypeFromC<short> { static const TypeDesc::BASETYPE value = TypeDesc::INT16; };
429 template<> struct BaseTypeFromC<unsigned int> { static const TypeDesc::BASETYPE value = TypeDesc::UINT; };
430 template<> struct BaseTypeFromC<int> { static const TypeDesc::BASETYPE value = TypeDesc::INT; };
431 template<> struct BaseTypeFromC<unsigned long long> { static const TypeDesc::BASETYPE value = TypeDesc::UINT64; };
432 template<> struct BaseTypeFromC<long long> { static const TypeDesc::BASETYPE value = TypeDesc::INT64; };
433 #if defined(_HALF_H_) || defined(IMATH_HALF_H_)
434 template<> struct BaseTypeFromC<half> { static const TypeDesc::BASETYPE value = TypeDesc::HALF; };
435 #endif
436 template<> struct BaseTypeFromC<float> { static const TypeDesc::BASETYPE value = TypeDesc::FLOAT; };
437 template<> struct BaseTypeFromC<double> { static const TypeDesc::BASETYPE value = TypeDesc::DOUBLE; };
438 template<> struct BaseTypeFromC<const char*> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
439 template<> struct BaseTypeFromC<char*> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
440 template<> struct BaseTypeFromC<std::string> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
441 template<> struct BaseTypeFromC<string_view> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
442 class ustring;
443 template<> struct BaseTypeFromC<ustring> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
444 template<size_t S> struct BaseTypeFromC<char[S]> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
445 template<size_t S> struct BaseTypeFromC<const char[S]> { static const TypeDesc::BASETYPE value = TypeDesc::STRING; };
446 
447 
448 /// A template mechanism for getting the TypeDesc from a C type.
449 /// The default for simple types is just the TypeDesc based on BaseTypeFromC.
450 /// But we can specialize more complex types.
451 template<typename T> struct TypeDescFromC { static const constexpr TypeDesc value() { return TypeDesc(BaseTypeFromC<T>::value); } };
452 template<> struct TypeDescFromC<int> { static const constexpr TypeDesc value() { return TypeDesc::INT; } };
453 template<> struct TypeDescFromC<float> { static const constexpr TypeDesc value() { return TypeDesc::FLOAT; } };
454 template<size_t S> struct TypeDescFromC<char[S]> { static const constexpr TypeDesc value() { return TypeDesc::STRING; } };
455 template<size_t S> struct TypeDescFromC<const char[S]> { static const constexpr TypeDesc value() { return TypeDesc::STRING; } };
456 #ifdef INCLUDED_IMATHVEC_H
457 template<> struct TypeDescFromC<Imath::V3f> { static const constexpr TypeDesc value() { return TypeVector; } };
458 template<> struct TypeDescFromC<Imath::V2f> { static const constexpr TypeDesc value() { return TypeVector2; } };
459 template<> struct TypeDescFromC<Imath::V4f> { static const constexpr TypeDesc value() { return TypeVector4; } };
460 template<> struct TypeDescFromC<Imath::V2i> { static const constexpr TypeDesc value() { return TypeVector2i; } };
461 #endif
462 #ifdef INCLUDED_IMATHCOLOR_H
463 template<> struct TypeDescFromC<Imath::Color3f> { static const constexpr TypeDesc value() { return TypeColor; } };
464 #endif
465 #ifdef INCLUDED_IMATHMATRIX_H
466 template<> struct TypeDescFromC<Imath::M33f> { static const constexpr TypeDesc value() { return TypeMatrix33; } };
467 template<> struct TypeDescFromC<Imath::M44f> { static const constexpr TypeDesc value() { return TypeMatrix44; } };
468 template<> struct TypeDescFromC<Imath::M33d> { static const constexpr TypeDesc value() { return TypeDesc(TypeDesc::DOUBLE, TypeDesc::MATRIX33); } };
469 template<> struct TypeDescFromC<Imath::M44d> { static const constexpr TypeDesc value() { return TypeDesc(TypeDesc::DOUBLE, TypeDesc::MATRIX44); } };
470 #endif
471 #ifdef INCLUDED_IMATHBOX_H
472 template<> struct TypeDescFromC<Imath::Box2f> { static const constexpr TypeDesc value() { return TypeBox2; } };
473 template<> struct TypeDescFromC<Imath::Box2i> { static const constexpr TypeDesc value() { return TypeBox2i; } };
474 template<> struct TypeDescFromC<Imath::Box3f> { static const constexpr TypeDesc value() { return TypeBox3; } };
475 template<> struct TypeDescFromC<Imath::Box3i> { static const constexpr TypeDesc value() { return TypeBox3i; } };
476 #endif
477 
478 
479 /// A template mechanism for getting C type of TypeDesc::BASETYPE.
480 ///
481 template<int b> struct CType {};
482 template<> struct CType<(int)TypeDesc::UINT8> { typedef unsigned char type; };
483 template<> struct CType<(int)TypeDesc::INT8> { typedef char type; };
484 template<> struct CType<(int)TypeDesc::UINT16> { typedef unsigned short type; };
485 template<> struct CType<(int)TypeDesc::INT16> { typedef short type; };
486 template<> struct CType<(int)TypeDesc::UINT> { typedef unsigned int type; };
487 template<> struct CType<(int)TypeDesc::INT> { typedef int type; };
488 template<> struct CType<(int)TypeDesc::UINT64> { typedef unsigned long long type; };
489 template<> struct CType<(int)TypeDesc::INT64> { typedef long long type; };
490 #if defined(_HALF_H_) || defined(IMATH_HALF_H_)
491 template<> struct CType<(int)TypeDesc::HALF> { typedef half type; };
492 #endif
493 template<> struct CType<(int)TypeDesc::FLOAT> { typedef float type; };
494 template<> struct CType<(int)TypeDesc::DOUBLE> { typedef double type; };
495 
496 
497 
498 /// Helper class for tostring() that contains a whole bunch of parameters
499 /// that control exactly how all the data types that can be described as
500 /// TypeDesc ought to be formatted as a string. Uses printf-like
501 /// conventions. This will someday be deprecated.
503  // Printf-like formatting specs for int, float, string, pointer data.
504  const char *int_fmt = "%d";
505  const char *float_fmt = "%g";
506  const char *string_fmt = "\"%s\"";
507  const char *ptr_fmt = "%p";
508  // Aggregates are multi-part types, like VEC3, etc. How do we mark the
509  // start, separation between elements, and end?
510  const char *aggregate_begin = "(";
511  const char *aggregate_end = ")";
512  const char *aggregate_sep = ",";
513  // For arrays, how do we mark the start, separation between elements,
514  // and end?
515  const char *array_begin = "{";
516  const char *array_end = "}";
517  const char *array_sep = ",";
518  // Miscellaneous control flags, OR the enum values together.
521  // Reserved space for future expansion without breaking the ABI.
522  const char *uint_fmt = "%u";
523  const char *reserved2 = "";
524  const char *reserved3 = "";
525  bool use_sprintf = true;
526 
527  enum Notation { STDFORMAT };
528 
529  tostring_formatting() = default;
530  tostring_formatting(const char *int_fmt, const char *float_fmt = "%g",
531  const char *string_fmt = "\"%s\"", const char *ptr_fmt = "%p",
532  const char *aggregate_begin = "(", const char *aggregate_end = ")",
533  const char *aggregate_sep = ",", const char *array_begin = "{",
534  const char *array_end = "}", const char *array_sep = ",",
535  int flags = escape_strings,
536  const char *uint_fmt = "%u");
537 
538  // Alternative ctr for std::format notation. You must pass STDFORMAT
539  // as the first argument.
540  tostring_formatting(Notation notation,
541  const char *int_fmt = "{}", const char *uint_fmt = "{}",
542  const char *float_fmt = "{}",
543  const char *string_fmt = "\"{}\"", const char *ptr_fmt = "{}",
544  const char *aggregate_begin = "(", const char *aggregate_end = ")",
545  const char *aggregate_sep = ",", const char *array_begin = "{",
546  const char *array_end = "}", const char *array_sep = ",",
547  int flags = escape_strings);
548 };
549 
550 
551 
552 /// Return a string containing the data values formatted according
553 /// to the type and the optional formatting control arguments. Will be
554 /// deprecated someday as printf formatting falls out of favor.
556 tostring(TypeDesc type, const void* data, const tostring_formatting& fmt = {});
557 
558 
559 
560 /// Given data pointed to by src and described by srctype, copy it to the
561 /// memory pointed to by dst and described by dsttype, and return true if a
562 /// conversion is possible, false if it is not. If the types are equivalent,
563 /// this is a straightforward memory copy. If the types differ, there are
564 /// several non-equivalent type conversions that will nonetheless succeed:
565 /// * If dsttype is a string (and therefore dst points to a ustring or a
566 /// `char*`): it will always succeed, producing a string akin to calling
567 /// `tostring()`.
568 /// * If dsttype is int32 or uint32: other integer types will do their best
569 /// (caveat emptor if you mix signed/unsigned). Also a source string will
570 /// convert to int if and only if its characters form a valid integer.
571 /// * If dsttype is float: inteegers and other float types will do
572 /// their best conversion; strings will convert if and only if their
573 /// characters form a valid float number.
574 OIIO_UTIL_API bool
575 convert_type(TypeDesc srctype, const void* src,
576  TypeDesc dsttype, void* dst, int n = 1);
577 
578 
580 
581 
582 
583 // Supply a fmtlib compatible custom formatter for TypeDesc.
585 template <>
586 struct formatter<OIIO::TypeDesc> {
587  // Parses format specification
588  // C++14: constexpr auto parse(format_parse_context& ctx) const {
589  auto parse(format_parse_context &ctx) -> decltype(ctx.begin()) // c++11
590  {
591  // Get the presentation type, if any. Required to be 's'.
592  auto it = ctx.begin(), end = ctx.end();
593  if (it != end && (*it == 's')) ++it;
594  // Check if reached the end of the range:
595  if (it != end && *it != '}')
596  throw format_error("invalid format");
597  // Return an iterator past the end of the parsed range:
598  return it;
599  }
600 
601  template <typename FormatContext>
602  auto format(const OIIO::TypeDesc& t, FormatContext& ctx) -> decltype(ctx.out()) const {
603  // C++14: auto format(const OIIO::TypeDesc& p, FormatContext& ctx) const {
604  // ctx.out() is an output iterator to write to.
605  return format_to(ctx.out(), "{}", t.c_str());
606  }
607 };
OIIO_HOSTDEVICE constexpr bool is_box3(BASETYPE b=FLOAT) const noexcept
Is this an array of aggregates that represents a 3D bounding box?
Definition: typedesc.h:324
32-bit IEEE floating point values, (C/C++ float).
Definition: typedesc.h:82
#define OIIO_CONSTEXPR14
Definition: platform.h:101
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
unsigned char reserved
Reserved for future expansion.
Definition: typedesc.h:127
const char * aggregate_end
Definition: typedesc.h:511
static const TypeDesc TypeTimeCode
Definition: typedesc.h:360
GLbitfield flags
Definition: glcorearb.h:1596
64-bit IEEE floating point values, (C/C++ double).
Definition: typedesc.h:83
16-bit IEEE floating point values (OpenEXR half).
Definition: typedesc.h:81
static const TypeDesc TypeString
Definition: typedesc.h:351
MX_GENSHADER_API const TypeDesc * MATRIX44
OIIO_HOSTDEVICE 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:313
static const TypeDesc TypeFloat4
Definition: typedesc.h:362
OIIO_HOSTDEVICE constexpr bool equivalent(const TypeDesc &b) const noexcept
Member version of equivalent.
Definition: typedesc.h:296
unsigned char aggregate
What kind of AGGREGATE is it?
Definition: typedesc.h:125
HALF
Definition: ImfPixelType.h:25
Definition: ImathVec.h:32
imath_half_bits_t half
if we're in a C-only context, alias the half bits type to half
Definition: half.h:266
const char * reserved3
Definition: typedesc.h:524
FLOAT
Definition: ImfPixelType.h:26
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
OIIO_HOSTDEVICE constexpr TypeDesc(BASETYPE btype=UNKNOWN, AGGREGATE agg=SCALAR, VECSEMANTICS semantics=NOSEMANTICS, int arraylen=0) noexcept
Definition: typedesc.h:132
OIIO_HOSTDEVICE constexpr TypeDesc scalartype() const
Definition: typedesc.h:234
Vector: a spatial direction.
Definition: typedesc.h:114
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
unknown type
Definition: typedesc.h:57
GLdouble s
Definition: glad.h:3009
auto format(const OIIO::TypeDesc &t, FormatContext &ctx) -> decltype(ctx.out()) const
Definition: typedesc.h:602
static const constexpr TypeDesc value()
Definition: typedesc.h:454
9 values representing a 3x3 matrix.
Definition: typedesc.h:102
static const TypeDesc TypePoint
Definition: typedesc.h:354
const char * c_str() const
OIIO_UTIL_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:821
int arraylen
Array length, 0 = not array, -1 = unsized.
Definition: typedesc.h:128
String-related utilities, all in namespace Strutil.
#define OIIO_UTIL_API
Definition: export.h:71
A VEC2 representing a rational number val[0] / val[1]
Definition: typedesc.h:120
#define FMT_END_NAMESPACE
Definition: core.h:229
tostring_formatting()=default
OIIO_HOSTDEVICE friend constexpr bool equivalent(const TypeDesc &a, const TypeDesc &b) noexcept
Definition: typedesc.h:290
MX_GENSHADER_API const TypeDesc * MATRIX33
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 size_t numelements() const noexcept
Definition: typedesc.h:182
auto parse(format_parse_context &ctx) -> decltype(ctx.begin())
Definition: typedesc.h:589
std::ostream & operator<<(std::ostream &ostr, const DataType &a)
Definition: DataType.h:133
const char * reserved2
Definition: typedesc.h:523
static const TypeDesc TypeHalf
Definition: typedesc.h:353
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
static const TypeDesc TypeKeyCode
Definition: typedesc.h:361
OIIO_HOSTDEVICE 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:303
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 size_t basevalues() const noexcept
Definition: typedesc.h:191
16 values representing a 4x4 matrix.
Definition: typedesc.h:103
GLdouble n
Definition: glcorearb.h:2008
OIIO_HOSTDEVICE void unarray(void) noexcept
Definition: typedesc.h:331
static const TypeDesc TypeNormal
Definition: typedesc.h:356
static const TypeDesc TypeMatrix44
Definition: typedesc.h:359
#define OIIO_DASSERT_MSG
Definition: dassert.h:56
OIIO_HOSTDEVICE constexpr bool is_sized_array() const noexcept
Does this TypeDesc describe an array, whose length is specified?
Definition: typedesc.h:203
signed 32-bit int values (C/C++ int).
Definition: typedesc.h:73
static const TypeDesc TypeFloat
Definition: typedesc.h:349
GLuint GLuint end
Definition: glcorearb.h:475
2 values representing a 2D vector.
Definition: typedesc.h:99
3 values representing a 3D vector.
Definition: typedesc.h:100
OIIO_HOSTDEVICE 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:308
bool operator<(const GU_TetrahedronFacet &a, const GU_TetrahedronFacet &b)
#define OIIO_HOSTDEVICE
Definition: platform.h:509
OIIO_HOSTDEVICE constexpr bool is_unsized_array() const noexcept
Definition: typedesc.h:200
A pointer value.
Definition: typedesc.h:85
OIIO_HOSTDEVICE size_t size() const noexcept
Definition: typedesc.h:207
const char * string_fmt
Definition: typedesc.h:506
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
OIIO_UTIL_API bool convert_type(TypeDesc srctype, const void *src, TypeDesc dsttype, void *dst, int n=1)
4 values representing a 4D vector.
Definition: typedesc.h:101
GLdouble t
Definition: glad.h:2397
static const TypeDesc TypeVector
Definition: typedesc.h:355
const char * array_end
Definition: typedesc.h:516
Character string.
Definition: typedesc.h:84
Normal: a surface normal.
Definition: typedesc.h:115
const char * array_sep
Definition: typedesc.h:517
const char * aggregate_begin
Definition: typedesc.h:510
GLenum GLenum dst
Definition: glcorearb.h:1793
#define SCALAR(T)
Simplify checking for scalar types.
Definition: GA_Handle.h:498
static const TypeDesc TypeMatrix
Definition: typedesc.h:357
static const TypeDesc TypeColor
Definition: typedesc.h:350
Definition: ImathVec.h:31
static const TypeDesc TypeMatrix33
Definition: typedesc.h:358
Point: a spatial location.
Definition: typedesc.h:113
unsigned char basetype
C data type at the heart of our type.
Definition: typedesc.h:124
OIIO_HOSTDEVICE constexpr TypeDesc(const TypeDesc &t) noexcept
Copy constructor.
Definition: typedesc.h:166
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
const char * aggregate_sep
Definition: typedesc.h:512
void/no type
Definition: typedesc.h:58
FMT_INLINE auto format_to(OutputIt out, format_string< T...> fmt, T &&...args) -> OutputIt
Definition: core.h:2917
const char * float_fmt
Definition: typedesc.h:505
static const constexpr TypeDesc value()
Definition: typedesc.h:451
unsigned char vecsemantics
Hint: What does the aggregate represent?
Definition: typedesc.h:126
Definition: core.h:1131
Definition: ImathBox.h:37
OIIO_HOSTDEVICE constexpr TypeDesc(BASETYPE btype, AGGREGATE agg, int arraylen) noexcept
Definition: typedesc.h:147
const char * uint_fmt
Definition: typedesc.h:522
#define FMT_BEGIN_NAMESPACE
Definition: core.h:234
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
#define const
Definition: zconf.h:214
VECSEMANTICS
Definition: typedesc.h:109
#define OIIO_NAMESPACE_END
Definition: oiioversion.h:94
OIIO_HOSTDEVICE constexpr TypeDesc(BASETYPE btype, int arraylen) noexcept
Construct an array of a non-aggregate BASETYPE.
Definition: typedesc.h:142
Definition: ImathVec.h:33
unsigned long long type
Definition: typedesc.h:488
OIIO_HOSTDEVICE OIIO_CONSTEXPR14 TypeDesc elementtype() const noexcept
Definition: typedesc.h:224
static const constexpr TypeDesc value()
Definition: typedesc.h:452
A VEC2[2] or VEC3[2] that represents a 2D or 3D bounds (min/max)
Definition: typedesc.h:121
static const TypeDesc TypeInt
Definition: typedesc.h:352
OIIO_HOSTDEVICE constexpr bool is_array() const noexcept
Does this TypeDesc describe an array?
Definition: typedesc.h:196
OIIO_HOSTDEVICE size_t elementsize() const noexcept
Definition: typedesc.h:230
const char * int_fmt
Definition: typedesc.h:504
type
Definition: core.h:1059
static const constexpr TypeDesc value()
Definition: typedesc.h:453
static const TypeDesc TypeRational
Definition: typedesc.h:363
OIIO_HOSTDEVICE constexpr bool is_box2(BASETYPE b=FLOAT) const noexcept
Is this an array of aggregates that represents a 2D bounding box?
Definition: typedesc.h:318
UINT
Definition: ImfPixelType.h:24
Definition: format.h:895
32-bit unsigned int values (C/C++ unsigned int).
Definition: typedesc.h:71
const char * ptr_fmt
Definition: typedesc.h:507
static const constexpr TypeDesc value()
Definition: typedesc.h:455
const char * array_begin
Definition: typedesc.h:515
#define OIIO_NAMESPACE_BEGIN
Definition: oiioversion.h:93
GLenum src
Definition: glcorearb.h:1793