forked from Alepha/Alepha
Add a NamedOperator
facility to Alepha.
This permits naming operators via an enhanced enum and then looking them up. This is a useful component for quick scripting language functionalities.
This commit is contained in:
@ -4,3 +4,4 @@ target_sources( alepha PRIVATE
|
|||||||
|
|
||||||
add_subdirectory( derived_pointer_cast.test )
|
add_subdirectory( derived_pointer_cast.test )
|
||||||
add_subdirectory( print_number.test )
|
add_subdirectory( print_number.test )
|
||||||
|
add_subdirectory( NamedOperator.test )
|
||||||
|
64
Utility/NamedOperator.h
Normal file
64
Utility/NamedOperator.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
static_assert( __cplusplus > 2023'00 );
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Alepha/Alepha.h>
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <Alepha/Enum.h>
|
||||||
|
|
||||||
|
namespace Alepha::Hydrogen::Utility ::detail:: NamedOperator_m
|
||||||
|
{
|
||||||
|
inline namespace exports
|
||||||
|
{
|
||||||
|
using OperatorName= Enum
|
||||||
|
<
|
||||||
|
"add"_value,
|
||||||
|
"sub"_value,
|
||||||
|
"mul"_value,
|
||||||
|
"mod"_value,
|
||||||
|
"idiv"_value
|
||||||
|
>;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
struct comparator
|
||||||
|
{
|
||||||
|
constexpr auto
|
||||||
|
operator () ( const OperatorName &lhs, const OperatorName &rhs ) const
|
||||||
|
{
|
||||||
|
return lhs.get_index() < rhs.get_index();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace exports
|
||||||
|
{
|
||||||
|
template< typename Type >
|
||||||
|
auto
|
||||||
|
getOperatorMap()
|
||||||
|
{
|
||||||
|
std::map< OperatorName, std::function< Type ( Type, Type ) >, comparator > rv
|
||||||
|
{
|
||||||
|
{ "add"_value, std::plus<>{} },
|
||||||
|
{ "sub"_value, std::minus<>{} },
|
||||||
|
{ "mul"_value, std::multiplies<>{} },
|
||||||
|
{ "mod"_value, std::modulus<>{} },
|
||||||
|
};
|
||||||
|
|
||||||
|
if constexpr( std::is_integral_v< Type > )
|
||||||
|
{
|
||||||
|
rv[ "idiv"_value ]= std::divides<>{};
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Alepha::Hydrogen::Utility::inline exports::inline NamedOperator_m
|
||||||
|
{
|
||||||
|
using namespace detail::NamedOperator_m::exports;
|
||||||
|
}
|
31
Utility/NamedOperator.test/0.cc
Normal file
31
Utility/NamedOperator.test/0.cc
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
static_assert( __cplusplus > 2023'00 );
|
||||||
|
|
||||||
|
#include "../NamedOperator.h"
|
||||||
|
|
||||||
|
#include <Alepha/Testing/test.h>
|
||||||
|
#include <Alepha/Testing/TableTest.h>
|
||||||
|
|
||||||
|
#include <Alepha/Utility/enroll.h>
|
||||||
|
|
||||||
|
static auto init= Alepha::Utility::enroll <=[]
|
||||||
|
{
|
||||||
|
using namespace Alepha::Testing::exports;
|
||||||
|
using namespace Alepha::Utility::NamedOperator_m;
|
||||||
|
using namespace Alepha::literals::enum_literals;
|
||||||
|
|
||||||
|
"Does the named operator system have the expected basic functionality?"_test <= TableTest
|
||||||
|
<
|
||||||
|
[]( const int lhs, const OperatorName name, const int rhs )
|
||||||
|
{
|
||||||
|
return getOperatorMap< int >().at( name )( lhs, rhs );
|
||||||
|
}
|
||||||
|
>
|
||||||
|
::Cases
|
||||||
|
{
|
||||||
|
{ "addition", { 1, "add"_value, 1 }, 2 },
|
||||||
|
{ "subtraction", { 1, "sub"_value, 1 }, 0 },
|
||||||
|
{ "multiplication", { 5, "mul"_value, 5 }, 25 },
|
||||||
|
{ "modulus", { 9, "mod"_value, 5 }, 4 },
|
||||||
|
{ "division", { 5, "idiv"_value, 3 }, 1 },
|
||||||
|
};
|
||||||
|
};
|
1
Utility/NamedOperator.test/CMakeLists.txt
Normal file
1
Utility/NamedOperator.test/CMakeLists.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
unit_test( 0 )
|
Reference in New Issue
Block a user