C++ STL to JSON

C++ STL to JSON

The JSON encode routines convert STL structures into JSON formatted strings. Using polymorphism and recursion, the function for each data-type is called, writing out finer and finer detail until raw data-types are written. Strings are URL encoded prior to writing to the file in order to handle special characters and internal quotes.

The source files for my encoder follows.

Logging header file "u_json_encode.h"

#pragma once

#include <json/json.h>

#include <map>
#include <ostream>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <vector>

namespace UJSON {
template <typename T> std::string encode(const T &t);

template <typename T> std::string raw(const T &val) {
  std::ostringstream ss;
  ss << val;
  return ss.str();
}

std::string raw(const std::string &val);
std::string raw(const std::u16string &val);

void encodeJSON(std::ostream &ss, int val);
void encodeJSON(std::ostream &ss, unsigned int val);
void encodeJSON(std::ostream &ss, float val);
void encodeJSON(std::ostream &ss, double val);
void encodeJSON(std::ostream &ss, long double val);
void encodeJSON(std::ostream &ss, const std::string &val);
void encodeJSON(std::ostream &ss, const std::u16string &val);

template <typename T>
void encodeJSON(std::ostream &ss, const std::vector<T> &t) {
  ss << "[";
  for (unsigned int i = 0; i < t.size(); i++) {
    ss << encode(t[i]);
    if (i < (t.size() - 1))
      ss << ",";
  }
  ss << "]";
}

template <typename T> void encodeJSON(std::ostream &ss, const std::set<T> &t) {
  ss << "[";
  unsigned int i = 0;
  for (auto v : t) {
    ss << encode(v);
    if (i < (t.size() - 1))
      ss << ",";
    i++;
  }
  ss << "]";
}

template <typename T, typename U>
void encodeJSON(std::ostream &ss, const std::map<T, U> &t) {
  ss << "{";
  unsigned int i = 0;
  for (auto v : t) {
    ss << encode(v.first);
    ss << ":";
    ss << encode(v.second);
    if (i < (t.size() - 1))
      ss << ",";
    i++;
  }
  ss << "}";
}

template <typename T, typename U>
void encodeJSON(std::ostream &ss, const std::pair<T, U> &t) {
  ss << "[";
  ss << encode(t.first);
  ss << ",";
  ss << encode(t.second);
  ss << "]";
}

template <typename T, typename U>
void encodeJSON(std::ostream &ss, const std::unordered_map<T, U> &t) {
  ss << "{";
  unsigned int i = 0;
  for (auto v : t) {
    ss << encode(v.first);
    ss << ":";
    ss << encode(v.second);
    if (i < (t.size() - 1))
      ss << ",";
    i++;
  }
  ss << "}";
}

template <typename... Ts>
void encodeJSON(std::ostream &ss, const std::tuple<Ts...> &t) {
  std::apply(
      [&ss](Ts const &...args) {
        ss << '[';
        std::size_t n{0};
        ((ss << encode(args) << (++n != sizeof...(Ts) ? "," : "")), ...);
        ss << ']';
      },
      t);
}

template <typename T> std::string encode(const T &t) {
  std::ostringstream ss;
  encodeJSON(ss, t);
  return ss.str();
}

template <typename T> std::string encode(const std::string &label, const T &t) {
  std::ostringstream ss;
  ss << "\"" << label << "\":" << encode(t);
  return ss.str();
}
} // namespace UJSON

Logging source file "u_json_encode.cpp"

#include "u_json_encode.h"
#include "u_log.h"

void UJSON::encodeJSON(std::ostream &ss, int val) {
    ss << raw(val);
}

void UJSON::encodeJSON(std::ostream &ss, unsigned int val) {
    ss << raw(val);
}

void UJSON::encodeJSON(std::ostream &ss, float val) {
    ss << raw(val);
}

void UJSON::encodeJSON(std::ostream &ss, double val) {
    ss << raw(val);
}

void UJSON::encodeJSON(std::ostream &ss, long double val) {
    ss << raw(val);
}

void UJSON::encodeJSON(std::ostream &ss, const std::string &val) {
    ss << raw(val);
}

void UJSON::encodeJSON(std::ostream &ss, const std::u16string &val) {
    ss << raw(val);
}

std::string UJSON::raw(const std::string &val) {
    std::ostringstream ss;
    ss << "\"" << mystd::urlEncode(val) << "\"";
    return ss.str();
}

std::string UJSON::raw(const std::u16string &val) {
    std::ostringstream ss;
    std::string wip = mystd::toUTF8(val);
    ss << "\"" << mystd::urlEncode(wip) << "\"";
    return ss.str();
}

C++ Logging Routines C++ STL from JSON