Skip to content

Instantly share code, notes, and snippets.

@matthiasvegh
Created September 27, 2015 00:36
Show Gist options
  • Save matthiasvegh/87e965011455381237e4 to your computer and use it in GitHub Desktop.
Save matthiasvegh/87e965011455381237e4 to your computer and use it in GitHub Desktop.
Creating classes with publicly visible bases
#define BOOST_PP_VARIADICS 1
#include <boost/mpl/vector.hpp>
#include <iostream>
#include <memory>
#include <typeinfo>
#include <boost/preprocessor.hpp>
#define GETCLASS(elem) BOOST_PP_SEQ_HEAD(elem)
#define GETACCESS(elem) \
BOOST_PP_IF(BOOST_PP_EQUAL(BOOST_PP_SEQ_SIZE(elem), 2), \
BOOST_PP_SEQ_HEAD(BOOST_PP_SEQ_REVERSE(elem)), private)
#define GETCOMPLETEDECL(d, data, elem) GETACCESS(elem) GETCLASS(elem)
#define GETONLYCLASSNAME(d, data, elem) GETCLASS(elem)
#define LISTOFCLASSNAMES(OPERATION, ...) \
BOOST_PP_LIST_ENUM(BOOST_PP_LIST_TRANSFORM( \
OPERATION, _, BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)))
#define DEFINECLASSWITHBASES(className, ...) \
class className : LISTOFCLASSNAMES(GETCOMPLETEDECL, __VA_ARGS__) { \
public: \
using Bases = boost::mpl::vector< \
LISTOFCLASSNAMES(GETONLYCLASSNAME, __VA_ARGS__)>; \
\
private:
#define DEFINECLASSWITHBASESEND() }
struct Base1 {
Base1() { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
};
struct Base2 {
Base2() { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
};
struct Base3 {
Base3() { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
};
DEFINECLASSWITHBASES(A, (Base1), (Base2))
public:
void operator()() const { std::cerr << __PRETTY_FUNCTION__ << std::endl; }
DEFINECLASSWITHBASESEND();
DEFINECLASSWITHBASES(B, (Base1), (Base2), (Base3))
public:
DEFINECLASSWITHBASESEND();
DEFINECLASSWITHBASES(C, (Base1)(public), (Base2))
public:
DEFINECLASSWITHBASESEND();
int main() {
static_assert(
std::is_same<boost::mpl::vector<Base1, Base2>, A::Bases>::value, "");
static_assert(
std::is_same<boost::mpl::vector<Base1, Base2, Base3>, B::Bases>::value,
"");
std::shared_ptr<Base1> c = std::make_shared<C>();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment