/* */ #pragma once template class slice { T* m_first; unsigned int m_len; public: slice(): m_first(nullptr), m_len(0) {} slice(const ::std::vector& v): m_first(&v[0]), m_len(v.size()) {} slice(::std::vector& v): m_first(&v[0]), m_len(v.size()) {} slice(T* ptr, unsigned int len): m_first(ptr), m_len(len) {} ::std::vector to_vec() const { return ::std::vector(begin(), end()); } unsigned int size() const { return m_len; } T& operator[](unsigned int i) const { assert(i < m_len); return m_first[i]; } slice subslice(unsigned int ofs, unsigned int len) const { assert(ofs < m_len); assert(len <= m_len); assert(ofs + len <= m_len); return slice { m_first + ofs, len }; } T* begin() const { return m_first; } T* end() const { return m_first + m_len; } T& front() const { return m_first[0]; } T& back() const { return m_first[m_len-1]; } }; template ::std::ostream& operator<<(::std::ostream& os, slice s) { if( s.size() > 0 ) { bool is_first = true; for( const auto& i : s ) { if(!is_first) os << ", "; is_first = false; os << i; } } return os; } namespace rust { template class option { char m_data[ sizeof(T) ]; bool m_set; void* data_ptr() { return m_data; } const void* data_ptr() const { return m_data; } public: option(T ent): m_set(true) { new (m_data) T(::std::move(ent)); } option(): m_set(false) {} ~option() { if( m_set ) { reinterpret_cast(data_ptr())->~T(); } } bool is_none() const { return !m_set; } bool is_some() const { return m_set; } const T& unwrap() const { assert(is_some()); return *reinterpret_cast(m_data); } void if_set(::std::function f) const { if( m_set ) { return f(m_data); } } //template //U match(::std::function if_some, ::Std::function if_none) const { // if( m_set ) { // return if_some(m_data); // } // else { // return if_none(); // } //} }; template class option { T* m_ptr; public: option(T& ent): m_ptr(&ent) {} option(): m_ptr(nullptr) {} bool is_none() const { return m_ptr == nullptr; } bool is_some() const { return m_ptr != nullptr; } T& unwrap() const { assert(is_some()); return *m_ptr; } void if_set(::std::function f) const { if( m_ptr ) { return f(*m_ptr); } } }; template option Some(T data) { return option( ::std::move(data) ); } template option None() { return option( ); } #define IF_OPTION_SOME(bind, var, ...) { auto __v = (var); if( var.is_some() ) { auto bind = __v.unwrap(); (void)&bind; __VA_ARGS__ } } };