These are chat archives for boostorg/hana

25th
Aug 2016
Louis Dionne
@ldionne
Aug 25 2016 01:17
@klemens-morgenstern You should be able to define your own comparison. LMC
First of all, you’d need ctti’s operator< to return a std::integral_constant (or a hana::bool_), not a straight bool.
Louis Dionne
@ldionne
Aug 25 2016 01:23
Secondly, you’ll have to provide a Hana tag for ctti, since this a “heterogeneous” type (a family of types that should all be considered the same “type” for Hana). You can do that by specializing hana::tag_of<ctti<…>>::type == whatever-you-want.
LMK if that doesn’t work.
Klemens Morgenstern
@klemens-morgenstern
Aug 25 2016 07:44
Ok, well I don't want to pull anything of that sort into boost.type_index, since I want to use it somewhere else. So I'll rather just go with my own predicate class.
Louis Dionne
@ldionne
Aug 25 2016 14:19
ok
Klemens Morgenstern
@klemens-morgenstern
Aug 25 2016 19:23

After looking into BOOST_HANA_STRINGI remembered, that I came up with a sort-of solution to define a static_string outside a class. Not pretty but it works (str has the member type, which is the static string):


template<char...C>
struct static_string
{
    static std::string str()
    {
        return {C...};
    }
};


template<std::size_t ...Indices>
struct seq {};

template<typename T, std::size_t>
struct push_back;

template<std::size_t ...Indices, std::size_t Value>
struct push_back<seq<Indices...>, Value>
{
    using type = seq<Indices..., Value>;
};

template<typename T, std::size_t Value>
using push_back_t = typename push_back<T, Value>::type; 

template<typename T, std::size_t Current, std::size_t Max>
struct make_sequence_impl
{
    using my = push_back_t<T, Current> ;
    using next = make_sequence_impl<my, Current+1, Max>;
    using type = typename next::type;
};

template<typename T, std::size_t Current>
struct make_sequence_impl<T, Current, Current>
{
    using type = push_back_t<T, Current> ;
};

template<std::size_t Size> 
using make_sequence = typename make_sequence_impl<seq<>, 0, Size>::type;

#define STR(Str)                                                                       \
struct                                                                                 \
{                                                                                      \
    using seq_t = make_sequence<sizeof(Str)-1>;                                        \
    template<std::size_t ... Indices>                                                  \
    constexpr static static_string<Str[Indices]...> make(seq<Indices...>) {return {};} \
                                                                                       \
    using type = decltype(make(seq_t()));                                              \
};                                                                                   \

using str = STR("MyString");

(run it here: http://ideone.com/MDpA3n)

So I could imagine to do something like this
using str = BOOST_HANA_STRING_TYPE("string"); //no idea how to do that.
BOOST_HANA_STRING_TYPE(str, "string"); //that would work.
Does anyone has an idea how to do the first? And: would you think that would be a good thing for hana?
Jason Rice
@ricejasonf
Aug 25 2016 19:30
I don't think it is possible without using a lambda.
Although outside of a class hmm...
Jason Rice
@ricejasonf
Aug 25 2016 19:35
Yeah, I can't see how it could be done.
the first part that is
@ldionne said that he was going to propose the use of lambdas in unevaluated contexts for C++17, but I don't know if it was even proposed or considered.
Louis Dionne
@ldionne
Aug 25 2016 19:39
The paper proposing lambdas in unevaluated contexts was rejected for C++17 because the wording was wrong.
I rewrote the wording and will be proposing it for C++20.
But regardless, the far better alternative is to standardize the literal operator template for string literals, for which I have also written a paper.
(For C++20)
Klemens Morgenstern
@klemens-morgenstern
Aug 25 2016 19:43

The first part does work already. But you can't write

using type = typename   struct {...}::type; 
//I.e.:
#define STR(Str) typename  struct {...}::type;

which is why I'd need something like that

#define STR(Id, Str) \
struct __##Id##__impl {}; \
using Id = typename  __##Id##__impl::type ;
You could then put this in a namespace or a class, but not a function.
@ldionne I sincerly hope that it becomes standard. Wasn't the literal operator also proposed for C++17? I actually don't get why a string-literal cannot be used as a template parameter.
Louis Dionne
@ldionne
Aug 25 2016 19:45
The literal operator was proposed in C++14 but rejected.
On what I argue is wrong basis
I’m not sure, but I think there were issues with acepting string literals as template parameters.
Since each literal has a unique address. I’m not sure anymore, you should do some archeology. I’m sure this has been discussed before.
And if there’s no reason not to support it, I encourage you to write a paper
Jason Rice
@ricejasonf
Aug 25 2016 19:48
It would be awesome to be able to do that.
Klemens Morgenstern
@klemens-morgenstern
Aug 25 2016 19:52
Ok, so would you think if the macro defines an additional type, but let's you define static string in an unevaluated context, that would fit into hana?
@ldionne Well, I think this is the issue: you would have to pass the string as a reference, making two equal declarations different. So you would need to use an alias here, analyze the string and than pass a back something like hana::string. Also you can pass a reference as a template parameter, if it has extern linkage; but that wouldn't allow you to analyze the value at compile-time. So the more I think about it, the more I guess there are good reasons.
Working with the literal operator is the much better approach here, I think. You wouldn't get the confusion.
Louis Dionne
@ldionne
Aug 25 2016 22:41
right