/Src/Dependencies/Boost/boost/array.hpp

http://hadesmem.googlecode.com/ · C++ Header · 437 lines · 296 code · 62 blank · 79 comment · 20 complexity · 20e0a365095d234de5868ab6d43daf81 MD5 · raw file

  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. #include <boost/detail/workaround.hpp>
  32. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  33. # pragma warning(push)
  34. # pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe
  35. # pragma warning(disable:4510) // boost::array<T,N>' : default constructor could not be generated
  36. # pragma warning(disable:4610) // warning C4610: class 'boost::array<T,N>' can never be instantiated - user defined constructor required
  37. #endif
  38. #include <cstddef>
  39. #include <stdexcept>
  40. #include <boost/assert.hpp>
  41. #include <boost/swap.hpp>
  42. // Handles broken standard libraries better than <iterator>
  43. #include <boost/detail/iterator.hpp>
  44. #include <boost/throw_exception.hpp>
  45. #include <algorithm>
  46. // FIXES for broken compilers
  47. #include <boost/config.hpp>
  48. namespace boost {
  49. template<class T, std::size_t N>
  50. class array {
  51. public:
  52. T elems[N]; // fixed-size array of elements of type T
  53. public:
  54. // type definitions
  55. typedef T value_type;
  56. typedef T* iterator;
  57. typedef const T* const_iterator;
  58. typedef T& reference;
  59. typedef const T& const_reference;
  60. typedef std::size_t size_type;
  61. typedef std::ptrdiff_t difference_type;
  62. // iterator support
  63. iterator begin() { return elems; }
  64. const_iterator begin() const { return elems; }
  65. const_iterator cbegin() const { return elems; }
  66. iterator end() { return elems+N; }
  67. const_iterator end() const { return elems+N; }
  68. const_iterator cend() const { return elems+N; }
  69. // reverse iterator support
  70. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
  71. typedef std::reverse_iterator<iterator> reverse_iterator;
  72. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  73. #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
  74. // workaround for broken reverse_iterator in VC7
  75. typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
  76. reference, iterator, reference> > reverse_iterator;
  77. typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
  78. const_reference, iterator, reference> > const_reverse_iterator;
  79. #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
  80. typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
  81. value_type, reference, iterator, difference_type> reverse_iterator;
  82. typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
  83. value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
  84. #else
  85. // workaround for broken reverse_iterator implementations
  86. typedef std::reverse_iterator<iterator,T> reverse_iterator;
  87. typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
  88. #endif
  89. reverse_iterator rbegin() { return reverse_iterator(end()); }
  90. const_reverse_iterator rbegin() const {
  91. return const_reverse_iterator(end());
  92. }
  93. const_reverse_iterator crbegin() const {
  94. return const_reverse_iterator(end());
  95. }
  96. reverse_iterator rend() { return reverse_iterator(begin()); }
  97. const_reverse_iterator rend() const {
  98. return const_reverse_iterator(begin());
  99. }
  100. const_reverse_iterator crend() const {
  101. return const_reverse_iterator(begin());
  102. }
  103. // operator[]
  104. reference operator[](size_type i)
  105. {
  106. BOOST_ASSERT( i < N && "out of range" );
  107. return elems[i];
  108. }
  109. const_reference operator[](size_type i) const
  110. {
  111. BOOST_ASSERT( i < N && "out of range" );
  112. return elems[i];
  113. }
  114. // at() with range check
  115. reference at(size_type i) { rangecheck(i); return elems[i]; }
  116. const_reference at(size_type i) const { rangecheck(i); return elems[i]; }
  117. // front() and back()
  118. reference front()
  119. {
  120. return elems[0];
  121. }
  122. const_reference front() const
  123. {
  124. return elems[0];
  125. }
  126. reference back()
  127. {
  128. return elems[N-1];
  129. }
  130. const_reference back() const
  131. {
  132. return elems[N-1];
  133. }
  134. // size is constant
  135. static size_type size() { return N; }
  136. static bool empty() { return false; }
  137. static size_type max_size() { return N; }
  138. enum { static_size = N };
  139. // swap (note: linear complexity)
  140. void swap (array<T,N>& y) {
  141. for (size_type i = 0; i < N; ++i)
  142. boost::swap(elems[i],y.elems[i]);
  143. }
  144. // direct access to data (read-only)
  145. const T* data() const { return elems; }
  146. T* data() { return elems; }
  147. // use array as C array (direct read/write access to data)
  148. T* c_array() { return elems; }
  149. // assignment with type conversion
  150. template <typename T2>
  151. array<T,N>& operator= (const array<T2,N>& rhs) {
  152. std::copy(rhs.begin(),rhs.end(), begin());
  153. return *this;
  154. }
  155. // assign one value to all elements
  156. void assign (const T& value) { fill ( value ); } // A synonym for fill
  157. void fill (const T& value)
  158. {
  159. std::fill_n(begin(),size(),value);
  160. }
  161. // check range (may be private because it is static)
  162. static void rangecheck (size_type i) {
  163. if (i >= size()) {
  164. std::out_of_range e("array<>: index out of range");
  165. boost::throw_exception(e);
  166. }
  167. }
  168. };
  169. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
  170. template< class T >
  171. class array< T, 0 > {
  172. public:
  173. // type definitions
  174. typedef T value_type;
  175. typedef T* iterator;
  176. typedef const T* const_iterator;
  177. typedef T& reference;
  178. typedef const T& const_reference;
  179. typedef std::size_t size_type;
  180. typedef std::ptrdiff_t difference_type;
  181. // iterator support
  182. iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); }
  183. const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
  184. const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); }
  185. iterator end() { return begin(); }
  186. const_iterator end() const { return begin(); }
  187. const_iterator cend() const { return cbegin(); }
  188. // reverse iterator support
  189. #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS)
  190. typedef std::reverse_iterator<iterator> reverse_iterator;
  191. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  192. #elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310)
  193. // workaround for broken reverse_iterator in VC7
  194. typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator,
  195. reference, iterator, reference> > reverse_iterator;
  196. typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator,
  197. const_reference, iterator, reference> > const_reverse_iterator;
  198. #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
  199. typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
  200. value_type, reference, iterator, difference_type> reverse_iterator;
  201. typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
  202. value_type, const_reference, const_iterator, difference_type> const_reverse_iterator;
  203. #else
  204. // workaround for broken reverse_iterator implementations
  205. typedef std::reverse_iterator<iterator,T> reverse_iterator;
  206. typedef std::reverse_iterator<const_iterator,T> const_reverse_iterator;
  207. #endif
  208. reverse_iterator rbegin() { return reverse_iterator(end()); }
  209. const_reverse_iterator rbegin() const {
  210. return const_reverse_iterator(end());
  211. }
  212. const_reverse_iterator crbegin() const {
  213. return const_reverse_iterator(end());
  214. }
  215. reverse_iterator rend() { return reverse_iterator(begin()); }
  216. const_reverse_iterator rend() const {
  217. return const_reverse_iterator(begin());
  218. }
  219. const_reverse_iterator crend() const {
  220. return const_reverse_iterator(begin());
  221. }
  222. // operator[]
  223. reference operator[](size_type /*i*/)
  224. {
  225. return failed_rangecheck();
  226. }
  227. const_reference operator[](size_type /*i*/) const
  228. {
  229. return failed_rangecheck();
  230. }
  231. // at() with range check
  232. reference at(size_type /*i*/) { return failed_rangecheck(); }
  233. const_reference at(size_type /*i*/) const { return failed_rangecheck(); }
  234. // front() and back()
  235. reference front()
  236. {
  237. return failed_rangecheck();
  238. }
  239. const_reference front() const
  240. {
  241. return failed_rangecheck();
  242. }
  243. reference back()
  244. {
  245. return failed_rangecheck();
  246. }
  247. const_reference back() const
  248. {
  249. return failed_rangecheck();
  250. }
  251. // size is constant
  252. static size_type size() { return 0; }
  253. static bool empty() { return true; }
  254. static size_type max_size() { return 0; }
  255. enum { static_size = 0 };
  256. void swap (array<T,0>& /*y*/) {
  257. }
  258. // direct access to data (read-only)
  259. const T* data() const { return 0; }
  260. T* data() { return 0; }
  261. // use array as C array (direct read/write access to data)
  262. T* c_array() { return 0; }
  263. // assignment with type conversion
  264. template <typename T2>
  265. array<T,0>& operator= (const array<T2,0>& ) {
  266. return *this;
  267. }
  268. // assign one value to all elements
  269. void assign (const T& value) { fill ( value ); }
  270. void fill (const T& ) {}
  271. // check range (may be private because it is static)
  272. static reference failed_rangecheck () {
  273. std::out_of_range e("attempt to access element of an empty array");
  274. boost::throw_exception(e);
  275. #if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__))
  276. //
  277. // We need to return something here to keep
  278. // some compilers happy: however we will never
  279. // actually get here....
  280. //
  281. static T placeholder;
  282. return placeholder;
  283. #endif
  284. }
  285. };
  286. #endif
  287. // comparisons
  288. template<class T, std::size_t N>
  289. bool operator== (const array<T,N>& x, const array<T,N>& y) {
  290. return std::equal(x.begin(), x.end(), y.begin());
  291. }
  292. template<class T, std::size_t N>
  293. bool operator< (const array<T,N>& x, const array<T,N>& y) {
  294. return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end());
  295. }
  296. template<class T, std::size_t N>
  297. bool operator!= (const array<T,N>& x, const array<T,N>& y) {
  298. return !(x==y);
  299. }
  300. template<class T, std::size_t N>
  301. bool operator> (const array<T,N>& x, const array<T,N>& y) {
  302. return y<x;
  303. }
  304. template<class T, std::size_t N>
  305. bool operator<= (const array<T,N>& x, const array<T,N>& y) {
  306. return !(y<x);
  307. }
  308. template<class T, std::size_t N>
  309. bool operator>= (const array<T,N>& x, const array<T,N>& y) {
  310. return !(x<y);
  311. }
  312. // global swap()
  313. template<class T, std::size_t N>
  314. inline void swap (array<T,N>& x, array<T,N>& y) {
  315. x.swap(y);
  316. }
  317. #if defined(__SUNPRO_CC)
  318. // Trac ticket #4757; the Sun Solaris compiler can't handle
  319. // syntax like 'T(&get_c_array(boost::array<T,N>& arg))[N]'
  320. //
  321. // We can't just use this for all compilers, because the
  322. // borland compilers can't handle this form.
  323. namespace detail {
  324. template <typename T, std::size_t N> struct c_array
  325. {
  326. typedef T type[N];
  327. };
  328. }
  329. // Specific for boost::array: simply returns its elems data member.
  330. template <typename T, std::size_t N>
  331. typename detail::c_array<T,N>::type& get_c_array(boost::array<T,N>& arg)
  332. {
  333. return arg.elems;
  334. }
  335. // Specific for boost::array: simply returns its elems data member.
  336. template <typename T, std::size_t N>
  337. typename const detail::c_array<T,N>::type& get_c_array(const boost::array<T,N>& arg)
  338. {
  339. return arg.elems;
  340. }
  341. #else
  342. // Specific for boost::array: simply returns its elems data member.
  343. template <typename T, std::size_t N>
  344. T(&get_c_array(boost::array<T,N>& arg))[N]
  345. {
  346. return arg.elems;
  347. }
  348. // Const version.
  349. template <typename T, std::size_t N>
  350. const T(&get_c_array(const boost::array<T,N>& arg))[N]
  351. {
  352. return arg.elems;
  353. }
  354. #endif
  355. #if 0
  356. // Overload for std::array, assuming that std::array will have
  357. // explicit conversion functions as discussed at the WG21 meeting
  358. // in Summit, March 2009.
  359. template <typename T, std::size_t N>
  360. T(&get_c_array(std::array<T,N>& arg))[N]
  361. {
  362. return static_cast<T(&)[N]>(arg);
  363. }
  364. // Const version.
  365. template <typename T, std::size_t N>
  366. const T(&get_c_array(const std::array<T,N>& arg))[N]
  367. {
  368. return static_cast<T(&)[N]>(arg);
  369. }
  370. #endif
  371. } /* namespace boost */
  372. #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
  373. # pragma warning(pop)
  374. #endif
  375. #endif /*BOOST_ARRAY_HPP*/