Skip to content

Commit

Permalink
* Helper structure any_ref for holding a generic reference
Browse files Browse the repository at this point in the history
  * Added a recursive modifier function to vref which allows the
  modification of an underlying object/value where it is important
  to retain the original type and therefore using a tree is not viable.
  • Loading branch information
parnham committed Oct 4, 2022
1 parent 63d8a6c commit 76aecbb
Show file tree
Hide file tree
Showing 9 changed files with 404 additions and 83 deletions.
42 changes: 42 additions & 0 deletions include/entity/any.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#pragma once
#include <typeinfo>
#include <stdexcept>


namespace ent
{
// Helper structure to hold a generic reference to an object/value along
// with the type_info so that a function can selectively modify
// that value based on the typeid. Potentially very dangerous!
// * Dangling references - unsafe to use beyond the lifetime of the object it is referencing
// * Type safety - casting to the wrong type would be bad, the cast() function is provided to
// check the type and throw an exception if there is a mismatch.
struct any_ref
{
void *value = nullptr;
const std::type_info *type = nullptr;


template <typename T> any_ref(T &value)
: value(&value), type(&typeid(value)) {}


template <typename T> bool is()
{
return type && *type == typeid(T);
}


template <typename T> T &cast()
{
if (this->is<T>())
{
return *static_cast<T*>(value);
}

throw std::runtime_error(
std::string("bad conversion of any_ref from ") + type->name() + " to " + typeid(T).name()
);
}
};
}
26 changes: 18 additions & 8 deletions include/entity/entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,24 @@ namespace ent
// If two arguments are passed then the supplied name is used as the mapping key
#ifndef ent_ref
#define ent_get_ref(_1, _2, name, ...) name
// #define ent_man_ref(name, item) std::make_pair(name, std::make_shared<ent::vref<typename std::remove_reference<decltype(item)>::type>>(item))
#define ent_man_ref(name, item) std::make_pair(name, std::make_unique<ent::vref<typename std::remove_reference<decltype(item)>::type>>(item))
#define ent_auto_ref(item) ent_man_ref(#item, item)
#define ent_ref(...) ent_get_ref(__VA_ARGS__, ent_man_ref, ent_auto_ref)(__VA_ARGS__)
#define ent_map(...) ent::mapping ent_describe() { return { __VA_ARGS__ }; } //\
// const ent::mapping ent_describe() const { return __VA_ARGS__ };
#define ent_merge(base, ...) ent::mapping ent_describe() { auto a = base::ent_describe(); a.insert({ __VA_ARGS__ }); return a; } //\
// const ent::mapping ent_describe() const { auto a = base::ent_describe(); a.insert({ __VA_ARGS__ }); return a; }
#define ent_man_ref(name, item) std::make_pair(name, std::make_unique<ent::vref<typename std::remove_reference<decltype(item)>::type>>(item))
#define ent_auto_ref(item) ent_man_ref(#item, item)
#define ent_ref(...) ent_get_ref(__VA_ARGS__, ent_man_ref, ent_auto_ref)(__VA_ARGS__)
#define ent_map(...) ent::mapping ent_describe() { return { __VA_ARGS__ }; }
#define ent_merge(base, ...) ent::mapping ent_describe() { auto a = base::ent_describe(); a.insert({ __VA_ARGS__ }); return a; }

// #if __cplusplus >= 202002L
// #define ent_parens () // Note space before (), so object-like macro
// #define ent_expand(arg) ent_expand1(ent_expand1(ent_expand1(ent_expand1(arg))))
// #define ent_expand1(arg) ent_expand2(ent_expand2(ent_expand2(ent_expand2(arg))))
// #define ent_expand2(arg) ent_expand3(ent_expand3(ent_expand3(ent_expand3(arg))))
// #define ent_expand3(arg) arg

// #define ent_for_each(macro, ...) __VA_OPT__(ent_expand(ent_helper(macro, __VA_ARGS__)))
// #define ent_helper(macro, a1, ...) macro(a1) __VA_OPT__(ent_again ent_parens (macro, __VA_ARGS__))
// #define ent_again() ent_helper
// #define ent_map_terse(...) ent::mapping ent_describe() { return { ent_for_each(ent_auto_ref, __VA_ARGS__) }; }
// #endif

// Concise call to ent_ref and ent_map, disable if they conflict
#define eref ent_ref
Expand Down
Loading

0 comments on commit 76aecbb

Please sign in to comment.