diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2010-10-07 14:48:13 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2010-10-07 14:48:13 +0200 |
commit | 4f38adc11ab1a3a1ab2dd3f958c917182be7d71f (patch) | |
tree | fd4242b2fb5648536a6307a18442abfcaf280573 /libxsde | |
parent | 0baca4b033509b6c4ebfabfb74bf6518c3b1182c (diff) |
Implement generation of clone functions
New test: clone.
Diffstat (limited to 'libxsde')
-rw-r--r-- | libxsde/xsde/cxx/buffer.cxx | 96 | ||||
-rw-r--r-- | libxsde/xsde/cxx/buffer.hxx | 17 | ||||
-rw-r--r-- | libxsde/xsde/cxx/buffer.ixx | 16 | ||||
-rw-r--r-- | libxsde/xsde/cxx/guard.hxx | 48 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/base.hxx | 21 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/sequence.cxx | 45 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/sequence.hxx | 33 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/sequence.ixx | 36 | ||||
-rw-r--r-- | libxsde/xsde/cxx/hybrid/sequence.txx | 48 | ||||
-rw-r--r-- | libxsde/xsde/cxx/qname.cxx | 118 | ||||
-rw-r--r-- | libxsde/xsde/cxx/qname.hxx | 10 | ||||
-rw-r--r-- | libxsde/xsde/cxx/qname.ixx | 18 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence-stl.cxx | 113 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence-stl.hxx | 17 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence-stl.ixx | 15 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence.cxx | 111 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence.hxx | 17 | ||||
-rw-r--r-- | libxsde/xsde/cxx/string-sequence.ixx | 12 |
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:: |