aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-03-11 15:09:17 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-03-11 15:09:17 +0200
commitf8bb2faef4b272ed150eb3ca4cedaa79da410694 (patch)
treefff08a4d3ce6380709c84dc6b93d02de097dd7d5
parentda1ce0f39a36a2fca1f8d51a67b92be6368ddbfd (diff)
Allow initialization of pod_seq and fix_seq from a C array
Use this in the hybrid/binary/custom example.
-rw-r--r--NEWS6
-rw-r--r--documentation/cxx/hybrid/guide/index.xhtml11
-rw-r--r--examples/cxx/hybrid/binary/custom/irawstream.txx8
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.hxx14
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.ixx30
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.txx28
-rw-r--r--libxsde/xsde/cxx/sequence-base.hxx2
-rw-r--r--tests/cxx/hybrid/sequences/driver.cxx9
8 files changed, 98 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index fc57707..35c8f2d 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,12 @@ Version 3.1.0
optimized non-recursive case (i.e., the first iteration still does
not result in any heap allocations for the state maintenance).
+ * Assignment function with signature assign(const T*, size_t) for
+ sequences of fixed-length types. With this function you can, for
+ example, initialize a sequence with a C array. Assignment of
+ sequences of fundamental types (e.g., int, float, etc.) is
+ implemented in terms of memcpy().
+
Version 3.0.0
* The new Embedded C++/Hybrid mapping provides a light-weight, tree-
diff --git a/documentation/cxx/hybrid/guide/index.xhtml b/documentation/cxx/hybrid/guide/index.xhtml
index 9a95473..f9ffccb 100644
--- a/documentation/cxx/hybrid/guide/index.xhtml
+++ b/documentation/cxx/hybrid/guide/index.xhtml
@@ -2008,12 +2008,16 @@ public:
void
reserve (size_t);
+
+ void
+ assign (const T* src, size_t n);
};
</pre>
<p>When C++ exceptions are disabled, the signatures of the
- <code>push_back()</code>, <code>insert()</code>, and
- <code>reserve()</code> functions change as follows:</p>
+ <code>push_back()</code>, <code>insert()</code>,
+ <code>reserve()</code>, and <code>assign()</code> functions
+ change as follows:</p>
<pre class="c++">
template &lt;typename T>
@@ -2040,6 +2044,9 @@ public:
error
reserve (size_t);
+
+ error
+ assign (const T* src, size_t n);
};
</pre>
diff --git a/examples/cxx/hybrid/binary/custom/irawstream.txx b/examples/cxx/hybrid/binary/custom/irawstream.txx
index 2d4965e..b1bf757 100644
--- a/examples/cxx/hybrid/binary/custom/irawstream.txx
+++ b/examples/cxx/hybrid/binary/custom/irawstream.txx
@@ -15,12 +15,8 @@ operator>> (irawstream& s, xml_schema::pod_seq<T>& x)
x.clear ();
if (n > 0)
- {
- x.reserve (n);
- size_t mn = sizeof (T) * n;
- memcpy (x.data_, s.align (sizeof (T), mn), mn);
- x.size_ = n;
- }
+ x.assign (
+ reinterpret_cast<const T*> (s.align (sizeof (T), sizeof (T) * n)), n);
}
template <typename T>
diff --git a/libxsde/xsde/cxx/hybrid/sequence.hxx b/libxsde/xsde/cxx/hybrid/sequence.hxx
index 3e43b6d..6d8f33b 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.hxx
+++ b/libxsde/xsde/cxx/hybrid/sequence.hxx
@@ -110,6 +110,13 @@ namespace xsde
#endif
reserve (size_t);
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ assign (const T*, size_t);
+
void
swap (pod_seq&);
};
@@ -204,6 +211,13 @@ namespace xsde
#endif
reserve (size_t);
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ assign (const T*, size_t);
+
void
swap (fix_seq&);
diff --git a/libxsde/xsde/cxx/hybrid/sequence.ixx b/libxsde/xsde/cxx/hybrid/sequence.ixx
index c1566d2..11bc13d 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.ixx
+++ b/libxsde/xsde/cxx/hybrid/sequence.ixx
@@ -3,7 +3,9 @@
// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
-#include <new> // placement new
+#include <string.h> // memcpy
+
+#include <new> // placement new
namespace xsde
{
@@ -154,6 +156,17 @@ namespace xsde
if (capacity_ < n)
grow_ (n, sizeof (T), 0);
}
+
+ template <typename T>
+ inline void pod_seq<T>::
+ assign (const T* p, size_t n)
+ {
+ if (capacity_ < n)
+ grow_ (n, sizeof (T), 0);
+
+ memcpy (data_, p, n * sizeof (T));
+ size_ = n;
+ }
#else
template <typename T>
inline sequence_base::error pod_seq<T>::
@@ -210,6 +223,21 @@ namespace xsde
r = grow_ (n, sizeof (T), 0);
return r;
}
+
+ template <typename T>
+ inline sequence_base::error pod_seq<T>::
+ assign (const T* p, size_t n)
+ {
+ if (capacity_ < n)
+ {
+ if (error r = grow_ (n, sizeof (T), 0))
+ return r;
+ }
+
+ memcpy (data_, p, n * sizeof (T));
+ size_ = n;
+ return error_none;
+ }
#endif
//
diff --git a/libxsde/xsde/cxx/hybrid/sequence.txx b/libxsde/xsde/cxx/hybrid/sequence.txx
index 12faa99..a81ad11 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.txx
+++ b/libxsde/xsde/cxx/hybrid/sequence.txx
@@ -28,6 +28,34 @@ namespace xsde
#ifdef XSDE_EXCEPTIONS
template <typename T>
void fix_seq<T>::
+ assign (const T* p, size_t n)
+ {
+ clear ();
+ reserve (n);
+
+ for (; size_ < n; ++size_)
+ new (static_cast<T*> (data_) + size_) T (p[size_]);
+ }
+#else
+ template <typename T>
+ sequence_base::error fix_seq<T>::
+ assign (const T* p, size_t n)
+ {
+ clear ();
+
+ if (error r = reserve (n))
+ return r;
+
+ for (; size_ < n; ++size_)
+ new (static_cast<T*> (data_) + size_) T (p[size_]);
+
+ return error_none;
+ }
+#endif
+
+#ifdef XSDE_EXCEPTIONS
+ template <typename T>
+ void fix_seq<T>::
move_ (void* dst, void* src, size_t n)
{
T* d = static_cast<T*> (dst);
diff --git a/libxsde/xsde/cxx/sequence-base.hxx b/libxsde/xsde/cxx/sequence-base.hxx
index 057ffdf..537ee7c 100644
--- a/libxsde/xsde/cxx/sequence-base.hxx
+++ b/libxsde/xsde/cxx/sequence-base.hxx
@@ -70,7 +70,7 @@ namespace xsde
void
swap_ (sequence_base&);
- public:
+ protected:
void* data_;
size_t size_;
size_t capacity_;
diff --git a/tests/cxx/hybrid/sequences/driver.cxx b/tests/cxx/hybrid/sequences/driver.cxx
index 3d6c702..1a27e9b 100644
--- a/tests/cxx/hybrid/sequences/driver.cxx
+++ b/tests/cxx/hybrid/sequences/driver.cxx
@@ -85,6 +85,10 @@ main ()
s.push_back (222);
s.push_back (333);
assert (s.size () == 3 && s[0] == 111 && s[1] == 222 && s[2] == 333);
+
+ pod c;
+ c.assign (s.begin (), s.size ());
+ assert (c.size () == 3 && c[0] == 111 && c[1] == 222 && c[2] == 333);
}
{
@@ -158,6 +162,11 @@ main ()
s.push_back ("ccc");
assert (s.size () == 3 && s[0] == "aaa" &&
s[1] == "bbb" && s[2] == "ccc");
+
+ fix c;
+ c.assign (s.begin (), s.size ());
+ assert (c.size () == 3 && c[0] == "aaa" &&
+ c[1] == "bbb" && c[2] == "ccc");
}
{