aboutsummaryrefslogtreecommitdiff
path: root/libxsde/xsde/cxx/hybrid
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/hybrid
parent0baca4b033509b6c4ebfabfb74bf6518c3b1182c (diff)
Implement generation of clone functions
New test: clone.
Diffstat (limited to 'libxsde/xsde/cxx/hybrid')
-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
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
}
}
}