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/xsde/cxx/hybrid | |
parent | 0baca4b033509b6c4ebfabfb74bf6518c3b1182c (diff) |
Implement generation of clone functions
New test: clone.
Diffstat (limited to 'libxsde/xsde/cxx/hybrid')
-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 |
5 files changed, 180 insertions, 3 deletions
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 } } } |