summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@gmail.com>2009-07-12 21:17:25 +0000
committerTavian Barnes <tavianator@gmail.com>2009-07-12 21:17:25 +0000
commit1928016fe7aa439d4bfb61d3a7e7b7399ca7a229 (patch)
treeacc592fefdeb322cc4d2f4b9c8cfe0f3780c8fe3
parent597b9a13dae1f514ca8afa56bab008cb67d4ac40 (diff)
downloaddimension-1928016fe7aa439d4bfb61d3a7e7b7399ca7a229.tar.xz
Fix Array's of objects which wrap their C types by value.
-rw-r--r--libdimensionxx/dimensionxx/array.hpp59
-rw-r--r--libdimensionxx/dimensionxx/color.hpp9
-rw-r--r--libdimensionxx/dimensionxx/geometry.hpp27
3 files changed, 72 insertions, 23 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 */
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<Color>
- : public DMNSN_Array_Element<Color, dmnsn_color>
+ : public By_Value_Array_Element<Color, dmnsn_color>
{
public:
typedef dmnsn_color C_Type;
- Array_Element()
- : DMNSN_Array_Element<Color, dmnsn_color>(Color()) { }
+ Array_Element() { }
Array_Element(Color& color)
- : DMNSN_Array_Element<Color, dmnsn_color>(color) { }
+ : By_Value_Array_Element<Color, dmnsn_color>(color) { }
Array_Element(C_Type c)
- : DMNSN_Array_Element<Color, dmnsn_color>(c) { }
+ : By_Value_Array_Element<Color, dmnsn_color>(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<Matrix>
- : public DMNSN_Array_Element<Matrix, dmnsn_matrix>
+ : public By_Value_Array_Element<Matrix, dmnsn_matrix>
{
public:
typedef dmnsn_matrix C_Type;
- Array_Element()
- : DMNSN_Array_Element<Matrix, dmnsn_matrix>(Matrix()) { }
+ Array_Element() { }
Array_Element(Matrix& matrix)
- : DMNSN_Array_Element<Matrix, dmnsn_matrix>(matrix) { }
+ : By_Value_Array_Element<Matrix, dmnsn_matrix>(matrix) { }
Array_Element(C_Type c)
- : DMNSN_Array_Element<Matrix, dmnsn_matrix>(c) { }
+ : By_Value_Array_Element<Matrix, dmnsn_matrix>(c) { }
// Array_Element(const Array_Element& ae);
// ~Array_Element();
@@ -157,17 +156,16 @@ namespace Dimension
template <>
class Array_Element<Vector>
- : public DMNSN_Array_Element<Vector, dmnsn_vector>
+ : public By_Value_Array_Element<Vector, dmnsn_vector>
{
public:
typedef dmnsn_vector C_Type;
- Array_Element()
- : DMNSN_Array_Element<Vector, dmnsn_vector>(Vector()) { }
+ Array_Element() { }
Array_Element(Vector& vector)
- : DMNSN_Array_Element<Vector, dmnsn_vector>(vector) { }
+ : By_Value_Array_Element<Vector, dmnsn_vector>(vector) { }
Array_Element(C_Type c)
- : DMNSN_Array_Element<Vector, dmnsn_vector>(c) { }
+ : By_Value_Array_Element<Vector, dmnsn_vector>(c) { }
// Array_Element(const Array_Element& ae);
// ~Array_Element();
@@ -176,17 +174,16 @@ namespace Dimension
template <>
class Array_Element<Line>
- : public DMNSN_Array_Element<Line, dmnsn_line>
+ : public By_Value_Array_Element<Line, dmnsn_line>
{
public:
typedef dmnsn_line C_Type;
- Array_Element()
- : DMNSN_Array_Element<Line, dmnsn_line>(Line()) { }
+ Array_Element() { }
Array_Element(Line& line)
- : DMNSN_Array_Element<Line, dmnsn_line>(line) { }
+ : By_Value_Array_Element<Line, dmnsn_line>(line) { }
Array_Element(C_Type c)
- : DMNSN_Array_Element<Line, dmnsn_line>(c) { }
+ : By_Value_Array_Element<Line, dmnsn_line>(c) { }
// Array_Element(const Array_Element& ae);
// ~Array_Element();