diff --git a/README.md b/README.md index 6c29b47..b9cfbb5 100644 --- a/README.md +++ b/README.md @@ -496,6 +496,7 @@ copy_popper: A copy popper replaces the original element ring: Allows to create data owning ring from container ring: Allows to create data owning ring from container - capacity is power of 2 ring: Allows to create data owning ring from std::array (C++11) +ring: Allows to create data owning ring from C-array tweak header: reads tweak header if supported [tweak] ``` diff --git a/include/nonstd/ring.hpp b/include/nonstd/ring.hpp index 81b79a9..4a32e8c 100644 --- a/include/nonstd/ring.hpp +++ b/include/nonstd/ring.hpp @@ -14,8 +14,70 @@ #include +#if nsrs_CPP11_OR_GREATER +# include +#endif + namespace nonstd { +namespace nsrs { + +namespace std11 { + +template< class T, T v > struct integral_constant { enum { value = v }; }; +template< bool B > struct bool_constant : integral_constant{}; + +typedef bool_constant< true > true_type; +typedef bool_constant< false > false_type; + +template< class C > +typename C::iterator begin( C & c ) { return c.begin(); } + +template< class C > +typename C::iterator end( C & c ) { return c.end(); } + +template< typename T, std::size_t N > +T * begin( T (&array)[N] ) { return &array[0]; } + +template< typename T, std::size_t N > +T * end( T (&array)[N] ) { return &array[N]; } + +} // namespace std11 +template< class Q > +struct is_array : std11::false_type {}; + +template< class T > +struct is_array : std11::true_type {}; + +template< class T, std::size_t N > +struct is_array : std11::true_type {}; + +template< class Q > +struct is_std_array_oracle : std11::false_type{}; + +//#if nsrs_HAVE( ARRAY ) +#if nsrs_CPP11_OR_GREATER + +template< class T, std::size_t Extent > +struct is_std_array_oracle< std::array > : std11::true_type{}; + +#endif + +template< class Q > +struct is_std_array : is_std_array_oracle< Q >{}; + +template< typename Container > +struct vt +{ + typedef typename Container::value_type value_type; +}; + +template< typename T, std::size_t N > +struct vt< T[N] > +{ + typedef T value_type; +}; + template < typename Container /*= std::vector*/ @@ -28,12 +90,12 @@ class ring public: #if nsrs_RING_SPAN_LITE_EXTENSION typedef ring_span< - typename Container::value_type - , default_popper + typename vt::value_type + , default_popper::value_type> , CapacityIsPowerOf2 > RingSpan; #else - typedef ring_span< typename Container::value_type > RingSpan; + typedef ring_span< typename vt::value_type > RingSpan; #endif typedef typename RingSpan::value_type value_type; @@ -48,14 +110,20 @@ class ring typedef typename RingSpan::const_reverse_iterator const_reverse_iterator; #endif -#if nsrs_CPP11_OR_GREATER - nsrs_REQUIRES_0( !std::is_constructible::value ) + nsrs_REQUIRES_0(( + is_array::value + || is_std_array::value + )) explicit ring() : cont{} - , rs( std::begin(cont), std::end(cont) ) + , rs( std11::begin(cont), std11::end(cont) ) {} -#endif + // non C-Array, non std::array + nsrs_REQUIRES_0(( + !is_array::value + && !is_std_array::value + )) explicit ring( size_type capacity ) : cont( capacity ) , rs( cont.begin(), cont.end() ) @@ -282,6 +350,12 @@ class ring RingSpan rs; }; +} // namespace nsrs + +// Make types available in namespace nonstd: + +using nsrs::ring; + } // namespace nonstd #endif // NONSTD_RING_LITE_HPP diff --git a/test/ring-span.t.cpp b/test/ring-span.t.cpp index fd04a48..da99e7b 100644 --- a/test/ring-span.t.cpp +++ b/test/ring-span.t.cpp @@ -1268,11 +1268,24 @@ CASE( "ring: Allows to create data owning ring from std::array (C++11)" ) { #if nsrs_CPP11_OR_GREATER ring< std::array> r; + + EXPECT( r.capacity() == 3 ); + EXPECT( r.size() == 0 ); #else EXPECT( !!"std::array is not available (no C++11)" ); #endif } +// issue-33: C-array + +CASE( "ring: Allows to create data owning ring from C-array" ) +{ + ring< int[3] > r; + + EXPECT( r.capacity() == 3 ); + EXPECT( r.size() == 0 ); +} + CASE( "tweak header: reads tweak header if supported " "[tweak]" ) { #if nsrs_HAVE_TWEAK_HEADER