Boost logo

Boost :

From: Daryle Walker (darylew_at_[hidden])
Date: 2000-09-16 00:47:28


To solve my boost/operators.hpp problem with template chaining getting too
long for my compiler to support, I want to group operator templates
together, then chain those groups together. I tried stuff like:

//==========================================================================
// Grouped operator classes (contributed by Daryle Walker) ---------------//
// A class can only be used portably if the derived class declares _all_
// the required member operators.
template <class T, class U, class B = ::boost::detail::empty_base>
struct additive_operators2
    : addable2<T,U
    , subtractable2<T,U
> > {};

// This template-building style is going to be repeated.
// Can some (severe) macro magic be used?
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T, class B = ::boost::detail::empty_base>
struct additive_operators : additive_operators2<T, U, B> {};

template <class T, class B /*= ::boost::detail::empty_base*/>
struct additive_operators<T, T, B>
#else
template <class T, class B = ::boost::detail::empty_base>
struct additive_operators
#endif
    : addable<T
    , subtractable<T
> > {};

template <class T, class U, class B = ::boost::detail::empty_base>
struct multiplicative_operators2
    : multipliable2<T,U
    , dividable2<T,U
> > {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T, class B = ::boost::detail::empty_base>
struct multiplicative_operators : multiplicative_operators2<T, U, B> {};

template <class T, class B /*= ::boost::detail::empty_base*/>
struct multiplicative_operators<T, T, B>
#else
template <class T, class B = ::boost::detail::empty_base>
struct multiplicative_operators
#endif
    : multipliable<T
    , dividable<T
> > {};

template <class T, class U, class B = ::boost::detail::empty_base>
struct integral_multiplicative_operators2
    : multiplicative_operators2<T,U
    , modable2<T,U
> > {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T, class B = ::boost::detail::empty_base>
struct integral_multiplicative_operators :
integral_multiplicative_operators2<T, U, B> {};

template <class T, class B /*= ::boost::detail::empty_base*/>
struct integral_multiplicative_operators<T, T, B>
#else
template <class T, class B = ::boost::detail::empty_base>
struct integral_multiplicative_operators
#endif
    : multiplicative_operators<T
    , modable<T
> > {};

template <class T, class U, class B = ::boost::detail::empty_base>
struct comparison_operators2
    : less_than_comparable2<T,U
    , equality_comparable2<T,U
> > {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T, class B = ::boost::detail::empty_base>
struct comparison_operators : comparison_operators2<T, U, B> {};

template <class T, class B /*= ::boost::detail::empty_base*/>
struct comparison_operators<T, T, B>
#else
template <class T, class B = ::boost::detail::empty_base>
struct comparison_operators
#endif
    : less_than_comparable<T
    , equality_comparable<T
> > {};

template <class T, class U, class B = ::boost::detail::empty_base>
struct bit_manipulative_operators2
    : orable2<T,U
    , andable2<T,U
    , xorable2<T,U
> > > {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T, class B = ::boost::detail::empty_base>
struct bit_manipulative_operators : bit_manipulative_operators2<T, U, B> {};

template <class T, class B /*= ::boost::detail::empty_base*/>
struct bit_manipulative_operators<T, T, B>
#else
template <class T, class B = ::boost::detail::empty_base>
struct bit_manipulative_operators
#endif
    : orable<T
    , andable<T
    , xorable<T
> > > {};

template <class T, class U, class B = ::boost::detail::empty_base>
struct shiftable_operators2
    : left_shiftable2<T,U
    , right_shiftable2<T,U
> > {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T, class B = ::boost::detail::empty_base>
struct shiftable_operators : shiftable_operators2<T, U, B> {};

template <class T, class B /*= ::boost::detail::empty_base*/>
struct shiftable_operators<T, T, B>
#else
template <class T, class B = ::boost::detail::empty_base>
struct shiftable_operators
#endif
    : left_shiftable<T
    , right_shiftable<T
> > {};

// The following classes were once built by individually including each
// operator class. However, some compilers could not handle the amount
// of template nesting the "base chaining" technique eventually
// required. The above operator group classes should shorten the
// chain's length to something compilers can handle.
template <class T, class U>
struct operators2
    : comparison_operators2<T,U
    , additive_operators2<T,U
    , integral_multiplicative_operators2<T,U
    , bit_manipulative_operators2<T,U
    , shiftable_operators2<T,U
> > > > > {};

#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
template <class T, class U = T>
struct operators : operators2<T, U> {};

template <class T> struct operators<T, T>
#else
template <class T> struct operators
#endif
    : comparison_operators<T
    , additive_operators<T
    , integral_multiplicative_operators<T
    , bit_manipulative_operators<T
    , shiftable_operators<T
    , idempotent<T
    , zero_default_quantifiable<T
    , incrementable<T
    , decrementable<T
> > > > > > > > > {};
//==========================================================================

But it turned out to be a failure. I don't really know this base chaining
stuff too well. Could someone else, like the inventor to the trick, help
find a way to do this?

-- 

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk