diff options
author | John Hodge <tpg@mutabah.net> | 2015-09-05 12:14:50 +0800 |
---|---|---|
committer | John Hodge <tpg@mutabah.net> | 2015-09-05 12:14:50 +0800 |
commit | 0b6d7c51056ed7b8eb25af6041c4feb5e6e23051 (patch) | |
tree | 33b4f6587a43fb5dae9907db6e94c19880300a73 /src/include | |
parent | db10e8219fefb01415b3a79e973844401d97c1ee (diff) | |
download | mrust-0b6d7c51056ed7b8eb25af6041c4feb5e6e23051.tar.gz |
Resolve - Work resolving UFCS traits
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/rustic.hpp | 28 | ||||
-rw-r--r-- | src/include/tagged_union.hpp | 8 |
2 files changed, 17 insertions, 19 deletions
diff --git a/src/include/rustic.hpp b/src/include/rustic.hpp index 84e98b31..15588565 100644 --- a/src/include/rustic.hpp +++ b/src/include/rustic.hpp @@ -50,23 +50,29 @@ namespace rust { template<typename T> class option { + char m_data[ sizeof(T) ]; bool m_set; - T m_data; public: option(T ent): - m_set(true), - m_data( ::std::move(ent) ) - {} + m_set(true) + { + new (m_data) T(::std::move(ent)); + } option(): m_set(false) {} + ~option() { + if( m_set ) { + reinterpret_cast<T*>(m_data)->~T(); + } + } bool is_none() const { return !m_set; } bool is_some() const { return m_set; } const T& unwrap() const { assert(is_some()); - return m_data; + return *reinterpret_cast<const T*>(m_data); } void if_set(::std::function<void (const T&)> f) const { @@ -107,16 +113,6 @@ public: 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 { - // if( m_set ) { - // return if_some(*m_ptr); - // } - // else { - // return if_none(); - // } - //} }; template<typename T> option<T> Some(T data) { @@ -127,4 +123,6 @@ option<T> None() { return option<T>( ); } +#define IF_OPTION_SOME(bind, var, ...) { auto __v = (var); if( var.is_some() ) { auto bind = __v.unwrap(); (void)&bind; __VA_ARGS__ } } + }; diff --git a/src/include/tagged_union.hpp b/src/include/tagged_union.hpp index 15eb3148..34657ff5 100644 --- a/src/include/tagged_union.hpp +++ b/src/include/tagged_union.hpp @@ -107,9 +107,9 @@ 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)); } \ + const __type& as_##__tag() const { assert(m_tag == __tag); return reinterpret_cast<const __type&>(m_data); } \ + __type& as_##__tag() { assert(m_tag == __tag); return reinterpret_cast<__type&>(m_data); } \ + __type unwrap_##__tag() { assert(m_tag == __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)) @@ -173,7 +173,7 @@ class _name TU_EXP _inherit { \ _name(): m_tag(_def) { new((void*)m_data) TU_DATANAME(_def); }\ _name(const _name&) = delete; \ _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& operator =(_name&& x) { this->~_name(); m_tag = x.m_tag; switch(m_tag) { TU_MOVE_CASES _variants }; return *this; } \ ~_name() { switch(m_tag) { TU_DEST_CASES _variants } } \ \ Tag tag() const { return m_tag; }\ |