Boost logo

Boost :

Subject: Re: [boost] [Boost-users] [Fit] About supported C++ version
From: paul Fultz (pfultz2_at_[hidden])
Date: 2016-03-16 10:02:45


> On Wednesday, March 16, 2016 2:44 AM, Vicente J. Botet Escriba <vicente.botet_at_[hidden]> wrote:
> > Le 15/03/2016 09:52, paul Fultz a écrit :
>>
>>
>>
>> On Tuesday, March 15, 2016 2:59 AM, Vicente J. Botet Escriba
> <vicente.botet_at_[hidden]> wrote:
>>
>>
>>>
>>> Hi,
>>>
>>> I was wondering if Boost.Fit shouldn't be a library as Boost.Hana,
>> a library that makes use of the last C++ version and avoids as
>> much portability issues as possible.
>>
>> I think portability is important, especially for a boost library. And since
> there is already Hana, I think there is room for a portable library, as well.
>>
> I can understand your portability need. However I believe that we should

> raise the bar in Boost.

How is striving for portability not raising the bar?

>
>>> Which C++14 features will make the library simpler?
>> There really isn't any C++14 features that would simplify the library.
>

> Which C++11 features are needed and missing on some C++11 compilers?

Its not about which features are missing, but also if the features are
implemented correctly.
>

> has the last C++11 version of those compilers fixed the issues?

To my knowledge no. The later versions of Gcc have gotten better, however, it
still has problems. And, of course, Gcc 5.1 is completely broken.
>
>>
>>
>>> Which adopted C++17 features will make the library simpler?
>> Inline variables and constexpr lambdas will help simplify the static
> function macros. Also, fold expressions might be useful as well.

> Do you mind to elaborate how inline variables could help?

Instead of the user writing BOOST_FIT_STATIC_FUNCTION, they can write:

inline constexpr const auto foo = foo_f();

>>
>>
>>> Which other C++ features would be missing?
>> Well, it doesn't need features, whats really missing is better
> diagnostics from the compiler.

> Would Concepts help here or is there something else?

No, it won't. Everything is already constrained. The compiler needs to produce
better diagnostics about why a function is not callable.
>>
>>> Paul I guess that you are using a C++11 compiler and want to
>> support this version, could you confirm?
>>
>> Yes I am. Furthermore, there may be other library authors who would like to
> utilize the functionality in Fit, that may need the same level of portability as
> well. So they would have to rewrite some of whats done in Fit if I were to due
> away with portability, which kind of defeats the purpose of reusability with a
> library.
> If you need a C++11 library, which compilers/versions do you want to

> support that need workarounds?

Gcc 4.6+, Clang 3.4+, and MSVC 2015.

>>
>>
>> Also, the work for portability has already been done, so it seems foolish
> to just throw it away. I don't think portability is hugely detrimental to
> the library. It is important to note that the ideal solution is chosen on the
> better compilers(which is usually clang). Furthermore, I plan to take advantage
> of C++17 features in the library when they become ready as well.
> My concern was that there were some comments, something like "there are

> too much macros in the implementation".

First, I use the `BOOST_FIT_RETURNS` macro to deduce the return and constrain
the function, based on the function call. There has never been a proposal for
a C++ feature to replace that. So that will stay.

Now, gcc 4.6 has problem mangling of certain expressions, so some macros are
provided that can be used inside of BOOST_FIT_RETURNS to make the expression
"mangable" for gcc 4.6. Basically, these macros expand to a declval inside of
the decltype, but expands to the expression in the return statement.

Also, gcc 4.6 and 4.7 have problems with incomplete `this` used in a decltype
as well(actually all versions of gcc have problems with incomplete `this`,
however 4.6 and 4.7 are more problematic). So the library provides a way to
write `BOOST_FIT_THIS` to refer to the `this` pointer inside of decltype.

Now on MSVC, expression SFINAE is not completely supported. So instead, it
relies on implicit converion operator to detect callability. This changes the
implementation to use some form of manual type deduction rather than the
trailing decltype. Rather than inflict this on the other compilers(as there is
a compile-time cost to manually computing the return type), there is a macro
to handle this.

Now, gcc 4.6 and 4.7 have trouble with type deduction in a few places as well.
So the Fit library will fallback on manually computing the type using the
infrastructure for expression SFINAE.

I could move to using a base implementation with less macros, however, this
makes the modern compilers pay for the problematic ones.

Now, while thinking about a way for the user to write their own adaptors, that
same mechanism could be used to simplify the implementation as well. So right
now, the flip adaptor is implemented like this(excluding the failure
reporting):

template<class F>
struct flip_adaptor : detail::callable_base<F>
{
   typedef flip_adaptor fit_rewritable1_tag;
      FIT_INHERIT_CONSTRUCTOR(flip_adaptor, detail::callable_base<F>);

      template<class... Ts>
      constexpr const F& base_function(Ts&&... xs) const
      {
       return always_ref(*this)(xs...);
      }

      FIT_RETURNS_CLASS(flip_adaptor);

      template<class T, class U, class... Ts>
      constexpr FIT_SFINAE_RESULT(const detail::callable_base<F>&, id_<U>, id_<T>, id_<Ts>...)
      operator()(T&& x, U&& y, Ts&&... xs) const FIT_SFINAE_RETURNS
      (
              (FIT_MANGLE_CAST(const detail::callable_base<F>&)(FIT_CONST_THIS->base_function(xs...)))
                    (FIT_FORWARD(U)(y), FIT_FORWARD(T)(x), FIT_FORWARD(Ts)(xs)...)
      );
};

Instead, I envision the adaptor to be written as this:

struct flip_adaptor_kernel
{
      template<class F, class... Ts>
      constexpr FIT_SFINAE_RESULT(const F&, id_<U>, id_<T>, id_<Ts>...)
      operator()(const F& f, T&& x, U&& y, Ts&&... xs) const FIT_SFINAE_RETURNS
      (
              f(FIT_FORWARD(U)(y), FIT_FORWARD(T)(x), FIT_FORWARD(Ts)(xs)...)
      );
};

template<class F>
using flip_adaptor = typename adaptor<flip_adaptor_kernel>::template apply<F>;

This will greatly simplify the implementation and reduce the number of macros
used, because now it doesn't have to deal with incomplete this nor conversions
to the base class.

>
> From my bad experience (with Boost.Chrono/Thread), I really believe
> that we should provide libraries for compilers supporting a specific C++
> version. Adding workarounds doesn't help on the long run and could give

> a false impression of portability.

Using this library externally, it makes things much easier, for when I want
portability.
>
> I can understand however that you want it with old compiler versions, as

> not anyone can upgrade to compilers supporting more recent versions.

Most of the time, I don't get a choice in the compiler.

>
>
>
> Vicente
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


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