Constexpr Sorted Unique Container Set as Array wrapper

  arrays, c++, compile-time, constructor, set

I want to create a constexpr container like std::array that is also sorted and all elements are unique. What I want to achieve is to check at compile time if the given data in the constructor are sorted and unique. I believe an std::set interface is more close to what I want to achieve but it is not constexpr (yet?). I plan to create a wrapper and use an std::array internally while I expose the std::set interface externally.

The current implementation looks like this

struct ConstexprSet
{
    constexpr ConstexprSet(const std::array<DataType, Size>& data) : mData(data)
    {
        if constexpr (!std::is_sorted(std::cbegin(mData), std::cend(mData)))
            throw std::runtime_error("Data not sorted");
        if constexpr (std::adjacent_find(std::cbegin(mData), std::cend(mData)) != std::cend(mData))
            throw std::runtime_error("Data not unique");
    }
    [[nodiscard]] constexpr auto GetData() const noexcept { return mData; }
private:
    std::array<DataType, Size> mData;
};

The error I get is that "this" is not a constant expression. If I change the mData with the data argument I get that data is not a constant expression. So what is a constant expression after all?
If I pass the whole array as an NTTP will this work?

The desired use case would be something like this

constexpr ConstexprSet features{"A"sv, "B"sv, "C"sv, "D"sv, "E"sv, "F"sv}; 

where the template arguments will be deduced from the input arguments like it is done in the std::array.

The following two examples should not compiled successfully and they should give comprehensive messages

constexpr ConstexprSet features{"A"sv, "D"sv, "C"sv, "B"sv, "E"sv, "F"sv}; // Data not sorted
constexpr ConstexprSet features{"A"sv, "B"sv, "B"sv, "D"sv, "E"sv, "F"sv}; // Data not unique

An other failed experiment was to create a constructor with an initializer list and pass it straight to the internal array but that does not work either…

Any ideas on how to overcome this problem or any other approach I can follow to achieve the desired behavior of this container would be more than welcome

The current draft I used for experimentation can be found here https://godbolt.org/z/1468cEjhW

Source: Windows Questions C++

LEAVE A COMMENT