I have a class named databaseManager that can open protected and shared database. You can know that a database is protected if it's name starts with a "#". I also have two methods:
openProtectedDatabase(QString name)
(private method)openSharedDatabase(QString name)
(public method)since 99.99% of the time the user is going to use openSharedDatabase
like that:
openSharedDatabase("I_m_a_database")
I want in this specific case to check at compile time that he has the right to do it (understand no "#"
at the beginning of the string). so I can throw an error immediately.
Here is what I started to do:
bool DatabaseManager::isDatabaseProtected(QString name) {
return name[0] == '#';
}
CollaoDatabase &DatabaseManager::openSharedDatabase(QString name){
//if a static assertion is possible
//static_assert(static_assertion_possible(name) && isDatabaseProtected(name), "this database name is protected")
//run time check
if (isDatabaseProtected(name)) {
qWarning() << name + " is a protected database";
return nullptr;
}
return openProtectedDatabase(name);
}
Ok thanks to you advices, I finally got something that do (kind of) what I wanted to do. I used the answer of this question: Conveniently Declaring Compile-Time Strings in C++ to create a compile-time character sequence and now have two overloads:
template <typename ct_str> inline CollaoDatabase &openSharedDatabase()
inline CollaoDatabase openSharedDatabase(QString name)
the first is used like this (this one do a static assert):
openSharedDatabase<CT_STR("#I_m_a_protected_name")>();
and the second like this (this one do a runtime check instead):
openSharedDatabase("Hithere");
Here is the code:
#define MACRO_GET_1(str, i) \
(sizeof(str) > (i) ? str[(i)] : 0)
#define MACRO_GET_4(str, i) \
MACRO_GET_1(str, i+0), \
MACRO_GET_1(str, i+1), \
MACRO_GET_1(str, i+2), \
MACRO_GET_1(str, i+3)
#define MACRO_GET_16(str, i) \
MACRO_GET_4(str, i+0), \
MACRO_GET_4(str, i+4), \
MACRO_GET_4(str, i+8), \
MACRO_GET_4(str, i+12)
#define MACRO_GET_64(str, i) \
MACRO_GET_16(str, i+0), \
MACRO_GET_16(str, i+16), \
MACRO_GET_16(str, i+32), \
MACRO_GET_16(str, i+48)
#define CT_STR(str) ct_string<MACRO_GET_64(str, 0), 0>
template <char firstL, char... letters>
struct ct_string{
static char const * c_str() {
static constexpr char string[]={firstL, letters...,'\0'};
return string;
}
static constexpr char first() {
return firstL;
}
};
inline bool isDatabaseProtected(QString name){
return name[0] == '#';
}
template<typename ct_str> static constexpr inline bool isDatabaseProtected() {
return ct_str::first() == '#';
}
inline CollaoDatabase &openSharedDatabase(QString name){
if (isDatabaseProtected(name)) {
qWarning() << name + " is a protected database";
}
return openProtectedDatabase(name);
}
template <typename ct_str> inline CollaoDatabase &openSharedDatabase() {
static_assert(!isDatabaseProtected<ct_str>(), "you are trying to open a protected database");
return openProtectedDatabase(QString(ct_str::c_str()));
}