LIBINT 2.7.2
stdarray_bits.h
1// shamelessly borrowed from MADNESS (GPLv3)
2// written by Justus Calvin (justus.c79@gmail.com)
3
4#ifndef _libint2_include_stdarraybits_h
5#define _libint2_include_stdarraybits_h
6
7#include <stdexcept>
8
9namespace libint2 {
10 namespace tr1 {
11 namespace array {
13 template <typename T, std::size_t N>
14 class array {
15 public:
16 T elems[N]; // fixed-size array of elements of type T
17
18 public:
19 // type definitions
20 typedef T value_type;
21 typedef T* iterator;
22 typedef const T* const_iterator;
23 typedef T& reference;
24 typedef const T& const_reference;
25 typedef std::size_t size_type;
26 typedef std::ptrdiff_t difference_type;
27
28 // iterator support
29 iterator begin() { return elems; }
30 const_iterator begin() const { return elems; }
31 iterator end() { return elems+N; }
32 const_iterator end() const { return elems+N; }
33
34 // reverse iterator support
35 typedef std::reverse_iterator<iterator> reverse_iterator;
36 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
37
38 reverse_iterator rbegin() { return reverse_iterator(end()); }
39 const_reverse_iterator rbegin() const {
40 return const_reverse_iterator(end());
41 }
42 reverse_iterator rend() { return reverse_iterator(begin()); }
43 const_reverse_iterator rend() const {
44 return const_reverse_iterator(begin());
45 }
46
47 // operator[]
48 reference operator[](size_type i) { return elems[i]; }
49 const_reference operator[](size_type i) const { return elems[i]; }
50
51 // at() with range check
52 reference at(size_type i) { rangecheck(i); return elems[i]; }
53 const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
54
55 // front() and back()
56 reference front() { return elems[0]; }
57 const_reference front() const { return elems[0]; }
58 reference back() { return elems[N-1]; }
59 const_reference back() const { return elems[N-1]; }
60
61 // size is constant
62 static size_type size() { return N; }
63 static bool empty() { return false; }
64 static size_type max_size() { return N; }
65 enum { static_size = N };
66
67 // swap (note: linear complexity in N, constant for given instantiation)
68 void swap (array<T,N>& y) {
69 std::swap_ranges(begin(),end(),y.begin());
70 }
71
72 // direct access to data (read-only)
73 const T* data() const { return elems; }
74
75 // use array as C array (direct read/write access to data)
76 T* data() { return elems; }
77
78 // assignment with type conversion
79 template <typename T2>
80 array<T,N>& operator= (const array<T2,N>& rhs) {
81 std::copy(rhs.begin(),rhs.end(), begin());
82 return *this;
83 }
84
85 // assign one value to all elements
86 void assign (const T& value)
87 {
88 std::fill_n(begin(),size(),value);
89 }
90
91 private:
92 // check range (may be private because it is static)
93 static void rangecheck (size_type i) {
94 if (i >= size()) {
95 throw std::out_of_range("array<>: index out of range");
96 }
97 }
98 };
99
100 template <typename T>
101 class array<T,0> {
102 public:
103 char c; // to ensure different array intances return unique values for begin/end
104
105 public:
106 // type definitions
107 typedef T value_type;
108 typedef T* iterator;
109 typedef const T* const_iterator;
110 typedef T& reference;
111 typedef const T& const_reference;
112 typedef std::size_t size_type;
113 typedef std::ptrdiff_t difference_type;
114
115 // iterator support
116 iterator begin() { return reinterpret_cast< iterator >( &c ); }
117 const_iterator begin() const { return reinterpret_cast< const_iterator >( &c ); }
118 iterator end() { return reinterpret_cast< iterator >( &c ); }
119 const_iterator end() const { return reinterpret_cast< const_iterator >( &c ); }
120
121 // reverse iterator support
122 typedef std::reverse_iterator<iterator> reverse_iterator;
123 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
124
125 reverse_iterator rbegin() { return reverse_iterator(end()); }
126 const_reverse_iterator rbegin() const {
127 return const_reverse_iterator(end());
128 }
129 reverse_iterator rend() { return reverse_iterator(begin()); }
130 const_reverse_iterator rend() const {
131 return const_reverse_iterator(begin());
132 }
133
134 // at() with range check
135 reference at(size_type i) {
136 makes_no_sense();
137 }
138 const_reference at(size_type i) const {
139 makes_no_sense();
140 }
141
142 // size is constant
143 static size_type size() { return 0; }
144 static bool empty() { return true; }
145 static size_type max_size() { return 0; }
146 enum { static_size = 0 };
147
148 // swap
149 void swap (array<T,0>& y) {
150 // could swap value of c, but value is not part of documented array state
151 }
152
153 // direct access to data
154 const T* data() const { return NULL; }
155 T* data() { return NULL; }
156
157 // assignment with type conversion
158 template < typename T2 >
159 array< T,0 >& operator= (const array< T2, 0>& rhs) {
160 return *this;
161 }
162
163 // Calling these operations are undefined behaviour for 0-size arrays,
164 // but Library TR1 requires their presence.
165 // operator[]
166 reference operator[](size_type i) { makes_no_sense(); }
167 const_reference operator[](size_type i) const { makes_no_sense(); }
168
169 // front() and back()
170 reference front() { makes_no_sense(); }
171 const_reference front() const { makes_no_sense(); }
172 reference back() { makes_no_sense(); }
173 const_reference back() const { makes_no_sense(); }
174
175 private:
176 // helper for operations that have undefined behaviour for 0-size arrays,
177 // assert( false ); added to make lack of support clear
178 static void makes_no_sense () {
179 //assert(true);
180 throw std::out_of_range("array<0>: index out of range");
181 }
182 };
183
184 // comparisons
185 template<class T, std::size_t N>
186 bool operator== (const array<T,N>& x, const array<T,N>& y) {
187 return std::equal(x.begin(), x.end(), y.begin());
188 }
189 template<class T, std::size_t N>
190 bool operator< (const array<T,N>& x, const array<T,N>& y) {
191 return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
192 }
193 template<class T, std::size_t N>
194 bool operator!= (const array<T,N>& x, const array<T,N>& y) {
195 return !(x==y);
196 }
197 template<class T, std::size_t N>
198 bool operator> (const array<T,N>& x, const array<T,N>& y) {
199 return y<x;
200 }
201 template<class T, std::size_t N>
202 bool operator<= (const array<T,N>& x, const array<T,N>& y) {
203 return !(y<x);
204 }
205 template<class T, std::size_t N>
206 bool operator>= (const array<T,N>& x, const array<T,N>& y) {
207 return !(x<y);
208 }
209
210 // global swap()
211 template<class T, std::size_t N>
212 inline void swap (array<T,N>& x, array<T,N>& y) {
213 x.swap(y);
214 }
215 }
216 }
217}
218
219#endif // header guard
Definition: stdarray_bits.h:101
Array idential to C++0X arrays.
Definition: stdarray_bits.h:14
Defaults definitions for various parameters assumed by Libint.
Definition: algebra.cc:24