diff options
author | Tavian Barnes <tavianator@gmail.com> | 2009-07-12 21:17:25 +0000 |
---|---|---|
committer | Tavian Barnes <tavianator@gmail.com> | 2009-07-12 21:17:25 +0000 |
commit | 1928016fe7aa439d4bfb61d3a7e7b7399ca7a229 (patch) | |
tree | acc592fefdeb322cc4d2f4b9c8cfe0f3780c8fe3 /libdimensionxx/dimensionxx/array.hpp | |
parent | 597b9a13dae1f514ca8afa56bab008cb67d4ac40 (diff) | |
download | dimension-1928016fe7aa439d4bfb61d3a7e7b7399ca7a229.tar.xz |
Fix Array's of objects which wrap their C types by value.
Diffstat (limited to 'libdimensionxx/dimensionxx/array.hpp')
-rw-r--r-- | libdimensionxx/dimensionxx/array.hpp | 59 |
1 files changed, 56 insertions, 3 deletions
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<dmnsn_array*> m_array; std::vector<Array_Element<T> > m_elements; + + inline void rebuild() const; + }; + + // Base class for non-polymorphic wrappers + template <typename T, typename C> + 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<T> 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<T> 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<T> m_object; @@ -279,6 +312,10 @@ namespace Dimension throw Dimension_Error("Attempting to access released array."); } + if (Array_Element<T>::must_rebuild) { + rebuild(); + } + return *m_array; } @@ -290,6 +327,10 @@ namespace Dimension throw Dimension_Error("Attempting to access released array."); } + if (Array_Element<T>::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 <typename T> + inline void + Array<T>::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 */ |