diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/rustic.hpp | 10 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 66 |
2 files changed, 44 insertions, 32 deletions
diff --git a/src/include/rustic.hpp b/src/include/rustic.hpp index f986a91d..84e98b31 100644 --- a/src/include/rustic.hpp +++ b/src/include/rustic.hpp @@ -69,6 +69,11 @@ public: return m_data; } + void if_set(::std::function<void (const T&)> f) const { + if( m_set ) { + return f(m_data); + } + } //template<typename U/*, class FcnSome, class FcnNone*/> //U match(::std::function<U(const T&)> if_some, ::Std::function<U()> if_none) const { // if( m_set ) { @@ -97,6 +102,11 @@ public: assert(is_some()); return *m_ptr; } + void if_set(::std::function<void (const T&)> f) const { + if( m_ptr ) { + return f(*m_ptr); + } + } //template<typename U/*, class FcnSome, class FcnNone*/> //U match(::std::function<U(const T&)> if_some, ::Std::function<U()> if_none) const { diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 5ff3bf48..15eb3148 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -13,25 +13,6 @@ #define TU_CASE(mod, class, var, name,src, ...) TU_CASE_BODY(mod,class,var, TU_CASE_ITEM(src,mod,var,name) __VA_ARGS__) #define TU_CASE2(mod, class, var, n1,s1, n2,s2, ...) TU_CASE_BODY(mod,class,var, TU_CASE_ITEM(s1,mod,var,n1) TU_CASE_ITEM(s2,mod,var,n2) __VA_ARGS__) - -#define TU_DATANAME(name) Data_##name -// Internals of TU_CONS -#define TU_CONS_I(__tag, __type) \ - static self_t make_null_##__tag() { self_t ret; ret.m_tag = __tag; new (ret.m_data) __type; return ::std::move(ret); } \ - static self_t make_##__tag(__type v) \ - {\ - self_t ret;\ - ret.m_tag = __tag;\ - new (ret.m_data) __type( ::std::move(v) ); \ - return ::std::move(ret); \ - }\ - bool is_##__tag() const { return m_tag == __tag; } \ - const __type& as_##__tag() const { return reinterpret_cast<const __type&>(m_data); } \ - __type& as_##__tag() { return reinterpret_cast<__type&>(m_data); } \ - __type unwrap_##__tag() { return ::std::move(reinterpret_cast<__type&>(m_data)); } \ -// Define a tagged union constructor -#define TU_CONS(name, _) TU_CONS_I(name, TU_DATANAME(name)) - #define TU_FIRST(a, ...) a // Argument iteration @@ -113,6 +94,25 @@ */} break; #define TU_MATCH_ARMS(CLASS, VAR, NAME, ...) TU_GMA(__VA_ARGS__)(TU_MATCH_ARM, (CLASS, VAR, NAME), __VA_ARGS__) +#define TU_IFLET(CLASS, VAR, TAG, NAME, ...) if(VAR.tag() == CLASS::TAG) { auto& NAME = VAR.as_##TAG(); (void)&NAME; __VA_ARGS__ } + + +#define TU_DATANAME(name) Data_##name +// Internals of TU_CONS +#define TU_CONS_I(__name, __tag, __type) \ + __name(__type v): m_tag(__tag) { new (m_data) __type( ::std::move(v) ); } \ + static self_t make_null_##__tag() { self_t ret; ret.m_tag = __tag; new (ret.m_data) __type; return ::std::move(ret); } \ + static self_t make_##__tag(__type v) \ + {\ + return __name( ::std::move(v) );\ + }\ + bool is_##__tag() const { return m_tag == __tag; } \ + const __type& as_##__tag() const { return reinterpret_cast<const __type&>(m_data); } \ + __type& as_##__tag() { return reinterpret_cast<__type&>(m_data); } \ + __type unwrap_##__tag() { return ::std::move(reinterpret_cast<__type&>(m_data)); } \ +// Define a tagged union constructor +#define TU_CONS(__name, name, _) TU_CONS_I(__name, name, TU_DATANAME(name)) + // Type definitions #define TU_EXP(...) __VA_ARGS__ #define TU_TYPEDEF(name, content) struct TU_DATANAME(name) { TU_EXP content; };/* @@ -136,7 +136,7 @@ */ #define MAXS(...) TU_GM(MAXS,__VA_ARGS__)(__VA_ARGS__) -#define TU_CONSS(...) TU_GMX(__VA_ARGS__)(TU_CONS , __VA_ARGS__) +#define TU_CONSS(_name, ...) TU_GMA(__VA_ARGS__)(TU_CONS, (_name), __VA_ARGS__) #define TU_TYPEDEFS(...) TU_GMX(__VA_ARGS__)(TU_TYPEDEF ,__VA_ARGS__) #define TU_TAGS(...) TU_GMX(__VA_ARGS__)(TU_TAG ,__VA_ARGS__) #define TU_DEST_CASES(...) TU_GMX(__VA_ARGS__)(TU_DEST_CASE,__VA_ARGS__) @@ -157,37 +157,39 @@ * ); * ``` */ -#define TAGGED_UNION(_name, _def, ...) \ -class _name { \ +#define TAGGED_UNION(_name, _def, ...) TAGGED_UNION_EX(_name, (), _def, (__VA_ARGS__), ()) +#define TAGGED_UNION_EX(_name, _inherit, _def, _variants, _extra) \ +class _name TU_EXP _inherit { \ typedef _name self_t;/* -*/ TU_TYPEDEFS(__VA_ARGS__)/* +*/ TU_TYPEDEFS _variants/* */public:\ enum Tag { \ - TU_TAGS(__VA_ARGS__)\ + TU_TAGS _variants\ };/* */ private:\ Tag m_tag; \ - char m_data[MAXS(__VA_ARGS__)];/* + char m_data[MAXS _variants];/* */ public:\ - _name(): m_tag(_def) {}\ + _name(): m_tag(_def) { new((void*)m_data) TU_DATANAME(_def); }\ _name(const _name&) = delete; \ - _name(_name&& x) noexcept: m_tag(x.m_tag) { x.m_tag = _def; switch(m_tag) { TU_MOVE_CASES(__VA_ARGS__) } } \ - _name& operator =(_name&& x) { this->~_name(); m_tag = x.m_tag; x.m_tag = _def; switch(m_tag) { TU_MOVE_CASES(__VA_ARGS__) }; return *this; } \ - ~_name() { switch(m_tag) { TU_DEST_CASES(__VA_ARGS__) } } \ + _name(_name&& x) noexcept: m_tag(x.m_tag) { switch(m_tag) { TU_MOVE_CASES _variants } } \ + _name& operator =(_name&& x) { this->~_name(); m_tag = x.m_tag; x.m_tag = _def; switch(m_tag) { TU_MOVE_CASES _variants }; return *this; } \ + ~_name() { switch(m_tag) { TU_DEST_CASES _variants } } \ \ Tag tag() const { return m_tag; }\ - TU_CONSS(__VA_ARGS__) \ + TU_CONSS(_name, TU_EXP _variants) \ /* */ static const char *tag_to_str(Tag tag) { \ switch(tag) {/* -*/ TU_TOSTR_CASES(__VA_ARGS__)/* +*/ TU_TOSTR_CASES _variants/* */ } return ""; \ }/* */ static Tag tag_from_str(const ::std::string& str) { \ if(0); /* -*/ TU_FROMSTR_CASES(__VA_ARGS__)/* +*/ TU_FROMSTR_CASES _variants/* */ else throw ::std::runtime_error("enum "#_name" No conversion"); \ }\ + TU_EXP _extra\ } /* |