aboutsummaryrefslogtreecommitdiff
path: root/libxsde/xsde
diff options
context:
space:
mode:
Diffstat (limited to 'libxsde/xsde')
-rw-r--r--libxsde/xsde/cxx/buffer.cxx96
-rw-r--r--libxsde/xsde/cxx/buffer.hxx17
-rw-r--r--libxsde/xsde/cxx/buffer.ixx16
-rw-r--r--libxsde/xsde/cxx/guard.hxx48
-rw-r--r--libxsde/xsde/cxx/hybrid/base.hxx21
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.cxx45
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.hxx33
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.ixx36
-rw-r--r--libxsde/xsde/cxx/hybrid/sequence.txx48
-rw-r--r--libxsde/xsde/cxx/qname.cxx118
-rw-r--r--libxsde/xsde/cxx/qname.hxx10
-rw-r--r--libxsde/xsde/cxx/qname.ixx18
-rw-r--r--libxsde/xsde/cxx/string-sequence-stl.cxx113
-rw-r--r--libxsde/xsde/cxx/string-sequence-stl.hxx17
-rw-r--r--libxsde/xsde/cxx/string-sequence-stl.ixx15
-rw-r--r--libxsde/xsde/cxx/string-sequence.cxx111
-rw-r--r--libxsde/xsde/cxx/string-sequence.hxx17
-rw-r--r--libxsde/xsde/cxx/string-sequence.ixx12
18 files changed, 774 insertions, 17 deletions
diff --git a/libxsde/xsde/cxx/buffer.cxx b/libxsde/xsde/cxx/buffer.cxx
index d9102ae..4084cde 100644
--- a/libxsde/xsde/cxx/buffer.cxx
+++ b/libxsde/xsde/cxx/buffer.cxx
@@ -110,6 +110,58 @@ namespace xsde
return true;
}
}
+
+ void buffer::
+ assign (void* data, size_t size)
+ {
+ capacity (size);
+ size_ = size;
+
+ if (size_)
+ memcpy (data_, data, size_);
+ }
+
+ struct buffer_guard
+ {
+ buffer_guard (buffer* p) : p_ (p) {}
+
+ ~buffer_guard ()
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete p_;
+#else
+ if (p_ != 0)
+ {
+ p_->~buffer ();
+ cxx::free (p_);
+ }
+#endif
+ }
+
+ void
+ release () { p_ = 0; }
+
+ private:
+ buffer* p_;
+ };
+
+ buffer* buffer::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ buffer* c = new buffer;
+#else
+ // Default buffer c-tor cannot throw so we don't need alloc_guard.
+ //
+ buffer* c = static_cast<buffer*> (cxx::alloc (sizeof (buffer)));
+ new (c) buffer;
+#endif
+ buffer_guard g (c);
+ _copy (*c);
+ g.release ();
+ return c;
+ }
+
#else
buffer::error buffer::
capacity (size_t capacity, bool copy, bool* moved)
@@ -156,6 +208,50 @@ namespace xsde
return error_none;
}
+
+ buffer::error buffer::
+ assign (void* data, size_t size)
+ {
+ if (error r = capacity (size))
+ return r;
+
+ size_ = size;
+
+ if (size_)
+ memcpy (data_, data, size_);
+
+ return error_none;
+ }
+
+ buffer* buffer::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ buffer* c = new buffer;
+#else
+ buffer* c = static_cast<buffer*> (cxx::alloc (sizeof (buffer)));
+#endif
+
+ if (c == 0)
+ return 0;
+
+#ifdef XSDE_CUSTOM_ALLOCATOR
+ new (c) buffer;
+#endif
+
+ if (!_copy (*c))
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete c;
+#else
+ c->~buffer ();
+ cxx::free (c);
+#endif
+ return 0;
+ }
+
+ return c;
+ }
#endif
}
}
diff --git a/libxsde/xsde/cxx/buffer.hxx b/libxsde/xsde/cxx/buffer.hxx
index 7ea1adf..2957a0a 100644
--- a/libxsde/xsde/cxx/buffer.hxx
+++ b/libxsde/xsde/cxx/buffer.hxx
@@ -60,6 +60,13 @@ namespace xsde
#else
void
#endif
+ assign (void* data, size_t size);
+
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
attach (void* data, size_t size, size_t capacity);
void*
@@ -68,6 +75,16 @@ namespace xsde
void
swap (buffer&);
+ buffer*
+ _clone () const;
+
+#ifndef XSDE_EXCEPTIONS
+ bool
+#else
+ void
+#endif
+ _copy (buffer&) const;
+
public:
size_t
capacity () const;
diff --git a/libxsde/xsde/cxx/buffer.ixx b/libxsde/xsde/cxx/buffer.ixx
index 2229396..d9c71eb 100644
--- a/libxsde/xsde/cxx/buffer.ixx
+++ b/libxsde/xsde/cxx/buffer.ixx
@@ -220,5 +220,21 @@ namespace xsde
{
return !(x == y);
}
+
+ //
+ //
+#ifndef XSDE_EXCEPTIONS
+ inline bool buffer::
+ _copy (buffer& c) const
+ {
+ return c.assign (data_, size_) == error_none;
+ }
+#else
+ inline void buffer::
+ _copy (buffer& c) const
+ {
+ c.assign (data_, size_);
+ }
+#endif
}
}
diff --git a/libxsde/xsde/cxx/guard.hxx b/libxsde/xsde/cxx/guard.hxx
new file mode 100644
index 0000000..3190983
--- /dev/null
+++ b/libxsde/xsde/cxx/guard.hxx
@@ -0,0 +1,48 @@
+// file : xsde/cxx/guard.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSDE_CXX_GUARD_HXX
+#define XSDE_CXX_GUARD_HXX
+
+#include <xsde/cxx/config.hxx>
+
+#ifdef XSDE_CUSTOM_ALLOCATOR
+# include <xsde/cxx/allocator.hxx>
+#endif
+
+namespace xsde
+{
+ namespace cxx
+ {
+#ifdef XSDE_EXCEPTIONS
+ template <typename T>
+ struct guard
+ {
+ guard (T* p) : p_ (p) {}
+
+ ~guard ()
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete p_;
+#else
+ if (p_ != 0)
+ {
+ p_->~T ();
+ cxx::free (p_);
+ }
+#endif
+ }
+
+ void
+ release () { p_ = 0; }
+
+ private:
+ T* p_;
+ };
+#endif // XSDE_EXCEPTIONS
+ }
+}
+
+#endif // XSDE_CXX_GUARD_HXX
diff --git a/libxsde/xsde/cxx/hybrid/base.hxx b/libxsde/xsde/cxx/hybrid/base.hxx
index 89431a2..a7b1e2a 100644
--- a/libxsde/xsde/cxx/hybrid/base.hxx
+++ b/libxsde/xsde/cxx/hybrid/base.hxx
@@ -10,6 +10,7 @@
#ifndef XSDE_STL
# include <string.h> // strcmp
+# include <xsde/cxx/strdupx.hxx>
#endif
#ifdef XSDE_CUSTOM_ALLOCATOR
@@ -599,6 +600,26 @@ namespace xsde
string_base& operator= (char* x) {base_value (x); return *this;}
+#ifndef XSDE_EXCEPTIONS
+ bool
+#else
+ void
+#endif
+ _copy (string_base& c) const
+ {
+ char* x = strdupx (x_);
+
+#ifndef XSDE_EXCEPTIONS
+ if (x == 0)
+ return false;
+#endif
+ c.base_value (x);
+
+#ifndef XSDE_EXCEPTIONS
+ return true;
+#endif
+ }
+
protected:
char* x_;
};
diff --git a/libxsde/xsde/cxx/hybrid/sequence.cxx b/libxsde/xsde/cxx/hybrid/sequence.cxx
index bf5f3c7..5293616 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.cxx
+++ b/libxsde/xsde/cxx/hybrid/sequence.cxx
@@ -26,6 +26,51 @@ namespace xsde
size_ = 0;
}
+
+#ifdef XSDE_EXCEPTIONS
+ void data_sequence::
+ copy (data_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ c.destructor_ = destructor_;
+ c.clone_ = clone_;
+
+ c.reserve (size_);
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ static_cast<void**> (c.data_)[c.size_] =
+ clone_ (static_cast<void**> (data_)[c.size_], c.size_);
+ }
+ }
+#else
+ sequence_base::error data_sequence::
+ copy (data_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ c.destructor_ = destructor_;
+ c.clone_ = clone_;
+
+ if (error r = c.reserve (size_))
+ return r;
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ void* x = clone_ (static_cast<void**> (data_)[c.size_], c.size_);
+
+ if (x == 0)
+ return error_no_memory;
+
+ static_cast<void**> (c.data_)[c.size_] = x;
+ }
+
+ return error_none;
+ }
+#endif
}
}
}
diff --git a/libxsde/xsde/cxx/hybrid/sequence.hxx b/libxsde/xsde/cxx/hybrid/sequence.hxx
index fa5c697..e21f219 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.hxx
+++ b/libxsde/xsde/cxx/hybrid/sequence.hxx
@@ -128,6 +128,13 @@ namespace xsde
void
swap (pod_sequence&);
+
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ copy (pod_sequence&) const;
};
// Sequence with fixed-length elements.
@@ -230,6 +237,13 @@ namespace xsde
void
swap (fix_sequence&);
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ copy (fix_sequence&) const;
+
private:
static void
move_ (void* dst, void* src, size_t n);
@@ -831,6 +845,13 @@ namespace xsde
void
swap (var_sequence&);
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ copy (var_sequence&) const;
+
#ifdef XSDE_EXCEPTIONS
public:
struct guard
@@ -877,10 +898,14 @@ namespace xsde
data_sequence ();
typedef void (*destroy_func) (void* data, size_t pos);
+ typedef void* (*clone_func) (void* data, size_t pos);
void
destructor (destroy_func);
+ void
+ clone (clone_func);
+
public:
iterator
begin ();
@@ -953,8 +978,16 @@ namespace xsde
void
swap (data_sequence&);
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ copy (data_sequence&) const;
+
private:
destroy_func destructor_;
+ clone_func clone_;
};
}
}
diff --git a/libxsde/xsde/cxx/hybrid/sequence.ixx b/libxsde/xsde/cxx/hybrid/sequence.ixx
index 1ec2a4c..e53b774 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.ixx
+++ b/libxsde/xsde/cxx/hybrid/sequence.ixx
@@ -167,6 +167,13 @@ namespace xsde
memcpy (data_, p, n * sizeof (T));
size_ = n;
}
+
+ template <typename T>
+ inline void pod_sequence<T>::
+ copy (pod_sequence& c) const
+ {
+ c.assign (begin (), size ());
+ }
#else
template <typename T>
inline sequence_base::error pod_sequence<T>::
@@ -238,6 +245,13 @@ namespace xsde
size_ = n;
return error_none;
}
+
+ template <typename T>
+ inline sequence_base::error pod_sequence<T>::
+ copy (pod_sequence& c) const
+ {
+ return c.assign (begin (), size ());
+ }
#endif
//
@@ -387,6 +401,13 @@ namespace xsde
if (capacity_ < n)
grow_ (n, sizeof (T), &move_);
}
+
+ template <typename T>
+ inline void fix_sequence<T>::
+ copy (fix_sequence& c) const
+ {
+ c.assign (begin (), size ());
+ }
#else
template <typename T>
inline sequence_base::error fix_sequence<T>::
@@ -448,6 +469,13 @@ namespace xsde
r = grow_ (n, sizeof (T), &move_);
return r;
}
+
+ template <typename T>
+ inline sequence_base::error fix_sequence<T>::
+ copy (fix_sequence& c) const
+ {
+ return c.assign (begin (), size ());
+ }
#endif
//
@@ -741,7 +769,7 @@ namespace xsde
inline data_sequence::
data_sequence ()
- : destructor_ (0)
+ : destructor_ (0), clone_ (0)
{
}
@@ -751,6 +779,12 @@ namespace xsde
destructor_ = d;
}
+ inline void data_sequence::
+ clone (data_sequence::clone_func c)
+ {
+ clone_ = c;
+ }
+
inline size_t data_sequence::
max_size () const
{
diff --git a/libxsde/xsde/cxx/hybrid/sequence.txx b/libxsde/xsde/cxx/hybrid/sequence.txx
index b79e9d5..5d7df7d 100644
--- a/libxsde/xsde/cxx/hybrid/sequence.txx
+++ b/libxsde/xsde/cxx/hybrid/sequence.txx
@@ -30,7 +30,9 @@ namespace xsde
void fix_sequence<T>::
assign (const T* p, size_t n)
{
- clear ();
+ if (size_ != 0)
+ clear ();
+
reserve (n);
for (; size_ < n; ++size_)
@@ -41,7 +43,8 @@ namespace xsde
sequence_base::error fix_sequence<T>::
assign (const T* p, size_t n)
{
- clear ();
+ if (size_ != 0)
+ clear ();
if (error r = reserve (n))
return r;
@@ -166,6 +169,47 @@ namespace xsde
size_ = 0;
}
+
+#ifdef XSDE_EXCEPTIONS
+ template <typename T>
+ void var_sequence<T>::
+ copy (var_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ c.reserve (size_);
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ static_cast<T**> (c.data_)[c.size_] =
+ static_cast<T**> (data_)[c.size_]->_clone ();
+ }
+ }
+#else
+ template <typename T>
+ sequence_base::error var_sequence<T>::
+ copy (var_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ if (error r = c.reserve (size_))
+ return r;
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ T* x = static_cast<T**> (data_)[c.size_]->_clone ();
+
+ if (x == 0)
+ return error_no_memory;
+
+ static_cast<T**> (c.data_)[c.size_] = x;
+ }
+
+ return error_none;
+ }
+#endif
}
}
}
diff --git a/libxsde/xsde/cxx/qname.cxx b/libxsde/xsde/cxx/qname.cxx
index be196be..f1e4238 100644
--- a/libxsde/xsde/cxx/qname.cxx
+++ b/libxsde/xsde/cxx/qname.cxx
@@ -10,11 +10,83 @@ namespace xsde
{
namespace cxx
{
-#ifndef XSDE_EXCEPTIONS
- qname::error qname::
+
+#ifdef XSDE_EXCEPTIONS
+
+ void qname::
+ prefix_copy (const char* prefix)
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete[] prefix_;
#else
+ cxx::free (prefix_);
+#endif
+
+ if (prefix)
+ prefix_ = strdupx (prefix);
+ else
+ prefix_ = 0;
+ }
+
void qname::
+ name_copy (const char* name)
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete[] name_;
+#else
+ cxx::free (name_);
+#endif
+
+ if (name)
+ name_ = strdupx (name);
+ else
+ name_ = 0;
+ }
+
+ struct qname_guard
+ {
+ qname_guard (qname* p) : p_ (p) {}
+
+ ~qname_guard ()
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete p_;
+#else
+ if (p_ != 0)
+ {
+ p_->~qname ();
+ cxx::free (p_);
+ }
#endif
+ }
+
+ void
+ release () { p_ = 0; }
+
+ private:
+ qname* p_;
+ };
+
+ qname* qname::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ qname* c = new qname;
+#else
+ // Default qname c-tor cannot throw so we don't need alloc_guard.
+ //
+ qname* c = static_cast<qname*> (cxx::alloc (sizeof (qname)));
+ new (c) qname;
+#endif
+ qname_guard g (c);
+ _copy (*c);
+ g.release ();
+ return c;
+ }
+
+#else
+
+ qname::error qname::
prefix_copy (const char* prefix)
{
#ifndef XSDE_CUSTOM_ALLOCATOR
@@ -27,24 +99,16 @@ namespace xsde
{
prefix_ = strdupx (prefix);
-#ifndef XSDE_EXCEPTIONS
if (prefix_ == 0)
return error_no_memory;
-#endif
}
else
prefix_ = 0;
-#ifndef XSDE_EXCEPTIONS
return error_none;
-#endif
}
-#ifndef XSDE_EXCEPTIONS
qname::error qname::
-#else
- void qname::
-#endif
name_copy (const char* name)
{
#ifndef XSDE_CUSTOM_ALLOCATOR
@@ -57,17 +121,45 @@ namespace xsde
{
name_ = strdupx (name);
-#ifndef XSDE_EXCEPTIONS
if (name_ == 0)
return error_no_memory;
-#endif
}
else
name_ = 0;
-#ifndef XSDE_EXCEPTIONS
return error_none;
+ }
+
+ qname* qname::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ qname* c = new qname;
+#else
+ qname* c = static_cast<qname*> (cxx::alloc (sizeof (qname)));
+#endif
+
+ if (c == 0)
+ return 0;
+
+#ifdef XSDE_CUSTOM_ALLOCATOR
+ new (c) qname;
#endif
+
+ if (!_copy (*c))
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete c;
+#else
+ c->~qname ();
+ cxx::free (c);
+#endif
+ return 0;
+ }
+
+ return c;
}
+
+#endif
}
}
diff --git a/libxsde/xsde/cxx/qname.hxx b/libxsde/xsde/cxx/qname.hxx
index 0b2d5f5..85b53bd 100644
--- a/libxsde/xsde/cxx/qname.hxx
+++ b/libxsde/xsde/cxx/qname.hxx
@@ -81,6 +81,16 @@ namespace xsde
char*
name_detach ();
+ qname*
+ _clone () const;
+
+#ifndef XSDE_EXCEPTIONS
+ bool
+#else
+ void
+#endif
+ _copy (qname&) const;
+
private:
char* prefix_;
char* name_;
diff --git a/libxsde/xsde/cxx/qname.ixx b/libxsde/xsde/cxx/qname.ixx
index f449ef3..7a374c6 100644
--- a/libxsde/xsde/cxx/qname.ixx
+++ b/libxsde/xsde/cxx/qname.ixx
@@ -124,6 +124,24 @@ namespace xsde
return r;
}
+#ifdef XSDE_EXCEPTIONS
+ inline void qname::
+ _copy (qname& c) const
+ {
+ c.prefix_copy (prefix_);
+ c.name_copy (name_);
+ }
+#else
+ inline bool qname::
+ _copy (qname& c) const
+ {
+ if (c.prefix_copy (prefix_) || c.name_copy (name_))
+ return false;
+
+ return true;
+ }
+#endif
+
//
//
inline bool
diff --git a/libxsde/xsde/cxx/string-sequence-stl.cxx b/libxsde/xsde/cxx/string-sequence-stl.cxx
index 255b341..2fd8a02 100644
--- a/libxsde/xsde/cxx/string-sequence-stl.cxx
+++ b/libxsde/xsde/cxx/string-sequence-stl.cxx
@@ -5,6 +5,10 @@
#include <xsde/cxx/string-sequence-stl.hxx>
+#ifdef XSDE_CUSTOM_ALLOCATOR
+# include <xsde/cxx/allocator.hxx>
+#endif
+
namespace xsde
{
namespace cxx
@@ -20,6 +24,115 @@ namespace xsde
}
#ifdef XSDE_EXCEPTIONS
+ void string_sequence::
+ copy (string_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ c.reserve (size_);
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ new (static_cast<std::string*> (c.data_) + c.size_) std::string (
+ static_cast<std::string*> (data_)[c.size_]);
+ }
+ }
+
+ struct string_sequence_guard
+ {
+ string_sequence_guard (string_sequence* p) : p_ (p) {}
+
+ ~string_sequence_guard ()
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete p_;
+#else
+ if (p_ != 0)
+ {
+ p_->~string_sequence ();
+ cxx::free (p_);
+ }
+#endif
+ }
+
+ void
+ release () { p_ = 0; }
+
+ private:
+ string_sequence* p_;
+ };
+
+ string_sequence* string_sequence::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ string_sequence* c = new string_sequence;
+#else
+ // Default string_sequence c-tor cannot throw so we don't need
+ // alloc_guard.
+ //
+ string_sequence* c = static_cast<string_sequence*> (
+ cxx::alloc (sizeof (string_sequence)));
+ new (c) string_sequence;
+#endif
+ string_sequence_guard g (c);
+ _copy (*c);
+ g.release ();
+ return c;
+ }
+#else
+ sequence_base::error string_sequence::
+ copy (string_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ if (error r = c.reserve (size_))
+ return r;
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ new (static_cast<std::string*> (c.data_) + c.size_) std::string (
+ static_cast<std::string*> (data_)[c.size_]);
+ }
+
+ return error_none;
+ }
+
+ string_sequence* string_sequence::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ string_sequence* c = new string_sequence;
+#else
+ string_sequence* c = static_cast<string_sequence*> (
+ cxx::alloc (sizeof (string_sequence)));
+#endif
+
+ if (c == 0)
+ return 0;
+
+#ifdef XSDE_CUSTOM_ALLOCATOR
+ new (c) string_sequence;
+#endif
+
+ if (!_copy (*c))
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete c;
+#else
+ c->~string_sequence ();
+ cxx::free (c);
+#endif
+ return 0;
+ }
+
+ return c;
+ }
+#endif
+
+#ifdef XSDE_EXCEPTIONS
struct guard
{
guard (std::string* p, size_t& n) : p_ (p), n_ (n) {}
diff --git a/libxsde/xsde/cxx/string-sequence-stl.hxx b/libxsde/xsde/cxx/string-sequence-stl.hxx
index 305fd0d..5e75ad8 100644
--- a/libxsde/xsde/cxx/string-sequence-stl.hxx
+++ b/libxsde/xsde/cxx/string-sequence-stl.hxx
@@ -106,6 +106,23 @@ namespace xsde
void
swap (string_sequence&);
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ copy (string_sequence&) const;
+
+ string_sequence*
+ _clone () const;
+
+#ifndef XSDE_EXCEPTIONS
+ bool
+#else
+ void
+#endif
+ _copy (string_sequence&) const;
+
private:
static void
move_ (void* dst, void* src, size_t n);
diff --git a/libxsde/xsde/cxx/string-sequence-stl.ixx b/libxsde/xsde/cxx/string-sequence-stl.ixx
index 55e3d5d..ae09d04 100644
--- a/libxsde/xsde/cxx/string-sequence-stl.ixx
+++ b/libxsde/xsde/cxx/string-sequence-stl.ixx
@@ -134,8 +134,15 @@ namespace xsde
reserve (size_t n)
{
if (capacity_ < n)
- grow_ (n, sizeof (std::string*), &move_);
+ grow_ (n, sizeof (std::string), &move_);
}
+
+ inline void string_sequence::
+ _copy (string_sequence& c) const
+ {
+ copy (c);
+ }
+
#else
inline sequence_base::error string_sequence::
push_back (const std::string& x)
@@ -193,6 +200,12 @@ namespace xsde
r = grow_ (n, sizeof (std::string), &move_);
return r;
}
+
+ inline bool string_sequence::
+ _copy (string_sequence& c) const
+ {
+ return copy (c) == error_none;
+ }
#endif
inline bool
diff --git a/libxsde/xsde/cxx/string-sequence.cxx b/libxsde/xsde/cxx/string-sequence.cxx
index 5387e79..63944fb 100644
--- a/libxsde/xsde/cxx/string-sequence.cxx
+++ b/libxsde/xsde/cxx/string-sequence.cxx
@@ -34,6 +34,64 @@ namespace xsde
static_cast<char**> (data_)[size_++] = strdupx (cs);
}
+
+ void string_sequence::
+ copy (string_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ c.reserve (size_);
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ static_cast<char**> (c.data_)[c.size_] =
+ strdupx (static_cast<char**> (data_)[c.size_]);
+ }
+ }
+
+ struct string_sequence_guard
+ {
+ string_sequence_guard (string_sequence* p) : p_ (p) {}
+
+ ~string_sequence_guard ()
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete p_;
+#else
+ if (p_ != 0)
+ {
+ p_->~string_sequence ();
+ cxx::free (p_);
+ }
+#endif
+ }
+
+ void
+ release () { p_ = 0; }
+
+ private:
+ string_sequence* p_;
+ };
+
+ string_sequence* string_sequence::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ string_sequence* c = new string_sequence;
+#else
+ // Default string_sequence c-tor cannot throw so we don't need
+ // alloc_guard.
+ //
+ string_sequence* c = static_cast<string_sequence*> (
+ cxx::alloc (sizeof (string_sequence)));
+ new (c) string_sequence;
+#endif
+ string_sequence_guard g (c);
+ _copy (*c);
+ g.release ();
+ return c;
+ }
#else
string_sequence::error string_sequence::
push_back_copy (const char* cs)
@@ -55,6 +113,59 @@ namespace xsde
return r;
}
+
+ sequence_base::error string_sequence::
+ copy (string_sequence& c) const
+ {
+ if (c.size_ != 0)
+ c.clear ();
+
+ if (error r = c.reserve (size_))
+ return r;
+
+ for (; c.size_ < size_; ++c.size_)
+ {
+ char* x = strdupx (static_cast<char**> (data_)[c.size_]);
+
+ if (x == 0)
+ return error_no_memory;
+
+ static_cast<char**> (c.data_)[c.size_] = x;
+ }
+
+ return error_none;
+ }
+
+ string_sequence* string_sequence::
+ _clone () const
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ string_sequence* c = new string_sequence;
+#else
+ string_sequence* c = static_cast<string_sequence*> (
+ cxx::alloc (sizeof (string_sequence)));
+#endif
+
+ if (c == 0)
+ return 0;
+
+#ifdef XSDE_CUSTOM_ALLOCATOR
+ new (c) string_sequence;
+#endif
+
+ if (!_copy (*c))
+ {
+#ifndef XSDE_CUSTOM_ALLOCATOR
+ delete c;
+#else
+ c->~string_sequence ();
+ cxx::free (c);
+#endif
+ return 0;
+ }
+
+ return c;
+ }
#endif
bool
diff --git a/libxsde/xsde/cxx/string-sequence.hxx b/libxsde/xsde/cxx/string-sequence.hxx
index c9a33e4..a94418a 100644
--- a/libxsde/xsde/cxx/string-sequence.hxx
+++ b/libxsde/xsde/cxx/string-sequence.hxx
@@ -123,6 +123,23 @@ namespace xsde
void
swap (string_sequence&);
+
+#ifndef XSDE_EXCEPTIONS
+ error
+#else
+ void
+#endif
+ copy (string_sequence&) const;
+
+ string_sequence*
+ _clone () const;
+
+#ifndef XSDE_EXCEPTIONS
+ bool
+#else
+ void
+#endif
+ _copy (string_sequence&) const;
};
bool
diff --git a/libxsde/xsde/cxx/string-sequence.ixx b/libxsde/xsde/cxx/string-sequence.ixx
index b902bd7..b74adf2 100644
--- a/libxsde/xsde/cxx/string-sequence.ixx
+++ b/libxsde/xsde/cxx/string-sequence.ixx
@@ -172,6 +172,12 @@ namespace xsde
if (capacity_ < n)
grow_ (n, sizeof (char*), 0);
}
+
+ inline void string_sequence::
+ _copy (string_sequence& c) const
+ {
+ copy (c);
+ }
#else
inline sequence_base::error string_sequence::
push_back (char* x)
@@ -244,6 +250,12 @@ namespace xsde
r = grow_ (n, sizeof (char*), 0);
return r;
}
+
+ inline bool string_sequence::
+ _copy (string_sequence& c) const
+ {
+ return copy (c) == error_none;
+ }
#endif
inline char* string_sequence::