vSMC
vSMC: Scalable Monte Carlo
array.hpp
Go to the documentation of this file.
1 //============================================================================
2 // vSMC/include/vsmc/utility/array.hpp
3 //----------------------------------------------------------------------------
4 // vSMC: Scalable Monte Carlo
5 //----------------------------------------------------------------------------
6 // Copyright (c) 2013,2014, Yan Zhou
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are met:
11 //
12 // Redistributions of source code must retain the above copyright notice,
13 // this list of conditions and the following disclaimer.
14 //
15 // Redistributions in binary form must reproduce the above copyright notice,
16 // this list of conditions and the following disclaimer in the documentation
17 // and/or other materials provided with the distribution.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 // POSSIBILITY OF SUCH DAMAGE.
30 //============================================================================
31 
32 #ifndef VSMC_UTILITY_ARRAY_HPP
33 #define VSMC_UTILITY_ARRAY_HPP
34 
35 #include <vsmc/internal/common.hpp>
36 
37 #ifdef VSMC_MSVC
38 #pragma warning(push)
39 #pragma warning(disable:4351)
40 #endif
41 
42 #define VSMC_STATIC_ASSERT_UTILITY_ARRAY_RANGE(Pos, N) \
43  VSMC_STATIC_ASSERT((Pos < N), USE_Array_WITH_AN_INDEX_OUT_OF_RANGE)
44 
45 #define VSMC_RUNTIME_ASSERT_UTILITY_ARRAY_RANGE(i, N) \
46  VSMC_RUNTIME_ASSERT((i < N), ("**Array** USED WITH AN INDEX OUT OF RANGE"))
47 
48 namespace vsmc {
49 
78 template <typename T, std::size_t N>
79 class Array
80 {
81  public :
82 
83  typedef T value_type;
84  typedef std::size_t size_type;
85  typedef std::ptrdiff_t difference_type;
86  typedef value_type & reference;
87  typedef const value_type & const_reference;
88  typedef value_type * pointer;
89  typedef const value_type * const_pointer;
90  typedef pointer iterator;
91  typedef const_pointer const_iterator;
92  typedef std::reverse_iterator<iterator> reverse_iterator;
93  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
94 
95  template <typename Archive>
96  void serialize (Archive &ar, const unsigned) {ar & data_;}
97 
98  template <typename Archive>
99  void serialize (Archive &ar, const unsigned) const {ar & data_;}
100 
101  reference at (size_type pos)
102  {
104 
105  return data_[pos];
106  }
107 
108  const_reference at (size_type pos) const
109  {
111 
112  return data_[pos];
113  }
114 
115  reference operator[] (size_type pos) {return data_[pos];}
116 
117  const_reference operator[] (size_type pos) const {return data_[pos];}
118 
119  reference front () {return at<0>();}
120 
121  const_reference front () const {return at<0>();}
122 
123  reference back () {return at<N - 1>();}
124 
125  const_reference back () const {return at<N - 1>();}
126 
127  pointer data () {return data_;}
128 
129  const_pointer data () const {return data_;}
130 
131  iterator begin () {return data_;}
132 
133  iterator end () {return data_ + N;}
134 
135  const_iterator begin () const {return data_;}
136 
137  const_iterator end () const {return data_ + N;}
138 
139  const_iterator cbegin () const {return data_;}
140 
141  const_iterator cend () const {return data_ + N;}
142 
143  reverse_iterator rbegin () {return reverse_iterator(end());}
144 
145  reverse_iterator rend () {return reverse_iterator(begin());}
146 
147  const_reverse_iterator rbegin () const
148  {return const_reverse_iterator(end());}
149 
150  const_reverse_iterator rend () const
151  {return const_reverse_iterator(begin());}
152 
153  const_reverse_iterator crbegin () const
154  {return const_reverse_iterator(cend());}
155 
156  const_reverse_iterator crend () const
157  {return const_reverse_iterator(cbegin());}
158 
159  static VSMC_CONSTEXPR bool empty () {return N == 0;}
160 
161  static VSMC_CONSTEXPR size_type size () {return N;}
162 
163  static VSMC_CONSTEXPR size_type max_size ()
164  {return static_cast<size_type>(~static_cast<size_type>(0)) / sizeof(T);}
165 
166  void fill (const T &value)
167  {
168  fill(value, cxx11::integral_constant<bool,
169  cxx11::is_integral<T>::value && N >= 100>());
170  }
171 
172  void swap (Array<T, N> &other)
173  {
174  using std::swap;
175 
176  for (size_type i = 0; i != N; ++i)
177  swap(data_[i], other.data_[i]);
178  }
179 
180  friend inline bool operator== (
181  const Array<T, N> &ary1, const Array<T, N> &ary2)
182  {
183  for (size_type i = 0; i != N; ++i)
184  if (ary1[i] != ary2[i])
185  return false;
186 
187  return true;
188  }
189 
190  friend inline bool operator!= (
191  const Array<T, N> &ary1, const Array<T, N> &ary2)
192  {return !(ary1 == ary2);}
193 
194  friend inline bool operator< (
195  const Array<T, N> &ary1, const Array<T, N> &ary2)
196  {
197  for (size_type i = 0; i != N; ++i) {
198  if (ary1[i] < ary2[i])
199  return true;
200  if (ary2[i] < ary1[i])
201  return false;
202  }
203 
204  return false;
205  }
206 
207  friend inline bool operator> (
208  const Array<T, N> &ary1, const Array<T, N> &ary2)
209  {
210  for (size_type i = 0; i != N; ++i) {
211  if (ary1[i] > ary2[i])
212  return true;
213  if (ary2[i] > ary1[i])
214  return false;
215  }
216 
217  return false;
218  }
219 
220  friend inline bool operator<= (
221  const Array<T, N> &ary1, const Array<T, N> &ary2)
222  {return !(ary1 > ary2);}
223 
224  friend inline bool operator>= (
225  const Array<T, N> &ary1, const Array<T, N> &ary2)
226  {return !(ary1 < ary2);}
227 
228  template <typename CharT, typename Traits>
229  friend inline std::basic_ostream<CharT, Traits> &operator<< (
230  std::basic_ostream<CharT, Traits> &os, const Array<T, N> &ary)
231  {
232  if (!os.good())
233  return os;
234 
235  for (size_type i = 0; i < N - 1; ++i)
236  os << ary[i] << ' ';
237  os << ary[N - 1];
238 
239  return os;
240  }
241 
242  template <typename CharT, typename Traits>
243  friend inline std::basic_istream<CharT, Traits> &operator>> (
244  std::basic_istream<CharT, Traits> &is, Array<T, N> &ary)
245  {
246  if (!is.good())
247  return is;
248 
249  Array<T, N> ary_tmp;
250  for (size_type i = 0; i != N; ++i)
251  is >> std::ws >> ary_tmp[i];
252 
253  if (is.good()) {
254 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
255  ary = cxx11::move(ary_tmp);
256 #else
257  ary = ary_tmp;
258 #endif
259  }
260 
261  return is;
262  }
263 
264  template <size_type Pos>
265  reference at ()
266  {
268  return data_[Pos];
269  }
270 
271  template <size_type Pos>
272  const_reference at () const
273  {
275  return data_[Pos];
276  }
277 
278  template <size_type Pos>
279  reference at (Position<Pos>)
280  {
282  return data_[Pos];
283  }
284 
285  template <size_type Pos>
286  const_reference at (Position<Pos>) const
287  {
289  return data_[Pos];
290  }
291 
292  template <size_type Pos>
293  reference operator[] (Position<Pos>) {return at<Pos>();}
294 
295  template <size_type Pos>
296  const_reference operator[] (Position<Pos>) const {return at<Pos>();}
297 
298  private :
299 
300  value_type data_[N];
301 
302  void fill (const T &value, cxx11::true_type)
303  {
304  if (value == 0)
305  std::memset(data_, 0, sizeof(T) * N);
306  else
307  fill(value, cxx11::false_type());
308  }
309 
310  void fill (const T &value, cxx11::false_type)
311  {for (size_type i = 0; i != N; ++i) data_[i] = value;}
312 }; // class Array
313 
316 template <typename T, std::size_t N>
317 inline void swap (Array<T, N> &ary1, Array<T, N> &ary2) {ary1.swap(ary2);}
318 
321 template <std::size_t I, typename T, std::size_t N>
322 inline T &get (Array<T, N> &ary) {return ary.template at<I>();}
323 
326 template <std::size_t I, typename T, std::size_t N>
327 inline const T &get (const Array<T, N> &ary) {return ary.template at<I>();}
328 
329 #if VSMC_HAS_CXX11_RVALUE_REFERENCES
330 template <std::size_t I, typename T, std::size_t N>
333 inline T &&get (Array<T, N> &&ary) {return cxx11::move(ary.template at<I>());}
334 #endif
335 
336 template <typename> struct TupleSize;
337 
340 template <typename T, std::size_t N>
341 struct TupleSize<Array<T, N> > :
342 public cxx11::integral_constant<std::size_t, N> {};
343 
344 template <std::size_t, typename> struct TupleElement;
345 
348 template <std::size_t I, typename T, std::size_t N>
349 struct TupleElement<I, Array<T, N> > {typedef T type;};
350 
351 } // namespace vsmc
352 
353 #ifdef VSMC_MSVC
354 #pragma warning(pop)
355 #endif
356 
357 #endif // VSMC_UTILITY_ARRAY_HPP
value_type * pointer
Definition: array.hpp:88
Definition: adapter.hpp:37
reverse_iterator rbegin()
Definition: array.hpp:143
const_reference at() const
Definition: array.hpp:272
const_pointer data() const
Definition: array.hpp:129
friend bool operator<(const Array< T, N > &ary1, const Array< T, N > &ary2)
Definition: array.hpp:194
const value_type * const_pointer
Definition: array.hpp:89
void serialize(Archive &ar, const unsigned)
Definition: array.hpp:96
std::ptrdiff_t difference_type
Definition: array.hpp:85
#define VSMC_CONSTEXPR
constexpr
Definition: defines.hpp:55
const_reverse_iterator crbegin() const
Definition: array.hpp:153
iterator begin()
Definition: array.hpp:131
const_pointer const_iterator
Definition: array.hpp:91
const_reverse_iterator rend() const
Definition: array.hpp:150
friend std::basic_istream< CharT, Traits > & operator>>(std::basic_istream< CharT, Traits > &is, Array< T, N > &ary)
Definition: array.hpp:243
void swap(Array< T, N > &other)
Definition: array.hpp:172
friend bool operator==(const Array< T, N > &ary1, const Array< T, N > &ary2)
Definition: array.hpp:180
reference operator[](size_type pos)
Definition: array.hpp:115
reference at()
Definition: array.hpp:265
pointer iterator
Definition: array.hpp:90
reference front()
Definition: array.hpp:119
const_iterator begin() const
Definition: array.hpp:135
reference at(Position< Pos >)
Definition: array.hpp:279
static constexpr size_type max_size()
Definition: array.hpp:163
reference back()
Definition: array.hpp:123
integral_constant< bool, false > false_type
void serialize(Archive &ar, const unsigned) const
Definition: array.hpp:99
Function template argument used for position.
Definition: defines.hpp:126
void * memset(void *dst, int ch, std::size_t n)
SIMD optimized memset with non-temporal store for large buffers.
Definition: cstring.hpp:906
friend bool operator>=(const Array< T, N > &ary1, const Array< T, N > &ary2)
Definition: array.hpp:224
friend bool operator!=(const Array< T, N > &ary1, const Array< T, N > &ary2)
Definition: array.hpp:190
#define VSMC_STATIC_ASSERT_UTILITY_ARRAY_RANGE(Pos, N)
Definition: array.hpp:42
static constexpr bool empty()
Definition: array.hpp:159
const_reference back() const
Definition: array.hpp:125
const_iterator cend() const
Definition: array.hpp:141
remove_reference< T >::type && move(T &&t) noexcept
reverse_iterator rend()
Definition: array.hpp:145
const_reference at(size_type pos) const
Definition: array.hpp:108
const_reverse_iterator rbegin() const
Definition: array.hpp:147
friend bool operator>(const Array< T, N > &ary1, const Array< T, N > &ary2)
Definition: array.hpp:207
const_reference at(Position< Pos >) const
Definition: array.hpp:286
void swap(Array< T, N > &ary1, Array< T, N > &ary2)
Array ADL of swap.
Definition: array.hpp:317
pointer data()
Definition: array.hpp:127
const_reference front() const
Definition: array.hpp:121
friend bool operator<=(const Array< T, N > &ary1, const Array< T, N > &ary2)
Definition: array.hpp:220
std::reverse_iterator< iterator > reverse_iterator
Definition: array.hpp:92
T value_type
Definition: array.hpp:83
#define VSMC_RUNTIME_ASSERT_UTILITY_ARRAY_RANGE(i, N)
Definition: array.hpp:45
const_reverse_iterator crend() const
Definition: array.hpp:156
value_type & reference
Definition: array.hpp:86
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: array.hpp:93
void fill(const T &value)
Definition: array.hpp:166
const_iterator cbegin() const
Definition: array.hpp:139
friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const Array< T, N > &ary)
Definition: array.hpp:229
std::size_t size_type
Definition: array.hpp:84
Static array.
Definition: array.hpp:79
reference at(size_type pos)
Definition: array.hpp:101
const value_type & const_reference
Definition: array.hpp:87
iterator end()
Definition: array.hpp:133
static constexpr size_type size()
Definition: array.hpp:161
const_iterator end() const
Definition: array.hpp:137