1+ /*
2+ * (c) Проект "SimJson", Александр Орефков orefkov@gmail.com
3+ * ver. 1.0
4+ * Классы для работы с JSON
5+ */
6+
17#pragma once
28#include < memory>
39#include < optional>
713#include < type_traits>
814#include < utility>
915
16+ #pragma once
17+ #ifndef __has_declspec_attribute
18+ #define __has_declspec_attribute (x ) 0
19+ #endif
20+
21+ #ifdef SIMJSON_IN_SHARED
22+ #if defined(_MSC_VER) || (defined(__clang__) && __has_declspec_attribute(dllexport))
23+ #ifdef SIMJSON_EXPORT
24+ #define SIMJSON_API __declspec (dllexport)
25+ #else
26+ #define SIMJSON_API __declspec (dllimport)
27+ #endif
28+ #elif (defined(__GNUC__) || defined(__GNUG__)) && defined(SIMSTR_EXPORT)
29+ #define SIMJSON_API __attribute__ ((visibility(" default" )))
30+ #else
31+ #define SIMJSON_API
32+ #endif
33+ #else
34+ #define SIMJSON_API
35+ #endif
36+
1037namespace simjson {
1138using namespace simstr ;
1239using namespace simstr ::literals;
@@ -93,7 +120,6 @@ concept JsonObjectSource = requires(const T& t) {
93120template <typename K>
94121class JsonValueTempl : public Json {
95122public:
96-
97123 using strType = sstring<K>;
98124 using ssType = simple_str<K>;
99125
@@ -106,7 +132,7 @@ class JsonValueTempl : public Json {
106132 // / Создает пустой объект с типом Undefined
107133 JsonValueTempl () : type_(Undefined) {}
108134 // / Конструктор копирования. Объекты и массивы копируются по ссылке
109- JsonValueTempl (const JsonValueTempl& other);
135+ SIMJSON_API JsonValueTempl (const JsonValueTempl& other);
110136 // / Конструктор перемещения
111137 JsonValueTempl (JsonValueTempl&& other) noexcept {
112138 type_ = other.type_ ;
@@ -126,7 +152,7 @@ class JsonValueTempl : public Json {
126152 other.type_ = Undefined;
127153 }
128154 // / Деструктор
129- ~JsonValueTempl ();
155+ SIMJSON_API ~JsonValueTempl ();
130156
131157 // / Конструктор из int8_t
132158 JsonValueTempl (int8_t v) : type_(Integer) { val_.integer = v; }
@@ -172,7 +198,7 @@ class JsonValueTempl : public Json {
172198 new (&val_.array ) json_array (std::make_shared<arr_type>());
173199 }
174200 // / Конструктор для создания дефолтного значения с типом type
175- JsonValueTempl (Type type);
201+ SIMJSON_API JsonValueTempl (Type type);
176202
177203 struct KeyInit : std::pair<const jt::KeyType<K>, json_value> {
178204 using base = std::pair<const jt::KeyType<K>, json_value>;
@@ -213,7 +239,7 @@ class JsonValueTempl : public Json {
213239 const json_value& from;
214240 };
215241 // / Конструктор клонирования. В этом случае для объектов и массивов создаются "глубокие" копии
216- JsonValueTempl (const Clone& clone);
242+ SIMJSON_API JsonValueTempl (const Clone& clone);
217243 // / Получить тип значения
218244 Type type () const { return type_; }
219245 // / Клонировать значение
@@ -262,7 +288,7 @@ class JsonValueTempl : public Json {
262288 throw Exc (std::forward<Args>(args)...);
263289 }
264290 // / Получить значение, конвертированное в boolean. Логика работы как в javascript `!!val`. Пример: bool val = json.to_boolean();
265- bool to_boolean () const ;
291+ SIMJSON_API bool to_boolean () const ;
266292
267293 // ---------------------------------------- Integer -------------------------------------
268294 // / Получить значение как integer. В отладочной версии проверяется, что значение действительно integer
@@ -288,7 +314,7 @@ class JsonValueTempl : public Json {
288314 // / Получить значение, конвертированное в integer, или ничего. Логика работы как в javascript `1 * val`.
289315 // / Если в результате NaN или Inf, то ничего. Нецелые числа - переводятся в целое.
290316 // / Пример: int val = json.to_integer().value_or(10);
291- std::optional<int64_t > to_integer () const ;
317+ SIMJSON_API std::optional<int64_t > to_integer () const ;
292318 // / Получить значение из to_integer, если оно есть, или выкинуть исключение.
293319 template <typename Exc, typename ... Args> requires (std::is_constructible_v<Exc, Args...>)
294320 int64_t to_integer_or_throw(Args&&...args) const {
@@ -320,7 +346,7 @@ class JsonValueTempl : public Json {
320346 }
321347
322348 // / Получить значение, конвертированное в double. Логика работы как в javascript `1 * val`. Для "не чисел" возвращает NaN.
323- double to_real () const ;
349+ SIMJSON_API double to_real () const ;
324350 // --------------------------------------- Number -----------------------------
325351 // В нашей реализации в отличии от чистого json числа могут быть int64_t или double
326352 // Поэтому добавим ещё логику для работы только с обоими вариантами чисел
@@ -336,7 +362,7 @@ class JsonValueTempl : public Json {
336362 throw Exc (std::forward<Args>(args)...);
337363 }
338364 // / Возвращает double, если хранится double или int64_t, либо ничего
339- std::optional<double > number_real () const ;
365+ SIMJSON_API std::optional<double > number_real () const ;
340366 // / Получить double, если хранится double или int64_t, либо выбросить исключение
341367 template <typename Exc, typename ... Args> requires (std::is_constructible_v<Exc, Args...>)
342368 double number_real_or_throw(Args&&...args) const {
@@ -379,7 +405,7 @@ class JsonValueTempl : public Json {
379405 }
380406
381407 // / Получить значение, конвертированное в текст. Логика работы как в javascript `"" + val`.
382- strType to_text () const ;
408+ SIMJSON_API strType to_text () const ;
383409
384410 // / Получить значение как json Object. В отладочной версии проверяется, что значение действительно Object
385411 json_object& as_object () {
@@ -552,7 +578,7 @@ class JsonValueTempl : public Json {
552578 * Если оба JSONа объекты - то сливаются по ключам. Ключи из другого объекта, которых нет в текущем - добавятся в текущий
553579 * объект. Которые есть - при replace == true будут заменены.
554580 */
555- void merge (const json_value& other, bool replace = true , bool append_arrays = false );
581+ SIMJSON_API void merge (const json_value& other, bool replace = true , bool append_arrays = false );
556582 /* !
557583 * @brief Распарсить текст с json.
558584 *
@@ -574,7 +600,7 @@ class JsonValueTempl : public Json {
574600 * @param indent_symbol - при "украшении" задаёт символ для отступов, по умолчанию пробел.
575601 * @param indent_count - количество символов отступа на один уровень, по умолчанию 2.
576602 */
577- void store (lstring<K, 0 , true >& stream, bool prettify = false , bool order_keys = false , K indent_symbol = ' ' , unsigned indent_count = 2 ) const ;
603+ SIMJSON_API void store (lstring<K, 0 , true >& stream, bool prettify = false , bool order_keys = false , K indent_symbol = ' ' , unsigned indent_count = 2 ) const ;
578604 /* !
579605 * @brief Сериализовать json-значение в строку
580606 * @param prettify - "украшать", в случае true в строке будут добавляться переносы строк и отступы.
@@ -593,8 +619,8 @@ class JsonValueTempl : public Json {
593619 }
594620
595621protected:
596- // Один объект "пустышка"
597- static const json_value UNDEFINED;
622+ SIMJSON_API static const json_value UNDEFINED;
623+
598624 // Тип значения
599625 Type type_;
600626 // Хранимое значение
@@ -648,7 +674,7 @@ struct StreamedJsonParser : StreamedJsonParserBase {
648674protected:
649675
650676 template <bool All, bool Last>
651- JsonParseResult process (ssType chunk);
677+ SIMJSON_API JsonParseResult process (ssType chunk);
652678
653679 static bool isWhiteSpace (K symbol) {
654680 return symbol == ' ' || symbol == ' \t ' || symbol == ' \n ' || symbol == ' \r ' ;
@@ -688,14 +714,17 @@ using JsonValueU = JsonValueTempl<u16s>;
688714using JsonValueUU = JsonValueTempl<u32s>;
689715
690716// / Один объект "пустышка"
717+ #if defined (SIMJSON_EXPORT) || !defined (SIMJSON_IN_SHARED)
691718template <typename K>
692- inline const JsonValueTempl<K> JsonValueTempl<K>::UNDEFINED;
719+ inline SIMJSON_API const JsonValueTempl<K> JsonValueTempl<K>::UNDEFINED;
720+ #else
721+ #endif
693722
694723/* !
695724 * @brief Прочитать файл в строку
696725 * @param filePath
697726 * @return stringa
698727 */
699- stringa get_file_content (stra filePath);
728+ SIMJSON_API stringa get_file_content (stra filePath);
700729
701730} // namespace simjson
0 commit comments