lgarithm / crystalnet

crystalnet -- a mini core AI library (being refactored, see https://github.com/lgarithm/stdnn-ops)
MIT License
16 stars 3 forks source link

a gcc bug #20

Closed lgarithm closed 6 years ago

lgarithm commented 6 years ago
#include <cstdio>
#include <cassert>
#include <tuple>
#include <utility>
#include <iostream>

template <typename T>
struct range_
{
    const T from;
    const T to;

    explicit range_(T n) : from(0), to(n)
    {
        std::cout << "range_("
                  << from
                  << ","
                  << to
                  << ")" << std::endl;
    }

    explicit range_(T m, T n) : from(m), to(n)
    {
        std::cout << "range_("
                  << from
                  << ","
                  << to
                  << ")" << std::endl;
    }

    struct iterator
    {
        T pos;

        explicit iterator(T pos) : pos(pos) {}

        bool operator!=(const iterator &it) const { return pos != it.pos; }

        T operator*() const { return pos; }

        void operator++() { ++pos; }
    };

    auto begin() const
    {
        std::cout << "range_::begin = " << from << std::endl;
        return iterator(from);
    }

    auto end() const
    {
        std::cout << "range_::end = " << to << std::endl;
        return iterator(to);
    }
};

template <typename T>
range_<T> range(T n)
{
    std::cout << "creating range: [" << 0 << ", " << n << ")" << std::endl;
    return range_<T>(n);
}

template <typename T>
range_<T> range(T m, T n)
{
    std::cout << "creating range: [" << m << ", " << n << ")" << std::endl;
    return range_<T>(m, n);
}

template <typename S, typename T>
struct zipper
{
    const S &a;
    const T &b;

    zipper(const S &a, const T &b) : a(a), b(b) {}

    template <typename I, typename J>
    struct iterator
    {
        I i;
        J j;

        iterator(const I &i, const J &j) : i(i), j(j) {}

        bool operator!=(const iterator &p) const
        {
            return i != p.i || j != p.j;
        }

        void operator++()
        {
            ++i;
            ++j;
        }

        auto operator*() { return std::make_pair(*i, *j); }
    };

    template <typename I, typename J>
    static iterator<I, J> iter(const I &i, const J &j)
    {
        return iterator<I, J>(i, j);
    }

    auto begin() const
    {
        std::cout << "zip begin: " << *a.begin() << "," << *b.begin() << std::endl;
        return iter(a.begin(), b.begin());
    }

    auto end() const
    {
        std::cout << "zip end: " << *a.end() << "," << *b.end() << std::endl;
        return iter(a.end(), b.end());
    }
};

template <typename S, typename T>
zipper<S, T> zip(const S &a, const T &b)
{
    return zipper<S, T>(a, b);
}

void test_1()
{
    const int n = 10;
    int idx = 0;
    // const auto r = range(n);
    const auto b = n;
    const auto e = b + n + 1;
    for (auto it : zip(range(n + 1), range(b, e)))
    {
        if (idx >= n + 1)
        {
            printf("%d >= %d\n", idx, n);
            assert(false);
        }

        printf("%d %d\n", std::get<0>(it), std::get<1>(it));
        ++idx;
    }
}

int main()
{
    test_1();
    return 0;
}
lgarithm commented 6 years ago

No plan to do more investigation on this ATM.

lgarithm commented 5 years ago

Note: clang++ doesn't have this problem.