text: /* +------------------------------------------------------------------------+
     |                     Mobile Robot Programming Toolkit (MRPT)            |
     |                          https://www.mrpt.org/                         |
     |                                                                        |
     | Copyright (c) 2005-2022, Individual contributors, see AUTHORS file     |
     | See: https://www.mrpt.org/Authors - All rights reserved.               |
     | Released under BSD License. See: https://www.mrpt.org/License          |
     +------------------------------------------------------------------------+ */
  #pragma once
  
  #include <mrpt/serialization/CSchemeArchiveBase.h>
  #include <mrpt/serialization/CSerializable.h>
  
  #include <memory>
  #include <optional>
  #include <sstream>
  #include <string>
  
  namespace mrpt::serialization
  {
  /** Base template class for schema-capable "archives", e.g. JSON, YAML,
   * from which to (de)serialize objects.
   *
   * See \ref mrpt_serialization_grp for examples of use.
   * \ingroup mrpt_serialization_grp
   * \note Original version by https://github.com/rachit173 for GSoC 2018.
   */
  template <typename SCHEME_CAPABLE>
  class CSchemeArchive : public mrpt::serialization::CSchemeArchiveBase_impl
  {
  	std::optional<SCHEME_CAPABLE> m_own_val;
  
     public:
  	/** Ctor that creates an own SCHEME_CAPABLE object. */
  	CSchemeArchive() : m_own_val{SCHEME_CAPABLE()}, m_val{m_own_val.value()} {}
  	/** Ctor that uses user-providen SCHEME_CAPABLE object. */
  	CSchemeArchive(SCHEME_CAPABLE& val) : m_val(val) {}
  	// Virtual assignment operators
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const int32_t val) override
  	{
  		m_val = val;
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const uint32_t val) override
  	{
  		m_val = val;
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const int64_t val) override
  	{
  		m_val = typename SCHEME_CAPABLE::Int64(val);
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const uint64_t val) override
  	{
  		m_val = typename SCHEME_CAPABLE::UInt64(val);
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(const float val) override
  	{
  		m_val = val;
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const double val) override
  	{
  		m_val = val;
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const std::string val) override
  	{
  		m_val = val;
  		return *m_parent;
  	}
  	mrpt::serialization::CSchemeArchiveBase& operator=(const bool val) override
  	{
  		m_val = val;
  		return *m_parent;
  	}
  
  	explicit operator int32_t() const override { return m_val.asInt(); }
  	explicit operator uint32_t() const override { return m_val.asUInt(); }
  	explicit operator int64_t() const override { return m_val.asInt64(); }
  	explicit operator uint64_t() const override { return m_val.asUInt64(); }
  	explicit operator float() const override { return m_val.asFloat(); }
  	explicit operator double() const override { return m_val.asDouble(); }
  	explicit operator bool() const override { return m_val.asBool(); }
  	explicit operator std::string() const override { return m_val.asString(); }
  	mrpt::serialization::CSchemeArchiveBase& operator=(
  		const mrpt::serialization::CSerializable& obj) override
  	{
  		ReadObject(*m_parent, obj);
  		return *m_parent;
  	}
  	void readTo(mrpt::serialization::CSerializable& obj) override
  	{
  		WriteObject(*m_parent, obj);
  		return;
  	}
  
  	mrpt::serialization::CSchemeArchiveBase operator[](size_t idx) override
  	{
  		return mrpt::serialization::CSchemeArchiveBase(
  			std::make_unique<CSchemeArchive<SCHEME_CAPABLE>>(m_val[(int)idx]));
  	}
  	mrpt::serialization::CSchemeArchiveBase operator[](std::string str) override
  	{
  		return mrpt::serialization::CSchemeArchiveBase(
  			std::make_unique<CSchemeArchive<SCHEME_CAPABLE>>(
  				m_val[std::string(str)]));
  	}
  
  	std::ostream& writeToStream(std::ostream& out) const override
  	{
  		out << m_val;
  		return out;
  	}
  	std::istream& readFromStream(std::istream& in) override
  	{
  		in >> m_val;
  		return in;
  	}
  
     private:
  	SCHEME_CAPABLE& m_val;
  };
  
  /** Returns an archive for reading/writing in JSON format.
   * This feature requires compiling MRPT with jsoncpp support.
   * See \ref mrpt_serialization_grp for examples of use.
   * \ingroup mrpt_serialization_grp */
  CSchemeArchiveBase archiveJSON();
  
  }  // namespace mrpt::serialization
  