Boost logo

Boost :

Subject: Re: [boost] [Hana] Migrating sqlpp11 to Hana (hypothetically)
From: Roland Bock (rbock_at_[hidden])
Date: 2015-06-16 02:16:09


On 2015-06-15 21:08, Louis Dionne wrote:
> Roland Bock <rbock <at> eudoxos.de> writes:
>
>> [...]
>>
>> _Compile__time strings:_
>> This one seems easy. There probably won't be a C++14 version of sqlpp11,
>> but there will be a C++17 version, hopefully allowing me to use the
>> string literal without relying on a non-standard compiler extension.
>>
>> This is what I currently have [2]:
>>
>> struct _alias_t
>> {
>> static constexpr const char _literal[] = "delta";
>> using _name_t = sqlpp::make_char_sequence<sizeof(_literal),
>> _literal>;
>> };
>>
>> This is what I would like to do:
>>
>> struct _alias_t
>> {
>> using _name_t = decltype("delta"_s);
>> };
>>
>> But the whole thing is in a header.
>>
>> * I do not want to "using namespace ::boost::hana::literals" at
>> top-level or in one of the namespaces in the header.
> Is it acceptable to only import the `_s` string literal from Hana?
>
> using boost::hana::literals::operator""_s;
Not really. This code has to be provided by the user of the library. It
lives outside the sqlpp namespace. I cannot just tell them, to please
import some string literal into their namespace.

It would be acceptable, if I could just do it inside a struct, but this
is illegal:

struct A
{
    using boost::hana::literals::operator""_s;
};

I could use a function instead of a type and then use decltype when I
want the type of the name.

struct A
{
  static constexpr auto test()
  {
    using boost::hana::literals::operator""_s;
    return "cheesecake"_s;
  }
};

I will let this sink in a bit...

>> [...]
>> * I also cannot use the BOOST_HANA_STRING macro, btw, because that
>> would be a lambda in a decltype...
> Yeah, the decltype + lambda restriction is annoying. Frankly, I don't know of
> any way to use UDLs from another namespace without importing them, and I'm
> not sure it's feasible.
That would be annoying. In the end, they are functions, aren't they. If
it is not possible yet, it should be so in the next standard...

I asked on the standard proposal list if there is anything like that
available or proposed yet. [1]

>
>> _type sets:_
>> Currently I store a bunch of types in type sets to do all kinds of tests
>> at compile time. My type set code will need some cleanup or replacement
>> one fine day. Hana to the rescue...
>>
>> Er, wait a second. There is no type set, or is there? There is a set for
>> objects (which might represent types). Replacing all those types with
>> objects would take some time, but I could live with that, I guess. But
>> then I would have to replace all my type_sets (which are types
>> themselves) with static constexpr objects, which use tons of constexpr
>> template variables. And there are other constructs which use the types I
>> now have replaced with objects. So I would have to adjust them, too,
>> probably turning even more types into objects.
> In theory, that would be the "right" way to do it. What Hana is proposing
> is a completely new metaprogramming paradigm. However, in practice, it's
> usually possible to isolate the part of the system using Hana from the rest
> of the system, or to have Hana interoperate with the rest of the system in
> some way. I would say this is something that must be handled on a
> case-per-case basis.
>
> For an example of a code base that was partially adapted to Hana with
> success, see this fork [1] of the Units-BLAS library by Zach Laine.
>
>
>> Can I be sure (given today's compilers) that all these objects stay
>> away from the generated binary?
> I guess you can't be __sure__ of it. My view on this is that as long as
> the objects are very small (they're basically empty) and constexpr, the
> compiler should be able to optimize it away. If that's not the case, and
> if this paradigm turns out to be as great as I advertise, perhaps compiler
> writers will have more incentive to apply such optimizations. Also, it is
> possible that the language will evolve in the direction of making these
> things easier.
>
> However, in practice, you can usually ensure that no objects are generated
> at all by doing your computations in a function with value-level syntax, and
> then using `decltype` on the result of that function. For example, here's
> something taken from the Units-BLAS code I linked above. Here's the original
> code (edited for simplicity):
[...]

> The trick is to enclose your value-level computations inside functions, and
> then use decltype on your functions to ensure they are never actually called.
> In practice, doing this in a non-messy way must be studied in a case-per-case
> basis, or at least I don't have clear guidelines for now.
That is a very nice approach for partially migrating (and as you said it
might also increase the likelihood that there are no leftovers in the
resulting binaries).

Thanks for the detailed reply!
>> Also, I did not find some of the methods I would expect for sets:
>>
>> * Create a joined set
>> * Create an intersect set
>> * Create a difference set
>> * Test if two sets are disjunct
>> * Test if A is a subset of B, no, strike that, just found it in Searchable
>>
>> I probably could create the methods above with just a few lines of code
>> using the available functions. But it would be convenient to have them
>> available, of course (or did I just miss them?).
> This is a simple oversight. Like I said elsewhere, the associative sequences
> (Set and Map) are still very naive and their interface is incomplete. So far,
> I have focused on the simplest and most frequently used structure, Tuple.
> I added this issue [2] to remind me of these missing functions.
Great :-)
>
>
>> By the way, I guess it would be easy for you to compile a list of
>> available methods for each type, e.g. Set. Such a mini-index would be
>> quite helpful IMO.
> Good idea. It would be a pain with my current Doxygen setup, but I think
> I'm about to break up with Doxygen anyway. I noted your idea in this
> issue [3].
Looking forward to it.

>
>
>> _any/all/none:
>> _Quite a bit of code is tuned to stuff like std::is_same: a type that
>> contains a value (true or false). My current versions of any/all/none
>> work like that, too.
>>
>> If I wanted to get rid of my own versions, could I use a drop-in from
>> hana? Or would I have to write something like
>>
>> template<bool... B>
>> struct my_all
>> {
>> static constexpr bool value =
>> ::boost::hana::all(::boost::hana::make_tuple(B...));
>> };
> The best way would be this:
>
> hana::all(hana::tuple_c<bool, b...>)
>
> This would return a boolean IntegralConstant (which is convertible to bool).
> This could also be made just as efficient as your clever implementation using
> std::is_same (that you posted on the list a while ago), because we have the
> knowledge that the content of the tuple are compile-time bools. However,
> using `hana::all(hana::make_tuple(b...))` will be comparatively __very__
> inefficient, because we can't know what's in the tuple and we must guarantee
> proper short-circuiting.
Oh, because the it could be tuple_t<bool, Foo> and you still want this
to work in case it short-circuits in the bool element?

If so, that sounds quite strange to me.

>
>
>> _Intermediate summary:_
>>
>> * I am not sure if I could replace my current compile-time string yet
> It depends on which compromises you are willing to do. As far as I know,
> you can't do it properly without using the GNU string-literal extension.
> Oh wait, I could also write a macro similar to BOOST_MPLLIBS_STRING from
> Metaparse, but that wouldn't be very C++14ish.
No worries. The current way is OK, and in the long run, I want
name-literals anyway [2] :-)
>
>
>> * I would like to have a few more convenience methods for Set.
> You will get that and much more by the end of the summer, or I won't
> get my GSoC T-shirt. :-)
Lol, that is a great incentive!
>
>
>> * It seems to me like if I wanted to use Hana, I should switch to
>> Hana-style completely. Otherwise it will just be a weird mixture.
> Mixing Hana and classic metaprogramming is indeed very difficult for things
> that have to travel a lot in your interface (e.g. compile-time strings that
> are exposed to the user). This is simply because Hana is such a different
> paradigm that if you want your interface to be Hana-like, then you must
> do it all in this way. However, you can still use Hana under the hood to
> simplify some metaprogramming locally while keeping your interface as-is.
> This is essentially what was done in the Units-BLAS project. But of course,
> the benefit of using Hana will then be limited to those local simplifications.
>
> I would be very curious to try and port sqlpp11 to Hana. If you ever want
> to give it a shot, please let me know. However, that will have to wait for
> a while because I'm neck deep right now.
Yes, I am also curious to give it a try. Preferably in combination with
Concepts Lite. Oh, that reminds me, I found a serious conceptual problem
in ConceptsLite with template-template parameters (at least I think I
did). Need to check on that with Andrew Sutton again...

I am also drowning in work at the moment. I'll let you know when I get
started :-)

Cheers,

Roland
[1]
https://groups.google.com/a/isocpp.org/forum/?fromgroups#!topic/std-proposals/hAnVRTlsQZY
[2]
https://groups.google.com/a/isocpp.org/forum/#!msg/std-proposals/hYh3hWB0mwg/mDgCErbUXbMJ


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk