Am 26.12.22 um 14:18 schrieb John Maddock via Boost:
On 26/12/2022 12:57, Gero Peterhoff via Boost wrote:
Am 25.12.22 um 09:45 schrieb Mathias Gaunard:
On Sat, 24 Dec 2022, 18:38 Gero Peterhoff via Boost, <boost@lists.boost.org <mailto:boost@lists.boost.org>> wrote:
Hi John, I had already addressed a similar topic and it is a good thing that this is brought up again or that other users see it that way too. In principle, as much as possible should be consolidated and simplified (here merging config + predef) in order to be able to provide uniform interfaces/macros without the user having to dig around in the internals of boost.
Example: There is BOOST_HAS_FLOAT128+BOOST_HAS_INT128 and BOOST_NO_INT64_T. It would make sense to provide a complete set for BOOST_HAS_FLOATxxx and BOOST_HAS_INTxxx
Boost.Config uses NO for lack of standard features and HAS for extensions.
OK. But that's what I mean: the user doesn't care whether a type is only available via an extension or not. He just wants to check whether this type is available -> uniform named macros. Would it be legitimate to introduce BOOST_NO_FLOAT128_T + BOOST_NO_INT128_T and other (like BOOST_NO_INT64_T) to do this?
I guess in principle, since there is no real guarantee that there are any such types, these would all be BOOST_HAS_ macros.
However, I have two questions:
1) Which Boost library need this? Generally speaking Config is there for configuring Boost libraries, and as mentioned early in this topic, wasn't originally intended for end-user use.
2) How would we implement this? Short of clairvoyance, I don't see how this is possible in the general case for all the integer and floating point widths.
Also, is this not already largely solved in the integer case by <cstdint> ?
In the floating point case, the only major questions, are:
* Do we have __float128 as an extension: this is already covered.
* Is long double a __float128: that can easily determined by querying LDBL_MANT_DIG
What am I missing?
John.
Hi John, Basically, I'm all about consistency. integer Apparently not all platforms have u/int64_t, hence BOOST_NO_INT64_T. Something similar could (I'm not sure) also apply to u/int8_t, eg 16-bit DSPs with CHAR_BIT==16 -> BOOST_NO_INT8_T. I don't know of any platforms for u/int16/32_t that don't support it, but you never know ... maybe you know which ones. float In <boost/math/cstdfloat/cstdfloat_types.hpp> there is BOOST_CSTDFLOAT_HAS_FLOATxxx_NATIVE_TYPE, but then they become undefined. I use BOOST_CSTDFLOAT_FLOATxxx_NATIVE_TYPE. ugly. So we need BOOST_NO_FLOATxxx_T. I'll update my config_integer.hpp + config_float.hpp and then send them to you. In addition, then stand for float: boost::float128_t + boost::float128_type + boost::math::cstdfloat::detail::float_internal128_t are available integer: only boost::(u)int128_type, but no boost::(u)int128_t It would make sense to consolidate this so that there is only boost::xxx128_t and no boost::xxx128_type to eliminate the redundancies and stick to the standard naming scheme. I would also like to provide macros/traits that check whether a type is natively available on the platform, eg BOOST_NO_NATIVE_xxx_T/is_native. This is especially useful with the float types from std (C++23 stdfloat). Eg I have a complicated algorithm template <std::floating_point Type> Type foo(const Type arg); If I call this with Type=std::(b)float16_t and these are not native, the emulation/conversion to/from float is constantly called within foo. This is slow and inaccurate. With the checks I can then implement (pseudo-code): template <std::floating_point Type> Type foo(const Type arg) { if (Type == std::(b)float16_t && !is_native_v<Type>) using type = float; else using type = Type; return Type(detail::foo_impl(type(arg)); } or foo specialize. There also seems to be an issue with <boost/math/tools/promotion.hpp>. a) promote_arg returns the correct type b) for Type=boost::float16_t or std::(b)float16_t deliver promote_args_2<Type, Type> -> float promote_args<Type, Type...> -> float Shouldn't that be Type? See eg <boost/math/special_functions/cbrt.hpp>: template <typename T, typename Policy> inline typename tools::promote_args<T>::type cbrt(T z, const Policy& pol) { using result_type = typename tools::promote_args<T>::type; using value_type = typename policies::evaluation<result_type, Policy>::type; return static_cast<result_type>(detail::cbrt_imp(value_type(z), pol)); } template <typename T> inline typename tools::promote_args<T>::type cbrt(T z) { return cbrt(z, policies::policy<>()); } thx & regards Gero