13 #ifndef __STOUT_JSONIFY__
14 #define __STOUT_JSONIFY__
26 #include <type_traits>
52 namespace JSON {
class Proxy; }
80 original_per_thread_ = _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
85 original_locale_ = setlocale(LC_NUMERIC,
"C");
90 setlocale(LC_NUMERIC, original_locale_.c_str());
91 _configthreadlocale(original_per_thread_);
95 int original_per_thread_;
96 std::string original_locale_;
101 c_locale_ = newlocale(LC_NUMERIC_MASK,
"C",
nullptr);
102 original_locale_ = uselocale(c_locale_);
107 uselocale(original_locale_);
108 CHECK(c_locale_ != 0);
109 freelocale(c_locale_);
113 locale_t original_locale_;
115 #endif // __WINDOWS__
132 operator std::string() &&
137 std::ostringstream stream;
138 stream << std::move(*
this);
143 Proxy(std::function<
void(std::ostream*)>
write) : write_(std::move(
write)) {}
155 Proxy(
const Proxy&) =
default;
156 Proxy(Proxy&&) =
default;
158 std::function<void(std::ostream*)> write_;
160 template <
typename T>
161 friend Proxy (::
jsonify)(
const T&);
163 friend std::ostream&
operator<<(std::ostream& stream, Proxy&& that);
172 that.write_(&stream);
192 void set(
bool value) { value_ = value; }
195 std::ostream* stream_;
206 : stream_(stream), type_(INT),
int_(0) {}
227 const int size = snprintf(
231 std::numeric_limits<double>::digits10,
240 for (; back > 0; --back) {
241 if (buffer[back] !=
'0') {
248 *stream_ << buffer << (buffer[back] ==
'.' ?
"0" :
"");
272 void set(
short int value) {
set(static_cast<long long int>(value)); }
274 void set(
int value) {
set(static_cast<long long int>(value)); }
276 void set(
long int value) {
set(static_cast<long long int>(value)); }
278 void set(
long long int value)
284 void set(
unsigned short int value)
286 set(static_cast<unsigned long long int>(value));
289 void set(
unsigned int value)
291 set(static_cast<unsigned long long int>(value));
294 void set(
unsigned long int value)
296 set(static_cast<unsigned long long int>(value));
299 void set(
unsigned long long int value)
305 void set(
float value) {
set(static_cast<double>(value)); }
314 std::ostream* stream_;
316 enum { INT, UINT, DOUBLE } type_;
332 StringWriter(std::ostream* stream) : stream_(stream) { *stream_ <<
'"'; }
345 case '"' : *stream_ <<
"\\\"";
break;
346 case '\\': *stream_ <<
"\\\\";
break;
347 case '/' : *stream_ <<
"\\/";
break;
348 case '\b': *stream_ <<
"\\b";
break;
349 case '\f': *stream_ <<
"\\f";
break;
350 case '\n': *stream_ <<
"\\n";
break;
351 case '\r': *stream_ <<
"\\r";
break;
352 case '\t': *stream_ <<
"\\t";
break;
354 if (static_cast<unsigned char>(c) < 0x20 || c == 0x7f) {
356 snprintf(buffer,
sizeof(buffer),
"\\u%04x", c & 0xff);
357 stream_->write(buffer,
sizeof(buffer) - 1);
366 template <std::
size_t N>
368 void append(
const std::string& value) {
append(value.data(), value.size()); }
371 void append(
const char* value, std::size_t
size)
373 for (std::size_t i = 0; i <
size; ++i) {
378 std::ostream* stream_;
400 template <
typename T>
411 std::ostream* stream_;
434 template <
typename T>
435 void field(
const std::string& key,
const T& value)
445 std::ostream* stream_;
464 std::ostream* stream_;
514 template <std::
size_t N>
534 template <
typename T>
548 template <
typename U>
549 static auto test(
Prefer) -> decltype(
551 void(std::begin(std::declval<U&>()) != std::end(std::declval<U&>())),
552 ++std::declval<decltype(std::begin(std::declval<U&>()))&>(),
553 *std::begin(std::declval<U&>()),
557 template <
typename U>
568 template <
typename T>
572 template <
typename U,
typename =
typename U::mapped_type>
573 static std::true_type test(
Prefer);
575 template <
typename U>
591 typename std::enable_if<
593 !(std::is_array<Iterable>::value &&
594 std::rank<Iterable>::value == 1 &&
600 foreach (
const auto& value, iterable) {
612 typename std::enable_if<
613 internal::IsSequence<Dictionary>::value &&
614 internal::HasMappedType<Dictionary>::value,
int>
::type = 0>
617 foreachpair (
const auto& key,
const auto& value, dictionary) {
619 writer->
field(key, value);
650 case BOOLEAN_WRITER: {
651 writer_.boolean_writer.~BooleanWriter();
654 case NUMBER_WRITER: {
655 writer_.number_writer.~NumberWriter();
658 case STRING_WRITER: {
659 writer_.string_writer.~StringWriter();
663 writer_.array_writer.~ArrayWriter();
666 case OBJECT_WRITER: {
667 writer_.object_writer.~ObjectWriter();
671 writer_.null_writer.~NullWriter();
680 type_ = BOOLEAN_WRITER;
681 return &writer_.boolean_writer;
687 type_ = NUMBER_WRITER;
688 return &writer_.number_writer;
694 type_ = STRING_WRITER;
695 return &writer_.string_writer;
701 type_ = ARRAY_WRITER;
702 return &writer_.array_writer;
708 type_ = OBJECT_WRITER;
709 return &writer_.object_writer;
714 new (&writer_.null_writer)
NullWriter(stream_);
716 return &writer_.null_writer;
734 BooleanWriter boolean_writer;
735 NumberWriter number_writer;
736 StringWriter string_writer;
737 ArrayWriter array_writer;
738 ObjectWriter object_writer;
739 NullWriter null_writer;
742 std::ostream* stream_;
767 template <
typename T>
770 return [&value](std::ostream* stream) {
778 template <
typename T>
784 #endif // __STOUT_JSONIFY__
std::function< void(std::ostream *)> jsonify(const F &write, Prefer)
Definition: jsonify.hpp:757
StringWriter & operator=(const StringWriter &)=delete
void set(short int value)
Definition: jsonify.hpp:272
Try< Bytes > size(const std::string &path, const FollowSymlink follow=FollowSymlink::FOLLOW_SYMLINK)
Definition: stat.hpp:100
BooleanWriter & operator=(const BooleanWriter &)=delete
~ClassicLocale()
Definition: jsonify.hpp:105
static constexpr bool value
Definition: jsonify.hpp:561
BooleanWriter(std::ostream *stream)
Definition: jsonify.hpp:182
ObjectWriter & operator=(const ObjectWriter &)=delete
~BooleanWriter()
Definition: jsonify.hpp:187
NumberWriter & operator=(const NumberWriter &)=delete
double double_
Definition: jsonify.hpp:322
ArrayWriter(std::ostream *stream)
Definition: jsonify.hpp:387
void append(const std::string &value)
Definition: jsonify.hpp:368
WriterProxy(std::ostream *stream)
Definition: jsonify.hpp:645
Definition: jsonify.hpp:450
Definition: jsonify.hpp:179
Definition: jsonify.hpp:569
friend std::ostream & operator<<(std::ostream &stream, Proxy &&that)
Definition: jsonify.hpp:167
void set(long long int value)
Definition: jsonify.hpp:278
Definition: jsonify.hpp:329
void element(const T &value)
Definition: jsonify.hpp:401
void set(double value)
Definition: jsonify.hpp:307
static constexpr bool value
Definition: jsonify.hpp:579
friend Proxy() jsonify(const T &)
StringWriter(std::ostream *stream)
Definition: jsonify.hpp:332
void json(BooleanWriter *writer, const Boolean &boolean)
Definition: json.hpp:694
~ArrayWriter()
Definition: jsonify.hpp:395
void set(long int value)
Definition: jsonify.hpp:276
void field(const std::string &key, const T &value)
Definition: jsonify.hpp:435
ObjectWriter(std::ostream *stream)
Definition: jsonify.hpp:421
Definition: jsonify.hpp:129
Definition: jsonify.hpp:531
void set(unsigned int value)
Definition: jsonify.hpp:289
Definition: jsonify.hpp:535
Definition: jsonify.hpp:418
#define foreachpair(KEY, VALUE, ELEMS)
Definition: foreach.hpp:51
void set(unsigned long long int value)
Definition: jsonify.hpp:299
~WriterProxy()
Definition: jsonify.hpp:647
Definition: jsonify.hpp:202
This object changes the current thread's locale to the default "C" locale for number printing purpose...
Definition: jsonify.hpp:72
std::ostream & operator<<(std::ostream &stream, const Boolean &boolean)
Definition: json.hpp:814
void append(char c)
Definition: jsonify.hpp:342
JSON::Proxy jsonify(const T &)
Definition: jsonify.hpp:779
~NumberWriter()
Definition: jsonify.hpp:211
long long int int_
Definition: jsonify.hpp:320
void set(unsigned long int value)
Definition: jsonify.hpp:294
~StringWriter()
Definition: jsonify.hpp:337
~ObjectWriter()
Definition: jsonify.hpp:429
Protocol< WriteRequest, WriteResponse > write
Try< uint32_t > type(const std::string &path)
NullWriter(std::ostream *stream)
Definition: jsonify.hpp:453
Definition: jsonify.hpp:530
unsigned long long int uint_
Definition: jsonify.hpp:321
ArrayWriter & operator=(const ArrayWriter &)=delete
void set(float value)
Definition: jsonify.hpp:305
void set(bool value)
Definition: jsonify.hpp:192
NullWriter & operator=(const NullWriter &)=delete
NumberWriter(std::ostream *stream)
Definition: jsonify.hpp:205
~NullWriter()
Definition: jsonify.hpp:458
void set(int value)
Definition: jsonify.hpp:274
void append(const char(&value)[N])
Definition: jsonify.hpp:367
Definition: jsonify.hpp:642
void set(unsigned short int value)
Definition: jsonify.hpp:284
ClassicLocale()
Definition: jsonify.hpp:99
Definition: jsonify.hpp:384