Boost logo

Boost :

From: John Maddock (John_Maddock_at_[hidden])
Date: 2000-04-29 06:18:20


Jens,

>What's the value of __BORLANDC__ for C++ Builder 4?
We need to augment its config.hpp section with the version number.
<

C++ Builder 4 defines __BORLANDC__ to 0x540
C++ Builder 5 defines __BORLANDC__ to 0x550

BTW there are no changes required to config.hpp for version 4, only version
5 needs fixing:

#elif defined __BORLANDC__
// C++ builder 4:
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# if defined BOOST_DECL_EXPORTS
# define BOOST_DECL __declspec(dllexport)
# else
# define BOOST_DECL __declspec(dllimport)
# endif
# if __BORLANDC__ == 0x550
# define BOOST_NO_OPERATORS_IN_NAMESPACE
# endif

>I think it's ok to have a different set of workarounds
>(i.e. a possibly disjoint set of BOOST_NO_XXX defines)
>for different compiler versions.

Actually I think I have a better fix for Builder 5 now, that will make
operators.hpp behave seemlessly by using inheritance, here is my test case:

template <class T, class U>
class boost_less_than_comparable
{
     friend bool operator<=( const T& x, const U& y ) { return !(x > y); }
     friend bool operator>=( const T& x, const U& y ) { return !(x < y); }
     friend bool operator>( const U& x, const T& y ) { return y < x; }
     friend bool operator<( const U& x, const T& y ) { return y > x; }
     friend bool operator<=( const U& x, const T& y ) { return !(y < x); }
     friend bool operator>=( const U& x, const T& y ) { return !(y > x); }
};
template <class T>
class boost_less_than_comparable<T, T>
{
     friend bool operator>( const T& x, const T& y ) { return y < x; }
     friend bool operator<=( const T& x, const T& y ) { return !(y < x); }
     friend bool operator>=( const T& x, const T& y ) { return !(x < y); }
};

namespace boost{

template <class T, class U = T> // = T really is needed; not a coding
error
class less_than_comparable : public ::boost_less_than_comparable<T,U>{};

}

class X : public boost::less_than_comparable<X>
{
        public:
        bool operator < (const X& x)const {return true;}
};

int main()
{
        X a,b;
        a <b;
        b<=a;
        a>=b;
        return 0;
}

Noet that defining BOOST_NO_OPERATORS_IN_NAMESPACE places requirements on
users of operators.hpp: they will need to use something like:

namespace boost{

class X : public boost::less_than_comparable<X>
{
        public:
#ifdef BOOST_NO_OPERATORS_IN_NAMESPACE
        bool operator < (const X& x)const;
#else
        friend bool operator < (const X&,const X& x);
#endif
};

}

>Btw, I've updated my BCC bug list with these new and depressing
>entries:

Add some more:

[cstring] defines the isXXX functions as macros in release mode only:

std::isspace(c)

will compile in debug mode but not release.

Workaround: if you use these functions use something like:

#ifdef __BORLANDC__ && __BORLANDC__ < 0x560 // all current and previous
verisons
#ifdef isspace
#undef isspace
#endif
#endif

which will unmask the ANSI C versions.

with regard to :

>[template value defaults] Dependent default
>arguments for template value parameters
>
>Template value parameters which default to an expression
>dependent on previous template parameters don't work:
>
>template<class T>
>struct A
>{
> static const bool value = true;
>};
>
>// "Templates must be classes or functions", "Declaration syntax error"
>template<class T, bool v = A::value>
>struct B {};

that should read:

template<class T, bool v = A<T>::value>
struct B {};

Its the dependence on T that causes the problem here, for example:

template<class T, bool v = non_dependent_type::value>
struct B {};

is fine.

If the defaulted parameter is an implementation detail, then inheritance
both solves the problem, and hides the implementation detail:

namespace boost{

template<class T>
struct A
{
  static const bool value = true;
};

template<class T, bool v>
struct B_base {/*implementation*/};

template<class T>
struct B: public B_base<T, ::boost::A<T>::value> {/*thin wrapper*/};

int foo()
{
  B<int> x;
}

}

Note the use of the fully qualified name ::boost::A<T>, this is important -
without it the compiler doesn't recognise integral constant members as
such.

Wow, I hope that's all for now!!

- John.


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