dimanche 29 avril 2018

why functional C++ have its form?

I'm reading the STL llmv and gcc, to learn how STL is implemented and then learn to code better. But also I'm trying to create my version that is more readable and if possible faster.

for example partition with Foward Iterator:

template<class FIter, class Predicate>
  FIter
  partition(FIter first, FIter last, Predicate pred)
  {
    // find the first element that don't pass the test
    first = newton::find_if(first, last, newton::not1(pred));
    // same that
    // first = std::find_if_not(first, last, pred);
    if (first == last)
      return first;

    // and then find the first next element that pass the test
    // if the element exist swap the first and next
    FIter next = newton::find(first + 1, last, pred);
    while (next != last) {
      std::iter_swap(first, next);
      ++first;
      ++next;
      next = newton::find(next, last, pred);
    }

    return first;
  }

That is more readable than GCC

  /// This is a helper function...
  template<typename _ForwardIterator, typename _Predicate>
  _ForwardIterator
  __partition(_ForwardIterator __first, _ForwardIterator __last,
              _Predicate __pred, forward_iterator_tag)
  {
    if (__first == __last)
      return __first;

    while (__pred(*__first))
      if (++__first == __last)
        return __first;

    _ForwardIterator __next = __first;

    while (++__next != __last)
      if (__pred(*__next))
        {
          std::iter_swap(__first, __next);
          ++__first;
        }

    return __first;
  }

I think my version it's better because it's easier to understand and review.

CppCon 2016: Marshall Clow “STL Algorithms - why you should use them, and how to write your own"

So..........

When I write the code I start to see how functions in works

And there is something CRAZY!, but not just crazy, CRAZY! CRAZY!.

GCC

template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
   bool operator()(const _Tp& __x, const _Tp& __y) const
   { return __x < __y; }
};

LLVM

template <class T> // <class T=void> in C++14
struct less : binary_function<T, T, bool>
{
    bool operator()(const T& x, const T& y) const;
};

I Just... don't understand. Who is crazy here, is it me?

Who writes template <class T> // <class T=void>?

My version is this:

struct less
  {
    // return true if left is less than right, false otherwise.
    template <class T, class U = T>
    constexpr bool operator()(const T& left, const U& right) const;
  } less;

I think it's better.

  1. because <class T, class U = T> can compare uint16_t and int16_t
  2. don't need a template when declare the struct, just when using operator std::less<uint16_t> comp vs newton::less comp
  3. end with } less;

And you can use it without declare it.

for example, I have another function that is not in STL. divisible

struct divisible
  {
    // return true if left is divisible by right, false otherwise.
    template <class T, class U = T>
    constexpr bool operator()(const T& left, const U& right) const;
  } divisible;

So you could:

if ( newton::divisible(element, 2) )
   party.on();

mean while using the form of STL you should:

std::divisible foo(); //(屮゚Д゚)屮
if ( foo(element, 2) )
   party.on();

So why STL have that form?

Should be because the binary_function<T, T, bool> but, right now I think it's unnecessary.

Aucun commentaire:

Enregistrer un commentaire