/** * Copyright (C) 2013-2015 Jessica James. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Written by Jessica James */ #if !defined _STRING_IMP_H_HEADER #define _STRING_IMP_H_HEADER /** * @file String_Imp.h * @brief Provides the implementations for String_Strict and String_Loose. * Note: Modification of this file is not supported in any way. */ #include "String.h" #if !defined va_copy #if defined __INTEL_COMPILER #pragma message("Warning: va_copy not properly defined. Assuming common implementation.") #define va_copy(dst, src) ((void)((dst) = (src))) #else #error "va_copy not defined." #endif // __INTEL_COMPILER #endif // va_copy #if !defined JUPITER_VSCPRINTF #if defined _WIN32 #define JUPITER_VSCPRINTF(format, format_args) _vscprintf(format, format_args) #define JUPITER_VSCWPRINTF(format, format_args) _vscwprintf(format, format_args) #else // _WIN32 #define JUPITER_VSCPRINTF(format, format_args) vsnprintf(nullptr, 0, format, format_args) #define JUPITER_VSCWPRINTF(format, format_args) vswprintf(nullptr, 0, format, format_args) #endif // _WIN32 #endif // JUPITER_VSCPRINTF /** * IMPLEMENTATION: * String_Strict */ template Jupiter::String_Strict::String_Strict() : Jupiter::String_Strict::String_Strict(size_t(0)) { } template Jupiter::String_Strict::String_Strict(size_t len) { Jupiter::Shift_String_Type::base = new T[len]; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::String_Type::length = 0; } template Jupiter::String_Strict::String_Strict(Jupiter::String_Strict &&source) : Jupiter::Shift_String_Type(std::move(source)) { } template Jupiter::String_Strict::String_Strict(const Jupiter::String_Strict &in) : Jupiter::String_Strict::String_Strict(in.ptr(), in.size()) { } template Jupiter::String_Strict::String_Strict(const Jupiter::Readable_String &in) : Jupiter::String_Strict::String_Strict(in.ptr(), in.size()) { } template Jupiter::String_Strict::String_Strict(const std::basic_string &in) : Jupiter::String_Strict::String_Strict(in.data(), in.size()) { } template Jupiter::String_Strict::String_Strict(const T *in, size_t len) : Jupiter::String_Strict::String_Strict(len) { while (Jupiter::String_Type::length != len) { Jupiter::String_Type::str[Jupiter::String_Type::length] = *in; Jupiter::String_Type::length++; in++; } } template Jupiter::String_Strict::String_Strict(const T *in) { if (in == nullptr) Jupiter::String_Type::length = 0; else Jupiter::String_Type::length = Jupiter::strlen(in); Jupiter::Shift_String_Type::base = new T[Jupiter::String_Type::length]; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; for (size_t index = 0; index != Jupiter::String_Type::length; index++, in++) Jupiter::String_Type::str[index] = *in; } template Jupiter::String_Strict::String_Strict(const Jupiter::DataBuffer &in) : String_Strict(reinterpret_cast(in.getHead()), in.size() / sizeof(T)) { } template Jupiter::String_Strict::String_Strict(const Jupiter::Readable_String &lhs, const T &rhs) : String_Strict(lhs.size() + 1) { const T *itr; const T *end; if (lhs.isNotEmpty()) { itr = lhs.ptr(); end = itr + lhs.size(); *Jupiter::String_Type::str = *itr; while (++itr != end) *++Jupiter::String_Type::str = *itr; ++Jupiter::String_Type::str; } *Jupiter::String_Type::str = rhs; Jupiter::String_Type::length = Jupiter::String_Type::str - Jupiter::Shift_String_Type::base + 1; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } template Jupiter::String_Strict::String_Strict(const Jupiter::Readable_String &lhs, const Jupiter::Readable_String &rhs) : String_Strict(lhs, rhs.ptr(), rhs.size()) { } template Jupiter::String_Strict::String_Strict(const Jupiter::Readable_String &lhs, const std::basic_string &rhs) : String_Strict(lhs, rhs.data(), rhs.size()) { } template Jupiter::String_Strict::String_Strict(const Jupiter::Readable_String &lhs, const T *rhs) : String_Strict(lhs, rhs, Jupiter::strlen(rhs)) { } template Jupiter::String_Strict::String_Strict(const Jupiter::Readable_String &lhs, const T *rhs, size_t rhs_size) : String_Strict(lhs.size() + rhs_size) { const T *itr; const T *end; if (lhs.isNotEmpty()) { itr = lhs.ptr(); end = itr + lhs.size(); *Jupiter::String_Type::str = *itr; while (++itr != end) *++Jupiter::String_Type::str = *itr; ++Jupiter::String_Type::str; } if (rhs_size != 0) { itr = rhs; end = itr + rhs_size; *Jupiter::String_Type::str = *itr; while (++itr != end) *++Jupiter::String_Type::str = *itr; ++Jupiter::String_Type::str; } Jupiter::String_Type::length = Jupiter::String_Type::str - Jupiter::Shift_String_Type::base; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } // vformat() template<> size_t inline Jupiter::String_Strict::vformat(const char *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSizeNoCopy(minLen + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vsnprintf(Jupiter::String_Type::str, minLen + 1, format, args); if (minLen < 0) return 0; return Jupiter::String_Type::length = minLen; } template<> size_t inline Jupiter::String_Strict::vformat(const wchar_t *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCWPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSizeNoCopy(minLen + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vswprintf(Jupiter::String_Type::str, minLen + 1, format, args); if (minLen < 0) return 0; return Jupiter::String_Type::length = minLen; } template size_t Jupiter::String_Strict::vformat(const T *format, va_list args) { return 0; } // avformat() template<> size_t inline Jupiter::String_Strict::avformat(const char *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSize(Jupiter::String_Type::length + minLen + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen + 1, format, args); if (minLen <= 0) return 0; Jupiter::String_Type::length += minLen; return minLen; } template<> size_t inline Jupiter::String_Strict::avformat(const wchar_t *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCWPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSize(minLen + Jupiter::String_Type::length + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vswprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen + 1, format, args); if (minLen <= 0) return 0; Jupiter::String_Type::length += minLen; return minLen; } template size_t Jupiter::String_Strict::avformat(const T *format, va_list args) { return 0; } template Jupiter::String_Strict Jupiter::String_Strict::Format(const T *format, ...) { String_Strict r; va_list args; va_start(args, format); r.vformat(format, args); va_end(args); return r; } template typename Jupiter::String_Strict Jupiter::String_Strict::substring(size_t pos) const { return Jupiter::String_Strict::substring(*this, pos); } template typename Jupiter::String_Strict Jupiter::String_Strict::substring(size_t pos, size_t len) const { return Jupiter::String_Strict::substring(*this, pos, len); } template typename Jupiter::String_Strict Jupiter::String_Strict::substring(const Jupiter::Readable_String &in, size_t pos) { return Jupiter::String_Type::template substring(in, pos); } template typename Jupiter::String_Strict Jupiter::String_Strict::substring(const T *in, size_t pos) { return Jupiter::String_Type::template substring(in, pos); } template typename Jupiter::String_Strict Jupiter::String_Strict::substring(const Jupiter::Readable_String &in, size_t pos, size_t len) { return Jupiter::String_Type::template substring(in, pos, len); } template typename Jupiter::String_Strict Jupiter::String_Strict::substring(const T *in, size_t pos, size_t len) { return Jupiter::String_Type::template substring(in, pos, len); } template Jupiter::String_Strict Jupiter::String_Strict::getWord(size_t pos, const T *whitespace) const { return Jupiter::String_Strict::getWord(*this, pos, whitespace); } template Jupiter::String_Strict Jupiter::String_Strict::getWord(const Jupiter::Readable_String &in, size_t pos, const T *whitespace) { return Jupiter::Readable_String::template getWord(in, pos, whitespace); } template Jupiter::String_Strict Jupiter::String_Strict::getWord(const T *in, size_t pos, const T *whitespace) { return Jupiter::Readable_String::template getWord(in, pos, whitespace); } template Jupiter::String_Strict Jupiter::String_Strict::getToken(size_t pos, const T &token) const { return Jupiter::String_Strict::getToken(*this, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::getToken(size_t pos, const Jupiter::Readable_String &token) const { return Jupiter::String_Strict::getToken(*this, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::getToken(const Jupiter::Readable_String &in, size_t pos, const T &token) { return Jupiter::Readable_String::template getToken(in, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::getToken(const Jupiter::Readable_String &in, size_t pos, const Jupiter::Readable_String &token) { return Jupiter::Readable_String::template getToken(in, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::gotoWord(size_t pos, const T *whitespace) const { return Jupiter::String_Strict::gotoWord(*this, pos, whitespace); } template Jupiter::String_Strict Jupiter::String_Strict::gotoWord(const Jupiter::Readable_String &in, size_t pos, const T *whitespace) { return Jupiter::Readable_String::template gotoWord(in, pos, whitespace); } template Jupiter::String_Strict Jupiter::String_Strict::gotoToken(size_t pos, const T &token) const { return Jupiter::String_Strict::gotoToken(*this, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::gotoToken(size_t pos, const Jupiter::Readable_String &token) const { return Jupiter::String_Strict::gotoToken(*this, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::gotoToken(const Jupiter::Readable_String &in, size_t pos, const T &token) { return Jupiter::Readable_String::template gotoToken(in, pos, token); } template Jupiter::String_Strict Jupiter::String_Strict::gotoToken(const Jupiter::Readable_String &in, size_t pos, const Jupiter::Readable_String &token) { return Jupiter::Readable_String::template gotoToken(in, pos, token); } // tokenize template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Strict::tokenize(const T &separator) const { return Jupiter::String_Strict::tokenize(*this, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Strict::tokenize(const Jupiter::Readable_String &separator) const { return Jupiter::String_Strict::tokenize(*this, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Strict::tokenize(const T *separator, size_t separator_size) const { return Jupiter::String_Strict::tokenize(*this, separator, separator_size); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Strict::tokenize(const Jupiter::Readable_String &in, const T &token) { return Jupiter::Readable_String::template tokenize(in, token); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Strict::tokenize(const Jupiter::Readable_String &in, const Jupiter::Readable_String &separator) { return Jupiter::Readable_String::template tokenize(in, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Strict::tokenize(const Jupiter::Readable_String &in, const T *separator, size_t separator_size) { return Jupiter::Readable_String::template tokenize(in, separator, separator_size); } // Operators template inline Jupiter::String_Strict Jupiter::String_Strict::operator+(const T &rhs) const { return Jupiter::operator+(*this, rhs); } template inline Jupiter::String_Strict Jupiter::String_Strict::operator+(const Jupiter::String_Strict &rhs) const { return Jupiter::String_Strict::operator+(reinterpret_cast &>(rhs)); } template inline Jupiter::String_Strict Jupiter::String_Strict::operator+(const Jupiter::Readable_String &rhs) const { return Jupiter::operator+(*this, rhs); } template inline Jupiter::String_Strict Jupiter::String_Strict::operator+(const std::basic_string &rhs) const { return Jupiter::operator+(*this, rhs); } template inline Jupiter::String_Strict Jupiter::String_Strict::operator+(const T *rhs) const { return Jupiter::operator+(*this, rhs); } #if defined JUPITER_STRING_STRICT_OPERATOR_PLUS template static inline Jupiter::String_Strict Jupiter::operator+(const Jupiter::Readable_String &lhs, const T &rhs) { return Jupiter::String_Strict(lhs, rhs); } template static inline Jupiter::String_Strict Jupiter::operator+(const Jupiter::Readable_String &lhs, const Jupiter::Readable_String &rhs) { return Jupiter::String_Strict(lhs, rhs); } template static inline Jupiter::String_Strict Jupiter::operator+(const Jupiter::Readable_String &lhs, const std::basic_string &rhs) { return Jupiter::String_Strict(lhs, rhs); } template static inline Jupiter::String_Strict Jupiter::operator+(const Jupiter::Readable_String &lhs, const T *rhs) { return Jupiter::String_Strict(lhs, rhs); } #endif // JUPITER_STRING_STRICT_OPERATOR_PLUS template const Jupiter::String_Strict Jupiter::String_Strict::empty = Jupiter::String_Strict(); // Jupiter::DataBuffer specialization template<> struct _Jupiter_DataBuffer_partial_specialization_impl { template static void push(Jupiter::DataBuffer *buffer, const Jupiter::String_Strict *data) { _Jupiter_DataBuffer_partial_specialization_impl::push(buffer, data); }; template static Jupiter::String_Strict interpret(uint8_t *&head) { size_t size_ = *reinterpret_cast(head); head += sizeof(size_t); Jupiter::String_Strict r = Jupiter::String_Strict(reinterpret_cast(head), size_); head += size_; return r; } }; /** * IMPLEMENTATION: * String_Loose */ template Jupiter::String_Loose::String_Loose() : Jupiter::String_Loose::String_Loose(Jupiter::String_Loose::start_size) { } template Jupiter::String_Loose::String_Loose(Jupiter::String_Loose &&source) : Jupiter::Shift_String_Type(std::move(source)) { Jupiter::String_Loose::strSize = source.strSize; source.strSize = 0; } template Jupiter::String_Loose::String_Loose(size_t len) { if (len > Jupiter::String_Loose::start_size) Jupiter::String_Loose::strSize = len; else Jupiter::String_Loose::strSize = Jupiter::String_Loose::start_size; Jupiter::Shift_String_Type::base = new T[Jupiter::String_Loose::strSize]; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::String_Type::length = 0; } template Jupiter::String_Loose::String_Loose(const Jupiter::String_Loose &in) { Jupiter::String_Loose::strSize = in.strSize; Jupiter::Shift_String_Type::base = new T[Jupiter::String_Loose::strSize]; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; for (Jupiter::String_Type::length = 0; Jupiter::String_Type::length != in.length; Jupiter::String_Type::length++) Jupiter::String_Type::str[Jupiter::String_Type::length] = in.get(Jupiter::String_Type::length); } template Jupiter::String_Loose::String_Loose(const Jupiter::Readable_String &in) : Jupiter::String_Loose::String_Loose(in.ptr(), in.size()) { } template Jupiter::String_Loose::String_Loose(const std::basic_string &in) : Jupiter::String_Loose::String_Loose(in.data(), in.size()) { } template Jupiter::String_Loose::String_Loose(const T *in, size_t len) : Jupiter::String_Loose::String_Loose(len) { while (Jupiter::String_Type::length != len) { Jupiter::String_Type::str[Jupiter::String_Type::length] = *in; ++in, ++Jupiter::String_Type::length; } } template Jupiter::String_Loose::String_Loose(const T *in) { if (in == nullptr) { Jupiter::String_Loose::strSize = Jupiter::String_Loose::start_size; Jupiter::Shift_String_Type::base = new T[Jupiter::String_Loose::strSize]; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; Jupiter::String_Type::length = 0; } else { Jupiter::String_Type::length = Jupiter::strlen(in); Jupiter::String_Loose::strSize = getPowerTwo32(Jupiter::String_Type::length); if (Jupiter::String_Loose::strSize < Jupiter::String_Loose::start_size) Jupiter::String_Loose::strSize = Jupiter::String_Loose::start_size; Jupiter::Shift_String_Type::base = new T[Jupiter::String_Loose::strSize]; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; for (Jupiter::String_Type::length = 0; *in != 0; Jupiter::String_Type::length++, in++) Jupiter::String_Type::str[Jupiter::String_Type::length] = *in; } } template Jupiter::String_Loose::String_Loose(const Jupiter::DataBuffer &in) : String_Loose(reinterpret_cast(in.getHead()), in.size() / sizeof(T)) { } template Jupiter::String_Loose::String_Loose(const Jupiter::Readable_String &lhs, const T &rhs) : String_Loose(lhs.size() + 1) { const T *itr; const T *end; if (lhs.isNotEmpty()) { itr = lhs.ptr(); end = itr + lhs.size(); *Jupiter::String_Type::str = *itr; while (++itr != end) *++Jupiter::String_Type::str = *itr; ++Jupiter::String_Type::str; } *Jupiter::String_Type::str = rhs; Jupiter::String_Type::length = Jupiter::String_Type::str - Jupiter::Shift_String_Type::base + 1; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } template Jupiter::String_Loose::String_Loose(const Jupiter::Readable_String &lhs, const Jupiter::Readable_String &rhs) : String_Loose(lhs, rhs.ptr(), rhs.size()) { } template Jupiter::String_Loose::String_Loose(const Jupiter::Readable_String &lhs, const std::basic_string &rhs) : String_Loose(lhs, rhs.data(), rhs.size()) { } template Jupiter::String_Loose::String_Loose(const Jupiter::Readable_String &lhs, const T *rhs) : String_Loose(lhs, rhs, Jupiter::strlen(rhs)) { } template Jupiter::String_Loose::String_Loose(const Jupiter::Readable_String &lhs, const T *rhs, size_t rhs_size) : String_Loose(lhs.size() + rhs_size) { const T *itr; const T *end; if (lhs.isNotEmpty()) { itr = lhs.ptr(); end = itr + lhs.size(); *Jupiter::String_Type::str = *itr; while (++itr != end) *++Jupiter::String_Type::str = *itr; ++Jupiter::String_Type::str; } if (rhs_size != 0) { itr = rhs; end = itr + rhs_size; *Jupiter::String_Type::str = *itr; while (++itr != end) *++Jupiter::String_Type::str = *itr; ++Jupiter::String_Type::str; } Jupiter::String_Type::length = Jupiter::String_Type::str - Jupiter::Shift_String_Type::base; Jupiter::String_Type::str = Jupiter::Shift_String_Type::base; } template bool Jupiter::String_Loose::setBufferSize(size_t len) { return Jupiter::Shift_String_Type::setBufferSize(Jupiter::String_Loose::strSize = getPowerTwo32(len)); } template bool Jupiter::String_Loose::setBufferSizeNoCopy(size_t len) { return Jupiter::Shift_String_Type::setBufferSizeNoCopy(Jupiter::String_Loose::strSize = getPowerTwo32(len)); } // vformat() template<> size_t inline Jupiter::String_Loose::vformat(const char *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSizeNoCopy(minLen + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vsnprintf(Jupiter::String_Type::str, minLen + 1, format, args); if (minLen < 0) return 0; return Jupiter::String_Type::length = minLen; } template<> size_t inline Jupiter::String_Loose::vformat(const wchar_t *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCWPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSizeNoCopy(minLen + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vswprintf(Jupiter::String_Type::str, minLen + 1, format, args); if (minLen < 0) return 0; return Jupiter::String_Type::length = minLen; } template size_t Jupiter::String_Loose::capacity() const { return Jupiter::String_Loose::strSize; } template size_t Jupiter::String_Loose::vformat(const T *format, va_list args) { return 0; } // avformat() template<> size_t inline Jupiter::String_Loose::avformat(const char *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSize(Jupiter::String_Type::length + minLen + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vsnprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen + 1, format, args); if (minLen <= 0) return 0; Jupiter::String_Type::length += minLen; return minLen; } template<> size_t inline Jupiter::String_Loose::avformat(const wchar_t *format, va_list args) { int minLen; va_list sargs; va_copy(sargs, args); minLen = JUPITER_VSCWPRINTF(format, sargs); va_end(sargs); if (minLen < 0) return 0; // We simply can not work with this. this->setBufferSize(minLen + Jupiter::String_Type::length + 1); // vsnprintf REQUIRES space for an additional null character. minLen = vswprintf(Jupiter::String_Type::str + Jupiter::String_Type::length, minLen + 1, format, args); if (minLen <= 0) return 0; Jupiter::String_Type::length += minLen; return minLen; } template size_t Jupiter::String_Loose::avformat(const T *format, va_list args) { return 0; } template Jupiter::String_Loose Jupiter::String_Loose::Format(const T *format, ...) { String_Loose r; va_list args; va_start(args, format); r.vformat(format, args); va_end(args); return r; } template typename Jupiter::template String_Loose Jupiter::String_Loose::substring(size_t pos) const { return Jupiter::String_Loose::substring(*this, pos); } template typename Jupiter::template String_Loose Jupiter::String_Loose::substring(size_t pos, size_t length) const { return Jupiter::String_Loose::substring(*this, pos, length); } template typename Jupiter::template String_Loose Jupiter::String_Loose::substring(const Jupiter::Readable_String &in, size_t pos) { return Jupiter::String_Type::template substring(in, pos); } template typename Jupiter::template String_Loose Jupiter::String_Loose::substring(const T *in, size_t pos) { return Jupiter::String_Type::template substring(in, pos); } template typename Jupiter::template String_Loose Jupiter::String_Loose::substring(const Jupiter::Readable_String &in, size_t pos, size_t len) { return Jupiter::String_Type::template substring(in, pos, len); } template typename Jupiter::template String_Loose Jupiter::String_Loose::substring(const T *in, size_t pos, size_t len) { return Jupiter::String_Type::template substring(in, pos, len); } template Jupiter::String_Loose Jupiter::String_Loose::getWord(size_t pos, const T *whitespace) const { return Jupiter::String_Loose::getWord(*this, pos, whitespace); } template Jupiter::String_Loose Jupiter::String_Loose::getWord(const Jupiter::Readable_String &in, size_t pos, const T *whitespace) { return Jupiter::Readable_String::template getWord(in, pos, whitespace); } template Jupiter::String_Loose Jupiter::String_Loose::getWord(const T *in, size_t pos, const T *whitespace) { return Jupiter::Readable_String::template getWord(in, pos, whitespace); } template Jupiter::String_Loose Jupiter::String_Loose::getToken(size_t pos, const T &token) const { return Jupiter::String_Loose::getToken(*this, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::getToken(size_t pos, const Jupiter::Readable_String &token) const { return Jupiter::String_Loose::getToken(*this, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::getToken(const Jupiter::Readable_String &in, size_t pos, const T &token) { return Jupiter::Readable_String::template getToken(in, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::getToken(const Jupiter::Readable_String &in, size_t pos, const Jupiter::Readable_String &token) { return Jupiter::Readable_String::template getToken(in, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::gotoWord(size_t pos, const T *whitespace) const { return Jupiter::String_Loose::gotoWord(*this, pos, whitespace); } template Jupiter::String_Loose Jupiter::String_Loose::gotoWord(const Jupiter::Readable_String &in, size_t pos, const T *whitespace) { return Jupiter::Readable_String::template gotoWord(in, pos, whitespace); } template Jupiter::String_Loose Jupiter::String_Loose::gotoToken(size_t pos, const T &token) const { return Jupiter::String_Loose::gotoToken(*this, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::gotoToken(size_t pos, const Jupiter::Readable_String &token) const { return Jupiter::String_Loose::gotoToken(*this, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::gotoToken(const Jupiter::Readable_String &in, size_t pos, const T &token) { return Jupiter::Readable_String::template gotoToken(in, pos, token); } template Jupiter::String_Loose Jupiter::String_Loose::gotoToken(const Jupiter::Readable_String &in, size_t pos, const Jupiter::Readable_String &token) { return Jupiter::Readable_String::template gotoToken(in, pos, token); } // Operators template inline Jupiter::String_Loose Jupiter::String_Loose::operator+(const T &rhs) const { return Jupiter::operator+(*this, rhs); } template inline Jupiter::String_Loose Jupiter::String_Loose::operator+(const Jupiter::String_Loose &rhs) const { return Jupiter::String_Loose::operator+(reinterpret_cast &>(rhs)); } template inline Jupiter::String_Loose Jupiter::String_Loose::operator+(const Jupiter::Readable_String &rhs) const { return Jupiter::operator+(*this, rhs); } template inline Jupiter::String_Loose Jupiter::String_Loose::operator+(const std::basic_string &rhs) const { return Jupiter::operator+(*this, rhs); } template inline Jupiter::String_Loose Jupiter::String_Loose::operator+(const T *rhs) const { return Jupiter::operator+(*this, rhs); } // tokenize template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Loose::tokenize(const T &separator) { return Jupiter::String_Loose::tokenize(*this, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Loose::tokenize(const Jupiter::Readable_String &separator) { return Jupiter::String_Loose::tokenize(*this, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Loose::tokenize(const T *separator, size_t separator_size) { return Jupiter::String_Loose::tokenize(*this, separator, separator_size); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Loose::tokenize(const Jupiter::Readable_String &in, const T &separator) { return Jupiter::Readable_String::template tokenize(in, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Loose::tokenize(const Jupiter::Readable_String &in, const Jupiter::Readable_String &separator) { return Jupiter::Readable_String::template tokenize(in, separator); } template typename Jupiter::Readable_String::template TokenizeResult Jupiter::String_Loose::tokenize(const Jupiter::Readable_String &in, const T *separator, size_t separator_size) { return Jupiter::Readable_String::template tokenize(in, separator, separator_size); } #if !defined JUPITER_STRING_STRICT_OPERATOR_PLUS #if !defined DISABLE_DEFAULT_JUPITER_STRING_OPERATOR_PLUS template static inline Jupiter::String_Loose Jupiter::operator+(const Jupiter::Readable_String &lhs, const T &rhs) { return Jupiter::String_Loose(lhs, rhs); } template static inline Jupiter::String_Loose Jupiter::operator+(const Jupiter::Readable_String &lhs, const Jupiter::Readable_String &rhs) { return Jupiter::String_Loose(lhs, rhs); } template static inline Jupiter::String_Loose Jupiter::operator+(const Jupiter::Readable_String &lhs, const std::basic_string &rhs) { return Jupiter::String_Loose(lhs, rhs); } template static inline Jupiter::String_Loose Jupiter::operator+(const Jupiter::Readable_String &lhs, const T *rhs) { return Jupiter::String_Loose(lhs, rhs); } #endif // DISABLE_DEFAULT_JUPITER_STRING_OPERATOR_PLUS #endif // JUPITER_STRING_STRICT_OPERATOR_PLUS template const Jupiter::String_Loose Jupiter::String_Loose::empty = Jupiter::String_Loose(); // Jupiter::DataBuffer specialization template<> struct _Jupiter_DataBuffer_partial_specialization_impl { template static void push(Jupiter::DataBuffer *buffer, const Jupiter::String_Loose *data) { _Jupiter_DataBuffer_partial_specialization_impl::push(buffer, data); }; template static Jupiter::String_Loose interpret(uint8_t *&head) { size_t size_ = *reinterpret_cast(head); head += sizeof(size_t); Jupiter::String_Loose r = Jupiter::String_Loose(reinterpret_cast(head), size_); head += size_; return r; } }; #endif // _STRING_IMP_H_HEADER