output_adapters.hpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // __ _____ _____ _____
  2. // __| | __| | | | JSON for Modern C++
  3. // | | |__ | | | | | | version 3.11.3
  4. // |_____|_____|_____|_|___| https://github.com/nlohmann/json
  5. //
  6. // SPDX-FileCopyrightText: 2013-2023 Niels Lohmann <https://nlohmann.me>
  7. // SPDX-License-Identifier: MIT
  8. #pragma once
  9. #include <algorithm> // copy
  10. #include <cstddef> // size_t
  11. #include <iterator> // back_inserter
  12. #include <memory> // shared_ptr, make_shared
  13. #include <string> // basic_string
  14. #include <vector> // vector
  15. #ifndef JSON_NO_IO
  16. #include <ios> // streamsize
  17. #include <ostream> // basic_ostream
  18. #endif // JSON_NO_IO
  19. #include <nlohmann/detail/macro_scope.hpp>
  20. NLOHMANN_JSON_NAMESPACE_BEGIN
  21. namespace detail
  22. {
  23. /// abstract output adapter interface
  24. template<typename CharType> struct output_adapter_protocol
  25. {
  26. virtual void write_character(CharType c) = 0;
  27. virtual void write_characters(const CharType* s, std::size_t length) = 0;
  28. virtual ~output_adapter_protocol() = default;
  29. output_adapter_protocol() = default;
  30. output_adapter_protocol(const output_adapter_protocol&) = default;
  31. output_adapter_protocol(output_adapter_protocol&&) noexcept = default;
  32. output_adapter_protocol& operator=(const output_adapter_protocol&) = default;
  33. output_adapter_protocol& operator=(output_adapter_protocol&&) noexcept = default;
  34. };
  35. /// a type to simplify interfaces
  36. template<typename CharType>
  37. using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
  38. /// output adapter for byte vectors
  39. template<typename CharType, typename AllocatorType = std::allocator<CharType>>
  40. class output_vector_adapter : public output_adapter_protocol<CharType>
  41. {
  42. public:
  43. explicit output_vector_adapter(std::vector<CharType, AllocatorType>& vec) noexcept
  44. : v(vec)
  45. {}
  46. void write_character(CharType c) override
  47. {
  48. v.push_back(c);
  49. }
  50. JSON_HEDLEY_NON_NULL(2)
  51. void write_characters(const CharType* s, std::size_t length) override
  52. {
  53. v.insert(v.end(), s, s + length);
  54. }
  55. private:
  56. std::vector<CharType, AllocatorType>& v;
  57. };
  58. #ifndef JSON_NO_IO
  59. /// output adapter for output streams
  60. template<typename CharType>
  61. class output_stream_adapter : public output_adapter_protocol<CharType>
  62. {
  63. public:
  64. explicit output_stream_adapter(std::basic_ostream<CharType>& s) noexcept
  65. : stream(s)
  66. {}
  67. void write_character(CharType c) override
  68. {
  69. stream.put(c);
  70. }
  71. JSON_HEDLEY_NON_NULL(2)
  72. void write_characters(const CharType* s, std::size_t length) override
  73. {
  74. stream.write(s, static_cast<std::streamsize>(length));
  75. }
  76. private:
  77. std::basic_ostream<CharType>& stream;
  78. };
  79. #endif // JSON_NO_IO
  80. /// output adapter for basic_string
  81. template<typename CharType, typename StringType = std::basic_string<CharType>>
  82. class output_string_adapter : public output_adapter_protocol<CharType>
  83. {
  84. public:
  85. explicit output_string_adapter(StringType& s) noexcept
  86. : str(s)
  87. {}
  88. void write_character(CharType c) override
  89. {
  90. str.push_back(c);
  91. }
  92. JSON_HEDLEY_NON_NULL(2)
  93. void write_characters(const CharType* s, std::size_t length) override
  94. {
  95. str.append(s, length);
  96. }
  97. private:
  98. StringType& str;
  99. };
  100. template<typename CharType, typename StringType = std::basic_string<CharType>>
  101. class output_adapter
  102. {
  103. public:
  104. template<typename AllocatorType = std::allocator<CharType>>
  105. output_adapter(std::vector<CharType, AllocatorType>& vec)
  106. : oa(std::make_shared<output_vector_adapter<CharType, AllocatorType>>(vec)) {}
  107. #ifndef JSON_NO_IO
  108. output_adapter(std::basic_ostream<CharType>& s)
  109. : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
  110. #endif // JSON_NO_IO
  111. output_adapter(StringType& s)
  112. : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
  113. operator output_adapter_t<CharType>()
  114. {
  115. return oa;
  116. }
  117. private:
  118. output_adapter_t<CharType> oa = nullptr;
  119. };
  120. } // namespace detail
  121. NLOHMANN_JSON_NAMESPACE_END