1 ///////////////////////////////////////////////////////////////////////////
3 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
6 // All rights reserved.
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
17 // * Neither the name of Industrial Light & Magic nor the names of
18 // its contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 ///////////////////////////////////////////////////////////////////////////
37 #ifndef INCLUDED_IMF_ATTRIBUTE_H
38 #define INCLUDED_IMF_ATTRIBUTE_H
40 //-----------------------------------------------------------------------------
44 //-----------------------------------------------------------------------------
46 #include "IexBaseExc.h"
58 //---------------------------
59 // Constructor and destructor
60 //---------------------------
63 virtual ~Attribute ();
66 //-------------------------------
67 // Get this attribute's type name
68 //-------------------------------
70 virtual const char * typeName () const = 0;
73 //------------------------------
74 // Make a copy of this attribute
75 //------------------------------
77 virtual Attribute * copy () const = 0;
80 //----------------------------------------
81 // Type-specific attribute I/O and copying
82 //----------------------------------------
84 virtual void writeValueTo (OStream &os,
85 int version) const = 0;
87 virtual void readValueFrom (IStream &is,
91 virtual void copyValueFrom (const Attribute &other) = 0;
98 static Attribute * newAttribute (const char typeName[]);
101 //-----------------------------------------------------------
102 // Test if a given attribute type has already been registered
103 //-----------------------------------------------------------
105 static bool knownType (const char typeName[]);
110 //--------------------------------------------------
111 // Register an attribute type so that newAttribute()
112 // knows how to make objects of this type.
113 //--------------------------------------------------
115 static void registerAttributeType (const char typeName[],
116 Attribute *(*newAttribute)());
118 //------------------------------------------------------
119 // Un-register an attribute type so that newAttribute()
120 // no longer knows how to make objects of this type (for
122 //------------------------------------------------------
124 static void unRegisterAttributeType (const char typeName[]);
128 //-------------------------------------------------
129 // Class template for attributes of a specific type
130 //-------------------------------------------------
133 class TypedAttribute: public Attribute
137 //----------------------------
138 // Constructors and destructor
139 //------------_---------------
142 TypedAttribute (const T &value);
143 TypedAttribute (const TypedAttribute<T> &other);
144 virtual ~TypedAttribute ();
147 //--------------------------------
148 // Access to the attribute's value
149 //--------------------------------
152 const T & value () const;
155 //--------------------------------
156 // Get this attribute's type name.
157 //--------------------------------
159 virtual const char * typeName () const;
162 //---------------------------------------------------------
163 // Static version of typeName()
164 // This function must be specialized for each value type T.
165 //---------------------------------------------------------
167 static const char * staticTypeName ();
170 //---------------------
171 // Make a new attribute
172 //---------------------
174 static Attribute * makeNewAttribute ();
177 //------------------------------
178 // Make a copy of this attribute
179 //------------------------------
181 virtual Attribute * copy () const;
184 //-----------------------------------------------------------------
185 // Type-specific attribute I/O and copying.
186 // Depending on type T, these functions may have to be specialized.
187 //-----------------------------------------------------------------
189 virtual void writeValueTo (OStream &os,
192 virtual void readValueFrom (IStream &is,
196 virtual void copyValueFrom (const Attribute &other);
199 //------------------------------------------------------------
200 // Dynamic casts that throw exceptions instead of returning 0.
201 //------------------------------------------------------------
203 static TypedAttribute * cast (Attribute *attribute);
204 static const TypedAttribute * cast (const Attribute *attribute);
205 static TypedAttribute & cast (Attribute &attribute);
206 static const TypedAttribute & cast (const Attribute &attribute);
209 //---------------------------------------------------------------
210 // Register this attribute type so that Attribute::newAttribute()
211 // knows how to make objects of this type.
213 // Note that this function is not thread-safe because it modifies
214 // a global variable in the IlmIlm library. A thread in a multi-
215 // threaded program may call registerAttributeType() only when no
216 // other thread is accessing any functions or classes in the
219 //---------------------------------------------------------------
221 static void registerAttributeType ();
224 //-----------------------------------------------------
225 // Un-register this attribute type (for debugging only)
226 //-----------------------------------------------------
228 static void unRegisterAttributeType ();
237 //------------------------------------
238 // Implementation of TypedAttribute<T>
239 //------------------------------------
242 TypedAttribute<T>::TypedAttribute (): _value (T())
249 TypedAttribute<T>::TypedAttribute (const T &value): _value (value)
256 TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other):
259 copyValueFrom (other);
264 TypedAttribute<T>::~TypedAttribute ()
272 TypedAttribute<T>::value ()
280 TypedAttribute<T>::value () const
288 TypedAttribute<T>::typeName () const
290 return staticTypeName();
296 TypedAttribute<T>::makeNewAttribute ()
298 return new TypedAttribute<T>();
304 TypedAttribute<T>::copy () const
306 Attribute * attribute = new TypedAttribute<T>();
307 attribute->copyValueFrom (*this);
314 TypedAttribute<T>::writeValueTo (OStream &os, int version) const
316 Xdr::write <StreamIO> (os, _value);
322 TypedAttribute<T>::readValueFrom (IStream &is, int size, int version)
324 Xdr::read <StreamIO> (is, _value);
330 TypedAttribute<T>::copyValueFrom (const Attribute &other)
332 _value = cast(other)._value;
338 TypedAttribute<T>::cast (Attribute *attribute)
340 TypedAttribute<T> *t =
341 dynamic_cast <TypedAttribute<T> *> (attribute);
344 throw Iex::TypeExc ("Unexpected attribute type.");
351 const TypedAttribute<T> *
352 TypedAttribute<T>::cast (const Attribute *attribute)
354 const TypedAttribute<T> *t =
355 dynamic_cast <const TypedAttribute<T> *> (attribute);
358 throw Iex::TypeExc ("Unexpected attribute type.");
365 inline TypedAttribute<T> &
366 TypedAttribute<T>::cast (Attribute &attribute)
368 return *cast (&attribute);
373 inline const TypedAttribute<T> &
374 TypedAttribute<T>::cast (const Attribute &attribute)
376 return *cast (&attribute);
382 TypedAttribute<T>::registerAttributeType ()
384 Attribute::registerAttributeType (staticTypeName(), makeNewAttribute);
390 TypedAttribute<T>::unRegisterAttributeType ()
392 Attribute::unRegisterAttributeType (staticTypeName());
398 #if defined(OPENEXR_DLL) && defined(_MSC_VER)
399 // Tell MS VC++ to disable "non dll-interface class used as base
400 // for dll-interface class" and "no suitable definition provided
401 // for explicit template"
402 #pragma warning (disable : 4275 4661)
404 #if defined (ILMIMF_EXPORTS)
405 #define IMF_EXPIMP_TEMPLATE
407 #define IMF_EXPIMP_TEMPLATE extern
410 IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>;
411 IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>;
413 #pragma warning(default : 4251)
414 #undef EXTERN_TEMPLATE
417 // Metrowerks compiler wants the .cpp file inlined, too
419 #include <ImfAttribute.cpp>