Boost logo

Boost :

Subject: Re: [boost] sqlpp11, 3rd iteration
From: Adam Wulkiewicz (adam.wulkiewicz_at_[hidden])
Date: 2014-08-19 12:56:24


Roland Bock wrote:
> On 2014-08-19 16:43, Adam Wulkiewicz wrote:
>> I'm wondering, could it be possible to implement similar, compile-time
>> interface in sqlpp, e.g. something similar to MPL?
>> I'm asking because what the sqlpp library requires is very
>> complicated:https://github.com/rbock/sqlpp11/blob/master/tests/Sample.h
>> I'm aware that its purpose is to create a type reflecting required
>> columns and to use them from the level of C++ but couldn't it be done
>> simpler?
> The crucial part is the _member_t template. I need that one. The other
> stuff can be constructed whatever way you like. But if the name of the
> column is `beta`, then I need a way to get this:
>
> template<typename T>
> struct _member_t
> {
> T beta;
> T& operator()() { return beta; }
> const T& operator()() const { return beta; }
> };
>
> This is the magic ingredient that makes tables, result rows and
> parameter sets of prepared statements to have members with a proper name.
>
> The way it works is best to be observed in the table_t template, see
> https://github.com/rbock/sqlpp11/blob/master/include/sqlpp11/table.h
>
> template<typename Table, typename... ColumnSpec>
> struct table_t
> : public table_base_t,
> public ColumnSpec::_name_t
> ::template _member_t<column_t<Table, ColumnSpec>>...

Ok AFAIU a struct like _member_t should define some convenient member
variable for the user and must define operator() for the library.
But the rest could be automatically generated, couldn't it?
Why not just pass a list of templates of classes adapted to MemberType
concept (defined operator()) into the table/column/etc.?
I'm thinking about something like the code below. I don't know exactly
what's required so this is just an example of a technique rather than a
solution ready-to-use in sqlpp.

namespace sqlpp {

template <template <typename> class Table>

struct table_t {/*all that's required*/};

template <template <typename> class Table,

           template <typename> class Member>

struct column_t {/*all that's required*/};

template <template <typename> class Table,

           template <typename> class... Members>

struct table

     : public Table< table_t<Table> >

     , public Members< column_t<Table, Members> >...

{};

}

template <typename T>

struct alpha_member

{

     T alpha;

     T& operator()() { return alpha; }

     const T& operator()() const { return alpha; }

};

template <typename T>

struct beta_member

{

     T beta;

     T& operator()() { return beta; }

     const T& operator()() const { return beta; }

};

template <typename T>

struct tab_table

{

     T tab;

     T& operator()() { return tab; }

     const T& operator()() const { return tab; }

};

struct my_tab

     : sqlpp::table<tab_table, alpha_member, beta_member>

{};

intmain()

{

     my_tab t;

}

which could be shortened to:

#defineSQLPP_NAME(NAME,MEMBER)template<typenameT>structNAME{/*...*/}

SQLPP_NAME(gamma_member,gamma);
SQLPP_NAME(delta_member,delta);
SQLPP_NAME(other_table,other);

structmy_other_tab
:sqlpp::table<other_table,gamma_member,delta_member>
{};

So here only the names would have to be "registered" and the rest would
be handled by the compiler.
Could a technique similar to the above be used in the case of sqlpp?

> For each column, the table inherits from the column's _member_t which is
> instantiated with the column itself. This adds a member of the column's
> type and the column's name to the table.
The same as above, table is inherited from Table and all passed Members.
The thing is to allow the user to implement only the required part and
generate the rest automatically.

> I see no way to create such a template other than having it in the code.
> You should of course not write it personally. You should use macros
> (yuk) or code generators similar to the ddl2cpp script in the
> repository. But you have to somehow create this code.
>
> Unless you know some brilliant TMP technique for this?
> Personally I think that is a missing feature in C++. I'd call it named
> member mixin. Or something like that. Hmm.
> Or, in addition to names and values, we should be able to declare names
> in templates. That would be awesome!
>
> Anyway, if the name thing can be solved without macros, I am all for a
> terser notation :-)

Maybe in one of the future standards... :)

Regards,
Adam


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