json/include/nlohmann/detail/output/output_adapters.hpp

138 lines
3.5 KiB
C++
Raw Normal View History

2018-01-10 17:18:31 +08:00
#pragma once
2017-08-14 23:41:23 +08:00
#include <algorithm> // copy
#include <cstddef> // size_t
#include <iterator> // back_inserter
#include <memory> // shared_ptr, make_shared
#include <string> // basic_string
#include <vector> // vector
#ifndef JSON_NO_IO
#include <ios> // streamsize
#include <ostream> // basic_ostream
#endif // JSON_NO_IO
2019-07-01 04:14:02 +08:00
#include <nlohmann/detail/macro_scope.hpp>
2017-08-14 23:41:23 +08:00
namespace nlohmann
{
namespace detail
{
/// abstract output adapter interface
template<typename CharType> struct output_adapter_protocol
{
virtual void write_character(CharType c) = 0;
virtual void write_characters(const CharType* s, std::size_t length) = 0;
virtual ~output_adapter_protocol() = default;
:rotating_light: add new CI and fix warnings (#2561) * :alembic: move CI targets to CMake * :recycle: add target for cpplint * :recycle: add target for self-contained binaries * :recycle: add targets for iwyu and infer * :loud_sound: add version output * :recycle: add target for oclint * :rotating_light: fix warnings * :recycle: rename targets * :recycle: use iwyu properly * :rotating_light: fix warnings * :recycle: use iwyu properly * :recycle: add target for benchmarks * :recycle: add target for CMake flags * :construction_worker: use GitHub Actions * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: try to install Clang 11 * :alembic: try to install GCC 11 * :alembic: add clang analyze target * :fire: remove Google Benchmark * :arrow_up: Google Benchmark 1.5.2 * :fire: use fetchcontent * :penguin: add target to download a Linux version of CMake * :hammer: fix dependency * :rotating_light: fix includes * :rotating_light: fix comment * :wrench: adjust flags for GCC 11.0.0 20210110 (experimental) * :whale: user Docker image to run CI * :wrench: add target for Valgrind * :construction_worker: add target for Valgrind tests * :alembic: add Dart * :rewind: remove Dart * :alembic: do not call ctest in test subdirectory * :alembic: download test data explicitly * :alembic: only execute Valgrind tests * :alembic: fix labels * :fire: remove unneeded jobs * :hammer: cleanup * :bug: fix OCLint call * :white_check_mark: add targets for offline and git-independent tests * :white_check_mark: add targets for C++ language versions and reproducible tests * :hammer: clean up * :construction_worker: add CI steps for cppcheck and cpplint * :rotating_light: fix warnings from Clang-Tidy * :construction_worker: add CI steps for Clang-Tidy * :rotating_light: fix warnings * :wrench: select proper binary * :rotating_light: fix warnings * :rotating_light: suppress some unhelpful warnings * :rotating_light: fix warnings * :art: fix format * :rotating_light: fix warnings * :construction_worker: add CI steps for Sanitizers * :rotating_light: fix warnings * :zap: add optimization to sanitizer build * :rotating_light: fix warnings * :rotating_light: add missing header * :rotating_light: fix warnings * :construction_worker: add CI step for coverage * :construction_worker: add CI steps for disabled exceptions and implicit conversions * :rotating_light: fix warnings * :construction_worker: add CI steps for checking indentation * :bug: fix variable use * :green_heart: fix build * :heavy_minus_sign: remove CircleCI * :construction_worker: add CI step for diagnostics * :rotating_light: fix warning * :fire: clean Travis
2021-03-24 14:15:18 +08:00
output_adapter_protocol() = default;
output_adapter_protocol(const output_adapter_protocol&) = default;
output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
2017-08-14 23:41:23 +08:00
};
/// a type to simplify interfaces
template<typename CharType>
using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
/// output adapter for byte vectors
template<typename CharType>
class output_vector_adapter : public output_adapter_protocol<CharType>
{
public:
2018-10-28 00:31:03 +08:00
explicit output_vector_adapter(std::vector<CharType>& vec) noexcept
: v(vec)
{}
2017-08-14 23:41:23 +08:00
void write_character(CharType c) override
{
v.push_back(c);
}
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_NON_NULL(2)
2017-08-14 23:41:23 +08:00
void write_characters(const CharType* s, std::size_t length) override
{
std::copy(s, s + length, std::back_inserter(v));
}
private:
std::vector<CharType>& v;
};
#ifndef JSON_NO_IO
2017-08-14 23:41:23 +08:00
/// output adapter for output streams
template<typename CharType>
class output_stream_adapter : public output_adapter_protocol<CharType>
{
public:
2018-10-28 00:31:03 +08:00
explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
: stream(s)
{}
2017-08-14 23:41:23 +08:00
void write_character(CharType c) override
{
stream.put(c);
}
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_NON_NULL(2)
2017-08-14 23:41:23 +08:00
void write_characters(const CharType* s, std::size_t length) override
{
stream.write(s, static_cast<std::streamsize>(length));
}
private:
std::basic_ostream<CharType>& stream;
};
#endif // JSON_NO_IO
2017-08-14 23:41:23 +08:00
/// output adapter for basic_string
template<typename CharType, typename StringType = std::basic_string<CharType>>
2017-08-14 23:41:23 +08:00
class output_string_adapter : public output_adapter_protocol<CharType>
{
public:
2018-10-28 00:31:03 +08:00
explicit output_string_adapter(StringType& s) noexcept
: str(s)
{}
2017-08-14 23:41:23 +08:00
void write_character(CharType c) override
{
str.push_back(c);
}
2019-07-02 04:37:30 +08:00
JSON_HEDLEY_NON_NULL(2)
2017-08-14 23:41:23 +08:00
void write_characters(const CharType* s, std::size_t length) override
{
str.append(s, length);
}
private:
StringType& str;
2017-08-14 23:41:23 +08:00
};
template<typename CharType, typename StringType = std::basic_string<CharType>>
2017-08-14 23:41:23 +08:00
class output_adapter
{
public:
output_adapter(std::vector<CharType>& vec)
: oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
#ifndef JSON_NO_IO
2017-08-14 23:41:23 +08:00
output_adapter(std::basic_ostream<CharType>& s)
: oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
#endif // JSON_NO_IO
2017-08-14 23:41:23 +08:00
output_adapter(StringType& s)
: oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
2017-08-14 23:41:23 +08:00
operator output_adapter_t<CharType>()
{
return oa;
}
private:
output_adapter_t<CharType> oa = nullptr;
};
} // namespace detail
} // namespace nlohmann