text: #pragma once
  
  #include "options.h"
  
  #include "options_types.h"
  
  #include "vw_exception.h"
  
  #include <sstream>
  
  namespace VW
  {
  namespace config
  {
  struct options_serializer_boost_po : options_serializer_i
  {
    options_serializer_boost_po() { m_output_stream.precision(15); }
  
    virtual void add(base_option& option) override;
    virtual std::string str() override;
    virtual const char* data() override;
    virtual size_t size() override;
  
   private:
    template <typename T>
    bool serialize_if_t(base_option& base_option)
    {
      if (base_option.m_type_hash == typeid(T).hash_code())
      {
        auto typed = dynamic_cast<typed_option<T>&>(base_option);
        serialize(typed);
        return true;
      }
  
      return false;
    }
  
    template <typename T>
    void serialize(typed_option<T> typed_option)
    {
      m_output_stream << " --" << typed_option.m_name << " " << typed_option.value();
    }
  
    template <typename T>
    void serialize(typed_option<std::vector<T>> typed_option)
    {
      auto vec = typed_option.value();
      if (vec.size() > 0)
      {
        for (auto const& value : vec)
        {
          m_output_stream << " --" << typed_option.m_name;
          m_output_stream << " " << value;
        }
      }
    }
  
    template <typename TTypes>
    void add_impl(base_option& options)
    {
      if (serialize_if_t<typename TTypes::head>(options))
      {
        return;
      }
      add_impl<typename TTypes::tail>(options);
    }
  
    std::stringstream m_output_stream;
  };
  
  template <>
  void options_serializer_boost_po::serialize<bool>(typed_option<bool> typed_argument);
  
  template <>
  void options_serializer_boost_po::add_impl<typelist<>>(base_option& options);
  }  // namespace config
  }  // namespace VW
  