Skip to content

Non constexpr operator== #34

@mcskatkat

Description

@mcskatkat

First of all, great work.
This is probably the most thorough and streamlined backport of string_view publicly available, and I thank you for making it such.

I'm using it to replace Google's Abseil implementation, which still has some rough edges, and certainly drags in a lot of baggage for someone who just needs string_view.

One of my biggest motivations for using string_view is to facilitate string keyed associative containers with compile-time lookup, which opens the door to many useful things with zero runtime overhead. However, this requires constexpr comparison to be available...
This string_view delegates operator== to char_traits::compare() which is part of std, and as such is required NOT to be marked constexpr in pre-C++17 compilation. This is despite the compiler being perfectly able to perform constexpr comparisons.

In my case then, there is little value in backporting string_view if it doesn't backport its benefits too.

My workaround solution for this was deriving my own char_traits to implement a constexpr compare(), and then deriving my own string_view, as shown below. Perhaps you can think of a better way to backport constexpr comparison.

Thx

namespace my_own {
    namespace _detail {
        struct char_traits : public std::char_traits<char> {
            static constexpr int compare( const char_type* s1, const char_type* s2, std::size_t count ) {
                ... compiler specific ...
            }
        };
        using plain_string_view = nonstd::basic_string_view<char>;
    }
    class string_view : public nonstd::basic_string_view<char, _detail::char_traits> {
        using Base = nonstd::basic_string_view<char, _detail::char_traits>;
    public:
        using Base::Base;
        // need to provide own implicit conversions with std::string, since it uses the default char_traits
        operator string() const noexcept { return string(data(), size()); }
        string_view(string const & s) noexcept : Base(s.data(), s.size()) {}
        // provide implicit conversions with a string view that uses standard char_traits
        constexpr operator _detail::plain_string_view() const {return {data(), size()};}
        constexpr string_view(_detail::plain_string_view p) : Base(p.data(), p.size()) {}
    };
    inline std::ostream & operator<<(std::ostream & os, string_view sv) { return os << _detail::plain_string_view(sv); }
} // namespace

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions