boostorg / describe

A C++14 reflection library
https://boost.org/libs/describe
67 stars 24 forks source link

Changes signature of name() from char const* to char const[] #10

Open Julien-Blanc-tgcm opened 3 years ago

Julien-Blanc-tgcm commented 3 years ago

Signed-off-by: Julien Blanc julien.blanc@tgcm.eu

pdimov commented 3 years ago

Is sizeof(decltype(D.name)) - 1 really a lot easier than strlen(D.name)? There's the problem with the latter not always being constexpr, sure, but if you need portability (to something that doesn't support __builtin_strlen) you can trivially write your own strlen that will be.

pdimov commented 3 years ago

I show how a descriptor name is turned into a compile-time Hana string here: https://lists.boost.org/Archives/boost/2020/09/250046.php

Not sure how your compile-time string works, but it should be similar.

Julien-Blanc-tgcm commented 3 years ago

I was more thinking of a library like this one: https://github.com/akrzemi1/static_string . It provides direct construction from a char[], but not from a char const*

Sure, you can write some adapters, but what for? Unless I'm missing something, returning an array gives more information directly available. I see some benefits, and fails to see drawbacks with this change, since char[] can silently be decayed to char*.

pdimov commented 3 years ago

I'm not 100% sure this won't create problems for a built-in compiler implementation down the road. I know that __func__ is defined as an array and this causes trouble for compilers in constexpr contexts.

Julien-Blanc-tgcm commented 3 years ago

Ok, i can't tell either, i'm not a compiler writer. Maybe just keep that open until you can get a definitive answer on that point. Do you want me to create an issue ?

pdimov commented 3 years ago

I'll keep it open as a reminder.

I've been looking into implementing Describe on top of the current reflection proposals (P2320 and P1240) and at this point it's basically impossible because their consteval name_of function returns std::string, and there's no way to get a compile time char const* from there, not even a compile-time string_view. Perhaps the authors may be persuaded to switch to char const*, but I don't think a char const [] will ever be possible in their framework.

Julien-Blanc-tgcm commented 3 years ago

Wouldn't std::array be a better choice in this regard (at least it's better than an std::string) ? Obviously there's a miss for a vocabulary compile time string, as it is a needed feature for any compile time reflection feature.

pdimov commented 3 years ago

array isn't good because it's also not possible to get a string_view or char const* that's enough-constexpr from it (because the array returned from a function has automatic storage and we want to get a view/pointer to static storage from it.)

The original compile-time new proposal allowed compile-time allocations to survive compile-time and get converted into static storage automatically; this would have allowed a compile-time std::string to become a char const* to static const storage. I suppose that's why P1240 returns std::string - it was designed with this ability in mind. But this feature didn't make it into C++20 because of implementation difficulties.

At the moment I think that char const* is the least worst alternative as it can cross all bridges, maybe not very conveniently, but at least it's possible.

beached commented 2 years ago

So I ran into this. I use CNTTP/NTTP for my library and string literals cannot be used there. I had to work around like

template<typename, typename>
        struct describe_member_impl;

        template<typename T, std::size_t... Is>
        struct describe_member_impl<T, std::index_sequence<Is...>> {
            static constexpr char const name[sizeof...( Is )]{ T::name[Is]... };
            using type = json_link<name, traits::member_type_of_t<DAW_TYPEOF( T::pointer )>>;
        };

        template<typename T>
        using describe_member =
          describe_member_impl<T,
                               std::make_index_sequence<std::char_traits<char>::length( T::name ) + 1>>;

Another nice addition to T::pointer, T::type or something like that.