From f8bb2faef4b272ed150eb3ca4cedaa79da410694 Mon Sep 17 00:00:00 2001
From: Boris Kolpackov
Date: Wed, 11 Mar 2009 15:09:17 +0200
Subject: Allow initialization of pod_seq and fix_seq from a C array
Use this in the hybrid/binary/custom example.
---
NEWS | 6 +++++
documentation/cxx/hybrid/guide/index.xhtml | 11 +++++++--
examples/cxx/hybrid/binary/custom/irawstream.txx | 8 ++-----
libxsde/xsde/cxx/hybrid/sequence.hxx | 14 +++++++++++
libxsde/xsde/cxx/hybrid/sequence.ixx | 30 +++++++++++++++++++++++-
libxsde/xsde/cxx/hybrid/sequence.txx | 28 ++++++++++++++++++++++
libxsde/xsde/cxx/sequence-base.hxx | 2 +-
tests/cxx/hybrid/sequences/driver.cxx | 9 +++++++
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);
};
When C++ exceptions are disabled, the signatures of the
- push_back()
, insert()
, and
- reserve()
functions change as follows:
+ push_back()
, insert()
,
+ reserve()
, and assign()
functions
+ change as follows:
template <typename T>
@@ -2040,6 +2044,9 @@ public:
error
reserve (size_t);
+
+ error
+ assign (const T* src, size_t n);
};
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& 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 (s.align (sizeof (T), sizeof (T) * n)), n);
}
template
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 // placement new
+#include // memcpy
+
+#include // placement new
namespace xsde
{
@@ -154,6 +156,17 @@ namespace xsde
if (capacity_ < n)
grow_ (n, sizeof (T), 0);
}
+
+ template
+ inline void pod_seq::
+ 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
inline sequence_base::error pod_seq::
@@ -210,6 +223,21 @@ namespace xsde
r = grow_ (n, sizeof (T), 0);
return r;
}
+
+ template
+ inline sequence_base::error pod_seq::
+ 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
void fix_seq::
+ assign (const T* p, size_t n)
+ {
+ clear ();
+ reserve (n);
+
+ for (; size_ < n; ++size_)
+ new (static_cast (data_) + size_) T (p[size_]);
+ }
+#else
+ template
+ sequence_base::error fix_seq::
+ assign (const T* p, size_t n)
+ {
+ clear ();
+
+ if (error r = reserve (n))
+ return r;
+
+ for (; size_ < n; ++size_)
+ new (static_cast (data_) + size_) T (p[size_]);
+
+ return error_none;
+ }
+#endif
+
+#ifdef XSDE_EXCEPTIONS
+ template
+ void fix_seq::
move_ (void* dst, void* src, size_t n)
{
T* d = static_cast (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");
}
{
--
cgit v1.1