Skip to content
Snippets Groups Projects
Commit a1b39424 authored by Jonathan Hanks's avatar Jonathan Hanks
Browse files

Adding the fixed_string class to the EPICS sequencer.

* Not pervasive yet, but used in all the table structures and many functions.
* Extended the fixed_string class with functions as needed.
parent 63654d22
No related branches found
No related tags found
2 merge requests!439RCG 5.0 release fro deb 10,!343convert the sequencer to C++
......@@ -29,6 +29,41 @@ namespace embedded
public:
typedef std::size_t size_type;
class buffer
{
friend class fixed_string;
explicit buffer( char* buf ) : buf_{ buf }
{
}
public:
buffer( buffer&& other ) noexcept = default;
~buffer( )
{
if ( buf_ )
{
buf_[ fixed_string< max_size >::last_index( ) ] = '\0';
}
}
buffer( const buffer& other ) = delete;
buffer& operator=( const buffer& other ) = delete;
buffer& operator=( buffer&& other ) noexcept = default;
char*
data( ) noexcept
{
return buf_;
}
constexpr size_type
capacity( ) const noexcept
{
return max_size;
}
private:
char* buf_;
};
fixed_string( ) noexcept : data_( )
{
data_[ 0 ] = '\0';
......@@ -46,6 +81,16 @@ namespace embedded
copy_in_data( in );
}
fixed_string& operator=( const fixed_string& other ) noexcept = default;
template < std::size_t other_max_size >
fixed_string&
operator=( const fixed_string< other_max_size >& other ) noexcept
{
operator=( other.c_str( ) );
return *this;
}
fixed_string&
operator=( const char* in ) noexcept
{
......@@ -80,6 +125,11 @@ namespace embedded
return *this;
}
explicit operator const char*( ) const noexcept
{
return c_str( );
}
void
clear( ) noexcept
{
......@@ -113,6 +163,13 @@ namespace embedded
return !operator==( str );
}
template < std::size_t other_max_size >
bool
operator!=( const fixed_string< other_max_size >& other ) const noexcept
{
return !operator==( other );
}
bool
operator==( const fixed_string& other ) const noexcept
{
......@@ -126,6 +183,13 @@ namespace embedded
return std::strcmp( c_str( ), ( str ? str : dummy ) ) == 0;
}
template < std::size_t other_max_size >
bool
operator==( const fixed_string< other_max_size >& other ) const noexcept
{
return std::strcmp( c_str( ), other.c_str( ) ) == 0;
}
size_type
remaining( ) const noexcept
{
......@@ -156,6 +220,23 @@ namespace embedded
return data_;
}
void
pop_back_n( size_type n ) noexcept
{
if ( n > 0 )
{
auto length = size( );
auto remove = std::min( length, n );
data_[ length - remove ] = '\0';
}
}
buffer
get_buffer( ) noexcept
{
return buffer( data_ );
}
private:
void
copy_in_data( const char* in ) noexcept
......
This diff is collapsed.
......@@ -160,6 +160,22 @@ TEST_CASE( "You can create a fixed_size_string" )
}
}
TEST_CASE( "Copy operators work even when the sizes are different, it just may "
"truncate" )
{
embedded::fixed_string< 64 > s0( "123456" );
embedded::fixed_string< 32 > s1;
embedded::fixed_string< 6 > s2;
embedded::fixed_string< 64 > s3( "123456" );
s1 = s0;
REQUIRE( s1 == "123456" );
s2 = s0;
REQUIRE( s2 == "12345" );
s3 = s2;
REQUIRE( s3 == "12345" );
}
TEST_CASE( "You can append to a fixed size string" )
{
embedded::fixed_string< 64 > s;
......@@ -250,6 +266,15 @@ TEST_CASE( "You can do printf style formatted printing" )
0 );
}
TEST_CASE( "You can assign and append via char arrays" )
{
embedded::fixed_string< 64 > s0( "123456" );
char blob[ 1 ][ 8 ] = { "abc" };
s0 += blob[ 0 ];
REQUIRE( s0 == "123456abc" );
}
TEST_CASE( "clear will reset the fixed_string to be empty" )
{
embedded::fixed_string< 64 > s0( "123456" );
......@@ -276,6 +301,16 @@ TEST_CASE(
REQUIRE( s0 != s1 );
}
TEST_CASE( "You can compare with a fixed_string using operator== and "
"operator!= even when capacities are different" )
{
embedded::fixed_string< 64 > s0( "1234" ), s1( "123456789" );
embedded::fixed_string< 6 > s2( "1234" );
REQUIRE( s0 == s2 );
REQUIRE( s1 != s2 );
}
TEST_CASE( "You can compare with a char* using operator== and operator!=" )
{
embedded::fixed_string< 64 > s0( "123456" );
......@@ -294,4 +329,32 @@ TEST_CASE( "It is safe to compare with a null char*, it matches an empty "
REQUIRE( s0 != nullptr );
REQUIRE( s1 == "" );
REQUIRE( s1 == nullptr );
}
TEST_CASE( "You can remove characters from the end" )
{
embedded::fixed_string< 64 > s0( "1234567890" );
REQUIRE( s0.size( ) == 10 );
s0.pop_back_n( 4 );
REQUIRE( s0.size( ) == 6 );
REQUIRE( s0 == "123456" );
s0.pop_back_n( 1 );
REQUIRE( s0.size( ) == 5 );
s0.pop_back_n( 10 );
REQUIRE( s0.size( ) == 0 );
}
TEST_CASE( "For direct manipulation you can get a buffer which cleans up when "
"it is done" )
{
embedded::fixed_string< 10 > s0( "abc" );
{
auto buf = s0.get_buffer( );
std::fill( buf.data( ), buf.data( ) + buf.capacity( ), 1 );
REQUIRE( buf.data( )[ buf.capacity( ) - 1 ] == 1 );
REQUIRE( s0.data( )[ s0.capacity( ) - 1 ] == 1 );
}
REQUIRE( s0.data( )[ s0.capacity( ) - 1 ] == '\0' );
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment