output_adapters.hpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. #pragma once
  2. #include <algorithm> // copy
  3. #include <cstddef> // size_t
  4. #include <ios> // streamsize
  5. #include <iterator> // back_inserter
  6. #include <memory> // shared_ptr, make_shared
  7. #include <ostream> // basic_ostream
  8. #include <string> // basic_string
  9. #include <vector> // vector
  10. namespace nlohmann
  11. {
  12. namespace detail
  13. {
  14. /// abstract output adapter interface
  15. template<typename CharType> struct output_adapter_protocol
  16. {
  17. virtual void write_character(CharType c) = 0;
  18. virtual void write_characters(const CharType* s, std::size_t length) = 0;
  19. virtual ~output_adapter_protocol() = default;
  20. };
  21. /// a type to simplify interfaces
  22. template<typename CharType>
  23. using output_adapter_t = std::shared_ptr<output_adapter_protocol<CharType>>;
  24. /// output adapter for byte vectors
  25. template<typename CharType>
  26. class output_vector_adapter : public output_adapter_protocol<CharType>
  27. {
  28. public:
  29. explicit output_vector_adapter(std::vector<CharType>& vec) : v(vec) {}
  30. void write_character(CharType c) override
  31. {
  32. v.push_back(c);
  33. }
  34. void write_characters(const CharType* s, std::size_t length) override
  35. {
  36. std::copy(s, s + length, std::back_inserter(v));
  37. }
  38. private:
  39. std::vector<CharType>& v;
  40. };
  41. /// output adapter for output streams
  42. template<typename CharType>
  43. class output_stream_adapter : public output_adapter_protocol<CharType>
  44. {
  45. public:
  46. explicit output_stream_adapter(std::basic_ostream<CharType>& s) : stream(s) {}
  47. void write_character(CharType c) override
  48. {
  49. stream.put(c);
  50. }
  51. void write_characters(const CharType* s, std::size_t length) override
  52. {
  53. stream.write(s, static_cast<std::streamsize>(length));
  54. }
  55. private:
  56. std::basic_ostream<CharType>& stream;
  57. };
  58. /// output adapter for basic_string
  59. template<typename CharType, typename StringType = std::basic_string<CharType>>
  60. class output_string_adapter : public output_adapter_protocol<CharType>
  61. {
  62. public:
  63. explicit output_string_adapter(StringType& s) : str(s) {}
  64. void write_character(CharType c) override
  65. {
  66. str.push_back(c);
  67. }
  68. void write_characters(const CharType* s, std::size_t length) override
  69. {
  70. str.append(s, length);
  71. }
  72. private:
  73. StringType& str;
  74. };
  75. template<typename CharType, typename StringType = std::basic_string<CharType>>
  76. class output_adapter
  77. {
  78. public:
  79. output_adapter(std::vector<CharType>& vec)
  80. : oa(std::make_shared<output_vector_adapter<CharType>>(vec)) {}
  81. output_adapter(std::basic_ostream<CharType>& s)
  82. : oa(std::make_shared<output_stream_adapter<CharType>>(s)) {}
  83. output_adapter(StringType& s)
  84. : oa(std::make_shared<output_string_adapter<CharType, StringType>>(s)) {}
  85. operator output_adapter_t<CharType>()
  86. {
  87. return oa;
  88. }
  89. private:
  90. output_adapter_t<CharType> oa = nullptr;
  91. };
  92. }
  93. }