aboutsummaryrefslogtreecommitdiff
path: root/libxsde/xsde/cxx/string-sequence-stl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'libxsde/xsde/cxx/string-sequence-stl.cxx')
-rw-r--r--libxsde/xsde/cxx/string-sequence-stl.cxx147
1 files changed, 147 insertions, 0 deletions
diff --git a/libxsde/xsde/cxx/string-sequence-stl.cxx b/libxsde/xsde/cxx/string-sequence-stl.cxx
new file mode 100644
index 0000000..ea2cb81
--- /dev/null
+++ b/libxsde/xsde/cxx/string-sequence-stl.cxx
@@ -0,0 +1,147 @@
+// file : xsde/cxx/string-sequence-stl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsde/cxx/string-sequence-stl.hxx>
+
+namespace xsde
+{
+ namespace cxx
+ {
+ void string_sequence::
+ clear ()
+ {
+ typedef std::string type;
+ for (size_t i = 0; i < size_; ++i)
+ static_cast<std::string*> (data_)[i].~type ();
+
+ size_ = 0;
+ }
+
+#ifdef XSDE_EXCEPTIONS
+ struct guard
+ {
+ guard (std::string* p, size_t& n) : p_ (p), n_ (n) {}
+
+ ~guard ()
+ {
+ typedef std::string type;
+ if (p_)
+ for (; n_ > 0; --n_)
+ p_[n_ - 1].~type ();
+ }
+
+ void
+ release () { p_ = 0; }
+
+ private:
+ std::string* p_;
+ size_t& n_;
+ };
+
+ void string_sequence::
+ move_ (void* dst, void* src, size_t n)
+ {
+ std::string* d = static_cast<std::string*> (dst);
+ std::string* s = static_cast<std::string*> (src);
+
+ // The copy c-tor can throw in which case we need to destroy
+ // whatever objects we already copied into d.
+ //
+ size_t i = 0;
+ guard g (d, i);
+
+ for (; i < n; i++)
+ new (d + i) std::string (s[i]);
+
+ g.release ();
+
+ typedef std::string type;
+ for (size_t j = 0; j < n; j++)
+ s[j].~type ();
+ }
+#else
+ void string_sequence::
+ move_ (void* dst, void* src, size_t n)
+ {
+ std::string* d = static_cast<std::string*> (dst);
+ std::string* s = static_cast<std::string*> (src);
+
+ for (size_t i = 0; i < n; i++)
+ {
+ typedef std::string type;
+ new (d + i) std::string (s[i]);
+ s[i].~type ();
+ }
+ }
+#endif
+
+ void string_sequence::
+ move_forward_ (void* p, size_t n)
+ {
+ // We are moving a sequence of elements one position to the left.
+ // The tricky part is to make sure we are in at least destructable
+ // state if things turn bad. We assume that there is a valid
+ // element at position p.
+ //
+ std::string* d = static_cast<std::string*> (p);
+
+ for (size_t i = 0; i < n; i++)
+ d[i] = d[i + 1];
+
+ typedef std::string type;
+ d[n].~type ();
+ }
+
+#ifdef XSDE_EXCEPTIONS
+ void string_sequence::
+ move_backward_ (void* p, size_t n, size_t& size)
+ {
+ // We are moving a sequence of elements one position to the right.
+ // The tricky part is to make sure we are in at least destructable
+ // state if things turn bad.
+ //
+ std::string* d = static_cast<std::string*> (p);
+ std::string* e = d + n;
+
+ new (e) std::string;
+ size++;
+
+ for (size_t i = n; i > 0; i--)
+ d[i] = d[i - 1];
+ }
+#else
+ void string_sequence::
+ move_backward_ (void* p, size_t n)
+ {
+ // We are moving a sequence of elements one position to the right.
+ //
+ std::string* d = static_cast<std::string*> (p);
+ std::string* e = d + n;
+
+ new (e) std::string;
+
+ for (size_t i = n; i > 0; i--)
+ d[i] = d[i - 1];
+ }
+#endif
+
+ bool
+ operator== (const string_sequence& x, const string_sequence& y)
+ {
+ if (x.size () != y.size ())
+ return false;
+
+ for (string_sequence::const_iterator
+ xi (x.begin ()), yi (y.begin ()), xe (x.end ());
+ xi != xe; ++xi, ++yi)
+ {
+ if (*xi != *yi)
+ return false;
+ }
+
+ return true;
+ }
+ }
+}