Skip to content

Commit

Permalink
change from_string to take pointer, return void
Browse files Browse the repository at this point in the history
  • Loading branch information
mgates3 committed May 24, 2024
1 parent ad53c37 commit dd94272
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 23 deletions.
50 changes: 50 additions & 0 deletions test/test_sort.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,46 @@

#include "test.hh"

// -----------------------------------------------------------------------------
/// An enum class without to_string, from_string.
enum class EnumOld
{
a, b, c
};

// -----------------------------------------------------------------------------
/// An enum class with wrong to_string, from_string.
enum class EnumOld2
{
a, b, c
};

const char* to_string( EnumOld2 value )
{
return "value";
}

void from_string( std::string const& str, EnumOld2 value )
{
}

// -----------------------------------------------------------------------------
/// An enum class with to_string, from_string.
enum class EnumNew
{
x, y, z
};

std::string to_string( EnumNew value )
{
return "value";
}

void from_string( std::string const& str, EnumNew* value )
{
*value = EnumNew::x;
}

// -----------------------------------------------------------------------------
// traits class maps data type to real_t and scalar_t.

Expand Down Expand Up @@ -114,6 +154,16 @@ void test_sort_work( Params &params, bool run )
if (! run)
return;

//----------
// Test has_to_string, has_from_string

static_assert( ! testsweeper::has_to_string<EnumOld>::value );
static_assert( ! testsweeper::has_from_string<EnumOld>::value );
static_assert( ! testsweeper::has_to_string<EnumOld2>::value );
static_assert( ! testsweeper::has_from_string<EnumOld2>::value );
static_assert( testsweeper::has_to_string<EnumNew>::value );
static_assert( testsweeper::has_from_string<EnumNew>::value );

// ----------
// setup
int64_t imax = 100000;
Expand Down
49 changes: 26 additions & 23 deletions testsweeper.hh
Original file line number Diff line number Diff line change
Expand Up @@ -92,34 +92,33 @@ extern const char* DataType_help;
/// @param[in] dummy
/// Dummy argument used to specify the return type for overloading.
///
inline DataType from_string( std::string const& str, DataType dummy )
inline void from_string( std::string const& str, DataType* val )
{
std::string str_ = str;
if (str_ == "i"
|| str_ == "int"
|| str_ == "integer" ) return DataType::Integer;
|| str_ == "integer" ) *val = DataType::Integer;
else if (str_ == "h"
|| str_ == "r16"
|| str_ == "half" ) return DataType::Half;
|| str_ == "half" ) *val = DataType::Half;
else if (str_ == "s"
|| str_ == "r32"
|| str_ == "float"
|| str_ == "single" ) return DataType::Single;
|| str_ == "single" ) *val = DataType::Single;
else if (str_ == "d"
|| str_ == "r64"
|| str_ == "double" ) return DataType::Double;
|| str_ == "double" ) *val = DataType::Double;
else if (str_ == "c"
|| str_ == "c32"
|| str_ == "complex<float>"
|| str_ == "complex-float"
|| str_ == "complex-single") return DataType::SingleComplex;
|| str_ == "complex-single") *val = DataType::SingleComplex;
else if (str_ == "z"
|| str_ == "c64"
|| str_ == "complex<double>"
|| str_ == "complex-double") return DataType::DoubleComplex;
|| str_ == "complex-double") *val = DataType::DoubleComplex;
else
throw_error( "invalid datatype '%s'", str.c_str() );
return DataType::Integer;
}

//--------------------
Expand All @@ -137,7 +136,9 @@ inline DataType char2datatype( char ch )
[[deprecated("Use from_string. To be removed 2025-05.")]]
inline DataType str2datatype( const char* str )
{
return from_string( str, DataType() );
DataType val;
from_string( str, &val );
return val;
}

//----------------------------------------
Expand Down Expand Up @@ -192,20 +193,22 @@ template <typename T>
class has_from_string
{
private:
/// Matches from_string( string str, T* val ); return type is void.
typedef T* T_ptr;

/// Matches `from_string( string str, T* val )`; return type is void.
template <typename T2>
static auto test( std::string str, T2 val )
-> decltype( from_string( str, T2() ) );
static auto test( std::string str, T2* val )
-> decltype( from_string( str, val ) );

/// Matches everything else; return type is void (something other than T).
/// Matches everything else; return type is int (something other than void).
template <typename T2>
static void test(...);
static int test(...);

public:
// True if from_string( string, type ) exists, based on void return type.
static const bool value = std::is_same<
T,
decltype( test<T>( std::string(), T() ) )
// True if `void from_string( string, T* )` exists.
static constexpr bool value = std::is_same<
void,
decltype( test<T>( std::string(), T_ptr() ) )
>::value;
};

Expand All @@ -217,18 +220,18 @@ template <typename T>
class has_to_string
{
private:
/// Matches to_string( T val ); return type is string.
/// Matches `to_string( T val )`; return type is string.
template <typename T2>
static auto test( T2 val )
-> decltype( to_string( val ) );

/// Matches everything else; return type is int (something other than string).
template <typename>
template <typename T2>
static int test(...);

public:
// True if from_string( string, type ) exists, based on string return type.
static const bool value = std::is_same<
// True if `std::string to_string( T val )` exists.
static constexpr bool value = std::is_same<
std::string,
decltype( test<T>( T() ) )
>::value;
Expand Down Expand Up @@ -813,7 +816,7 @@ void ParamEnum<ENUM>::parse( const char *str )
// Parse word into enum. str2enum_ & char2enum_ throw errors.
ENUM val;
if constexpr (has_from_string<ENUM>::value) {
val = from_string( buf, ENUM() );
from_string( buf, &val );
}
else if (str2enum_) {
val = str2enum_( buf );
Expand Down

0 comments on commit dd94272

Please sign in to comment.