Skip to content

Commit

Permalink
=default copy/move/assign for TypedAttribute
Browse files Browse the repository at this point in the history
TypedAttribute assumes that the T class supports copy/move/assign
operations, so it should, too.

Also, the move/moveassign operators for OStream/IStream incorrectly
declared their arguments as const.

Signed-off-by: Cary Phillips <cary@ilm.com>
  • Loading branch information
cary-ilm committed Nov 14, 2019
1 parent fa2e458 commit b7857b9
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 38 deletions.
45 changes: 11 additions & 34 deletions OpenEXR/IlmImf/ImfAttribute.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,20 @@ class TypedAttribute: public Attribute
{
public:

//----------------------------
// Constructors and destructor
//------------_---------------
//------------------------------------------------------------
// Constructors and destructor: default behavior. This assumes
// that the type T is copyable/assignable/moveable.
//------------------------------------------------------------

TypedAttribute ();
TypedAttribute () = default;
TypedAttribute (const T &value);
TypedAttribute (const TypedAttribute<T> &other);
virtual ~TypedAttribute ();
TypedAttribute (const TypedAttribute<T> &other) = default;
TypedAttribute (TypedAttribute<T> &&other) = default;

virtual ~TypedAttribute () = default;

TypedAttribute& operator = (const TypedAttribute& other) = delete;
TypedAttribute (const TypedAttribute<T> &&other);
TypedAttribute& operator = (const TypedAttribute&& other) = delete;
TypedAttribute& operator = (const TypedAttribute<T>& other) = default;
TypedAttribute& operator = (TypedAttribute<T>&& other) = default;

//--------------------------------
// Access to the attribute's value
Expand Down Expand Up @@ -247,14 +249,6 @@ class TypedAttribute: public Attribute
//------------------------------------
// Implementation of TypedAttribute<T>
//------------------------------------
template <class T>
TypedAttribute<T>::TypedAttribute ():
Attribute (),
_value (T())
{
// empty
}


template <class T>
TypedAttribute<T>::TypedAttribute (const T & value):
Expand All @@ -264,23 +258,6 @@ TypedAttribute<T>::TypedAttribute (const T & value):
// empty
}


template <class T>
TypedAttribute<T>::TypedAttribute (const TypedAttribute<T> &other):
Attribute (other),
_value ()
{
copyValueFrom (other);
}


template <class T>
TypedAttribute<T>::~TypedAttribute ()
{
// empty
}


template <class T>
inline T &
TypedAttribute<T>::value ()
Expand Down
8 changes: 4 additions & 4 deletions OpenEXR/IlmImf/ImfIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ class IStream

IStream (const IStream &) = delete;
IStream & operator = (const IStream &) = delete;
IStream (const IStream &&) = delete;
IStream & operator = (const IStream &&) = delete;
IStream (IStream &&) = delete;
IStream & operator = (IStream &&) = delete;

std::string _fileName;
};
Expand Down Expand Up @@ -217,8 +217,8 @@ class OStream

OStream (const OStream &) = delete;
OStream & operator = (const OStream &) = delete;
OStream (const OStream &&) = delete;
OStream & operator = (const OStream &&) = delete;
OStream (OStream &&) = delete;
OStream & operator = (OStream &&) = delete;

std::string _fileName;
};
Expand Down
217 changes: 217 additions & 0 deletions OpenEXR/IlmImfTest/testAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,13 +578,230 @@ print_type(const OPENEXR_IMF_NAMESPACE::TypedAttribute<T> & object)
cout << object.typeName() << endl;
}

//
// Test to confirm that the copy/move constructors are implemented
// properly.
//

static int default_constructor;
static int destructor;
static int copy_constructor;
static int assignment_operator;
static int move_constructor;
static int move_assignment_operator;

struct TestType
{
TestType()
{
default_constructor++;
}

~TestType()
{
destructor++;
}

TestType (const TestType& other)
: _f (other._f)
{
copy_constructor++;
}

TestType& operator = (const TestType& other)
{
assignment_operator++;
_f = other._f;
return *this;
}

TestType (TestType&& other)
: _f (std::move (other._f))
{
move_constructor++;
}

TestType& operator = (TestType&& other)
{
move_assignment_operator++;
_f = std::move (other._f);
return *this;
}

static TestType func()
{
TestType t;
return t;
}

static TestType arg (TestType a)
{
return a;
}

int _f;

static void assert_count (int dc, int d, int cc, int ao, int mc, int mao)
{
assert (dc == default_constructor);
assert (d == destructor);
assert (cc == copy_constructor);
assert (ao == assignment_operator);
assert (mc == move_constructor);
assert (mao == move_assignment_operator);
}

static void reset()
{
default_constructor = 0;
destructor = 0;
copy_constructor = 0;
assignment_operator = 0;
move_constructor = 0;
move_assignment_operator = 0;
}

static std::string str()
{
std::stringstream s;
if (default_constructor)
s << "default_constructor=" << default_constructor << std::endl;
if (destructor)
s << "destructor=" << destructor << std::endl;

if (copy_constructor)
s << "copy_constructor=" << copy_constructor << std::endl;

if (assignment_operator)
s << "assignment_operator=" << assignment_operator << std::endl;
if (move_constructor)
s << "move_constructor=" << move_constructor << std::endl;

if (move_assignment_operator)
s << "move_assignment_operator=" << move_assignment_operator << std::endl;
return s.str();
}
};

typedef Imf::TypedAttribute<TestType> TestTypedAttribute;

template <>
const char *
TestTypedAttribute::staticTypeName ()
{
return "test";
}

template <>
void
TestTypedAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
{
}

template <>
void
TestTypedAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
{
}

TestType
testTypeFunc()
{
return TestType();
}

TestTypedAttribute
testFunc()
{
TestTypedAttribute a;
return a;
}

TestTypedAttribute
testArg (TestTypedAttribute a)
{
return a;
}

void
testTypedAttribute()
{
std::cout << "running testTypedAttribute()\n";

//
// Validate the test type
//

TestType A;
TestType::assert_count (1, 0, 0, 0, 0, 0);
TestType::reset();

TestType B (A);
TestType::assert_count (0, 0, 1, 0, 0, 0);
TestType::reset();

B = A;
TestType::assert_count (0, 0, 0, 1, 0, 0);
TestType::reset();

A = std::move (B);
TestType::assert_count (0, 0, 0, 0, 0, 1);
TestType::reset();

A = TestType::func();
TestType::assert_count (1, 1, 0, 0, 0, 1);
TestType::reset();

A = TestType::arg(B);
TestType::assert_count (0, 2, 1, 0, 1, 1);
TestType::reset();

//
// Test the attribute type
//

TestTypedAttribute a;
TestType::assert_count (1, 0, 0, 0, 0, 0);
TestType::reset();

{
TestType x;
}
TestType::assert_count (1, 1, 0, 0, 0, 0);
TestType::reset();

TestTypedAttribute b(a);
TestType::assert_count (0, 0, 1, 0, 0, 0);
TestType::reset();

a = b;
TestType::assert_count (0, 0, 0, 1, 0, 0);
TestType::reset();

a = std::move (b);
TestType::assert_count (0, 0, 0, 0, 0, 1);
TestType::reset();

a = testFunc();
TestType::assert_count (1, 1, 0, 0, 0, 1);
TestType::reset();

a = testArg(b);
TestType::assert_count (0, 2, 1, 0, 1, 1);
TestType::reset();

std::cout << "ok." << std::endl;
}

void
testAttributes (const std::string &tempDir)
{
try
{
cout << "Testing built-in attributes" << endl;

testTypedAttribute();

const int W = 217;
const int H = 197;

Expand Down

0 comments on commit b7857b9

Please sign in to comment.