add util::string_view
authorJacob Lifshay <programmerjake@gmail.com>
Fri, 16 Jun 2017 22:23:18 +0000 (15:23 -0700)
committerJacob Lifshay <programmerjake@gmail.com>
Fri, 16 Jun 2017 22:23:18 +0000 (15:23 -0700)
src/util/CMakeLists.txt
src/util/string_view.cpp [new file with mode: 0644]
src/util/string_view.h [new file with mode: 0644]

index 42d814dd557c8e2b08b893d4f04d41044fcfee44..3f0fea948eb4e922f6862fb137be5b7c76bf955b 100644 (file)
@@ -28,6 +28,7 @@ set(sources bit_intrinsics.cpp
             is_swappable.cpp
             optional.cpp
             soft_float.cpp
+            string_view.cpp
             variant.cpp
             void_t.cpp)
 add_library(util STATIC ${sources})
diff --git a/src/util/string_view.cpp b/src/util/string_view.cpp
new file mode 100644 (file)
index 0000000..143f3e5
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2017 Jacob Lifshay
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+#include "string_view.h"
diff --git a/src/util/string_view.h b/src/util/string_view.h
new file mode 100644 (file)
index 0000000..577f379
--- /dev/null
@@ -0,0 +1,606 @@
+/*
+* Copyright 2017 Jacob Lifshay
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+*/
+// derived and relicensed from
+// https://github.com/programmerjake/quick-shell/blob/d963cb5057e7013b8ff64db1cc42f464e3195644/util/string_view.h
+#ifndef UTIL_STRING_VIEW_H_
+#define UTIL_STRING_VIEW_H_
+
+#include <string>
+#include <iterator>
+#include <initializer_list>
+#include <utility>
+#include <stdexcept>
+#include <ostream>
+
+namespace vulkan_cpu
+{
+namespace util
+{
+template <typename Char_type, typename Traits_type = std::char_traits<Char_type>>
+class basic_string_view
+{
+public:
+    typedef Traits_type traits_type;
+    typedef Char_type value_type;
+    typedef Char_type *pointer;
+    typedef const Char_type *const_pointer;
+    typedef Char_type &reference;
+    typedef const Char_type &const_reference;
+    typedef const Char_type *const_iterator;
+    typedef const_iterator iterator;
+    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+    typedef const_reverse_iterator reverse_iterator;
+    typedef std::size_t size_type;
+    typedef std::ptrdiff_t difference_type;
+    static constexpr std::size_t npos = static_cast<std::size_t>(-1);
+
+private:
+    const Char_type *string_pointer;
+    std::size_t string_size;
+
+private:
+    static constexpr std::size_t constexpr_min(std::size_t a, std::size_t b) noexcept
+    {
+        return a < b ? a : b;
+    }
+
+public:
+    constexpr basic_string_view() noexcept : string_pointer(nullptr), string_size(0)
+    {
+    }
+    constexpr basic_string_view(const basic_string_view &) noexcept = default;
+    template <typename Allocator>
+    constexpr basic_string_view(
+        const std::basic_string<Char_type, Traits_type, Allocator> &str) noexcept
+        : string_pointer(str.data()),
+          string_size(str.size())
+    {
+    }
+    constexpr basic_string_view(const Char_type *str, std::size_t count) noexcept
+        : string_pointer(str),
+          string_size(count)
+    {
+    }
+    basic_string_view(const Char_type *str)
+        : string_pointer(str), string_size(traits_type::length(str))
+    {
+    }
+    basic_string_view &operator=(const basic_string_view &) noexcept = default;
+    constexpr const_iterator begin() const noexcept
+    {
+        return string_pointer;
+    }
+    constexpr const_iterator cbegin() const noexcept
+    {
+        return string_pointer;
+    }
+    constexpr const_iterator end() const noexcept
+    {
+        return string_pointer + string_size;
+    }
+    constexpr const_iterator cend() const noexcept
+    {
+        return string_pointer + string_size;
+    }
+    constexpr const_reverse_iterator rbegin() const noexcept
+    {
+        return const_reverse_iterator(end());
+    }
+    constexpr const_reverse_iterator crbegin() const noexcept
+    {
+        return const_reverse_iterator(end());
+    }
+    constexpr const_reverse_iterator rend() const noexcept
+    {
+        return const_reverse_iterator(begin());
+    }
+    constexpr const_reverse_iterator crend() const noexcept
+    {
+        return const_reverse_iterator(begin());
+    }
+    constexpr const Char_type &at(std::size_t index) const
+    {
+        return index >= string_size ?
+                   throw std::out_of_range("out of range in util::basic_string_view::at") :
+                   string_pointer[index];
+    }
+    constexpr const Char_type &operator[](std::size_t index) const noexcept
+    {
+        return string_pointer[index];
+    }
+    constexpr const Char_type &front() const noexcept
+    {
+        return string_pointer[0];
+    }
+    constexpr const Char_type &back() const noexcept
+    {
+        return string_pointer[string_size - 1];
+    }
+    constexpr const Char_type *data() const noexcept
+    {
+        return string_pointer;
+    }
+    constexpr std::size_t size() const noexcept
+    {
+        return string_size;
+    }
+    constexpr std::size_t length() const noexcept
+    {
+        return string_size;
+    }
+    constexpr std::size_t max_size() const noexcept
+    {
+        return static_cast<std::size_t>(-1) / sizeof(Char_type);
+    }
+    constexpr bool empty() const noexcept
+    {
+        return string_size == 0;
+    }
+    void remove_prefix(std::size_t n) noexcept
+    {
+        string_pointer += n;
+        string_size -= n;
+    }
+    void remove_suffix(std::size_t n) noexcept
+    {
+        string_size -= n;
+    }
+    void swap(basic_string_view &rt) noexcept
+    {
+        basic_string_view temp = *this;
+        *this = rt;
+        rt = temp;
+    }
+    std::size_t copy(Char_type *dest, std::size_t count, std::size_t pos = 0) const
+    {
+        if(pos > count)
+            throw std::out_of_range("out of range in util::basic_string_view::copy");
+        count = constexpr_min(count, string_size - pos);
+        for(std::size_t i = 0; i < count; i++)
+            traits_type::assign(dest[i], string_pointer[i + pos]);
+        return count;
+    }
+    constexpr basic_string_view substr(std::size_t pos = 0, std::size_t count = npos) const
+    {
+        return pos > string_size ?
+                   throw std::out_of_range("out of range in util::basic_string_view::substr") :
+                   basic_string_view(string_pointer + pos, constexpr_min(count, string_size - pos));
+    }
+
+private:
+    constexpr int compareHelper(int compare_result, basic_string_view rt) const noexcept
+    {
+        return compare_result != 0 ? compare_result : string_size > rt.string_size ?
+                                     1 :
+                                     string_size < rt.string_size ? -1 : 0;
+    }
+
+public:
+    constexpr int compare(basic_string_view rt) const noexcept
+    {
+        return compareHelper(
+            traits_type::compare(
+                string_pointer, rt.string_pointer, constexpr_min(string_size, rt.string_size)),
+            rt);
+    }
+    constexpr int compare(std::size_t pos1, std::size_t count1, basic_string_view rt) const
+    {
+        return substr(pos1, count1).compare(rt);
+    }
+    constexpr int compare(std::size_t pos1,
+                          std::size_t count1,
+                          basic_string_view rt,
+                          std::size_t pos2,
+                          std::size_t count2) const
+    {
+        return substr(pos1, count1).compare(rt.substr(pos2, count2));
+    }
+    constexpr int compare(const Char_type *rt) const
+    {
+        return compare(basic_string_view(rt));
+    }
+    constexpr int compare(std::size_t pos1, std::size_t count1, const Char_type *rt) const
+    {
+        return substr(pos1, count1).compare(rt);
+    }
+    constexpr int compare(std::size_t pos1,
+                          std::size_t count1,
+                          basic_string_view rt,
+                          std::size_t count2) const
+    {
+        return substr(pos1, count1).compare(basic_string_view(rt, count2));
+    }
+    std::size_t find(basic_string_view v, std::size_t pos = 0) const noexcept
+    {
+        if(pos > string_size)
+            return npos;
+        for(; string_size - pos < v.string_size; pos++)
+        {
+            bool found = true;
+            for(std::size_t i = 0; i < v.string_size; i++)
+            {
+                if(!traits_type::eq(string_pointer[i + pos], v.string_pointer[i]))
+                {
+                    found = false;
+                    break;
+                }
+            }
+            if(found)
+                return pos;
+        }
+        return npos;
+    }
+    std::size_t find(Char_type c, std::size_t pos = 0) const noexcept
+    {
+        return find(basic_string_view(std::addressof(c), 1), pos);
+    }
+    std::size_t find(const Char_type *s, std::size_t pos, std::size_t count) const noexcept
+    {
+        return find(basic_string_view(s, count), pos);
+    }
+    std::size_t find(const Char_type *s, std::size_t pos = 0) const
+    {
+        return find(basic_string_view(s), pos);
+    }
+    std::size_t rfind(basic_string_view v, std::size_t pos = npos) const noexcept
+    {
+        if(v.string_size > string_size)
+            return npos;
+        pos = constexpr_min(pos, string_size - v.string_size);
+        for(std::size_t i = 0, count = pos; i < count; i++, pos--)
+        {
+            bool found = true;
+            for(std::size_t i = 0; i < v.string_size; i++)
+            {
+                if(!traits_type::eq(string_pointer[i + pos], v.string_pointer[i]))
+                {
+                    found = false;
+                    break;
+                }
+            }
+            if(found)
+                return pos;
+        }
+        return npos;
+    }
+    std::size_t rfind(Char_type c, std::size_t pos = npos) const noexcept
+    {
+        return rfind(basic_string_view(std::addressof(c), 1), pos);
+    }
+    std::size_t rfind(const Char_type *s, std::size_t pos, std::size_t count) const noexcept
+    {
+        return rfind(basic_string_view(s, count), pos);
+    }
+    std::size_t rfind(const Char_type *s, std::size_t pos = npos) const
+    {
+        return rfind(basic_string_view(s), pos);
+    }
+    std::size_t find_first_of(basic_string_view v, std::size_t pos = 0) const noexcept
+    {
+        for(; pos < string_size; pos++)
+        {
+            if(v.find(string_pointer[pos]) != npos)
+                return pos;
+        }
+        return npos;
+    }
+    std::size_t find_first_of(Char_type v, std::size_t pos = 0) const noexcept
+    {
+        return find(v, pos);
+    }
+    std::size_t find_first_of(const Char_type *s, std::size_t pos, std::size_t count) const noexcept
+    {
+        return find_first_of(basic_string_view(s, count), pos);
+    }
+    std::size_t find_first_of(const Char_type *s, std::size_t pos = 0) const
+    {
+        return find_first_of(basic_string_view(s), pos);
+    }
+    std::size_t find_first_not_of(basic_string_view v, std::size_t pos = 0) const noexcept
+    {
+        for(; pos < string_size; pos++)
+        {
+            if(v.find(string_pointer[pos]) == npos)
+                return pos;
+        }
+        return npos;
+    }
+    std::size_t find_first_not_of(Char_type v, std::size_t pos = 0) const noexcept
+    {
+        return find_first_not_of(basic_string_view(std::addressof(v), 1), pos);
+    }
+    std::size_t find_first_not_of(const Char_type *s, std::size_t pos, std::size_t count) const
+        noexcept
+    {
+        return find_first_not_of(basic_string_view(s, count), pos);
+    }
+    std::size_t find_first_not_of(const Char_type *s, std::size_t pos = 0) const
+    {
+        return find_first_not_of(basic_string_view(s), pos);
+    }
+    std::size_t find_last_of(basic_string_view v, std::size_t pos = npos) const noexcept
+    {
+        if(empty())
+            return npos;
+        pos = constexpr_min(pos, string_size - 1);
+        for(std::size_t i = 0, count = pos; i < count; i++, pos--)
+        {
+            if(v.find(string_pointer[pos]) != npos)
+                return pos;
+        }
+        return npos;
+    }
+    std::size_t find_last_of(Char_type v, std::size_t pos = npos) const noexcept
+    {
+        return rfind(v, pos);
+    }
+    std::size_t find_last_of(const Char_type *s, std::size_t pos, std::size_t count) const noexcept
+    {
+        return find_last_of(basic_string_view(s, count), pos);
+    }
+    std::size_t find_last_of(const Char_type *s, std::size_t pos = npos) const
+    {
+        return find_last_of(basic_string_view(s), pos);
+    }
+    std::size_t find_last_not_of(basic_string_view v, std::size_t pos = npos) const noexcept
+    {
+        if(empty())
+            return npos;
+        pos = constexpr_min(pos, string_size - 1);
+        for(std::size_t i = 0, count = pos; i < count; i++, pos--)
+        {
+            if(v.find(string_pointer[pos]) == npos)
+                return pos;
+        }
+        return npos;
+    }
+    std::size_t find_last_not_of(Char_type v, std::size_t pos = npos) const noexcept
+    {
+        return find_last_not_of(basic_string_view(std::addressof(v), 1), pos);
+    }
+    std::size_t find_last_not_of(const Char_type *s, std::size_t pos, std::size_t count) const
+        noexcept
+    {
+        return find_last_not_of(basic_string_view(s, count), pos);
+    }
+    std::size_t find_last_not_of(const Char_type *s, std::size_t pos = npos) const
+    {
+        return find_last_not_of(basic_string_view(s), pos);
+    }
+    template <typename Allocator>
+    explicit operator std::basic_string<Char_type, Traits_type, Allocator>() const
+    {
+        return std::basic_string<Char_type, Traits_type, Allocator>(string_pointer, string_size);
+    }
+    template <typename Allocator>
+    friend std::basic_string<Char_type, Traits_type, Allocator> &operator+=(
+        std::basic_string<Char_type, Traits_type, Allocator> &l, basic_string_view r)
+    {
+        l.append(r.data(), r.size());
+        return l;
+    }
+    template <typename Allocator>
+    friend std::basic_string<Char_type, Traits_type, Allocator> &operator+=(
+        std::basic_string<Char_type, Traits_type, Allocator> &&l, basic_string_view r)
+    {
+        l.append(r.data(), r.size());
+        return l;
+    }
+};
+
+template <typename Char_type, typename Traits_type>
+constexpr std::size_t basic_string_view<Char_type, Traits_type>::npos;
+
+template <typename Char_type, typename Traits_type>
+constexpr bool operator==(basic_string_view<Char_type, Traits_type> a,
+                          basic_string_view<Char_type, Traits_type> b) noexcept
+{
+    return a.size() == b.size() && Traits_type::compare(a.data(), b.data(), a.size()) == 0;
+}
+
+template <typename Char_type, typename Traits_type>
+constexpr bool operator!=(basic_string_view<Char_type, Traits_type> a,
+                          basic_string_view<Char_type, Traits_type> b) noexcept
+{
+    return !operator==(a, b);
+}
+
+template <typename Char_type, typename Traits_type>
+constexpr bool operator<=(basic_string_view<Char_type, Traits_type> a,
+                          basic_string_view<Char_type, Traits_type> b) noexcept
+{
+    return a.compare(b) <= 0;
+}
+
+template <typename Char_type, typename Traits_type>
+constexpr bool operator>=(basic_string_view<Char_type, Traits_type> a,
+                          basic_string_view<Char_type, Traits_type> b) noexcept
+{
+    return a.compare(b) >= 0;
+}
+
+template <typename Char_type, typename Traits_type>
+constexpr bool operator<(basic_string_view<Char_type, Traits_type> a,
+                         basic_string_view<Char_type, Traits_type> b) noexcept
+{
+    return a.compare(b) < 0;
+}
+
+template <typename Char_type, typename Traits_type>
+constexpr bool operator>(basic_string_view<Char_type, Traits_type> a,
+                         basic_string_view<Char_type, Traits_type> b) noexcept
+{
+    return a.compare(b) > 0;
+}
+
+#define QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_NO_ALLOCATOR(...) \
+    template <typename Char_type, typename Traits_type>                                 \
+    bool operator==(__VA_ARGS__) noexcept                                               \
+    {                                                                                   \
+        return operator==(static_cast<basic_string_view<Char_type, Traits_type>>(a),    \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));   \
+    }                                                                                   \
+                                                                                        \
+    template <typename Char_type, typename Traits_type>                                 \
+    bool operator!=(__VA_ARGS__) noexcept                                               \
+    {                                                                                   \
+        return operator!=(static_cast<basic_string_view<Char_type, Traits_type>>(a),    \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));   \
+    }                                                                                   \
+                                                                                        \
+    template <typename Char_type, typename Traits_type>                                 \
+    bool operator<=(__VA_ARGS__) noexcept                                               \
+    {                                                                                   \
+        return operator<=(static_cast<basic_string_view<Char_type, Traits_type>>(a),    \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));   \
+    }                                                                                   \
+                                                                                        \
+    template <typename Char_type, typename Traits_type>                                 \
+    bool operator>=(__VA_ARGS__) noexcept                                               \
+    {                                                                                   \
+        return operator>=(static_cast<basic_string_view<Char_type, Traits_type>>(a),    \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));   \
+    }                                                                                   \
+                                                                                        \
+    template <typename Char_type, typename Traits_type>                                 \
+    bool operator<(__VA_ARGS__) noexcept                                                \
+    {                                                                                   \
+        return operator<(static_cast<basic_string_view<Char_type, Traits_type>>(a),     \
+                         static_cast<basic_string_view<Char_type, Traits_type>>(b));    \
+    }                                                                                   \
+                                                                                        \
+    template <typename Char_type, typename Traits_type>                                 \
+    bool operator>(__VA_ARGS__) noexcept                                                \
+    {                                                                                   \
+        return operator>(static_cast<basic_string_view<Char_type, Traits_type>>(a),     \
+                         static_cast<basic_string_view<Char_type, Traits_type>>(b));    \
+    }
+
+#define QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_WITH_ALLOCATOR(...) \
+    template <typename Char_type, typename Traits_type, typename Allocator>               \
+    bool operator==(__VA_ARGS__) noexcept                                                 \
+    {                                                                                     \
+        return operator==(static_cast<basic_string_view<Char_type, Traits_type>>(a),      \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));     \
+    }                                                                                     \
+                                                                                          \
+    template <typename Char_type, typename Traits_type, typename Allocator>               \
+    bool operator!=(__VA_ARGS__) noexcept                                                 \
+    {                                                                                     \
+        return operator!=(static_cast<basic_string_view<Char_type, Traits_type>>(a),      \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));     \
+    }                                                                                     \
+                                                                                          \
+    template <typename Char_type, typename Traits_type, typename Allocator>               \
+    bool operator<=(__VA_ARGS__) noexcept                                                 \
+    {                                                                                     \
+        return operator<=(static_cast<basic_string_view<Char_type, Traits_type>>(a),      \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));     \
+    }                                                                                     \
+                                                                                          \
+    template <typename Char_type, typename Traits_type, typename Allocator>               \
+    bool operator>=(__VA_ARGS__) noexcept                                                 \
+    {                                                                                     \
+        return operator>=(static_cast<basic_string_view<Char_type, Traits_type>>(a),      \
+                          static_cast<basic_string_view<Char_type, Traits_type>>(b));     \
+    }                                                                                     \
+                                                                                          \
+    template <typename Char_type, typename Traits_type, typename Allocator>               \
+    bool operator<(__VA_ARGS__) noexcept                                                  \
+    {                                                                                     \
+        return operator<(static_cast<basic_string_view<Char_type, Traits_type>>(a),       \
+                         static_cast<basic_string_view<Char_type, Traits_type>>(b));      \
+    }                                                                                     \
+                                                                                          \
+    template <typename Char_type, typename Traits_type, typename Allocator>               \
+    bool operator>(__VA_ARGS__) noexcept                                                  \
+    {                                                                                     \
+        return operator>(static_cast<basic_string_view<Char_type, Traits_type>>(a),       \
+                         static_cast<basic_string_view<Char_type, Traits_type>>(b));      \
+    }
+
+QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_NO_ALLOCATOR(
+    const Char_type *a, basic_string_view<Char_type, Traits_type> b)
+QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_NO_ALLOCATOR(
+    basic_string_view<Char_type, Traits_type> a, const Char_type *b)
+QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_WITH_ALLOCATOR(
+    basic_string_view<Char_type, Traits_type> a,
+    std::basic_string<Char_type, Traits_type, Allocator> b)
+QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_WITH_ALLOCATOR(
+    std::basic_string<Char_type, Traits_type, Allocator> a,
+    basic_string_view<Char_type, Traits_type> b)
+#undef QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_NO_ALLOCATOR
+#undef QUICK_SHELL_UTIL_STRING_VIEW_GENERATE_EXTRA_COMPARE_OPERATORS_WITH_ALLOCATOR
+
+template <typename Char_type, typename Traits_type>
+std::basic_ostream<Char_type, Traits_type> &operator<<(
+    std::basic_ostream<Char_type, Traits_type> &os, basic_string_view<Char_type, Traits_type> v)
+{
+    os << static_cast<std::basic_string<Char_type, Traits_type>>(v);
+    return os;
+}
+
+typedef basic_string_view<char> string_view;
+typedef basic_string_view<wchar_t> wstring_view;
+typedef basic_string_view<char16_t> u16string_view;
+typedef basic_string_view<char32_t> u32string_view;
+
+inline namespace literals
+{
+inline namespace string_view_literals
+{
+constexpr string_view operator"" _sv(const char *str, std::size_t length) noexcept
+{
+    return string_view(str, length);
+}
+constexpr wstring_view operator"" _sv(const wchar_t *str, std::size_t length) noexcept
+{
+    return wstring_view(str, length);
+}
+constexpr u16string_view operator"" _sv(const char16_t *str, std::size_t length) noexcept
+{
+    return u16string_view(str, length);
+}
+constexpr u32string_view operator"" _sv(const char32_t *str, std::size_t length) noexcept
+{
+    return u32string_view(str, length);
+}
+}
+}
+}
+}
+
+namespace std
+{
+template <typename Char_type, typename Traits_type>
+struct hash<vulkan_cpu::util::basic_string_view<Char_type, Traits_type>>
+{
+    std::size_t operator()(vulkan_cpu::util::basic_string_view<Char_type, Traits_type> v) const
+    {
+        typedef std::basic_string<Char_type, Traits_type> stringType;
+        return std::hash<stringType>(static_cast<stringType>(v));
+    }
+};
+}
+
+#endif /* UTIL_STRING_VIEW_H_ */
\ No newline at end of file