DYT/Tool/OpenSceneGraph-3.6.5/include/OpenEXR/ImfAttribute.h
2024-12-25 07:49:36 +08:00

337 lines
9.2 KiB
C++

//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
#ifndef INCLUDED_IMF_ATTRIBUTE_H
#define INCLUDED_IMF_ATTRIBUTE_H
//-----------------------------------------------------------------------------
//
// class Attribute
//
//-----------------------------------------------------------------------------
#include "ImfForward.h"
#include "ImfIO.h"
#include "ImfXdr.h"
#include "IexBaseExc.h"
#include <cstring>
#include <typeinfo>
#if defined(_MSC_VER)
// suppress warning about non-exported base classes
# pragma warning(push)
# pragma warning(disable : 4251)
# pragma warning(disable : 4275)
#endif
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
class IMF_EXPORT_TYPE Attribute
{
public:
//---------------------------
// Constructor and destructor
//---------------------------
IMF_EXPORT Attribute ();
IMF_EXPORT virtual ~Attribute ();
//-------------------------------
// Get this attribute's type name
//-------------------------------
virtual const char* typeName () const = 0;
//------------------------------
// Make a copy of this attribute
//------------------------------
virtual Attribute* copy () const = 0;
//----------------------------------------
// Type-specific attribute I/O and copying
//----------------------------------------
virtual void writeValueTo (
OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, int version) const = 0;
virtual void readValueFrom (
OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int size, int version) = 0;
virtual void copyValueFrom (const Attribute& other) = 0;
//------------------
// Attribute factory
//------------------
IMF_EXPORT static Attribute* newAttribute (const char typeName[]);
//-----------------------------------------------------------
// Test if a given attribute type has already been registered
//-----------------------------------------------------------
IMF_EXPORT static bool knownType (const char typeName[]);
protected:
//--------------------------------------------------
// Register an attribute type so that newAttribute()
// knows how to make objects of this type.
//--------------------------------------------------
IMF_EXPORT
static void registerAttributeType (
const char typeName[], Attribute* (*newAttribute) ());
//------------------------------------------------------
// Un-register an attribute type so that newAttribute()
// no longer knows how to make objects of this type (for
// debugging only).
//------------------------------------------------------
IMF_EXPORT
static void unRegisterAttributeType (const char typeName[]);
};
//-------------------------------------------------
// Class template for attributes of a specific type
//-------------------------------------------------
template <class T>
class IMF_EXPORT_TEMPLATE_TYPE TypedAttribute : public Attribute
{
public:
//------------------------------------------------------------
// Constructors and destructor: default behavior. This assumes
// that the type T is copyable/assignable/moveable.
//------------------------------------------------------------
TypedAttribute () = default;
TypedAttribute (const T& value);
TypedAttribute (const TypedAttribute<T>& other) = default;
TypedAttribute (TypedAttribute<T>&& other) = default;
//NB: if we use a default destructor, it wreaks havoc with where the vtable and such end up
//at least under mingw+windows, and since we are providing extern template instantiations
//this will be pretty trim and should reduce code bloat
virtual ~TypedAttribute ();
TypedAttribute& operator= (const TypedAttribute<T>& other) = default;
TypedAttribute& operator= (TypedAttribute<T>&& other) = default;
//--------------------------------
// Access to the attribute's value
//--------------------------------
T& value ();
const T& value () const;
//--------------------------------
// Get this attribute's type name.
//--------------------------------
virtual const char* typeName () const;
//---------------------------------------------------------
// Static version of typeName()
// This function must be specialized for each value type T.
//---------------------------------------------------------
static const char* staticTypeName ();
//---------------------
// Make a new attribute
//---------------------
static Attribute* makeNewAttribute ();
//------------------------------
// Make a copy of this attribute
//------------------------------
virtual Attribute* copy () const;
//-----------------------------------------------------------------
// Type-specific attribute I/O and copying.
// Depending on type T, these functions may have to be specialized.
//-----------------------------------------------------------------
virtual void writeValueTo (
OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, int version) const;
virtual void readValueFrom (
OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int size, int version);
virtual void copyValueFrom (const Attribute& other);
//------------------------------------------------------------
// Dynamic casts that throw exceptions instead of returning 0.
//------------------------------------------------------------
static TypedAttribute* cast (Attribute* attribute);
static const TypedAttribute* cast (const Attribute* attribute);
static TypedAttribute& cast (Attribute& attribute);
static const TypedAttribute& cast (const Attribute& attribute);
//---------------------------------------------------------------
// Register this attribute type so that Attribute::newAttribute()
// knows how to make objects of this type.
//
// Note that this function is not thread-safe because it modifies
// a global variable in the IlmIlm library. A thread in a multi-
// threaded program may call registerAttributeType() only when no
// other thread is accessing any functions or classes in the
// OpenEXR library.
//
//---------------------------------------------------------------
static void registerAttributeType ();
//-----------------------------------------------------
// Un-register this attribute type (for debugging only)
//-----------------------------------------------------
static void unRegisterAttributeType ();
private:
T _value;
};
//------------------------------------
// Implementation of TypedAttribute<T>
//------------------------------------
template <class T>
TypedAttribute<T>::TypedAttribute (const T& value)
: Attribute (), _value (value)
{
// empty
}
template <class T> TypedAttribute<T>::~TypedAttribute ()
{
// empty
}
template <class T>
inline T&
TypedAttribute<T>::value ()
{
return _value;
}
template <class T>
inline const T&
TypedAttribute<T>::value () const
{
return _value;
}
template <class T>
const char*
TypedAttribute<T>::typeName () const
{
return staticTypeName ();
}
template <class T>
Attribute*
TypedAttribute<T>::makeNewAttribute ()
{
return new TypedAttribute<T> ();
}
template <class T>
Attribute*
TypedAttribute<T>::copy () const
{
Attribute* attribute = new TypedAttribute<T> ();
attribute->copyValueFrom (*this);
return attribute;
}
template <class T>
void
TypedAttribute<T>::writeValueTo (
OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, int version) const
{
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write<
OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value);
}
template <class T>
void
TypedAttribute<T>::readValueFrom (
OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int size, int version)
{
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read<
OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value);
}
template <class T>
void
TypedAttribute<T>::copyValueFrom (const Attribute& other)
{
_value = cast (other)._value;
}
template <class T>
TypedAttribute<T>*
TypedAttribute<T>::cast (Attribute* attribute)
{
TypedAttribute<T>* t = dynamic_cast<TypedAttribute<T>*> (attribute);
if (t == 0) throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
return t;
}
template <class T>
const TypedAttribute<T>*
TypedAttribute<T>::cast (const Attribute* attribute)
{
const TypedAttribute<T>* t =
dynamic_cast<const TypedAttribute<T>*> (attribute);
if (t == 0) throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
return t;
}
template <class T>
inline TypedAttribute<T>&
TypedAttribute<T>::cast (Attribute& attribute)
{
return *cast (&attribute);
}
template <class T>
inline const TypedAttribute<T>&
TypedAttribute<T>::cast (const Attribute& attribute)
{
return *cast (&attribute);
}
template <class T>
inline void
TypedAttribute<T>::registerAttributeType ()
{
Attribute::registerAttributeType (staticTypeName (), makeNewAttribute);
}
template <class T>
inline void
TypedAttribute<T>::unRegisterAttributeType ()
{
Attribute::unRegisterAttributeType (staticTypeName ());
}
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif