X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2Fsstring.hh;fp=src%2Fceph%2Fsrc%2Fcommon%2Fsstring.hh;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=3783cc1efac6c5c2586a69a99d00f9a54772f8e5;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/common/sstring.hh b/src/ceph/src/common/sstring.hh deleted file mode 100644 index 3783cc1..0000000 --- a/src/ceph/src/common/sstring.hh +++ /dev/null @@ -1,717 +0,0 @@ -/* - * This file is open source software, licensed to you under the terms - * of the Apache License, Version 2.0 (the "License"). See the NOTICE file - * distributed with this work for additional information regarding copyright - * ownership. You may not use this file except in compliance with the License. - * - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/* - * Copyright 2014 Cloudius Systems - */ -/* - * C++2014 dependencies removed. Uses of std::string_view adapted to - * boost::string_ref. Matt Benjamin - */ - -#ifndef SSTRING_HH_ -#define SSTRING_HH_ - -#include -#include - -#include "include/buffer.h" -#include "include/denc.h" - -template -class basic_sstring; - -using sstring = basic_sstring; - -template -inline string_type to_sstring(T value); - -template -class basic_sstring { - static_assert( - (std::is_same::value - || std::is_same::value - || std::is_same::value), - "basic_sstring only supports single byte char types"); - union contents { - struct external_type { - char_type* str; - Size size; - int8_t pad; - } external; - struct internal_type { - char_type str[max_size]; - int8_t size; - } internal; - static_assert(sizeof(external_type) <= sizeof(internal_type), "max_size too small"); - static_assert(max_size <= 127, "max_size too large"); - } u; - bool is_internal() const noexcept { - return u.internal.size >= 0; - } - bool is_external() const noexcept { - return !is_internal(); - } - const char_type* str() const { - return is_internal() ? u.internal.str : u.external.str; - } - char_type* str() { - return is_internal() ? u.internal.str : u.external.str; - } - - template - static inline string_type to_sstring_sprintf(T value, const char* fmt) { - char tmp[sizeof(value) * 3 + 2]; - auto len = std::sprintf(tmp, fmt, value); - using ch_type = typename string_type::value_type; - return string_type(reinterpret_cast(tmp), len); - } - - template - static inline string_type to_sstring(int value) { - return to_sstring_sprintf(value, "%d"); - } - - template - static inline string_type to_sstring(unsigned value) { - return to_sstring_sprintf(value, "%u"); - } - - template - static inline string_type to_sstring(long value) { - return to_sstring_sprintf(value, "%ld"); - } - - template - static inline string_type to_sstring(unsigned long value) { - return to_sstring_sprintf(value, "%lu"); - } - - template - static inline string_type to_sstring(long long value) { - return to_sstring_sprintf(value, "%lld"); - } - - template - static inline string_type to_sstring(unsigned long long value) { - return to_sstring_sprintf(value, "%llu"); - } - - template - static inline string_type to_sstring(float value) { - return to_sstring_sprintf(value, "%g"); - } - - template - static inline string_type to_sstring(double value) { - return to_sstring_sprintf(value, "%g"); - } - - template - static inline string_type to_sstring(long double value) { - return to_sstring_sprintf(value, "%Lg"); - } - - template - static inline string_type to_sstring(const char* value) { - return string_type(value); - } - - template - static inline string_type to_sstring(sstring value) { - return value; - } - -public: - using value_type = char_type; - using traits_type = std::char_traits; - using allocator_type = std::allocator; - using reference = char_type&; - using const_reference = const char_type&; - using pointer = char_type*; - using const_pointer = const char_type*; - using iterator = char_type*; - using const_iterator = const char_type*; - // FIXME: add reverse_iterator and friend - using difference_type = ssize_t; // std::make_signed_t can be too small - using size_type = Size; - static constexpr size_type npos = static_cast(-1); -public: - struct initialized_later {}; - - basic_sstring() noexcept { - u.internal.size = 0; - u.internal.str[0] = '\0'; - } - basic_sstring(const basic_sstring& x) { - if (x.is_internal()) { - u.internal = x.u.internal; - } else { - u.internal.size = -1; - u.external.str = reinterpret_cast(std::malloc(x.u.external.size + 1)); - if (!u.external.str) { - throw std::bad_alloc(); - } - std::copy(x.u.external.str, x.u.external.str + x.u.external.size + 1, u.external.str); - u.external.size = x.u.external.size; - } - } - basic_sstring(basic_sstring&& x) noexcept { - u = x.u; - x.u.internal.size = 0; - x.u.internal.str[0] = '\0'; - } - basic_sstring(initialized_later, size_t size) { - if (size_type(size) != size) { - throw std::overflow_error("sstring overflow"); - } - if (size + 1 <= sizeof(u.internal.str)) { - u.internal.str[size] = '\0'; - u.internal.size = size; - } else { - u.internal.size = -1; - u.external.str = reinterpret_cast(std::malloc(size + 1)); - if (!u.external.str) { - throw std::bad_alloc(); - } - u.external.size = size; - u.external.str[size] = '\0'; - } - } - basic_sstring(const char_type* x, size_t size) { - if (size_type(size) != size) { - throw std::overflow_error("sstring overflow"); - } - if (size + 1 <= sizeof(u.internal.str)) { - std::copy(x, x + size, u.internal.str); - u.internal.str[size] = '\0'; - u.internal.size = size; - } else { - u.internal.size = -1; - u.external.str = reinterpret_cast(std::malloc(size + 1)); - if (!u.external.str) { - throw std::bad_alloc(); - } - u.external.size = size; - std::copy(x, x + size, u.external.str); - u.external.str[size] = '\0'; - } - } - - basic_sstring(size_t size, char_type x) : basic_sstring(initialized_later(), size) { - memset(begin(), x, size); - } - - basic_sstring(const char* x) : basic_sstring(reinterpret_cast(x), std::strlen(x)) {} - basic_sstring(std::basic_string& x) : basic_sstring(x.c_str(), x.size()) {} - basic_sstring(std::initializer_list x) : basic_sstring(x.begin(), x.end() - x.begin()) {} - basic_sstring(const char_type* b, const char_type* e) : basic_sstring(b, e - b) {} - basic_sstring(const std::basic_string& s) - : basic_sstring(s.data(), s.size()) {} - template - basic_sstring(InputIterator first, InputIterator last) - : basic_sstring(initialized_later(), std::distance(first, last)) { - std::copy(first, last, begin()); - } - ~basic_sstring() noexcept { - if (is_external()) { - std::free(u.external.str); - } - } - basic_sstring& operator=(const basic_sstring& x) { - basic_sstring tmp(x); - swap(tmp); - return *this; - } - basic_sstring& operator=(basic_sstring&& x) noexcept { - if (this != &x) { - swap(x); - x.reset(); - } - return *this; - } - operator std::basic_string() const { - return { str(), size() }; - } - size_t size() const noexcept { - return is_internal() ? u.internal.size : u.external.size; - } - - size_t length() const noexcept { - return size(); - } - - size_t find(char_type t, size_t pos = 0) const noexcept { - const char_type* it = str() + pos; - const char_type* end = str() + size(); - while (it < end) { - if (*it == t) { - return it - str(); - } - it++; - } - return npos; - } - - size_t find(const basic_sstring& s, size_t pos = 0) const noexcept { - const char_type* it = str() + pos; - const char_type* end = str() + size(); - const char_type* c_str = s.str(); - const char_type* c_str_end = s.str() + s.size(); - - while (it < end) { - auto i = it; - auto j = c_str; - while ( i < end && j < c_str_end && *i == *j) { - i++; - j++; - } - if (j == c_str_end) { - return it - str(); - } - it++; - } - return npos; - } - - /** - * find_last_of find the last occurrence of c in the string. - * When pos is specified, the search only includes characters - * at or before position pos. - * - */ - size_t find_last_of (char_type c, size_t pos = npos) const noexcept { - const char_type* str_start = str(); - if (size()) { - if (pos >= size()) { - pos = size() - 1; - } - const char_type* p = str_start + pos + 1; - do { - p--; - if (*p == c) { - return (p - str_start); - } - } while (p != str_start); - } - return npos; - } - - /** - * Append a C substring. - * @param s The C string to append. - * @param n The number of characters to append. - * @return Reference to this string. - */ - basic_sstring& append (const char_type* s, size_t n) { - basic_sstring ret(initialized_later(), size() + n); - std::copy(begin(), end(), ret.begin()); - std::copy(s, s + n, ret.begin() + size()); - *this = std::move(ret); - return *this; - } - - /** - * Replace characters with a value of a C style substring. - * - */ - basic_sstring& replace(size_type pos, size_type n1, const char_type* s, - size_type n2) { - if (pos > size()) { - throw std::out_of_range("sstring::replace out of range"); - } - - if (n1 > size() - pos) { - n1 = size() - pos; - } - - if (n1 == n2) { - if (n2) { - std::copy(s, s + n2, begin() + pos); - } - return *this; - } - basic_sstring ret(initialized_later(), size() + n2 - n1); - char_type* p= ret.begin(); - std::copy(begin(), begin() + pos, p); - p += pos; - if (n2) { - std::copy(s, s + n2, p); - } - p += n2; - std::copy(begin() + pos + n1, end(), p); - *this = std::move(ret); - return *this; - } - - template - basic_sstring& replace (const_iterator i1, const_iterator i2, - InputIterator first, InputIterator last) { - if (i1 < begin() || i1 > end() || i2 < begin()) { - throw std::out_of_range("sstring::replace out of range"); - } - if (i2 > end()) { - i2 = end(); - } - - if (i2 - i1 == last - first) { - //in place replacement - std::copy(first, last, const_cast(i1)); - return *this; - } - basic_sstring ret(initialized_later(), size() + (last - first) - (i2 - i1)); - char_type* p = ret.begin(); - p = std::copy(cbegin(), i1, p); - p = std::copy(first, last, p); - std::copy(i2, cend(), p); - *this = std::move(ret); - return *this; - } - - iterator erase(iterator first, iterator last) { - size_t pos = first - begin(); - replace(pos, last - first, nullptr, 0); - return begin() + pos; - } - - /** - * Inserts additional characters into the string right before - * the character indicated by p. - */ - template - void insert(const_iterator p, InputIterator beg, InputIterator end) { - replace(p, p, beg, end); - } - - /** - * Returns a read/write reference to the data at the last - * element of the string. - * This function shall not be called on empty strings. - */ - reference - back() noexcept { - return operator[](size() - 1); - } - - /** - * Returns a read-only (constant) reference to the data at the last - * element of the string. - * This function shall not be called on empty strings. - */ - const_reference - back() const noexcept { - return operator[](size() - 1); - } - - basic_sstring substr(size_t from, size_t len = npos) const { - if (from > size()) { - throw std::out_of_range("sstring::substr out of range"); - } - if (len > size() - from) { - len = size() - from; - } - if (len == 0) { - return ""; - } - return { str() + from , len }; - } - - const char_type& at(size_t pos) const { - if (pos >= size()) { - throw std::out_of_range("sstring::at out of range"); - } - return *(str() + pos); - } - - char_type& at(size_t pos) { - if (pos >= size()) { - throw std::out_of_range("sstring::at out of range"); - } - return *(str() + pos); - } - - bool empty() const noexcept { - return u.internal.size == 0; - } - void reset() noexcept { - if (is_external()) { - std::free(u.external.str); - } - u.internal.size = 0; - u.internal.str[0] = '\0'; - } - - int compare(const basic_sstring& x) const noexcept { - auto n = traits_type::compare(begin(), x.begin(), std::min(size(), x.size())); - if (n != 0) { - return n; - } - if (size() < x.size()) { - return -1; - } else if (size() > x.size()) { - return 1; - } else { - return 0; - } - } - - int compare(size_t pos, size_t sz, const basic_sstring& x) const { - if (pos > size()) { - throw std::out_of_range("pos larger than string size"); - } - - sz = std::min(size() - pos, sz); - auto n = traits_type::compare(begin() + pos, x.begin(), std::min(sz, x.size())); - if (n != 0) { - return n; - } - if (sz < x.size()) { - return -1; - } else if (sz > x.size()) { - return 1; - } else { - return 0; - } - } - - void swap(basic_sstring& x) noexcept { - contents tmp; - tmp = x.u; - x.u = u; - u = tmp; - } - const char_type* c_str() const { - return str(); - } - const char_type* begin() const { return str(); } - const char_type* end() const { return str() + size(); } - const char_type* cbegin() const { return str(); } - const char_type* cend() const { return str() + size(); } - char_type* begin() { return str(); } - char_type* end() { return str() + size(); } - bool operator==(const basic_sstring& x) const { - return size() == x.size() && std::equal(begin(), end(), x.begin()); - } - bool operator!=(const basic_sstring& x) const { - return !operator==(x); - } - bool operator<(const basic_sstring& x) const { - return compare(x) < 0; - } - basic_sstring operator+(const basic_sstring& x) const { - basic_sstring ret(initialized_later(), size() + x.size()); - std::copy(begin(), end(), ret.begin()); - std::copy(x.begin(), x.end(), ret.begin() + size()); - return ret; - } - basic_sstring& operator+=(const basic_sstring& x) { - return *this = *this + x; - } - char_type& operator[](size_type pos) { - return str()[pos]; - } - const char_type& operator[](size_type pos) const { - return str()[pos]; - } - operator boost::basic_string_view() const { - return boost::basic_string_view(str(), size()); - } - template - friend inline string_type to_sstring(T value); -}; -template -constexpr Size basic_sstring::npos; - -template -inline -basic_sstring -operator+(const char(&s)[N], const basic_sstring& t) { - using sstring = basic_sstring; - // don't copy the terminating NUL character - sstring ret(typename sstring::initialized_later(), N-1 + t.size()); - auto p = std::copy(std::begin(s), std::end(s)-1, ret.begin()); - std::copy(t.begin(), t.end(), p); - return ret; -} - -template -static inline -size_t str_len(const char(&s)[N]) { return N - 1; } - -template -static inline -const char* str_begin(const char(&s)[N]) { return s; } - -template -static inline -const char* str_end(const char(&s)[N]) { return str_begin(s) + str_len(s); } - -template -static inline -const char_type* str_begin(const basic_sstring& s) { return s.begin(); } - -template -static inline -const char_type* str_end(const basic_sstring& s) { return s.end(); } - -template -static inline -size_type str_len(const basic_sstring& s) { return s.size(); } - -template -static inline -size_t str_len(const First& first, const Second& second, const Tail&... tail) { - return str_len(first) + str_len(second, tail...); -} - -template -inline -void swap(basic_sstring& x, - basic_sstring& y) noexcept -{ - return x.swap(y); -} - -template -inline -std::basic_ostream& -operator<<(std::basic_ostream& os, - const basic_sstring& s) { - return os.write(s.begin(), s.size()); -} - -template -inline -std::basic_istream& -operator>>(std::basic_istream& is, - basic_sstring& s) { - std::string tmp; - is >> tmp; - s = tmp; - return is; -} - -namespace std { - -template -struct hash> { - size_t operator()(const basic_sstring& s) const { - using traits_type = std::char_traits; - return std::hash>()(s); - } -}; - -} - -static inline -char* copy_str_to(char* dst) { - return dst; -} - -template -static inline -char* copy_str_to(char* dst, const Head& head, const Tail&... tail) { - return copy_str_to(std::copy(str_begin(head), str_end(head), dst), tail...); -} - -template -static String make_sstring(Args&&... args) -{ - String ret(sstring::initialized_later(), str_len(args...)); - copy_str_to(ret.begin(), args...); - return ret; -} - -template -inline string_type to_sstring(T value) { - return sstring::to_sstring(value); -} - - -// encode/decode -template -struct denc_traits> { -private: - using value_type = basic_sstring; -public: - static constexpr bool supported = true; - static constexpr bool featured = false; - static constexpr bool bounded = false; - - static void bound_encode(const value_type& s, size_t& p, uint64_t f=0) { - p += sizeof(Size) + s.size(); - } - - static void encode_nohead(const value_type& s, - buffer::list::contiguous_appender& p) - { - auto len = s.size(); - if (len) { - p.append(reinterpret_cast(s.c_str()), len); - } - } - - static void decode_nohead(size_t len, value_type& s, - buffer::ptr::iterator& p) - { - s.reset(); - if (len) { - s.append(reinterpret_cast(p.get_pos_add(len)), len); - } - } - - static void encode(const value_type& s, - buffer::list::contiguous_appender& p, - uint64_t f=0) - { - Size len = (Size)(s.size()); - ::denc(len, p); - if (len) { - p.append(reinterpret_cast(s.c_str()), len); - } - } - - static void decode(value_type& s, - buffer::ptr::iterator& p, - uint64_t f=0) - { - Size len; - ::denc(len, p); - decode_nohead(len, s, p); - } -}; - -#if 0 /* XXX conflicts w/Ceph types.h */ -template -inline -std::ostream& operator<<(std::ostream& os, const std::vector& v) { - bool first = true; - os << "{"; - for (auto&& elem : v) { - if (!first) { - os << ", "; - } else { - first = false; - } - os << elem; - } - os << "}"; - return os; -} -#endif - -#endif /* SSTRING_HH_ */