Форум программистов, компьютерный форум CyberForum.ru

SAX json парсер - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Передача типа указателя на функцию http://www.cyberforum.ru/cpp/thread913130.html
Всем привет. Недавно в теме начинающих возник вопрос, а можно ли передать тип (указатель на функцию) без использования typedef: typedef void (*func)(void); func f = va_arg(vl,func); Конкретно речь идет о втором аргументе макроса va_arg (из <cstdarg>). Первое, что пришло на ум, это использование decltype. Но всё же эта фишка C++11. А есть ли решение в старом стиле? Заранее спасибо.
C++ Десять возможностей C++11, которые должен использовать каждый C++ разработчик Обсуждаем статью: http://habrahabr.ru/post/182920/ Надо же этот раздел немного оживить :) Я, естественно, не участвую. ^_^ http://www.cyberforum.ru/cpp/thread899038.html
C++ Лямбда не допускает auto
Всем привет! Имеем код: #include <iostream> #include <vector> #include <algorithm> #include <numeric> int main()
C++ Вызов через указатель на функцию-член
Всем экспертам привет :) Разбавим раздел, так сказать. Задался тут таким вопросом: Есть класс, в котором объявлено поле типа "указатель на функцию-член" : struct C { void (C::*m)(); ... };
C++ std::filesystem && std::asio и пр http://www.cyberforum.ru/cpp/thread607412.html
Пытался найти хоть какие-то сроки включения всего этого в стандарт (так же ожидается lexical_cast, any, string_algo и т.д.) и вообщем везде написано разное, проскакивает инфа о 2017 годе... Как-то не слишком оптимистично, кто-то может подсказать какие-либо сведения по этому поводу (желательно с пруф линками)?
C++ Многомерный вектор Необходимо разработать шаблон, который будет реализовывать функционал n-мерного массива, то есть, во время выполнения нужно изменять колличество измерений и размерность каждого. Словом, то же самое, что vector, только n-мерный. Подскажите, есть что-то такое готовое? Если нет, как такое можно написать? Писать на статике, естественно, не подходит, и выделять всю память при изменении размера тоже... подробнее

Показать сообщение отдельно
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3

SAX json парсер - C++

05.07.2013, 22:46. Просмотров 4612. Ответов 6
Метки (Все метки)

Вечер добрый.
Есть задача реализовать SAX-парсер JSON-a (парсинг не во временные переменные, а сразу в текущие, на которые указатели/ссылки сохранены в некий контекст в классе). Задача парсить не просто примитивные типы и контейнеры, но и сложные/составные типы.

Нечто вроде такого

C++
1
2
3
4
5
6
struct A
{
   int a;
   std::vector<int> b;
   std::string c;
};
Должно переводиться в json и обратно
C++
1
2
3
4
5
const std::string json = "{\"A\":{\"a\":1,\"b\":{1,2},\"c\":\"string\"}}";
A a;
statement stmt;
stmt.use(a);
stmt.deserialize(json);
Я сделал данный кейс через fusion (сделано по аналогу SOCI, но там нет парсинга СРАЗУ в сложные типы). Капитально приходится испытывать сложности с составными объектами, я выбрал вариант, когда просто биндятся simple/container/conversion типы, который находятся в структуре (страдает время компиляции, для каждого объекта приходится создавать новый statement, причем динамически, ибо хранятся указатели (это проще, постольку поскольку, конструктор копирования реализовывать несколько сложнее), уходит довольно много памяти (допустим для примера из сериализации/десериализации двух структур + массива интов + boost::gregorian::date уходит примерно 271к байт, терпимо, но не слишком круто)).
Пример:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct other
{
   std::string name;
   unsigned int age;
   bool flag;
   double number;
 
   struct name_key { static const char* name() { return "name"; }};
   struct age_key { static const char* name() { return "age"; }};
   struct flag_key { static const char* name() { return "flag"; }};
   struct number_key { static const char* name() { return "number"; }};
};
 
BOOST_FUSION_ADAPT_ASSOC_STRUCT(
      other,
      (std::string, name, other::name_key)
      (unsigned int, age, other::age_key)
      (bool, flag, other::flag_key)
      (double, number, other::number_key)
);
структура становится fusion_sequence и через код вроде этого ее можно обойти

C++
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
template<typename Next, typename Last>
struct traverse_types
{
   template<typename Object>
   static void traverse_helper(statement& stmt, Object& object, const std::string& name)
   {
      typedef typename get_exchange_type<Object>::type type;
      stmt.add_field(name, new type(object, name));
   }
   template<typename Object>
   static void apply(statement& stmt, Object& object)
   {
      typedef typename boost::fusion::result_of::key_of<Next>::type key_t;
      typedef typename boost::fusion::result_of::next<Next>::type next_t;
      typedef typename boost::fusion::result_of::at_key<Object, key_t>::type value_ref_t;
      typedef typename boost::remove_reference<value_ref_t>::type value_t;
      traverse_helper(stmt, boost::fusion::at_key<key_t>(object), key_t::name());
      traverse_types<next_t, Last>::apply(stmt, object);
   }
};
 
template<typename Last>
struct traverse_types<Last, Last>
{
   template<typename Object>
   static void apply(statement&, Object&)
   {
   }
};
// в конкретном классе use/into
 static void traverse(statement& stmt, T& object)
 {
    traverse_types<typename boost::fusion::result_of::begin<T>::type,
      typename boost::fusion::result_of::end<T>::type>::
      apply(stmt, object);
};
Где get_exchange_type некий шаблон, который просто typedef-ит нужный into/use тип.

C++
1
2
3
4
5
6
7
8
9
template<typename T>
struct get_exchange_type
{
   typedef typename exchange_traits<T>::type_tag tag;
   typedef typename boost::mpl::if_<typename boost::is_same<tag, basic_tag>::type, into_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, container_tag>::type, container_into_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, conversion_tag>::type, conversion_into_type<T>,
           user_into_type<T>>::type>::type>::type type;
};
C++
1
2
3
4
5
6
7
8
9
template<typename T>
struct get_exchange_type<const T>
{
   typedef typename exchange_traits<T>::type_tag tag;
   typedef typename boost::mpl::if_<typename boost::is_same<tag, basic_tag>::type, use_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, container_tag>::type, container_use_type<T>,
           typename boost::mpl::if_<typename boost::is_same<tag, conversion_tag>::type, conversion_use_type<T>,
           user_use_type<T>>::type>::type>::type type;
};
Перегрузка для statement/writer реализована на тегах
C++
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
template<typename T>
struct type_conversion;
 
struct basic_tag {};
struct user_tag {};
struct container_tag {};
struct conversion_tag {};
 
template<typename T>
struct has_type_conversion
{
   typedef char no;
   typedef char yes[2];
 
   template<typename U>
   static yes& test(typename type_conversion<U>::base_type*);
   template<typename>
   static no& test(...);
 
   static const bool value = sizeof(test<T>(0)) == sizeof(yes);
   typedef boost::mpl::bool_<value> type;
};
 
template<typename T>
struct exchange_traits
{
   typedef typename has_type_conversion<T>::type conversion;
   typedef typename boost::mpl::if_<conversion, conversion_tag, user_tag>::type type_tag;
   template<typename U, typename = void>
   struct get_type
   {
      enum { x_type = x_object };
   };
   template<typename U>
   struct get_type<U, typename boost::enable_if<typename has_type_conversion<U>::type>::type>
   {
      enum { x_type = exchange_traits<typename type_conversion<U>::base_type>::x_type };
   };
   enum
   {
      x_type = get_type<T>::x_type
   };
};
Дальше идут специализации для basic типов / контейнеров.

Есть возможность сделать интроспекцию/отражение в С++ проще, чем сделано на данный момент? Если данный вопрос нужно перенести в С++ для экспертов/boost - скажите, перенесу. Спасибо.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru