Program Listing for File OpLookup.hpp¶
↰ Return to documentation for file (include/sgpl/library/OpLookup.hpp)
#pragma once
#ifndef SGPL_LIBRARY_OPLOOKUP_HPP_INCLUDE
#define SGPL_LIBRARY_OPLOOKUP_HPP_INCLUDE
#include <cassert>
#include <unordered_map>
#include "../../../third-party/conduit/include/uitsl/meta/tuple_has_type.hpp"
#include "../../../third-party/conduit/include/uitsl/meta/tuple_index.hpp"
#include "../../../third-party/conduit/include/uit_emp/base/macros.hpp"
#include "../debug/sgpl_assert.hpp"
#include "../debug/sgpl_error.hpp"
#include "../operations/actions/Nop.hpp"
#include "../utility/ByteEnumeration.hpp"
#include "../utility/count_operation_random_touches.hpp"
namespace sgpl {
#include "../../../third-party/conduit/include/uit_emp/vendorization/push_macros.hh"
template<typename Library>
class OpLookup {
std::unordered_map<std::string, unsigned char> table;
using library_parent_t = typename Library::parent_t;
public:
OpLookup() {
#define SGPL_OP_LOOKUP_PAYLOAD(N) \
if constexpr (N < Library::GetSize()) { \
using Operation = typename Library::template Operation<N>; \
table[ Operation::name() ] = N; \
} \
static_assert( Library::GetSize() < 256 );
EMP_WRAP_EACH( SGPL_OP_LOOKUP_PAYLOAD, SGPL_BYTE_ENUMERATION )
sgpl_assert(
table.size() == Library::GetSize(),
table.size() << Library::GetSize()
);
}
unsigned char GetOpCode(const std::string op_name) const {
return table.at(op_name);
}
static std::string GetOpName(const size_t op_code) {
// can't use assert due to obsucre macro error
#define SGPL_OP_NAME_PAYLOAD(N) \
case N: \
if constexpr (N < Library::GetSize()) { \
using Operation = typename Library::template Operation<N>; \
return Operation::name(); \
} else { \
assert( false && N ); \
__builtin_unreachable(); \
} \
break;
static_assert( Library::GetSize() < 256 );
switch( op_code ) {
EMP_WRAP_EACH( SGPL_OP_NAME_PAYLOAD, SGPL_BYTE_ENUMERATION )
default:
sgpl_assert( false, op_code );
__builtin_unreachable();
}
sgpl_error(op_code);
__builtin_unreachable();
}
template< typename Spec >
static size_t GetOpNumRngTouches(const size_t op_code) {
#define SGPL_OP_NUM_RNG_TOUCHES_PAYLOAD(N) \
case N: \
if constexpr (N < Library::GetSize()) { \
using Operation = typename Library::template Operation<N>; \
return sgpl::count_operation_random_touches< Operation, Spec >(); \
} else { \
assert( false && N ); \
__builtin_unreachable(); \
} \
break;
static_assert( Library::GetSize() < 256 );
switch( op_code ) {
EMP_WRAP_EACH( SGPL_OP_NUM_RNG_TOUCHES_PAYLOAD, SGPL_BYTE_ENUMERATION )
default:
sgpl_error(op_code);
__builtin_unreachable();
}
sgpl_error(op_code);
__builtin_unreachable();
}
static size_t GetNopOpCode( const size_t num_rng_touches ) {
#define SGPL_NOP_OP_CODE_PAYLOAD(N) \
case N: \
if constexpr ( \
uitsl::tuple_has_type< sgpl::Nop<N>, library_parent_t >::value \
) return uitsl::tuple_index< sgpl::Nop<N>, library_parent_t >::value; \
else if constexpr ( \
uitsl::tuple_has_type< sgpl::Nop<N, 0>, library_parent_t >::value \
) return uitsl::tuple_index<sgpl::Nop<N, 0>, library_parent_t>::value; \
else { \
assert( false && N ); \
__builtin_unreachable(); \
} \
break;
assert( num_rng_touches < 256 );
switch( num_rng_touches ) {
EMP_WRAP_EACH( SGPL_NOP_OP_CODE_PAYLOAD, SGPL_BYTE_ENUMERATION )
default:
sgpl_error(num_rng_touches);
__builtin_unreachable();
}
sgpl_error(num_rng_touches);
__builtin_unreachable();
}
static size_t GetOpPrevalence(const size_t op_code) {
#define SGPL_OP_PREVALENCE_PAYLOAD(N) \
case N: \
if constexpr (N < Library::GetSize()) { \
using Operation = typename Library::template Operation<N>; \
return Operation::prevalence(); \
} else { \
assert( false && N ); \
__builtin_unreachable(); \
} \
break;
static_assert( Library::GetSize() < 256 );
switch( op_code ) {
EMP_WRAP_EACH( SGPL_OP_PREVALENCE_PAYLOAD, SGPL_BYTE_ENUMERATION )
default:
sgpl_error(op_code);
__builtin_unreachable();
}
sgpl_error(op_code);
__builtin_unreachable();
}
template< typename Instruction >
static auto GetOpDescriptors(
const size_t op_code, const Instruction& instruction
) {
#define SGPL_OP_GET_DESCRIPTORS(N) \
case N: \
if constexpr (N < Library::GetSize()) { \
using Operation = typename Library::template Operation<N>; \
return Operation::descriptors( instruction ); \
} else { \
assert( false && N ); \
__builtin_unreachable(); \
} \
break;
static_assert( Library::GetSize() < 256 );
switch( op_code ) {
EMP_WRAP_EACH(
SGPL_OP_GET_DESCRIPTORS, SGPL_BYTE_ENUMERATION
)
default:
sgpl_error(op_code);
__builtin_unreachable();
}
sgpl_error(op_code);
__builtin_unreachable();
}
template< typename Instruction >
static auto GetOpCategories(
const size_t op_code, const Instruction& instruction
) {
// can't use sgpl_assert due to obsucre macro error
#define SGPL_OP_GET_CATEGORIES(N) \
case N: \
if constexpr (N < Library::GetSize()) { \
using Operation = typename Library::template Operation<N>; \
return Operation::categories( instruction ); \
} else { \
assert( false && N ); \
__builtin_unreachable(); \
} \
break;
static_assert( Library::GetSize() < 256 );
switch( op_code ) {
EMP_WRAP_EACH(
SGPL_OP_GET_CATEGORIES, SGPL_BYTE_ENUMERATION
)
default:
sgpl_error(op_code);
__builtin_unreachable();
}
sgpl_error(op_code);
__builtin_unreachable();
}
};
#include "../../../third-party/conduit/include/uit_emp/vendorization/pop_macros.hh"
} // namespace sgpl
#endif // #ifndef SGPL_LIBRARY_OPLOOKUP_HPP_INCLUDE