📄 storage.hpp
字号:
//
// Copyright (c) 2000-2002
// Joerg Walter, Mathias Koch
//
// Permission to use, copy, modify, distribute and sell this software
// and its documentation for any purpose is hereby granted without fee,
// provided that the above copyright notice appear in all copies and
// that both that copyright notice and this permission notice appear
// in supporting documentation. The authors make no representations
// about the suitability of this software for any purpose.
// It is provided "as is" without express or implied warranty.
//
// 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/numeric/ublas/exception.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_);
// ISSUE some compilers may zero POD here
#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
// array form fails on some compilers due to size cookie, is it standard conforming?
new (data_) value_type[size_];
#else
for (pointer d = data_; d != data_ + size_; ++d)
new (d) value_type;
#endif
}
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):
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_) {
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 {
// ISSUE some compilers may zero POD here
#ifdef BOOST_UBLAS_USEFUL_ARRAY_PLACEMENT_NEW
// array form fails on some compilers due to size cookie, is it standard conforming?
new (data_) value_type[size];
#else
for (pointer di = data_; di != data_ + size; ++di)
new (di) value_type;
#endif
}
}
if (size_) {
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:
// 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.data_, c.data_ + c.size_, data_);
}
// 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) {
if (this != &a) {
resize (a.size_);
std::copy (a.data_, a.data_ + a.size_, data_);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -