C++ Concept-based tag dispatching using the Tick library

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

C++ Concept-based tag dispatching using the Tick library

Paul Fultz II
Hello Everyone,

For those interested. I added support for tag dispatching in the Tick. The
reason it wasn't added earlier was concern over specialization. So now as a
simple example, the `advance` function could be implemented like this:

    TICK_TRAIT(is_incrementable)
    {
        template<class T>
        auto requires_(T&& x) -> tick::valid<
            decltype(x++),
            decltype(++x)
        >;
    };

    TICK_TRAIT(is_decrementable, is_incrementable<_>)
    {
        template<class T>
        auto requires_(T&& x) -> tick::valid<
            decltype(x--),
            decltype(--x)
        >;
    };

    TICK_TRAIT(is_advanceable, is_decrementable<_>)
    {
        template<class T, class Number>
        auto requires_(T&& x, Number n) -> tick::valid<
            decltype(x += n)
        >;
    };

    template<class Iterator>
    void advance_impl(Iterator& it, int n, tick::tag<is_advanceable>)
    {
        it += n;
    }

    template<class Iterator>
    void advance_impl(Iterator& it, int n, tick::tag<is_decrementable>)
    {
        if (n > 0) while (n--) ++it;
        else
        {
            n *= -1;
            while (n--) --it;
        }
    }

    template<class Iterator>
    void advance_impl(Iterator& it, int n, tick::tag<is_incrementable>)
    {
        while (n--) ++it;
    }

    template<class Iterator>
    void advance(Iterator& it, int n)
    {
        advance_impl(it, n, tick::most_refined<is_advanceable<Iterator>>());
    }

Now, specialization is still supported in a sane way. As an example, say there
was an iterator called `foo_iterator` that fulfilled the type requirements for
`is_incrementable`, `is_decrementable`, and `is_advanceable`, but it had an
incorrect `+=` operator on it(perhaps it crahsed at runtime). So
`is_advanceable` can be specialized to prevent this problem:

    template<>
    struct is_advanceable<foo_iterator>
    : std::false_type
    {};

Even though it is specialized to false, it can still dispatch to
`tag<is_decrementable>` and `tag<is_incrementable>` tags. You can read more
about it here:

http://pfultz2.github.io/Tick/doc/html/tag/

Any feedback is appreciated. Thanks,

Paul Fultz II