HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VOP_TypeInfo.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: VOP_TypeInfo.h ( Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __VOP_TypeInfo__
12 #define __VOP_TypeInfo__
13 
14 #include "VOP_API.h"
15 #include "VOP_Types.h"
16 #include <UT/UT_SharedPtr.h>
17 #include <UT/UT_StringHolder.h>
18 
19 class VOP_Language;
22 
23 
24 // ============================================================================
25 // In general, this is a type meta-name that accepts any struct name.
26 // An empty string does not collide with custom struct type names and
27 // also works well with printf() which is used for connector type name tokens.
28 // The exact meaning is imposed by the use of it:
29 // - auto-detect and adhoc-unpack (etc) vops specify it as input types,
30 // indicating that any struct type is accepted
31 // - some vops test the incoming wire type, and interpret it as a struct type
32 // yet-unresolved to anything concrete
33 #define VOP_STRUCT_TYPE_NAME_ANY ""
34 
35 // ============================================================================
36 /// Class abstracting VOP variable and connector types.
37 /// Unlike the basic VOP_Type enum, this class can represent and refer to any
38 /// type, including structs and custom types.
40 {
41 public:
42  /// @{
43  /// A constructor and a destructor.
44  // NB: explicit keyword is useful during sweeps to convert code from
45  // VOP_Type to VOP_TypeInfo; after that we can remove the keyword
47  const char * type_name = NULL );
48  ~VOP_TypeInfo();
49  /// @}
50 
51  /// Utility function that converts VOP_Type into a VOP_TypeInfo.
52  /// It is used during transition from VOP_Type to VOP_TypeInfo to mark
53  /// the places that should abandon VOP_Type in favour of VOP_TypeInfo,
54  /// but whose conversion is quite involved and likely requires lengthy
55  /// sweeps, and thus is postponed untill later phases.
56  // TODO: convert all places that call this function to use VOP_TypeInfo
57  // directly, instead of going through VOP_Type.
59  { setType( type ); }
60 
61  /// @{
62  /// Sets a new type and additional data for the type info.
63  void setType( VOP_Type type,
64  VOP_Type raw_type = VOP_TYPE_UNDEF,
65  const char *type_name = NULL );
66  void setType( VOP_Type type,
67  const char *type_name );
68  /// @}
69 
70  /// @{ Returns the type enumeration value.
71  VOP_Type getType() const
72  { return myType; }
74  { return myRawType; }
76  { return VOP_BASE_TYPE( myType ); }
77  /// @}
78 
79  /// Returns the official type name.
81  { return myTypeName; }
82 
83  /// Returns the actual type definition for the type represented by object.
84  VOP_TypeDefinitionHandle getTypeDefinitionHandle() const;
85 
86  /// @{ Sets and gets the array length.
87  enum { UNKNOWN_ARRAY_LENGTH = -1 };
89  { myArrayLength = length; }
90  int getArrayLength() const
91  { return myArrayLength; }
92  bool isFixedArrayLength() const
93  { return myArrayLength != UNKNOWN_ARRAY_LENGTH; }
94  /// @}
95 
96  /// Returns a type info that represents an undefined type.
97  static const VOP_TypeInfo & getUndefinedTypeInfo();
98 
99 
100  /// @{ Comparison operators.
101  bool operator==( const VOP_TypeInfo &other ) const;
102  bool operator!=( const VOP_TypeInfo &other ) const;
103  /// @}
104 
105  /// Language will condition the type to an equivalent base type,
106  /// which is useful for comparing types to test assignment compatibility
107  /// (eg, color and vector). Makes the type and raw type equal to the
108  /// type conditioned by the language.
109  void conditionType( const VOP_Language &language );
110 
111  /// Returns true if a variable of this type can be directly assigned
112  /// a value of the src_type type, without any explicit conversion.
113  bool canDirectlyAssign( const VOP_TypeInfo &src_type,
114  const VOP_Language *language = nullptr) const;
115 
116  /// Returns true if the type is valid.
117  bool isValid() const;
118 
119  /// Returns true if the type is an array.
120  bool isArray() const;
121 
122  /// Returns the type of the array element, if this type is an array.
123  VOP_TypeInfo getArrayElementTypeInfo() const;
124 
125  /// Returns true for sturct and class custom type.
126  bool isStructLike() const;
127 
128  /// Returns a type description used for labeling node inputs, outputs,
129  /// and other places with a legible name. Eg, "int", "uniform float",
130  /// "vector array", and "mystruct" (for 'struct mystruct' type).
131  void getDescriptionString( UT_String &description ) const;
133  {
134  UT_String tmp_str;
135  getDescriptionString( tmp_str );
136  return UT_StringHolder( std::move( tmp_str ));
137  }
138 
139  /// Returns a string that encodes the type information into a single-worded
140  /// string. Eg, "int", "ufloat", "vectora", "struct_mystruct" (for 'struct
141  /// mystruct' type).
142  void getTokenString( UT_String &token ) const;
144  {
145  UT_String tmp_str;
146  getTokenString( tmp_str );
147  return UT_StringHolder( std::move( tmp_str ));
148  }
149 
150  /// Sets the type info from the string representation of that type.
151  /// The string representation should be compatible with the strings
152  /// returned from getDescriptionString() or getTokenString() above.
153  /// Note, the struct types can be only deduced from strings compatible
154  /// with getTokenString(), or if str is "struct" (unnamed struct).
155  void setFromTokenString( const char *token_or_description );
156 
157 private:
158  /// The basic type of a variable or a connector.
159  VOP_Type myType;
160 
161  // The raw (unconditioned) type of the variable or connector. The
162  // raw type is not used for VOP_TypeInfo comparison, but is simply a way of
163  // doing an exact equivalence check when selecting the most appropriate
164  // signature of a scripted VOP.
165  VOP_Type myRawType;
166 
167  /// The name of the type.
168  /// For simple types it is an empty string (tough it could contain the
169  /// official vop type name for simple types too).
170  /// For structs and custom types, it contains the official type name
171  /// recognized by the language & type manager, VOP_LanguageManager.
172  UT_StringHolder myTypeName;
173 
174  /// The length of the array.
175  /// Some languages like OSL require statically determined lengths.
176  int myArrayLength;
177 };
178 
179 #endif
180 
Reprsents a language for which VOPs can generate source code.
Definition: VOP_Language.h:29
A class abstracting definition of a VOP data type.
bool isFixedArrayLength() const
Sets and gets the array length.
Definition: VOP_TypeInfo.h:92
void setArrayLength(int length)
Sets and gets the array length.
Definition: VOP_TypeInfo.h:88
VOP_Type getType() const
Returns the type enumeration value.
Definition: VOP_TypeInfo.h:71
GLuint GLsizei GLsizei * length
Definition: glcorearb.h:795
VOP_Type getBaseType() const
Returns the type enumeration value.
Definition: VOP_TypeInfo.h:75
UT_SharedPtr< const VOP_TypeDefinition > VOP_TypeDefinitionHandle
Definition: VOP_TypeInfo.h:20
bool operator==(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:137
#define VOP_API
Definition: VOP_API.h:10
std::shared_ptr< T > UT_SharedPtr
Wrapper around std::shared_ptr.
Definition: UT_SharedPtr.h:36
const UT_StringHolder & getTypeName() const
Returns the official type name.
Definition: VOP_TypeInfo.h:80
constexpr std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size(){return subtype_count< typename std::tuple_element< I, T >::type >::value+tuple_type_size< T, I+1 >);}template< typename T > struct type_count< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size< T, 0 >)};};template< typename T > struct subtype_count{static constexpr int value{is_mutable_container< T >::value?expected_max_vector_size:type_count< T >::value};};template< typename T, typename Enable=void > struct type_count_min{static const int value{0};};template< typename T >struct type_count_min< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_tuple_like< T >::value &&!is_wrapper< T >::value &&!is_complex< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{type_count< T >::value};};template< typename T > struct type_count_min< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr int value{1};};template< typename T >struct type_count_min< T, typename std::enable_if< is_wrapper< T >::value &&!is_complex< T >::value &&!is_tuple_like< T >::value >::type >{static constexpr int value{subtype_count_min< typename T::value_type >::value};};template< typename T, std::size_t I >constexpr typename std::enable_if< I==type_count_base< T >::value, int >::type tuple_type_size_min(){return 0;}template< typename T, std::size_t I > constexpr typename std::enable_if< I< type_count_base< T >::value, int >::type tuple_type_size_min(){return subtype_count_min< typename std::tuple_element< I, T >::type >::value+tuple_type_size_min< T, I+1 >);}template< typename T > struct type_count_min< T, typename std::enable_if< is_tuple_like< T >::value >::type >{static constexpr int value{tuple_type_size_min< T, 0 >)};};template< typename T > struct subtype_count_min{static constexpr int value{is_mutable_container< T >::value?((type_count< T >::value< expected_max_vector_size)?type_count< T >::value:0):type_count_min< T >::value};};template< typename T, typename Enable=void > struct expected_count{static const int value{0};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&!is_wrapper< T >::value &&!std::is_void< T >::value >::type >{static constexpr int value{1};};template< typename T > struct expected_count< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr int value{expected_max_vector_size};};template< typename T >struct expected_count< T, typename std::enable_if<!is_mutable_container< T >::value &&is_wrapper< T >::value >::type >{static constexpr int value{expected_count< typename T::value_type >::value};};enum class object_category:int{char_value=1, integral_value=2, unsigned_integral=4, enumeration=6, boolean_value=8, floating_point=10, number_constructible=12, double_constructible=14, integer_constructible=16, string_assignable=23, string_constructible=24, other=45, wrapper_value=50, complex_number=60, tuple_value=70, container_value=80,};template< typename T, typename Enable=void > struct classify_object{static constexpr object_category value{object_category::other};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&!std::is_same< T, char >::value &&std::is_signed< T >::value &&!is_bool< T >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::integral_value};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&!std::is_same< T, char >::value &&!is_bool< T >::value >::type >{static constexpr object_category value{object_category::unsigned_integral};};template< typename T >struct classify_object< T, typename std::enable_if< std::is_same< T, char >::value &&!std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::char_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_bool< T >::value >::type >{static constexpr object_category value{object_category::boolean_value};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_floating_point< T >::value >::type >{static constexpr object_category value{object_category::floating_point};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&std::is_assignable< T &, std::string >::value >::type >{static constexpr object_category value{object_category::string_assignable};};template< typename T >struct classify_object< T, typename std::enable_if<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&(type_count< T >::value==1)&&std::is_constructible< T, std::string >::value >::type >{static constexpr object_category value{object_category::string_constructible};};template< typename T > struct classify_object< T, typename std::enable_if< std::is_enum< T >::value >::type >{static constexpr object_category value{object_category::enumeration};};template< typename T > struct classify_object< T, typename std::enable_if< is_complex< T >::value >::type >{static constexpr object_category value{object_category::complex_number};};template< typename T > struct uncommon_type{using type=typename std::conditional<!std::is_floating_point< T >::value &&!std::is_integral< T >::value &&!std::is_assignable< T &, std::string >::value &&!std::is_constructible< T, std::string >::value &&!is_complex< T >::value &&!is_mutable_container< T >::value &&!std::is_enum< T >::value, std::true_type, std::false_type >::type;static constexpr bool value=type::value;};template< typename T >struct classify_object< T, typename std::enable_if<(!is_mutable_container< T >::value &&is_wrapper< T >::value &&!is_tuple_like< T >::value &&uncommon_type< T >::value)>::type >{static constexpr object_category value{object_category::wrapper_value};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::number_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&!is_direct_constructible< T, double >::value &&is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::integer_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< uncommon_type< T >::value &&type_count< T >::value==1 &&!is_wrapper< T >::value &&is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value >::type >{static constexpr object_category value{object_category::double_constructible};};template< typename T >struct classify_object< T, typename std::enable_if< is_tuple_like< T >::value &&((type_count< T >::value >=2 &&!is_wrapper< T >::value)||(uncommon_type< T >::value &&!is_direct_constructible< T, double >::value &&!is_direct_constructible< T, int >::value)||(uncommon_type< T >::value &&type_count< T >::value >=2))>::type >{static constexpr object_category value{object_category::tuple_value};};template< typename T > struct classify_object< T, typename std::enable_if< is_mutable_container< T >::value >::type >{static constexpr object_category value{object_category::container_value};};template< typename T, enable_if_t< classify_object< T >::value==object_category::char_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"CHAR";}template< typename T, enable_if_t< classify_object< T >::value==object_category::integral_value||classify_object< T >::value==object_category::integer_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"INT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::unsigned_integral, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"UINT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::floating_point||classify_object< T >::value==object_category::number_constructible||classify_object< T >::value==object_category::double_constructible, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"FLOAT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::enumeration, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"ENUM";}template< typename T, enable_if_t< classify_object< T >::value==object_category::boolean_value, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"BOOLEAN";}template< typename T, enable_if_t< classify_object< T >::value==object_category::complex_number, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"COMPLEX";}template< typename T, enable_if_t< classify_object< T >::value >=object_category::string_assignable &&classify_object< T >::value<=object_category::other, detail::enabler >=detail::dummy >constexpr const char *type_name(){return"TEXT";}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::container_value||classify_object< T >::value==object_category::wrapper_value, detail::enabler >=detail::dummy >std::string type_name();template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value==1, detail::enabler >=detail::dummy >inline std::string type_name(){return type_name< typename std::decay< typename std::tuple_element< 0, T >::type >::type >);}template< typename T, std::size_t I >inline typename std::enable_if< I==type_count_base< T >::value, std::string >::type tuple_name(){return std::string{};}template< typename T, std::size_t I >inline typename std::enable_if<(I< type_count_base< T >::value), std::string >::type tuple_name(){auto str=std::string{type_name< typename std::decay< typename std::tuple_element< I, T >::type >::type >)}+ ','+tuple_name< T, I+1 >);if(str.back()== ',') str.pop_back();return str;}template< typename T, enable_if_t< classify_object< T >::value==object_category::tuple_value &&type_count_base< T >::value >=2, detail::enabler > > std::string type_name()
Recursively generate the tuple type name.
Definition: CLI11.h:1729
#define VOP_BASE_TYPE(type)
Definition: VOP_Types.h:146
int getArrayLength() const
Sets and gets the array length.
Definition: VOP_TypeInfo.h:90
VOP_Type getRawType() const
Returns the type enumeration value.
Definition: VOP_TypeInfo.h:73
void setTypeInfoFromType(VOP_Type type)
Definition: VOP_TypeInfo.h:58
VOP_Type
Enumeration of the built-in (basic) VOP data types.
Definition: VOP_Types.h:25
UT_StringHolder getDescriptionString() const
Definition: VOP_TypeInfo.h:132
UT_StringHolder getTokenString() const
Definition: VOP_TypeInfo.h:143
bool operator!=(const BaseDimensions< T > &a, const BaseDimensions< Y > &b)
Definition: Dimensions.h:165
type
Definition: core.h:1059
UT_SharedPtr< const VOP_TypeDefinition > VOP_TypeDefinitionHandle
Define a handle for the type definition objects.