File: Writer.hpp

package info (click to toggle)
reflect-cpp 0.18.0%2Bds-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 12,524 kB
  • sloc: cpp: 44,484; python: 131; makefile: 30; sh: 3
file content (147 lines) | stat: -rw-r--r-- 4,407 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#ifndef FLEXBUF_WRITER_HPP_
#define FLEXBUF_WRITER_HPP_

#include <flatbuffers/flexbuffers.h>

#include <cstddef>
#include <exception>
#include <functional>
#include <map>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>

#include "../Bytestring.hpp"
#include "../Ref.hpp"
#include "../Result.hpp"
#include "../always_false.hpp"

namespace rfl {
namespace flexbuf {

struct Writer {
  struct OutputArray {
    size_t start_;
  };

  struct OutputObject {
    size_t start_;
  };

  struct OutputVar {};

  using OutputArrayType = OutputArray;
  using OutputObjectType = OutputObject;
  using OutputVarType = OutputVar;

  Writer(const Ref<flexbuffers::Builder>& _fbb);

  ~Writer();

  OutputArrayType array_as_root(const size_t _size) const noexcept;

  OutputObjectType object_as_root(const size_t _size) const noexcept;

  OutputVarType null_as_root() const noexcept;

  template <class T>
  OutputVarType value_as_root(const T& _var) const noexcept {
    return insert_value(_var);
  }

  OutputArrayType add_array_to_array(const size_t _size,
                                     OutputArrayType* _parent) const noexcept;

  OutputArrayType add_array_to_object(
      const std::string_view& _name, const size_t _size,
      OutputObjectType* _parent) const noexcept;

  OutputObjectType add_object_to_array(
      const size_t _size, OutputArrayType* _parent) const noexcept;

  OutputObjectType add_object_to_object(
      const std::string_view& _name, const size_t _size,
      OutputObjectType* _parent) const noexcept;

  template <class T>
  OutputVarType add_value_to_array(const T& _var,
                                   OutputArrayType* _parent) const noexcept {
    return insert_value(_var);
  }

  template <class T>
  OutputVarType add_value_to_object(const std::string_view& _name,
                                    const T& _var,
                                    OutputObjectType* _parent) const noexcept {
    return insert_value(_name, _var);
  }

  OutputVarType add_null_to_array(OutputArrayType* _parent) const noexcept;

  OutputVarType add_null_to_object(const std::string_view& _name,
                                   OutputObjectType* _parent) const noexcept;

  void end_array(OutputArrayType* _arr) const noexcept;

  void end_object(OutputObjectType* _obj) const noexcept;

 private:
  template <class T>
  OutputVarType insert_value(const std::string_view& _name,
                             const T& _var) const noexcept {
    if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
      fbb_->String(_name.data(), _var);
    } else if constexpr (std::is_same<std::remove_cvref_t<T>,
                                      rfl::Bytestring>()) {
      fbb_->Blob(_name.data(), _var.c_str(), _var.size());
    } else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
      fbb_->Bool(_name.data(), _var);
    } else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
      fbb_->Double(_name.data(), _var);
    } else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
      fbb_->Int(_name.data(), _var);
    } else {
      static_assert(always_false_v<T>, "Unsupported type");
    }
    return OutputVarType{};
  }

  template <class T>
  OutputVarType insert_value(const T& _var) const noexcept {
    if constexpr (std::is_same<std::remove_cvref_t<T>, std::string>()) {
      fbb_->String(_var);
    } else if constexpr (std::is_same<std::remove_cvref_t<T>,
                                      rfl::Bytestring>()) {
      fbb_->Blob(_var.c_str(), _var.size());
    } else if constexpr (std::is_same<std::remove_cvref_t<T>, bool>()) {
      fbb_->Bool(_var);
    } else if constexpr (std::is_floating_point<std::remove_cvref_t<T>>()) {
      fbb_->Double(_var);
    } else if constexpr (std::is_integral<std::remove_cvref_t<T>>()) {
      fbb_->Int(_var);
    } else {
      static_assert(always_false_v<T>, "Unsupported type");
    }
    return OutputVarType{};
  }

  OutputArrayType new_array(const std::string_view& _name) const noexcept;

  OutputArrayType new_array() const noexcept;

  OutputObjectType new_object(const std::string_view& _name) const noexcept;

  OutputObjectType new_object() const noexcept;

 private:
  Ref<flexbuffers::Builder> fbb_;
};

}  // namespace flexbuf
}  // namespace rfl

#endif