diff options
Diffstat (limited to 'boost/array.hpp')
-rw-r--r-- | boost/array.hpp | 95 |
1 files changed, 53 insertions, 42 deletions
diff --git a/boost/array.hpp b/boost/array.hpp index fa06fa9a5f..210c072125 100644 --- a/boost/array.hpp +++ b/boost/array.hpp @@ -13,6 +13,7 @@ * accompanying file LICENSE_1_0.txt or copy at * http://www.boost.org/LICENSE_1_0.txt) * + * 9 Jan 2013 - (mtc) Added constexpr * 14 Apr 2012 - (mtc) Added support for boost::hash * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility. * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group. @@ -42,12 +43,12 @@ #include <cstddef> #include <stdexcept> #include <boost/assert.hpp> +#include <boost/static_assert.hpp> #include <boost/swap.hpp> // Handles broken standard libraries better than <iterator> #include <boost/detail/iterator.hpp> #include <boost/throw_exception.hpp> -#include <boost/functional/hash_fwd.hpp> #include <algorithm> // FIXES for broken compilers @@ -81,15 +82,9 @@ namespace boost { const_iterator cend() const { return elems+N; } // reverse iterator support -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; -#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) - // workaround for broken reverse_iterator in VC7 - typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator, - reference, iterator, reference> > reverse_iterator; - typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator, - const_reference, iterator, reference> > const_reverse_iterator; #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) typedef std::reverse_iterator<iterator, std::random_access_iterator_tag, value_type, reference, iterator, difference_type> reverse_iterator; @@ -120,19 +115,17 @@ namespace boost { // operator[] reference operator[](size_type i) { - BOOST_ASSERT_MSG( i < N, "out of range" ); - return elems[i]; + return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; } - const_reference operator[](size_type i) const + /*BOOST_CONSTEXPR*/ const_reference operator[](size_type i) const { - BOOST_ASSERT_MSG( i < N, "out of range" ); - return elems[i]; + return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; } // at() with range check - reference at(size_type i) { rangecheck(i); return elems[i]; } - const_reference at(size_type i) const { rangecheck(i); return elems[i]; } + reference at(size_type i) { return rangecheck(i), elems[i]; } + /*BOOST_CONSTEXPR*/ const_reference at(size_type i) const { return rangecheck(i), elems[i]; } // front() and back() reference front() @@ -140,7 +133,7 @@ namespace boost { return elems[0]; } - const_reference front() const + BOOST_CONSTEXPR const_reference front() const { return elems[0]; } @@ -150,15 +143,15 @@ namespace boost { return elems[N-1]; } - const_reference back() const + BOOST_CONSTEXPR const_reference back() const { return elems[N-1]; } // size is constant - static size_type size() { return N; } - static bool empty() { return false; } - static size_type max_size() { return N; } + static BOOST_CONSTEXPR size_type size() { return N; } + static BOOST_CONSTEXPR bool empty() { return false; } + static BOOST_CONSTEXPR size_type max_size() { return N; } enum { static_size = N }; // swap (note: linear complexity) @@ -189,16 +182,12 @@ namespace boost { } // check range (may be private because it is static) - static void rangecheck (size_type i) { - if (i >= size()) { - std::out_of_range e("array<>: index out of range"); - boost::throw_exception(e); - } + static BOOST_CONSTEXPR bool rangecheck (size_type i) { + return i > size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; } }; -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) template< class T > class array< T, 0 > { @@ -222,15 +211,9 @@ namespace boost { const_iterator cend() const { return cbegin(); } // reverse iterator support -#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator; -#elif defined(_MSC_VER) && (_MSC_VER == 1300) && defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB == 310) - // workaround for broken reverse_iterator in VC7 - typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, iterator, - reference, iterator, reference> > reverse_iterator; - typedef std::reverse_iterator<std::_Ptrit<value_type, difference_type, const_iterator, - const_reference, iterator, reference> > const_reverse_iterator; #elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) typedef std::reverse_iterator<iterator, std::random_access_iterator_tag, value_type, reference, iterator, difference_type> reverse_iterator; @@ -264,14 +247,14 @@ namespace boost { return failed_rangecheck(); } - const_reference operator[](size_type /*i*/) const + /*BOOST_CONSTEXPR*/ const_reference operator[](size_type /*i*/) const { return failed_rangecheck(); } // at() with range check reference at(size_type /*i*/) { return failed_rangecheck(); } - const_reference at(size_type /*i*/) const { return failed_rangecheck(); } + /*BOOST_CONSTEXPR*/ const_reference at(size_type /*i*/) const { return failed_rangecheck(); } // front() and back() reference front() @@ -279,7 +262,7 @@ namespace boost { return failed_rangecheck(); } - const_reference front() const + BOOST_CONSTEXPR const_reference front() const { return failed_rangecheck(); } @@ -289,15 +272,15 @@ namespace boost { return failed_rangecheck(); } - const_reference back() const + BOOST_CONSTEXPR const_reference back() const { return failed_rangecheck(); } // size is constant - static size_type size() { return 0; } - static bool empty() { return true; } - static size_type max_size() { return 0; } + static BOOST_CONSTEXPR size_type size() { return 0; } + static BOOST_CONSTEXPR bool empty() { return true; } + static BOOST_CONSTEXPR size_type max_size() { return 0; } enum { static_size = 0 }; void swap (array<T,0>& /*y*/) { @@ -335,7 +318,6 @@ namespace boost { #endif } }; -#endif // comparisons template<class T, std::size_t N> @@ -391,7 +373,7 @@ namespace boost { // Specific for boost::array: simply returns its elems data member. template <typename T, std::size_t N> - typename const detail::c_array<T,N>::type& get_c_array(const boost::array<T,N>& arg) + typename detail::c_array<T,N>::type const& get_c_array(const boost::array<T,N>& arg) { return arg.elems; } @@ -429,6 +411,7 @@ namespace boost { } #endif + template <class It> std::size_t hash_range(It, It); template<class T, std::size_t N> std::size_t hash_value(const array<T,N>& arr) @@ -436,8 +419,36 @@ namespace boost { return boost::hash_range(arr.begin(), arr.end()); } + template <size_t Idx, typename T, size_t N> + T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" ); + return arr[Idx]; + } + + template <size_t Idx, typename T, size_t N> + const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" ); + return arr[Idx]; + } + } /* namespace boost */ +#ifndef BOOST_NO_CXX11_HDR_ARRAY +// If we don't have std::array, I'm assuming that we don't have std::get +namespace std { + template <size_t Idx, typename T, size_t N> + T &get(boost::array<T,N> &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" ); + return arr[Idx]; + } + + template <size_t Idx, typename T, size_t N> + const T &get(const boost::array<T,N> &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" ); + return arr[Idx]; + } +} +#endif #if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) # pragma warning(pop) |