serdepp
serdepp copied to clipboard
C++14 Support?
Hi,
Could you please give us any idea how can we adapt serdepp with our C++14 project?
Serdepp is the only suitable library for our project ( it's amazing between others [serde-cpp, getml->reflect-cpp etc.] ) but we suffer from some drawbacks.
- Using exceptions prohibited.
- Using macros prohibited.
- Using any version other than C++14 prohibited.
Thank you so much.
Please bear with me because my native language is not English so I used a translator.
When I first created serdepp, I considered C++14, but as I created serdepp with only the features of C++14, the complexity of the code increased noticeably, so I chose C++17, which has better TMP support. If modifying to support C++14, you will need to modify everything using constexpr and string_view.
Can you tell me in more detail about the non-use of macros? Do you mean DERIVE_SERDE?
Please bear with me because my native language is not English so I used a translator. Oh, you are welcome.
I think I can use custom implementation of string_view ( with ETLCPP )
Do you mean DERIVE_SERDE? Yes macros like DERIVE_SERDE.
Maybe macros can be ignored for projects like our's but do you think will be hard to convert serdepp to c++14?
I think I can use custom implementation of string_view ( with ETLCPP )
I would need to look into replacing string_view with serdepp's custom library, but perhaps it could be supported in a similar way to how serdepp supports custom containers.
Additionally, the reason serdepp currently uses string_view is to support compile-time computation (constexpr) to reduce the cost of member name computation, so using a custom string library may result in poor performance.
Do you mean DERIVE_SERDE? Yes macros like DERIVE_SERDE.
serdepp does not use any macros except DERIVE_SERDE, which is a utility to reduce code repetition. In Reflection.hppAlthough I am using DERIVE_SERDE I think that part can be easily removed.
Maybe macros can be ignored for projects like our's but do you think will be hard to convert serdepp to c++14?
The biggest part of the c++17 -> c++14 task seems to be modifying all if constexpr statements to SFINAE. For example, the most easily changeable code in serdepp is:
C++17
template<typename T, typename serde_ctx, typename = void>
struct serde_serializer {
using Adaptor = typename serde_ctx::Adaptor;
template <typename = void>
constexpr inline static auto from(serde_ctx& ctx, T& data, std::string_view key) {
if constexpr(is_serdeable_v<serde_ctx, T>) {
if(key.empty()) {
serde_context struct_ctx = serde_context<Adaptor>{ctx.adaptor};
data.serde(struct_ctx, data);
} else {
serde_adaptor<Adaptor, T, type::struct_t>::from(ctx.adaptor, key, data);
}
} else {
serde_adaptor<Adaptor, std::remove_reference_t<T>>::from(ctx.adaptor, key, data);
}
ctx.read();
}
constexpr inline static auto into(serde_ctx& ctx, const T& data, std::string_view key) {
if constexpr(is_serdeable_v<serde_ctx, T>) {
if(key.empty()) {
auto struct_ctx = serde_context<Adaptor, true>(ctx.adaptor);
data.serde(struct_ctx, const_cast<T&>(data));
} else {
serde_adaptor<Adaptor, T, type::struct_t>::into(ctx.adaptor, key, data);
}
} else {
serde_adaptor<Adaptor, std::remove_reference_t<T>>::into(ctx.adaptor, key, data);
}
ctx.read();
}
};
C++14
template<typename T, typename serde_ctx, typename = void>
struct serde_serializer {
using Adaptor = typename serde_ctx::Adaptor;
template <typename = void>
constexpr inline static auto from(serde_ctx& ctx, T& data, std::string_view key) {
serde_adaptor<Adaptor, std::remove_reference_t<T>>::from(ctx.adaptor, key, data);
ctx.read();
}
constexpr inline static auto into(serde_ctx& ctx, const T& data, std::string_view key) {
serde_adaptor<Adaptor, std::remove_reference_t<T>>::into(ctx.adaptor, key, data);
ctx.read();
}
};
template<typename T, typename serde_ctx>
struct serde_serializer<T, serde_ctx, std::enable_if_t<is_serdeable_v<serde_ctx, T>>> {
using Adaptor = typename serde_ctx::Adaptor;
template <typename = void>
constexpr inline static auto from(serde_ctx& ctx, T& data, std::string_view key) {
if(key.empty()) {
serde_context struct_ctx = serde_context<Adaptor>{ctx.adaptor};
data.serde(struct_ctx, data);
} else {
serde_adaptor<Adaptor, T, type::struct_t>::from(ctx.adaptor, key, data);
}
ctx.read();
}
constexpr inline static auto into(serde_ctx& ctx, const T& data, std::string_view key) {
if(key.empty()) {
auto struct_ctx = serde_context<Adaptor, true>(ctx.adaptor);
data.serde(struct_ctx, const_cast<T&>(data));
} else {
serde_adaptor<Adaptor, T, type::struct_t>::into(ctx.adaptor, key, data);
}
ctx.read();
}
};
If you don't use if constexpr
, you'll see your code grow significantly.
As a result of roughly calculating the number of parts that use if constexpr
in serdepp, it seems to be about 76.
Converting all of this is expected to be a very difficult task.
Thank you so much for you politeness. I just realized the other problem will be for magic_enum and nameof libraries. They don't support c++14 :)
I've been working on a similar project in C++11 -> https://github.com/asherikov/ariles, it wont be usable in your case either though due to exceptions and excessive macro usage. There is also a C++98 enum library that may be useful -> https://github.com/aantron/better-enums, but it also relies on macro. If macro prohibition is a choice it is a bad one. ;(