diff --git a/doc/array.xml b/doc/array.xml
index fb1f51f..68ee5a3 100644
--- a/doc/array.xml
+++ b/doc/array.xml
@@ -7,6 +7,10 @@
Nicolai
Josuttis
+
+ Marshall
+ Clow
+
2001
@@ -16,6 +20,11 @@
Nicolai M. Josuttis
+
+ 2012
+ Marshall Clow
+
+
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
@@ -176,6 +185,24 @@
iterator for position after the last element
will not throw
+
+
+
+ const_iterator
+
+
+ constant iterator for the first element
+ will not throw
+
+
+
+
+ const_iterator
+
+
+ constant iterator for position after the last element
+ will not throw
+
@@ -200,6 +227,24 @@
reverse iterator for position after the last element in reverse iteration
+
+
+
+ const_reverse_iterator
+
+
+ constant reverse iterator for the first element of reverse iteration
+ will not throw
+
+
+
+
+ const_reverse_iterator
+
+
+ constant reverse iterator for position after the last element in reverse iteration
+ will not throw
+
@@ -465,6 +510,49 @@
!(x < y)
+
+
+
+
+
+
+ std::size_t
+
+
+ std::size_t
+
+
+
+ T
+
+
+ array<T, N>&
+
+ element of array with index Idx
+ Will static_assert
if Idx >= N
+
+
+
+
+
+
+ std::size_t
+
+
+ std::size_t
+
+
+
+ T
+
+
+ const array<T, N>&
+
+ const element of array with index Idx
+ Will static_assert
if Idx >= N
+
+
+
diff --git a/include/boost/array.hpp b/include/boost/array.hpp
index fa06fa9..210c072 100644
--- a/include/boost/array.hpp
+++ b/include/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
#include
#include
+#include
#include
// Handles broken standard libraries better than
#include
#include
-#include
#include
// 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 reverse_iterator;
typedef std::reverse_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 > reverse_iterator;
- typedef std::reverse_iterator > const_reverse_iterator;
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
typedef std::reverse_iterator 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 reverse_iterator;
typedef std::reverse_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 > reverse_iterator;
- typedef std::reverse_iterator > const_reverse_iterator;
#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC)
typedef std::reverse_iterator 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& /*y*/) {
@@ -335,7 +318,6 @@ namespace boost {
#endif
}
};
-#endif
// comparisons
template
@@ -391,7 +373,7 @@ namespace boost {
// Specific for boost::array: simply returns its elems data member.
template
- typename const detail::c_array::type& get_c_array(const boost::array& arg)
+ typename detail::c_array::type const& get_c_array(const boost::array& arg)
{
return arg.elems;
}
@@ -429,6 +411,7 @@ namespace boost {
}
#endif
+ template std::size_t hash_range(It, It);
template
std::size_t hash_value(const array& arr)
@@ -436,8 +419,36 @@ namespace boost {
return boost::hash_range(arr.begin(), arr.end());
}
+ template
+ T &get(boost::array &arr) BOOST_NOEXCEPT {
+ BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" );
+ return arr[Idx];
+ }
+
+ template
+ const T &get(const boost::array &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
+ T &get(boost::array &arr) BOOST_NOEXCEPT {
+ BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" );
+ return arr[Idx];
+ }
+
+ template
+ const T &get(const boost::array &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)
diff --git a/meta/libraries.json b/meta/libraries.json
new file mode 100644
index 0000000..7710ee2
--- /dev/null
+++ b/meta/libraries.json
@@ -0,0 +1,17 @@
+{
+ "key": "array",
+ "name": "Array",
+ "authors": [
+ "Nicolai Josuttis"
+ ],
+ "description": "STL compliant container wrapper for arrays of constant size.",
+ "std": [
+ "tr1"
+ ],
+ "category": [
+ "Containers"
+ ],
+ "maintainers": [
+ "Marshall Clow "
+ ]
+}
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 5037474..1a04d91 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -17,5 +17,9 @@ test-suite array :
[ run array4.cpp ]
[ run array5.cpp ]
[ run array6.cpp unit_test_framework : : : : array6 ]
+ [ run array7.cpp unit_test_framework : : : : array7 ]
+# [ run array_constexpr.cpp unit_test_framework : : : : array_constexpr ]
+ [ compile-fail array_getfail1.cpp ]
+ [ compile-fail array_getfail2.cpp ]
[ run array_hash.cpp unit_test_framework : : : : array_hash ]
;
diff --git a/test/array7.cpp b/test/array7.cpp
new file mode 100644
index 0000000..de2ebe0
--- /dev/null
+++ b/test/array7.cpp
@@ -0,0 +1,67 @@
+/* tests using std::get on boost:array
+ * (C) Copyright Marshall Clow 2012
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include
+#include
+#include
+#include
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+#include
+#endif
+
+#define BOOST_TEST_MAIN
+#include
+
+namespace {
+
+ #ifndef BOOST_NO_CXX11_HDR_ARRAY
+ template< class T >
+ void RunStdTests()
+ {
+ typedef boost::array< T, 5 > test_type;
+ typedef T arr[5];
+ test_type test_case; // = { 1, 1, 2, 3, 5 };
+
+ T &aRef = std::get<0> ( test_case );
+ BOOST_CHECK ( &*test_case.begin () == &aRef );
+
+ const T &caRef = std::get<0> ( test_case );
+ BOOST_CHECK ( &*test_case.cbegin () == &caRef );
+ }
+ #endif
+
+ template< class T >
+ void RunBoostTests()
+ {
+ typedef boost::array< T, 5 > test_type;
+ typedef T arr[5];
+ test_type test_case; // = { 1, 1, 2, 3, 5 };
+
+ T &aRef = boost::get<0> ( test_case );
+ BOOST_CHECK ( &*test_case.begin () == &aRef );
+
+ const T &caRef = boost::get<0> ( test_case );
+ BOOST_CHECK ( &*test_case.cbegin () == &caRef );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ RunBoostTests< bool >();
+ RunBoostTests< void * >();
+ RunBoostTests< long double >();
+ RunBoostTests< std::string >();
+
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+ RunStdTests< bool >();
+ RunStdTests< void * >();
+ RunStdTests< long double >();
+ RunStdTests< std::string >();
+#endif
+}
+
diff --git a/test/array_constexpr.cpp b/test/array_constexpr.cpp
new file mode 100644
index 0000000..927bdec
--- /dev/null
+++ b/test/array_constexpr.cpp
@@ -0,0 +1,42 @@
+/* tests using constexpr on boost:array
+ * (C) Copyright Marshall Clow 2012
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include
+#include
+#include
+#include
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+#include
+#endif
+
+#define BOOST_TEST_MAIN
+#include
+
+#ifndef BOOST_NO_CXX11_CONSTEXPR
+constexpr boost::array arr {{ 0,1,2,3,4,5,6,7,8,9 }};
+constexpr std::array arr_std {{ 0,1,2,3,4,5,6,7,8,9 }};
+
+template
+void sink ( T t ) {}
+
+template
+void sink ( boost::array &arr ) {}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+// constexpr int two = arr_std.at (2);
+ constexpr int three = arr.at (3);
+ int whatever [ arr.at(4) ];
+ (void)three;
+ (void) whatever;
+}
+
+#else // no constexpr means no constexpr tests!
+BOOST_AUTO_TEST_CASE( test_main )
+{
+}
+#endif
diff --git a/test/array_getfail1.cpp b/test/array_getfail1.cpp
new file mode 100644
index 0000000..21ae62f
--- /dev/null
+++ b/test/array_getfail1.cpp
@@ -0,0 +1,49 @@
+/* tests using std::get on boost:array
+ * (C) Copyright Marshall Clow 2012
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include
+#include
+
+
+#include
+#include
+#include
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+#include
+#endif
+
+#define BOOST_TEST_MAIN
+#include
+
+namespace {
+
+ #ifndef BOOST_NO_CXX11_HDR_ARRAY
+ template< class T >
+ void RunStdTests()
+ {
+ typedef boost::array< T, 5 > test_type;
+ typedef T arr[5];
+ test_type test_case; // = { 1, 1, 2, 3, 5 };
+
+ T &aRef = std::get<5> ( test_case ); // should fail to compile
+ BOOST_CHECK ( &*test_case.begin () == &aRef );
+ }
+ #endif
+
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+ RunStdTests< bool >();
+ RunStdTests< void * >();
+ RunStdTests< long double >();
+ RunStdTests< std::string >();
+#else
+ BOOST_STATIC_ASSERT ( false ); // fail on C++03 systems.
+#endif
+}
diff --git a/test/array_getfail2.cpp b/test/array_getfail2.cpp
new file mode 100644
index 0000000..e2277b0
--- /dev/null
+++ b/test/array_getfail2.cpp
@@ -0,0 +1,64 @@
+/* tests using std::get on boost:array
+ * (C) Copyright Marshall Clow 2012
+ * Distributed under the Boost Software License, Version 1.0. (See
+ * accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include
+#include
+#include
+#include
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+#include
+#endif
+
+#define BOOST_TEST_MAIN
+#include
+
+namespace {
+
+ #ifndef BOOST_NO_CXX11_HDR_ARRAY
+ template< class T >
+ void RunStdTests()
+ {
+ typedef boost::array< T, 5 > test_type;
+ typedef T arr[5];
+ test_type test_case; // = { 1, 1, 2, 3, 5 };
+
+ T &aRef = std::get<0> ( test_case );
+ BOOST_CHECK ( &*test_case.begin () == &aRef );
+
+ const T &caRef = std::get<0> ( test_case );
+ BOOST_CHECK ( &*test_case.cbegin () == &caRef );
+ }
+ #endif
+
+ template< class T >
+ void RunBoostTests()
+ {
+ typedef boost::array< T, 5 > test_type;
+ typedef T arr[5];
+ test_type test_case; // = { 1, 1, 2, 3, 5 };
+
+ T &aRef = boost::get<5> ( test_case );
+ BOOST_CHECK ( &*test_case.begin () == &aRef );
+ }
+
+}
+
+BOOST_AUTO_TEST_CASE( test_main )
+{
+ RunBoostTests< bool >();
+ RunBoostTests< void * >();
+ RunBoostTests< long double >();
+ RunBoostTests< std::string >();
+
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+ RunStdTests< bool >();
+ RunStdTests< void * >();
+ RunStdTests< long double >();
+ RunStdTests< std::string >();
+#endif
+}
+