Следующий код может быть началом реализации ORM, но я застрял (никаких сюрпризов) в некоторых аспектах метапрограммирования. Нижеприведенный код будет началом разработки классов, которые могут создавать свои таблицы (а затем читать и писать их строки). Но я уже получаю злой «отжим палача» в этой вложенной табличной декларации в основном (любой хочет связать этот xkcd комикс об этом ???). Поэтому я хотел бы изменить этот вложенный формат на плоский список, используя пакет аргументов вариационного шаблона.Использование вариационного шаблона для преобразования вложенного списка типов в плоский список типов
Как изменить вложенный список вершин в основном на плоский список с использованием вариативных шаблонов?
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;
struct nil {
static const string create() {return string("");}
};
struct required {};
struct optional {};
template <const char* nm,typename req=required>
struct serial {
static const string create() {return string(nm)+" INTEGER PRIMARY KEY NOT NULL";}
};
template <const char* nm,typename req=required>
struct integer {
static const string create() {return string(nm)+" INTEGER NOT NULL";}
};
template <const char* nm>
struct integer<nm,optional> {
static const string create() {return string(nm)+" INTEGER";}
};
template<typename car,typename cdr>
struct cons {
static const string create() {
return
string("\t")
+car::create()
+",\n"
+cdr::create();
}
};
template<typename car>
struct cons<car,nil> {
static const string create() {
return
string("\t")+car::create();
}
};
template<typename DDL>
struct table {
static const string create() {
return
string("CREATE TABLE (\n")
+DDL::create()
+"\n);";
}
};
namespace fields {
const char id[]="id";
const char someint[]="someint";
const char someint2[]="someint2";
};
int main(int argc,char* argv[]) {
typedef table<
cons<serial<(const char*)fields::id>,
cons<integer<(const char*)fields::someint>,
cons<integer<
(const char*)fields::someint2,optional>,nil
>
>
>
> test;
cout << test::create() << endl;
return 0;
}
Вместо:
typedef table<
cons<serial<(const char*)fields::id>,
cons<integer<(const char*)fields::someint>,
cons<integer<
(const char*)fields::someint2,optional>,nil
>
>
>
> test;
Я хотел бы быть в состоянии использовать:
typedef table<
list<
serial<(const char*)fields::id>,
integer<(const char*)fields::someint>,
integer<(const char*)fields::someint2,optional>
>
> test;
есть способ для этого расширитель знать список его индекс? –
@BrianJack да, используя 'index_sequence' –
@BrianJack, где вам нужны те индексы, которые нужно разместить? –