MPQC  3.0.0-alpha
stdarray_bits.h
1 // shamelessly borrowed from MADNESS (GPLed)
2 // written by Justus Calvin (justus.c79@gmail.com)
3 
4 #ifndef _util_container_stdarraybits_h
5 #define _util_container_stdarraybits_h
6 
7 #include <stdexcept>
8 
9 namespace sc {
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  // MPQC_ASSERT( false ); added to make lack of support clear
178  static void makes_no_sense () {
179  //MPQC_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
sc::tr1::array::array
Array idential to C++0X arrays.
Definition: stdarray_bits.h:14
sc::operator!=
bool operator!=(const Atom &a, const Atom &b)
Definition: atom.h:170
sc::tr1::array::array< T, 0 >
Definition: stdarray_bits.h:101
mpqc::ci::operator<
bool operator<(const Space< Spin > &a, const Space< Spin > &b)
Compare two spaces by their rank.
Definition: subspace.hpp:44
sc::operator==
bool operator==(const Atom &a, const Atom &b)
sc
Contains all MPQC code up to version 3.
Definition: mpqcin.h:14

Generated at Sun Jan 26 2020 23:24:01 for MPQC 3.0.0-alpha using the documentation package Doxygen 1.8.16.