[config] polygon library long long, long double portability

I use long long and long double in the configuration of my integer arithmetic traits. I'd like to guard those usages with boost macros to allow the code to compile on platforms that don't support long long and long double (replace with long and double respectively) but I can only find a BOOST_HAS_LONG_LONG macro (which is apparently not documented) and not a corresponding BOOST_HAS_LONG_DOUBLE. Is there some other macro I can use to detect BOOST_HAS_LONG_DOUBLE or a typedef I can use that is already set to long double if available and double otherwise? Thanks, Luke

AMDG Simonson, Lucanus J wrote:
I use long long and long double in the configuration of my integer arithmetic traits. I'd like to guard those usages with boost macros to allow the code to compile on platforms that don't support long long and long double (replace with long and double respectively) but I can only find a BOOST_HAS_LONG_LONG macro (which is apparently not documented) and not a corresponding BOOST_HAS_LONG_DOUBLE. Is there some other macro I can use to detect BOOST_HAS_LONG_DOUBLE or a typedef I can use that is already set to long double if available and double otherwise?
long double is standard C++. long long is only the the new standard. You might also consider using boost::int64_t from boost/cstdint.hpp guarded by BOOST_NO_INT64_T msvc has 64 bit ints, but doesn't call them long long. In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Simonson, Lucanus J wrote:
I use long long and long double in the configuration of my integer arithmetic traits. I'd like to guard those usages with boost macros to allow the code to compile on platforms that don't support long long and long double (replace with long and double respectively) but I can only find a BOOST_HAS_LONG_LONG macro (which is apparently not documented) and not a corresponding BOOST_HAS_LONG_DOUBLE. Is there some other macro I can use to detect BOOST_HAS_LONG_DOUBLE or a typedef I can use that is already set to long double if available and double otherwise?
long double is standard C++. long long is only the the new standard.
You might also consider using boost::int64_t from boost/cstdint.hpp guarded by BOOST_NO_INT64_T
msvc has 64 bit ints, but doesn't call them long long.
In Christ, Steven Watanabe
Yes, I realized that long double must be standard after grepping the boost codebase and seeing it used everywhere. If we searched the archive we'd probably find I asked this same question in the past. I might be a slow learner. My code with long long compiles in MSVC, does is compile to a 32 bit int? Specifying int64_t would make sense if my integer coordinate traits were in terms of int32_t, but they are in terms of int. Perhaps I should change that as well. Thanks, Luke

Simonson, Lucanus J wrote:
I use long long and long double in the configuration of my integer arithmetic traits. I'd like to guard those usages with boost macros to allow the code to compile on platforms that don't support long long and long double (replace with long and double respectively) but I can only find a BOOST_HAS_LONG_LONG macro (which is apparently not documented) and not a corresponding BOOST_HAS_LONG_DOUBLE. Is there some other macro I can use to detect BOOST_HAS_LONG_DOUBLE or a typedef I can use that is already set to long double if available and double otherwise?
long double is standard C++. long long is only the the new standard.
You might also consider using boost::int64_t from boost/cstdint.hpp guarded by BOOST_NO_INT64_T
msvc has 64 bit ints, but doesn't call them long long.
In Christ, Steven Watanabe
Yes, I realized that long double must be standard after grepping the boost codebase and seeing it used everywhere. If we searched the archive we'd probably find I asked this same question in the past. I might be a slow learner. My code with long long compiles in MSVC, does is compile to a 32 bit int? Specifying int64_t would make sense if my integer coordinate traits were in terms of int32_t, but they are in terms of int. Perhaps I should change that as well.
FWIW, Boost has boost::long_long_type and boost::ulong_long_type typedefs (only if BOOST_HAS_LONG_LONG is defined) representing the platform specific long long/__int64/etc. Regards Hartmut

msvc has 64 bit ints, but doesn't call them long long.
Yes it does, at least with current versions :-)
Yes, I realized that long double must be standard after grepping the boost codebase and seeing it used everywhere. If we searched the archive we'd probably find I asked this same question in the past. I might be a slow learner. My code with long long compiles in MSVC, does is compile to a 32 bit int? Specifying int64_t would make sense if my integer coordinate traits were in terms of int32_t, but they are in terms of int. Perhaps I should change that as well.
Please don't confuse types, with widths: you need to use either specific width types throughout (which are all of unspecified type), or use specific types. For example code that needs to overload a function for all the integer *types* would use long long where available, where as code that's designed to work with specific *widths* should use the boost::intXX_t types throughout, in the knowledge that these may not cover all the available *types* (for example if long is a 64-bit int then long long is never used by the intXX_t typedefs). I hope that's not too confusing :-) Basically decide which set to used based on what your code does, and what the integers represent. HTH, John.

John Maddock wrote:
msvc has 64 bit ints, but doesn't call them long long.
Yes it does, at least with current versions :-)
I don't compile in old versions of MSVC for a number of reasons, and only test with MSVC9. I guess for my purposes MSVC does have 64 bit long long.
Yes, I realized that long double must be standard after grepping the boost codebase and seeing it used everywhere. If we searched the archive we'd probably find I asked this same question in the past. I might be a slow learner. My code with long long compiles in MSVC, does is compile to a 32 bit int? Specifying int64_t would make sense if my integer coordinate traits were in terms of int32_t, but they are in terms of int. Perhaps I should change that as well.
Please don't confuse types, with widths: you need to use either specific width types throughout (which are all of unspecified type), or use specific types. For example code that needs to overload a function for all the integer *types* would use long long where available, where as code that's designed to work with specific *widths* should use the boost::intXX_t types throughout, in the knowledge that these may not cover all the available *types* (for example if long is a 64-bit int then long long is never used by the intXX_t typedefs).
I hope that's not too confusing :-) Basically decide which set to used based on what your code does, and what the integers represent.
That is what I'm doing. Currently I define coordinate traits in terms of built-ins and am aware that their widths change from platform to platform. To the greatest extent possible I try to ensure correctness across platforms by (for example) not assuming long is wider than int and using long long instead. I'm debating whether to replace that system completely with one where I am explicit about bit width by using typedefs. I'm inclined to leave things as they are now that I have proper guards around my usage of long long. Thanks, Luke

Simonson, Lucanus J wrote:
John Maddock wrote:
msvc has 64 bit ints, but doesn't call them long long.
Yes it does, at least with current versions :-)
I don't compile in old versions of MSVC for a number of reasons, and only test with MSVC9. I guess for my purposes MSVC does have 64 bit long long.
Visual C++ 8.0 is not old and is well supported by Boost. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Mateusz Loskot wrote:
Simonson, Lucanus J wrote:
John Maddock wrote:
msvc has 64 bit ints, but doesn't call them long long.
Yes it does, at least with current versions :-)
I don't compile in old versions of MSVC for a number of reasons, and only test with MSVC9. I guess for my purposes MSVC does have 64 bit long long.
Visual C++ 8.0 is not old and is well supported by Boost.
I was quite happy to move forward to MSVC9, though I don't remember what it was about MSVC8 that I was happy to get away from. Maybe I was just still so happy to get away from MSVC7 that I got the same warm happy feeling when upgrading to MSVC9. ;) Does anyone know what issues I can expect to encounter back porting from MSVC9 to MSVC8? Since the code is portable to several front ends and compiles in MSVC8 I would expect back porting it to be minor. Thanks, Luke

Simonson, Lucanus J wrote:
Mateusz Loskot wrote:
Simonson, Lucanus J wrote:
John Maddock wrote:
msvc has 64 bit ints, but doesn't call them long long. Yes it does, at least with current versions :-) I don't compile in old versions of MSVC for a number of reasons, and only test with MSVC9. I guess for my purposes MSVC does have 64 bit long long. Visual C++ 8.0 is not old and is well supported by Boost.
I was quite happy to move forward to MSVC9, though I don't remember what it was about MSVC8 that I was happy to get away from. Maybe I was just still so happy to get away from MSVC7
Do you mean 7.0 or 7.1?
that I got the same warm happy feeling when upgrading to MSVC9. ;)
Nice, but I believe Boost does still support older versions. I'm not sure if it's a Boost-wide requirement that all libraries must support all compilers, but it's quite common between users to assume that's true. So, I'm not sure if your happiness meets users expactations as Viasual C++ 8.0 is still widely used and will be for long time. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Mateusz Loskot wrote:
I'm not sure if it's a Boost-wide requirement that all libraries must support all compilers, but it's quite common between users to assume that's true.
So, I'm not sure if your happiness meets users expactations as Viasual C++ 8.0 is still widely used and will be for long time.
You misinterpret my lightheartedness for carelessness. I fully intend to attempt back porting to MSVC8 and I tried to make that clear when I asked if anyone had words of wisdom to offer me before I set out to do just that. Since it takes hours to install visual studio 2005 over the network I'll probably wait until Monday to get started. Regards, Luke

Simonson, Lucanus J wrote:
Mateusz Loskot wrote:
I'm not sure if it's a Boost-wide requirement that all libraries must support all compilers, but it's quite common between users to assume that's true.
So, I'm not sure if your happiness meets users expactations as Viasual C++ 8.0 is still widely used and will be for long time.
You misinterpret my lightheartedness for carelessness.
Yes, I probably did.
I fully intend to attempt back porting to MSVC8 and I tried to make that clear when I asked if anyone had words of wisdom to offer me before I set out to do just that.
There is no general wisdom of Visual C++ 8.0. The only I can recommend is to try to build and walk through errors fixing them. Best regards, -- Mateusz Loskot, http://mateusz.loskot.net Charter Member of OSGeo, http://osgeo.org

Mateusz Loskot wrote:
I fully intend to attempt back porting to MSVC8 and I tried to make that clear when I asked if anyone had words of wisdom to offer me before I set out to do just that.
There is no general wisdom of Visual C++ 8.0. The only I can recommend is to try to build and walk through errors fixing them.
Ok, so I think I know why I was happy to get away from MSVC8. SFINAE just isn't working for me in MSVC8--I get a duplicate definition error for practically every overload of generic functions. The two function declarations below are an example. They differ by conceptual type exected (and checked with compile time SFINAE logic) for the second argument. Fixing such a syntax error is not straightforward since the syntax error is due to the failure of the compiler to support the language feature. Only though trial and error experimenting with the quirks of MSVC8 wrt SFINAE can I potentially come up with an alternative syntax which the compiler will accept. Since the standard cannot guide me I can draw only on my own experience of MSVC (which is that default metafunction return values seem to play an important role in when and how the compiler fails to the the right thing, as does whether the template is parameterized by a type or by a literal value) and the experience of the rest of the boost community. For example, enable_if uses enable_if_c which is parameterized by a literal constant, which works around a bug in the way SFINAE works in complicated template instantiations. // enlarge rectangle to encompass the point b template <typename rectangle_type_1, typename point_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type encompass(rectangle_type_1& rectangle, const point_type& b) template <typename rectangle_type_1, typename rectangle_type_2> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, bool>::type encompass(rectangle_type_1& rectangle, const rectangle_type_2& b) Currently gtl_and looks like this: template <typename T, typename T2> struct gtl_and { typedef gtl_no type; }; template <typename T> struct gtl_and<T, T> { typedef T type; }; I changed it to this: template <bool larg, bool rarg> struct gtl_and_c { typedef gtl_no type; }; template <> struct gtl_and_c<true, true> { typedef gtl_yes type; }; template <typename T, typename T2> struct gtl_and : gtl_and_c<T::value, T2::value> {}; But that didn't help MSVC8 do the right thing. It seems MSVC8 assumes both templates can be instantiated without performing the compile time logic or invoking SFINAE and I don't know how to trick it into doing the right thing. I'd be happy to switch from my own logic metafunctions to something in boost::mpl, especially if it improves portability. It was already on my todo list. I don't believe that will fix my problems with MSVC8, however. Does someone know what specifically is different between MSVC8 and MSVC9 wrt. SFINAE conformance? I am shooting in the dark to reverse engineer the bugs in the compiler that were fixed between MSVC8 and 9. There is a good chance that my library won't get backported to MSVC8 without some guidance from the community. There is apparently another problem with MSVC8 that enums are less typesafe than in MSVC9--an integral literal constant is assumed to be potentially the same type as an enum value for the purposes of template matching, which is wrong and breaks my code in numerous places as well. This issue I can more easily handle myself. Does lack of backward compatibility to MSVC8 (and obviously MSVC7.1) constitute a strong argument against acceptance of a library that would not likely make it into a release of boost until 2010? By that time Visual Studio 2005 will be two major releases behind the current MS compiler version. Do we really let compiler bugs in five year old versions of a major compiler dictate to us what features of the language we are allowed to use in boost for new libraries? Regards, Luke

On Wed, Jul 1, 2009 at 1:52 PM, Simonson, Lucanus J<lucanus.j.simonson@intel.com> wrote:
Does someone know what specifically is different between MSVC8 and MSVC9 wrt. SFINAE conformance? I am shooting in the dark to reverse engineer the bugs in the compiler that were fixed between MSVC8 and 9. There is a good chance that my library won't get backported to MSVC8 without some guidance from the community.
I'm sorry I don't know enough to help out, but both trunk and release test results show that enable_if passes all tests on 7.1, 8.0, 9.0, and 10.0. Are you sure it's a compiler bug? http://www.boost.org/development/tests/release/developer/utility-enable_if.h... http://www.boost.org/development/tests/trunk/developer/utility-enable_if.htm... --Michael Fawcett

Michael Fawcett wrote:
On Wed, Jul 1, 2009 at 1:52 PM, Simonson, Lucanus J<lucanus.j.simonson@intel.com> wrote:
Does someone know what specifically is different between MSVC8 and MSVC9 wrt. SFINAE conformance? I am shooting in the dark to reverse engineer the bugs in the compiler that were fixed between MSVC8 and 9. There is a good chance that my library won't get backported to MSVC8 without some guidance from the community.
I'm sorry I don't know enough to help out, but both trunk and release test results show that enable_if passes all tests on 7.1, 8.0, 9.0, and 10.0. Are you sure it's a compiler bug?
http://www.boost.org/development/tests/release/developer/utility-enable_if.h... http://www.boost.org/development/tests/trunk/developer/utility-enable_if.htm...
Simple cases with enable_if doe work in MSVC8, but as the template parameters of enable_if get more elaborate with compile time logic metafunctions it breaks down in MSVC8 and not longer seems to work. I'm putting together a set of compilation tests that should all pass in MSVC9 but some of which fail in MSVC8 to try to empirically determine what works and what doesn't with MSVC8. I am quite sure it is a compiler bug. Even MSVC9 has severe limitations due to a bug that prevents SFINAE from being effective in all but top level template instantiation, and the situation is apparently worse still with MSVC8 where even in top level instantiation SFINAE is not always effective. I'll post the results of my testing to share my findings about what specifically is broken about SFINAE in MSVC8 that works in MSVC9 once the experiments are complete. Regards, Luke

Simonson, Lucanus J wrote:
Michael Fawcett wrote:
On Wed, Jul 1, 2009 at 1:52 PM, Simonson, Lucanus J<lucanus.j.simonson@intel.com> wrote:
Does someone know what specifically is different between MSVC8 and MSVC9 wrt. SFINAE conformance? I am shooting in the dark to reverse engineer the bugs in the compiler that were fixed between MSVC8 and 9. There is a good chance that my library won't get backported to MSVC8 without some guidance from the community.
I'm sorry I don't know enough to help out, but both trunk and release test results show that enable_if passes all tests on 7.1, 8.0, 9.0, and 10.0. Are you sure it's a compiler bug?
http://www.boost.org/development/tests/release/developer/utility-enable_if.h... http://www.boost.org/development/tests/trunk/developer/utility-enable_if.htm...
Simple cases with enable_if doe work in MSVC8, but as the template parameters of enable_if get more elaborate with compile time logic metafunctions it breaks down in MSVC8 and not longer seems to work. I'm putting together a set of compilation tests that should all pass in MSVC9 but some of which fail in MSVC8 to try to empirically determine what works and what doesn't with MSVC8.
I am quite sure it is a compiler bug. Even MSVC9 has severe limitations due to a bug that prevents SFINAE from being effective in all but top level template instantiation, and the situation is apparently worse still with MSVC8 where even in top level instantiation SFINAE is not always effective.
I'll post the results of my testing to share my findings about what specifically is broken about SFINAE in MSVC8 that works in MSVC9 once the experiments are complete.
It turns out the bug in MSVC8 is much worse than I had feared. I extracted out the minimum subset of code necessary to test the encompass function I showed earlier and MSVC8 dutifully compiled it. I then tried the minimum subset of my own header files necessary to test the encompass function and got a syntax error. Then I started eliminating definitions of unrelated functions from my code until the syntax error disappeared. It turns out that I get a syntax error on my rectangle encompass overloads if my rectangle convolve function is declared before it but not if convolve is declared after. Convolve does not depend on encompass or vis-vera. The relative order of these should be of no consequence since they are unrelated. Changing the order of the declarations of these three functions causes the compilation to succeed, but in the order I declare them compilation fails. If it were just this one overload I'd be able to change the order and sneak past the compiler bug, but this problem impacts dozens of overloaded functions throughout gtl, especially the operators. If the only way to fix it is the change the order of lots of functions that don't depend on eachother it will be practically impossible to find an ordering that doesn't give syntax errors as the number of functions increases. This is because there is no way to reason about what the right order should be, since the behavior of the compiler is inexplicable. I don't believe it is feasible for me to back port to MSVC8. Does anyone see a way around this? Thanks, Luke Below is the minimum code snippet required to reproced the syntax error in MSVC8 when compiling in my sandbox gtl/boost/polygon directory: #include "isotropy.hpp" #include "rectangle_data.hpp" #include "point_data.hpp" #include "point_traits.hpp" #include "interval_traits.hpp" #include "rectangle_traits.hpp" #include "point_concept.hpp" #include "interval_concept.hpp" //#include "rectangle_concept.hpp" namespace boost { namespace polygon { struct rectangle_concept{}; template <typename T> struct geometry_concept<rectangle_data<T> > { typedef rectangle_concept type; }; template <typename T> struct is_mutable_rectangle_concept { typedef gtl_no type; }; template <> struct is_mutable_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; template <typename T> struct is_rectangle_concept { typedef gtl_no type; }; template <> struct is_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; template <typename rectangle_type, typename point_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type & convolve(rectangle_type& rectangle, const point_type& convolution_point); template <typename rectangle_type, typename interval_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, bool>::type encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) {return true;} template <typename rectangle_type_1, typename point_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type encompass(rectangle_type_1& rectangle, const point_type& b) {return true;} }} int main() { using namespace boost; using namespace boost::polygon; rectangle_data<int> r; point_data<int> p; encompass(r, p); return 0; }

Lucanus, this following compiles just fine with mine MSVC8. I have basically moved the enable_if as a function parameter. I hope this helps you. I for myself had similar issues when I set up the the new gil::io. These compiler errors are very painful to deal with. template< typename rectangle_type , typename interval_type > void encompass( rectangle_type& rectangle , const interval_type& b , orientation_2d orient , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept< typename geometry_concept< rectangle_type >::type >::type , typename is_interval_concept < typename geometry_concept< interval_type
::type >::type >::type , bool >::type* ptr = 0 ) { }
template <typename rectangle_type_1, typename point_type> void encompass( rectangle_type_1& rectangle , const point_type& b , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept< typename geometry_concept< rectangle_type_1 >::type >::type , typename is_point_concept < typename geometry_concept< point_type
::type>::type >::type , bool >::type* ptr = 0 ) { }
Sorry for the bad formatting. I cannot send files from work in gmail. :-/ Regards, Christian On Wed, Jul 1, 2009 at 7:50 PM, Simonson, Lucanus J<lucanus.j.simonson@intel.com> wrote:
Simonson, Lucanus J wrote:
Michael Fawcett wrote:
On Wed, Jul 1, 2009 at 1:52 PM, Simonson, Lucanus J<lucanus.j.simonson@intel.com> wrote:
Does someone know what specifically is different between MSVC8 and MSVC9 wrt. SFINAE conformance? I am shooting in the dark to reverse engineer the bugs in the compiler that were fixed between MSVC8 and 9. There is a good chance that my library won't get backported to MSVC8 without some guidance from the community.
I'm sorry I don't know enough to help out, but both trunk and release test results show that enable_if passes all tests on 7.1, 8.0, 9.0, and 10.0. Are you sure it's a compiler bug?
http://www.boost.org/development/tests/release/developer/utility-enable_if.h... http://www.boost.org/development/tests/trunk/developer/utility-enable_if.htm...
Simple cases with enable_if doe work in MSVC8, but as the template parameters of enable_if get more elaborate with compile time logic metafunctions it breaks down in MSVC8 and not longer seems to work. I'm putting together a set of compilation tests that should all pass in MSVC9 but some of which fail in MSVC8 to try to empirically determine what works and what doesn't with MSVC8.
I am quite sure it is a compiler bug. Even MSVC9 has severe limitations due to a bug that prevents SFINAE from being effective in all but top level template instantiation, and the situation is apparently worse still with MSVC8 where even in top level instantiation SFINAE is not always effective.
I'll post the results of my testing to share my findings about what specifically is broken about SFINAE in MSVC8 that works in MSVC9 once the experiments are complete.
It turns out the bug in MSVC8 is much worse than I had feared. I extracted out the minimum subset of code necessary to test the encompass function I showed earlier and MSVC8 dutifully compiled it. I then tried the minimum subset of my own header files necessary to test the encompass function and got a syntax error. Then I started eliminating definitions of unrelated functions from my code until the syntax error disappeared. It turns out that I get a syntax error on my rectangle encompass overloads if my rectangle convolve function is declared before it but not if convolve is declared after. Convolve does not depend on encompass or vis-vera. The relative order of these should be of no consequence since they are unrelated. Changing the order of the declarations of these three functions causes the compilation to succeed, but in the order I declare them compilation fails. If it were just this one overload I'd be able to change the order and sneak past the compiler bug, but this problem impacts dozens of overloaded functions throughout gtl, especially the operators. If the only way to fix it is the change the order of lots of functions that don't depend on eachother it will be practically impossible to find an ordering that doesn't give syntax errors as the number of functions increases. This is because there is no way to reason about what the right order should be, since the behavior of the compiler is inexplicable. I don't believe it is feasible for me to back port to MSVC8. Does anyone see a way around this?
Thanks, Luke
Below is the minimum code snippet required to reproced the syntax error in MSVC8 when compiling in my sandbox gtl/boost/polygon directory:
#include "isotropy.hpp" #include "rectangle_data.hpp" #include "point_data.hpp" #include "point_traits.hpp" #include "interval_traits.hpp" #include "rectangle_traits.hpp" #include "point_concept.hpp" #include "interval_concept.hpp" //#include "rectangle_concept.hpp"
namespace boost { namespace polygon {
struct rectangle_concept{}; template <typename T> struct geometry_concept<rectangle_data<T> > { typedef rectangle_concept type; }; template <typename T> struct is_mutable_rectangle_concept { typedef gtl_no type; }; template <> struct is_mutable_rectangle_concept<rectangle_concept> { typedef gtl_yes type; }; template <typename T> struct is_rectangle_concept { typedef gtl_no type; }; template <> struct is_rectangle_concept<rectangle_concept> { typedef gtl_yes type; };
template <typename rectangle_type, typename point_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, rectangle_type>::type & convolve(rectangle_type& rectangle, const point_type& convolution_point);
template <typename rectangle_type, typename interval_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, typename is_interval_concept<typename geometry_concept<interval_type>::type>::type>::type, bool>::type encompass(rectangle_type& rectangle, const interval_type& b, orientation_2d orient) {return true;}
template <typename rectangle_type_1, typename point_type> typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, bool>::type encompass(rectangle_type_1& rectangle, const point_type& b) {return true;}
}}
int main() { using namespace boost; using namespace boost::polygon; rectangle_data<int> r; point_data<int> p; encompass(r, p); return 0; } _______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Christian Henning wrote:
Lucanus, this following compiles just fine with mine MSVC8. I have basically moved the enable_if as a function parameter. I hope this helps you. I for myself had similar issues when I set up the the new gil::io. These compiler errors are very painful to deal with.
Sneaky! I like it. I'm glad someone who has dealt with the issue in the past was able to offer some guidance. It may take me some time to apply the fix because the number of functions in question is large. Thank you, Luke

Christian Henning wrote:
Lucanus, this following compiles just fine with mine MSVC8. I have basically moved the enable_if as a function parameter. I hope this helps you. I for myself had similar issues when I set up the the new gil::io. These compiler errors are very painful to deal with.
It turns out this only works because the two versions of encompass in my example differ in their arguments such that the compiler can disambiguate them without SFINAE. There are three versions of encompass related to rectangle. The two that work on rectangle,rectangle and rectangle,point respectively still don't compile with your fix: // enlarge rectangle to encompass the Rectangle b template <typename rectangle_type_1, typename rectangle_type_2> bool encompass(rectangle_type_1& rectangle, const rectangle_type_2& b, typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type>::type, void>::type *dummy = 0) { return true; } // enlarge rectangle to encompass the point b template <typename rectangle_type_1, typename point_type> bool encompass(rectangle_type_1& rectangle, const point_type& b, typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type *dummy = 0) { return true; } The compiler gives a "redefinition of default parameter : parameter 3" for these two overloads, failing to take SFINAE into account. By changing the type from void* to int* the compiler allows them to both instantiate, but then gives a "function call is ambiguous" error because it is using the normal rules for overloading and only by specifying the third parameter would the caller be able to select the correct function. Luke

We have to make sure we are trying to compile the same code! The following works when using MSVC8. There are three encompass functions. Can you tell me if that's the right code? #include "isotropy.hpp" #include "rectangle_data.hpp" #include "point_data.hpp" #include "point_traits.hpp" #include "interval_traits.hpp" #include "rectangle_traits.hpp" #include "point_concept.hpp" #include "interval_concept.hpp" //#include "rectangle_concept.hpp" namespace boost { namespace polygon { struct rectangle_concept{}; template <typename T> struct geometry_concept< rectangle_data< T > > { typedef rectangle_concept type; }; template <typename T> struct is_mutable_rectangle_concept { typedef gtl_no type; }; template <> struct is_mutable_rectangle_concept< rectangle_concept > { typedef gtl_yes type; }; template <typename T> struct is_rectangle_concept { typedef gtl_no type; }; template <> struct is_rectangle_concept< rectangle_concept > { typedef gtl_yes type; }; template< typename rectangle_type , typename interval_type > bool encompass( rectangle_type& rectangle , const interval_type& b , orientation_2d orient , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept< typename geometry_concept< rectangle_type >::type >::type , typename is_interval_concept < typename geometry_concept< interval_type
::type >::type >::type , bool >::type* ptr = 0 ) { return true; }
// enlarge rectangle to encompass the Rectangle b template < typename rectangle_type_1 , typename rectangle_type_2 > bool encompass( rectangle_type_1& rectangle , const rectangle_type_2& b , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type , typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type , void >::type* dummy = 0 ) { return true; } // enlarge rectangle to encompass the point b template <typename rectangle_type_1, typename point_type> bool encompass( rectangle_type_1& rectangle , const point_type& b , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept< typename geometry_concept<rectangle_type_1 >::type>::type , typename is_point_concept < typename geometry_concept<point_type
::type>::type >::type , void >::type* dummy = 0 ) { return true; }
} } int main() { using namespace boost; using namespace boost::polygon; rectangle_data<int> r; point_data<int> p; encompass(r, p); return 0; } Christian

Christian Henning wrote:
We have to make sure we are trying to compile the same code! The following works when using MSVC8. There are three encompass functions. Can you tell me if that's the right code?
Remember, I didn't get any syntax error from the start when convolve() wasn't declared before the encompass() functions. When you add convolve back in the errors come back regardless of where enable_if goes. Below I have added convolve() back in and tried to use your suggestion of putting enable_if as a default argument instead of return type pattern in convolve() as well. Neither place for enable_if in convolve() is effective in eliminating the error. Still, moving convolve() to follow the three encompass() functions makes the error go away, but since they are not directly related there is no way to know why. I understand that it isn't intuitive what is going on. Your sensible approach ought to work, but we need to remember that this is a compiler bug that results in inconsistent SFINAE behavior when templates are instantiated in the context of other templates that have arguments to enable_if in common. One thing that does work is the *change the order* or arguments to gtl_and<> in the enable_if of convolve() which breaks the (compiler internal) relationship between it and the overload of encompass such that compilation is able to succeed. At this point I have enough understanding of the compiler bug to reason about how to work around it. What is required is that *no two arguments to enable_if should ever be the same between any two functions in the entire compilation unit*. This discipline can prevent the "optimization" MSVC8 is doing on template instantiations from breaking SFINAE because if no two enable_if's take the same arguments the compiler is forced to instantiate them all seperately and not change the order of instantiation (and make incorrect assumptions in doing so) in the way that breaks SFINAE. I can likely do this easily by adding extra gtl_yes parameters to the gtl_and<> logic of functions that result in the erroneous error. By the way, what is the minimal header dependency I include to get the standard boost version of and<> to use in place of gtl_and? I found the mpl header files rather hard to navigate and the documentation didn't answer my question. Is the thing I need boost::mpl::and_<> which takes 2 or more parameters? Thanks, Luke #include "isotropy.hpp" #include "rectangle_data.hpp" #include "point_data.hpp" #include "point_traits.hpp" #include "interval_traits.hpp" #include "rectangle_traits.hpp" #include "point_concept.hpp" #include "interval_concept.hpp" //#include "rectangle_concept.hpp" namespace boost { namespace polygon { struct rectangle_concept{}; template <typename T> struct geometry_concept< rectangle_data< T > > { typedef rectangle_concept type; }; template <typename T> struct is_mutable_rectangle_concept { typedef gtl_no type; }; template <> struct is_mutable_rectangle_concept< rectangle_concept > { typedef gtl_yes type; }; template <typename T> struct is_rectangle_concept { typedef gtl_no type; }; template <> struct is_rectangle_concept< rectangle_concept > { typedef gtl_yes type; }; // convolve with point template <typename rectangle_type, typename point_type> rectangle_type& convolve(rectangle_type& rectangle, const point_type& convolution_point, typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type>::type>::type, typename is_point_concept<typename geometry_concept<point_type>::type>::type>::type, void>::type *dummy = 0); template< typename rectangle_type , typename interval_type > bool encompass( rectangle_type& rectangle , const interval_type& b , orientation_2d orient , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept< typename geometry_concept< rectangle_type >::type >::type , typename is_interval_concept < typename geometry_concept< interval_type
::type >::type >::type , bool >::type* ptr = 0 ) { return true; }
// enlarge rectangle to encompass the Rectangle b template < typename rectangle_type_1 , typename rectangle_type_2 > bool encompass( rectangle_type_1& rectangle , const rectangle_type_2& b , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type>::type , typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type>::type >::type , void >::type* dummy = 0 ) { return true; } // enlarge rectangle to encompass the point b template <typename rectangle_type_1, typename point_type> bool encompass( rectangle_type_1& rectangle , const point_type& b , typename enable_if< typename gtl_and< typename is_mutable_rectangle_concept< typename geometry_concept<rectangle_type_1 >::type>::type , typename is_point_concept < typename geometry_concept<point_type
::type>::type >::type , void >::type* dummy = 0 ) { return true; }
} } int main() { using namespace boost; using namespace boost::polygon; rectangle_data<int> r; point_data<int> p; encompass(r, p); return 0; }

The following compiles and uses mpl::and_. Your problem is very similar to a problem I once had. Steven Watanabe was able to fix by just leaving out the ::type references. For instance problem with msvc8: mpl::and_< my_metafunction<...>::type, my_metafunction2<....>::type >::type NO problem with msvc8: mpl::and_< my_metafunction<...>, my_metafunction2<....> > ---------------- #include <boost/mpl/and.hpp> #include "isotropy.hpp" #include "rectangle_data.hpp" #include "point_data.hpp" #include "point_traits.hpp" #include "interval_traits.hpp" #include "rectangle_traits.hpp" #include "point_concept.hpp" #include "interval_concept.hpp" //#include "rectangle_concept.hpp" using namespace boost::mpl; namespace boost { namespace polygon { struct rectangle_concept{}; template <typename T> struct geometry_concept< rectangle_data< T > > { typedef rectangle_concept type; }; template <typename T> struct is_mutable_rectangle_concept { typedef gtl_no type; }; template <> struct is_mutable_rectangle_concept< rectangle_concept > { typedef gtl_yes type; }; template <typename T> struct is_rectangle_concept { typedef gtl_no type; }; template <> struct is_rectangle_concept< rectangle_concept > { typedef gtl_yes type; }; // convolve with point template< typename rectangle_type , typename point_type > rectangle_type& convolve( rectangle_type& rectangle , const point_type& convolution_point , typename enable_if< typename mpl::and_< typename is_mutable_rectangle_concept< typename geometry_concept< rectangle_type >::type > , typename is_point_concept < typename geometry_concept< point_type >::type > > , void >::type *dummy = 0 ); template< typename rectangle_type , typename interval_type > bool encompass( rectangle_type& rectangle , const interval_type& b , orientation_2d orient , typename enable_if< typename mpl::and_< typename is_mutable_rectangle_concept< typename geometry_concept< rectangle_type >::type > , typename is_interval_concept < typename geometry_concept< interval_type
::type > > , bool >::type* ptr = 0 ) { return true; }
// enlarge rectangle to encompass the Rectangle b template < typename rectangle_type_1 , typename rectangle_type_2 > bool encompass( rectangle_type_1& rectangle , const rectangle_type_2& b , typename enable_if< typename mpl::and_< typename is_mutable_rectangle_concept<typename geometry_concept<rectangle_type_1>::type> , typename is_rectangle_concept<typename geometry_concept<rectangle_type_2>::type> > , void >::type* dummy = 0 ) { return true; } // enlarge rectangle to encompass the point b template <typename rectangle_type_1, typename point_type> bool encompass( rectangle_type_1& rectangle , const point_type& b , typename enable_if< typename mpl::and_< typename is_mutable_rectangle_concept< typename geometry_concept<rectangle_type_1 >::type > , typename is_point_concept < typename geometry_concept<point_type
::type > > , void >::type* dummy = 0 ) { return true; }
} } int main() { using namespace boost; using namespace boost::polygon; rectangle_data<int> r; point_data<int> p; encompass(r, p); return 0; } I hope that fixes your problem and you have a great time fixing all of your code. ;-) I was there already. Regards, Christian

Christian Henning wrote:
The following compiles and uses mpl::and_. Your problem is very similar to a problem I once had. Steven Watanabe was able to fix by just leaving out the ::type references. For instance
I tried replacing gtl_and and gtl_yes/no everywhere with mpl::bool_ and mpl::and_ and I get compile errors in MSVC9. I have managed to work around bugs in MSVC9 with the way I have implemented gtl_and to return false by default and return true only in the case where I want the template to instantiate. Because gtl_and_ has a complex default case MSVC9 incorrectly makes assumptions when optimizing its instantiation of multiple templates that cause it to ignore the SFINAE behavior I want under certain circumstances. I don't fully understand what those circumstances are, but it is similar to the problems in MSVC8 where simple SFINAE tests work, but realistic code breaks down. I don't believe it is feasible for me to use mpl::and_ and support even MSVC9. At this point I feel that the prospects for ever supporting MSVC8 are very dim. SFINAE just doesn't work in MSVC well enough to use it to overload large numbers of generic functions. This is why Barend and Bruno abandoned SFINAE, support for it in MSVC is so bad (inconsistent) it might as well not exist at all. Porting my code to MSVC9 was extremely difficult and consumed several weeks for sustained (including overtime) effort. If I would port to MSVC8 in 120 hours of programming effort comparable to what the port to MSVC9 took I might consider it, but I have no assurance that after 120 hour I would have SFINAE based code that works in MSVC8. Since generic operators require SFINAE to not side swipe the stl and operator calls on enum types I have to use SFINAE, so changing to tag dispatching with static assert is not an option unless I defeature the operators. I don't think supporting MSVC8 warrents re-writing the entire set of interfaces including defeaturing a significant number of them. Regards, Luke

Luke, I'm sure there are plenty of projects out there, including mine, that make heavy use of SFINAE. Although, I understand that code can become quite messy and hard to read, it does work fine in most of the cases. For instance have a look at: https://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension... esspecially at files like detail/read_image.hpp If your project has a similar level of SFINAE usage, I would think we could fix your code. I'm willing helping you out. Could you provide minimal code that shows your problem with MSVC9? Not all is lost. ;-) Regards, Christian On Mon, Jul 6, 2009 at 2:47 PM, Simonson, Lucanus J<lucanus.j.simonson@intel.com> wrote:
Christian Henning wrote:
The following compiles and uses mpl::and_. Your problem is very similar to a problem I once had. Steven Watanabe was able to fix by just leaving out the ::type references. For instance
I tried replacing gtl_and and gtl_yes/no everywhere with mpl::bool_ and mpl::and_ and I get compile errors in MSVC9. I have managed to work around bugs in MSVC9 with the way I have implemented gtl_and to return false by default and return true only in the case where I want the template to instantiate. Because gtl_and_ has a complex default case MSVC9 incorrectly makes assumptions when optimizing its instantiation of multiple templates that cause it to ignore the SFINAE behavior I want under certain circumstances. I don't fully understand what those circumstances are, but it is similar to the problems in MSVC8 where simple SFINAE tests work, but realistic code breaks down. I don't believe it is feasible for me to use mpl::and_ and support even MSVC9.
At this point I feel that the prospects for ever supporting MSVC8 are very dim. SFINAE just doesn't work in MSVC well enough to use it to overload large numbers of generic functions. This is why Barend and Bruno abandoned SFINAE, support for it in MSVC is so bad (inconsistent) it might as well not exist at all. Porting my code to MSVC9 was extremely difficult and consumed several weeks for sustained (including overtime) effort. If I would port to MSVC8 in 120 hours of programming effort comparable to what the port to MSVC9 took I might consider it, but I have no assurance that after 120 hour I would have SFINAE based code that works in MSVC8. Since generic operators require SFINAE to not side swipe the stl and operator calls on enum types I have to use SFINAE, so changing to tag dispatching with static assert is not an option unless I defeature the operators. I don't think supporting MSVC8 warrents re-writing the entire set of interfaces including defeaturing a signific ant number of them.
Regards, Luke
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Christian Henning wrote:
Luke, I'm sure there are plenty of projects out there, including mine, that make heavy use of SFINAE. Although, I understand that code can become quite messy and hard to read, it does work fine in most of the cases. For instance have a look at:
https://gil-contributions.googlecode.com/svn/trunk/gil_2/boost/gil/extension...
esspecially at files like detail/read_image.hpp
If your project has a similar level of SFINAE usage, I would think we could fix your code. I'm willing helping you out. Could you provide minimal code that shows your problem with MSVC9?
Not all is lost. ;-)
Thank you for this kind offer. The compile time logic of your code looks very similar to what I'm doing, and you do indeed have many overloads of read_image(). I'm gussing that the default argument usage of enable_if somehow gets around some of the problems I'm having with MSVC8 and 9. I'd expect that it allows the compiler to decide that the functions are not ambiguous with its cursory examination and then if SFINAE actually gets triggered in all cases the enable_if'd argument doesn't need to be provided to call the functions. I'll have to move literally hundreds of enable_if parameters from the return type to the last argument of every SFINAE protected function. However, the operator functions cannot use this mechanism, and have to use SFINAE on the return type because they are limited to only two arguments. It is likely that I cannot get them working at all in MSVC and will need to disable them with the preprocessor and provide alternative function call syntax. I may end up separating them out into optional header files since generic operators are often prone to problems. It looks like I have quite a bit of work ahead of me just to get my library compiling in MSVC9 using mpl::and_. I'll see if I can get past the initial mass failures by moving the enable_if from the return type to the argument list so that I can determine what other problems I might have. Thanks again, Luke

Simonson, Lucanus J wrote:
If your project has a similar level of SFINAE usage, I would think we could fix your code. I'm willing helping you out. Could you provide minimal code that shows your problem with MSVC9?
It looks like I have quite a bit of work ahead of me just to get my library compiling in MSVC9 using mpl::and_. I'll see if I can get past the initial mass failures by moving the enable_if from the return type to the argument list so that I can determine what other problems I might have.
It turns out I was wrong, there were only a few instances where I needed to move enable_if from the return type to a default argument to get mpl::and_ working in MSVC9 in place of gtl_and. Also, it looks like I am able to fix most problems in MSVC8 by moving enable_if to from the return type to a default argument and it turns out that with my workaround for MSVC8 enable_if can be induced to work on the return type for the operators that require that syntax if I take care to ensure that the argument to those enable_if instantiations is always a unique template. I only have about 40 such operator declarations, so it is reasonable to do. The easy way is to create a unique true type that inherits from mpl::bool_<true> for each such and add it in as an extra parameter to and_. I may be able to work around all the MSVC bugs and have the entire library compiling in MSVC8 much easier than I had feared. I still have to touch hundreds of declarations, but it looks like all problems I'll encounter now have a proscribed solution. Thanks, Christian, for not giving up on me, Luke

Simonson, Lucanus J wrote:
Simonson, Lucanus J wrote:
If your project has a similar level of SFINAE usage, I would think we could fix your code. I'm willing helping you out. Could you provide minimal code that shows your problem with MSVC9?
All code compiles and generally passes my unit tests in MSVC8. It turns out that making the enable_if a default argument impacts regular overloading of functions and that adding a unique type into the enable_if logic to make all instantiations unique was a more reliable way to work around the compiler bugs. I ran into a problem where boost::long_long_type isn't able to convert correctly to double. In the code below the return type of square_euclidean_distance is long long because I need twice as many bits to store the result of a multiply. euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { double val = (double)square_euclidean_distance(lvalue, rvalue); return sqrt(val); } It fails a runtime check stating that val is left unitialized and in the debugger I can see that the value is indeed uninitialized. My question for any experts is why is this code failing? I looking into the dissasembly and it looks like long long is 64 bit emulated in software in my 32 bit windows environment compiling with MSVC8. I couldn't find anywhere the conversion from long long to double, and it seems that it is just silently failing to provide it, leaving me with uninitialized data. In MSVC8 BOOST_HAS_LONG_LONG is defined and I'm using the boost::long_long_type the way it was suggested that I should. Thanks, Luke

AMDG Simonson, Lucanus J wrote:
All code compiles and generally passes my unit tests in MSVC8.
It turns out that making the enable_if a default argument impacts regular overloading of functions and that adding a unique type into the enable_if logic to make all instantiations unique was a more reliable way to work around the compiler bugs.
I ran into a problem where boost::long_long_type isn't able to convert correctly to double. In the code below the return type of square_euclidean_distance is long long because I need twice as many bits to store the result of a multiply.
euclidean_distance(const rectangle_type& lvalue, const rectangle_type_2& rvalue) { double val = (double)square_euclidean_distance(lvalue, rvalue); return sqrt(val); }
It fails a runtime check stating that val is left unitialized and in the debugger I can see that the value is indeed uninitialized. My question for any experts is why is this code failing?
I looking into the dissasembly and it looks like long long is 64 bit emulated in software in my 32 bit windows environment compiling with MSVC8. I couldn't find anywhere the conversion from long long to double, and it seems that it is just silently failing to provide it, leaving me with uninitialized data.
In MSVC8 BOOST_HAS_LONG_LONG is defined and I'm using the boost::long_long_type the way it was suggested that I should.
I don't think this is related to the use of long long since the following program works okay. #include <iostream> int main() { long long x = 1.0; double d = x; std::cout << x << std::endl; } I seem to recall seeing a problem like this before when overload resolution doesn't quite work. Perhaps you remember this thread? http://lists.boost.org/Archives/boost/2009/01/146859.php I think I had similar runtime weirdness in some of the tests that I ran. In Christ, Steven Watanabe

Steven Watanabe wrote:
In MSVC8 BOOST_HAS_LONG_LONG is defined and I'm using the boost::long_long_type the way it was suggested that I should.
I don't think this is related to the use of long long since the following program works okay.
#include <iostream>
int main() { long long x = 1.0; double d = x; std::cout << x << std::endl; }
It turns out that I was using boost::long_long_type, and when I changed that typedef to long long the problem goes away. I remember you mentioned this to me a while back:
You might also consider using boost::int64_t from boost/cstdint.hpp guarded by BOOST_NO_INT64_T
msvc has 64 bit ints, but doesn't call them long long.
I checked sizeof(long long) in my MSVC8 environment and it was 8 bytes, so I think I'm happy to use it. Do you know what data type boost::long_long_type was using? I ought to be able to check in a version of the code sometime tomorrow that works in MSVC8,9, gcc 3.2.2 and later, and icc9 and later. Thanks, Luke

Simonson, Lucanus J wrote:
Steven Watanabe wrote:
AMDG
Simonson, Lucanus J wrote:
I use long long and long double in the configuration of my integer arithmetic traits. I'd like to guard those usages with boost macros to allow the code to compile on platforms that don't support long long and long double (replace with long and double respectively) but I can only find a BOOST_HAS_LONG_LONG macro (which is apparently not documented) and not a corresponding BOOST_HAS_LONG_DOUBLE. Is there some other macro I can use to detect BOOST_HAS_LONG_DOUBLE or a typedef I can use that is already set to long double if available and double otherwise?
long double is standard C++. long long is only the the new standard.
You might also consider using boost::int64_t from boost/cstdint.hpp guarded by BOOST_NO_INT64_T
msvc has 64 bit ints, but doesn't call them long long.
In Christ, Steven Watanabe
Yes, I realized that long double must be standard after grepping the boost codebase and seeing it used everywhere. If we searched the archive we'd probably find I asked this same question in the past. I might be a slow learner. My code with long long compiles in MSVC, does is compile to a 32 bit int? Specifying int64_t would make sense if my integer coordinate traits were in terms of int32_t, but they are in terms of int. Perhaps I should change that as well.
Later versions of MSVC actually have long long (as well as their own __int64). They behave like a typedef for each other, so are interchangeable. Bo Persson

I use long long and long double in the configuration of my integer arithmetic traits. I'd like to guard those usages with boost macros to allow the code to compile on platforms that don't support long long and long double (replace with long and double respectively) but I can only find a BOOST_HAS_LONG_LONG macro (which is apparently not documented) and not a corresponding BOOST_HAS_LONG_DOUBLE. Is there some other macro I can use to detect BOOST_HAS_LONG_DOUBLE or a typedef I can use that is already set to long double if available and double otherwise?
~~ BOOST_HAS_LONG_LONG has been deprecated in favor of BOOST_NO_LONG_LONG now that long long is actually part of the next standard: http://www.boost.org/doc/libs/1_39_0/libs/config/doc/html/boost_config/boost... There's no BOOST_NO_LONG_DOUBLE because as far as I know there are no compilers that don't support long double as a distinct type. However, there are platforms/compilers that have either none or broken std lib support for the long double math functions. Boost.Math has it's own config macro for that, but it's rather specific to the list of functions used by that library. So... how are you using long double? Regards, John.

John Maddock wrote:
So... how are you using long double?
long double is the maximally precise built-in numerical data type available. I use it as the default "high_precision_type" numerical data type and allow the user to override it with a data type derived from gmp or other arbitrary precicision numerical data type when long double is not enough. long double is not sufficient to make all computations performed by the library on 32 bit integer inputs robust, but it is sufficient for a vast majority, allowing even very large polygonal inputs to be processed by my sweepline correctly. For example, the 6 ft. by 8 ft. poster we hung up at boostcon with roughly one million line intersection in a polygon set intersection operation was computed with long double rather than gmp because the measures I took to make things robust without the need to resort to infinite precision rational are effective in all but the most extreme cases of pairwise line segment intersection. None of my robust predicates rely on non-integer arithmetic, for example, it is only the computation of coordinates that relies on the high_precision_type. We have real large CAD layouts where long double is not enough, and we use gmp infinite precision rational in production because reliability trumps performance when performance is already better than required. Regards, Luke

John Maddock wrote:
BOOST_HAS_LONG_LONG has been deprecated in favor of BOOST_NO_LONG_LONG now that long long is actually part of the next standard: http://www.boost.org/doc/libs/1_39_0/libs/config/doc/html/boost_config/boost...
Hi John, Some comments on that section of the page: s/explicit/extern in the description of BOOST_NO_EXTERN_TEMPLATE s/BOOST_NO_STD_UNORDERD/BOOST_NO_STD_UNORDERED (should we mention it now that it has been deprecated in favor of BOOST_NO_0X_HDR_UNORDERED_* ?) Also I think that listing is far from being complete, as it is missing BOOST_NO_CONCEPTS, BOOST_NO_NULLPTR, all of BOOST_NO_0X_HDR_*, BOOST_NO_LAMBDAS, and a few others. Best Regards, Gevorg
participants (9)
-
Bo Persson
-
Christian Henning
-
Gevorg Voskanyan
-
Hartmut Kaiser
-
John Maddock
-
Mateusz Loskot
-
Michael Fawcett
-
Simonson, Lucanus J
-
Steven Watanabe