19 #ifndef __TPIE_ARRAY_H__
20 #define __TPIE_ARRAY_H__
27 #include <boost/iterator/iterator_facade.hpp>
30 #include <type_traits>
40 template <
typename TT,
bool forward>
42 array_iter_base<TT, forward>,
43 TT , boost::random_access_traversal_tag> {
45 template <
typename,
typename>
friend class array;
46 friend class boost::iterator_core_access;
51 TT & dereference()
const {
return * elm;}
54 void increment() {elm += forward?1:-1;}
55 void decrement() {elm += forward?-1:1;}
56 void advance(
size_t n) {
if (forward) elm += n;
else elm -= n;}
57 ptrdiff_t distance_to(array_iter_base
const & o)
const {
return o.elm - elm;}
72 typename std::enable_if<
73 std::is_convertible<U*,TT*>::value>::type* = 0)
143 template <
typename T,
typename Allocator = allocator<T> >
168 assert(idx <=
size());
169 return get_iter(idx);
179 assert(idx <=
size());
180 return get_iter(idx);
188 T &
at(
size_t i)
throw() {
190 return m_elements[i];
196 const T &
at(
size_t i)
const throw() {
198 return m_elements[i];
211 for (
size_t i=0; i <
size(); ++i) m_elements[i] = other[i];
225 std::swap(m_allocator, other.m_allocator);
226 std::swap(m_elements, other.m_elements);
227 std::swap(m_size, other.m_size);
228 std::swap(m_tss_used, other.m_tss_used);
241 template <
typename OtherAllocator>
244 for (
size_t i=0; i <
size(); ++i) m_elements[i] = other[i];
285 if (
size() != other.
size())
return false;
286 for (
size_t i=0;i<
size();++i)
if (*get_iter(i) != *other.get_iter(i))
return false;
297 if (
size() != other.
size())
return true;
298 for (
size_t i=0; i<
size(); ++i)
if (*get_iter(i) != *other.get_iter(i))
return true;
394 return (
double)
sizeof(T);
409 const Allocator & alloc=Allocator()
410 ): m_elements(0), m_size(0), m_tss_used(false), m_allocator(alloc)
414 m_elements(0), m_size(0), m_tss_used(false), m_allocator(bucket)
417 array(memory_bucket_ref bucket):
418 m_elements(0), m_size(0), m_tss_used(false), m_allocator(bucket) {}
425 array(size_type s=0,
const Allocator & alloc=
426 Allocator()): m_elements(0), m_size(0), m_tss_used(false),
427 m_allocator(alloc) {
resize(s);}
433 array(
const array & other): m_elements(0), m_size(other.m_size), m_tss_used(false), m_allocator(other.m_allocator) {
434 if (other.
size() == 0)
return;
435 alloc_copy(other.m_elements);
443 : m_elements(other.m_elements)
444 , m_size(other.m_size)
445 , m_tss_used(other.m_tss_used)
446 , m_allocator(other.m_allocator) {
447 other.m_elements =
nullptr;
449 other.m_tss_used =
false;
454 , m_size(view.
size())
457 if (view.
size() == 0)
return;
458 alloc_copy(&*view.
begin());
461 array(
const array_view_base<const T> & view)
463 , m_size(view.
size())
466 if (view.size() == 0)
return;
467 alloc_copy(&*view.begin());
486 if (size != m_size) {
487 destruct_and_dealloc();
492 std::fill(m_elements+0, m_elements+m_size, elm);
500 std::swap(m_allocator, other.m_allocator);
501 std::swap(m_elements, other.m_elements);
502 std::swap(m_size, other.m_size);
503 std::swap(m_tss_used, other.m_tss_used);
516 destruct_and_dealloc();
526 size_type
size()
const {
return m_size;}
531 T *
get() {
return m_elements;}
536 const T *
get()
const {
return m_elements;}
561 void alloc_fill(
const T & elm) { bits::allocator_usage<T, Allocator>::alloc_fill(*
this, elm); }
568 void alloc_dfl() { bits::allocator_usage<T, Allocator>::alloc_dfl(*
this); }
575 void destruct_and_dealloc() { bits::allocator_usage<T, Allocator>::destruct_and_dealloc(*
this); }
581 Allocator m_allocator;
586 template <
typename T>
589 host.m_elements = host.m_size ?
reinterpret_cast<T*
>(tpie_new_array<trivial_same_size<T> >(host.m_size)) : 0;
590 host.m_tss_used =
true;
592 if (host.m_allocator.bucket)
593 host.m_allocator.bucket->count +=
sizeof(T) * host.m_size;
595 std::uninitialized_copy(copy_from+0, copy_from+host.m_size, host.m_elements+0);
599 host.m_elements = host.m_size ?
reinterpret_cast<T*
>(tpie_new_array<trivial_same_size<T> >(host.m_size)) : 0;
600 host.m_tss_used =
true;
602 if (host.m_allocator.bucket)
603 host.m_allocator.bucket->count +=
sizeof(T) * host.m_size;
606 std::uninitialized_fill(host.m_elements+0, host.m_elements+host.m_size, elm);
610 host.m_elements = host.m_size ? tpie_new_array<T>(host.m_size) : 0;
611 host.m_tss_used =
false;
613 if (host.m_allocator.bucket)
614 host.m_allocator.bucket->count +=
sizeof(T) * host.m_size;
618 if (host.m_allocator.bucket)
619 host.m_allocator.bucket->count -=
sizeof(T) * host.m_size;
621 if (!host.m_tss_used) {
628 for (
size_t i = 0; i < host.m_size; ++i) {
629 host.m_elements[i].~T();
635 template <
typename T,
typename Allocator>
638 host.m_elements = host.m_size ? host.m_allocator.allocate(host.m_size) : 0;
639 for (
size_t i = 0; i < host.m_size; ++i) {
640 host.m_allocator.construct(host.m_elements+i, copy_from[i]);
644 static void alloc_fill(array<T, Allocator> & host,
const T & elm) {
645 host.m_elements = host.m_size ? host.m_allocator.allocate(host.m_size) : 0;
646 for (
size_t i = 0; i < host.m_size; ++i) {
647 host.m_allocator.construct(host.m_elements+i, elm);
651 static void alloc_dfl(array<T, Allocator> & host) {
652 host.m_elements = host.m_size ? host.m_allocator.allocate(host.m_size) : 0;
653 for (
size_t i = 0; i < host.m_size; ++i) {
654 host.m_allocator.construct(host.m_elements+i);
658 static void destruct_and_dealloc(array<T, Allocator> & host) {
659 for (
size_t i = 0; i < host.m_size; ++i) {
660 host.m_allocator.destroy(host.m_elements+i);
662 host.m_allocator.deallocate(host.m_elements, host.m_size);
668 template <
typename T>
669 std::ostream & operator<<(std::ostream & o, const array<T> & a) {
672 for(
size_t i=0; i < a.size(); ++i) {
673 if (first) first =
false;
703 template <
typename T>
711 template <
typename TT1,
bool forward1,
typename TT2,
bool forward2>
717 ptrdiff_t dist = copy(&*first, &*last, &*d_first) - &*d_first;
718 return d_first + dist;
724 template <
typename TT,
bool forward,
typename OutputIterator>
728 OutputIterator d_first) {
730 return copy(&*first, &*last, d_first);
736 template <
typename TT,
bool forward,
typename InputIterator>
738 copy(InputIterator first,
742 ptrdiff_t dist = copy(first, last, &*d_first) - &*d_first;
743 return d_first + dist;
748 #endif //__TPIE_ARRAY_H__
Base class for array_view.
const_iterator end() const
Return a const iterator to the end of the array.
array_iter_base< T const, false > const_reverse_iterator
Reverse iterator over a const array.
T & front()
Return the first element in the array.
array(size_type s=0, const Allocator &alloc=Allocator())
Construct array of given size.
array(const array &other)
Construct a copy of another array.
iterator find(size_t idx)
Return an iterator to the i'th element of the array.
array & operator=(const array &other)
Copy elements from another array into this.
T & at(size_t i)
Return the element located at the given index.
Memory management subsystem.
T value_type
Type of values containd in the array.
Base class for array_view.
Base class of data structures with linear memory usage.
reverse_iterator rend()
Reverse iterator to end of reverse sequence.
A generic array with a fixed size.
const T & at(size_t i) const
const_reverse_iterator rbegin() const
Const reverse iterator to beginning of reverse sequence.
array_iter_base()
Default constructor.
const T & front() const
Return the first element in the array.
const_iterator begin() const
Return a const iterator to the beginning of the array.
void resize(size_t s)
Change the size of the array.
Allocator get_allocator() const
Return copy of the allocator.
const_iterator find(size_t idx) const
Return a const iterator to the i'th element of the array.
Shared implementation of array iterators.
array_iter_base(array_iter_base< U, forward > const &o, typename std::enable_if< std::is_convertible< U *, TT * >::value >::type *=0)
Copy constructor.
array & operator=(array &&other)
Move elements from another array into this.
T & operator[](size_t i)
Return a reference to an array entry.
const T & back() const
Return the last element in the array.
array_iter_base< T, false > reverse_iterator
Reverse iterator over an array.
A allocator object usable in STL containers, using the TPIE memory manager.
Class storring a reference to a memory bucket.
array(array &&other)
Move construct from another array.
Miscellaneous utility functions.
static double memory_coefficient()
Return the memory coefficient of the structure.
array_iter_base< T const, true > const_iterator
Iterator over a const array.
reverse_iterator rbegin()
Reverse iterator to beginning of reverse sequence.
size_t size() const
Get number of elements in the array.
array & operator=(const array< T, OtherAllocator > &other)
Copy elements from another array with any allocator into this.
void resize(size_t size, const T &elm)
Change the size of the array.
array_iter_base< T, true > iterator
Iterator over an array.
static double memory_overhead()
Return the memory overhead of the structure.
iterator begin() const
Return an iterator to the beginning of the array.
const_reverse_iterator rend() const
Const reverse iterator to end of reverse sequence.
const T & operator[](size_t i) const
Return a const reference to an array entry.
void swap(array &other)
Swap two arrays.
T & back()
Return the last element in the array.
iterator end()
Return an iterator to the end of the array.
bool operator==(const array &other) const
Compare if the other array has the same elements in the same order as this.
iterator begin()
Return an iterator to the beginning of the array.
size_type size() const
Return the size of the array.
bool empty() const
Check if the array is empty.
bool operator!=(const array &other) const
Check if two arrays differ.
array(size_type s, const T &value, const Allocator &alloc=Allocator())
Construct array of given size.
~array()
Free up all memory used by the array.
void tpie_delete_array(T *a, size_t size)
Delete an array allocated with tpie_new_array.