Skip to content

Commit

Permalink
Add ring (default) constructor for use with a C-array type as the con…
Browse files Browse the repository at this point in the history
…tainer (#33, thanks @Crzyrndm)

Move definition of class ring into namespace `nsrs` and make it available in namespace `nonstd`.
  • Loading branch information
martinmoene committed May 20, 2024
1 parent aa9de65 commit 4754447
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 7 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
```

Expand Down
88 changes: 81 additions & 7 deletions include/nonstd/ring.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,70 @@

#include <nonstd/ring_span.hpp>

#if nsrs_CPP11_OR_GREATER
# include <array>
#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<bool, B>{};

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<T[]> : std11::true_type {};

template< class T, std::size_t N >
struct is_array<T[N]> : 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<T, Extent> > : 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<T>*/
Expand All @@ -28,12 +90,12 @@ class ring
public:
#if nsrs_RING_SPAN_LITE_EXTENSION
typedef ring_span<
typename Container::value_type
, default_popper<typename Container::value_type>
typename vt<Container>::value_type
, default_popper<typename vt<Container>::value_type>
, CapacityIsPowerOf2
> RingSpan;
#else
typedef ring_span< typename Container::value_type > RingSpan;
typedef ring_span< typename vt<Container>::value_type > RingSpan;
#endif

typedef typename RingSpan::value_type value_type;
Expand All @@ -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<Container, size_t>::value )
nsrs_REQUIRES_0((
is_array<Container>::value
|| is_std_array<Container>::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<Container>::value
&& !is_std_array<Container>::value
))
explicit ring( size_type capacity )
: cont( capacity )
, rs( cont.begin(), cont.end() )
Expand Down Expand Up @@ -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
13 changes: 13 additions & 0 deletions test/ring-span.t.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, 3 >> 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
Expand Down

0 comments on commit 4754447

Please sign in to comment.