aboutsummaryrefslogtreecommitdiff
path: root/libxsde/xsde/cxx/string-sequence-stl.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2010-10-07 14:48:13 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2010-10-07 14:48:13 +0200
commit4f38adc11ab1a3a1ab2dd3f958c917182be7d71f (patch)
treefd4242b2fb5648536a6307a18442abfcaf280573 /libxsde/xsde/cxx/string-sequence-stl.cxx
parent0baca4b033509b6c4ebfabfb74bf6518c3b1182c (diff)
Implement generation of clone functions
New test: clone.
Diffstat (limited to 'libxsde/xsde/cxx/string-sequence-stl.cxx')
-rw-r--r--libxsde/xsde/cxx/string-sequence-stl.cxx113
1 files changed, 113 insertions, 0 deletions
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) {}