📄 storage.hpp
字号:
//// Copyright (c) 2000-2002// Joerg Walter, Mathias Koch//// Distributed under the Boost Software License, Version 1.0. (See// accompanying file LICENSE_1_0.txt or copy at// http://www.boost.org/LICENSE_1_0.txt)//// The authors gratefully acknowledge the support of// GeNeSys mbH & Co. KG in producing this work.//#ifndef BOOST_UBLAS_STORAGE_H#define BOOST_UBLAS_STORAGE_H#include <algorithm>#ifdef BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR#include <boost/shared_array.hpp>#endif#include <boost/serialization/array.hpp>#include <boost/serialization/collection_size_type.hpp>#include <boost/serialization/nvp.hpp>#include <boost/numeric/ublas/exception.hpp>#include <boost/numeric/ublas/traits.hpp>#include <boost/numeric/ublas/detail/iterator.hpp>namespace boost { namespace numeric { namespace ublas { // Base class for Storage Arrays - see the Barton Nackman trick template<class E> class storage_array: private nonassignable { }; // Unbounded array - with allocator template<class T, class ALLOC> class unbounded_array: public storage_array<unbounded_array<T, ALLOC> > { typedef unbounded_array<T, ALLOC> self_type; public: typedef ALLOC allocator_type; typedef typename ALLOC::size_type size_type; typedef typename ALLOC::difference_type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; typedef const T *const_pointer; typedef T *pointer; typedef const_pointer const_iterator; typedef pointer iterator; // Construction and destruction explicit BOOST_UBLAS_INLINE unbounded_array (const ALLOC &a = ALLOC()): alloc_ (a), size_ (0) { data_ = 0; } explicit BOOST_UBLAS_INLINE unbounded_array (size_type size, const ALLOC &a = ALLOC()): alloc_(a), size_ (size) { if (size_) { data_ = alloc_.allocate (size_); if (! detail::has_trivial_constructor<T>::value) { for (pointer d = data_; d != data_ + size_; ++d) alloc_.construct(d, value_type()); } } else data_ = 0; } // No value initialised, but still be default constructed BOOST_UBLAS_INLINE unbounded_array (size_type size, const value_type &init, const ALLOC &a = ALLOC()): alloc_ (a), size_ (size) { if (size_) { data_ = alloc_.allocate (size_); std::uninitialized_fill (begin(), end(), init); } else data_ = 0; } BOOST_UBLAS_INLINE unbounded_array (const unbounded_array &c): storage_array<unbounded_array<T, ALLOC> >(), alloc_ (c.alloc_), size_ (c.size_) { if (size_) { data_ = alloc_.allocate (size_); std::uninitialized_copy (c.begin(), c.end(), begin()); } else data_ = 0; } BOOST_UBLAS_INLINE ~unbounded_array () { if (size_) { if (! detail::has_trivial_destructor<T>::value) { // std::_Destroy (begin(), end(), alloc_); const iterator i_end = end(); for (iterator i = begin (); i != i_end; ++i) { iterator_destroy (i); } } alloc_.deallocate (data_, size_); } } // Resizing private: BOOST_UBLAS_INLINE void resize_internal (const size_type size, const value_type init, const bool preserve) { if (size != size_) { pointer p_data = data_; if (size) { data_ = alloc_.allocate (size); if (preserve) { pointer si = p_data; pointer di = data_; if (size < size_) { for (; di != data_ + size; ++di) { alloc_.construct (di, *si); ++si; } } else { for (pointer si = p_data; si != p_data + size_; ++si) { alloc_.construct (di, *si); ++di; } for (; di != data_ + size; ++di) { alloc_.construct (di, init); } } } else { if (! detail::has_trivial_constructor<T>::value) { for (pointer di = data_; di != data_ + size; ++di) alloc_.construct (di, value_type()); } } } if (size_) { if (! detail::has_trivial_destructor<T>::value) { for (pointer si = p_data; si != p_data + size_; ++si) alloc_.destroy (si); } alloc_.deallocate (p_data, size_); } if (!size) data_ = 0; size_ = size; } } public: BOOST_UBLAS_INLINE void resize (size_type size) { resize_internal (size, value_type (), false); } BOOST_UBLAS_INLINE void resize (size_type size, value_type init) { resize_internal (size, init, true); } // Random Access Container BOOST_UBLAS_INLINE size_type max_size () const { return ALLOC ().max_size(); } BOOST_UBLAS_INLINE bool empty () const { return size_ == 0; } BOOST_UBLAS_INLINE size_type size () const { return size_; } // Element access BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { BOOST_UBLAS_CHECK (i < size_, bad_index ()); return data_ [i]; } BOOST_UBLAS_INLINE reference operator [] (size_type i) { BOOST_UBLAS_CHECK (i < size_, bad_index ()); return data_ [i]; } // Assignment BOOST_UBLAS_INLINE unbounded_array &operator = (const unbounded_array &a) { if (this != &a) { resize (a.size_); std::copy (a.data_, a.data_ + a.size_, data_); } return *this; } BOOST_UBLAS_INLINE unbounded_array &assign_temporary (unbounded_array &a) { swap (a); return *this; } // Swapping BOOST_UBLAS_INLINE void swap (unbounded_array &a) { if (this != &a) { std::swap (size_, a.size_); std::swap (data_, a.data_); } } BOOST_UBLAS_INLINE friend void swap (unbounded_array &a1, unbounded_array &a2) { a1.swap (a2); } BOOST_UBLAS_INLINE const_iterator begin () const { return data_; } BOOST_UBLAS_INLINE const_iterator end () const { return data_ + size_; } BOOST_UBLAS_INLINE iterator begin () { return data_; } BOOST_UBLAS_INLINE iterator end () { return data_ + size_; } // Reverse iterators typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator; BOOST_UBLAS_INLINE const_reverse_iterator rbegin () const { return const_reverse_iterator (end ()); } BOOST_UBLAS_INLINE const_reverse_iterator rend () const { return const_reverse_iterator (begin ()); } BOOST_UBLAS_INLINE reverse_iterator rbegin () { return reverse_iterator (end ()); } BOOST_UBLAS_INLINE reverse_iterator rend () { return reverse_iterator (begin ()); } // Allocator allocator_type get_allocator () { return alloc_; } private: friend class boost::serialization::access; // Serialization template<class Archive> void serialize(Archive & ar, const unsigned int version) { serialization::collection_size_type s(size_); ar & serialization::make_nvp("size",s); if ( Archive::is_loading::value ) { resize(s); } ar & serialization::make_array(data_, s); } private: // Handle explict destroy on a (possibly indexed) iterator BOOST_UBLAS_INLINE static void iterator_destroy (iterator &i) { (&(*i)) -> ~value_type (); } ALLOC alloc_; size_type size_; pointer data_; }; // Bounded array - with allocator for size_type and difference_type template<class T, std::size_t N, class ALLOC> class bounded_array: public storage_array<bounded_array<T, N, ALLOC> > { typedef bounded_array<T, N, ALLOC> self_type; public: // No allocator_type as ALLOC is not used for allocation typedef typename ALLOC::size_type size_type; typedef typename ALLOC::difference_type difference_type; typedef T value_type; typedef const T &const_reference; typedef T &reference; typedef const T *const_pointer; typedef T *pointer; typedef const_pointer const_iterator; typedef pointer iterator; // Construction and destruction BOOST_UBLAS_INLINE bounded_array (): size_ (0) /*, data_ ()*/ { // size 0 - use bounded_vector to default construct with size N } explicit BOOST_UBLAS_INLINE bounded_array (size_type size): size_ (size) /*, data_ ()*/ { BOOST_UBLAS_CHECK (size_ <= N, bad_size ()); // data_ (an array) elements are already default constructed } BOOST_UBLAS_INLINE bounded_array (size_type size, const value_type &init): size_ (size) /*, data_ ()*/ { BOOST_UBLAS_CHECK (size_ <= N, bad_size ()); // ISSUE elements should be value constructed here, but we must fill instead as already default constructed std::fill (begin(), end(), init) ; } BOOST_UBLAS_INLINE bounded_array (const bounded_array &c): size_ (c.size_) { // ISSUE elements should be copy constructed here, but we must copy instead as already default constructed std::copy (c.begin(), c.end(), begin()); } // Resizing BOOST_UBLAS_INLINE void resize (size_type size) { BOOST_UBLAS_CHECK (size_ <= N, bad_size ()); size_ = size; } BOOST_UBLAS_INLINE void resize (size_type size, value_type init) { BOOST_UBLAS_CHECK (size_ <= N, bad_size ()); if (size > size_) std::fill (data_ + size_, data_ + size, init); size_ = size; } // Random Access Container BOOST_UBLAS_INLINE size_type max_size () const { return ALLOC ().max_size(); } BOOST_UBLAS_INLINE bool empty () const { return size_ == 0; } BOOST_UBLAS_INLINE size_type size () const { return size_; } // Element access BOOST_UBLAS_INLINE const_reference operator [] (size_type i) const { BOOST_UBLAS_CHECK (i < size_, bad_index ()); return data_ [i]; } BOOST_UBLAS_INLINE reference operator [] (size_type i) { BOOST_UBLAS_CHECK (i < size_, bad_index ()); return data_ [i]; } // Assignment BOOST_UBLAS_INLINE bounded_array &operator = (const bounded_array &a) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -