<commit_before>/*
 *   Copyright (C) 2016 <NAME> <ivan.cukic(at)kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2,
 *   or (at your option) any later version, as published by the Free
 *   Software Foundation
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

//
// W A R N I N G
// -------------
//
// This file is not part of the AsynQt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <type_traits>

#include "../utils_p.h"

namespace AsynQt {
namespace detail {

template <typename _In, typename _Transformation>
struct TransformFutureInterfaceHelper {
    typedef typename std::result_of<_Transformation(_In)>::type result_type;
};

template <typename _Transformation>
struct TransformFutureInterfaceHelper<void, _Transformation> {
    typedef typename std::result_of<_Transformation()>::type result_type;
};


template <typename _In, typename _Transformation>
class TransformFutureInterface
    : public QObject
    , public QFutureInterface<
        typename TransformFutureInterfaceHelper<_In, _Transformation>::result_type
    > {

public:
    typedef typename TransformFutureInterfaceHelper<_In, _Transformation>::result_type result_type;
    typedef typename std::is_void<_In>::type   in_type_is_void;
    typedef typename std::is_void<result_type> result_type_is_void;

    TransformFutureInterface(QFuture<_In> future,
                                _Transformation transormation)
        : m_future(future)
        , m_transormation(transormation)
    {
    }

    ~TransformFutureInterface()
    {
    }

    // If _In is void, we are never going to get a result,
    // so, we need to pretend like we got one when the
    // future is successfully finished
    inline
    void setFutureResultOnFinished(
            std::true_type, // _In is void
            std::true_type  // result_type is void
        )
    {
        qDebug() << "value to void";
        // no value, no result to create, but we still
        // want to call the transformation function
        if (!m_future.isCanceled()) {
            m_transormation();
        }
    }

    inline
    void setFutureResultOnFinished(
            std::true_type,  // _In is void
            std::false_type  // result_type is not void
        )
    {
        qDebug() << "void to value";
        if (!m_future.isCanceled()) {
            this->reportResult(m_transormation());
        }
    }

    // Ignore id _In is not void
    template <typename T>
    inline
    void setFutureResultOnFinished(std::false_type, T) {}

    // If _In is not void, then all is as it should be
    inline
    void setFutureResultAt(
            int index,
            std::false_type, // _In is not void
            std::true_type   // result_type is void
        )
    {
        qDebug() << "value to void";
        // nothing to do with the value, but we still
        // want to call the transformation function
        m_transormation(m_future.resultAt(index));
    }

    inline
    void setFutureResultAt(
            int index,
            std::false_type, // _In is not void
            std::false_type  // result_type is not void
        )
    {
        qDebug() << "value to value";
        this->reportResult(m_transormation(m_future.resultAt(index)));
    }

    template <typename T>
    inline
    void setFutureResultAt(int, std::true_type, T) {}


    QFuture<result_type> start()
    {
        m_futureWatcher.reset(new QFutureWatcher<_In>());

        onFinished(m_futureWatcher, [this]() {
            setFutureResultOnFinished(in_type_is_void(), result_type_is_void());
            this->reportFinished();
        });

        onCanceled(m_futureWatcher, [this]() { this->reportCanceled(); });

        onResultReadyAt(m_futureWatcher, [this](int index) {
            setFutureResultAt(index, in_type_is_void(), result_type_is_void());
        });

        m_futureWatcher->setFuture(m_future);

        this->reportStarted();

        return this->future();
    }

private:
    QFuture<_In> m_future;
    _Transformation m_transormation;
    std::unique_ptr<QFutureWatcher<_In>> m_futureWatcher;
};

template <typename _In, typename _Transformation>
QFuture<
    typename detail::TransformFutureInterface<_In, _Transformation>::result_type
    >
transform_impl(const QFuture<_In> &future, _Transformation &&transormation)
{
    return (new TransformFutureInterface<_In, _Transformation>(
                future, std::forward<_Transformation>(transormation)))
        ->start();
}


namespace operators {

    template <typename _Transformation>
    class TransformationModifier {
    public:
        TransformationModifier(_Transformation transormation)
            : m_transormation(transormation)
        {
        }

        _Transformation m_transormation;
    };

    template <typename _In, typename _Transformation>
    auto operator | (const QFuture<_In> &future,
                     TransformationModifier<_Transformation> &&modifier)
        -> decltype(transform_impl(future, modifier.m_transormation))
    {
        return transform_impl(future, modifier.m_transormation);
    }

} // namespace operators

} // namespace detail
} // namespace AsynQt

<commit_msg>Fixing some cornder-cases for result_of usage<commit_after>/*
 *   Copyright (C) 2016 <NAME> <ivan.cukic(at)kde.org>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License version 2,
 *   or (at your option) any later version, as published by the Free
 *   Software Foundation
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details
 *
 *   You should have received a copy of the GNU General Public
 *   License along with this program; if not, write to the
 *   Free Software Foundation, Inc.,
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

//
// <NAME>
// -------------
//
// This file is not part of the AsynQt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include <type_traits>

#include "../utils_p.h"

namespace AsynQt {
namespace detail {

template <typename _In, typename _Transformation>
struct TransformFutureInterfaceHelper {
    typedef typename std::result_of<_Transformation&(_In&&)>::type result_type;
};

template <typename _Transformation>
struct TransformFutureInterfaceHelper<void, _Transformation> {
    typedef typename std::result_of<_Transformation&()>::type result_type;
};


template <typename _In, typename _Transformation>
class TransformFutureInterface
    : public QObject
    , public QFutureInterface<
        typename TransformFutureInterfaceHelper<_In, _Transformation>::result_type
    > {

public:
    typedef typename TransformFutureInterfaceHelper<_In, _Transformation>::result_type result_type;
    typedef typename std::is_void<_In>::type   in_type_is_void;
    typedef typename std::is_void<result_type> result_type_is_void;

    TransformFutureInterface(QFuture<_In> future,
                                _Transformation transormation)
        : m_future(future)
        , m_transormation(transormation)
    {
    }

    ~TransformFutureInterface()
    {
    }

    // If _In is void, we are never going to get a result,
    // so, we need to pretend like we got one when the
    // future is successfully finished
    inline
    void setFutureResultOnFinished(
            std::true_type, // _In is void
            std::true_type  // result_type is void
        )
    {
        qDebug() << "value to void";
        // no value, no result to create, but we still
        // want to call the transformation function
        if (!m_future.isCanceled()) {
            m_transormation();
        }
    }

    inline
    void setFutureResultOnFinished(
            std::true_type,  // _In is void
            std::false_type  // result_type is not void
        )
    {
        qDebug() << "void to value";
        if (!m_future.isCanceled()) {
            this->reportResult(m_transormation());
        }
    }

    // Ignore id _In is not void
    template <typename T>
    inline
    void setFutureResultOnFinished(std::false_type, T) {}

    // If _In is not void, then all is as it should be
    inline
    void setFutureResultAt(
            int index,
            std::false_type, // _In is not void
            std::true_type   // result_type is void
        )
    {
        qDebug() << "value to void";
        // nothing to do with the value, but we still
        // want to call the transformation function
        m_transormation(m_future.resultAt(index));
    }

    inline
    void setFutureResultAt(
            int index,
            std::false_type, // _In is not void
            std::false_type  // result_type is not void
        )
    {
        qDebug() << "value to value";
        this->reportResult(m_transormation(m_future.resultAt(index)));
    }

    template <typename T>
    inline
    void setFutureResultAt(int, std::true_type, T) {}


    QFuture<result_type> start()
    {
        m_futureWatcher.reset(new QFutureWatcher<_In>());

        onFinished(m_futureWatcher, [this]() {
            setFutureResultOnFinished(in_type_is_void(), result_type_is_void());
            this->reportFinished();
        });

        onCanceled(m_futureWatcher, [this]() { this->reportCanceled(); });

        onResultReadyAt(m_futureWatcher, [this](int index) {
            setFutureResultAt(index, in_type_is_void(), result_type_is_void());
        });

        m_futureWatcher->setFuture(m_future);

        this->reportStarted();

        return this->future();
    }

private:
    QFuture<_In> m_future;
    _Transformation m_transormation;
    std::unique_ptr<QFutureWatcher<_In>> m_futureWatcher;
};

template <typename _In, typename _Transformation>
QFuture<
    typename detail::TransformFutureInterface<_In, _Transformation>::result_type
    >
transform_impl(const QFuture<_In> &future, _Transformation &&transormation)
{
    return (new TransformFutureInterface<_In, _Transformation>(
                future, std::forward<_Transformation>(transormation)))
        ->start();
}


namespace operators {

    template <typename _Transformation>
    class TransformationModifier {
    public:
        TransformationModifier(_Transformation transormation)
            : m_transormation(transormation)
        {
        }

        _Transformation m_transormation;
    };

    template <typename _In, typename _Transformation>
    auto operator | (const QFuture<_In> &future,
                     TransformationModifier<_Transformation> &&modifier)
        -> decltype(transform_impl(future, modifier.m_transormation))
    {
        return transform_impl(future, modifier.m_transormation);
    }

} // namespace operators

} // namespace detail
} // namespace AsynQt


{'fraction_non_alphanumeric': 0.0942879164168879, 'fraction_numerical': 0.0027404299049413375, 'mean_word_length': 2.7274178104053624, 'pattern_counts': {'":': 0, '<': 84, '<?xml version=': 0, '>': 86, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6596429', 'n_tokens_mistral': 3383, 'n_tokens_neox': 3253, 'n_words': 943}