Program Listing for File string_silent.hpp

Return to documentation for file (/tmp/ws/src/apex_containers/apex_containers/include/string/string_silent.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_SILENT_HPP_
#define STRING__STRING_SILENT_HPP_

#include <apexutils/apexdef.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 String : 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>;

  String(void) noexcept
  : apex::BaseString<STRING_BUFFER_SIZE>()
  {
  }

  String(const ::size64_t n, const ::char8_t c) noexcept
  : String()
  {
    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);
  }

  String & operator+=(const char8_t * const src) noexcept
  {
    if (src != nullptr) {
      const ::size64_t my_length = this->length();
      if (my_length < this->capacity()) {
        const ::size64_t their_length = ::strnlen(src, this->capacity());
        if (their_length > 0U) {
          const ::size64_t max_copy_size = this->capacity() - my_length;
          const ::size64_t copy_size =
            (max_copy_size < their_length) ? max_copy_size : their_length;
          (void)::memmove(&(this->m_string[my_length]), src, copy_size);
          this->m_string[my_length + copy_size] = '\0';
        }
      }
    }
    return *this;
  }

  String & operator+=(const char8_t chr) noexcept
  {
    const ::size64_t my_length = this->length();
    if (my_length < this->capacity()) {
      this->m_string[my_length] = chr;
      this->m_string[my_length + 1] = '\0';
    }
    return *this;
  }

  String(const ::char8_t * const str) noexcept  // NOLINT: constructors should be explicit
  : String()  // but we want to have ability to convert a classic char pointer to apex::string
  {
    *this += str;
  }

  explicit String(const ::apex_string_t & str) noexcept
  : String(str.c_str)
  {
  }

  template<::size64_t LEN>
  String(const apex::BaseString<LEN> & src) noexcept // NOLINT: constructors should be explicit but we
  : String(src.c_str())  // want to to convert a different legth string to apex::string
  {
  }

  explicit String(const apex::String<STRING_BUFFER_SIZE> & src) noexcept
  : String(src.c_str())
  {
  }

  // Addition

  template<::size64_t LEN>
  const apex::String<STRING_BUFFER_SIZE + LEN>
  operator+(const apex::String<LEN> & rhs) const noexcept
  {
    apex::String<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::String<STRING_BUFFER_SIZE + LEN> retval(*this);
    retval += rhs;
    return retval;
  }

  const apex::String<STRING_BUFFER_SIZE + APEX_STRING_SIZE>
  operator+(const ::apex_string_t & rhs) const noexcept
  {
    apex::String<STRING_BUFFER_SIZE + APEX_STRING_SIZE> retval(*this);
    retval += rhs.c_str;
    return retval;
  }

  // Increments

  template<::size64_t LEN>
  apex::String<STRING_BUFFER_SIZE> & operator+=(const apex::String<LEN> & rhs) noexcept
  {
    *this += rhs.c_str();
    return *this;
  }

  apex::String<STRING_BUFFER_SIZE> & operator+=(const ::apex_string_t & src) noexcept
  {
    *this += src.c_str;
    return *this;
  }

  // Assignments

  String & operator=(const String & rhs) noexcept
  {
    // 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>
  apex::String<STRING_BUFFER_SIZE> & operator=(const apex::String<LEN> & rhs) noexcept
  {
    // Ignore unneeded pointer to destination
    (void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
    *this += rhs.c_str();
    return *this;
  }

  apex::String<STRING_BUFFER_SIZE> & operator=(const ::char8_t * const src) noexcept
  {
    // Ignore unneeded pointer to destination
    (void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
    *this += src;
    return *this;
  }

  apex::String<STRING_BUFFER_SIZE> & operator=(const ::apex_string_t & src) noexcept
  {
    // Ignore unneeded pointer to destination
    (void)::memset(&(this->m_string[0U]), 0, this->get_buffer_size());
    *this += src.c_str;
    return *this;
  }

  static apex::String<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::String<APEX_STRING_SIZE + LEN>
operator+(const ::apex_string_t & lhs, const apex::String<LEN> & rhs) noexcept
{
  String<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::String<APEX_STRING_LEN> & rhs)
{
  apex::String<CSTR_LEN + APEX_STRING_LEN> retval(lhs);
  retval += rhs;
  return retval;
}


using string8_t = String<8U>;
static_assert(sizeof(string8_t) == 8U, "sizeof(string8_t) != 8U");

using string16_t = String<16U>;
static_assert(sizeof(string16_t) == 16U, "sizeof(string16_t) != 16U");

using string32_t = String<32U>;
static_assert(sizeof(string32_t) == 32U, "sizeof(string32_t) != 32U");

using string64_t = String<64U>;
static_assert(sizeof(string64_t) == 64U, "sizeof(string64_t) != 64U");

using string128_t = String<128U>;
static_assert(sizeof(string128_t) == 128U, "sizeof(string8_t) != 128U");

using string256_t = String<APEX_STRING_SIZE>;
static_assert(sizeof(string256_t) == 256U, "sizeof(string256_t) != 256U");

template<size64_t STRING_BUFFER_SIZE>
typename ::std::istream & operator>>(
  std::istream & in_stream,
  apex::String<STRING_BUFFER_SIZE> & str)
{
  typename apex::String<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::String<SizeN>>: std::hash<apex::BaseString<SizeN>> {};
}  // namespace std

#endif  // STRING__STRING_SILENT_HPP_