serdepp icon indicating copy to clipboard operation
serdepp copied to clipboard

C++14 Support?

Open thknx opened this issue 1 year ago • 5 comments

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.

thknx avatar Oct 26 '23 10:10 thknx

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?

injae avatar Oct 28 '23 08:10 injae

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?

thknx avatar Oct 30 '23 09:10 thknx

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.

injae avatar Oct 31 '23 15:10 injae

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 :)

thknx avatar Nov 09 '23 12:11 thknx

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. ;(

asherikov avatar Nov 19 '23 17:11 asherikov