<commit_before>//==================================================
// Copyright (c) 2015 <NAME>
//
// See the file license.txt for copying permission.
//==================================================

/*
 * =====================================================================================
 *
 *       Filename:  Filter.hpp
 *
 *    Description:  Filter class
 *
 *        Version:  1.0
 *        Created:  08/04/2014 07:37:01 PM
 *       Compiler:  gcc
 *
 *         Author:  <NAME> (dk), <EMAIL>
 *
 * =====================================================================================
 */

#ifndef FILTER_O8Y22ICC
#define FILTER_O8Y22ICC

#include <utility>

#include <templatious/util/Exceptions.hpp>
#include <templatious/CollectionAdapter.hpp>
#include <templatious/proxy/Picker.hpp>

namespace templatious {

TEMPLATIOUS_BOILERPLATE_EXCEPTION( FilterPastEndIterationException,
    "Trying to iterate past end of filter.");

template <class T,class Fn,template <class> class StoragePolicy>
struct Filter {

    template <class I,class Fun>
    struct PIterator;

    typedef typename adapters::CollectionAdapter<T> Ad;
    typedef PIterator<typename Ad::Iterator,Fn> Iterator;
    typedef PIterator<typename Ad::ConstIterator,Fn> ConstIterator;
    typedef detail::IsProxy<T> ProxUtil;
    typedef typename ProxUtil::ICollection ICollection;
    typedef Filter<T,Fn,StoragePolicy> ThisFilter;

    static const bool proxy_inside = ProxUtil::val;
    static const bool floating_iterator = Ad::floating_iterator;
    static const bool random_access_iterator = false;

    static_assert(Ad::is_valid,"Adapter is invalid.");

    typedef typename StoragePolicy<T>::Container Ref;
    typedef typename StoragePolicy<Fn>::Container Fun;

#ifndef TEMPLATIOUS_TESTING
private:
#endif

    Ref _c;
    Fun _fn;
    Iterator _b;
    Iterator _e;
    bool _cleared;

    void assertUncleared() const {
        if (_cleared) {
            throw detail::ProxyClearedUsageException();
        }
    }

    void tagCleared() {
        _cleared = true;
    }

#ifndef TEMPLATIOUS_TESTING
public:
#endif

    template <class V,class FnRef>
    Filter(V&& v,FnRef&& fn) :
        _c(std::forward<V>(v)),
        _fn(std::forward<FnRef>(fn)),
        _b(Ad::begin(_c.getRef()),
           Ad::end(_c.getRef()),
           _fn.getRef()),
        _e(Ad::end(_c.getRef()),
           Ad::end(_c.getRef()),
           _fn.getRef()),
        _cleared(false)
    {
        bool begEqEnd = _b == _e;
        if (!begEqEnd && !_fn.getRef()(*_b)) {
            ++_b;
        }
    }

    Filter(ThisFilter&& other)
        : _c(other._c.cpy()),
          _fn(other._fn.cpy()),
          _b(Ad::begin(_c.getRef()),
             Ad::end(_c.getRef()),
             _fn.getRef()),
          _e(Ad::end(_c.getRef()),
              Ad::end(_c.getRef()),
              _fn.getRef()),
          _cleared(other._cleared)
    {
        bool begEqEnd = _b == _e;
        if (!begEqEnd && !_fn.getRef()(*_b)) {
            ++_b;
        }
    }

    Iterator begin() {
        assertUncleared();
        return _b;
    }

    Iterator end() {
        assertUncleared();
        return _e;
    }

    ConstIterator cbegin() const {
        assertUncleared();
        return ConstIterator(
            ProxUtil::const_iter_cast(_b._i),
            ProxUtil::const_iter_cast(_b._e),
            _b._fn
        );
    }

    ConstIterator cend() const {
        assertUncleared();
        return ConstIterator(
            ProxUtil::const_iter_cast(_e._i),
            ProxUtil::const_iter_cast(_e._e),
            _e._fn
        );
    }

    Iterator iterAt(long i) {
        assertUncleared();
        auto res(_b);
        detail::naiveIterAdvance(res,_e,i);
        return res;
    }

    long size() const {
        if (!_cleared) {
            return -1;
        } else {
            return 0;
        }
    }

    template <class I,class Fun>
    struct PIterator {
    private:
        I _i;
        I _e;
        typedef typename StoragePolicy<Fn>::Container Func;
        Func _fn;

        friend struct Filter<T,Fun,StoragePolicy>;

        template <class V>
        friend struct detail::IsProxy;
    public:

        typedef PIterator<I,Fun> ThisIter;
        typedef decltype(*_i) IVal;
        static const bool is_rvalue = std::is_rvalue_reference<IVal>::value;

        template <class V>
        PIterator(const I& i,const I& e,V&& fn) :
            _i(i), _e(e), _fn(std::forward<V>(fn)) {}

        PIterator& operator=(const PIterator& rhs) {
            _i = rhs._i;
            _e = rhs._e;
            return *this;
        }

        ThisIter& operator++() {
            if (_e == _i) {
                throw FilterPastEndIterationException();
            }

            do {
                ++_i;
            } while (_e != _i && !_fn.getRef()(*_i));
            return *this;
        }

        bool operator==(const ThisIter& rhs) const {
            return _i == rhs._i;
        }
<commit_msg>Scott Meyers trick<commit_after>//==================================================
// Copyright (c) 2015 <NAME>
//
// See the file license.txt for copying permission.
//==================================================

/*
 * =====================================================================================
 *
 *       Filename:  Filter.hpp
 *
 *    Description:  Filter class
 *
 *        Version:  1.0
 *        Created:  08/04/2014 07:37:01 PM
 *       Compiler:  gcc
 *
 *         Author:  <NAME> (dk), <EMAIL>
 *
 * =====================================================================================
 */

#ifndef FILTER_O8Y22ICC
#define FILTER_O8Y22ICC

#include <utility>

#include <templatious/util/Exceptions.hpp>
#include <templatious/CollectionAdapter.hpp>
#include <templatious/proxy/Picker.hpp>

namespace templatious {

TEMPLATIOUS_BOILERPLATE_EXCEPTION( FilterPastEndIterationException,
    "Trying to iterate past end of filter.");

template <class T,class Fn,template <class> class StoragePolicy>
struct Filter {

    template <class I,class Fun>
    struct PIterator;

    typedef typename adapters::CollectionAdapter<T> Ad;
    typedef PIterator<typename Ad::Iterator,Fn> Iterator;
    typedef PIterator<typename Ad::ConstIterator,Fn> ConstIterator;
    typedef detail::IsProxy<T> ProxUtil;
    typedef typename ProxUtil::ICollection ICollection;
    typedef Filter<T,Fn,StoragePolicy> ThisFilter;

    static const bool proxy_inside = ProxUtil::val;
    static const bool floating_iterator = Ad::floating_iterator;
    static const bool random_access_iterator = false;

    static_assert(Ad::is_valid,"Adapter is invalid.");

    typedef typename StoragePolicy<T>::Container Ref;
    typedef typename StoragePolicy<Fn>::Container Fun;

#ifndef TEMPLATIOUS_TESTING
private:
#endif

    Ref _c;
    Fun _fn;
    Iterator _b;
    Iterator _e;
    bool _cleared;

    void assertUncleared() const {
        if (_cleared) {
            throw detail::ProxyClearedUsageException();
        }
    }

    void tagCleared() {
        _cleared = true;
    }

#ifndef TEMPLATIOUS_TESTING
public:
#endif

    template <class V,class FnRef>
    Filter(V&& v,FnRef&& fn) :
        _c(std::forward<V>(v)),
        _fn(std::forward<FnRef>(fn)),
        _b(Ad::begin(_c.getRef()),
           Ad::end(_c.getRef()),
           _fn.getRef()),
        _e(Ad::end(_c.getRef()),
           Ad::end(_c.getRef()),
           _fn.getRef()),
        _cleared(false)
    {
        bool begEqEnd = _b == _e;
        if (!begEqEnd && !_fn.getRef()(*_b)) {
            ++_b;
        }
    }

    Filter(ThisFilter&& other)
        : _c(other._c.cpy()),
          _fn(other._fn.cpy()),
          _b(Ad::begin(_c.getRef()),
             Ad::end(_c.getRef()),
             _fn.getRef()),
          _e(Ad::end(_c.getRef()),
              Ad::end(_c.getRef()),
              _fn.getRef()),
          _cleared(other._cleared)
    {
        bool begEqEnd = _b == _e;
        if (!begEqEnd && !_fn.getRef()(*_b)) {
            ++_b;
        }
    }

    Iterator begin() {
        assertUncleared();
        return _b;
    }

    Iterator end() {
        assertUncleared();
        return _e;
    }

    ConstIterator cbegin() const {
        assertUncleared();
        return ConstIterator(
            ProxUtil::const_iter_cast(_b._i),
            ProxUtil::const_iter_cast(_b._e),
            _b._fn
        );
    }

    ConstIterator cend() const {
        assertUncleared();
        return ConstIterator(
            ProxUtil::const_iter_cast(_e._i),
            ProxUtil::const_iter_cast(_e._e),
            _e._fn
        );
    }

    Iterator iterAt(long i) {
        assertUncleared();
        auto res(_b);
        detail::naiveIterAdvance(res,_e,i);
        return res;
    }

    long size() const {
        if (!_cleared) {
            return -1;
        } else {
            return 0;
        }
    }

    template <class I,class Fun>
    struct PIterator {
    private:
        I _i;
        I _e;
        typedef typename StoragePolicy<Fn>::Container Func;
        Func _fn;

        friend struct Filter<T,Fun,StoragePolicy>;

        template <class V>
        friend struct detail::IsProxy;
    public:

        typedef PIterator<I,Fun> ThisIter;
        typedef decltype(*_i)&& IVal;
        static const bool is_rvalue = std::is_rvalue_reference<IVal>::value;

        template <class V>
        PIterator(const I& i,const I& e,V&& fn) :
            _i(i), _e(e), _fn(std::forward<V>(fn)) {}

        PIterator& operator=(const PIterator& rhs) {
            _i = rhs._i;
            _e = rhs._e;
            return *this;
        }

        ThisIter& operator++() {
            if (_e == _i) {
                throw FilterPastEndIterationException();
            }

            do {
                ++_i;
            } while (_e != _i && !_fn.getRef()(*_i));
            return *this;
        }

        bool operator==(const ThisIter& rhs) const {
            return _i == rhs._i;
        }

{'fraction_non_alphanumeric': 0.1733826617338266, 'fraction_numerical': 0.005599440055994401, 'mean_word_length': 2.196548418024928, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 59, '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': '1498108', 'n_tokens_mistral': 3184, 'n_tokens_neox': 3024, 'n_words': 636}