1

I have an existing codebase that makes fairly good use of Boost. In particular, it uses different flavours of boost::variant in a few places:

typedef boost::variant<double, int, unsigned int, size_t, bool> MBVariant;
typedef boost::variant<double, float> FPVariant;
// ...

It also uses other Boost facilities like:

typedef boost::shared_ptr<int> MyPtr;

I am porting this code to a new platform that does not support Boost, but must be maintained alongside a platform that does. I am therefore creating a "Boost-wrapping" layer that will help remove the Boost dependency:

#ifdef USE_BOOST
# include <boost/shared_ptr.hpp>
# include <boost/variant.hpp>

template <class T>
using my_shared_ptr = boost::shared_ptr<T>

// how to wrap variant?
// template <typename T0_, BOOST_VARIANT_ENUM_SHIFTED_PARAMS(typename T)>
// using my_variant = boost::variant<T0_, ???>;

#else
# include <memory>

// in the absence of Boost, use something else like std::shared_ptr:
template <class T>
using my_shared_ptr = std::shared_ptr<T>

// wrap variant with something non-Boost
template <typename T0, /* uh... */>
class variant { /* ... */ };

#endif

Now the client code can use my_shared_ptr or my_variant based on whether USE_BOOST is defined for the target plaform, or not:

typedef my_variant<double, int, unsigned int, size_t, bool> MBVariant;
typedef my_variant<double, float> FPVariant;
typedef my_shared_ptr<int> MyPtr;

The problem for me is that the boost::variant is a class template that takes an arbitrary number of parameter types in the form of a recursive type list. I'm not sure if (or how) typedefs or type aliases can cope with this.

Is there a general way to wrap boost::variant for this purpose?

I know that I could use simple typedefs to provide new type names for specific sets of parameters to boost::variant, and I don't have a huge number at the moment, so that's a possibility, but I'm very interested in the general approach to type aliasing something like boost::variant, while avoiding use of the preprocessor as much as possible as I need to integrate this into a namespace hierarchy.

davidA
  • 12,528
  • 9
  • 64
  • 96
  • How good are the C++11 capabilities of your compiler? And just out of curiosity, what platform doesn't support Boost? – Timo Geusch Jun 06 '14 at 04:31
  • I'm supplied with a custom-built Clang-3.0 (with the flag -std=c++11 disabled, so only the standard C++0x capabilities are available). It's for a virtual LLVM CPU and has a limited implementation of the standard library (e.g. it's missing all iostream stuff, amongst others) which is why Boost has a lot of problems. In parallel I'm trying to get Boost working, but it's not looking good at this point... – davidA Jun 06 '14 at 04:47
  • As an aside, I'm not entirely sure I understand the whole C++11 support in Clang - it seems that some features are supported by default, and some require -std=c++11 to be specified. I don't understand where the line is drawn. What I do know is that with this custom build of clang I do not have the -std=c++11 switch available, but other C++11 features like `auto`, Ranged-for, type aliases work fine. Strongly-typed enums do not work, for example. – davidA Jun 06 '14 at 04:51
  • My original idea was that you might be able to wrap the boost::variants using variadic templates, but if you have no C++11 support, that's not going to work. – Timo Geusch Jun 06 '14 at 05:35
  • wouldn't [namespaces](http://stackoverflow.com/a/16367158/819272) be a much cleaner way to hide boost/non-boost dependencies? – TemplateRex Jun 06 '14 at 06:37
  • Could be easier to compile the latest version of clang with C++11/14 support. – Maxim Egorushkin Jun 06 '14 at 09:16

1 Answers1

0
template <typename... T>
using my_variant = boost::variant<T...>

Or, as I'd prefer

namespace library
{
    #if defined(HAS_BOOST)
        using boost::variant;
    #else
        using my_utils::variant;
    #endif
}

Note that you will be running into problems related to ADL and specializations in either case. You can't hide the presence of the conditionals as long as you're using typedefs.

Instead, you could/should write your own interface headers and swap out implementation files.

sehe
  • 374,641
  • 47
  • 450
  • 633