Program Listing for File string_strict.hpp
↰ Return to documentation for file (/tmp/ws/src/apex_containers/apex_containers/include/string/string_strict.hpp
)
// 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__STRING_STRICT_HPP_
#define STRING__STRING_STRICT_HPP_
#include <apexutils/apexdef.h>
#include <apexutils/apex_string.h>
#include <apex_containers/visibility_control.hpp>
#include <stdexcept>
#include <cstring>
#include <algorithm>
#include <istream>
#include <ostream>
#include <string>
namespace apex
{
template<::size64_t STRING_BUFFER_SIZE>
class StringStrict : public BaseString<STRING_BUFFER_SIZE>
{
public:
using iterator =
typename apex::template BaseString<STRING_BUFFER_SIZE>::template abs_iterator<::char8_t>;
using const_iterator = typename
apex::template BaseString<STRING_BUFFER_SIZE>::template abs_iterator<const ::char8_t>;
StringStrict(void)
: apex::BaseString<STRING_BUFFER_SIZE>()
{
}
StringStrict(const ::size64_t n, const ::char8_t c)
: StringStrict()
{
if ((n != StringStrict::npos) && (n > this->capacity())) {
throw std::overflow_error("n > this->capacity()");
}
const ::size64_t chars_to_fill = (n < this->capacity()) ? n : this->capacity();
// Ignore unneeded returned pointer to destination
(void)memset(this->m_string, c, chars_to_fill);
}
StringStrict<STRING_BUFFER_SIZE> & operator+=(const ::char8_t * const src)
{
if (src != nullptr) {
const ::size64_t my_length = this->length();
const ::size64_t their_length = ::strnlen(src, this->get_buffer_size());
if ((my_length + their_length + 1U) <= this->get_buffer_size()) {
// Ignore returned self reference
(void)::memmove(&(this->m_string[0U]) + my_length, src, their_length);
this->m_string[my_length + their_length] = '\0';
} else {
throw std::overflow_error("Can't add too large string");
}
} else {
throw std::invalid_argument("Can't add NULL string");
}
return *this;
}
StringStrict<STRING_BUFFER_SIZE> & operator+=(const ::char8_t chr)
{
const ::size64_t my_length = this->length();
if ((my_length + 2U) <= this->get_buffer_size()) {
this->m_string[my_length] = chr;
this->m_string[my_length + 1U] = '\0';
} else {
throw std::overflow_error("Can't add too large string");
}
return *this;
}
StringStrict(const ::char8_t * const str) // NOLINT: constructors should be explicit, but
: StringStrict() // we want to have ability to convert a classic char pointer to apex::string
{
*this += str;
}
explicit StringStrict(const ::apex_string_t & str)
: StringStrict(str.c_str)
{
}
template<::size64_t LEN>
StringStrict(const apex::BaseString<LEN> & src) // NOLINT: constructors should be explicit, but
: StringStrict(src.c_str()) // we want to have ability to assign another string
{
}
explicit StringStrict(const BaseString<STRING_BUFFER_SIZE> & src)
: StringStrict(src.c_str())
{
}
// Addition
template<::size64_t LEN>
const StringStrict<STRING_BUFFER_SIZE + LEN> operator+(const StringStrict<LEN> & rhs) const
{
StringStrict<STRING_BUFFER_SIZE + LEN> retval(*this);
retval += rhs.c_str();
return retval;
}
template<::size64_t LEN>
auto
operator+(const char (& rhs)[LEN]) const noexcept
{
apex::StringStrict<STRING_BUFFER_SIZE + LEN> retval(*this);
retval += rhs;
return retval;
}
const apex::StringStrict<STRING_BUFFER_SIZE + APEX_STRING_SIZE>
operator+(const ::apex_string_t & rhs) const
{
StringStrict<STRING_BUFFER_SIZE + APEX_STRING_SIZE> retval(*this);
retval += rhs.c_str;
return retval;
}
// Increments
template<::size64_t LEN>
StringStrict & operator+=(const StringStrict<LEN> & rhs)
{
*this += rhs.c_str();
return *this;
}
StringStrict<STRING_BUFFER_SIZE> & operator+=(const apex_string_t & src)
{
*this += src.c_str;
return *this;
}
// Assignments
StringStrict<STRING_BUFFER_SIZE> & operator=(const BaseString<STRING_BUFFER_SIZE> & rhs)
{
// Ignore unneeded pointer to destination
(void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
*this += rhs.c_str();
return *this;
}
template<::size64_t LEN>
StringStrict<STRING_BUFFER_SIZE> & operator=(const BaseString<LEN> & rhs)
{
// Ignore unneeded pointer to destination
(void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
*this += rhs.c_str();
return *this;
}
StringStrict<STRING_BUFFER_SIZE> & operator=(const char8_t * const src)
{
// Ignore unneeded pointer to destination
(void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
*this += src;
return *this;
}
StringStrict<STRING_BUFFER_SIZE> & operator=(const apex_string_t & src)
{
// Ignore unneeded pointer to destination
(void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
*this += src.c_str;
return *this;
}
static apex::StringStrict<STRING_BUFFER_SIZE> to_string(const uint32_t value);
iterator begin() noexcept
{
return iterator(&(BaseString<STRING_BUFFER_SIZE>::m_string[0U]));
}
iterator end() noexcept
{
return iterator(
&(BaseString<STRING_BUFFER_SIZE>::m_string[0U]) + BaseString<STRING_BUFFER_SIZE>::size());
}
const_iterator cbegin() const noexcept
{
return const_iterator(&(BaseString<STRING_BUFFER_SIZE>::m_string[0U]));
}
const_iterator cend() const noexcept
{
return const_iterator(
&(BaseString<STRING_BUFFER_SIZE>::m_string[0U]) +
BaseString<STRING_BUFFER_SIZE>::size());
}
};
template<::size64_t LEN>
inline apex::StringStrict<APEX_STRING_SIZE + LEN>
operator+(const ::apex_string_t & lhs, const apex::StringStrict<LEN> & rhs)
{
StringStrict<APEX_STRING_SIZE + LEN> retval(lhs.c_str);
retval += rhs.c_str();
return retval;
}
template<::size64_t CSTR_LEN, ::size64_t APEX_STRING_LEN>
inline auto
operator+(const char (& lhs)[CSTR_LEN], const apex::StringStrict<APEX_STRING_LEN> & rhs)
{
StringStrict<CSTR_LEN + APEX_STRING_LEN> retval(lhs);
retval += rhs;
return retval;
}
using string_strict8_t = StringStrict<8U>;
static_assert(sizeof(string_strict8_t) == 8U, "sizeof(string_strict8_t) != 8U");
using string_strict16_t = StringStrict<16U>;
static_assert(sizeof(string_strict16_t) == 16U, "sizeof(string_strict16_t) != 16U");
using string_strict32_t = StringStrict<32U>;
static_assert(sizeof(string_strict32_t) == 32U, "sizeof(string_strict32_t) != 32U");
using string_strict64_t = StringStrict<64U>;
static_assert(sizeof(string_strict64_t) == 64U, "sizeof(string_strict64_t) != 64U");
using string_strict128_t = StringStrict<128U>;
static_assert(sizeof(string_strict128_t) == 128U, "sizeof(string_strict8_t) != 128U");
using string_strict256_t = StringStrict<APEX_STRING_SIZE>;
static_assert(sizeof(string_strict256_t) == 256U, "sizeof(string_strict256_t) != 256U");
template<size64_t STRING_BUFFER_SIZE>
typename ::std::istream & operator>>(
std::istream & in_stream,
apex::StringStrict<STRING_BUFFER_SIZE> & str)
{
typename apex::StringStrict<STRING_BUFFER_SIZE>::iterator it = str.begin();
return in_stream.getline(&(it[0U]), str.get_buffer_size());
}
} // namespace apex
namespace std
{
template<size64_t SizeN>
struct hash<apex::StringStrict<SizeN>>: std::hash<apex::BaseString<SizeN>> {};
} // namespace std
#endif // STRING__STRING_STRICT_HPP_