.. _program_listing_file__tmp_ws_src_apex_containers_apex_containers_include_string_base_string.hpp: Program Listing for File base_string.hpp ======================================== |exhale_lsh| :ref:`Return to documentation for file ` (``/tmp/ws/src/apex_containers/apex_containers/include/string/base_string.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2017-2018 Apex.AI, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // 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. #ifndef STRING__BASE_STRING_HPP_ #define STRING__BASE_STRING_HPP_ #include #include #include #include #include #include #include #include #include namespace apex { template<::size64_t BUFFER_SIZE> class BaseString { public: using char_type = char8_t; BaseString(void) noexcept { // Ignore unneeded pointer to destination (void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size()); } constexpr static const ::size64_t npos = ULLONG_MAX; constexpr const ::char8_t * data() const noexcept { return &(m_string[0U]); } BaseString substr(const ::size64_t pos = 0U, const ::size64_t len = npos) const { BaseString retval; ::size64_t my_size = size(); if (pos > my_size) { throw std::out_of_range("pos > my_size"); } if (pos != my_size) { const ::size64_t chars_to_copy = std::min(my_size - pos, len); // Ignore unneeded returned pointer (void)memmove(retval.m_string, m_string + pos, chars_to_copy); } return retval; } // Comparisons int32_t compare( const ::size64_t pos1, const ::size64_t count1, const ::char8_t * const s, const ::size64_t count2 = npos) const { if (nullptr == s) { throw std::invalid_argument("s == NULL"); } const ::size64_t my_size = length(); if (pos1 > my_size) { throw std::out_of_range("pos > my_len"); } const ::size64_t _count1 = (npos == count1) ? my_size : count1; ::size64_t n_str = count2; if (npos == count2) { n_str = ::strnlen(s, APEX_STRING_SIZE); } const ::size64_t rlen = std::min(_count1, my_size - pos1); int32_t cmp_retval = ::strncmp(data() + pos1, s, std::min(rlen, n_str)); if (cmp_retval == 0) { if (rlen < n_str) { cmp_retval = -1; } if (rlen > n_str) { cmp_retval = 1; } } return cmp_retval; } inline int32_t compare(const ::char8_t * const s) const { return this->compare(0U, npos, s); } bool operator==(const char8_t * const rhs) const { return this->compare(rhs) == 0; } template<::size64_t LEN> int32_t compare( const ::size64_t pos1, const ::size64_t count1, const BaseString & str) const { return compare(pos1, count1, str.c_str()); } int32_t compare( const ::size64_t pos1, const ::size64_t count1, const std::string & str) const { return compare(pos1, count1, str.c_str()); } template<::size64_t LEN> int32_t compare(const BaseString & str) const { return compare(0U, npos, str); } int32_t compare(const std::string & str) const { return compare(0U, npos, str); } template<::size64_t LEN> bool operator==(const BaseString & rhs) const { const int32_t cmp_retval = compare(0U, npos, rhs); return cmp_retval == 0; } bool operator==(const std::string & rhs) const { const int32_t cmp_retval = compare(0U, npos, rhs.c_str()); return cmp_retval == 0; } bool operator!=(const char8_t * const rhs) const { return !operator==(rhs); } template<::size64_t LEN> bool operator!=(const BaseString & rhs) const { return !operator==(rhs); } bool operator!=(const std::string & rhs) const { return !operator==(rhs); } bool operator<(const char8_t * const rhs) const { return this->compare(rhs) < 0; } template<::size64_t LEN> bool operator<(const BaseString & rhs) const { const int32_t cmp_retval = compare(0U, npos, rhs); return cmp_retval < 0; } bool operator<(const std::string & rhs) const { const int32_t cmp_retval = compare(0U, npos, rhs); return cmp_retval < 0; } bool operator<=(const char8_t * const rhs) const { return !operator>(rhs); } template<::size64_t LEN> bool operator<=(const BaseString & rhs) const { return !operator>(rhs); } bool operator<=(const std::string & rhs) const { return !operator>(rhs); } bool operator>(const char8_t * const rhs) const { return this->compare(rhs) > 0; } template<::size64_t LEN> bool operator>(const BaseString & rhs) const { const int32_t cmp_retval = compare(0U, npos, rhs); return cmp_retval > 0; } bool operator>(const std::string & rhs) const { const int32_t cmp_retval = compare(0U, npos, rhs); return cmp_retval > 0; } bool operator>=(const char8_t * const rhs) const { return !operator<(rhs); } template bool operator>=(const BaseString & rhs) const { return !operator<(rhs); } bool operator>=(const std::string & rhs) const { return !operator<(rhs); } // Getters bool empty() const noexcept {return m_string[0U] == '\0';} const char8_t * c_str() const noexcept { return m_string; } char8_t * data() noexcept { return &m_string[0]; } inline constexpr size64_t capacity() const { return get_buffer_size() - 1U; } size64_t size() const noexcept { return ::strnlen(m_string, this->capacity()); } size64_t length() const noexcept { return size(); } char8_t & operator[](size64_t idx) { if (idx >= get_buffer_size()) { throw std::out_of_range("idx >= get_buffer_size()"); } return m_string[idx]; } char8_t operator[](size64_t idx) const { if (idx >= get_buffer_size()) { throw std::out_of_range("idx >= get_buffer_size()"); } return m_string[idx]; } inline constexpr ::size64_t get_buffer_size() const noexcept { return BUFFER_SIZE; } static inline constexpr ::size64_t get_buffer_size_static() noexcept { return BUFFER_SIZE; } operator std::string() const { return std::string(this->m_string); } // Removes all elements. void clear() noexcept { (void)std::memset(&(this->m_string[0U]), 0, this->get_buffer_size()); } protected: // The apex::BaseString iterator abs_iterator class below is based on // stackoverflow.com/questions/12092448/code-for-a-basic-random-access-iterator-based-on-pointers // This class is for internal apex::string use only template class abs_iterator : public std::iterator { public: using difference_type = typename std::iterator::difference_type; abs_iterator() : m_ptr(nullptr) { } explicit abs_iterator(Type * rhs) : m_ptr(rhs) { } abs_iterator(const abs_iterator & rhs) : m_ptr(rhs.m_ptr) { } inline abs_iterator & operator+=(difference_type rhs) { m_ptr += rhs; return *this; } inline abs_iterator & operator-=(difference_type rhs) { m_ptr -= rhs; return *this; } inline Type & operator*() const { return *m_ptr; } inline Type * operator->() const { return m_ptr; } inline Type & operator[](difference_type rhs) { return m_ptr[rhs]; } inline const Type & operator[](difference_type rhs) const { return m_ptr[rhs]; } inline abs_iterator & operator++() { ++m_ptr; return *this; } inline abs_iterator & operator--() { --m_ptr; return *this; } inline abs_iterator operator++(int) { abs_iterator tmp(*this); ++m_ptr; return tmp; } inline abs_iterator operator--(int) { abs_iterator tmp(*this); --m_ptr; return tmp; } inline difference_type operator-(const abs_iterator & rhs) const { return difference_type(m_ptr - rhs.m_ptr); } inline abs_iterator operator+(difference_type rhs) const { return abs_iterator(m_ptr + rhs); } inline abs_iterator operator-(difference_type rhs) const { return abs_iterator(m_ptr - rhs); } friend inline abs_iterator operator+(difference_type lhs, const abs_iterator & rhs) { return abs_iterator(lhs + rhs.m_ptr); } friend inline abs_iterator operator-(difference_type lhs, const abs_iterator & rhs) { return abs_iterator(lhs - rhs.m_ptr); } inline bool operator==(const abs_iterator & rhs) const { return m_ptr == rhs.m_ptr; } inline bool operator!=(const abs_iterator & rhs) const { return m_ptr != rhs.m_ptr; } inline bool operator>(const abs_iterator & rhs) const { return m_ptr > rhs.m_ptr; } inline bool operator<(const abs_iterator & rhs) const { return m_ptr < rhs.m_ptr; } inline bool operator>=(const abs_iterator & rhs) const { return m_ptr >= rhs.m_ptr; } inline bool operator<=(const abs_iterator & rhs) const { return m_ptr <= rhs.m_ptr; } private: Type * m_ptr; }; char8_t m_string[BUFFER_SIZE]; }; template typename ::std::basic_ostream & operator<<( std::basic_ostream & out_stream, const apex::BaseString & str) { return out_stream.write(str.c_str(), static_cast(str.size())); } template<::size64_t STRING_BUFFER_SIZE> inline ::float32_t stof(const apex::BaseString & str) noexcept { const float32_t value = strtof(str.c_str(), nullptr); return value; } template<::size64_t STRING_BUFFER_SIZE> inline ::float64_t stod(const apex::BaseString & str) noexcept { const float64_t value = strtod(str.c_str(), nullptr); return value; } template<::size64_t STRING_BUFFER_SIZE> inline ::int32_t stol(const apex::BaseString & str) noexcept { ::int64_t value = ::strtol(str.c_str(), nullptr, 10); if (value < static_cast(INT32_MIN)) { value = static_cast(INT32_MIN); } if (value > static_cast(INT32_MAX)) { value = static_cast(INT32_MAX); } return static_cast(value); } template<::size64_t STRING_BUFFER_SIZE> inline ::int64_t stoll(const apex::BaseString & str) noexcept { ::int64_t value = ::strtoll(str.c_str(), nullptr, 10); return value; } template<::size64_t STRING_BUFFER_SIZE> inline ::uint32_t stoul(const apex::BaseString & str) noexcept { ::uint64_t value = ::strtoul(str.c_str(), nullptr, 10); if (value > static_cast(UINT32_MAX)) { value = static_cast(UINT32_MAX); } return static_cast(value & UINT32_MAX); } template<::size64_t STRING_BUFFER_SIZE> inline ::uint64_t stoull(const apex::BaseString & str) noexcept { ::uint64_t value = ::strtoull(str.c_str(), nullptr, 10); return value; } } // namespace apex // Extending std::hash for apex::BaseString // cppcheck-suppress syntaxError namespace std { // hash combine function based on the boost implementation: // https://www.boost.org/doc/libs/1_68_0/boost/container_hash/hash.hpp template struct hash> { size_t operator()(const apex::BaseString & str) const noexcept { size64_t seed = str.size(); for (size64_t idx = 0U; idx < str.size(); idx++) { // cast char to unsigned char to size64_t for int array hashing seed ^= static_cast(static_cast(str[idx])) + 0x9e3779b9U + (seed << 6U) + (seed >> 2U); } return seed; } }; } // namespace std #endif // STRING__BASE_STRING_HPP_