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

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions