#include <type_traits> #include <utility> #include <cassert> #include <memory> #include <iostream> struct none_t {}; const auto none = none_t (); template <typename T> struct optional { public: optional ( none_t ) : present(false) { } optional ( ) : present(false) { } template <typename ...Tn> optional ( Tn&&... argn ) : present(false) { place(std::forward<Tn>( argn )...); } optional ( const T& t ) : present(false) { place(t);
value_t(): val(none_t()) {}
inline std::string generate_string(const tree_t& tree, size_t initial_size=128) { std::string ret(initial_size, ' '); generator_t gen(&tree); writer_t writer; writer.set_buffer(&(ret[0]), ret.size()); error_e err = error_ok; do { switch (gen.last()) { case event_object_begin: err = writer.write_begin(scope_object); break; case event_object_end: err = writer.write_end(); break; case event_object_key: err = writer.write_key(gen.key()); break; case event_array_begin: err = writer.write_begin(scope_array); break; case event_array_end: err = writer.write_end(); break; case event_number: err = writer.write_value(gen.number()); break; case event_string: err = writer.write_value(gen.string()); break; case event_predicate: err = writer.write_value(gen.predicate()); break; case event_null: err = writer.write_value(none_t()); break; case event_begin: case event_end: break; default: ONT_SHOULD_NOT_BE_REACHED(); return ""; } switch (err) { case error_ok: gen.next(); break; case error_need_buffer: { size_t written = writer.buffer().head() - &(ret[0]); ret.resize(ret.size()*2); writer.set_buffer(&(ret[written]), ret.size() - written); } break; default: assert(false); return ""; } } while (!gen.done()); ret.resize(writer.buffer().head() - &(ret[0])); return ret; }
static void fail(lslboost::optional<Exposed>& val) { val = none_t(); // leave optional uninitialized if rhs failed }