PBRT
/home/felix/UBC/projects/AdaptiveLightfieldSampling/pbrt_v2/src/3rdparty/openexr-1.7.0/ImfAttribute.h
00001 
00002 //
00003 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
00004 // Digital Ltd. LLC
00005 // 
00006 // All rights reserved.
00007 // 
00008 // Redistribution and use in source and binary forms, with or without
00009 // modification, are permitted provided that the following conditions are
00010 // met:
00011 // *       Redistributions of source code must retain the above copyright
00012 // notice, this list of conditions and the following disclaimer.
00013 // *       Redistributions in binary form must reproduce the above
00014 // copyright notice, this list of conditions and the following disclaimer
00015 // in the documentation and/or other materials provided with the
00016 // distribution.
00017 // *       Neither the name of Industrial Light & Magic nor the names of
00018 // its contributors may be used to endorse or promote products derived
00019 // from this software without specific prior written permission. 
00020 // 
00021 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00024 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00025 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00027 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00028 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00029 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00030 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00031 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00032 //
00034 
00035 
00036 
00037 #ifndef INCLUDED_IMF_ATTRIBUTE_H
00038 #define INCLUDED_IMF_ATTRIBUTE_H
00039 
00040 //-----------------------------------------------------------------------------
00041 //
00042 //      class Attribute
00043 //
00044 //-----------------------------------------------------------------------------
00045 
00046 #include "IexBaseExc.h"
00047 #include <ImfIO.h>
00048 #include <ImfXdr.h>
00049 
00050 
00051 namespace Imf {
00052 
00053 
00054 class Attribute
00055 {
00056   public:
00057 
00058     //---------------------------
00059     // Constructor and destructor
00060     //---------------------------
00061 
00062     Attribute ();
00063     virtual ~Attribute ();
00064 
00065 
00066     //-------------------------------
00067     // Get this attribute's type name
00068     //-------------------------------
00069 
00070     virtual const char *        typeName () const = 0;
00071 
00072 
00073     //------------------------------
00074     // Make a copy of this attribute
00075     //------------------------------
00076 
00077     virtual Attribute *         copy () const = 0;
00078 
00079 
00080     //----------------------------------------
00081     // Type-specific attribute I/O and copying
00082     //----------------------------------------
00083 
00084     virtual void                writeValueTo (OStream &os,
00085                                               int version) const = 0;
00086 
00087     virtual void                readValueFrom (IStream &is,
00088                                                int size,
00089                                                int version) = 0;
00090 
00091     virtual void                copyValueFrom (const Attribute &other) = 0;
00092 
00093 
00094     //------------------
00095     // Attribute factory
00096     //------------------
00097 
00098     static Attribute *          newAttribute (const char typeName[]);
00099 
00100 
00101     //-----------------------------------------------------------
00102     // Test if a given attribute type has already been registered
00103     //-----------------------------------------------------------
00104 
00105     static bool                 knownType (const char typeName[]);
00106 
00107 
00108   protected:
00109 
00110     //--------------------------------------------------
00111     // Register an attribute type so that newAttribute()
00112     // knows how to make objects of this type.
00113     //--------------------------------------------------
00114 
00115     static void         registerAttributeType (const char typeName[],
00116                                                Attribute *(*newAttribute)());
00117 
00118     //------------------------------------------------------
00119     // Un-register an attribute type so that newAttribute()
00120     // no longer knows how to make objects of this type (for
00121     // debugging only).
00122     //------------------------------------------------------
00123 
00124     static void         unRegisterAttributeType (const char typeName[]);
00125 };
00126 
00127 
00128 //-------------------------------------------------
00129 // Class template for attributes of a specific type
00130 //-------------------------------------------------
00131 
00132 template <class T>
00133 class TypedAttribute: public Attribute
00134 {
00135   public:
00136 
00137     //----------------------------
00138     // Constructors and destructor
00139     //------------_---------------
00140 
00141     TypedAttribute ();
00142     TypedAttribute (const T &value);
00143     TypedAttribute (const TypedAttribute<T> &other);
00144     virtual ~TypedAttribute ();
00145 
00146 
00147     //--------------------------------
00148     // Access to the attribute's value
00149     //--------------------------------
00150 
00151     T &                                 value ();
00152     const T &                           value () const;
00153 
00154 
00155     //--------------------------------
00156     // Get this attribute's type name.
00157     //--------------------------------
00158 
00159     virtual const char *                typeName () const;
00160     
00161 
00162     //---------------------------------------------------------
00163     // Static version of typeName()
00164     // This function must be specialized for each value type T.
00165     //---------------------------------------------------------
00166 
00167     static const char *                 staticTypeName ();
00168     
00169 
00170     //---------------------
00171     // Make a new attribute
00172     //---------------------
00173 
00174     static Attribute *                  makeNewAttribute ();
00175 
00176 
00177     //------------------------------
00178     // Make a copy of this attribute
00179     //------------------------------
00180 
00181     virtual Attribute *                 copy () const;
00182 
00183 
00184     //-----------------------------------------------------------------
00185     // Type-specific attribute I/O and copying.
00186     // Depending on type T, these functions may have to be specialized.
00187     //-----------------------------------------------------------------
00188 
00189     virtual void                writeValueTo (OStream &os,
00190                                               int version) const;
00191 
00192     virtual void                readValueFrom (IStream &is,
00193                                                int size,
00194                                                int version);
00195 
00196     virtual void                copyValueFrom (const Attribute &other);
00197 
00198 
00199     //------------------------------------------------------------
00200     // Dynamic casts that throw exceptions instead of returning 0.
00201     //------------------------------------------------------------
00202 
00203     static TypedAttribute *             cast (Attribute *attribute);
00204     static const TypedAttribute *       cast (const Attribute *attribute);
00205     static TypedAttribute &             cast (Attribute &attribute);
00206     static const TypedAttribute &       cast (const Attribute &attribute);
00207 
00208 
00209     //---------------------------------------------------------------
00210     // Register this attribute type so that Attribute::newAttribute()
00211     // knows how to make objects of this type.
00212     //
00213     // Note that this function is not thread-safe because it modifies
00214     // a global variable in the IlmIlm library.  A thread in a multi-
00215     // threaded program may call registerAttributeType() only when no
00216     // other thread is accessing any functions or classes in the
00217     // IlmImf library.
00218     //
00219     //---------------------------------------------------------------
00220 
00221     static void                         registerAttributeType ();
00222 
00223 
00224     //-----------------------------------------------------
00225     // Un-register this attribute type (for debugging only)
00226     //-----------------------------------------------------
00227 
00228     static void                          unRegisterAttributeType ();
00229 
00230 
00231   private:
00232 
00233     T                                   _value;
00234 };
00235 
00236 
00237 //------------------------------------
00238 // Implementation of TypedAttribute<T>
00239 //------------------------------------
00240 
00241 template <class T>
00242 TypedAttribute<T>::TypedAttribute ():
00243     Attribute (),
00244     _value (T())
00245 {
00246     // empty
00247 }
00248 
00249 
00250 template <class T>
00251 TypedAttribute<T>::TypedAttribute (const T &value):
00252     Attribute (),
00253     _value (value)
00254 {
00255     // empty
00256 }
00257 
00258 
00259 template <class T>
00260 TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other):
00261     Attribute (other),
00262     _value ()
00263 {
00264     copyValueFrom (other);
00265 }
00266 
00267 
00268 template <class T>
00269 TypedAttribute<T>::~TypedAttribute ()
00270 {
00271     // empty
00272 }
00273 
00274 
00275 template <class T>
00276 inline T &
00277 TypedAttribute<T>::value ()
00278 {
00279     return _value;
00280 }
00281 
00282 
00283 template <class T>
00284 inline const T &
00285 TypedAttribute<T>::value () const
00286 {
00287     return _value;
00288 }
00289 
00290 
00291 template <class T>
00292 const char *    
00293 TypedAttribute<T>::typeName () const
00294 {
00295     return staticTypeName();
00296 }
00297 
00298 
00299 template <class T>
00300 Attribute *
00301 TypedAttribute<T>::makeNewAttribute ()
00302 {
00303     return new TypedAttribute<T>();
00304 }
00305 
00306 
00307 template <class T>
00308 Attribute *
00309 TypedAttribute<T>::copy () const
00310 {
00311     Attribute * attribute = new TypedAttribute<T>();
00312     attribute->copyValueFrom (*this);
00313     return attribute;
00314 }
00315 
00316 
00317 template <class T>
00318 void            
00319 TypedAttribute<T>::writeValueTo (OStream &os, int version) const
00320 {
00321     Xdr::write <StreamIO> (os, _value);
00322 }
00323 
00324 
00325 template <class T>
00326 void            
00327 TypedAttribute<T>::readValueFrom (IStream &is, int size, int version)
00328 {
00329     Xdr::read <StreamIO> (is, _value);
00330 }
00331 
00332 
00333 template <class T>
00334 void            
00335 TypedAttribute<T>::copyValueFrom (const Attribute &other)
00336 {
00337     _value = cast(other)._value;
00338 }
00339 
00340 
00341 template <class T>
00342 TypedAttribute<T> *
00343 TypedAttribute<T>::cast (Attribute *attribute)
00344 {
00345     TypedAttribute<T> *t =
00346         dynamic_cast <TypedAttribute<T> *> (attribute);
00347 
00348     if (t == 0)
00349         throw Iex::TypeExc ("Unexpected attribute type.");
00350 
00351     return t;
00352 }
00353 
00354 
00355 template <class T>
00356 const TypedAttribute<T> *
00357 TypedAttribute<T>::cast (const Attribute *attribute)
00358 {
00359     const TypedAttribute<T> *t =
00360         dynamic_cast <const TypedAttribute<T> *> (attribute);
00361 
00362     if (t == 0)
00363         throw Iex::TypeExc ("Unexpected attribute type.");
00364 
00365     return t;
00366 }
00367 
00368 
00369 template <class T>
00370 inline TypedAttribute<T> &      
00371 TypedAttribute<T>::cast (Attribute &attribute)
00372 {
00373     return *cast (&attribute);
00374 }
00375 
00376 
00377 template <class T>
00378 inline const TypedAttribute<T> &
00379 TypedAttribute<T>::cast (const Attribute &attribute)
00380 {
00381     return *cast (&attribute);
00382 }
00383 
00384 
00385 template <class T>
00386 inline void
00387 TypedAttribute<T>::registerAttributeType ()
00388 {
00389     Attribute::registerAttributeType (staticTypeName(), makeNewAttribute);
00390 }
00391 
00392 
00393 template <class T>
00394 inline void
00395 TypedAttribute<T>::unRegisterAttributeType ()
00396 {
00397     Attribute::unRegisterAttributeType (staticTypeName());
00398 }
00399 
00400 
00401 } // namespace Imf
00402 
00403 #if defined(OPENEXR_DLL) && defined(_MSC_VER)
00404     // Tell MS VC++ to disable "non dll-interface class used as base
00405     // for dll-interface class" and "no suitable definition provided
00406     // for explicit template"
00407     #pragma warning (disable : 4275 4661)
00408 
00409     #if defined (ILMIMF_EXPORTS)
00410         #define IMF_EXPIMP_TEMPLATE
00411     #else
00412         #define IMF_EXPIMP_TEMPLATE extern
00413     #endif
00414 
00415     IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>;
00416     IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>;
00417 
00418     #pragma warning(default : 4251)
00419     #undef EXTERN_TEMPLATE
00420 #endif
00421 
00422 // Metrowerks compiler wants the .cpp file inlined, too
00423 #ifdef __MWERKS__
00424 #include <ImfAttribute.cpp>
00425 #endif
00426 
00427 #endif