view graph.cc @ 22:68cf11026c57

work on MDSpan
author Lewin Bormann <lbo@spheniscida.de>
date Sun, 09 Apr 2023 12:07:14 +0200
parents
children c3fb5f666e2d
line wrap: on
line source

#include "lib/exec.h"

#include <iterator>
#include <ranges>
#include <vector>

using namespace std;

template<typename T, typename Iter>
    requires random_access_iterator<Iter> && is_same_v<remove_cv_t<iter_value_t<Iter>>, remove_cv_t<T>>
class MDSpan {
    const Iter begin, end;
    const size_t Nx, Ny;

    public:

    template<typename R>
        requires is_same_v<ranges::iterator_t<R>, Iter>
    MDSpan(R&& rng, size_t Nx, size_t Ny) : begin(std::begin(rng)), end(std::end(rng)), Nx(Nx), Ny(Ny) {
        if (static_cast<signed long>(Nx * Ny) != end - begin) {
            throw string("bad dimensions");
        }
    }

    MDSpan(const MDSpan<T, Iter>& other) : begin(other.begin), end(other.end), Nx(other.Nx), Ny(other.Ny) {
        fmt::print("copy ctor\n");
    }

    const MDSpan<T, Iter>& operator=(const MDSpan<T, Iter>& other) = delete;

    T& operator[](size_t x, size_t y) {
        size_t ix = y * Nx + x;
        return begin[ix];
    }
};

template<typename Cont> requires ranges::range<Cont>
MDSpan<ranges::range_value_t<Cont>, ranges::iterator_t<Cont>> make_mdspan(Cont&& c, size_t x, size_t y) {
    return MDSpan<ranges::range_value_t<Cont>, ranges::iterator_t<Cont>>(c, x, y);
}

template<typename C>
concept constant_range = requires (C c) {
    { c.cbegin() } -> same_as<typename remove_cvref_t<C>::const_iterator>;
    { c.cend() } -> same_as<typename remove_cvref_t<C>::const_iterator>;
};

// Note: const specialization, uses static member type
template <typename Cont>
  requires constant_range<Cont>
MDSpan<const ranges::range_value_t<remove_cvref_t<Cont>>,
       typename remove_cvref_t<Cont>::const_iterator>
make_const_mdspan(Cont &&c, size_t x, size_t y) {
    return MDSpan<const ranges::range_value_t<remove_cvref_t<Cont>>,
                  typename remove_cvref_t<Cont>::const_iterator>(c, x, y);
}

// https://www.techiedelight.com/single-source-shortest-paths-bellman-ford-algorithm/
void bellman_ford() {
    const vector<int> v(42);

    //MDSpan<const int, vector<int>::const_iterator> mds = make_mdspan(v, 6, 7);
    auto mds = make_const_mdspan(v, 6, 7);

    //mds[3, 3] = 47;
    fmt::print("{}\n", mds[2,3]);
    //fmt::print("{}\n", mds[3,3]);
}

int main(void) {
    bellman_ford();

    return 0;
}