/************************************************************************************ * * * Copyright (c) 2014 - 2018 Axel Menzel * * * * This file is part of RTTR (Run Time Type Reflection) * * License: MIT License * * * * 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. * * * *************************************************************************************/ #ifndef RTTR_STRING_VIEW_IMPL_H_ #define RTTR_STRING_VIEW_IMPL_H_ #include "rttr/detail/misc/utility.h" namespace rttr { ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR basic_string_view::basic_string_view() RTTR_NOEXCEPT : m_data(nullptr), m_size(0) { } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR basic_string_view::basic_string_view(const basic_string_view& other) RTTR_NOEXCEPT : m_data(other.m_data), m_size(other.m_size) { } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR basic_string_view::basic_string_view(const CharT* str) : m_data(str), m_size(str ? traits_type::length(str) : 0) { } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR basic_string_view::basic_string_view(const CharT* str, size_type len) : m_data(str), m_size(len) { } ///////////////////////////////////////////////////////////////////////////////////////// template template basic_string_view::basic_string_view(const std::basic_string& str) RTTR_NOEXCEPT : m_data(str.data()), m_size(str.length()) { } ///////////////////////////////////////////////////////////////////////////////////////// template basic_string_view& basic_string_view::operator=(const basic_string_view& other) RTTR_NOEXCEPT { m_data = other.m_data; m_size = other.m_size; return *this; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CXX14_CONSTEXPR void basic_string_view::swap(basic_string_view& s) RTTR_NOEXCEPT { std::swap(m_data, s.m_data); std::swap(m_size, s.m_size); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_iterator basic_string_view::begin() const RTTR_NOEXCEPT { return m_data; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_iterator basic_string_view::cbegin() const RTTR_NOEXCEPT { return m_data; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_iterator basic_string_view::end() const RTTR_NOEXCEPT { return (m_data + m_size); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_iterator basic_string_view::cend() const RTTR_NOEXCEPT { return (m_data + m_size); } ///////////////////////////////////////////////////////////////////////////////////////// template typename basic_string_view::const_reverse_iterator basic_string_view::rbegin() const RTTR_NOEXCEPT { return const_reverse_iterator(end()); } ///////////////////////////////////////////////////////////////////////////////////////// template typename basic_string_view::const_reverse_iterator basic_string_view::crbegin() const RTTR_NOEXCEPT { return const_reverse_iterator(end()); } ///////////////////////////////////////////////////////////////////////////////////////// template typename basic_string_view::const_reverse_iterator basic_string_view::rend() const RTTR_NOEXCEPT { return const_reverse_iterator(begin()); } ///////////////////////////////////////////////////////////////////////////////////////// template typename basic_string_view::const_reverse_iterator basic_string_view::crend() const RTTR_NOEXCEPT { return const_reverse_iterator(begin()); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::size_type basic_string_view::size() const RTTR_NOEXCEPT { return m_size; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::size_type basic_string_view::length() const RTTR_NOEXCEPT { return m_size; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::size_type basic_string_view::max_size() const RTTR_NOEXCEPT { return m_size; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR bool basic_string_view::empty() const RTTR_NOEXCEPT { return (m_size == 0); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_reference basic_string_view::operator[](size_type pos) const RTTR_NOEXCEPT { return m_data[pos]; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_reference basic_string_view::front() const { return m_data[0]; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_reference basic_string_view::back() const { return m_data[m_size - 1]; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CONSTEXPR typename basic_string_view::const_pointer basic_string_view::data() const RTTR_NOEXCEPT { return m_data; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CXX14_CONSTEXPR void basic_string_view::remove_prefix(size_type n) RTTR_NOEXCEPT { if (n > m_size) n = m_size; m_data += n; m_size -= n; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CXX14_CONSTEXPR void basic_string_view::remove_suffix(size_type n) RTTR_NOEXCEPT { m_size -= (n > m_size ? m_size : n); } ///////////////////////////////////////////////////////////////////////////////////////// template template basic_string_view::operator std::basic_string() const { return std::basic_string(begin(), end()); } ///////////////////////////////////////////////////////////////////////////////////////// template template std::basic_string basic_string_view::to_string(const Allocator& a) const { return std::basic_string(begin(), end(), a); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CXX14_CONSTEXPR int basic_string_view::compare(basic_string_view v) const RTTR_NOEXCEPT { const int cmp = traits_type::compare(m_data, v.m_data, (std::min)(m_size, v.m_size)); return (cmp != 0 ? cmp : (m_size == v.m_size ? 0 : m_size < v.m_size ? -1 : 1)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_CXX14_CONSTEXPR int basic_string_view::compare(const CharT* c) const RTTR_NOEXCEPT { return compare(basic_string_view(c)); } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator==(basic_string_view lhs, basic_string_view rhs) RTTR_NOEXCEPT { if (lhs.size () == rhs.size ()) return (lhs.compare(rhs) == 0); else return false; } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator==(const char* lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) == rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator==(basic_string_view lhs, const char* rhs) RTTR_NOEXCEPT { return (lhs == basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator==(const std::basic_string& lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) == rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator==(basic_string_view lhs, const std::basic_string& rhs) RTTR_NOEXCEPT { return (lhs == basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator!=(basic_string_view lhs, basic_string_view rhs) RTTR_NOEXCEPT { if (lhs.size () != rhs.size ()) return true; else return (lhs.compare(rhs) != 0); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator!=(const char* lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) != rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator!=(basic_string_view lhs, const char* rhs) RTTR_NOEXCEPT { return (lhs != basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator!=(const std::basic_string& lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) != rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator!=(basic_string_view lhs, const std::basic_string& rhs) RTTR_NOEXCEPT { return (lhs != basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<=(basic_string_view lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (lhs.compare(rhs) <= 0); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<=(const char* lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) <= rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<=(basic_string_view lhs, const char* rhs) RTTR_NOEXCEPT { return (lhs <= basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<=(const std::basic_string& lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) <= rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<=(basic_string_view lhs, const std::basic_string& rhs) RTTR_NOEXCEPT { return (lhs <= basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>=(basic_string_view lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (lhs.compare(rhs) >= 0); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>=(const char* lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) >= rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>=(basic_string_view lhs, const char* rhs) RTTR_NOEXCEPT { return (lhs >= basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>=(const std::basic_string& lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) >= rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>=(basic_string_view lhs, const std::basic_string& rhs) RTTR_NOEXCEPT { return (lhs >= basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>(basic_string_view lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (lhs.compare(rhs) > 0); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>(const char* lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) > rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>(basic_string_view lhs, const char* rhs) RTTR_NOEXCEPT { return (lhs > basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>(const std::basic_string& lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) > rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator>(basic_string_view lhs, const std::basic_string& rhs) RTTR_NOEXCEPT { return (lhs > basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<(basic_string_view lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (lhs.compare(rhs) < 0); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<(const char* lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) < rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<(basic_string_view lhs, const char* rhs) RTTR_NOEXCEPT { return (lhs < basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<(const std::basic_string& lhs, basic_string_view rhs) RTTR_NOEXCEPT { return (basic_string_view(lhs) < rhs); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE RTTR_CXX14_CONSTEXPR bool operator<(basic_string_view lhs, const std::basic_string& rhs) RTTR_NOEXCEPT { return (lhs < basic_string_view(rhs)); } ///////////////////////////////////////////////////////////////////////////////////////// template RTTR_INLINE std::basic_string operator+(basic_string_view lhs, const std::basic_string& rhs) { return (lhs.to_string() + rhs); } template RTTR_INLINE std::basic_string operator+(const std::basic_string& lhs, basic_string_view rhs) { return (lhs + rhs.to_string()); } template RTTR_INLINE std::basic_string operator+(basic_string_view lhs, std::basic_string&& rhs) { return std::move(rhs.insert(0, lhs.data(), lhs.size())); } template RTTR_INLINE std::basic_string operator+(std::basic_string&& lhs, basic_string_view rhs) { return std::move(lhs.append(rhs.data(), rhs.size())); } ///////////////////////////////////////////////////////////////////////////////////////// namespace detail { template inline void insert_fill_chars(std::basic_ostream& os, std::size_t n) { enum { chunk_size = 8 }; CharT fill_chars[chunk_size]; std::fill_n(fill_chars, static_cast< std::size_t >(chunk_size), os.fill()); for (; n >= chunk_size && os.good(); n -= chunk_size) os.write(fill_chars, static_cast< std::size_t >(chunk_size)); if (n > 0 && os.good()) os.write(fill_chars, n); } ///////////////////////////////////////////////////////////////////////////////////////// template void insert_aligned(std::basic_ostream& os, const basic_string_view& str) { const std::size_t size = str.size(); const std::size_t alignment_size = static_cast< std::size_t >(os.width()) - size; const bool align_left = (os.flags() & std::basic_ostream::adjustfield) == std::basic_ostream::left; if (!align_left) { detail::insert_fill_chars(os, alignment_size); if (os.good()) os.write(str.data(), size); } else { os.write(str.data(), size); if (os.good()) detail::insert_fill_chars(os, alignment_size); } } } // end namespace detail ///////////////////////////////////////////////////////////////////////////////////////// template std::basic_ostream& operator<<(std::basic_ostream& os, basic_string_view str) { if (os.good()) { const std::size_t size = str.size(); const std::size_t w = static_cast< std::size_t >(os.width()); if (w <= size) os.write(str.data(), size); else detail::insert_aligned(os, str); os.width(0); } return os; } ///////////////////////////////////////////////////////////////////////////////////////// namespace detail { template <> struct hash { public: size_t operator()(const string_view& text) const { return generate_hash(text.data(), text.length()); } }; } // end namespace detail } // end namespace rttr ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// namespace std { template struct hash> { public: size_t operator()(const rttr::basic_string_view& value) const { return rttr::detail::generate_hash(value.data(), value.size()); } }; } // end namespace std ///////////////////////////////////////////////////////////////////////////////////////// #endif // RTTR_STRING_VIEW_IMPL_H_