c++c++23mdspan

How to create mdspan when indexing does not begin at 0?


I have binary-files of the form

Inhabitants_Year_1913_2023_Month_1_12_ZipCode_20000_20999.bin

with 100 * 12 * 1000 = 1.2 million lines, each line containing an int representing the number of inhabitants for a given year / month / ZipCode combination. I have a function that parses the file and returns a std::vector<int> with 1.2mn elements. I can create a lightweight view

auto my_md_span = std::mdspan(vec.data(), 100, 12, 1000);

and can pass it around to other functions and then access the right element via

my_md_span[year - 1913, month - 1, ZipCode - 20000]

Question: Is it possible to create a std::mdspan such that I can access the rigth element directly via my_md_span[year, month, ZipCode]?


Solution

  • First I would recommend using strong types for your axes:

    enum class Year  : uint16_t; // or a std::chrono::year
    enum class Month : uint8_t;  /*1-based*/ // or a std::chrono::month
    enum class Zip   : uint16_t;
    

    Then wrap (or inherit privately) the mdspan, adding/exposing just the needed method(s):

    class DataSet
    {
        mdspan< .... > data;
        
    public:
        int operator[]( Year y, Month m, Zip z ) const {
            return data[ uint16_t(y)-1913, uint8_t(m) - 1, uint16_t(z) - 20000 ];
        }
        // and of course add a constructor...
    };