// file : xsde/cxx/hybrid/sequence.ixx // author : Boris Kolpackov // copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #include // placement new namespace xsde { namespace cxx { namespace hybrid { // // pod_seq // template inline size_t pod_seq:: max_size () const { return size_t (-1) / sizeof (T); } template inline void pod_seq:: swap (pod_seq& x) { swap_ (x); } template inline T* pod_seq:: begin () { return static_cast (data_); } template inline const T* pod_seq:: begin () const { // g++ 2.95 does not like static_cast here. // return (const T*) (data_); } template inline T* pod_seq:: end () { return static_cast (data_) + size_; } template inline const T* pod_seq:: end () const { return ((const T*) (data_)) + size_; } template inline T& pod_seq:: front () { return *static_cast (data_); } template inline const T& pod_seq:: front () const { return *((const T*) (data_)); } template inline T& pod_seq:: back () { return static_cast (data_)[size_ - 1]; } template inline const T& pod_seq:: back () const { return ((const T*) (data_))[size_ - 1]; } template inline T& pod_seq:: operator[] (size_t i) { return static_cast (data_)[i]; } template inline const T& pod_seq:: operator[] (size_t i) const { return ((const T*) (data_))[i]; } template inline void pod_seq:: clear () { size_ = 0; } template inline void pod_seq:: pop_back () { --size_; } template inline T* pod_seq:: erase (T* i) { if (i != static_cast (data_) + (size_ - 1)) erase_ (i, sizeof (T), 0); else --size_; return i; } #ifdef XSDE_EXCEPTIONS template inline void pod_seq:: push_back (const T& x) { if (capacity_ < size_ + 1) grow_ (0, sizeof (T), 0); static_cast (data_)[size_++] = x; } template inline T* pod_seq:: insert (T* i, const T& x) { T* p = static_cast (insert_ (i, sizeof (T), 0, 0)); *p = x; return p; } template inline void pod_seq:: reserve (size_t n) { if (capacity_ < n) grow_ (n, sizeof (T), 0); } #else template inline sequence_base::error pod_seq:: push_back (const T& x) { error r = error_none; if (capacity_ < size_ + 1) r = grow_ (0, sizeof (T), 0); if (r == error_none) static_cast (data_)[size_++] = x; return r; } template inline sequence_base::error pod_seq:: insert (T* i, const T& x) { T* p = static_cast (insert_ (i, sizeof (T), 0, 0)); if (p) { *p = x; return error_none; } else return error_no_memory; } template inline sequence_base::error pod_seq:: insert (T* i, const T& x, T*& r) { T* p = static_cast (insert_ (i, sizeof (T), 0, 0)); if (p) { *p = x; r = p; return error_none; } else return error_no_memory; } template inline sequence_base::error pod_seq:: reserve (size_t n) { error r = error_none; if (capacity_ < n) r = grow_ (n, sizeof (T), 0); return r; } #endif // // fix_seq // template inline fix_seq:: ~fix_seq () { clear (); } template inline size_t fix_seq:: max_size () const { return size_t (-1) / sizeof (T); } template inline void fix_seq:: swap (fix_seq& x) { swap_ (x); } template inline T* fix_seq:: begin () { return static_cast (data_); } template inline const T* fix_seq:: begin () const { return (const T*) (data_); } template inline T* fix_seq:: end () { return static_cast (data_) + size_; } template inline const T* fix_seq:: end () const { return ((const T*) (data_)) + size_; } template inline T& fix_seq:: front () { return *static_cast (data_); } template inline const T& fix_seq:: front () const { return *((const T*) (data_)); } template inline T& fix_seq:: back () { return static_cast (data_)[size_ - 1]; } template inline const T& fix_seq:: back () const { return ((const T*) (data_))[size_ - 1]; } template inline T& fix_seq:: operator[] (size_t i) { return static_cast (data_)[i]; } template inline const T& fix_seq:: operator[] (size_t i) const { return ((const T*) (data_))[i]; } template inline void fix_seq:: pop_back () { static_cast (data_)[size_ - 1].~T (); --size_; } template inline T* fix_seq:: erase (T* i) { if (i != static_cast (data_) + (size_ - 1)) erase_ (i, sizeof (T), &move_forward_); else { static_cast (data_)[size_ - 1].~T (); --size_; } return i; } #ifdef XSDE_EXCEPTIONS template inline void fix_seq:: push_back (const T& x) { if (capacity_ < size_ + 1) grow_ (0, sizeof (T), &move_); new (static_cast (data_) + size_) T (x); size_++; } template inline T* fix_seq:: insert (T* i, const T& x) { T* p = static_cast ( insert_ (i, sizeof (T), &move_, &move_backward_)); *p = x; return p; } template inline void fix_seq:: reserve (size_t n) { if (capacity_ < n) grow_ (n, sizeof (T), &move_); } #else template inline sequence_base::error fix_seq:: push_back (const T& x) { error r = error_none; if (capacity_ < size_ + 1) r = grow_ (0, sizeof (T), &move_); if (r == error_none) { new (static_cast (data_) + size_) T (x); size_++; } return r; } template inline sequence_base::error fix_seq:: insert (T* i, const T& x) { T* p = static_cast ( insert_ (i, sizeof (T), &move_, &move_backward_)); if (p) { *p = x; return error_none; } else return error_no_memory; } template inline sequence_base::error fix_seq:: insert (T* i, const T& x, T*& r) { T* p = static_cast ( insert_ (i, sizeof (T), &move_, &move_backward_)); if (p) { *p = x; r = p; return error_none; } else return error_no_memory; } template inline sequence_base::error fix_seq:: reserve (size_t n) { error r = error_none; if (capacity_ < n) r = grow_ (n, sizeof (T), &move_); return r; } #endif // // var_seq // template inline var_seq:: ~var_seq () { clear (); } template inline size_t var_seq:: max_size () const { return size_t (-1) / sizeof (T*); } template inline void var_seq:: swap (var_seq& x) { swap_ (x); } template inline var_iterator var_seq:: begin () { return iterator (static_cast (data_)); } template inline var_const_iterator var_seq:: begin () const { return const_iterator ((const T**) (data_)); } template inline var_iterator var_seq:: end () { return iterator (static_cast (data_) + size_); } template inline var_const_iterator var_seq:: end () const { return const_iterator (((const T**) (data_)) + size_); } template inline T& var_seq:: front () { return **static_cast (data_); } template inline const T& var_seq:: front () const { // g++ 2.95 does not like static_cast here. // return **((const T* const*) (data_)); } template inline T& var_seq:: back () { return *(static_cast (data_)[size_ - 1]); } template inline const T& var_seq:: back () const { return *(((const T* const*) (data_))[size_ - 1]); } template inline T& var_seq:: operator[] (size_t i) { return *(static_cast (data_)[i]); } template inline const T& var_seq:: operator[] (size_t i) const { return *(((const T* const*) (data_))[i]); } template inline void var_seq:: pop_back () { delete static_cast (data_)[size_ - 1]; --size_; } template inline var_iterator var_seq:: erase (iterator i) { delete *i.i_; if (i.i_ != static_cast (data_) + (size_ - 1)) erase_ (i.i_, sizeof (T*), 0); else --size_; return i; } #ifdef XSDE_EXCEPTIONS template inline void var_seq:: push_back (T* x) { guard g (x); if (capacity_ < size_ + 1) grow_ (0, sizeof (T*), 0); static_cast (data_)[size_++] = x; g.release (); } template inline var_iterator var_seq:: insert (iterator i, T* x) { guard g (x); T** p = static_cast (insert_ (i.i_, sizeof (T*), 0, 0)); *p = x; g.release (); return iterator (p); } template inline void var_seq:: reserve (size_t n) { if (capacity_ < n) grow_ (n, sizeof (T*), 0); } #else template inline sequence_base::error var_seq:: push_back (T* x) { error r = error_none; if (capacity_ < size_ + 1) r = grow_ (0, sizeof (T*), 0); if (r == error_none) static_cast (data_)[size_++] = x; else delete x; return r; } template inline sequence_base::error var_seq:: insert (iterator i, T* x) { T** p = static_cast (insert_ (i.i_, sizeof (T*), 0, 0)); if (p) { *p = x; return error_none; } else { delete x; return error_no_memory; } } template inline sequence_base::error var_seq:: insert (iterator i, T* x, iterator& r) { T** p = static_cast (insert_ (i.i_, sizeof (T*), 0, 0)); if (p) { *p = x; r.i_ = p; return error_none; } else { delete x; return error_no_memory; } } template inline sequence_base::error var_seq:: reserve (size_t n) { error r = error_none; if (capacity_ < n) r = grow_ (n, sizeof (T*), 0); return r; } #endif // // data_seq // inline data_seq:: ~data_seq () { clear (); } inline data_seq:: data_seq () : destructor_ (0) { } inline void data_seq:: destructor (data_seq::destroy_func d) { destructor_ = d; } inline size_t data_seq:: max_size () const { return size_t (-1) / sizeof (void*); } inline void data_seq:: swap (data_seq& x) { swap_ (x); } inline data_seq::iterator data_seq:: begin () { return static_cast (data_); } inline data_seq::const_iterator data_seq:: begin () const { // g++ 2.95 does not like static_cast here. // return (const void* const*) (data_); } inline data_seq::iterator data_seq:: end () { return static_cast (data_) + size_; } inline data_seq::const_iterator data_seq:: end () const { return ((const void* const*) (data_)) + size_; } inline void* data_seq:: front () { return *static_cast (data_); } inline const void* data_seq:: front () const { return *((const void* const*) (data_)); } inline void* data_seq:: back () { return static_cast (data_)[size_ - 1]; } inline const void* data_seq:: back () const { return ((const void* const*) (data_))[size_ - 1]; } inline void* data_seq:: operator[] (size_t i) { return static_cast (data_)[i]; } inline const void* data_seq:: operator[] (size_t i) const { return ((const void* const*) (data_))[i]; } inline void data_seq:: pop_back () { if (destructor_) destructor_ (static_cast (data_)[size_ - 1], size_ - 1); --size_; } inline data_seq::iterator data_seq:: erase (iterator i) { if (destructor_) destructor_ (*i, i - static_cast (data_)); if (i != static_cast (data_) + (size_ - 1)) erase_ (i, sizeof (void*), 0); else --size_; return i; } #ifdef XSDE_EXCEPTIONS namespace data_seq_bits { struct guard { ~guard () { if (p_ && d_) d_ (p_, i_); } guard (data_seq::destroy_func d, void* p, size_t i) : d_ (d), p_ (p), i_ (i) {} void release () { p_ = 0; } private: data_seq::destroy_func d_; void* p_; size_t i_; }; } inline void data_seq:: push_back (void* x) { data_seq_bits::guard g (destructor_, x, size_); if (capacity_ < size_ + 1) grow_ (0, sizeof (void*), 0); static_cast (data_)[size_++] = x; g.release (); } inline data_seq::iterator data_seq:: insert (iterator i, void* x) { data_seq_bits::guard g ( destructor_, x, i - static_cast (data_)); void** p = static_cast (insert_ (i, sizeof (void*), 0, 0)); *p = x; g.release (); return p; } inline void data_seq:: reserve (size_t n) { if (capacity_ < n) grow_ (n, sizeof (void*), 0); } #else inline sequence_base::error data_seq:: push_back (void* x) { error r = error_none; if (capacity_ < size_ + 1) r = grow_ (0, sizeof (void*), 0); if (r == error_none) static_cast (data_)[size_++] = x; else { if (destructor_) destructor_ (x, size_); } return r; } inline sequence_base::error data_seq:: insert (iterator i, void* x) { size_t pos = i - static_cast (data_); void** p = static_cast (insert_ (i, sizeof (void*), 0, 0)); if (p) { *p = x; return error_none; } else { if (destructor_) destructor_ (x, pos); return error_no_memory; } } inline sequence_base::error data_seq:: insert (iterator i, void* x, iterator& r) { size_t pos = i - static_cast (data_); void** p = static_cast (insert_ (i, sizeof (void*), 0, 0)); if (p) { *p = x; r = p; return error_none; } else { if (destructor_) destructor_ (x, pos); return error_no_memory; } } inline sequence_base::error data_seq:: reserve (size_t n) { error r = error_none; if (capacity_ < n) r = grow_ (n, sizeof (void*), 0); return r; } #endif } } }