Skip to content

Commit

Permalink
refactor(tools::type): refactor 2/N
Browse files Browse the repository at this point in the history
  • Loading branch information
berdal84 committed Oct 13, 2024
1 parent 70d7ea8 commit 8555781
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 102 deletions.
2 changes: 1 addition & 1 deletion src/ndbl/core/Graph.specs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ TEST_F(Graph_, clear)
EXPECT_TRUE( graph->get_edge_registry().empty() );

VariableNode* variable = graph->create_variable(type::get<int>(), "var", nullptr);
FunctionDescriptor* fct_type = FunctionDescriptor::create_new<int(int, int)>("+");
FunctionDescriptor* fct_type = FunctionDescriptor::create<int(int, int)>("+");
const IInvokable* invokable = app.get_language()->find_operator_fct_exact(fct_type);

EXPECT_TRUE(invokable != nullptr);
Expand Down
6 changes: 3 additions & 3 deletions src/ndbl/core/language/Nodlang.basics.specs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ TEST_F(Language_basics, can_get_add_operator_with_short_identifier )

TEST_F(Language_basics, can_get_add_operator_with_signature )
{
const FunctionDescriptor descriptor = FunctionDescriptor::create<double(double, double)>("+");
const FunctionDescriptor descriptor = FunctionDescriptor::construct<double(double, double)>("+");
EXPECT_TRUE(language->find_operator_fct(&descriptor));
}

TEST_F(Language_basics, can_get_invert_operator_with_signature )
{
const FunctionDescriptor descriptor = FunctionDescriptor::create<double(double)>("-");
const FunctionDescriptor descriptor = FunctionDescriptor::construct<double(double)>("-");
EXPECT_TRUE(language->find_operator_fct(&descriptor));
}

TEST_F(Language_basics, by_ref_assign )
{
const FunctionDescriptor descriptor = FunctionDescriptor::create<double(double&, double)>("=");
const FunctionDescriptor descriptor = FunctionDescriptor::construct<double(double &, double)>("=");

EXPECT_TRUE(descriptor.get_args()[0].m_by_reference);

Expand Down
6 changes: 3 additions & 3 deletions src/ndbl/core/language/Nodlang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ Slot *Nodlang::parse_binary_operator_expression(u8_t _precedence, Slot& _left)
}

// Create a function signature according to ltype, rtype and operator word
FunctionDescriptor* type = FunctionDescriptor::create_new<any_t()>(ope->identifier.c_str());
FunctionDescriptor* type = FunctionDescriptor::create<any_t()>(ope->identifier.c_str());
type->push_arg( _left.get_property()->get_type());
type->push_arg(right->get_property()->get_type());

Expand Down Expand Up @@ -409,7 +409,7 @@ Slot *Nodlang::parse_unary_operator_expression(u8_t _precedence)
}

// Create a function signature
FunctionDescriptor* type = FunctionDescriptor::create_new<any_t()>(operator_token.word_to_string().c_str());
FunctionDescriptor* type = FunctionDescriptor::create<any_t()>(operator_token.word_to_string().c_str());
type->push_arg( out_atomic->get_property()->get_type());

FunctionNode* node = parser_state.graph->create_operator(std::move(type));
Expand Down Expand Up @@ -1006,7 +1006,7 @@ Slot* Nodlang::parse_function_call()
std::vector<Slot*> result_slots;

// Declare a new function prototype
FunctionDescriptor* signature = FunctionDescriptor::create_new<any_t()>(fct_id.c_str());
FunctionDescriptor* signature = FunctionDescriptor::create<any_t()>(fct_id.c_str());

bool parsingError = false;
while (!parsingError && parser_state.ribbon.can_eat() &&
Expand Down
2 changes: 1 addition & 1 deletion src/ndbl/gui/NodableView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ using namespace tools;
template<typename T>
static FunctionDescriptor* create_variable_node_signature()
{
static FunctionDescriptor descriptor = FunctionDescriptor::create<T(T)>("variable");
static FunctionDescriptor descriptor = FunctionDescriptor::construct<T(T)>("variable");
return &descriptor;
}

Expand Down
4 changes: 2 additions & 2 deletions src/tools/core/memory/Pool.bench.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ static void mutate_N_instances__enterlaced_with_another_type__using_Pool_create(

for( auto i = 0; i < COUNT; i++ )
{
ids.emplace_back(pool->create_new<DataPool<128>>() );
ids2.emplace_back(pool->create_new<DataPool<64>>() );
ids.emplace_back(pool->create<DataPool<128>>() );
ids2.emplace_back(pool->create<DataPool<64>>() );
}

if( VECTOR )
Expand Down
5 changes: 3 additions & 2 deletions src/tools/core/reflection/Initializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace tools

explicit Initializer(const char *_name)
{
TypeDescriptor *type = type::create<T>(_name);
TypeDescriptor *type = TypeDescriptor::create<T>(_name);
m_type = TypeRegister::insert_or_merge(type);
}
};
Expand All @@ -41,7 +41,7 @@ namespace tools

explicit Initializer(const char *_name)
{
TypeDescriptor *type = type::create<T>(_name);
TypeDescriptor *type = ClassDescriptor::create<T>(_name);
m_class = (ClassDescriptor *) TypeRegister::insert_or_merge(type);
}

Expand All @@ -68,6 +68,7 @@ namespace tools
template<typename BaseClassT>
Initializer &extends()
{
static_assert(std::is_class_v<BaseClassT>);
static_assert(std::is_base_of_v<BaseClassT, T>);

auto base_class = const_cast<ClassDescriptor *>( type::get_class<BaseClassT>()); // get or create
Expand Down
4 changes: 2 additions & 2 deletions src/tools/core/reflection/Invokable.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ namespace tools

InvokableStaticFunction(const char* _name, const FunctionT* _function_pointer)
: m_function_pointer( _function_pointer )
, m_function_signature(FunctionDescriptor::create_new<FunctionT>(_name) )
, m_function_signature(FunctionDescriptor::create<FunctionT>(_name) )
{ ASSERT( m_function_pointer ) }

variant invoke(const std::vector<variant *> &_args) const override
Expand Down Expand Up @@ -217,7 +217,7 @@ namespace tools
public:
InvokableMethod(const char* _name, MethodT _method_pointer )
: m_method_pointer( _method_pointer )
, m_method_signature(FunctionDescriptor::create_new<MethodT>(_name) )
, m_method_signature(FunctionDescriptor::create<MethodT>(_name) )
{ ASSERT( m_method_pointer ) }

variant invoke( void* _instance, const std::vector<variant*>& _args ) const override
Expand Down
140 changes: 67 additions & 73 deletions src/tools/core/reflection/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ namespace tools
const TypeDescriptor* any();
const TypeDescriptor* null();

template<typename T> std::type_index id();
template<typename T> std::type_index primitive_id();
template<typename T> const char* compiler_name();
template<typename T> TypeFlags flags();
template<typename T> std::type_index get_id();
template<typename T> std::type_index get_primitive_id();
template<typename T> const char* get_compiler_name();
template<typename T> TypeFlags get_flags();
template<typename T> const TypeDescriptor* get();
template<typename T> const ClassDescriptor* get_class(T* ptr);
template<typename T> const ClassDescriptor* get_class();
Expand Down Expand Up @@ -118,18 +118,6 @@ namespace tools
// };
};

template<typename T>
std::type_index type::id()
{ return std::type_index(typeid(T)); }

template<typename T>
std::type_index type::primitive_id()
{ return id<typename remove_pointer<T>::type>(); }

template<typename T>
const char* type::compiler_name()
{ return typeid(T).name(); }

/**
* @class TypeDesc (type descriptor) holds meta data relative to a given type.
*
Expand Down Expand Up @@ -189,8 +177,8 @@ namespace tools
{
public:

template<typename T> static FunctionDescriptor* create_new(const char* _name);
template<typename T> static FunctionDescriptor create(const char* _name);
template<typename T> static FunctionDescriptor* create(const char* _name);
template<typename T> static FunctionDescriptor construct(const char* _name);

FunctionDescriptor(std::type_index _id, std::type_index _primitive_id): TypeDescriptor(_id, _primitive_id) {}

Expand All @@ -207,7 +195,7 @@ namespace tools
std::vector<FuncArg>& get_args() { return m_args;};
const std::vector<FuncArg>& get_args()const { return m_args;};
size_t get_arg_count() const { return m_args.size(); }
const TypeDescriptor* get_return_type() const { return m_return_type; }
const TypeDescriptor* get_return_type() const { return m_return_type; }
void set_return_type(const TypeDescriptor* _type) { m_return_type = _type; };
private:
template<typename T> static void init(FunctionDescriptor*, const char* _name);
Expand All @@ -216,32 +204,6 @@ namespace tools
const TypeDescriptor* m_return_type = type::null();
};

template<int N, typename ArgsAsTuple>
void FunctionDescriptor::push_nth_arg()
{
using NTH_ARG = std::tuple_element_t<N, ArgsAsTuple>;
const TypeDescriptor* type_descriptor = type::get<NTH_ARG>();
push_arg(type_descriptor, std::is_reference_v<NTH_ARG>);
}

template<typename ...Args>
void FunctionDescriptor::push_args()
{
constexpr size_t ARG_COUNT = std::tuple_size_v<Args...>;
static_assert(ARG_COUNT <= 8, "maximum 8 arguments can be pushed at once");

// note: I duplicate instead of using template recursion hell. :)

if constexpr (ARG_COUNT > 0 ) push_nth_arg<0, Args...>();
if constexpr (ARG_COUNT > 1 ) push_nth_arg<1, Args...>();
if constexpr (ARG_COUNT > 2 ) push_nth_arg<2, Args...>();
if constexpr (ARG_COUNT > 3 ) push_nth_arg<3, Args...>();
if constexpr (ARG_COUNT > 4 ) push_nth_arg<4, Args...>();
if constexpr (ARG_COUNT > 5 ) push_nth_arg<5, Args...>();
if constexpr (ARG_COUNT > 6 ) push_nth_arg<6, Args...>();
if constexpr (ARG_COUNT > 7 ) push_nth_arg<7, Args...>();
}

/**
* @class ClassDesc (class descriptor) holds meta data relative to a given class.
*
Expand Down Expand Up @@ -285,30 +247,72 @@ namespace tools
std::unordered_map<std::string, const IInvokableMethod*> m_methods_by_name;
};

template<typename T>
std::type_index type::get_id()
{ return std::type_index(typeid(T)); }

template<typename T>
std::type_index type::get_primitive_id()
{ return type::get_id<typename remove_pointer<T>::type>(); }

template<typename T>
const char* type::get_compiler_name()
{ return typeid(T).name(); }

template<int N, typename ArgsAsTuple>
void FunctionDescriptor::push_nth_arg()
{
using NTH_ARG = std::tuple_element_t<N, ArgsAsTuple>;
const TypeDescriptor* type_descriptor = type::get<NTH_ARG>();
push_arg(type_descriptor, std::is_reference_v<NTH_ARG>);
}

template<typename ...Args>
void FunctionDescriptor::push_args()
{
constexpr size_t ARG_COUNT = std::tuple_size_v<Args...>;
static_assert(ARG_COUNT <= 8, "maximum 8 arguments can be pushed at once");

// note: I duplicate instead of using template recursion hell. :)

if constexpr (ARG_COUNT > 0 ) push_nth_arg<0, Args...>();
if constexpr (ARG_COUNT > 1 ) push_nth_arg<1, Args...>();
if constexpr (ARG_COUNT > 2 ) push_nth_arg<2, Args...>();
if constexpr (ARG_COUNT > 3 ) push_nth_arg<3, Args...>();
if constexpr (ARG_COUNT > 4 ) push_nth_arg<4, Args...>();
if constexpr (ARG_COUNT > 5 ) push_nth_arg<5, Args...>();
if constexpr (ARG_COUNT > 6 ) push_nth_arg<6, Args...>();
if constexpr (ARG_COUNT > 7 ) push_nth_arg<7, Args...>();
}

template<typename T>
bool TypeDescriptor::is() const
{ return type::equals(this, type::get<T>()); }

template<typename T>
TypeDescriptor* TypeDescriptor::create(const char* _name)
{
TypeDescriptor* descriptor = new TypeDescriptor(type::id<T>(), type::primitive_id<T>() );
static_assert( std::is_class_v<T> == false );

TypeDescriptor* descriptor = new TypeDescriptor(type::get_id<T>(), type::get_primitive_id<T>() );

descriptor->m_name = _name;
descriptor->m_compiler_name = type::compiler_name<T>();
descriptor->m_flags = type::flags<T>();
descriptor->m_compiler_name = type::get_compiler_name<T>();
descriptor->m_flags = type::get_flags<T>();

return descriptor;
}

template<typename T>
ClassDescriptor* ClassDescriptor::create(const char* _name)
{
ClassDescriptor* descriptor = new ClassDescriptor(type::id<T>(), type::primitive_id<T>() );
static_assert( std::is_class_v<T> );

ClassDescriptor* descriptor = new ClassDescriptor(type::get_id<T>(), type::get_primitive_id<T>() );

descriptor->m_name = _name;
descriptor->m_compiler_name = type::compiler_name<T>();
descriptor->m_flags = type::flags<T>();
descriptor->m_compiler_name = type::get_compiler_name<T>();
descriptor->m_flags = type::get_flags<T>();

return descriptor;
}
Expand All @@ -317,8 +321,8 @@ namespace tools
void FunctionDescriptor::init(FunctionDescriptor* _descriptor, const char* _name)
{
_descriptor->m_name = _name;
_descriptor->m_compiler_name = type::compiler_name<T>();
_descriptor->m_flags = type::flags<T>();
_descriptor->m_compiler_name = type::get_compiler_name<T>();
_descriptor->m_flags = type::get_flags<T>();
_descriptor->m_return_type = type::get<typename FunctionTrait<T>::result_t >();

using Args = typename FunctionTrait<T>::args_t;
Expand All @@ -327,17 +331,17 @@ namespace tools
}

template<typename T>
FunctionDescriptor FunctionDescriptor::create(const char* _name)
FunctionDescriptor FunctionDescriptor::construct(const char* _name)
{
FunctionDescriptor descriptor(type::id<T>(), type::primitive_id<T>());
FunctionDescriptor descriptor(type::get_id<T>(), type::get_primitive_id<T>());
FunctionDescriptor::init<T>(&descriptor, _name);
return descriptor;
}

template<typename T>
FunctionDescriptor* FunctionDescriptor::create_new(const char* _name)
FunctionDescriptor* FunctionDescriptor::create(const char* _name)
{
FunctionDescriptor* descriptor = new FunctionDescriptor(type::id<T>(), type::primitive_id<T>());
FunctionDescriptor* descriptor = new FunctionDescriptor(type::get_id<T>(), type::get_primitive_id<T>());
FunctionDescriptor::init<T>(descriptor, _name);
return descriptor;
}
Expand All @@ -359,21 +363,21 @@ namespace tools
template<typename T>
const TypeDescriptor* type::get()
{
auto id = type::id<T>();
auto id = type::get_id<T>();

if ( TypeRegister::has(id) )
{
return TypeRegister::get(id);
}

TypeDescriptor* descriptor = create<T>();
TypeDescriptor* descriptor = type::create<T>();
TypeRegister::insert(descriptor);

return descriptor;
}

template<typename T>
TypeFlags type::flags()
TypeFlags type::get_flags()
{
return (TypeFlag_IS_POINTER * std::is_pointer_v<T>)
| (TypeFlag_IS_CONST * std::is_const_v<T>)
Expand All @@ -385,10 +389,11 @@ namespace tools
TypeDescriptor* type::create(const char* _name)
{
if constexpr ( std::is_member_function_pointer_v<T> || std::is_function_v<T>)
return FunctionDescriptor::create_new<T>(_name);
return FunctionDescriptor::create<T>(_name);
if constexpr ( std::is_class_v<T> )
return ClassDescriptor::create<T>(_name);
return TypeDescriptor::create<T>(_name);
else
return TypeDescriptor::create<T>(_name);
}

/**
Expand Down Expand Up @@ -428,15 +433,4 @@ namespace tools
{
return source_ptr;
}

template<class Type>
constexpr bool has_get_type = std::is_member_pointer<decltype(&Type::get_type)>::value;

template<class DerivedT, class BaseT>
struct is_base_of
{
static_assert( tools::has_get_type<BaseT>, "BaseT must have polymorphic reflection");
static_assert( tools::has_get_type<DerivedT>, "DerivedT must have polymorphic reflection");
static constexpr bool value = std::is_same_v<DerivedT, BaseT> || std::is_base_of_v<DerivedT, BaseT>;
};
}
Loading

0 comments on commit 8555781

Please sign in to comment.