From 1928016fe7aa439d4bfb61d3a7e7b7399ca7a229 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 12 Jul 2009 21:17:25 +0000 Subject: Fix Array's of objects which wrap their C types by value. --- libdimensionxx/dimensionxx/array.hpp | 59 +++++++++++++++++++++++++++++++-- libdimensionxx/dimensionxx/color.hpp | 9 +++-- libdimensionxx/dimensionxx/geometry.hpp | 27 +++++++-------- 3 files changed, 72 insertions(+), 23 deletions(-) (limited to 'libdimensionxx') diff --git a/libdimensionxx/dimensionxx/array.hpp b/libdimensionxx/dimensionxx/array.hpp index aa1f805..e9c2967 100644 --- a/libdimensionxx/dimensionxx/array.hpp +++ b/libdimensionxx/dimensionxx/array.hpp @@ -51,7 +51,10 @@ namespace Dimension // Array_Element& operator=(const Array_Element& ae); C_Type dmnsn() const { return m_t; } - T& object(C_Type* c) const { return *c; } + T& object(C_Type& c) const { return c; } + + // Must the dmnsn_array* be rebuilt on every access? + static const bool must_rebuild = false; private: T m_t; @@ -95,6 +98,32 @@ namespace Dimension std::tr1::shared_ptr m_array; std::vector > m_elements; + + inline void rebuild() const; + }; + + // Base class for non-polymorphic wrappers + template + class By_Value_Array_Element + { + public: + typedef C C_Type; + + By_Value_Array_Element() : m_object(new T()) { } + By_Value_Array_Element(const T& object) : m_object(new T(object)) { } + By_Value_Array_Element(C_Type c) : m_object(new T(c)) { } + // By_Value_Array_Element(const By_Value_Array_Element& ae); + // ~By_Value_Array_Element(); + + // By_Value_Array_Element& operator=(const By_Value_Array_Element& ae); + + C_Type dmnsn() const { return m_object->dmnsn(); } + T& object(C_Type& c) const { *m_object = T(c); return *m_object; } + + static const bool must_rebuild = true; + + private: + std::tr1::shared_ptr m_object; }; // Base class for non-polymorphic wrappers @@ -116,7 +145,9 @@ namespace Dimension // DMNSN_Array_Element& operator=(const DMNSN_Array_Element& ae); C_Type dmnsn() const { return m_object->dmnsn(); } - T& object(C_Type* c) const { return *m_object; } + T& object(C_Type& c) const { return *m_object; } + + static const bool must_rebuild = false; private: std::tr1::shared_ptr m_object; @@ -149,7 +180,9 @@ namespace Dimension // Polymorphic_Array_Element& operator=(const Polymorphic_Array_Element& e); C_Type dmnsn() const { return m_object->dmnsn(); } - T& object(C_Type* c) const { return *m_object; } + T& object(C_Type& c) const { return *m_object; } + + static const bool must_rebuild = false; private: std::tr1::shared_ptr m_object; @@ -279,6 +312,10 @@ namespace Dimension throw Dimension_Error("Attempting to access released array."); } + if (Array_Element::must_rebuild) { + rebuild(); + } + return *m_array; } @@ -290,6 +327,10 @@ namespace Dimension throw Dimension_Error("Attempting to access released array."); } + if (Array_Element::must_rebuild) { + rebuild(); + } + return *m_array; } @@ -307,6 +348,18 @@ namespace Dimension return array; } } + + // Rebuild the dmnsn_array* from the C++ elements, needed if the C++ objects + // wrap their C objects by value, not reference + template + inline void + Array::rebuild() const + { + for (std::size_t i = 0; i < size(); ++i) { + C_Type c = m_elements[i].dmnsn(); + dmnsn_array_set(*m_array, i, &c); + } + } } #endif /* DIMENSIONXX_ARRAY_HPP */ diff --git a/libdimensionxx/dimensionxx/color.hpp b/libdimensionxx/dimensionxx/color.hpp index 7d804f5..ad28c4d 100644 --- a/libdimensionxx/dimensionxx/color.hpp +++ b/libdimensionxx/dimensionxx/color.hpp @@ -203,17 +203,16 @@ namespace Dimension // Array_Element specialization template <> class Array_Element - : public DMNSN_Array_Element + : public By_Value_Array_Element { public: typedef dmnsn_color C_Type; - Array_Element() - : DMNSN_Array_Element(Color()) { } + Array_Element() { } Array_Element(Color& color) - : DMNSN_Array_Element(color) { } + : By_Value_Array_Element(color) { } Array_Element(C_Type c) - : DMNSN_Array_Element(c) { } + : By_Value_Array_Element(c) { } // Array_Element(const Array_Element& ae); // ~Array_Element(); diff --git a/libdimensionxx/dimensionxx/geometry.hpp b/libdimensionxx/dimensionxx/geometry.hpp index 4da6f47..671e204 100644 --- a/libdimensionxx/dimensionxx/geometry.hpp +++ b/libdimensionxx/dimensionxx/geometry.hpp @@ -138,17 +138,16 @@ namespace Dimension template <> class Array_Element - : public DMNSN_Array_Element + : public By_Value_Array_Element { public: typedef dmnsn_matrix C_Type; - Array_Element() - : DMNSN_Array_Element(Matrix()) { } + Array_Element() { } Array_Element(Matrix& matrix) - : DMNSN_Array_Element(matrix) { } + : By_Value_Array_Element(matrix) { } Array_Element(C_Type c) - : DMNSN_Array_Element(c) { } + : By_Value_Array_Element(c) { } // Array_Element(const Array_Element& ae); // ~Array_Element(); @@ -157,17 +156,16 @@ namespace Dimension template <> class Array_Element - : public DMNSN_Array_Element + : public By_Value_Array_Element { public: typedef dmnsn_vector C_Type; - Array_Element() - : DMNSN_Array_Element(Vector()) { } + Array_Element() { } Array_Element(Vector& vector) - : DMNSN_Array_Element(vector) { } + : By_Value_Array_Element(vector) { } Array_Element(C_Type c) - : DMNSN_Array_Element(c) { } + : By_Value_Array_Element(c) { } // Array_Element(const Array_Element& ae); // ~Array_Element(); @@ -176,17 +174,16 @@ namespace Dimension template <> class Array_Element - : public DMNSN_Array_Element + : public By_Value_Array_Element { public: typedef dmnsn_line C_Type; - Array_Element() - : DMNSN_Array_Element(Line()) { } + Array_Element() { } Array_Element(Line& line) - : DMNSN_Array_Element(line) { } + : By_Value_Array_Element(line) { } Array_Element(C_Type c) - : DMNSN_Array_Element(c) { } + : By_Value_Array_Element(c) { } // Array_Element(const Array_Element& ae); // ~Array_Element(); -- cgit v1.2.3