Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:29:01

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_PROCESS_V2_CSTRING_REF_HPP
0006 #define BOOST_PROCESS_V2_CSTRING_REF_HPP
0007 
0008 #include <boost/process/v2/detail/config.hpp>
0009 
0010 #if defined(BOOST_PROCESS_V2_STANDALONE)
0011 #include <string_view>
0012 #else
0013 #include <boost/utility/string_view.hpp>
0014 #endif
0015 
0016 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0017 
0018 namespace detail
0019 {
0020 
0021 BOOST_CONSTEXPR static const char*     null_char_(char)     {return "";}
0022 BOOST_CONSTEXPR static const wchar_t*  null_char_(wchar_t)  {return L"";}
0023 BOOST_CONSTEXPR static const char16_t* null_char_(char16_t) {return u"";}
0024 BOOST_CONSTEXPR static const char32_t* null_char_(char32_t) {return U"";}
0025 
0026 #if defined(BOOST_PROCESS_V2_HAS_CHAR8_T)
0027 BOOST_CONSTEXPR static const char8_t* null_char_(char8_t) {return u8"";}
0028 #endif
0029 
0030 }
0031 
0032 #if defined(BOOST_PROCESS_V2_STANDALONE)
0033 using std::basic_string_view;
0034 using std::   string_view;
0035 using std::  wstring_view;
0036 #else
0037 using boost::basic_string_view;
0038 using boost::   string_view;
0039 using boost::  wstring_view;
0040 #endif
0041 
0042 
0043 /// Small wrapper for a null-terminated string that can be directly passed to C APIS
0044 /** This ref can only be modified by moving the front pointer. It does not store the 
0045  * size, but can detect values that can directly be passed to system APIs.
0046  * 
0047  * It can be constructed from a `char*` pointer or any class that has a `c_str()` 
0048  * member function, e.g. std::string or boost::static_string.
0049  * 
0050  */
0051 template<typename CharT, typename Traits = std::char_traits<CharT>>
0052 struct basic_cstring_ref
0053 {
0054     using value_type             = CharT;
0055     using traits_type            = Traits;
0056 
0057     BOOST_CONSTEXPR basic_cstring_ref() noexcept : view_(detail::null_char_(value_type{})) {}
0058     BOOST_CONSTEXPR basic_cstring_ref(std::nullptr_t) = delete;
0059 
0060     BOOST_CONSTEXPR basic_cstring_ref( const value_type* s ) : view_(s) {}
0061 
0062     template<typename Source,
0063             typename =
0064             typename std::enable_if<
0065                     std::is_same<const value_type,
0066                             typename std::remove_pointer<decltype(std::declval<Source>().c_str())>::type
0067                     >::value>::type>
0068     BOOST_CONSTEXPR basic_cstring_ref(Source && src) : view_(src.c_str()) {}
0069 
0070     BOOST_CONSTEXPR typename basic_string_view<value_type, Traits>::const_pointer c_str() const BOOST_NOEXCEPT
0071     {
0072         return this->data();
0073     }
0074 
0075     using string_view_type = basic_string_view<value_type, Traits>;
0076     constexpr operator string_view_type() const {return view_;}
0077 
0078     using pointer                =       CharT *;
0079     using const_pointer          = const CharT *;
0080     using reference              =       CharT &;
0081     using const_reference        = const CharT &;
0082     using const_iterator         = const_pointer;
0083     using iterator               = const_iterator;
0084     using const_reverse_iterator = typename std::reverse_iterator<const_iterator>;
0085     using reverse_iterator       = typename std::reverse_iterator<iterator>;
0086     using size_type              = std::size_t;
0087     using difference_type        = std::ptrdiff_t;
0088 
0089     static BOOST_CONSTEXPR size_type npos = -1;
0090 
0091     BOOST_CONSTEXPR const_iterator begin()  const BOOST_NOEXCEPT {return view_;};
0092     BOOST_CONSTEXPR const_iterator end()    const BOOST_NOEXCEPT {return view_ + length();};
0093     BOOST_CONSTEXPR const_iterator cbegin() const BOOST_NOEXCEPT {return view_;};
0094     BOOST_CONSTEXPR const_iterator cend()   const BOOST_NOEXCEPT {return view_ + length();};
0095     BOOST_CONSTEXPR const_reverse_iterator rbegin()  const BOOST_NOEXCEPT {return reverse_iterator(view_ + length());};
0096     BOOST_CONSTEXPR const_reverse_iterator rend()    const BOOST_NOEXCEPT {return reverse_iterator(view_);};
0097     BOOST_CONSTEXPR const_reverse_iterator crbegin() const BOOST_NOEXCEPT {return reverse_iterator(view_ + length());};
0098     BOOST_CONSTEXPR const_reverse_iterator crend()   const BOOST_NOEXCEPT {return reverse_iterator(view_);};
0099 
0100     BOOST_CONSTEXPR size_type size() const BOOST_NOEXCEPT {return length(); }
0101     BOOST_CONSTEXPR size_type length() const BOOST_NOEXCEPT {return traits_type::length(view_); }
0102     BOOST_CONSTEXPR size_type max_size() const BOOST_NOEXCEPT {return (std::numeric_limits<std::size_t>::max)() / sizeof(CharT); }
0103     BOOST_ATTRIBUTE_NODISCARD BOOST_CONSTEXPR bool empty() const BOOST_NOEXCEPT {return *view_ == *detail::null_char_(CharT{}); }
0104 
0105     BOOST_CONSTEXPR const_reference operator[](size_type pos) const  {return view_[pos] ;}
0106     BOOST_CXX14_CONSTEXPR const_reference at(size_type pos) const
0107     {
0108         if (pos >= size())
0109             throw_exception(std::out_of_range("cstring-view out of range"));
0110         return view_[pos];
0111     }
0112     BOOST_CONSTEXPR const_reference front() const  {return *view_;}
0113     BOOST_CONSTEXPR const_reference back()  const  {return view_[length() - 1];}
0114     BOOST_CONSTEXPR const_pointer data()    const BOOST_NOEXCEPT  {return view_;}
0115     BOOST_CXX14_CONSTEXPR void remove_prefix(size_type n)  {view_ = view_ + n;}
0116     void swap(basic_cstring_ref& s) BOOST_NOEXCEPT {std::swap(view_, s.view_);}
0117 
0118     size_type copy(value_type* s, size_type n, size_type pos = 0) const
0119     {
0120         return traits_type::copy(s, view_ + pos, n) - view_;
0121     }
0122     BOOST_CONSTEXPR basic_cstring_ref substr(size_type pos = 0) const
0123     {
0124         return basic_cstring_ref(view_ + pos);
0125     }
0126 
0127     BOOST_CONSTEXPR string_view_type substr(size_type pos, size_type length) const
0128     {
0129         return string_view_type(view_).substr(pos, length);
0130     }
0131 
0132     BOOST_CXX14_CONSTEXPR int compare(basic_cstring_ref x) const BOOST_NOEXCEPT
0133     {
0134         auto idx = 0u;
0135         for (; view_[idx] != null_char_()[0] && x[idx] != null_char_()[0]; idx++)
0136             if (!traits_type::eq(view_[idx], x[idx]))
0137                 return traits_type::lt(view_[idx], x[idx]) ? -1 : 1;
0138 
0139         return traits_type::to_int_type(view_[idx]) -
0140                traits_type::to_int_type(x[idx]); // will compare to null char of either.
0141     }
0142 
0143     BOOST_CXX14_CONSTEXPR bool starts_with(string_view_type x) const BOOST_NOEXCEPT
0144     {
0145         if (x.empty())
0146             return true;
0147 
0148         auto idx = 0u;
0149         for (; view_[idx] != null_char_()[0] && idx < x.size(); idx++)
0150             if (!traits_type::eq(view_[idx], x[idx]))
0151                 return false;
0152 
0153         return idx == x.size() || view_[idx] != null_char_()[0];
0154     }
0155     BOOST_CONSTEXPR bool starts_with(value_type x)       const BOOST_NOEXCEPT
0156     {
0157         return traits_type::eq(view_[0], x);
0158     }
0159 
0160     BOOST_CXX14_CONSTEXPR size_type find( CharT ch, size_type pos = 0 ) const BOOST_NOEXCEPT
0161     {
0162         for (auto p = view_ + pos; *p != *null_char_(); p++)
0163             if (traits_type::eq(*p, ch))
0164                 return p - view_;
0165         return npos;
0166     }
0167 
0168 
0169     friend BOOST_CXX14_CONSTEXPR bool operator==(basic_cstring_ref x, basic_cstring_ref y) BOOST_NOEXCEPT
0170     {
0171         std::size_t idx = 0u;
0172         for (idx = 0u; x[idx] != null_char_()[0] && y[idx] != null_char_()[0]; idx++)
0173             if (!traits_type::eq(x[idx], y[idx]))
0174                 return false;
0175         return x[idx] == y[idx];
0176     }
0177     friend BOOST_CXX14_CONSTEXPR bool operator!=(basic_cstring_ref x, basic_cstring_ref y) BOOST_NOEXCEPT
0178     {
0179         std::size_t idx = 0u;
0180         for (idx = 0u; x[idx] != null_char_()[0] &&
0181                        y[idx] != null_char_()[0]; idx++)
0182             if (!traits_type::eq(x[idx], y[idx]))
0183                 return true;
0184         return x[idx] != y[idx];
0185     }
0186     friend BOOST_CXX14_CONSTEXPR bool operator< (basic_cstring_ref x, basic_cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) <  0;}
0187     friend BOOST_CXX14_CONSTEXPR bool operator> (basic_cstring_ref x, basic_cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) >  0;}
0188     friend BOOST_CXX14_CONSTEXPR bool operator<=(basic_cstring_ref x, basic_cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) <= 0;}
0189     friend BOOST_CXX14_CONSTEXPR bool operator>=(basic_cstring_ref x, basic_cstring_ref y) BOOST_NOEXCEPT {return x.compare(y) >= 0;}
0190 
0191     // modifiers
0192     void clear() BOOST_NOEXCEPT { view_ =  null_char_(); }          // Boost extension
0193 
0194     std::basic_string<value_type, traits_type> to_string() const {
0195         return std::basic_string<CharT, Traits>(begin(), end());
0196     }
0197 
0198     template<typename Allocator>
0199     std::basic_string<value_type, traits_type, Allocator> to_string(const Allocator& a) const {
0200         return std::basic_string<value_type, traits_type, Allocator>(begin(), end(), a);
0201     }
0202 
0203   private:
0204     BOOST_CONSTEXPR static const_pointer   null_char_()         {return detail::null_char_(CharT{});}
0205     const_pointer view_;
0206 };
0207 
0208 template<class charT, class traits>
0209 inline std::basic_ostream<charT, traits>&
0210 operator<<(std::basic_ostream<charT, traits>& os,
0211            const basic_cstring_ref<charT,traits>& str)
0212 {
0213     return os << static_cast<basic_string_view<charT, traits>>(str);
0214 }
0215 
0216 template <class charT, class traits>
0217 std::size_t hash_value(basic_string_view<charT, traits> s) {
0218     return boost::hash_range(s.begin(), s.end());
0219 }
0220 
0221 using cstring_ref    = basic_cstring_ref<char>;
0222 using wcstring_ref   = basic_cstring_ref<wchar_t>;
0223 using u16cstring_ref = basic_cstring_ref<char16_t>;
0224 using u32cstring_ref = basic_cstring_ref<char32_t>;
0225 
0226 #if defined(BOOST_PROCESS_V2_HAS_CHAR8_T)
0227 using u8cstring_ref  = basic_cstring_ref<char8_t>;
0228 #endif
0229 
0230 BOOST_PROCESS_V2_END_NAMESPACE
0231 
0232 #endif //BOOST_PROCESS_V2_CSTRING_REF_HPP