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