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