#include <string>
#include <iostream>
#include <type_traits>
// Forward declaration for our "default values" class.
class CQQC;
namespace detail {
// String wrapper, convertible to std::string.
class literal_string {
const char* const str;
size_t sz; // Currently not needed, but useful if additional functionality is desired.
static constexpr size_t length(const char* const str_) {
return *str_ ? 1 + length(str_ + 1) : 0;
}
public:
template<size_t N>
constexpr literal_string(const char (&str_)[N])
: str(str_), sz(N - 1) { }
constexpr literal_string(const char* const str_)
: str(str_), sz(length(str_)) { }
operator std::string() const {
return std::string(str);
}
};
// Generic "default values" type, specialise for each class.
template<typename>
struct Defaults_;
// Defaults for CQQC.
template<>
struct Defaults_<::CQQC> {
int i, j, k;
literal_string str;
/*
template<size_t N = 12>
constexpr Defaults_(int i_ = 0,
int j_ = 42,
int k_ = 359,
const char (&str_)[N] = "Hey, y'all!")
: i(i_), j(j_), k(k_), str(str_) { }
*/
constexpr Defaults_(int i_ = 0,
int j_ = 42,
int k_ = 359,
const char* const str_ = "Hey, y'all!")
: i(i_), j(j_), k(k_), str(str_) { }
};
} // namespace detail
// Boilerplate macro.
#define MAKE_DEFAULTS(Class) \
constexpr static ::detail::Defaults_<Class> Defaults = ::detail::Defaults_<Class>()
class CQQC {
static_assert(std::is_literal_type<detail::Defaults_<CQQC>>::value,
"Default value holder isn't a literal type.");
MAKE_DEFAULTS(CQQC);
// Expands to:
// constexpr static ::detail::Defaults_<CQQC> Defaults = ::detail::Defaults_<CQQC>();
int i, j, k;
std::string str;
public:
// Allows the user to specify that they want the default value.
enum Flags { DEFAULT };
// Initialise to defaults, unless otherwise specified.
CQQC(int i_ = Defaults.i,
int j_ = Defaults.j,
int k_ = Defaults.k,
std::string str_ = Defaults.str)
: i(i_), j(j_), k(k_), str(str_) {}
bool isDefault() {
return (i == Defaults.i &&
j == Defaults.j &&
k == Defaults.k &&
str == Defaults.str.operator std::string());
}
void set_i(int i_) { i = i_; }
// Set to default.
void set_i(Flags f_) {
if (f_ == Flags::DEFAULT) { i = Defaults.i; }
}
// And so on...
};
constexpr detail::Defaults_<CQQC> CQQC::Defaults;
int main() {
CQQC c1(4);
CQQC c2;
if (c1.isDefault()) {
std::cout << "c1 has default values.\n";
} else {
std::cout << "c1 is weird.\n";
}
if (c2.isDefault()) {
std::cout << "c2 has default values.\n";
} else {
std::cout << "c2 is weird.\n";
}
c1.set_i(CQQC::DEFAULT);
if (c1.isDefault()) {
std::cout << "c1 now has default values.\n";
} else {
std::cout << "c1 is still weird.\n";
}
}
I2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dHlwZV90cmFpdHM+CgovLyBGb3J3YXJkIGRlY2xhcmF0aW9uIGZvciBvdXIgImRlZmF1bHQgdmFsdWVzIiBjbGFzcy4KY2xhc3MgQ1FRQzsKCm5hbWVzcGFjZSBkZXRhaWwgewogICAgLy8gU3RyaW5nIHdyYXBwZXIsIGNvbnZlcnRpYmxlIHRvIHN0ZDo6c3RyaW5nLgogICAgY2xhc3MgbGl0ZXJhbF9zdHJpbmcgewogICAgICAgIGNvbnN0IGNoYXIqIGNvbnN0IHN0cjsKICAgICAgICBzaXplX3Qgc3o7IC8vIEN1cnJlbnRseSBub3QgbmVlZGVkLCBidXQgdXNlZnVsIGlmIGFkZGl0aW9uYWwgZnVuY3Rpb25hbGl0eSBpcyBkZXNpcmVkLgoKICAgICAgICBzdGF0aWMgY29uc3RleHByIHNpemVfdCBsZW5ndGgoY29uc3QgY2hhciogY29uc3Qgc3RyXykgewogICAgICAgICAgICByZXR1cm4gKnN0cl8gPyAxICsgbGVuZ3RoKHN0cl8gKyAxKSA6IDA7CiAgICAgICAgfQoKICAgICAgcHVibGljOgogICAgICAgIHRlbXBsYXRlPHNpemVfdCBOPgogICAgICAgIGNvbnN0ZXhwciBsaXRlcmFsX3N0cmluZyhjb25zdCBjaGFyICgmc3RyXylbTl0pCiAgICAgICAgICA6IHN0cihzdHJfKSwgc3ooTiAtIDEpIHsgfQoKICAgICAgICBjb25zdGV4cHIgbGl0ZXJhbF9zdHJpbmcoY29uc3QgY2hhciogY29uc3Qgc3RyXykKICAgICAgICAgIDogc3RyKHN0cl8pLCBzeihsZW5ndGgoc3RyXykpIHsgfQoKICAgICAgICBvcGVyYXRvciBzdGQ6OnN0cmluZygpIGNvbnN0IHsKICAgICAgICAgICAgcmV0dXJuIHN0ZDo6c3RyaW5nKHN0cik7CiAgICAgICAgfQogICAgfTsKCiAgICAvLyBHZW5lcmljICJkZWZhdWx0IHZhbHVlcyIgdHlwZSwgc3BlY2lhbGlzZSBmb3IgZWFjaCBjbGFzcy4KICAgIHRlbXBsYXRlPHR5cGVuYW1lPgogICAgc3RydWN0IERlZmF1bHRzXzsKCiAgICAvLyBEZWZhdWx0cyBmb3IgQ1FRQy4KICAgIHRlbXBsYXRlPD4KICAgIHN0cnVjdCBEZWZhdWx0c188OjpDUVFDPiB7CiAgICAgICAgaW50IGksIGosIGs7CiAgICAgICAgbGl0ZXJhbF9zdHJpbmcgc3RyOwoKLyoKICAgICAgICB0ZW1wbGF0ZTxzaXplX3QgTiA9IDEyPgogICAgICAgIGNvbnN0ZXhwciBEZWZhdWx0c18oaW50IGlfID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBqXyA9IDQyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGtfID0gMzU5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAoJnN0cl8pW05dID0gIkhleSwgeSdhbGwhIikKICAgICAgICAgIDogaShpXyksIGooal8pLCBrKGtfKSwgc3RyKHN0cl8pIHsgfQoqLwogICAgCiAgICAgICAgY29uc3RleHByIERlZmF1bHRzXyhpbnQgaV8gPSAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGpfID0gNDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQga18gPSAzNTksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyKiBjb25zdCBzdHJfID0gIkhleSwgeSdhbGwhIikKICAgICAgICAgIDogaShpXyksIGooal8pLCBrKGtfKSwgc3RyKHN0cl8pIHsgfQogICAgfTsKfSAvLyBuYW1lc3BhY2UgZGV0YWlsCgovLyBCb2lsZXJwbGF0ZSBtYWNyby4KI2RlZmluZSBNQUtFX0RFRkFVTFRTKENsYXNzKSBcCiAgICBjb25zdGV4cHIgc3RhdGljIDo6ZGV0YWlsOjpEZWZhdWx0c188Q2xhc3M+IERlZmF1bHRzID0gOjpkZXRhaWw6OkRlZmF1bHRzXzxDbGFzcz4oKQogICAgCmNsYXNzIENRUUMgewogICAgc3RhdGljX2Fzc2VydChzdGQ6OmlzX2xpdGVyYWxfdHlwZTxkZXRhaWw6OkRlZmF1bHRzXzxDUVFDPj46OnZhbHVlLAogICAgICAgICAgICAgICAgICAiRGVmYXVsdCB2YWx1ZSBob2xkZXIgaXNuJ3QgYSBsaXRlcmFsIHR5cGUuIik7CgogICAgTUFLRV9ERUZBVUxUUyhDUVFDKTsKICAgIC8vIEV4cGFuZHMgdG86CiAgICAvLyBjb25zdGV4cHIgc3RhdGljIDo6ZGV0YWlsOjpEZWZhdWx0c188Q1FRQz4gRGVmYXVsdHMgPSA6OmRldGFpbDo6RGVmYXVsdHNfPENRUUM+KCk7CgogICAgaW50IGksIGosIGs7CiAgICBzdGQ6OnN0cmluZyBzdHI7CgogIHB1YmxpYzoKICAgIC8vIEFsbG93cyB0aGUgdXNlciB0byBzcGVjaWZ5IHRoYXQgdGhleSB3YW50IHRoZSBkZWZhdWx0IHZhbHVlLgogICAgZW51bSBGbGFncyB7IERFRkFVTFQgfTsKCiAgICAvLyBJbml0aWFsaXNlIHRvIGRlZmF1bHRzLCB1bmxlc3Mgb3RoZXJ3aXNlIHNwZWNpZmllZC4KICAgIENRUUMoaW50IGlfID0gRGVmYXVsdHMuaSwKICAgICAgICAgaW50IGpfID0gRGVmYXVsdHMuaiwKICAgICAgICAgaW50IGtfID0gRGVmYXVsdHMuaywKICAgICAgICAgc3RkOjpzdHJpbmcgc3RyXyA9IERlZmF1bHRzLnN0cikKICAgICAgOiBpKGlfKSwgaihqXyksIGsoa18pLCBzdHIoc3RyXykge30KCiAgICBib29sIGlzRGVmYXVsdCgpIHsKICAgICAgICByZXR1cm4gKGkgICA9PSBEZWZhdWx0cy5pICYmCiAgICAgICAgICAgICAgICBqICAgPT0gRGVmYXVsdHMuaiAmJgogICAgICAgICAgICAgICAgayAgID09IERlZmF1bHRzLmsgJiYKICAgICAgICAgICAgICAgIHN0ciA9PSBEZWZhdWx0cy5zdHIub3BlcmF0b3Igc3RkOjpzdHJpbmcoKSk7CiAgICB9CgogICAgdm9pZCBzZXRfaShpbnQgaV8pIHsgaSA9IGlfOyB9CgogICAgLy8gU2V0IHRvIGRlZmF1bHQuCiAgICB2b2lkIHNldF9pKEZsYWdzIGZfKSB7CiAgICAgICAgaWYgKGZfID09IEZsYWdzOjpERUZBVUxUKSB7IGkgPSBEZWZhdWx0cy5pOyB9CiAgICB9CgogICAgLy8gQW5kIHNvIG9uLi4uCn07CmNvbnN0ZXhwciBkZXRhaWw6OkRlZmF1bHRzXzxDUVFDPiBDUVFDOjpEZWZhdWx0czsKCmludCBtYWluKCkgewoJQ1FRQyBjMSg0KTsKCUNRUUMgYzI7CgkKCWlmIChjMS5pc0RlZmF1bHQoKSkgewoJCXN0ZDo6Y291dCA8PCAiYzEgaGFzIGRlZmF1bHQgdmFsdWVzLlxuIjsKCX0gZWxzZSB7CgkJc3RkOjpjb3V0IDw8ICJjMSBpcyB3ZWlyZC5cbiI7Cgl9CgkKCWlmIChjMi5pc0RlZmF1bHQoKSkgewoJCXN0ZDo6Y291dCA8PCAiYzIgaGFzIGRlZmF1bHQgdmFsdWVzLlxuIjsKCX0gZWxzZSB7CgkJc3RkOjpjb3V0IDw8ICJjMiBpcyB3ZWlyZC5cbiI7Cgl9CgoJYzEuc2V0X2koQ1FRQzo6REVGQVVMVCk7CglpZiAoYzEuaXNEZWZhdWx0KCkpIHsKCQlzdGQ6OmNvdXQgPDwgImMxIG5vdyBoYXMgZGVmYXVsdCB2YWx1ZXMuXG4iOwoJfSBlbHNlIHsKCQlzdGQ6OmNvdXQgPDwgImMxIGlzIHN0aWxsIHdlaXJkLlxuIjsKCX0KfQ==