- 001
- 002
- 003
- 004
- 005
- 006
- 007
- 008
- 009
- 010
- 011
- 012
- 013
- 014
- 015
- 016
- 017
- 018
- 019
- 020
- 021
- 022
- 023
- 024
- 025
- 026
- 027
- 028
- 029
- 030
- 031
- 032
- 033
- 034
- 035
- 036
- 037
- 038
- 039
- 040
- 041
- 042
- 043
- 044
- 045
- 046
- 047
- 048
- 049
- 050
- 051
- 052
- 053
- 054
- 055
- 056
- 057
- 058
- 059
- 060
- 061
- 062
- 063
- 064
- 065
- 066
- 067
- 068
- 069
- 070
- 071
- 072
- 073
- 074
- 075
- 076
- 077
- 078
- 079
- 080
- 081
- 082
- 083
- 084
- 085
- 086
- 087
- 088
- 089
- 090
- 091
- 092
- 093
- 094
- 095
- 096
- 097
- 098
- 099
- 100
#ifndef RPCCALL_H
#define RPCCALL_H
#include <deque>
#include <typeinfo>
#include <string>
#include "byteinbuffer.h"
#include <byteoutbuffer.h>
#include <ostream>
class RPCPack
{
public:
RPCPack();
//RPCPack(const RPCPack &obj);
RPCPack(RPCPack && obj);
RPCPack & operator = (RPCPack&& obj);
template<class T, typename std::enable_if<
std::is_pod<T>::value && !std::is_pointer<T>::value>::type* = nullptr>
bool pack(const T& param);
template <class T,typename std::enable_if<
std::is_same<typename T::iterator::iterator_category,std::random_access_iterator_tag>::value>::type* = nullptr>
bool pack(const T& param);
template <class T,typename std::enable_if<
std::is_same<typename T::iterator::iterator_category,std::bidirectional_iterator_tag>::value>::type* = nullptr>
bool pack(const T& param);
template <class T,typename std::enable_if<
std::is_same<typename T::iterator::iterator_category,std::forward_iterator_tag>::value>::type* = nullptr>
bool pack(const T& param);
template<class D,class ... T >
bool pack(const D& param,const T& ... params);
template<class ... T>
bool pack(const T& ... params);
template<class T, typename std::enable_if<
std::is_pod<T>::value && !std::is_pointer<T>::value && !std::is_array<T>::value>::type* = nullptr>
bool unpack(T& param);
template <class T,typename std::enable_if<
std::is_same<typename T::iterator::iterator_category,std::random_access_iterator_tag>::value>::type* = nullptr>
bool unpack(T& param);
template <class T,typename std::enable_if<
std::is_same<typename T::iterator::iterator_category,std::bidirectional_iterator_tag>::value>::type* = nullptr>
bool unpack(T& param);
template <class T,typename std::enable_if<
std::is_same<typename T::iterator::iterator_category,std::forward_iterator_tag>::value>::type* = nullptr>
bool unpack(T& param);
template<class D,class ... T >
bool unpack(D& param, T& ... params);
template<class ... T>
bool unpack(T& ... params);
template <class T,class D>
bool pack(const std::pair<T,D> & p);
template <class T,class D>
bool unpack(std::pair<T,D>& p);
std::vector<char> getSerialized();
void deserialize(std::istream &vs);
size_t getSize();
bool isEmpty();
void copyOuttoIn();
void moveOuttoIn();
ByteOutBuffer<char> getBuffer() const;
void setBuffer(const ByteOutBuffer<char> &value);
private:
std::deque<size_t> sig;
std::vector<char> outdata;
std::vector<char> indata;
ByteOutBuffer<char> outbuffer;
ByteInBuffer<char> inbuffer;
std::istream is;
std::ostream os;
};
template<class T, typename std::enable_if<
std::is_pod<T>::value && !std::is_pointer<T>::value>::type*>
bool RPCPack::pack(const T& param)
{
sig.push_back(typeid(param).hash_code());
if(os.write((char*)¶m,sizeof(param)))
return true;
return false;
}
template <class T,class D>
bool RPCPack::pack(const std::pair<T,D>& param)
{
return pack(param.first) & pack(param.second);
}
template <class T,class D>
Хуячу сериализацию. Я метапрограммер)
Зачем ты его написал? Это шутка или всерьез? Ведь если ты запостил его сюда, то понимаешь, что это говно. Было бы интересно послушать, что именно ты думаешь о своем творении. Какие именно места тебе кажутся плохими? Или ты запостил его, чтобы похвастаться?
1) Ты захардкодил методы pack и unpack в классе вместо того, чтобы сделать их свободными функциями и дать пользователю возможность переопределять их для своих типов.
2) Очевидно, твой сериализатор сосет по перфомансу, потому что данные 100500 раз копируются между буферами, дофига аллокаций из кучи, которые пользователь не контролирует, используются стремные иостримы. Хороший сериализатор не аллоцирует вектор, а пишет в буфер или стрим пользователя.
3) Непонятно, почему в одном классе смешана в кучу сериализация и десериализация.
4) Твоя сериализация не только зависит от архитектуры (порядок байт в структурах), она зависит от компилятора (паддинг).
5) > pack(param.first) & pack(param.second)
Выучи разницу между битовыми и логическими операциями.
Вот так изящно всё, что уже сериализовано на диск, превращается в мусор, когда в структурке добавляются / меняются поля.
Чего только люди не придумают, лишь бы не использовать Protocol Buffers / https://capnproto.org/ и прочие MMS
На самом деле это я сказал, прикрывшись снаутом.
А где в protobuf-е схема рядом с данными?
https://developers.google.com/protocol-buffers/docs/encoding#structure
> чтение новой версии данных старой версией софта
Ну это в каких-то случаях так, а в каких-то не так. Если нужно на сервере обеспечить поддержку старых клиентов, то можно просто договариваться об используемой версии протокола во время хэндшейка или типа того.
Мне кажется, что подход протобуфа более костыле-ориентированный и опасный, а версионирование - просто и надежно.
Я говорю о чтении старой версией программы данных, которые были записаны с новой версией схемы. Никакого сервера при этом нет.
> подход протобуфа более костыле-ориентированный
Если есть 100500 batch-задач, которые обрабатывают массив данных, записанный другой программой, то такой подход очень даже хорошо работает. Именно в таких условиях протобуф и создавали.
А то я видел, как некоторые товарищи воспринимают протобуф, как серебрянную пулю, решающую проблему обратной совместимости, а потом "ой, ну мы тут протокол сломали, обновитесь".
Разница не принципиальна. Вполне может оказаться, что на разных концах канала передачи данных разные версии софта.
Для сетки, имхо, даже хуже ;)
На диске это ещё можно было бы списать на пирфоманс (у той же постгри, емнип, базу нельзя таскать на другие машины из-за такой вот привязки к архитектуре/компилеру). А в сетке как минимум машины с x86 и amd64 обязательно попадутся...
Инфа 100%?
Они не умели VCS, не умели модульность, и каждую свой мегапроект писали с нуля.
Ну правда это были школьники (в буквальном смысле) ;)
А у меня на приставке с бейсиком некуда было сохранять проги...
А ее легко было набрать по памяти. Все семь строк.
Как что-то плохое. Не хотеть писать свою реализацию ASN.1 - совершенно нормально.
З.Ы. Готовые либы запрещено юзать?
с другой стороны, кодирование данных в ASN.1 говно. если не знаешь заранее что за данные - то и не распарсишь, и незнакомые поля не перепрыгнешь. я лично пользуюсь TLV. все на меня ругаются за это - потому что "медленно" и "избыточно" - но мне нравится.
раньше думал что это нечто что помогает интерфейсы/этц темплейтов компилеру верифицировать - и еще до инстанциирования. но как выяснилось это не оно.
Откуда выяснилось?
У вас был компилятор с поддержкой концептов? Сомневаюсь.
Если использовали BOOST_CONCEPT_CHECK, то это не совсем то. Он не проверяет, что в шаблоне не используется то, что не заявлено в требованиях. Вообще всё это похоже на "опциональные тайп-хинты", попытку прикрутить типизацию к языку, в котором её изначально не было. Много вопросов возникает.
И разве шаблон может использовать только то, что написано в концепте?
Пошёл полистать Concept-Lite. В общем это просто предикаты на типах, компилятор не проверяет, что используются только те операции, которые были разрешены. Да не сможет он, ибо шаблон с концептами должен в теории уметь вызывать шаблоны без концептов, а там уж не известно заранее, что происходит. Это как типизацию к питону постфактум прикручивать.
дока к концептам есть где? потому что когда гуглишь "кресты концепции" находится только мусор.
https://en.wikipedia.org/w/index.php?title=Concepts_(C%2B%2B)&oldid =696409818
и было каким-то более или менее теоретическим Г. я еще тогда смотрелся в сырцы STL где якобы были какие-то концепции, но там точно так же ничего интересного не было.
Ну ктож так гуглит
Там есть ссылки на PDF и гуглодоки с более подробным описанием.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf
133 страниц счастья.
как раз для тех кто слишком долго ходил по крестам.
степени мазохизма: ходил по лего, ходил по граблям, ходил по крестам.
Больше ненужных фич богу ненужных фич!
умные вещи можно продавать только умным. но умным продать что ли бо сложно, потому что в конце часто все сводится к "all is good in moderation". и поиск этого самого moderation в книжках не вычитаешь - это зависит от приложений/людей/прикладной области. с чем теоретические материалы не сильно помогают.
Спорное утверждение. В чём говно-то? Мне, вообще говоря, нравились его книги, когда я только начинал учить кресты. Гораздо лучше многого из того, что можно найти по той же жабе.
я его книжек не читал, но догадываюсь что они будут ОК, потому что он более прагматичный чудак. (его уже имеет смысл критиковать, по сравнению с толпами пустых мест.) я читал его лекции/презентации с воркшопов по С++ в паре прикладных областей. если ни разу в универ не ходил - то они может быть и полезны, но по уровню они CompSci 101/201, и не более.
При этом кресты цветут и пахнут, а крестопрограммисты остаются одними из самых высококлассных программистов в мире.
В чём секрет?
Сравнение тайплассов хаскеля и концептов с++ (проползал из c++0x, едва ли Concepts TS много в чем хуже). Вывод автора статьи:
Out of our 27 criteria, summarised in table 2, 16 are equally supported in both languages, and only one or two are not portable. So, we can safely conclude as we started — C++ concepts and Haskell type classes are very similar.
Мой вывод: вы, сударь, говноглор
PS: Поставь себе анимешную девочку на аватарку, раз старую удалил.
щито
Я официально нарёк это словом "Метушня". Будьте добры использовать мой форсед мем.