ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
array.hpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file array.hpp
1 /* The following code declares class array,
2  * an STL container (as wrapper) for arrays of constant size.
3  *
4  * See
5  * http://www.boost.org/libs/array/
6  * for documentation.
7  *
8  * The original author site is at: http://www.josuttis.com/
9  *
10  * (C) Copyright Nicolai M. Josuttis 2001.
11  *
12  * Distributed under the Boost Software License, Version 1.0. (See
13  * accompanying file LICENSE_1_0.txt or copy at
14  * http://www.boost.org/LICENSE_1_0.txt)
15  *
16  * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility.
17  * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group.
18  * See <http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#776> or Trac issue #3168
19  * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow)
20  * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow)
21  * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis)
22  * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries.
23  * 05 Aug 2001 - minor update (Nico Josuttis)
24  * 20 Jan 2001 - STLport fix (Beman Dawes)
25  * 29 Sep 2000 - Initial Revision (Nico Josuttis)
26  *
27  * Jan 29, 2004
28  */
29 #ifndef BOOST_ARRAY_HPP
30 #define BOOST_ARRAY_HPP
31 
32 #include <boost/detail/workaround.hpp>
33 
34 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
35 # pragma warning(push)
36 # pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe
37 # pragma warning(disable:4510) // boost::array<T,N>' : default constructor could not be generated
38 # pragma warning(disable:4610) // warning C4610: class 'boost::array<T,N>' can never be instantiated - user defined constructor required
39 #endif
40 
41 #include <cstddef>
42 #include <stdexcept>
43 #include <boost/assert.hpp>
44 #include <boost/swap.hpp>
45 
46 // Handles broken standard libraries better than <iterator>
47 #include <boost/detail/iterator.hpp>
48 #include <boost/throw_exception.hpp>
49 #include <algorithm>
50 
51 // FIXES for broken compilers
52 #include <boost/config.hpp>
53 
54 
55 namespace boost {
56 
57  template<class T, std::size_t N>
58  class array {
59  public:
60  T elems[N]; // fixed-size array of elements of type T
61 
62  public:
63  // type definitions
64  typedef T value_type;
65  typedef T* iterator;
66  typedef const T* const_iterator;
67  typedef T& reference;
68  typedef const T& const_reference;
69  typedef std::size_t size_type;
70  typedef std::ptrdiff_t difference_type;
71 
72  // iterator support
73  iterator begin() { return elems; }
74  const_iterator begin() const { return elems; }
75  const_iterator cbegin() const { return elems; }
76 
77  iterator end() { return elems+N; }
78  const_iterator end() const { return elems+N; }
79  const_iterator cend() const { return elems+N; }
80 
81  // reverse iterator support
82 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
83  typedef std::reverse_iterator<iterator> reverse_iterator;
84  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
85 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
86  // workaround for broken reverse_iterator in VC7
87  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
89  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
91 #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
92  typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
94  typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
96 #else
97  // workaround for broken reverse_iterator implementations
98  typedef std::reverse_iterator<iterator,T> reverse_iterator;
99  typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
100 #endif
101 
104  return const_reverse_iterator(end());
105  }
107  return const_reverse_iterator(end());
108  }
109 
112  return const_reverse_iterator(begin());
113  }
115  return const_reverse_iterator(begin());
116  }
117 
118  // operator[]
120  {
121  BOOST_ASSERT( i < N && "out of range" );
122  return elems[i];
123  }
124 
126  {
127  BOOST_ASSERT( i < N && "out of range" );
128  return elems[i];
129  }
130 
131  // at() with range check
132  reference at(size_type i) { rangecheck(i); return elems[i]; }
133  const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
134 
135  // front() and back()
137  {
138  return elems[0];
139  }
140 
142  {
143  return elems[0];
144  }
145 
147  {
148  return elems[N-1];
149  }
150 
152  {
153  return elems[N-1];
154  }
155 
156  // size is constant
157  static size_type size() { return N; }
158  static bool empty() { return false; }
159  static size_type max_size() { return N; }
160  enum { static_size = N };
161 
162  // swap (note: linear complexity)
163  void swap (array<T,N>& y) {
164  for (size_type i = 0; i < N; ++i)
165  boost::swap(elems[i],y.elems[i]);
166  }
167 
168  // direct access to data (read-only)
169  const T* data() const { return elems; }
170  T* data() { return elems; }
171 
172  // use array as C array (direct read/write access to data)
173  T* c_array() { return elems; }
174 
175  // assignment with type conversion
176  template <typename T2>
178  std::copy(rhs.begin(),rhs.end(), begin());
179  return *this;
180  }
181 
182  // assign one value to all elements
183  void assign (const T& value) { fill ( value ); } // A synonym for fill
184  void fill (const T& value)
185  {
186  std::fill_n(begin(),size(),value);
187  }
188 
189  // check range (may be private because it is static)
190  static void rangecheck (size_type i) {
191  if (i >= size()) {
192  std::out_of_range e("array<>: index out of range");
193  boost::throw_exception(e);
194  }
195  }
196 
197  };
198 
199 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
200  template< class T >
201  class array< T, 0 > {
202 
203  public:
204  // type definitions
205  typedef T value_type;
206  typedef T* iterator;
207  typedef const T* const_iterator;
208  typedef T& reference;
209  typedef const T& const_reference;
210  typedef std::size_t size_type;
211  typedef std::ptrdiff_t difference_type;
212 
213  // iterator support
214  iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); }
215  const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
216  const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
217 
218  iterator end() { return begin(); }
219  const_iterator end() const { return begin(); }
220  const_iterator cend() const { return cbegin(); }
221 
222  // reverse iterator support
223 #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
224  typedef std::reverse_iterator<iterator> reverse_iterator;
225  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
226 #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
227  // workaround for broken reverse_iterator in VC7
228  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
230  typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
232 #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
233  typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
235  typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
237 #else
238  // workaround for broken reverse_iterator implementations
239  typedef std::reverse_iterator<iterator,T> reverse_iterator;
240  typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
241 #endif
242 
245  return const_reverse_iterator(end());
246  }
248  return const_reverse_iterator(end());
249  }
250 
253  return const_reverse_iterator(begin());
254  }
256  return const_reverse_iterator(begin());
257  }
258 
259  // operator[]
261  {
262  return failed_rangecheck();
263  }
264 
266  {
267  return failed_rangecheck();
268  }
269 
270  // at() with range check
271  reference at(size_type /*i*/) { return failed_rangecheck(); }
272  const_reference at(size_type /*i*/) const { return failed_rangecheck(); }
273 
274  // front() and back()
276  {
277  return failed_rangecheck();
278  }
279 
281  {
282  return failed_rangecheck();
283  }
284 
286  {
287  return failed_rangecheck();
288  }
289 
291  {
292  return failed_rangecheck();
293  }
294 
295  // size is constant
296  static size_type size() { return 0; }
297  static bool empty() { return true; }
298  static size_type max_size() { return 0; }
299  enum { static_size = 0 };
300 
301  void swap (array<T,0>& /*y*/) {
302  }
303 
304  // direct access to data (read-only)
305  const T* data() const { return 0; }
306  T* data() { return 0; }
307 
308  // use array as C array (direct read/write access to data)
309  T* c_array() { return 0; }
310 
311  // assignment with type conversion
312  template <typename T2>
314  return *this;
315  }
316 
317  // assign one value to all elements
318  void assign (const T& value) { fill ( value ); }
319  void fill (const T& ) {}
320 
321  // check range (may be private because it is static)
323  std::out_of_range e("attempt to access element of an empty array");
324  boost::throw_exception(e);
325 #if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__))
326  //
327  // We need to return something here to keep
328  // some compilers happy: however we will never
329  // actually get here....
330  //
331  static T placeholder;
332  return placeholder;
333 #endif
334  }
335  };
336 #endif
337 
338  // comparisons
339  template<class T, std::size_t N>
340  bool operator== (const array<T,N>& x, const array<T,N>& y) {
341  return std::equal(x.begin(), x.end(), y.begin());
342  }
343  template<class T, std::size_t N>
344  bool operator< (const array<T,N>& x, const array<T,N>& y) {
345  return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
346  }
347  template<class T, std::size_t N>
348  bool operator!= (const array<T,N>& x, const array<T,N>& y) {
349  return !(x==y);
350  }
351  template<class T, std::size_t N>
352  bool operator> (const array<T,N>& x, const array<T,N>& y) {
353  return y<x;
354  }
355  template<class T, std::size_t N>
356  bool operator<= (const array<T,N>& x, const array<T,N>& y) {
357  return !(y<x);
358  }
359  template<class T, std::size_t N>
360  bool operator>= (const array<T,N>& x, const array<T,N>& y) {
361  return !(x<y);
362  }
363 
364  // global swap()
365  template<class T, std::size_t N>
366  inline void swap (array<T,N>& x, array<T,N>& y) {
367  x.swap(y);
368  }
369 
370 #if defined(__SUNPRO_CC)
371 // Trac ticket #4757; the Sun Solaris compiler can't handle
372 // syntax like 'T(&get_c_array(boost::array<T,N>& arg))[N]'
373 //
374 // We can't just use this for all compilers, because the
375 // borland compilers can't handle this form.
376  namespace detail {
377  template <typename T, std::size_t N> struct c_array
378  {
379  typedef T type[N];
380  };
381  }
382 
383  // Specific for boost::array: simply returns its elems data member.
384  template <typename T, std::size_t N>
385  typename detail::c_array<T,N>::type& get_c_array(boost::array<T,N>& arg)
386  {
387  return arg.elems;
388  }
389 
390  // Specific for boost::array: simply returns its elems data member.
391  template <typename T, std::size_t N>
392  typename const detail::c_array<T,N>::type& get_c_array(const boost::array<T,N>& arg)
393  {
394  return arg.elems;
395  }
396 #else
397 // Specific for boost::array: simply returns its elems data member.
398  template <typename T, std::size_t N>
400  {
401  return arg.elems;
402  }
403 
404  // Const version.
405  template <typename T, std::size_t N>
406  const T(&get_c_array(const boost::array<T,N>& arg))[N]
407  {
408  return arg.elems;
409  }
410 #endif
411 
412 #if 0
413  // Overload for std::array, assuming that std::array will have
414  // explicit conversion functions as discussed at the WG21 meeting
415  // in Summit, March 2009.
416  template <typename T, std::size_t N>
417  T(&get_c_array(std::array<T,N>& arg))[N]
418  {
419  return static_cast<T(&)[N]>(arg);
420  }
421 
422  // Const version.
423  template <typename T, std::size_t N>
424  const T(&get_c_array(const std::array<T,N>& arg))[N]
425  {
426  return static_cast<T(&)[N]>(arg);
427  }
428 #endif
429 
430 } /* namespace boost */
431 
432 
433 #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
434 # pragma warning(pop)
435 #endif
436 
437 #endif /*BOOST_ARRAY_HPP*/