Skip to content

Instantly share code, notes, and snippets.

@fbaeuerlein
Last active February 11, 2019 19:55
Show Gist options
  • Save fbaeuerlein/2e0a3134c12e76cea62bb16f13c4a5c7 to your computer and use it in GitHub Desktop.
Save fbaeuerlein/2e0a3134c12e76cea62bb16f13c4a5c7 to your computer and use it in GitHub Desktop.
Config-Class that supports adding of config item member functions during compile time with macros and uses C++ member initialization order to read and release the document on construction
#include <iostream>
#include <string>
// uses the initialization ordering of c++ to construct members, based on previously created member (document)
// that will be released within the constructor body
// http://en.cppreference.com/w/cpp/language/initializer_list
// this is what should be released after initialization was done
struct Document
{
int extract_value() { return 1234; }
};
#define ADD_CONFIG_ITEM(ITEM_TYPE, ITEM_NAME)\
private: ConfigItem<ITEM_TYPE> m_config_item_ ## ITEM_NAME = { *this };\
public: ITEM_TYPE get_ ## ITEM_NAME () const noexcept { return m_config_item_ ## ITEM_NAME.get_value(); }
class Config
{
private:
// document to extract values from
Document * m_document;
template<typename T>
struct ConfigItem
{
// constructor gets document member from Config and extracts it's value
// the value will be stored internally and then it's available forever
ConfigItem(Config const & conf) : value(conf.m_document->extract_value()) {}
// add constructor with additional default value
T const & get_value() const noexcept { return value; }
T const value;
};
public:
// maybe use shared_ptr or unique instead
Config(Document * d)
: m_document(d)
{
// members of values should be extracted through member default initialization
// so delete should be safe because noone else is using it anymore
delete d;
std::cout << "d was deleted" << std::endl;
}
// add config items here
// member will be default initialized BEFORE constructor body of Config will be executed
ConfigItem<int> m_mem = { *this }; // initialize with this to get the previously initialized m_document member
ADD_CONFIG_ITEM(int, test_item1);
ADD_CONFIG_ITEM(int, test_some_very_long_item1);
};
int main()
{
auto d = new Document();
Config c(d);
std::cout << c.m_mem.get_value() << std::endl;
std::cout << c.get_test_item1() << std::endl;
std::cout << c.get_test_some_very_long_item1() << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment