diff --git a/test/perftest/misctest.cpp b/test/perftest/misctest.cpp index fe2d947..3edadda 100644 --- a/test/perftest/misctest.cpp +++ b/test/perftest/misctest.cpp @@ -25,30 +25,6 @@ #define __STDC_FORMAT_MACROS #include "rapidjson/stringbuffer.h" -#ifdef _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4996) -#endif - -#define strtk_no_tr1_or_boost -#include "strtk/strtk.hpp" - -#ifdef _MSC_VER -#pragma warning (pop) -#endif - -#ifdef _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4245; disable: 4512; disable: 4996) -#endif - -#include "cppformat/format.h" -#include "cppformat/format.cc" - -#ifdef _MSC_VER -#pragma warning (pop) -#endif - #define protected public #include "rapidjson/writer.h" #undef private @@ -1001,107 +977,4 @@ TEST_F(Misc, itoa64_Writer2_InsituStringStream) { itoa64_Writer_InsituStringStre TEST_F(Misc, itoa64_Writer3_InsituStringStream) { itoa64_Writer_InsituStringStream >(); } TEST_F(Misc, itoa64_Writer4_InsituStringStream) { itoa64_Writer_InsituStringStream >(); } -TEST_F(Misc, itoa_sprintf) { - size_t length = 0; - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - char buffer[32]; - length += sprintf(buffer, "%d", randval[j]); - } - } - OUTPUT_LENGTH(length); -} - -TEST_F(Misc, itoa64_sprintf) { - size_t length = 0; - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - char buffer[32]; - int64_t x = randval[j] * randval[j]; - length += sprintf(buffer, "%" PRIi64, x); - } - } - OUTPUT_LENGTH(length); -} - -#ifdef _MSC_VER -TEST_F(Misc, itoa_VC) { - size_t length = 0; - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - char buffer[32]; - _itoa(randval[j], buffer, 10); - length += strlen(buffer); - } - } - OUTPUT_LENGTH(length); -} - -TEST_F(Misc, itoa64_VC) { - size_t length = 0; - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - char buffer[32]; - _i64toa(randval[j] * randval[j], buffer, 10); - length += strlen(buffer); - } - } - OUTPUT_LENGTH(length); -} -#endif - -TEST_F(Misc, itoa_strtk) { - size_t length = 0; - std::string s; - s.reserve(32); - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - s = strtk::type_to_string(randval[j]); - length += s.size(); - } - } - OUTPUT_LENGTH(length); -} - -TEST_F(Misc, itoa64_strtk) { - size_t length = 0; - std::string s; - s.reserve(32); - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - int64_t x = randval[j] * randval[j]; - s = strtk::type_to_string(x); - length += s.size(); - } - } - OUTPUT_LENGTH(length); -} - -TEST_F(Misc, itoa_cppformat) { - size_t length = 0; - char buffer[32]; - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - char* p = buffer; - fmt::FormatDec(p, randval[j]); - length += (p - buffer); - } - } - OUTPUT_LENGTH(length); -} - -TEST_F(Misc, itoa64_cppformat) { - size_t length = 0; - char buffer[32]; - for (size_t i = 0; i < kItoaTrialCount; i++) { - for (size_t j = 0; j < randvalCount; j++) { - char* p = buffer; - int64_t x = randval[j] * randval[j]; - fmt::FormatDec(p, x); - length += (p - buffer); - } - } - OUTPUT_LENGTH(length); -} - #endif // TEST_MISC diff --git a/thirdparty/cppformat/format.cc b/thirdparty/cppformat/format.cc deleted file mode 100644 index 895a796..0000000 --- a/thirdparty/cppformat/format.cc +++ /dev/null @@ -1,1202 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - 2014, Victor Zverovich - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Disable useless MSVC warnings. -#undef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#undef _SCL_SECURE_NO_WARNINGS -#define _SCL_SECURE_NO_WARNINGS - -#include "format.h" - -#include - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -# define WIN32_LEAN_AND_MEAN -# ifdef __MINGW32__ -# include -# endif -# include -# undef ERROR -#endif - -using fmt::LongLong; -using fmt::ULongLong; -using fmt::internal::Arg; - -#if _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4127) // conditional expression is constant -#endif - -namespace { - -#ifndef _MSC_VER - -inline int SignBit(double value) { - // When compiled in C++11 mode signbit is no longer a macro but a function - // defined in namespace std and the macro is undefined. -#ifdef signbit - return signbit(value); -#else - return std::signbit(value); -#endif -} - -inline int IsInf(double x) { -#ifdef isinf - return isinf(x); -#else - return std::isinf(x); -#endif -} - -#define FMT_SNPRINTF snprintf - -#else // _MSC_VER - -inline int SignBit(double value) { - if (value < 0) return 1; - if (value == value) return 0; - int dec = 0, sign = 0; - char buffer[2]; // The buffer size must be >= 2 or _ecvt_s will fail. - _ecvt_s(buffer, sizeof(buffer), value, 0, &dec, &sign); - return sign; -} - -inline int IsInf(double x) { return !_finite(x); } - -inline int FMT_SNPRINTF(char *buffer, size_t size, const char *format, ...) { - va_list args; - va_start(args, format); - int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); - va_end(args); - return result; -} - -#endif // _MSC_VER - -const char RESET_COLOR[] = "\x1b[0m"; - -typedef void (*FormatFunc)(fmt::Writer &, int , fmt::StringRef); - -void ReportError(FormatFunc func, - int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { - try { - fmt::Writer full_message; - func(full_message, error_code, message); // TODO: make sure this doesn't throw - std::fwrite(full_message.c_str(), full_message.size(), 1, stderr); - std::fputc('\n', stderr); - } catch (...) {} -} - -const Arg DUMMY_ARG = {Arg::INT, 0}; - -fmt::ULongLong GetIntValue(const Arg &arg) { - switch (arg.type) { - case Arg::INT: - return arg.int_value; - case Arg::UINT: - return arg.uint_value; - case Arg::LONG_LONG: - return arg.long_long_value; - case Arg::ULONG_LONG: - return arg.ulong_long_value; - default: - return -1; - } -} - -// Parses an unsigned integer advancing s to the end of the parsed input. -// This function assumes that the first character of s is a digit. -template -int ParseNonnegativeInt(const Char *&s, const char *&error) FMT_NOEXCEPT(true) { - assert('0' <= *s && *s <= '9'); - unsigned value = 0; - do { - unsigned new_value = value * 10 + (*s++ - '0'); - // Check if value wrapped around. - value = new_value >= value ? new_value : UINT_MAX; - } while ('0' <= *s && *s <= '9'); - if (value > INT_MAX) { - if (!error) - error = "number is too big in format"; - return 0; - } - return value; -} - -template -const Char *find_closing_brace(const Char *s, int num_open_braces = 1) { - for (int n = num_open_braces; *s; ++s) { - if (*s == '{') { - ++n; - } else if (*s == '}') { - if (--n == 0) - return s; - } - } - throw fmt::FormatError("unmatched '{' in format"); -} - -// Checks if an argument is a valid printf width specifier and sets -// left alignment if it is negative. -struct WidthHandler : public fmt::internal::ArgVisitor { - private: - fmt::FormatSpec &spec_; - - public: - explicit WidthHandler(fmt::FormatSpec &spec) : spec_(spec) {} - - ULongLong visit_unhandled_arg() { - throw fmt::FormatError("width is not integer"); - } - - ULongLong visit_any_int(fmt::LongLong value) { - ULongLong width = value; - if (value < 0) { - spec_.align_ = fmt::ALIGN_LEFT; - width = 0 - width; - } - return width; - } - - ULongLong visit_any_uint(ULongLong value) { return value; } -}; - -// This function template is used to prevent compile errors when handling -// incompatible string arguments, e.g. handling a wide string in a narrow -// string formatter. -template -Arg::StringValue ignore_incompatible_str(Arg::StringValue); - -template <> -inline Arg::StringValue ignore_incompatible_str( - Arg::StringValue) { return Arg::StringValue(); } - -template <> -inline Arg::StringValue ignore_incompatible_str( - Arg::StringValue s) { return s; } -} // namespace - -int fmt::internal::SignBitNoInline(double value) { return SignBit(value); } - -void fmt::SystemError::init( - int error_code, StringRef format_str, const ArgList &args) { - error_code_ = error_code; - Writer w; - internal::FormatSystemErrorMessage(w, error_code, format(format_str, args)); - std::runtime_error &base = *this; - base = std::runtime_error(w.str()); -} - -template -int fmt::internal::CharTraits::FormatFloat( - char *buffer, std::size_t size, const char *format, - unsigned width, int precision, T value) { - if (width == 0) { - return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, value) : - FMT_SNPRINTF(buffer, size, format, precision, value); - } - return precision < 0 ? - FMT_SNPRINTF(buffer, size, format, width, value) : - FMT_SNPRINTF(buffer, size, format, width, precision, value); -} - -template -int fmt::internal::CharTraits::FormatFloat( - wchar_t *buffer, std::size_t size, const wchar_t *format, - unsigned width, int precision, T value) { - if (width == 0) { - return precision < 0 ? - swprintf(buffer, size, format, value) : - swprintf(buffer, size, format, precision, value); - } - return precision < 0 ? - swprintf(buffer, size, format, width, value) : - swprintf(buffer, size, format, width, precision, value); -} - -const char fmt::internal::DIGITS[] = - "0001020304050607080910111213141516171819" - "2021222324252627282930313233343536373839" - "4041424344454647484950515253545556575859" - "6061626364656667686970717273747576777879" - "8081828384858687888990919293949596979899"; - -#define FMT_POWERS_OF_10(factor) \ - factor * 10, \ - factor * 100, \ - factor * 1000, \ - factor * 10000, \ - factor * 100000, \ - factor * 1000000, \ - factor * 10000000, \ - factor * 100000000, \ - factor * 1000000000 - -const uint32_t fmt::internal::POWERS_OF_10_32[] = {0, FMT_POWERS_OF_10(1)}; -const uint64_t fmt::internal::POWERS_OF_10_64[] = { - 0, - FMT_POWERS_OF_10(1), - FMT_POWERS_OF_10(ULongLong(1000000000)), - // Multiply several constants instead of using a single long long constants - // to avoid warnings about C++98 not supporting long long. - ULongLong(1000000000) * ULongLong(1000000000) * 10 -}; - -void fmt::internal::ReportUnknownType(char code, const char *type) { - if (std::isprint(static_cast(code))) { - throw fmt::FormatError( - fmt::format("unknown format code '{}' for {}", code, type)); - } - throw fmt::FormatError( - fmt::format("unknown format code '\\x{:02x}' for {}", - static_cast(code), type)); -} - -#ifdef _WIN32 - -fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) { - int length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, 0, 0); - static const char ERROR[] = "cannot convert string from UTF-8 to UTF-16"; - if (length == 0) - throw WindowsError(GetLastError(), ERROR); - buffer_.resize(length); - length = MultiByteToWideChar( - CP_UTF8, MB_ERR_INVALID_CHARS, s.c_str(), -1, &buffer_[0], length); - if (length == 0) - throw WindowsError(GetLastError(), ERROR); -} - -fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) { - if (int error_code = Convert(s)) { - throw WindowsError(error_code, - "cannot convert string from UTF-16 to UTF-8"); - } -} - -int fmt::internal::UTF16ToUTF8::Convert(fmt::WStringRef s) { - int length = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, 0, 0, 0, 0); - if (length == 0) - return GetLastError(); - buffer_.resize(length); - length = WideCharToMultiByte( - CP_UTF8, 0, s.c_str(), -1, &buffer_[0], length, 0, 0); - if (length == 0) - return GetLastError(); - return 0; -} - -void fmt::WindowsError::init( - int error_code, StringRef format_str, const ArgList &args) { - error_code_ = error_code; - Writer w; - internal::FormatWinErrorMessage(w, error_code, format(format_str, args)); - std::runtime_error &base = *this; - base = std::runtime_error(w.str()); -} - -#endif - -int fmt::internal::StrError( - int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true) { - assert(buffer != 0 && buffer_size != 0); - int result = 0; -#ifdef _GNU_SOURCE - char *message = strerror_r(error_code, buffer, buffer_size); - // If the buffer is full then the message is probably truncated. - if (message == buffer && strlen(buffer) == buffer_size - 1) - result = ERANGE; - buffer = message; -#elif __MINGW32__ - errno = 0; - (void)buffer_size; - buffer = strerror(error_code); - result = errno; -#elif _WIN32 - result = strerror_s(buffer, buffer_size, error_code); - // If the buffer is full then the message is probably truncated. - if (result == 0 && std::strlen(buffer) == buffer_size - 1) - result = ERANGE; -#else - result = strerror_r(error_code, buffer, buffer_size); - if (result == -1) - result = errno; // glibc versions before 2.13 return result in errno. -#endif - return result; -} - -void fmt::internal::FormatSystemErrorMessage( - fmt::Writer &out, int error_code, fmt::StringRef message) { - Array buffer; - buffer.resize(INLINE_BUFFER_SIZE); - char *system_message = 0; - for (;;) { - system_message = &buffer[0]; - int result = StrError(error_code, system_message, buffer.size()); - if (result == 0) - break; - if (result != ERANGE) { - // Can't get error message, report error code instead. - out << message << ": error code = " << error_code; - return; - } - buffer.resize(buffer.size() * 2); - } - out << message << ": " << system_message; -} - -#ifdef _WIN32 -void fmt::internal::FormatWinErrorMessage( - fmt::Writer &out, int error_code, fmt::StringRef message) { - class String { - private: - LPWSTR str_; - - public: - String() : str_() {} - ~String() { LocalFree(str_); } - LPWSTR *ptr() { return &str_; } - LPCWSTR c_str() const { return str_; } - }; - String system_message; - if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 0, - error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - reinterpret_cast(system_message.ptr()), 0, 0)) { - UTF16ToUTF8 utf8_message; - if (!utf8_message.Convert(system_message.c_str())) { - out << message << ": " << utf8_message; - return; - } - } - // Can't get error message, report error code instead. - out << message << ": error code = " << error_code; -} -#endif - -// An argument formatter. -template -class fmt::internal::ArgFormatter : - public fmt::internal::ArgVisitor, void> { - private: - fmt::BasicWriter &writer_; - fmt::FormatSpec &spec_; - const Char *format_; - - public: - ArgFormatter(fmt::BasicWriter &w, fmt::FormatSpec &s, const Char *fmt) - : writer_(w), spec_(s), format_(fmt) {} - - void visit_int(int value) { - writer_.FormatInt(value, spec_); - } - void visit_uint(unsigned value) { - writer_.FormatInt(value, spec_); - } - void visit_long_long(LongLong value) { - writer_.FormatInt(value, spec_); - } - void visit_ulong_long(ULongLong value) { - writer_.FormatInt(value, spec_); - } - void visit_double(double value) { - writer_.FormatDouble(value, spec_); - } - void visit_long_double(long double value) { - writer_.FormatDouble(value, spec_); - } - - void visit_char(int value) { - if (spec_.type_ && spec_.type_ != 'c') - fmt::internal::ReportUnknownType(spec_.type_, "char"); - typedef typename fmt::BasicWriter::CharPtr CharPtr; - CharPtr out = CharPtr(); - if (spec_.width_ > 1) { - Char fill = static_cast(spec_.fill()); - out = writer_.GrowBuffer(spec_.width_); - if (spec_.align_ == fmt::ALIGN_RIGHT) { - std::fill_n(out, spec_.width_ - 1, fill); - out += spec_.width_ - 1; - } else if (spec_.align_ == fmt::ALIGN_CENTER) { - out = writer_.FillPadding(out, spec_.width_, 1, fill); - } else { - std::fill_n(out + 1, spec_.width_ - 1, fill); - } - } else { - out = writer_.GrowBuffer(1); - } - *out = static_cast(value); - } - - void visit_string(Arg::StringValue value) { - writer_.write_str(value, spec_); - } - void visit_wstring(Arg::StringValue value) { - writer_.write_str(ignore_incompatible_str(value), spec_); - } - - void visit_pointer(const void *value) { - if (spec_.type_ && spec_.type_ != 'p') - fmt::internal::ReportUnknownType(spec_.type_, "pointer"); - spec_.flags_ = fmt::HASH_FLAG; - spec_.type_ = 'x'; - writer_.FormatInt(reinterpret_cast(value), spec_); - } - - void visit_custom(Arg::CustomValue c) { - c.format(this, c.value, format_); - } -}; - -template -void fmt::internal::FormatErrorReporter::operator()( - const Char *s, fmt::StringRef message) const { - if (find_closing_brace(s, num_open_braces)) - throw fmt::FormatError(message); -} - -// Fills the padding around the content and returns the pointer to the -// content area. -template -typename fmt::BasicWriter::CharPtr - fmt::BasicWriter::FillPadding(CharPtr buffer, - unsigned total_size, std::size_t content_size, wchar_t fill) { - std::size_t padding = total_size - content_size; - std::size_t left_padding = padding / 2; - Char fill_char = static_cast(fill); - std::fill_n(buffer, left_padding, fill_char); - buffer += left_padding; - CharPtr content = buffer; - std::fill_n(buffer + content_size, padding - left_padding, fill_char); - return content; -} - -template -template -void fmt::BasicWriter::FormatDouble(T value, const FormatSpec &spec) { - // Check type. - char type = spec.type(); - bool upper = false; - switch (type) { - case 0: - type = 'g'; - break; - case 'e': case 'f': case 'g': case 'a': - break; - case 'F': -#ifdef _MSC_VER - // MSVC's printf doesn't support 'F'. - type = 'f'; -#endif - // Fall through. - case 'E': case 'G': case 'A': - upper = true; - break; - default: - internal::ReportUnknownType(type, "double"); - break; - } - - char sign = 0; - // Use SignBit instead of value < 0 because the latter is always - // false for NaN. - if (SignBit(static_cast(value))) { - sign = '-'; - value = -value; - } else if (spec.sign_flag()) { - sign = spec.plus_flag() ? '+' : ' '; - } - - if (value != value) { - // Format NaN ourselves because sprintf's output is not consistent - // across platforms. - std::size_t size = 4; - const char *nan = upper ? " NAN" : " nan"; - if (!sign) { - --size; - ++nan; - } - CharPtr out = write_str(nan, size, spec); - if (sign) - *out = sign; - return; - } - - if (IsInf(static_cast(value))) { - // Format infinity ourselves because sprintf's output is not consistent - // across platforms. - std::size_t size = 4; - const char *inf = upper ? " INF" : " inf"; - if (!sign) { - --size; - ++inf; - } - CharPtr out = write_str(inf, size, spec); - if (sign) - *out = sign; - return; - } - - std::size_t offset = buffer_.size(); - unsigned width = spec.width(); - if (sign) { - buffer_.reserve(buffer_.size() + (std::max)(width, 1u)); - if (width > 0) - --width; - ++offset; - } - - // Build format string. - enum { MAX_FORMAT_SIZE = 10}; // longest format: %#-*.*Lg - Char format[MAX_FORMAT_SIZE]; - Char *format_ptr = format; - *format_ptr++ = '%'; - unsigned width_for_sprintf = width; - if (spec.hash_flag()) - *format_ptr++ = '#'; - if (spec.align() == ALIGN_CENTER) { - width_for_sprintf = 0; - } else { - if (spec.align() == ALIGN_LEFT) - *format_ptr++ = '-'; - if (width != 0) - *format_ptr++ = '*'; - } - if (spec.precision() >= 0) { - *format_ptr++ = '.'; - *format_ptr++ = '*'; - } - if (internal::IsLongDouble::VALUE) - *format_ptr++ = 'L'; - *format_ptr++ = type; - *format_ptr = '\0'; - - // Format using snprintf. - Char fill = static_cast(spec.fill()); - for (;;) { - std::size_t size = buffer_.capacity() - offset; -#if _MSC_VER - // MSVC's vsnprintf_s doesn't work with zero size, so reserve - // space for at least one extra character to make the size non-zero. - // Note that the buffer's capacity will increase by more than 1. - if (size == 0) { - buffer_.reserve(offset + 1); - size = buffer_.capacity() - offset; - } -#endif - Char *start = &buffer_[offset]; - int n = internal::CharTraits::FormatFloat( - start, size, format, width_for_sprintf, spec.precision(), value); - if (n >= 0 && offset + n < buffer_.capacity()) { - if (sign) { - if ((spec.align() != ALIGN_RIGHT && spec.align() != ALIGN_DEFAULT) || - *start != ' ') { - *(start - 1) = sign; - sign = 0; - } else { - *(start - 1) = fill; - } - ++n; - } - if (spec.align() == ALIGN_CENTER && - spec.width() > static_cast(n)) { - unsigned width = spec.width(); - CharPtr p = GrowBuffer(width); - std::copy(p, p + n, p + (width - n) / 2); - FillPadding(p, spec.width(), n, fill); - return; - } - if (spec.fill() != ' ' || sign) { - while (*start == ' ') - *start++ = fill; - if (sign) - *(start - 1) = sign; - } - GrowBuffer(n); - return; - } - // If n is negative we ask to increase the capacity by at least 1, - // but as std::vector, the buffer grows exponentially. - buffer_.reserve(n >= 0 ? offset + n + 1 : buffer_.capacity() + 1); - } -} - -template -template -void fmt::BasicWriter::write_str( - const Arg::StringValue &str, const FormatSpec &spec) { - // Check if StringChar is convertible to Char. - internal::CharTraits::convert(StringChar()); - if (spec.type_ && spec.type_ != 's') - internal::ReportUnknownType(spec.type_, "string"); - const StringChar *s = str.value; - std::size_t size = str.size; - if (size == 0) { - if (!s) - throw FormatError("string pointer is null"); - if (*s) - size = std::char_traits::length(s); - } - write_str(s, size, spec); -} - -template -inline const Arg - &fmt::BasicFormatter::ParseArgIndex(const Char *&s) { - unsigned arg_index = 0; - if (*s < '0' || *s > '9') { - if (*s != '}' && *s != ':') - report_error_(s, "invalid argument index in format string"); - if (next_arg_index_ < 0) { - report_error_(s, - "cannot switch from manual to automatic argument indexing"); - } - arg_index = next_arg_index_++; - } else { - if (next_arg_index_ > 0) { - report_error_(s, - "cannot switch from automatic to manual argument indexing"); - } - next_arg_index_ = -1; - const char *error = 0; - arg_index = ParseNonnegativeInt(s, error); - if (error) - report_error_(s, error); // TODO - } - if (arg_index >= args_.size()) - report_error_(s, "argument index is out of range in format"); - return args_[arg_index]; -} - -template -void fmt::BasicFormatter::CheckSign( - const Char *&s, const Arg &arg) { - char sign = static_cast(*s); - if (arg.type > Arg::LAST_NUMERIC_TYPE) { - report_error_(s, - fmt::format("format specifier '{}' requires numeric argument", sign).c_str()); - } - if (arg.type == Arg::UINT || arg.type == Arg::ULONG_LONG) { - report_error_(s, - fmt::format("format specifier '{}' requires signed argument", sign).c_str()); - } - ++s; -} - -template -void fmt::internal::PrintfParser::ParseFlags( - FormatSpec &spec, const Char *&s) { - for (;;) { - switch (*s++) { - case '-': - spec.align_ = ALIGN_LEFT; - break; - case '+': - spec.flags_ |= SIGN_FLAG | PLUS_FLAG; - break; - case '0': - spec.fill_ = '0'; - break; - case ' ': - spec.flags_ |= SIGN_FLAG; - break; - case '#': - spec.flags_ |= HASH_FLAG; - break; - default: - --s; - return; - } - } -} - -template -unsigned fmt::internal::PrintfParser::ParseHeader( - const Char *&s, FormatSpec &spec, const char *&error) { - unsigned arg_index = UINT_MAX; - Char c = *s; - if (c >= '0' && c <= '9') { - // Parse an argument index (if followed by '$') or a width possibly - // preceded with '0' flag(s). - unsigned value = ParseNonnegativeInt(s, error); - if (*s == '$') { // value is an argument index - ++s; - arg_index = value; - } else { - if (c == '0') - spec.fill_ = '0'; - if (value != 0) { - // Nonzero value means that we parsed width and don't need to - // parse it or flags again, so return now. - spec.width_ = value; - return arg_index; - } - } - } - ParseFlags(spec, s); - // Parse width. - if (*s >= '0' && *s <= '9') { - spec.width_ = ParseNonnegativeInt(s, error); - } else if (*s == '*') { - ++s; - ULongLong width = WidthHandler(spec).visit(HandleArgIndex(UINT_MAX, error)); - if (width <= INT_MAX) - spec.width_ = static_cast(width); - else if (!error) - error = "number is too big in format"; - } - return arg_index; -} - -// TODO: move to a base class that doesn't depend on template argument -template -const Arg &fmt::internal::PrintfParser::HandleArgIndex( - unsigned arg_index, const char *&error) { - if (arg_index != UINT_MAX) { - if (next_arg_index_ <= 0) { - next_arg_index_ = -1; - --arg_index; - } else if (!error) { - error = "cannot switch from automatic to manual argument indexing"; - } - } else if (next_arg_index_ >= 0) { - arg_index = next_arg_index_++; - } else if (!error) { - error = "cannot switch from manual to automatic argument indexing"; - } - if (arg_index < args_.size()) - return args_[arg_index]; - if (!error) - error = "argument index is out of range in format"; - return DUMMY_ARG; -} - -template -void fmt::internal::PrintfParser::Format( - BasicWriter &writer, BasicStringRef format, - const ArgList &args) { - const Char *start = format.c_str(); - args_ = args; - next_arg_index_ = 0; - const Char *s = start; - while (*s) { - Char c = *s++; - if (c != '%') continue; - if (*s == c) { - writer.buffer_.append(start, s); - start = ++s; - continue; - } - writer.buffer_.append(start, s - 1); - - FormatSpec spec; - spec.align_ = ALIGN_RIGHT; - - // Reporting errors is delayed till the format specification is - // completely parsed. This is done to avoid potentially confusing - // error messages for incomplete format strings. For example, in - // sprintf("%2$", 42); - // the format specification is incomplete. In naive approach we - // would parse 2 as an argument index and report an error that the - // index is out of range which would be rather confusing if the - // use meant "%2d$" rather than "%2$d". If we delay an error, the - // user will get an error that the format string is invalid which - // is OK for both cases. - const char *error = 0; - - // Parse argument index, flags and width. - unsigned arg_index = ParseHeader(s, spec, error); - - // Parse precision. - if (*s == '.') { - ++s; - if ('0' <= *s && *s <= '9') { - spec.precision_ = ParseNonnegativeInt(s, error); - } else if (*s == '*') { - ++s; - const Arg &arg = HandleArgIndex(UINT_MAX, error); - if (arg.type <= Arg::LAST_INTEGER_TYPE) - spec.precision_ = static_cast(GetIntValue(arg)); // TODO: check for overflow - else if (!error) - error = "precision is not integer"; - } - } - - const Arg &arg = HandleArgIndex(arg_index, error); - if (spec.hash_flag() && GetIntValue(arg) == 0) - spec.flags_ &= ~HASH_FLAG; - if (spec.fill_ == '0') { - if (arg.type <= Arg::LAST_NUMERIC_TYPE) - spec.align_ = ALIGN_NUMERIC; - else - spec.fill_ = ' '; // Ignore '0' flag for non-numeric types. - } - - // Parse length. - switch (*s) { - case 'h': - // TODO: convert to short - case 'l': - case 'j': - case 'z': - case 't': - case 'L': - // TODO: handle length - ++s; - break; - } - - // Parse type. - if (!*s) - throw FormatError("invalid format string"); - if (error) - throw FormatError(error); - spec.type_ = static_cast(*s++); - - start = s; - - // Format argument. - switch (arg.type) { - case Arg::INT: - writer.FormatInt(arg.int_value, spec); - break; - case Arg::UINT: - writer.FormatInt(arg.uint_value, spec); - break; - case Arg::LONG_LONG: - writer.FormatInt(arg.long_long_value, spec); - break; - case Arg::ULONG_LONG: - writer.FormatInt(arg.ulong_long_value, spec); - break; - case Arg::DOUBLE: - writer.FormatDouble(arg.double_value, spec); - break; - case Arg::LONG_DOUBLE: - writer.FormatDouble(arg.long_double_value, spec); - break; - case Arg::CHAR: { - if (spec.type_ && spec.type_ != 'c') - internal::ReportUnknownType(spec.type_, "char"); - typedef typename BasicWriter::CharPtr CharPtr; - CharPtr out = CharPtr(); - if (spec.width_ > 1) { - Char fill = static_cast(spec.fill()); - out = writer.GrowBuffer(spec.width_); - if (spec.align_ == ALIGN_RIGHT) { - std::fill_n(out, spec.width_ - 1, fill); - out += spec.width_ - 1; - } else if (spec.align_ == ALIGN_CENTER) { - out = writer.FillPadding(out, spec.width_, 1, fill); - } else { - std::fill_n(out + 1, spec.width_ - 1, fill); - } - } else { - out = writer.GrowBuffer(1); - } - *out = static_cast(arg.int_value); - break; - } - case Arg::STRING: - writer.write_str(arg.string, spec); - break; - case Arg::WSTRING: - writer.write_str(ignore_incompatible_str(arg.wstring), spec); - break; - case Arg::POINTER: - if (spec.type_ && spec.type_ != 'p') - internal::ReportUnknownType(spec.type_, "pointer"); - spec.flags_= HASH_FLAG; - spec.type_ = 'x'; - writer.FormatInt(reinterpret_cast(arg.pointer_value), spec); - break; - case Arg::CUSTOM: - if (spec.type_) - internal::ReportUnknownType(spec.type_, "object"); - arg.custom.format(&writer, arg.custom.value, "s"); - break; - default: - assert(false); - break; - } - } - writer.buffer_.append(start, s); -} - -template -const Char *fmt::BasicFormatter::format( - const Char *format_str, const Arg &arg) { - const Char *s = format_str; - const char *error = 0; - FormatSpec spec; - if (*s == ':') { - if (arg.type == Arg::CUSTOM) { - arg.custom.format(this, arg.custom.value, s); - return find_closing_brace(s) + 1; - } - ++s; - // Parse fill and alignment. - if (Char c = *s) { - const Char *p = s + 1; - spec.align_ = ALIGN_DEFAULT; - do { - switch (*p) { - case '<': - spec.align_ = ALIGN_LEFT; - break; - case '>': - spec.align_ = ALIGN_RIGHT; - break; - case '=': - spec.align_ = ALIGN_NUMERIC; - break; - case '^': - spec.align_ = ALIGN_CENTER; - break; - } - if (spec.align_ != ALIGN_DEFAULT) { - if (p != s) { - if (c == '}') break; - if (c == '{') - report_error_(s, "invalid fill character '{'"); - s += 2; - spec.fill_ = c; - } else ++s; - if (spec.align_ == ALIGN_NUMERIC && arg.type > Arg::LAST_NUMERIC_TYPE) - report_error_(s, "format specifier '=' requires numeric argument"); - break; - } - } while (--p >= s); - } - - // Parse sign. - switch (*s) { - case '+': - CheckSign(s, arg); - spec.flags_ |= SIGN_FLAG | PLUS_FLAG; - break; - case '-': - CheckSign(s, arg); - break; - case ' ': - CheckSign(s, arg); - spec.flags_ |= SIGN_FLAG; - break; - } - - if (*s == '#') { - if (arg.type > Arg::LAST_NUMERIC_TYPE) - report_error_(s, "format specifier '#' requires numeric argument"); - spec.flags_ |= HASH_FLAG; - ++s; - } - - // Parse width and zero flag. - if ('0' <= *s && *s <= '9') { - if (*s == '0') { - if (arg.type > Arg::LAST_NUMERIC_TYPE) - report_error_(s, "format specifier '0' requires numeric argument"); - spec.align_ = ALIGN_NUMERIC; - spec.fill_ = '0'; - } - // Zero may be parsed again as a part of the width, but it is simpler - // and more efficient than checking if the next char is a digit. - spec.width_ = ParseNonnegativeInt(s, error); - if (error) - report_error_(s, error); - } - - // Parse precision. - if (*s == '.') { - ++s; - spec.precision_ = 0; - if ('0' <= *s && *s <= '9') { - spec.precision_ = ParseNonnegativeInt(s, error); - if (error) - report_error_(s, error); - } else if (*s == '{') { - ++s; - ++report_error_.num_open_braces; - const Arg &precision_arg = ParseArgIndex(s); - ULongLong value = 0; - switch (precision_arg.type) { - case Arg::INT: - if (precision_arg.int_value < 0) - report_error_(s, "negative precision in format"); - value = precision_arg.int_value; - break; - case Arg::UINT: - value = precision_arg.uint_value; - break; - case Arg::LONG_LONG: - if (precision_arg.long_long_value < 0) - report_error_(s, "negative precision in format"); - value = precision_arg.long_long_value; - break; - case Arg::ULONG_LONG: - value = precision_arg.ulong_long_value; - break; - default: - report_error_(s, "precision is not integer"); - } - if (value > INT_MAX) - report_error_(s, "number is too big in format"); - spec.precision_ = static_cast(value); - if (*s++ != '}') - throw FormatError("unmatched '{' in format"); - --report_error_.num_open_braces; - } else { - report_error_(s, "missing precision in format"); - } - if (arg.type != Arg::DOUBLE && arg.type != Arg::LONG_DOUBLE) { - report_error_(s, - "precision specifier requires floating-point argument"); - } - } - - // Parse type. - if (*s != '}' && *s) - spec.type_ = static_cast(*s++); - } - - if (*s++ != '}') - throw FormatError("unmatched '{' in format"); - start_ = s; - - // Format argument. - internal::ArgFormatter(writer_, spec, s - 1).visit(arg); - return s; -} - -template -void fmt::BasicFormatter::Format( - BasicStringRef format_str, const ArgList &args) { - const Char *s = start_ = format_str.c_str(); - args_ = args; - next_arg_index_ = 0; - while (*s) { - Char c = *s++; - if (c != '{' && c != '}') continue; - if (*s == c) { - writer_.buffer_.append(start_, s); - start_ = ++s; - continue; - } - if (c == '}') - throw FormatError("unmatched '}' in format"); - report_error_.num_open_braces = 1; - writer_.buffer_.append(start_, s - 1); - Arg arg = ParseArgIndex(s); - s = format(s, arg); - } - writer_.buffer_.append(start_, s); -} - -void fmt::ReportSystemError( - int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { - // FIXME: FormatSystemErrorMessage may throw - ReportError(internal::FormatSystemErrorMessage, error_code, message); -} - -#ifdef _WIN32 -void fmt::ReportWinError( - int error_code, fmt::StringRef message) FMT_NOEXCEPT(true) { - // FIXME: FormatWinErrorMessage may throw - ReportError(internal::FormatWinErrorMessage, error_code, message); -} -#endif - -void fmt::print(StringRef format, const ArgList &args) { - Writer w; - w.write(format, args); - std::fwrite(w.data(), 1, w.size(), stdout); -} - -void fmt::print(std::FILE *f, StringRef format, const ArgList &args) { - Writer w; - w.write(format, args); - std::fwrite(w.data(), 1, w.size(), f); -} - -void fmt::print(std::ostream &os, StringRef format, const ArgList &args) { - Writer w; - w.write(format, args); - os.write(w.data(), w.size()); -} - -void fmt::print_colored(Color c, StringRef format, const ArgList &args) { - char escape[] = "\x1b[30m"; - escape[3] = '0' + static_cast(c); - std::fputs(escape, stdout); - print(format, args); - std::fputs(RESET_COLOR, stdout); -} - -void fmt::printf(StringRef format, const ArgList &args) { - Writer w; - printf(w, format, args); - std::fwrite(w.data(), 1, w.size(), stdout); -} - -// Explicit instantiations for char. - -template fmt::BasicWriter::CharPtr - fmt::BasicWriter::FillPadding(CharPtr buffer, - unsigned total_size, std::size_t content_size, wchar_t fill); - -template void fmt::BasicFormatter::Format( - BasicStringRef format, const ArgList &args); - -template void fmt::internal::PrintfParser::Format( - BasicWriter &writer, BasicStringRef format, const ArgList &args); - -// Explicit instantiations for wchar_t. - -template fmt::BasicWriter::CharPtr - fmt::BasicWriter::FillPadding(CharPtr buffer, - unsigned total_size, std::size_t content_size, wchar_t fill); - -template void fmt::BasicFormatter::Format( - BasicStringRef format, const ArgList &args); - -template void fmt::internal::PrintfParser::Format( - BasicWriter &writer, BasicStringRef format, - const ArgList &args); - -#if _MSC_VER -# pragma warning(pop) -#endif diff --git a/thirdparty/cppformat/format.h b/thirdparty/cppformat/format.h deleted file mode 100644 index 6a30dba..0000000 --- a/thirdparty/cppformat/format.h +++ /dev/null @@ -1,2019 +0,0 @@ -/* - Formatting library for C++ - - Copyright (c) 2012 - 2014, Victor Zverovich - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FMT_FORMAT_H_ -#define FMT_FORMAT_H_ - -#include - -#include -#include // for std::ptrdiff_t -#include -#include -#include -#include -#include -#include - -#if _SECURE_SCL -# include -#endif - -#ifdef __GNUC__ -# define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# define FMT_GCC_EXTENSION __extension__ -// Disable warning about "long long" which is sometimes reported even -// when using __extension__. -# if FMT_GCC_VERSION >= 406 -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wlong-long" -# endif -#else -# define FMT_GCC_EXTENSION -#endif - -#ifdef __GNUC_LIBSTD__ -# define FMT_GNUC_LIBSTD_VERSION (__GNUC_LIBSTD__ * 100 + __GNUC_LIBSTD_MINOR__) -#endif - -#ifdef __has_feature -# define FMT_HAS_FEATURE(x) __has_feature(x) -#else -# define FMT_HAS_FEATURE(x) 0 -#endif - -#ifdef __has_builtin -# define FMT_HAS_BUILTIN(x) __has_builtin(x) -#else -# define FMT_HAS_BUILTIN(x) 0 -#endif - -#ifndef FMT_USE_VARIADIC_TEMPLATES -// Variadic templates are available in GCC since version 4.4 -// (http://gcc.gnu.org/projects/cxx0x.html) and in Visual C++ -// since version 2013. -# define FMT_USE_VARIADIC_TEMPLATES \ - (FMT_HAS_FEATURE(cxx_variadic_templates) || \ - (FMT_GCC_VERSION >= 404 && __cplusplus >= 201103) || _MSC_VER >= 1800) -#endif - -#ifndef FMT_USE_RVALUE_REFERENCES -// Don't use rvalue references when compiling with clang and an old libstdc++ -// as the latter doesn't provide std::move. -# if defined(FMT_GNUC_LIBSTD_VERSION) && FMT_GNUC_LIBSTD_VERSION <= 402 -# define FMT_USE_RVALUE_REFERENCES 0 -# else -# define FMT_USE_RVALUE_REFERENCES \ - (FMT_HAS_FEATURE(cxx_rvalue_references) || \ - (FMT_GCC_VERSION >= 403 && __cplusplus >= 201103) || _MSC_VER >= 1600) -# endif -#endif - -#if FMT_USE_RVALUE_REFERENCES -# include // for std::move -#endif - -// Define FMT_USE_NOEXCEPT to make C++ Format use noexcept (C++11 feature). -#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ - (FMT_GCC_VERSION >= 408 && __cplusplus >= 201103) -# define FMT_NOEXCEPT(expr) noexcept(expr) -#else -# define FMT_NOEXCEPT(expr) -#endif - -// A macro to disallow the copy constructor and operator= functions -// This should be used in the private: declarations for a class -#define FMT_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&); \ - void operator=(const TypeName&) - -namespace fmt { - -// Fix the warning about long long on older versions of GCC -// that don't support the diagnostic pragma. -FMT_GCC_EXTENSION typedef long long LongLong; -FMT_GCC_EXTENSION typedef unsigned long long ULongLong; - -#if FMT_USE_RVALUE_REFERENCES -using std::move; -#endif - -template -class BasicWriter; - -typedef BasicWriter Writer; -typedef BasicWriter WWriter; - -template -class BasicFormatter; - -template -void format(BasicFormatter &f, const Char *format_str, const T &value); - -/** - \rst - A string reference. It can be constructed from a C string or - ``std::string``. - - You can use one of the following typedefs for common character types: - - +------------+-------------------------+ - | Type | Definition | - +============+=========================+ - | StringRef | BasicStringRef | - +------------+-------------------------+ - | WStringRef | BasicStringRef | - +------------+-------------------------+ - - This class is most useful as a parameter type to allow passing - different types of strings to a function, for example:: - - template - std::string format(StringRef format, const Args & ... args); - - format("{}", 42); - format(std::string("{}"), 42); - \endrst - */ -template -class BasicStringRef { - private: - const Char *data_; - mutable std::size_t size_; - - public: - /** - Constructs a string reference object from a C string and a size. - If *size* is zero, which is the default, the size is computed - automatically. - */ - BasicStringRef(const Char *s, std::size_t size = 0) : data_(s), size_(size) {} - - /** - Constructs a string reference from an `std::string` object. - */ - BasicStringRef(const std::basic_string &s) - : data_(s.c_str()), size_(s.size()) {} - - /** - Converts a string reference to an `std::string` object. - */ - operator std::basic_string() const { - return std::basic_string(data_, size()); - } - - /** - Returns the pointer to a C string. - */ - const Char *c_str() const { return data_; } - - /** - Returns the string size. - */ - std::size_t size() const { - if (size_ == 0 && data_) size_ = std::char_traits::length(data_); - return size_; - } - - friend bool operator==(BasicStringRef lhs, BasicStringRef rhs) { - return lhs.data_ == rhs.data_; - } - friend bool operator!=(BasicStringRef lhs, BasicStringRef rhs) { - return lhs.data_ != rhs.data_; - } -}; - -typedef BasicStringRef StringRef; -typedef BasicStringRef WStringRef; - -/** - A formatting error such as invalid format string. -*/ -class FormatError : public std::runtime_error { -public: - explicit FormatError(const std::string &message) - : std::runtime_error(message) {} -}; - -namespace internal { - -// The number of characters to store in the Array object, representing the -// output buffer, itself to avoid dynamic memory allocation. -enum { INLINE_BUFFER_SIZE = 500 }; - -#if _SECURE_SCL -// Use checked iterator to avoid warnings on MSVC. -template -inline stdext::checked_array_iterator CheckPtr(T *ptr, std::size_t size) { - return stdext::checked_array_iterator(ptr, size); -} -#else -template -inline T *CheckPtr(T *ptr, std::size_t) { return ptr; } -#endif - -// A simple array for POD types with the first SIZE elements stored in -// the object itself. It supports a subset of std::vector's operations. -template -class Array { - private: - std::size_t size_; - std::size_t capacity_; - T *ptr_; - T data_[SIZE]; - - void grow(std::size_t size); - - // Free memory allocated by the array. - void free() { - if (ptr_ != data_) delete [] ptr_; - } - - // Move data from other to this array. - void move(Array &other) { - size_ = other.size_; - capacity_ = other.capacity_; - if (other.ptr_ == other.data_) { - ptr_ = data_; - std::copy(other.data_, other.data_ + size_, CheckPtr(data_, capacity_)); - } else { - ptr_ = other.ptr_; - // Set pointer to the inline array so that delete is not called - // when freeing. - other.ptr_ = other.data_; - } - } - - FMT_DISALLOW_COPY_AND_ASSIGN(Array); - - public: - Array() : size_(0), capacity_(SIZE), ptr_(data_) {} - ~Array() { free(); } - -#if FMT_USE_RVALUE_REFERENCES - Array(Array &&other) { - move(other); - } - - Array& operator=(Array &&other) { - assert(this != &other); - free(); - move(other); - return *this; - } -#endif - - // Returns the size of this array. - std::size_t size() const { return size_; } - - // Returns the capacity of this array. - std::size_t capacity() const { return capacity_; } - - // Resizes the array. If T is a POD type new elements are not initialized. - void resize(std::size_t new_size) { - if (new_size > capacity_) - grow(new_size); - size_ = new_size; - } - - // Reserves space to store at least capacity elements. - void reserve(std::size_t capacity) { - if (capacity > capacity_) - grow(capacity); - } - - void clear() { size_ = 0; } - - void push_back(const T &value) { - if (size_ == capacity_) - grow(size_ + 1); - ptr_[size_++] = value; - } - - // Appends data to the end of the array. - void append(const T *begin, const T *end); - - T &operator[](std::size_t index) { return ptr_[index]; } - const T &operator[](std::size_t index) const { return ptr_[index]; } -}; - -template -void Array::grow(std::size_t size) { - capacity_ = (std::max)(size, capacity_ + capacity_ / 2); - T *p = new T[capacity_]; - std::copy(ptr_, ptr_ + size_, CheckPtr(p, capacity_)); - if (ptr_ != data_) - delete [] ptr_; - ptr_ = p; -} - -template -void Array::append(const T *begin, const T *end) { - std::ptrdiff_t num_elements = end - begin; - if (size_ + num_elements > capacity_) - grow(size_ + num_elements); - std::copy(begin, end, CheckPtr(ptr_, capacity_) + size_); - size_ += num_elements; -} - -template -class BasicCharTraits { - public: -#if _SECURE_SCL - typedef stdext::checked_array_iterator CharPtr; -#else - typedef Char *CharPtr; -#endif -}; - -template -class CharTraits; - -template <> -class CharTraits : public BasicCharTraits { - private: - // Conversion from wchar_t to char is not allowed. - static char convert(wchar_t); - -public: - typedef const wchar_t *UnsupportedStrType; - - static char convert(char value) { return value; } - - template - static int FormatFloat(char *buffer, std::size_t size, - const char *format, unsigned width, int precision, T value); -}; - -template <> -class CharTraits : public BasicCharTraits { - public: - typedef const char *UnsupportedStrType; - - static wchar_t convert(char value) { return value; } - static wchar_t convert(wchar_t value) { return value; } - - template - static int FormatFloat(wchar_t *buffer, std::size_t size, - const wchar_t *format, unsigned width, int precision, T value); -}; - -// Selects uint32_t if FitsIn32Bits is true, uint64_t otherwise. -template -struct TypeSelector { typedef uint32_t Type; }; - -template <> -struct TypeSelector { typedef uint64_t Type; }; - -// Checks if a number is negative - used to avoid warnings. -template -struct SignChecker { - template - static bool IsNegative(T) { return false; } -}; - -template <> -struct SignChecker { - template - static bool IsNegative(T value) { return value < 0; } -}; - -// Returns true if value is negative, false otherwise. -// Same as (value < 0) but doesn't produce warnings if T is an unsigned type. -template -inline bool IsNegative(T value) { - return SignChecker::is_signed>::IsNegative(value); -} - -int SignBitNoInline(double value); - -template -struct IntTraits { - // Smallest of uint32_t and uint64_t that is large enough to represent - // all values of T. - typedef typename - TypeSelector::digits <= 32>::Type MainType; -}; - -template -struct IsLongDouble { enum {VALUE = 0}; }; - -template <> -struct IsLongDouble { enum {VALUE = 1}; }; - -void ReportUnknownType(char code, const char *type); - -extern const uint32_t POWERS_OF_10_32[]; -extern const uint64_t POWERS_OF_10_64[]; - -#if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clzll) -// Returns the number of decimal digits in n. Leading zeros are not counted -// except for n == 0 in which case CountDigits returns 1. -inline unsigned CountDigits(uint64_t n) { - // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. - uint64_t t = (64 - __builtin_clzll(n | 1)) * 1233 >> 12; - return t - (n < POWERS_OF_10_64[t]) + 1; -} -# if FMT_GCC_VERSION >= 400 || FMT_HAS_BUILTIN(__builtin_clz) -// Optional version of CountDigits for better performance on 32-bit platforms. -inline unsigned CountDigits(uint32_t n) { - uint32_t t = (32 - __builtin_clz(n | 1)) * 1233 >> 12; - return t - (n < POWERS_OF_10_32[t]) + 1; -} -# endif -#else -// Slower version of CountDigits used when __builtin_clz is not available. -inline unsigned CountDigits(uint64_t n) { - unsigned count = 1; - for (;;) { - // Integer division is slow so do it for a group of four digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - if (n < 10) return count; - if (n < 100) return count + 1; - if (n < 1000) return count + 2; - if (n < 10000) return count + 3; - n /= 10000u; - count += 4; - } -} -#endif - -extern const char DIGITS[]; - -// Formats a decimal unsigned integer value writing into buffer. -template -void FormatDecimal(Char *buffer, UInt value, unsigned num_digits) { - --num_digits; - while (value >= 100) { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; - value /= 100; - buffer[num_digits] = DIGITS[index + 1]; - buffer[num_digits - 1] = DIGITS[index]; - num_digits -= 2; - } - if (value < 10) { - *buffer = static_cast('0' + value); - return; - } - unsigned index = static_cast(value * 2); - buffer[1] = DIGITS[index + 1]; - buffer[0] = DIGITS[index]; -} - -#ifdef _WIN32 -// A converter from UTF-8 to UTF-16. -// It is only provided for Windows since other systems use UTF-8. -class UTF8ToUTF16 { - private: - Array buffer_; - - public: - explicit UTF8ToUTF16(StringRef s); - operator WStringRef() const { return WStringRef(&buffer_[0], size()); } - size_t size() const { return buffer_.size() - 1; } - const wchar_t *c_str() const { return &buffer_[0]; } - std::wstring str() const { return std::wstring(&buffer_[0], size()); } -}; - -// A converter from UTF-16 to UTF-8. -// It is only provided for Windows since other systems use UTF-8. -class UTF16ToUTF8 { - private: - Array buffer_; - - public: - UTF16ToUTF8() {} - explicit UTF16ToUTF8(WStringRef s); - operator StringRef() const { return StringRef(&buffer_[0], size()); } - size_t size() const { return buffer_.size() - 1; } - const char *c_str() const { return &buffer_[0]; } - std::string str() const { return std::string(&buffer_[0], size()); } - - // Performs conversion returning a system error code instead of - // throwing exception on error. - int Convert(WStringRef s); -}; -#endif - -// Portable thread-safe version of strerror. -// Sets buffer to point to a string describing the error code. -// This can be either a pointer to a string stored in buffer, -// or a pointer to some static immutable string. -// Returns one of the following values: -// 0 - success -// ERANGE - buffer is not large enough to store the error message -// other - failure -// Buffer should be at least of size 1. -int StrError(int error_code, - char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT(true); - -void FormatSystemErrorMessage( - fmt::Writer &out, int error_code, fmt::StringRef message); - -#ifdef _WIN32 -void FormatWinErrorMessage( - fmt::Writer &out, int error_code, fmt::StringRef message); -#endif - -struct SimpleErrorReporter { - void operator()(const void *, fmt::StringRef message) const { - throw fmt::FormatError(message); - } -}; - -// Throws Exception(message) if format contains '}', otherwise throws -// FormatError reporting unmatched '{'. The idea is that unmatched '{' -// should override other errors. -template -struct FormatErrorReporter { - int num_open_braces; - void operator()(const Char *s, fmt::StringRef message) const; -}; - -// Computes max(Arg, 1) at compile time. It is used to avoid errors about -// allocating an array of 0 size. -template -struct NonZero { - enum { VALUE = Arg }; -}; - -template <> -struct NonZero<0> { - enum { VALUE = 1 }; -}; - -// A formatting argument. It is a POD type to allow storage in internal::Array. -struct Arg { - enum Type { - // Integer types should go first, - INT, UINT, LONG_LONG, ULONG_LONG, LAST_INTEGER_TYPE = ULONG_LONG, - // followed by floating-point types. - DOUBLE, LONG_DOUBLE, LAST_NUMERIC_TYPE = LONG_DOUBLE, - CHAR, STRING, WSTRING, POINTER, CUSTOM - }; - Type type; - - template - struct StringValue { - const Char *value; - std::size_t size; - }; - - typedef void (*FormatFunc)( - void *formatter, const void *arg, const void *format_str); - - struct CustomValue { - const void *value; - FormatFunc format; - }; - - union { - int int_value; - unsigned uint_value; - LongLong long_long_value; - ULongLong ulong_long_value; - double double_value; - long double long_double_value; - const void *pointer_value; - StringValue string; - StringValue wstring; - CustomValue custom; - }; -}; - -// Makes an Arg object from any type. -template -class MakeArg : public Arg { - private: - // The following two methods are private to disallow formatting of - // arbitrary pointers. If you want to output a pointer cast it to - // "void *" or "const void *". In particular, this forbids formatting - // of "[const] volatile char *" which is printed as bool by iostreams. - // Do not implement! - template - MakeArg(const T *value); - template - MakeArg(T *value); - - void set_string(StringRef str) { - type = STRING; - string.value = str.c_str(); - string.size = str.size(); - } - - void set_string(WStringRef str) { - type = WSTRING; - CharTraits::convert(wchar_t()); - wstring.value = str.c_str(); - wstring.size = str.size(); - } - - // Formats an argument of a custom type, such as a user-defined class. - template - static void format_custom_arg( - void *formatter, const void *arg, const void *format_str) { - format(*static_cast*>(formatter), - static_cast(format_str), *static_cast(arg)); - } - -public: - MakeArg() {} - MakeArg(bool value) { type = INT; int_value = value; } - MakeArg(short value) { type = INT; int_value = value; } - MakeArg(unsigned short value) { type = UINT; uint_value = value; } - MakeArg(int value) { type = INT; int_value = value; } - MakeArg(unsigned value) { type = UINT; uint_value = value; } - MakeArg(long value) { - // To minimize the number of types we need to deal with, long is - // translated either to int or to long long depending on its size. - if (sizeof(long) == sizeof(int)) { - type = INT; - int_value = static_cast(value); - } else { - type = LONG_LONG; - long_long_value = value; - } - } - MakeArg(unsigned long value) { - if (sizeof(unsigned long) == sizeof(unsigned)) { - type = UINT; - uint_value = static_cast(value); - } else { - type = ULONG_LONG; - ulong_long_value = value; - } - } - MakeArg(LongLong value) { type = LONG_LONG; long_long_value = value; } - MakeArg(ULongLong value) { type = ULONG_LONG; ulong_long_value = value; } - MakeArg(float value) { type = DOUBLE; double_value = value; } - MakeArg(double value) { type = DOUBLE; double_value = value; } - MakeArg(long double value) { type = LONG_DOUBLE; long_double_value = value; } - MakeArg(signed char value) { type = CHAR; int_value = value; } - MakeArg(unsigned char value) { type = CHAR; int_value = value; } - MakeArg(char value) { type = CHAR; int_value = value; } - MakeArg(wchar_t value) { - type = CHAR; - int_value = internal::CharTraits::convert(value); - } - - MakeArg(char *value) { set_string(value); } - MakeArg(const char *value) { set_string(value); } - MakeArg(const std::string &value) { set_string(value); } - MakeArg(StringRef value) { set_string(value); } - - MakeArg(wchar_t *value) { set_string(value); } - MakeArg(const wchar_t *value) { set_string(value); } - MakeArg(const std::wstring &value) { set_string(value); } - MakeArg(WStringRef value) { set_string(value); } - - MakeArg(void *value) { type = POINTER; pointer_value = value; } - MakeArg(const void *value) { type = POINTER; pointer_value = value; } - - template - MakeArg(const T &value) { - type = CUSTOM; - custom.value = &value; - custom.format = &format_custom_arg; - } -}; - -#define FMT_DISPATCH(call) static_cast(this)->call - -// An argument visitor. -// To use ArgVisitor define a subclass that implements some or all of the -// visit methods with the same signatures as the methods in ArgVisitor, -// for example, visit_int(int). -// Specify the subclass name as the Impl template parameter. Then calling -// ArgVisitor::visit for some argument will dispatch to a visit method -// specific to the argument type. For example, if the argument type is -// double then visit_double(double) method of a subclass will be called. -// If the subclass doesn't contain a method with this signature, then -// a corresponding method of ArgVisitor will be called. -// -// Example: -// class MyArgVisitor : public ArgVisitor { -// public: -// void visit_int(int value) { print("{}", value); } -// void visit_double(double value) { print("{}", value ); } -// }; -// -// ArgVisitor uses the curiously recurring template pattern: -// http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern -template -class ArgVisitor { - public: - Result visit_unhandled_arg() { return Result(); } - - Result visit_int(int value) { - return FMT_DISPATCH(visit_any_int(value)); - } - Result visit_long_long(LongLong value) { - return FMT_DISPATCH(visit_any_int(value)); - } - Result visit_any_int(LongLong) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - Result visit_uint(unsigned value) { - return FMT_DISPATCH(visit_any_uint(value)); - } - Result visit_ulong_long(ULongLong value) { - return FMT_DISPATCH(visit_any_uint(value)); - } - Result visit_any_uint(ULongLong) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - Result visit_double(double) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_long_double(long double) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_char(int) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_string(Arg::StringValue) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_wstring(Arg::StringValue) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_pointer(const void *) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - Result visit_custom(Arg::CustomValue) { - return FMT_DISPATCH(visit_unhandled_arg()); - } - - Result visit(const Arg &arg) { - switch (arg.type) { - default: - assert(false); - // Fall through. - case Arg::INT: - return FMT_DISPATCH(visit_int(arg.int_value)); - case Arg::UINT: - return FMT_DISPATCH(visit_uint(arg.uint_value)); - case Arg::LONG_LONG: - return FMT_DISPATCH(visit_long_long(arg.long_long_value)); - case Arg::ULONG_LONG: - return FMT_DISPATCH(visit_ulong_long(arg.ulong_long_value)); - case Arg::DOUBLE: - return FMT_DISPATCH(visit_double(arg.double_value)); - case Arg::LONG_DOUBLE: - return FMT_DISPATCH(visit_long_double(arg.long_double_value)); - case Arg::CHAR: - return FMT_DISPATCH(visit_char(arg.int_value)); - case Arg::STRING: - return FMT_DISPATCH(visit_string(arg.string)); - case Arg::WSTRING: - return FMT_DISPATCH(visit_wstring(arg.wstring)); - case Arg::POINTER: - return FMT_DISPATCH(visit_pointer(arg.pointer_value)); - case Arg::CUSTOM: - return FMT_DISPATCH(visit_custom(arg.custom)); - } - } -}; - -class RuntimeError : public std::runtime_error { - protected: - RuntimeError() : std::runtime_error("") {} -}; - -template -class ArgFormatter; -} // namespace internal - -/** - An argument list. - */ -class ArgList { - private: - const internal::Arg *args_; - std::size_t size_; - - public: - ArgList() : size_(0) {} - ArgList(const internal::Arg *args, std::size_t size) - : args_(args), size_(size) {} - - /** - Returns the list size (the number of arguments). - */ - std::size_t size() const { return size_; } - - /** - Returns the argument at specified index. - */ - const internal::Arg &operator[](std::size_t index) const { - return args_[index]; - } -}; - -struct FormatSpec; - -// A formatter. -template -class BasicFormatter { -private: - BasicWriter &writer_; - ArgList args_; - int next_arg_index_; - const Char *start_; - internal::FormatErrorReporter report_error_; - - // Parses argument index and returns an argument with this index. - const internal::Arg &ParseArgIndex(const Char *&s); - - void CheckSign(const Char *&s, const internal::Arg &arg); - -public: - explicit BasicFormatter(BasicWriter &w) : writer_(w) {} - - BasicWriter &writer() { return writer_; } - - void Format(BasicStringRef format_str, const ArgList &args); - - const Char *format(const Char *format_str, const internal::Arg &arg); -}; - -namespace internal { -// Printf format string parser. -template -class PrintfParser { - private: - ArgList args_; - int next_arg_index_; - - void ParseFlags(FormatSpec &spec, const Char *&s); - - // Parses argument index, flags and width and returns the parsed - // argument index. - unsigned ParseHeader(const Char *&s, FormatSpec &spec, const char *&error); - - const internal::Arg &HandleArgIndex(unsigned arg_index, const char *&error); - - public: - void Format(BasicWriter &writer, - BasicStringRef format, const ArgList &args); -}; -} // namespace internal - -enum Alignment { - ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC -}; - -// Flags. -enum { SIGN_FLAG = 1, PLUS_FLAG = 2, HASH_FLAG = 4 }; - -// An empty format specifier. -struct EmptySpec {}; - -// A type specifier. -template -struct TypeSpec : EmptySpec { - Alignment align() const { return ALIGN_DEFAULT; } - unsigned width() const { return 0; } - int precision() const { return -1; } - - bool sign_flag() const { return false; } - bool plus_flag() const { return false; } - bool hash_flag() const { return false; } - - char type() const { return TYPE; } - char fill() const { return ' '; } -}; - -// A width specifier. -struct WidthSpec { - unsigned width_; - // Fill is always wchar_t and cast to char if necessary to avoid having - // two specialization of WidthSpec and its subclasses. - wchar_t fill_; - - WidthSpec(unsigned width, wchar_t fill) : width_(width), fill_(fill) {} - - unsigned width() const { return width_; } - wchar_t fill() const { return fill_; } -}; - -// An alignment specifier. -struct AlignSpec : WidthSpec { - Alignment align_; - - AlignSpec(unsigned width, wchar_t fill, Alignment align = ALIGN_DEFAULT) - : WidthSpec(width, fill), align_(align) {} - - Alignment align() const { return align_; } - - int precision() const { return -1; } -}; - -// An alignment and type specifier. -template -struct AlignTypeSpec : AlignSpec { - AlignTypeSpec(unsigned width, wchar_t fill) : AlignSpec(width, fill) {} - - bool sign_flag() const { return false; } - bool plus_flag() const { return false; } - bool hash_flag() const { return false; } - - char type() const { return TYPE; } -}; - -// A full format specifier. -struct FormatSpec : AlignSpec { - unsigned flags_; - int precision_; - char type_; - - FormatSpec( - unsigned width = 0, char type = 0, wchar_t fill = ' ') - : AlignSpec(width, fill), flags_(0), precision_(-1), type_(type) {} - - bool sign_flag() const { return (flags_ & SIGN_FLAG) != 0; } - bool plus_flag() const { return (flags_ & PLUS_FLAG) != 0; } - bool hash_flag() const { return (flags_ & HASH_FLAG) != 0; } - - int precision() const { return precision_; } - - char type() const { return type_; } -}; - -// An integer format specifier. -template , typename Char = char> -class IntFormatSpec : public SpecT { - private: - T value_; - - public: - IntFormatSpec(T value, const SpecT &spec = SpecT()) - : SpecT(spec), value_(value) {} - - T value() const { return value_; } -}; - -// A string format specifier. -template -class StrFormatSpec : public AlignSpec { - private: - const T *str_; - - public: - StrFormatSpec(const T *str, unsigned width, wchar_t fill) - : AlignSpec(width, fill), str_(str) {} - - const T *str() const { return str_; } -}; - -/** - Returns an integer format specifier to format the value in base 2. - */ -IntFormatSpec > bin(int value); - -/** - Returns an integer format specifier to format the value in base 8. - */ -IntFormatSpec > oct(int value); - -/** - Returns an integer format specifier to format the value in base 16 using - lower-case letters for the digits above 9. - */ -IntFormatSpec > hex(int value); - -/** - Returns an integer formatter format specifier to format in base 16 using - upper-case letters for the digits above 9. - */ -IntFormatSpec > hexu(int value); - -/** - \rst - Returns an integer format specifier to pad the formatted argument with the - fill character to the specified width using the default (right) numeric - alignment. - - **Example**:: - - Writer out; - out << pad(hex(0xcafe), 8, '0'); - // out.str() == "0000cafe" - - \endrst - */ -template -IntFormatSpec, Char> pad( - int value, unsigned width, Char fill = ' '); - -#define FMT_DEFINE_INT_FORMATTERS(TYPE) \ -inline IntFormatSpec > bin(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'b'>()); \ -} \ - \ -inline IntFormatSpec > oct(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'o'>()); \ -} \ - \ -inline IntFormatSpec > hex(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'x'>()); \ -} \ - \ -inline IntFormatSpec > hexu(TYPE value) { \ - return IntFormatSpec >(value, TypeSpec<'X'>()); \ -} \ - \ -template \ -inline IntFormatSpec > pad( \ - IntFormatSpec > f, unsigned width) { \ - return IntFormatSpec >( \ - f.value(), AlignTypeSpec(width, ' ')); \ -} \ - \ -/* For compatibility with older compilers we provide two overloads for pad, */ \ -/* one that takes a fill character and one that doesn't. In the future this */ \ -/* can be replaced with one overload making the template argument Char */ \ -/* default to char (C++11). */ \ -template \ -inline IntFormatSpec, Char> pad( \ - IntFormatSpec, Char> f, \ - unsigned width, Char fill) { \ - return IntFormatSpec, Char>( \ - f.value(), AlignTypeSpec(width, fill)); \ -} \ - \ -inline IntFormatSpec > pad( \ - TYPE value, unsigned width) { \ - return IntFormatSpec >( \ - value, AlignTypeSpec<0>(width, ' ')); \ -} \ - \ -template \ -inline IntFormatSpec, Char> pad( \ - TYPE value, unsigned width, Char fill) { \ - return IntFormatSpec, Char>( \ - value, AlignTypeSpec<0>(width, fill)); \ -} - -FMT_DEFINE_INT_FORMATTERS(int) -FMT_DEFINE_INT_FORMATTERS(long) -FMT_DEFINE_INT_FORMATTERS(unsigned) -FMT_DEFINE_INT_FORMATTERS(unsigned long) -FMT_DEFINE_INT_FORMATTERS(LongLong) -FMT_DEFINE_INT_FORMATTERS(ULongLong) - -/** - \rst - Returns a string formatter that pads the formatted argument with the fill - character to the specified width using the default (left) string alignment. - - **Example**:: - - std::string s = str(Writer() << pad("abc", 8)); - // s == "abc " - - \endrst - */ -template -inline StrFormatSpec pad( - const Char *str, unsigned width, Char fill = ' ') { - return StrFormatSpec(str, width, fill); -} - -inline StrFormatSpec pad( - const wchar_t *str, unsigned width, char fill = ' ') { - return StrFormatSpec(str, width, fill); -} - -// Generates a comma-separated list with results of applying f to numbers 0..n-1. -# define FMT_GEN(n, f) FMT_GEN##n(f) -# define FMT_GEN1(f) f(0) -# define FMT_GEN2(f) FMT_GEN1(f), f(1) -# define FMT_GEN3(f) FMT_GEN2(f), f(2) -# define FMT_GEN4(f) FMT_GEN3(f), f(3) -# define FMT_GEN5(f) FMT_GEN4(f), f(4) -# define FMT_GEN6(f) FMT_GEN5(f), f(5) -# define FMT_GEN7(f) FMT_GEN6(f), f(6) -# define FMT_GEN8(f) FMT_GEN7(f), f(7) -# define FMT_GEN9(f) FMT_GEN8(f), f(8) -# define FMT_GEN10(f) FMT_GEN9(f), f(9) - -# define FMT_MAKE_TEMPLATE_ARG(n) typename T##n -# define FMT_MAKE_ARG(n) const T##n &v##n -# define FMT_MAKE_REF_char(n) fmt::internal::MakeArg(v##n) -# define FMT_MAKE_REF_wchar_t(n) fmt::internal::MakeArg(v##n) - -#if FMT_USE_VARIADIC_TEMPLATES -// Defines a variadic function returning void. -# define FMT_VARIADIC_VOID(func, arg_type) \ - template \ - void func(arg_type arg1, const Args & ... args) { \ - using fmt::internal::Arg; \ - const Arg arg_array[fmt::internal::NonZero::VALUE] = { \ - fmt::internal::MakeArg(args)... \ - }; \ - func(arg1, ArgList(arg_array, sizeof...(Args))); \ - } - -// Defines a variadic constructor. -# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ - template \ - ctor(arg0_type arg0, arg1_type arg1, const Args & ... args) { \ - using fmt::internal::Arg; \ - const Arg arg_array[fmt::internal::NonZero::VALUE] = { \ - fmt::internal::MakeArg(args)... \ - }; \ - func(arg0, arg1, ArgList(arg_array, sizeof...(Args))); \ - } - -#else - -# define FMT_MAKE_REF(n) fmt::internal::MakeArg(v##n) -// Defines a wrapper for a function taking one argument of type arg_type -// and n additional arguments of arbitrary types. -# define FMT_WRAP1(func, arg_type, n) \ - template \ - inline void func(arg_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ - const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ - func(arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ - } - -// Emulates a variadic function returning void on a pre-C++11 compiler. -# define FMT_VARIADIC_VOID(func, arg_type) \ - FMT_WRAP1(func, arg_type, 1) FMT_WRAP1(func, arg_type, 2) \ - FMT_WRAP1(func, arg_type, 3) FMT_WRAP1(func, arg_type, 4) \ - FMT_WRAP1(func, arg_type, 5) FMT_WRAP1(func, arg_type, 6) \ - FMT_WRAP1(func, arg_type, 7) FMT_WRAP1(func, arg_type, 8) \ - FMT_WRAP1(func, arg_type, 9) FMT_WRAP1(func, arg_type, 10) - -# define FMT_CTOR(ctor, func, arg0_type, arg1_type, n) \ - template \ - ctor(arg0_type arg0, arg1_type arg1, FMT_GEN(n, FMT_MAKE_ARG)) { \ - const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF)}; \ - func(arg0, arg1, fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ - } - -// Emulates a variadic constructor on a pre-C++11 compiler. -# define FMT_VARIADIC_CTOR(ctor, func, arg0_type, arg1_type) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 1) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 2) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 3) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 4) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 5) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 6) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 7) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 8) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 9) \ - FMT_CTOR(ctor, func, arg0_type, arg1_type, 10) -#endif - -// Generates a comma-separated list with results of applying f to pairs -// (argument, index). -#define FMT_FOR_EACH1(f, x0) f(x0, 0) -#define FMT_FOR_EACH2(f, x0, x1) \ - FMT_FOR_EACH1(f, x0), f(x1, 1) -#define FMT_FOR_EACH3(f, x0, x1, x2) \ - FMT_FOR_EACH2(f, x0 ,x1), f(x2, 2) -#define FMT_FOR_EACH4(f, x0, x1, x2, x3) \ - FMT_FOR_EACH3(f, x0, x1, x2), f(x3, 3) -#define FMT_FOR_EACH5(f, x0, x1, x2, x3, x4) \ - FMT_FOR_EACH4(f, x0, x1, x2, x3), f(x4, 4) -#define FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5) \ - FMT_FOR_EACH5(f, x0, x1, x2, x3, x4), f(x5, 5) -#define FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6) \ - FMT_FOR_EACH6(f, x0, x1, x2, x3, x4, x5), f(x6, 6) -#define FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7) \ - FMT_FOR_EACH7(f, x0, x1, x2, x3, x4, x5, x6), f(x7, 7) -#define FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8) \ - FMT_FOR_EACH8(f, x0, x1, x2, x3, x4, x5, x6, x7), f(x8, 8) -#define FMT_FOR_EACH10(f, x0, x1, x2, x3, x4, x5, x6, x7, x8, x9) \ - FMT_FOR_EACH9(f, x0, x1, x2, x3, x4, x5, x6, x7, x8), f(x9, 9) - -/** -An error returned by an operating system or a language runtime, -for example a file opening error. -*/ -class SystemError : public internal::RuntimeError { - private: - void init(int error_code, StringRef format_str, const ArgList &args); - - protected: - int error_code_; - - typedef char Char; // For FMT_VARIADIC_CTOR. - - SystemError() {} - - public: - /** - \rst - Constructs a :cpp:class:`fmt::SystemError` object with the description - of the form "**: **", where ** is the - formatted message and ** is the system message corresponding - to the error code. - *error_code* is a system error code as given by ``errno``. - \endrst - */ - SystemError(int error_code, StringRef message) { - init(error_code, message, ArgList()); - } - FMT_VARIADIC_CTOR(SystemError, init, int, StringRef) - - int error_code() const { return error_code_; } -}; - -/** - \rst - This template provides operations for formatting and writing data into - a character stream. The output is stored in a memory buffer that grows - dynamically. - - You can use one of the following typedefs for common character types: - - +---------+----------------------+ - | Type | Definition | - +=========+======================+ - | Writer | BasicWriter | - +---------+----------------------+ - | WWriter | BasicWriter | - +---------+----------------------+ - - **Example**:: - - Writer out; - out << "The answer is " << 42 << "\n"; - out.write("({:+f}, {:+f})", -3.14, 3.14); - - This will write the following output to the ``out`` object: - - .. code-block:: none - - The answer is 42 - (-3.140000, +3.140000) - - The output can be converted to an ``std::string`` with ``out.str()`` or - accessed as a C string with ``out.c_str()``. - \endrst - */ -template -class BasicWriter { - private: - // Output buffer. - mutable internal::Array buffer_; - - typedef typename internal::CharTraits::CharPtr CharPtr; - -#if _SECURE_SCL - static Char *GetBase(CharPtr p) { return p.base(); } -#else - static Char *GetBase(Char *p) { return p; } -#endif - - static CharPtr FillPadding(CharPtr buffer, - unsigned total_size, std::size_t content_size, wchar_t fill); - - // Grows the buffer by n characters and returns a pointer to the newly - // allocated area. - CharPtr GrowBuffer(std::size_t n) { - std::size_t size = buffer_.size(); - buffer_.resize(size + n); - return internal::CheckPtr(&buffer_[size], n); - } - - // Prepare a buffer for integer formatting. - CharPtr PrepareBufferForInt(unsigned num_digits, - const EmptySpec &, const char *prefix, unsigned prefix_size) { - unsigned size = prefix_size + num_digits; - CharPtr p = GrowBuffer(size); - std::copy(prefix, prefix + prefix_size, p); - return p + size - 1; - } - - template - CharPtr PrepareBufferForInt(unsigned num_digits, - const Spec &spec, const char *prefix, unsigned prefix_size); - - // Formats an integer. - template - void FormatInt(T value, const Spec &spec); - - // Formats a floating-point number (double or long double). - template - void FormatDouble(T value, const FormatSpec &spec); - - // Writes a formatted string. - template - CharPtr write_str( - const StringChar *s, std::size_t size, const AlignSpec &spec); - - template - void write_str( - const internal::Arg::StringValue &str, const FormatSpec &spec); - - // This method is private to disallow writing a wide string to a - // char stream and vice versa. If you want to print a wide string - // as a pointer as std::ostream does, cast it to const void*. - // Do not implement! - void operator<<(typename internal::CharTraits::UnsupportedStrType); - - friend class internal::ArgFormatter; - friend class BasicFormatter; - friend class internal::PrintfParser; - - public: - /** - Constructs a ``BasicWriter`` object. - */ - BasicWriter() {} - -#if FMT_USE_RVALUE_REFERENCES - /** - Constructs a ``BasicWriter`` object moving the content of the other - object to it. - */ - BasicWriter(BasicWriter &&other) : buffer_(std::move(other.buffer_)) {} - - /** - Moves the content of the other ``BasicWriter`` object to this one. - */ - BasicWriter& operator=(BasicWriter &&other) { - assert(this != &other); - buffer_ = std::move(other.buffer_); - return *this; - } -#endif - - /** - Returns the total number of characters written. - */ - std::size_t size() const { return buffer_.size(); } - - /** - Returns a pointer to the output buffer content. No terminating null - character is appended. - */ - const Char *data() const { return &buffer_[0]; } - - /** - Returns a pointer to the output buffer content with terminating null - character appended. - */ - const Char *c_str() const { - std::size_t size = buffer_.size(); - buffer_.reserve(size + 1); - buffer_[size] = '\0'; - return &buffer_[0]; - } - - /** - Returns the content of the output buffer as an `std::string`. - */ - std::basic_string str() const { - return std::basic_string(&buffer_[0], buffer_.size()); - } - - /** - \rst - Writes formatted data. - - *args* is an argument list representing arbitrary arguments. - - **Example**:: - - Writer out; - out.write("Current point:\n"); - out.write("({:+f}, {:+f})", -3.14, 3.14); - - This will write the following output to the ``out`` object: - - .. code-block:: none - - Current point: - (-3.140000, +3.140000) - - The output can be accessed using :meth:`data`, :meth:`c_str` or :meth:`str` - methods. - - See also `Format String Syntax`_. - \endrst - */ - void write(BasicStringRef format, const ArgList &args) { - BasicFormatter(*this).Format(format, args); - } - FMT_VARIADIC_VOID(write, fmt::BasicStringRef) - - BasicWriter &operator<<(int value) { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(unsigned value) { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(long value) { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(unsigned long value) { - return *this << IntFormatSpec(value); - } - BasicWriter &operator<<(LongLong value) { - return *this << IntFormatSpec(value); - } - - /** - Formats *value* and writes it to the stream. - */ - BasicWriter &operator<<(ULongLong value) { - return *this << IntFormatSpec(value); - } - - BasicWriter &operator<<(double value) { - FormatDouble(value, FormatSpec()); - return *this; - } - - /** - Formats *value* using the general format for floating-point numbers - (``'g'``) and writes it to the stream. - */ - BasicWriter &operator<<(long double value) { - FormatDouble(value, FormatSpec()); - return *this; - } - - /** - Writes a character to the stream. - */ - BasicWriter &operator<<(char value) { - *GrowBuffer(1) = value; - return *this; - } - - BasicWriter &operator<<(wchar_t value) { - *GrowBuffer(1) = internal::CharTraits::convert(value); - return *this; - } - - /** - Writes *value* to the stream. - */ - BasicWriter &operator<<(const fmt::BasicStringRef value) { - const Char *str = value.c_str(); - std::size_t size = value.size(); - std::copy(str, str + size, GrowBuffer(size)); - return *this; - } - - template - BasicWriter &operator<<(const IntFormatSpec &spec) { - internal::CharTraits::convert(FillChar()); - FormatInt(spec.value(), spec); - return *this; - } - - template - BasicWriter &operator<<(const StrFormatSpec &spec) { - const StringChar *s = spec.str(); - // TODO: error if fill is not convertible to Char - write_str(s, std::char_traits::length(s), spec); - return *this; - } - - void clear() { buffer_.clear(); } -}; - -template -template -typename BasicWriter::CharPtr BasicWriter::write_str( - const StringChar *s, std::size_t size, const AlignSpec &spec) { - CharPtr out = CharPtr(); - if (spec.width() > size) { - out = GrowBuffer(spec.width()); - Char fill = static_cast(spec.fill()); - if (spec.align() == ALIGN_RIGHT) { - std::fill_n(out, spec.width() - size, fill); - out += spec.width() - size; - } else if (spec.align() == ALIGN_CENTER) { - out = FillPadding(out, spec.width(), size, fill); - } else { - std::fill_n(out + size, spec.width() - size, fill); - } - } else { - out = GrowBuffer(size); - } - std::copy(s, s + size, out); - return out; -} - -template -template -typename fmt::BasicWriter::CharPtr - fmt::BasicWriter::PrepareBufferForInt( - unsigned num_digits, const Spec &spec, - const char *prefix, unsigned prefix_size) { - unsigned width = spec.width(); - Alignment align = spec.align(); - Char fill = static_cast(spec.fill()); - if (spec.precision() > static_cast(num_digits)) { - // Octal prefix '0' is counted as a digit, so ignore it if precision - // is specified. - if (prefix_size > 0 && prefix[prefix_size - 1] == '0') - --prefix_size; - unsigned number_size = prefix_size + spec.precision(); - AlignSpec subspec(number_size, '0', ALIGN_NUMERIC); - if (number_size >= width) - return PrepareBufferForInt(num_digits, subspec, prefix, prefix_size); - buffer_.reserve(width); - unsigned fill_size = width - number_size; - if (align != ALIGN_LEFT) { - CharPtr p = GrowBuffer(fill_size); - std::fill(p, p + fill_size, fill); - } - CharPtr result = PrepareBufferForInt(num_digits, subspec, prefix, prefix_size); - if (align == ALIGN_LEFT) { - CharPtr p = GrowBuffer(fill_size); - std::fill(p, p + fill_size, fill); - } - return result; - } - unsigned size = prefix_size + num_digits; - if (width <= size) { - CharPtr p = GrowBuffer(size); - std::copy(prefix, prefix + prefix_size, p); - return p + size - 1; - } - CharPtr p = GrowBuffer(width); - CharPtr end = p + width; - if (align == ALIGN_LEFT) { - std::copy(prefix, prefix + prefix_size, p); - p += size; - std::fill(p, end, fill); - } else if (align == ALIGN_CENTER) { - p = FillPadding(p, width, size, fill); - std::copy(prefix, prefix + prefix_size, p); - p += size; - } else { - if (align == ALIGN_NUMERIC) { - if (prefix_size != 0) { - p = std::copy(prefix, prefix + prefix_size, p); - size -= prefix_size; - } - } else { - std::copy(prefix, prefix + prefix_size, end - size); - } - std::fill(p, end - size, fill); - p = end; - } - return p - 1; -} - -template -template -void BasicWriter::FormatInt(T value, const Spec &spec) { - unsigned prefix_size = 0; - typedef typename internal::IntTraits::MainType UnsignedType; - UnsignedType abs_value = value; - char prefix[4] = ""; - if (internal::IsNegative(value)) { - prefix[0] = '-'; - ++prefix_size; - abs_value = 0 - abs_value; - } else if (spec.sign_flag()) { - prefix[0] = spec.plus_flag() ? '+' : ' '; - ++prefix_size; - } - switch (spec.type()) { - case 0: case 'd': { - unsigned num_digits = internal::CountDigits(abs_value); - CharPtr p = PrepareBufferForInt( - num_digits, spec, prefix, prefix_size) + 1 - num_digits; - internal::FormatDecimal(GetBase(p), abs_value, num_digits); - break; - } - case 'x': case 'X': { - UnsignedType n = abs_value; - if (spec.hash_flag()) { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type(); - } - unsigned num_digits = 0; - do { - ++num_digits; - } while ((n >>= 4) != 0); - Char *p = GetBase(PrepareBufferForInt( - num_digits, spec, prefix, prefix_size)); - n = abs_value; - const char *digits = spec.type() == 'x' ? - "0123456789abcdef" : "0123456789ABCDEF"; - do { - *p-- = digits[n & 0xf]; - } while ((n >>= 4) != 0); - break; - } - case 'b': case 'B': { - UnsignedType n = abs_value; - if (spec.hash_flag()) { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = spec.type(); - } - unsigned num_digits = 0; - do { - ++num_digits; - } while ((n >>= 1) != 0); - Char *p = GetBase(PrepareBufferForInt(num_digits, spec, prefix, prefix_size)); - n = abs_value; - do { - *p-- = '0' + (n & 1); - } while ((n >>= 1) != 0); - break; - } - case 'o': { - UnsignedType n = abs_value; - if (spec.hash_flag()) - prefix[prefix_size++] = '0'; - unsigned num_digits = 0; - do { - ++num_digits; - } while ((n >>= 3) != 0); - Char *p = GetBase(PrepareBufferForInt( - num_digits, spec, prefix, prefix_size)); - n = abs_value; - do { - *p-- = '0' + (n & 7); - } while ((n >>= 3) != 0); - break; - } - default: - internal::ReportUnknownType(spec.type(), "integer"); - break; - } -} - -// Formats a value. -template -void format(BasicFormatter &f, const Char *format_str, const T &value) { - std::basic_ostringstream os; - os << value; - f.format(format_str, internal::MakeArg(os.str())); -} - -// Reports a system error without throwing an exception. -// Can be used to report errors from destructors. -void ReportSystemError(int error_code, StringRef message) FMT_NOEXCEPT(true); - -#ifdef _WIN32 - -/** - A Windows error. -*/ -class WindowsError : public SystemError { - private: - void init(int error_code, StringRef format_str, const ArgList &args); - - public: - /** - \rst - Constructs a :cpp:class:`fmt::WindowsError` object with the description - of the form "**: **", where ** is the - formatted message and ** is the system message corresponding - to the error code. - *error_code* is a Windows error code as given by ``GetLastError``. - \endrst - */ - WindowsError(int error_code, StringRef message) { - init(error_code, message, ArgList()); - } - FMT_VARIADIC_CTOR(WindowsError, init, int, StringRef) -}; - -// Reports a Windows error without throwing an exception. -// Can be used to report errors from destructors. -void ReportWinError(int error_code, StringRef message) FMT_NOEXCEPT(true); - -#endif - -enum Color { BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE }; - -/** - Formats a string and prints it to stdout using ANSI escape sequences - to specify color (experimental). - Example: - PrintColored(fmt::RED, "Elapsed time: {0:.2f} seconds") << 1.23; - */ -void print_colored(Color c, StringRef format, const ArgList &args); - -/** - \rst - Formats a string similarly to Python's `str.format - `__ function - and returns the result as a string. - - *format_str* is a format string that contains literal text and replacement - fields surrounded by braces ``{}``. The fields are replaced with formatted - arguments in the resulting string. - - *args* is an argument list representing arbitrary arguments. - - **Example**:: - - std::string message = format("The answer is {}", 42); - - See also `Format String Syntax`_. - \endrst -*/ -inline std::string format(StringRef format_str, const ArgList &args) { - Writer w; - w.write(format_str, args); - return w.str(); -} - -inline std::wstring format(WStringRef format, const ArgList &args) { - WWriter w; - w.write(format, args); - return w.str(); -} - -/** - \rst - Prints formatted data to ``stdout``. - - **Example**:: - - print("Elapsed time: {0:.2f} seconds", 1.23); - \endrst - */ -void print(StringRef format, const ArgList &args); - -/** - \rst - Prints formatted data to a file. - - **Example**:: - - print(stderr, "Don't {}!", "panic"); - \endrst - */ -void print(std::FILE *f, StringRef format, const ArgList &args); - -/** - \rst - Prints formatted data to a stream. - - **Example**:: - - print(cerr, "Don't {}!", "panic"); - \endrst - */ -void print(std::ostream &os, StringRef format, const ArgList &args); - -template -void printf(BasicWriter &w, - BasicStringRef format, const ArgList &args) { - internal::PrintfParser().Format(w, format, args); -} - -inline std::string sprintf(StringRef format, const ArgList &args) { - Writer w; - printf(w, format, args); - return w.str(); -} - -void printf(StringRef format, const ArgList &args); - -/** - Fast integer formatter. - */ -class FormatInt { - private: - // Buffer should be large enough to hold all digits (digits10 + 1), - // a sign and a null character. - enum {BUFFER_SIZE = std::numeric_limits::digits10 + 3}; - mutable char buffer_[BUFFER_SIZE]; - char *str_; - - // Formats value in reverse and returns the number of digits. - char *FormatDecimal(ULongLong value) { - char *buffer_end = buffer_ + BUFFER_SIZE - 1; - while (value >= 100) { - // Integer division is slow so do it for a group of two digits instead - // of for every digit. The idea comes from the talk by Alexandrescu - // "Three Optimization Tips for C++". See speed-test for a comparison. - unsigned index = (value % 100) * 2; - value /= 100; - *--buffer_end = internal::DIGITS[index + 1]; - *--buffer_end = internal::DIGITS[index]; - } - if (value < 10) { - *--buffer_end = static_cast('0' + value); - return buffer_end; - } - unsigned index = static_cast(value * 2); - *--buffer_end = internal::DIGITS[index + 1]; - *--buffer_end = internal::DIGITS[index]; - return buffer_end; - } - - void FormatSigned(LongLong value) { - ULongLong abs_value = value; - bool negative = value < 0; - if (negative) - abs_value = 0 - value; - str_ = FormatDecimal(abs_value); - if (negative) - *--str_ = '-'; - } - - public: - explicit FormatInt(int value) { FormatSigned(value); } - explicit FormatInt(long value) { FormatSigned(value); } - explicit FormatInt(LongLong value) { FormatSigned(value); } - explicit FormatInt(unsigned value) : str_(FormatDecimal(value)) {} - explicit FormatInt(unsigned long value) : str_(FormatDecimal(value)) {} - explicit FormatInt(ULongLong value) : str_(FormatDecimal(value)) {} - - /** - Returns the number of characters written to the output buffer. - */ - std::size_t size() const { return buffer_ - str_ + BUFFER_SIZE - 1; } - - /** - Returns a pointer to the output buffer content. No terminating null - character is appended. - */ - const char *data() const { return str_; } - - /** - Returns a pointer to the output buffer content with terminating null - character appended. - */ - const char *c_str() const { - buffer_[BUFFER_SIZE - 1] = '\0'; - return str_; - } - - /** - Returns the content of the output buffer as an `std::string`. - */ - std::string str() const { return std::string(str_, size()); } -}; - -// Formats a decimal integer value writing into buffer and returns -// a pointer to the end of the formatted string. This function doesn't -// write a terminating null character. -template -inline void FormatDec(char *&buffer, T value) { - typename internal::IntTraits::MainType abs_value = value; - if (internal::IsNegative(value)) { - *buffer++ = '-'; - abs_value = 0 - abs_value; - } - if (abs_value < 100) { - if (abs_value < 10) { - *buffer++ = static_cast('0' + abs_value); - return; - } - unsigned index = static_cast(abs_value * 2); - *buffer++ = internal::DIGITS[index]; - *buffer++ = internal::DIGITS[index + 1]; - return; - } - unsigned num_digits = internal::CountDigits(abs_value); - internal::FormatDecimal(buffer, abs_value, num_digits); - buffer += num_digits; -} -} - -#if FMT_GCC_VERSION -// Use the system_header pragma to suppress warnings about variadic macros -// because suppressing -Wvariadic-macros with the diagnostic pragma doesn't work. -// It is used at the end because we want to suppress as little warnings as -// possible. -# pragma GCC system_header -#endif - -// This is used to work around VC++ bugs in handling variadic macros. -#define FMT_EXPAND(args) args - -// Returns the number of arguments. -// Based on https://groups.google.com/forum/#!topic/comp.std.c/d-6Mj5Lko_s. -#define FMT_NARG(...) FMT_NARG_(__VA_ARGS__, FMT_RSEQ_N()) -#define FMT_NARG_(...) FMT_EXPAND(FMT_ARG_N(__VA_ARGS__)) -#define FMT_ARG_N(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, N, ...) N -#define FMT_RSEQ_N() 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - -#define FMT_CONCAT(a, b) a##b -#define FMT_FOR_EACH_(N, f, ...) \ - FMT_EXPAND(FMT_CONCAT(FMT_FOR_EACH, N)(f, __VA_ARGS__)) -#define FMT_FOR_EACH(f, ...) \ - FMT_EXPAND(FMT_FOR_EACH_(FMT_NARG(__VA_ARGS__), f, __VA_ARGS__)) - -#define FMT_ADD_ARG_NAME(type, index) type arg##index -#define FMT_GET_ARG_NAME(type, index) arg##index - -#if FMT_USE_VARIADIC_TEMPLATES -# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ - template \ - ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ - const Args & ... args) { \ - using fmt::internal::Arg; \ - const Arg array[fmt::internal::NonZero::VALUE] = { \ - fmt::internal::MakeArg(args)... \ - }; \ - call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ - fmt::ArgList(array, sizeof...(Args))); \ - } -#else -// Defines a wrapper for a function taking __VA_ARGS__ arguments -// and n additional arguments of arbitrary types. -# define FMT_WRAP(Char, ReturnType, func, call, n, ...) \ - template \ - inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__), \ - FMT_GEN(n, FMT_MAKE_ARG)) { \ - const fmt::internal::Arg args[] = {FMT_GEN(n, FMT_MAKE_REF_##Char)}; \ - call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), \ - fmt::ArgList(args, sizeof(args) / sizeof(*args))); \ - } - -# define FMT_VARIADIC_(Char, ReturnType, func, call, ...) \ - inline ReturnType func(FMT_FOR_EACH(FMT_ADD_ARG_NAME, __VA_ARGS__)) { \ - call(FMT_FOR_EACH(FMT_GET_ARG_NAME, __VA_ARGS__), fmt::ArgList()); \ - } \ - FMT_WRAP(Char, ReturnType, func, call, 1, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 2, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 3, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 4, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 5, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 6, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 7, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 8, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 9, __VA_ARGS__) \ - FMT_WRAP(Char, ReturnType, func, call, 10, __VA_ARGS__) -#endif // FMT_USE_VARIADIC_TEMPLATES - -/** - \rst - Defines a variadic function with the specified return type, function name - and argument types passed as variable arguments to this macro. - - **Example**:: - - void print_error(const char *file, int line, const char *format, - const fmt::ArgList &args) { - fmt::print("{}: {}: ", file, line); - fmt::print(format, args); - } - FMT_VARIADIC(void, print_error, const char *, int, const char *) - \endrst - */ -#define FMT_VARIADIC(ReturnType, func, ...) \ - FMT_VARIADIC_(char, ReturnType, func, return func, __VA_ARGS__) - -#define FMT_VARIADIC_W(ReturnType, func, ...) \ - FMT_VARIADIC_(wchar_t, ReturnType, func, return func, __VA_ARGS__) - -namespace fmt { -FMT_VARIADIC(std::string, format, StringRef) -FMT_VARIADIC_W(std::wstring, format, WStringRef) -FMT_VARIADIC(void, print, StringRef) -FMT_VARIADIC(void, print, std::FILE *, StringRef) -FMT_VARIADIC(void, print, std::ostream &, StringRef) -FMT_VARIADIC(void, print_colored, Color, StringRef) -FMT_VARIADIC(std::string, sprintf, StringRef) -FMT_VARIADIC(void, printf, StringRef) -} - -// Restore warnings. -#if FMT_GCC_VERSION >= 406 -# pragma GCC diagnostic pop -#endif - -#endif // FMT_FORMAT_H_ diff --git a/thirdparty/strtk/strtk.hpp b/thirdparty/strtk/strtk.hpp deleted file mode 100644 index 2bfa702..0000000 --- a/thirdparty/strtk/strtk.hpp +++ /dev/null @@ -1,23653 +0,0 @@ -/* - ***************************************************************** - * String Toolkit Library * - * * - * Author: Arash Partow (2002-2014) * - * URL: http://www.partow.net/programming/strtk/index.html * - * * - * Copyright notice: * - * Free use of the String Toolkit Library is permitted under the * - * guidelines and in accordance with the most current version of * - * the Common Public License. * - * http://www.opensource.org/licenses/cpl1.0.php * - * * - ***************************************************************** -*/ - - -#ifndef INCLUDE_STRTK_HPP -#define INCLUDE_STRTK_HPP - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#ifndef strtk_no_tr1_or_boost - #define strtk_enable_lexical_cast - #define strtk_enable_random - #define strtk_enable_regex -#endif - -#ifdef strtk_enable_lexical_cast - #include -#endif - -#ifdef strtk_enable_random - // Requires definition of a TR1 compatible random library header - //#include - #include -#endif - -#ifdef strtk_enable_regex - // Requires definition of a TR1 compatible regex library header - //#include - #include -#endif - - -namespace strtk -{ - - static const std::size_t one_kilobyte = 1024; - static const std::size_t one_megabyte = 1024 * one_kilobyte; - static const std::size_t one_gigabyte = 1024 * one_megabyte; - static const std::size_t magic_seed = 0xA5A5A5A5; - - template - inline std::size_t for_each_token(const std::string& buffer, - Tokenizer& tokenizer, - Function function) - { - std::size_t token_count = 0; - tokenizer.assign(buffer); - typename Tokenizer::iterator itr = tokenizer.begin(); - typename Tokenizer::const_iterator end = tokenizer.end(); - while (end != itr) - { - function(*itr); - ++itr; - ++token_count; - } - return token_count; - } - - template - inline std::size_t for_each_line(std::istream& stream, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - function(buffer); - ++line_count; - } - return line_count; - } - - template - inline std::size_t for_each_line_n(std::istream& stream, - const std::size_t& n, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - function(buffer); - if (n == ++line_count) - break; - } - return line_count; - } - - template - inline std::size_t for_each_line(const std::string& file_name, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (stream) - return for_each_line(stream,function,buffer_size); - else - return 0; - } - - template - inline std::size_t for_each_line_n(const std::string& file_name, - const std::size_t& n, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (stream) - return for_each_line_n(stream,n,function,buffer_size); - else - return 0; - } - - template - inline std::size_t for_each_line_conditional(std::istream& stream, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - if (!function(buffer)) - { - return line_count; - } - ++line_count; - } - return line_count; - } - - template - inline std::size_t for_each_line_n_conditional(std::istream& stream, - const std::size_t& n, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - if (!function(buffer)) - { - return line_count; - } - if (n == ++line_count) - break; - } - return line_count; - } - - template - inline std::size_t for_each_line_conditional(const std::string& file_name, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (stream) - return for_each_line_conditional(stream,function,buffer_size); - else - return 0; - } - - template - inline std::size_t for_each_line_n_conditional(const std::string& file_name, - const std::size_t& n, - Function function, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (stream) - return for_each_line_n_conditional(stream,n,function,buffer_size); - else - return 0; - } - - template - inline bool read_line_as_value(std::istream& stream, - T& t, - const std::size_t& buffer_size = one_kilobyte) - { - std::string buffer; - buffer.reserve(buffer_size); - if (!std::getline(stream,buffer)) - return false; - return string_to_type_converter(buffer,t); - } - - namespace details - { - struct not_supported_type_tag {}; - struct unsigned_type_tag {}; - struct signed_type_tag {}; - struct real_type_tag {}; - struct byte_type_tag {}; - struct bool_type_tag {}; - struct hex_number_type_tag {}; - struct hex_string_type_tag {}; - struct base64_type_tag {}; - struct ignore_token_type_tag {}; - struct stdstring_type_tag {}; - struct stdstring_range_type_tag {}; - struct value_type_tag {}; - struct sink_type_tag {}; - struct stl_seq_type_tag {}; - struct attribute_type_tag {}; - struct semantic_action_type_tag {}; - struct expect_type_tag {}; - struct like_type_tag {}; - struct inrange_type_tag {}; - struct trim_type_tag {}; - struct lcase_type_tag {}; - struct ucase_type_tag {}; - struct fillchararray_type_tag {}; - struct truncint_type_tag {}; - - template - struct supported_conversion_to_type - { - typedef not_supported_type_tag type; - }; - - template - struct supported_conversion_from_type - { - typedef not_supported_type_tag type; - }; - - template - struct enable_if {}; - - template - struct enable_if { typedef T type; }; - - template - struct supported_iterator_type - { - enum { value = false }; - }; - - template - struct is_valid_iterator - { - typedef typename details::enable_if::value,T>::type type; - }; - - template struct numeric; - template inline std::size_t type_length(const T&); - - struct no_t {}; - struct yes_t {}; - - template - struct is_pod - { - typedef no_t result_t; - enum { result = false }; - }; - - template - struct is_stl_container - { typedef no_t result_t; }; - - #define register_stl_container1(C) \ - template struct is_stl_container >{ typedef yes_t result_t; }; - - #define register_stl_container2(C) \ - template struct is_stl_container >{ typedef yes_t result_t; }; - - register_stl_container1(std::vector) - register_stl_container1(std::deque) - register_stl_container1(std::list) - register_stl_container1(std::queue) - register_stl_container1(std::stack) - register_stl_container2(std::set) - register_stl_container2(std::multiset) - register_stl_container2(std::priority_queue) - - #undef register_stl_container1 - #undef register_stl_container2 - - template - void convert_type_assert(){} - - } // namespace details - - template - inline bool string_to_type_converter(const Iterator begin, const Iterator end, T& t) - { - typedef typename details::is_valid_iterator::type itr_type; - typename details::supported_conversion_to_type::type type; - details::convert_type_assert(); - Iterator itr = begin; - return string_to_type_converter_impl(itr,end,t,type); - } - - template - inline bool string_to_type_converter(const std::pair& range, T& t) - { - return string_to_type_converter(range.first,range.second,t); - } - - template - inline T string_to_type_converter(const Iterator begin, const Iterator end) - { - typedef typename details::is_valid_iterator::type itr_type; - typename details::supported_conversion_to_type::type type; - details::convert_type_assert(); - T t; - Iterator itr = begin; - if (string_to_type_converter_impl(itr,end,t,type)) - return t; - else - throw std::invalid_argument("string_to_type_converter() - Failed to convert: " + - std::string(begin,end)); - } - - template - inline T string_to_type_converter(const std::pair& range) - { - return string_to_type_converter(range.first,range.second); - } - - template - inline bool string_to_type_converter(const std::string& s, T& t) - { - return string_to_type_converter(s.data(),s.data() + s.size(),t); - } - - template - inline T string_to_type_converter(const std::string& s) - { - return string_to_type_converter(s.data(),s.data() + s.size()); - } - - template - inline bool type_to_string(const T& t, std::string& s) - { - typename details::supported_conversion_from_type::type type; - return type_to_string_converter_impl(t,s,type); - } - - template - inline std::string type_to_string(const T& t) - { - std::string s; - if (type_to_string(t,s)) - return s; - else - throw std::invalid_argument("type_to_string() - Failed to convert type to string"); - } - - #define strtk_begin_register_string_to_type \ - namespace strtk { namespace details { \ - - #define strtk_end_register_string_to_type \ - }} \ - - #define strtk_string_to_type_begin(Type) \ - namespace strtk { namespace details { template \ - inline bool string_to_type_converter_impl(const Iterator& begin, const Iterator& end, \ - Type& t, details::not_supported_type_tag&) { \ - - #define strtk_string_to_type_end() \ - }}} \ - - template class Sequence> - inline std::size_t load_from_text_file(std::istream& stream, - Sequence& sequence, - const std::size_t& buffer_size = one_kilobyte) - { - if (!stream) return 0; - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - ++line_count; - sequence.push_back(string_to_type_converter(buffer)); - } - return line_count; - } - - template - inline std::size_t load_from_text_file(std::istream& stream, - std::set& set, - const std::size_t& buffer_size = one_kilobyte) - { - if (!stream) return 0; - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - ++line_count; - set.insert(string_to_type_converter(buffer)); - } - return line_count; - } - - template - inline std::size_t load_from_text_file(std::istream& stream, - std::multiset& multiset, - const std::size_t& buffer_size = one_kilobyte) - { - if (!stream) return 0; - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - ++line_count; - multiset.insert(string_to_type_converter(buffer)); - } - return line_count; - } - - template - inline std::size_t load_from_text_file(std::istream& stream, - std::queue& queue, - const std::size_t& buffer_size = one_kilobyte) - { - if (!stream) return 0; - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - ++line_count; - queue.push(string_to_type_converter(buffer)); - } - return line_count; - } - - template - inline std::size_t load_from_text_file(std::istream& stream, - std::stack& stack, - const std::size_t& buffer_size = one_kilobyte) - { - if (!stream) return 0; - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - ++line_count; - stack.push(string_to_type_converter(buffer)); - } - return line_count; - } - - template - inline std::size_t load_from_text_file(std::istream& stream, - std::priority_queue& priority_queue, - const std::size_t& buffer_size = one_kilobyte) - { - if (!stream) return 0; - std::string buffer; - buffer.reserve(buffer_size); - std::size_t line_count = 0; - while (std::getline(stream,buffer)) - { - ++line_count; - priority_queue.push(string_to_type_converter(buffer)); - } - return line_count; - } - - template class Sequence> - inline std::size_t load_from_text_file(const std::string& file_name, - Sequence& sequence, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return load_from_text_file(stream,sequence,buffer_size); - } - - template - inline std::size_t load_from_text_file(const std::string& file_name, - std::set& set, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return load_from_text_file(stream,set,buffer_size); - } - - template - inline std::size_t load_from_text_file(const std::string& file_name, - std::multiset& multiset, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return load_from_text_file(stream,multiset,buffer_size); - } - - template - inline std::size_t load_from_text_file(const std::string& file_name, - std::queue& queue, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return load_from_text_file(stream,queue,buffer_size); - } - - template - inline std::size_t load_from_text_file(const std::string& file_name, - std::stack& stack, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return load_from_text_file(stream,stack,buffer_size); - } - - template - inline std::size_t load_from_text_file(const std::string& file_name, - std::priority_queue& priority_queue, - const std::size_t& buffer_size = one_kilobyte) - { - std::ifstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return load_from_text_file(stream,priority_queue,buffer_size); - } - - template class Sequence> - inline std::size_t write_to_text_file(std::ostream& stream, - const Sequence& sequence, - const std::string& delimiter = "") - { - if (!stream) return 0; - - std::size_t count = 0; - typename Sequence::const_iterator itr = sequence.begin(); - typename Sequence::const_iterator end = sequence.end(); - - if (!delimiter.empty()) - { - while (end != itr) - { - stream << (*itr) << delimiter; - ++itr; - ++count; - } - } - else - { - while (end != itr) - { - stream << (*itr); - ++itr; - ++count; - } - } - return count; - } - - template - inline std::size_t write_to_text_file(std::ostream& stream, - const std::set& set, - const std::string& delimiter = "") - { - if (!stream) return 0; - - std::size_t count = 0; - typename std::set::const_iterator itr = set.begin(); - typename std::set::const_iterator end = set.end(); - - if (!delimiter.empty()) - { - while (end != itr) - { - stream << (*itr) << delimiter; - ++itr; - ++count; - } - } - else - { - while (end != itr) - { - stream << (*itr); - ++itr; - ++count; - } - } - return count; - } - - template - inline std::size_t write_to_text_file(std::ostream& stream, - const std::multiset& multiset, - const std::string& delimiter = "") - { - if (!stream) return 0; - - std::size_t count = 0; - typename std::multiset::const_iterator itr = multiset.begin(); - typename std::multiset::const_iterator end = multiset.end(); - - if (!delimiter.empty()) - { - while (end != itr) - { - stream << (*itr) << delimiter; - ++itr; - ++count; - } - } - else - { - while (end != itr) - { - stream << (*itr); - ++itr; - ++count; - } - } - return count; - } - - template class Sequence> - inline std::size_t write_to_text_file(const std::string& file_name, - const Sequence& sequence, - const std::string& delimiter = "") - { - std::ofstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return write_to_text_file(stream,sequence,delimiter); - } - - template - inline std::size_t write_to_text_file(const std::string& file_name, - const std::set& set, - const std::string& delimiter = "") - { - std::ofstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return write_to_text_file(stream,set,delimiter); - } - - template - inline std::size_t write_to_text_file(const std::string& file_name, - const std::multiset& multiset, - const std::string& delimiter = "") - { - std::ofstream stream(file_name.c_str()); - if (!stream) - return 0; - else - return write_to_text_file(stream,multiset,delimiter); - } - - template - inline void copy_n(InputIterator itr, std::size_t n, OutputIterator out) - { - while (n) - { - (*out) = (*itr); - ++itr; - ++out; - --n; - } - } - - template - inline void copy_if(Predicate predicate, - const InputIterator begin, const InputIterator end, - OutputIterator out) - { - InputIterator itr = begin; - while (end != itr) - { - if (predicate(*itr)) - { - *(out++) = (*itr); - } - ++itr; - } - } - - template - inline InputIterator copy_while(Predicate predicate, - const InputIterator begin, const InputIterator end, - OutputIterator out) - { - InputIterator itr = begin; - while (end != itr) - { - if (!predicate(*itr)) - return itr; - *(out++) = *(itr++); - } - return end; - } - - template - inline InputIterator copy_until(Predicate predicate, - const InputIterator begin, const InputIterator end, - OutputIterator out) - { - InputIterator itr = begin; - while (end != itr) - { - if (predicate(*itr)) - return itr; - *(out++) = *(itr++); - } - return end; - } - - template - inline void extract_unique(const InputIterator begin, const InputIterator end, - OutputIterator out) - { - typedef typename std::iterator_traits::value_type T; - std::vector buffer(begin,end); - std::sort(buffer.begin(),buffer.end()); - std::unique_copy(buffer.begin(),buffer.end(),out); - } - - template - inline bool range_only_contains(Predicate predicate, - const InputIterator begin, - const InputIterator end) - { - InputIterator itr = begin; - while (end != itr) - { - if (!predicate(*itr)) - { - return false; - } - ++itr; - } - return true; - } - - namespace range - { - template - class adapter - { - public: - - typedef T value_type; - typedef T* iterator; - typedef const iterator const_iterator; - - adapter(T* const begin, T* const end) - : begin_(begin), - end_(end) - {} - - adapter(const std::pair& r) - : begin_(r.first), - end_(r.second) - {} - - adapter(T* const begin, const std::size_t length) - : begin_(begin), - end_(begin_ + length) - {} - - inline iterator begin() const - { - return begin_; - } - - inline iterator end() const - { - return end_; - } - - inline std::size_t size() const - { - return std::distance(begin_,end_); - } - - inline operator std::string() const - { - return stringify(begin_,end_); - } - - inline const T& operator[](const std::size_t& index) const - { - return *(begin_ + index); - } - - inline T& operator[](const std::size_t& index) - { - return *(begin_ + index); - } - - private: - - template - static inline std::string stringify(Type*,Type*) - { - static std::string result = ""; - return result; - } - - static inline std::string stringify(const char* begin, const char* end) - { - return std::string(begin,end); - } - - iterator begin_; - iterator end_; - }; - - typedef adapter string; - typedef adapter ustring; - - template - inline adapter type(const T* begin, const T* end) - { - return adapter(begin,end); - } - - template - inline adapter type(const T (&t)[N]) - { - return adapter(t,N); - } - - static inline adapter type(const std::string& s) - { - return adapter(s.data(),s.size()); - } - - template class Sequence> - inline adapter::iterator> type(const Sequence& seq) - { - return adapter::iterator>(seq.begin(),seq.end()); - } - - inline std::string as_string(const adapter& a) - { - return std::string(a.begin(),a.end()); - } - - inline std::string as_string(const adapter& a) - { - return std::string(a.begin(),a.end()); - } - - } // namespace range - - template - struct single_delimiter_predicate - { - public: - - typedef T value_type; - - single_delimiter_predicate(const T& d) - : delimiter_(d) - {} - - inline bool operator()(const T& d) const - { - return delimiter_ == d; - } - - private: - - single_delimiter_predicate& operator=(const single_delimiter_predicate&); - const T delimiter_; - }; - - template - struct multiple_delimiter_predicate - { - public: - - typedef T value_type; - - multiple_delimiter_predicate(const T* d_begin, const T* d_end) - : length_(std::distance(d_begin,d_end)), - delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]), - delimiter_end_(delimiter_ + length_) - { - std::copy(d_begin,d_end, delimiter_); - } - - multiple_delimiter_predicate(const T d[], const std::size_t& length) - : length_(length), - delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]), - delimiter_end_(delimiter_ + length_) - { - std::copy(d,d + length, delimiter_); - } - - template - multiple_delimiter_predicate(const Iterator begin, const Iterator end) - : length_(std::distance(begin,end)), - delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]), - delimiter_end_(delimiter_ + length_) - { - //static_assert(T == std::iterator_traits::value_type); - std::copy(begin,end, delimiter_); - } - - template - multiple_delimiter_predicate(const range::adapter& r) - : length_(std::distance(r.begin(),r.end())), - delimiter_((length_ <= sbo_buffer_size) ? sbo_buffer : new T[length_]), - delimiter_end_(delimiter_ + length_) - { - //static_assert(T == std::iterator_traits::value_type); - std::copy(r.begin(),r.end(), delimiter_); - } - - ~multiple_delimiter_predicate() - { - if (length_ > sbo_buffer_size) - { - delete[] delimiter_; - } - } - - inline bool operator()(const T& d) const - { - return (std::find(delimiter_,delimiter_end_,d) != delimiter_end_); - } - - private: - - multiple_delimiter_predicate(const multiple_delimiter_predicate& mdp); - multiple_delimiter_predicate& operator=(const multiple_delimiter_predicate& mdp); - - std::size_t length_; - T* delimiter_; - T* delimiter_end_; - enum { sbo_buffer_size = 32 }; - T sbo_buffer[sbo_buffer_size]; - }; - - struct multiple_char_delimiter_predicate - { - public: - - template - multiple_char_delimiter_predicate(const Iterator begin, const Iterator end) - { - setup_delimiter_table(begin,end); - } - - multiple_char_delimiter_predicate(const std::string& s) - { - setup_delimiter_table(s.data(),s.data() + s.size()); - } - - inline bool operator()(const unsigned char& c) const - { - return (delimiter_table_[c]); - } - - inline bool operator()(const char& c) const - { - return operator()(static_cast(c)); - } - - private: - - static const std::size_t table_size = 256; - - template - inline void setup_delimiter_table(const Iterator begin, const Iterator end) - { - std::fill_n(delimiter_table_,table_size,false); - for (Iterator itr = begin; itr != end; ++itr) - { - delimiter_table_[static_cast(*itr)] = true; - } - } - - bool delimiter_table_[table_size]; - }; - - namespace details - { - template class Sequence> - struct index_remover_impl - { - typedef Sequence sequence_t; - index_remover_impl(const sequence_t& sequence) - : itr_(sequence.begin()), - end_(sequence.end()), - current_index_(0), - check_(true) - {} - - template - inline bool operator()(const T&) - { - if (check_) - { - if (current_index_++ == *itr_) - { - if (end_ == ++itr_) - { - check_ = false; - } - return true; - } - } - return false; - } - - typename sequence_t::const_iterator itr_; - typename sequence_t::const_iterator end_; - std::size_t current_index_; - bool check_; - }; - } - - template class Sequence> - inline details::index_remover_impl index_remover(const Sequence& sequence) - { - return details::index_remover_impl(sequence); - } - - template - inline std::size_t remove_inplace(Predicate predicate, - Iterator begin, - Iterator end) - { - Iterator itr1 = begin; - Iterator itr2 = begin; - std::size_t removal_count = 0; - while (end != itr1) - { - if (predicate(*itr1)) - { - ++itr1; - ++removal_count; - } - else - { - if (itr1 != itr2) - { - (*itr2) = (*itr1); - } - ++itr1; - ++itr2; - } - } - return removal_count; - } - - template - inline std::size_t remove_inplace(Predicate predicate, const range::adapter& r) - { - return remove_inplace(predicate,r.begin(),r.end()); - } - - template class Sequence> - inline std::size_t remove_inplace(Predicate predicate, Sequence& sequence) - { - const std::size_t removal_count = remove_inplace(predicate,sequence.begin(),sequence.end()); - sequence.resize(sequence.size() - removal_count); - return removal_count; - } - - inline void remove_inplace(const std::string::value_type c, std::string& s) - { - const std::size_t removal_count = remove_inplace(single_delimiter_predicate(c), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template - inline void remove_inplace(Predicate predicate, std::string& s) - { - const std::size_t removal_count = remove_inplace(predicate, - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template - inline std::size_t remove_consecutives_inplace(Predicate predicate, - Iterator begin, - Iterator end) - { - if (0 == std::distance(begin,end)) return 0; - Iterator itr1 = begin; - Iterator itr2 = begin; - typename std::iterator_traits::value_type prev = *begin; - std::size_t removal_count = 0; - ++itr1; - ++itr2; - while (end != itr1) - { - while ((end != itr1) && (!predicate(*itr1) || !predicate(prev))) - { - if (itr1 != itr2) - { - (*itr2) = (*itr1); - } - prev = (*itr1); - ++itr1; - ++itr2; - } - - while ((end != itr1) && predicate(*itr1)) - { - ++itr1; - ++removal_count; - } - } - - return removal_count; - } - - template - inline std::size_t remove_consecutives_inplace(Predicate predicate, const range::adapter& r) - { - return remove_consecutives_inplace(predicate,r.begin(),r.end()); - } - - inline void remove_consecutives_inplace(const std::string::value_type c, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_consecutives_inplace(single_delimiter_predicate(c), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline void remove_consecutives_inplace(const std::string& rem_chars, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate(rem_chars), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - namespace details - { - #if (defined(__MINGW32_VERSION)) || \ - (defined(__CYGWIN__) || defined(__CYGWIN32__)) || \ - (defined(__APPLE__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070)) || \ - (defined(_WIN32) && (_MSC_VER < 1400)) - inline std::size_t strnlength(const char* s, const std::size_t& n) - { - const char *end = reinterpret_cast(memchr(s, '\0', n)); - return end ? (size_t) (end - s) : n; - } - #else - inline std::size_t strnlength(const char* s, const std::size_t& n) - { - return strnlen(s,n); - } - #endif - } - - inline void remove_consecutives_inplace(const char* rem_chars, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_consecutives_inplace(multiple_char_delimiter_predicate( - rem_chars, - rem_chars + details::strnlength(rem_chars,256)), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template - inline void remove_consecutives_inplace(Predicate predicate, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_consecutives_inplace(predicate, - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template - inline std::size_t remove_consecutives_inplace(Iterator begin, Iterator end) - { - if (0 == std::distance(begin,end)) return 0; - - Iterator itr1 = begin; ++itr1; - Iterator itr2 = begin; ++itr2; - typename std::iterator_traits::value_type prev = *begin; - std::size_t removal_count = 0; - - while (end != itr1) - { - while ((end != itr1) && (prev != (*itr1))) - { - if (itr1 != itr2) - { - (*itr2) = (*itr1); - } - prev = (*itr1); - ++itr1; - ++itr2; - } - - while ((end != itr1) && (prev == (*itr1))) - { - ++itr1; - ++removal_count; - } - } - - return removal_count; - } - - template - inline std::size_t remove_consecutives_inplace(const range::adapter& r) - { - return remove_consecutives_inplace(r.begin(),r.end()); - } - - template class Sequence> - inline void remove_consecutives_inplace(Sequence& sequence) - { - const std::size_t removal_count = remove_consecutives_inplace(sequence.begin(),sequence.end()); - sequence.resize(sequence.size() - removal_count); - } - - inline void remove_consecutives_inplace(std::string& s) - { - std::size_t removal_count = remove_consecutives_inplace(const_cast(s.data()), - const_cast(s.data() + s.size())); - - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline std::string remove_duplicates(const std::string& str) - { - std::string::value_type table[0xFF]; - std::fill_n(table,0xFF,static_cast(0)); - std::string result; - result.reserve(str.size()); - for (std::size_t i = 0; i < str.size(); ++i) - { - const char c = str[i]; - if (0 == table[static_cast(c)]) - { - table[static_cast(c)] = 0x01; - result += c; - } - } - return result; - } - - inline std::string remove_duplicates_inplace(std::string& str) - { - return remove_duplicates(str); - } - - template - inline std::size_t remove_trailing(Predicate predicate, - Iterator begin, - Iterator end) - { - const std::size_t length = std::distance(begin,end); - if (0 == length) - return 0; - Iterator itr = begin + (length - 1); - std::size_t removal_count = 0; - - while ((begin != itr) && predicate(*itr)) - { - --itr; - ++removal_count; - } - - return removal_count; - } - - template - inline std::size_t remove_trailing(Predicate predicate, const range::adapter& r) - { - return remove_trailing(predicate,r.begin(),r.end()); - } - - inline void remove_trailing(const std::string::value_type c, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_trailing(single_delimiter_predicate(c), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline void remove_trailing(const std::string& rem_chars, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate(rem_chars), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline void remove_trailing(const char* rem_chars, std::string& s) - { - const std::size_t removal_count = remove_trailing(multiple_char_delimiter_predicate( - rem_chars, - rem_chars + details::strnlength(rem_chars,256)), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template - inline void remove_trailing(Predicate predicate, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_trailing(predicate, - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template - inline std::size_t remove_leading(Predicate predicate, - Iterator begin, - Iterator end) - { - const std::size_t length = std::distance(begin,end); - if (0 == length) - return 0; - Iterator itr = begin; - std::size_t removal_count = 0; - - while ((end != itr) && predicate(*itr)) - { - ++itr; - ++removal_count; - } - - std::copy(itr,end,begin); - return removal_count; - } - - template - inline std::size_t remove_leading(Predicate predicate, const range::adapter& r) - { - return remove_leading(predicate,r.begin(),r.end()); - } - - inline void remove_leading(const std::string::value_type c, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_leading(single_delimiter_predicate(c), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline void remove_leading(const std::string& rem_chars, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate(rem_chars), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline void remove_leading(const char* rem_chars, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_leading(multiple_char_delimiter_predicate( - rem_chars, - rem_chars + details::strnlength(rem_chars,256)), - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - inline void remove_leading_trailing(const std::string& rem_chars, std::string& s) - { - remove_leading(rem_chars,s); - remove_trailing(rem_chars,s); - } - - template - inline void remove_leading(Predicate predicate, std::string& s) - { - if (s.empty()) return; - const std::size_t removal_count = remove_leading(predicate, - const_cast(s.data()), - const_cast(s.data() + s.size())); - if (removal_count > 0) - { - s.resize(s.size() - removal_count); - } - } - - template class Sequence> - void remove_empty_strings(Sequence& seq) - { - struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } }; - seq.erase(std::remove_if(seq.begin(),seq.end(),is_empty::check),seq.end()); - } - - template - void remove_empty_strings(std::list& l) - { - struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } }; - l.remove_if(is_empty::check); - } - - template - void remove_empty_strings(std::set& set) - { - struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } }; - typename std::set::iterator itr = set.begin(); - while (set.end() != itr) - { - if ((*itr).empty()) - set.erase(itr++); - else - ++itr; - } - } - - template - void remove_empty_strings(std::multiset& set) - { - struct is_empty { static inline bool check(const std::string& s) { return s.empty(); } }; - typename std::multiset::iterator itr = set.begin(); - while (set.end() != itr) - { - if ((*itr).empty()) - set.erase(itr++); - else - ++itr; - } - } - - template - inline void replace(const typename std::iterator_traits::value_type& c1, - const typename std::iterator_traits::value_type& c2, - const Iterator begin, - const Iterator end) - { - for (Iterator itr = begin; end != itr; ++itr) - { - if (c1 == (*itr)) - { - (*itr) = c2; - } - } - } - - inline void replace(const std::string::value_type& c0, - const std::string::value_type& c1, - std::string& s) - { - replace(c0,c1,const_cast(s.data()),const_cast(s.data() + s.size())); - } - - template - inline void replace(const T& c1, const T& c2, const range::adapter& r) - { - replace(c1,c2,r.begin(),r.end()); - } - - inline void replace_pattern(const std::string& s, // input - const std::string& p, // pattern - const std::string& r, // replacement - std::string& n) - { - if (p.empty() || (p == r)) - { - n.assign(s); - return; - } - - const std::size_t p_size = p.size(); - const std::size_t r_size = r.size(); - int inc = static_cast(r_size) - static_cast(p_size); - std::size_t pos = 0; - std::vector delta_list; - delta_list.reserve(std::min(32,(s.size() / p_size) + 1)); - - while (std::string::npos != (pos = s.find(p,pos))) - { - delta_list.push_back(pos); - pos += p_size; - } - - if (delta_list.empty()) - { - n.assign(s); - return; - } - - n.resize(delta_list.size() * inc + s.size(), 0x00); - char* n_itr = const_cast(n.data()); - const char* s_end = s.data() + s.size(); - const char* s_itr = s.data(); - const char* r_begin = r.data(); - const char* r_end = r.data() + r_size; - const std::size_t delta_list_size = delta_list.size(); - std::size_t i = 0; - std::size_t delta = delta_list[0]; - - for ( ; ; ) - { - std::copy(s_itr, s_itr + delta, n_itr); - s_itr += p_size + delta; - n_itr += delta; - std::copy(r_begin, r_end, n_itr); - n_itr += r_size; - if (++i >= delta_list_size) - break; - delta = delta_list[i] - (delta_list[i - 1] + p_size); - } - - if (s_end != s_itr) - { - std::copy(s_itr, s_end, n_itr); - } - } - - template - inline std::size_t replace_pattern(const InputIterator s_begin, const InputIterator s_end, // input - const InputIterator p_begin, const InputIterator p_end, // pattern - const InputIterator r_begin, const InputIterator r_end, // replacement - OutputIterator out) - { - InputIterator s_itr = s_begin; - InputIterator r_itr = r_begin; - InputIterator p_itr = p_begin; - - const std::size_t p_size = std::distance(p_begin,p_end); - const std::size_t r_size = std::distance(r_begin,r_end); - - if ((0 == p_size) || ((p_size == r_size) && std::equal(p_begin,p_end,r_begin))) - { - std::copy(s_begin,s_end,out); - return std::distance(s_begin,s_end); - } - - std::size_t pos = 0; - std::size_t prev_pos = 0; - std::size_t count = 0; - std::size_t new_size = std::distance(s_begin,s_end); - int inc = r_size - p_size; - - InputIterator temp_s_itr = s_itr; - - while (s_end != s_itr) - { - /* - Need to replace the following search code with - Knuth-Pratt-Morris or Boyer-Moore string search - algorithms. - */ - bool found = true; - p_itr = p_begin; - temp_s_itr = s_itr; - - while ((p_end != p_itr) && (s_end != temp_s_itr)) - { - if (*(temp_s_itr++) != *(p_itr++)) - { - found = false; - break; - } - } - - if (found && (p_itr == p_end)) - { - ++count; - new_size += inc; - s_itr = temp_s_itr; - } - else - ++s_itr; - } - - s_itr = s_begin; - p_itr = p_begin; - - pos = 0; - prev_pos = 0; - - temp_s_itr = s_itr; - - while (0 < count) - { - p_itr = p_begin; - bool found = true; - InputIterator pattern_start = temp_s_itr; - - while ((p_end != p_itr) && (s_end != temp_s_itr)) - { - if (*(temp_s_itr++) != *(p_itr++)) - { - found = false; - temp_s_itr = pattern_start; - ++temp_s_itr; - break; - } - } - - if (!found || (p_itr != p_end)) continue; - - pos = std::distance(s_begin,temp_s_itr) - p_size; - int diff = pos - prev_pos; - - std::copy(s_itr,s_itr + diff, out); - s_itr = temp_s_itr; - std::copy(r_itr,r_end, out); - - pos += p_size; - prev_pos = pos; - --count; - } - - std::copy(s_itr,s_end,out); - - return new_size; - } - - inline void remove_pattern(const std::string& s, - const std::string& p, - std::string& n) - { - static const std::string r(""); - replace_pattern(s,p,r,n); - } - - inline void sort(std::string& s) - { - std::sort(s.begin(),s.end()); - } - - template - inline bool match(const Iterator pattern_begin, - const Iterator pattern_end, - const Iterator data_begin, - const Iterator data_end, - const typename std::iterator_traits::value_type& zero_or_more, - const typename std::iterator_traits::value_type& zero_or_one) - { - /* - Credits: Adapted from code by Jack Handy (2001) - */ - if (0 == std::distance(data_begin,data_end)) return false; - - Iterator d_itr = data_begin; - Iterator p_itr = pattern_begin; - Iterator c_itr = data_begin; - Iterator m_itr = data_begin; - - while ((data_end != d_itr) && (zero_or_more != (*p_itr))) - { - if (((*p_itr) != (*d_itr)) && (zero_or_one != (*p_itr))) - { - return false; - } - ++p_itr; - ++d_itr; - } - - while (data_end != d_itr) - { - if (zero_or_more == (*p_itr)) - { - if (pattern_end == (++p_itr)) - { - return true; - } - m_itr = p_itr; - c_itr = d_itr; - ++c_itr; - } - else if (((*p_itr) == (*d_itr)) || (zero_or_one == (*p_itr))) - { - ++p_itr; - ++d_itr; - } - else - { - p_itr = m_itr; - d_itr = c_itr++; - } - } - - while ((p_itr != pattern_end) && (zero_or_more == (*p_itr))) ++p_itr; - - return (p_itr == pattern_end); - } - - inline bool match(const std::string& wild_card, - const std::string& str) - { - /* - * : Zero or more match - ? : Zero or one match - */ - return match(wild_card.data(), - wild_card.data() + wild_card.size(), - str.data(), - str.data() + str.size(), - '*', - '?'); - } - - inline bool imatch_char(const char c1, const char c2) - { - return std::toupper(c1) == std::toupper(c2); - } - - template - inline bool imatch(const InputIterator begin1, const InputIterator end1, - const InputIterator begin2, const InputIterator end2) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (std::distance(begin1,end1) != std::distance(begin2,end2)) - { - return false; - } - - InputIterator itr1 = begin1; - InputIterator itr2 = begin2; - - while (end1 != itr1) - { - //if (std::toupper(*itr1, std::locale::classic()) != std::toupper(*it2, std::locale::classic())) - if (std::toupper(*itr1) != std::toupper(*itr2)) - { - return false; - } - ++itr1; - ++itr2; - } - - return true; - } - - template - inline bool imatch(const range::adapter& r1, const range::adapter& r2) - { - return imatch(r1.begin(),r1.end(),r2.begin(),r2.end()); - } - - inline bool imatch(const std::string& s1, const std::string& s2) - { - return imatch(s1.data(), - s1.data() + s1.size(), - s2.data(), - s2.data() + s2.size()); - } - - template - inline Iterator imatch(const std::string& s, const Iterator begin, const Iterator end) - { - for (const std::string* itr = begin; end != itr; ++itr) - { - if (imatch(s,*itr)) - { - return itr; - } - } - return end; - } - - template class Sequence> - inline bool imatch(const std::string& s, const Sequence& sequence) - { - return (sequence.end() != imatch(s,sequence.begin(),sequence.end())); - } - - template - inline bool imatch(const std::string& s, const std::set& set) - { - return imatch(s,set.begin(),set.end()); - } - - template - inline bool imatch(const std::string& s, const std::multiset& multiset) - { - return imatch(s,multiset.begin(),multiset.end()); - } - - template - inline std::size_t find_all(const Iterator pattern_begin, - const Iterator pattern_end, - const Iterator begin, - const Iterator end, - OutputIterator out) - { - Iterator itr = begin; - const std::size_t pattern_length = std::distance(pattern_begin,pattern_end); - std::size_t match_count = 0; - while (end != (itr = std::search(itr, end, pattern_begin, pattern_end))) - { - (*out) = std::make_pair(itr,itr + pattern_length); - itr += pattern_length; - ++out; - ++match_count; - } - return match_count; - } - - template class Sequence> - inline std::size_t find_all(const Iterator pattern_begin, - const Iterator pattern_end, - const Iterator begin, - const Iterator end, - Sequence& seq) - { - return find_all(pattern_begin,pattern_end,begin,end,std::back_inserter(seq)); - } - - inline std::size_t ifind(const std::string& pattern, const std::string& data) - { - if (pattern.size() > data.size()) - return std::string::npos; - const char* result_itr = std::search(data.data(),data.data() + data.size(), - pattern.data(), pattern.data() + pattern.size(), - imatch_char); - if ((data.data() + data.size()) == result_itr) - return std::string::npos; - else - return std::distance(data.data(),result_itr); - } - - template - inline std::size_t ifind_all(const Iterator pattern_begin, - const Iterator pattern_end, - const Iterator begin, - const Iterator end, - OutputIterator out) - { - Iterator itr = begin; - const std::size_t pattern_length = std::distance(pattern_begin,pattern_end); - std::size_t match_count = 0; - - while (end != (itr = std::search(itr, end, pattern_begin, pattern_end, imatch_char))) - { - (*out) = std::make_pair(itr,itr + pattern_length); - itr += pattern_length; - ++out; - ++match_count; - } - - return match_count; - } - - template - inline std::size_t find_all(const std::string& pattern, - const std::string& data, - OutputIterator out) - { - return find_all(pattern.data(), pattern.data() + pattern.size(), - data.data(), data.data() + data.size(), - out); - } - - template class Sequence> - inline std::size_t find_all(const std::string& pattern, - const std::string& data, - Sequence& seq) - { - return find_all(pattern,data,std::back_inserter(seq)); - } - - template - inline std::size_t ifind_all(const std::string& pattern, - const std::string& data, - OutputIterator out) - { - return ifind_all(pattern.data(), pattern.data() + pattern.size(), - data.data(), data.data() + data.size(), - out); - } - - template class Sequence> - inline std::size_t ifind_all(const std::string& pattern, - const std::string& data, - Sequence& seq) - { - return ifind_all(pattern,data,std::back_inserter(seq)); - } - - template - inline bool begins_with(const InputIterator pattern_begin, - const InputIterator pattern_end, - const InputIterator begin, - const InputIterator end) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end)) - { - return std::equal(pattern_begin,pattern_end,begin); - } - else - return false; - } - - inline bool begins_with(const std::string& pattern, const std::string& data) - { - if (pattern.size() <= data.size()) - { - return begins_with(pattern.data(), - pattern.data() + pattern.size(), - data.data(), - data.data() + data.size()); - } - else - return false; - } - - template - inline bool ibegins_with(const InputIterator pattern_begin, - const InputIterator pattern_end, - const InputIterator begin, - const InputIterator end) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (std::distance(pattern_begin,pattern_end) <= std::distance(begin,end)) - { - return std::equal(pattern_begin,pattern_end,begin,imatch_char); - } - else - return false; - } - - inline bool ibegins_with(const std::string& pattern, const std::string& data) - { - if (pattern.size() <= data.size()) - { - return ibegins_with(pattern.data(), - pattern.data() + pattern.size(), - data.data(), - data.data() + data.size()); - } - else - return false; - } - - template - inline bool ends_with(const InputIterator pattern_begin, - const InputIterator pattern_end, - const InputIterator begin, - const InputIterator end) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - const std::size_t pattern_length = std::distance(pattern_begin,pattern_end); - const std::size_t data_length = std::distance(begin,end); - if (pattern_length <= data_length) - { - return std::equal(pattern_begin, - pattern_end, - begin + (data_length - pattern_length)); - } - else - return false; - } - - inline bool ends_with(const std::string& pattern, const std::string& data) - { - if (pattern.size() <= data.size()) - { - return ends_with(pattern.data(), - pattern.data() + pattern.size(), - data.data(), - data.data() + data.size()); - } - else - return false; - } - - template - inline bool iends_with(const InputIterator pattern_begin, - const InputIterator pattern_end, - const InputIterator begin, - const InputIterator end) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - const std::size_t pattern_length = std::distance(pattern_begin,pattern_end); - const std::size_t data_length = std::distance(begin,end); - if (pattern_length <= data_length) - { - return std::equal(pattern_begin, - pattern_end, - begin + (data_length - pattern_length), - imatch_char); - } - else - return false; - } - - inline bool iends_with(const std::string& pattern, const std::string& data) - { - if (pattern.size() <= data.size()) - { - return iends_with(pattern.data(), - pattern.data() + pattern.size(), - data.data(), - data.data() + data.size()); - } - else - return false; - } - - inline std::size_t index_of(const std::string& pattern, const std::string& data) - { - if (pattern.empty()) - return std::string::npos; - else if (data.empty()) - return std::string::npos; - else if (pattern.size() > data.size()) - return std::string::npos; - const char* itr = std::search(data.data(), - data.data() + data.size(), - pattern.data(), - pattern.data() + pattern.size()); - return ((data.data() + data.size()) == itr) ? std::string::npos : std::distance(data.data(),itr); - } - - namespace tokenize_options - { - typedef std::size_t type; - enum - { - default_mode = 0, - compress_delimiters = 1, - include_1st_delimiter = 2, - include_all_delimiters = 4 - }; - - static inline bool perform_compress_delimiters(const type& split_opt) - { - return compress_delimiters == (split_opt & compress_delimiters); - } - - static inline bool perform_include_1st_delimiter(const type& split_opt) - { - return include_1st_delimiter == (split_opt & include_1st_delimiter); - } - - static inline bool perform_include_all_delimiters(const type& split_opt) - { - return include_all_delimiters == (split_opt & include_all_delimiters); - } - - } // namespace tokenize_options - - template - class tokenizer - { - private: - - template > - class tokenizer_iterator : public std::iterator - { - protected: - - typedef Iterator iterator; - typedef const iterator const_iterator; - typedef typename std::pair range_type; - - public: - - explicit inline tokenizer_iterator(const iterator begin, - const iterator end, - const Predicate& predicate, - const tokenize_options::type tokenize_option = tokenize_options::default_mode) - : predicate_(predicate), - end_(end), - range_(begin,begin), - current_token_(end,end), - compress_delimiters_(tokenize_options::perform_compress_delimiters(tokenize_option)), - include_1st_delimiter_(tokenize_options::perform_include_1st_delimiter(tokenize_option)), - include_all_delimiters_(tokenize_options::perform_include_all_delimiters(tokenize_option)), - include_delimiters_(include_1st_delimiter_ || include_all_delimiters_), - last_token_done_(false) - { - if (end != begin) - { - this->operator++(); - } - } - - inline tokenizer_iterator& operator++() - { - if (last_token_done_) - { - range_.first = range_.second; - return (*this); - } - else if (end_ != range_.second) - { - range_.first = range_.second; - } - - while (end_ != range_.second) - { - if (predicate_(*(range_.second))) - { - if (include_delimiters_) - { - if (include_1st_delimiter_) - ++range_.second; - else if (include_all_delimiters_) - while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second; - current_token_ = range_; - if ((!include_all_delimiters_) && compress_delimiters_) - while ((end_ != range_.second) && predicate_(*(range_.second))) ++range_.second; - } - else - { - current_token_ = range_; - if (compress_delimiters_) - while ((end_ != (++range_.second)) && predicate_(*(range_.second))) ; - else - ++range_.second; - } - return (*this); - } - else - ++range_.second; - } - - if (range_.first != range_.second) - { - current_token_.second = range_.second; - if (!last_token_done_) - { - if (predicate_(*(range_.second - 1))) - current_token_.first = range_.second; - else - current_token_.first = range_.first; - last_token_done_ = true; - } - else - range_.first = range_.second; - } - - return (*this); - } - - inline tokenizer_iterator operator++(int) - { - tokenizer_iterator tmp = (*this); - this->operator++(); - return tmp; - } - - inline tokenizer_iterator& operator+=(const int inc) - { - if (inc > 0) - { - for (int i = 0; i < inc; ++i, ++(*this)) ; - } - return (*this); - } - - inline T operator*() const - { - return current_token_; - } - - inline std::string as_string() const - { - return std::string(current_token_.first,current_token_.second); - } - - inline bool operator==(const tokenizer_iterator& itr) const - { - return (range_ == itr.range_) && (end_ == itr.end_); - } - - inline bool operator!=(const tokenizer_iterator& itr) const - { - return (range_ != itr.range_) || (end_ != itr.end_); - } - - inline tokenizer_iterator& operator=(const tokenizer_iterator& itr) - { - if (this != &itr) - { - range_ = itr.range_; - current_token_ = itr.current_token_; - end_ = itr.end_; - compress_delimiters_ = itr.compress_delimiters_; - include_1st_delimiter_ = itr.include_1st_delimiter_; - include_all_delimiters_ = itr.include_all_delimiters_; - include_delimiters_ = itr.include_delimiters_; - last_token_done_ = itr.last_token_done_; - } - return (*this); - } - - inline std::string remaining() const - { - return std::string(current_token_.first,end_); - } - - protected: - - const Predicate& predicate_; - iterator end_; - range_type range_; - range_type current_token_; - bool compress_delimiters_; - bool include_1st_delimiter_; - bool include_all_delimiters_; - bool include_delimiters_; - bool last_token_done_; - }; - - public: - - typedef typename std::iterator_traits::value_type value_type; - typedef DelimiterPredicate predicate; - typedef tokenizer_iterator iterator; - typedef const iterator const_iterator; - typedef iterator& iterator_ref; - typedef const_iterator& const_iterator_ref; - - inline tokenizer(const Iterator begin, - const Iterator end, - const DelimiterPredicate& predicate, - const tokenize_options::type tokenize_options = tokenize_options::default_mode) - : tokenize_options_(tokenize_options), - predicate_(predicate), - begin_(begin), - end_(end), - begin_itr_(begin_,end_,predicate_,tokenize_options_), - end_itr_(end_,end_,predicate_,tokenize_options_) - {} - - inline tokenizer(const std::string& s, - const DelimiterPredicate& predicate, - const tokenize_options::type tokenize_options = tokenize_options::default_mode) - : tokenize_options_(tokenize_options), - predicate_(predicate), - begin_(s.data()), - end_(s.data() + s.size()), - begin_itr_(begin_,end_,predicate_,tokenize_options_), - end_itr_(end_,end_,predicate_,tokenize_options_) - {} - - inline tokenizer& operator=(const tokenizer& t) - { - if (this != &t) - { - begin_ = t.begin_; - end_ = t.end_; - end_itr_ = t.end_itr_; - begin_itr_ = t.begin_itr_; - tokenize_options_ = t.tokenize_options_; - } - return (*this); - } - - inline void assign(const std::string& s) const - { - assign(s.data(),s.data() + s.size()); - } - - inline void assign(const std::string& s) - { - assign(s.data(),s.data() + s.size()); - } - - inline void assign(const Iterator begin, const Iterator end) - { - begin_ = begin; - end_ = end; - begin_itr_ = iterator(begin_,end_,predicate_,tokenize_options_); - end_itr_ = iterator(end_,end_,predicate_,tokenize_options_); - } - - inline const_iterator_ref begin() const - { - return begin_itr_; - } - - inline const_iterator_ref end() const - { - return end_itr_; - } - - private: - - tokenize_options::type tokenize_options_; - const DelimiterPredicate& predicate_; - Iterator begin_; - Iterator end_; - iterator begin_itr_; - iterator end_itr_; - }; - - namespace std_string - { - template > - struct tokenizer - { - typedef DelimiterPredicate predicate_type; - typedef const std::string::value_type* string_iterator_type; - typedef strtk::tokenizer type; - typedef strtk::tokenizer md_type; - typedef std::pair iterator_type; - }; - - typedef tokenizer<>::iterator_type iterator_type; - typedef tokenizer<>::iterator_type range_t; - - typedef std::vector token_vector_type; - typedef std::deque token_deque_type; - typedef std::list token_list_type; - - } // namespace std_string - - template - class range_to_type_back_inserter_iterator : public std::iterator - { - public: - - typedef typename Sequence::value_type value_type; - - explicit inline range_to_type_back_inserter_iterator(Sequence& sequence) - : sequence_(sequence) - {} - - range_to_type_back_inserter_iterator(const range_to_type_back_inserter_iterator& it) - : sequence_(it.sequence_) - {} - - inline range_to_type_back_inserter_iterator& operator=(const range_to_type_back_inserter_iterator& it) - { - if (this != &it) - { - this->sequence_ = it.sequence_; - } - return (*this); - } - - template - inline range_to_type_back_inserter_iterator& operator=(const std::pair& r) - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - sequence_.push_back(t); - return (*this); - } - - inline range_to_type_back_inserter_iterator& operator=(const std::string& s) - { - value_type t; - if (string_to_type_converter(s.data(),s.data() + s.size(),t)) - sequence_.push_back(t); - return (*this); - } - - template - inline void operator()(const std::pair& r) const - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - sequence_.push_back(t); - } - - template - inline void operator()(const Iterator begin, const Iterator end) - { - sequence_.push_back(string_to_type_converter(begin,end)); - } - - inline range_to_type_back_inserter_iterator& operator*() - { - return (*this); - } - - inline range_to_type_back_inserter_iterator& operator++() - { - return (*this); - } - - inline range_to_type_back_inserter_iterator operator++(int) - { - return (*this); - } - - private: - - Sequence& sequence_; - }; - - template - inline range_to_type_back_inserter_iterator range_to_type_back_inserter(Sequence& sequence) - { - return (range_to_type_back_inserter_iterator(sequence)); - } - - template - class range_to_type_inserter_iterator : public std::iterator - { - public: - - typedef typename Set::value_type value_type; - - explicit inline range_to_type_inserter_iterator(Set& set) - : set_(set) - {} - - range_to_type_inserter_iterator(const range_to_type_inserter_iterator& it) - : set_(it.set_) - {} - - inline range_to_type_inserter_iterator& operator=(const range_to_type_inserter_iterator& it) - { - if (this != &it) - { - this->set_ = it.set_; - } - return (*this); - } - - template - inline range_to_type_inserter_iterator& operator=(const std::pair& r) - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - set_.insert(t); - return (*this); - } - - template - inline void operator()(const std::pair& r) - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - set_.insert(t); - } - - inline range_to_type_inserter_iterator& operator*() - { - return (*this); - } - - inline range_to_type_inserter_iterator& operator++() - { - return (*this); - } - - inline range_to_type_inserter_iterator operator++(int) - { - return (*this); - } - - private: - - Set& set_; - }; - - template - inline range_to_type_inserter_iterator range_to_type_inserter(Set& set) - { - return (range_to_type_inserter_iterator(set)); - } - - template - class range_to_type_push_inserter_iterator : public std::iterator - { - public: - - typedef typename Container::value_type value_type; - - explicit inline range_to_type_push_inserter_iterator(Container& container) - : container_(container) - {} - - range_to_type_push_inserter_iterator(const range_to_type_push_inserter_iterator& it) - : container_(it.container_) - {} - - inline range_to_type_push_inserter_iterator& operator=(const range_to_type_push_inserter_iterator& it) - { - if (this != &it) - { - this->container_ = it.container_; - } - return (*this); - } - - template - inline range_to_type_push_inserter_iterator& operator=(const std::pair& r) - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - container_.push(t); - return (*this); - } - - template - inline void operator()(const std::pair& r) - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - container_.push(t); - } - - inline range_to_type_push_inserter_iterator& operator*() - { - return (*this); - } - - inline range_to_type_push_inserter_iterator& operator++() - { - return (*this); - } - - inline range_to_type_push_inserter_iterator operator++(int) - { - return (*this); - } - - private: - - Container& container_; - }; - - template - inline range_to_type_push_inserter_iterator range_to_type_push_inserter(Container& container) - { - return (range_to_type_push_inserter_iterator(container)); - } - - template - class back_inserter_with_valuetype_iterator : public std::iterator - { - public: - - explicit inline back_inserter_with_valuetype_iterator(Sequence& sequence) - : sequence_(sequence) - {} - - back_inserter_with_valuetype_iterator(const back_inserter_with_valuetype_iterator& it) - : sequence_(it.sequence_) - {} - - inline back_inserter_with_valuetype_iterator& operator=(const back_inserter_with_valuetype_iterator& it) - { - if (this != &it) - { - this->sequence_ = it.sequence_; - } - return (*this); - } - - inline back_inserter_with_valuetype_iterator& operator=(const typename Sequence::value_type& v) - { - sequence_.push_back(v); - return (*this); - } - - inline void operator()(const typename Sequence::value_type& v) - { - sequence_.push_back(v); - } - - inline back_inserter_with_valuetype_iterator& operator*() - { - return (*this); - } - - inline back_inserter_with_valuetype_iterator& operator++() - { - return (*this); - } - - inline back_inserter_with_valuetype_iterator operator++(int) - { - return (*this); - } - - private: - - Sequence& sequence_; - }; - - template - inline back_inserter_with_valuetype_iterator back_inserter_with_valuetype(Sequence& sequence_) - { - return (back_inserter_with_valuetype_iterator(sequence_)); - } - - template - class inserter_with_valuetype_iterator : public std::iterator - { - public: - - explicit inline inserter_with_valuetype_iterator(Set& set) - : set_(set) - {} - - inserter_with_valuetype_iterator(const inserter_with_valuetype_iterator& itr) - : set_(itr.set_) - {} - - inline inserter_with_valuetype_iterator& operator=(const inserter_with_valuetype_iterator& itr) - { - if (this != &itr) - { - this->set_ = itr.set_; - } - return (*this); - } - - inline inserter_with_valuetype_iterator& operator=(const typename Set::value_type& v) - { - set_.insert(v); - return (*this); - } - - inline void operator()(const typename Set::value_type& v) - { - set_.insert(v); - } - - inline inserter_with_valuetype_iterator& operator*() - { - return (*this); - } - - inline inserter_with_valuetype_iterator& operator++() - { - return (*this); - } - - inline inserter_with_valuetype_iterator operator++(int) - { - return (*this); - } - - private: - - Set& set_; - }; - - template - inline inserter_with_valuetype_iterator inserter_with_valuetype(Set& set_) - { - return (inserter_with_valuetype_iterator(set_)); - } - - template - class push_inserter_iterator : public std::iterator - { - public: - - explicit inline push_inserter_iterator(Container& container) - : container_(container) - {} - - inline push_inserter_iterator& operator=(const push_inserter_iterator& itr) - { - if (this != &itr) - { - this->container_ = itr.container_; - } - return (*this); - } - - inline push_inserter_iterator& operator=(typename Container::const_reference v) - { - container_.push(v); - return (*this); - } - - inline push_inserter_iterator& operator*() - { - return (*this); - } - - inline push_inserter_iterator& operator++() - { - return (*this); - } - - inline push_inserter_iterator operator++(int) - { - return (*this); - } - - private: - - Container& container_; - }; - - template - inline push_inserter_iterator push_inserter(Container& c) - { - return push_inserter_iterator(c); - } - - template - class range_to_ptr_type_iterator : public std::iterator - { - public: - - typedef T value_type; - - explicit inline range_to_ptr_type_iterator(T* pointer, std::size_t& insert_count) - : pointer_(pointer), - insert_count_(insert_count) - {} - - range_to_ptr_type_iterator(const range_to_ptr_type_iterator& it) - : pointer_(it.pointer_) - {} - - inline range_to_ptr_type_iterator& operator=(const range_to_ptr_type_iterator& it) - { - if (this != &it) - { - this->pointer_ = it.pointer_; - } - return (*this); - } - - template - inline range_to_ptr_type_iterator& operator=(const std::pair& r) - { - value_type t = value_type(); - if (string_to_type_converter(r.first,r.second,t)) - { - (*pointer_) = t; - ++pointer_; - ++insert_count_; - } - return (*this); - } - - inline range_to_ptr_type_iterator& operator=(const std::string& s) - { - value_type t = value_type(); - if (string_to_type_converter(s.data(),s.data() + s.size(),t)) - { - (*pointer_) = t; - ++pointer_; - ++insert_count_; - } - return (*this); - } - - template - inline void operator()(const std::pair& r) const - { - value_type t; - if (string_to_type_converter(r.first,r.second,t)) - { - (*pointer_) = t; - ++pointer_; - ++insert_count_; - } - } - - template - inline void operator()(const Iterator begin, const Iterator end) - { - (*pointer_) = string_to_type_converter(begin,end); - ++pointer_; - ++insert_count_; - } - - inline range_to_ptr_type_iterator& operator*() - { - return (*this); - } - - inline range_to_ptr_type_iterator& operator++() - { - return (*this); - } - - inline range_to_ptr_type_iterator operator++(int) - { - return (*this); - } - - private: - - T* pointer_; - std::size_t& insert_count_; - }; - - template - inline range_to_ptr_type_iterator range_to_ptr_type(T* pointer, std::size_t& insert_count) - { - return (range_to_ptr_type_iterator(pointer,insert_count)); - } - - template - inline range_to_ptr_type_iterator range_to_ptr_type(T* pointer) - { - static std::size_t insert_count = 0; - return (range_to_ptr_type_iterator(pointer,insert_count)); - } - - template - class counting_back_inserter_iterator : public std::iterator - { - public: - - explicit inline counting_back_inserter_iterator(std::size_t& counter) - : counter_(counter) - {} - - counting_back_inserter_iterator(const counting_back_inserter_iterator& itr) - : counter_(itr.counter_) - {} - - inline counting_back_inserter_iterator& operator=(const counting_back_inserter_iterator& itr) - { - if (this != &itr) - { - this->counter_ = itr.counter_; - } - return (*this); - } - - inline counting_back_inserter_iterator& operator=(const T&) - { - ++counter_; - return (*this); - } - - inline void operator()(const T&) - { - ++counter_; - } - - inline counting_back_inserter_iterator& operator*() - { - return (*this); - } - - inline counting_back_inserter_iterator& operator++() - { - return (*this); - } - - inline counting_back_inserter_iterator operator++(int) - { - return (*this); - } - - private: - - std::size_t& counter_; - }; - - template - inline counting_back_inserter_iterator counting_back_inserter(std::size_t& counter_) - { - return (counting_back_inserter_iterator(counter_)); - } - - template - class functional_inserter_iterator : public std::iterator - { - public: - - explicit inline functional_inserter_iterator(Function function) - : function_(function) - {} - - functional_inserter_iterator(const functional_inserter_iterator& it) - : function_(it.function_) - {} - - inline functional_inserter_iterator& operator=(const functional_inserter_iterator& it) - { - if (this != &it) - { - this->function_ = it.function_; - } - return (*this); - } - - template - inline functional_inserter_iterator& operator=(const T& t) - { - function_(t); - return (*this); - } - - template - inline void operator()(const T& t) - { - function_(t); - } - - inline functional_inserter_iterator& operator*() - { - return (*this); - } - - inline functional_inserter_iterator& operator++() - { - return (*this); - } - - inline functional_inserter_iterator operator++(int) - { - return (*this); - } - - private: - - Function function_; - }; - - template - inline functional_inserter_iterator functional_inserter(Function function) - { - return (functional_inserter_iterator(function)); - } - - namespace split_options - { - typedef std::size_t type; - enum - { - default_mode = 0, - compress_delimiters = 1, - include_1st_delimiter = 2, - include_all_delimiters = 4 - }; - - static inline bool perform_compress_delimiters(const type& split_opt) - { - return compress_delimiters == (split_opt & compress_delimiters); - } - - static inline bool perform_include_1st_delimiter(const type& split_opt) - { - return include_1st_delimiter == (split_opt & include_1st_delimiter); - } - - static inline bool perform_include_all_delimiters(const type& split_opt) - { - return include_all_delimiters == (split_opt & include_all_delimiters); - } - - } // namespace split_options - - namespace details - { - template - inline std::size_t split_compress_delimiters(const DelimiterPredicate& delimiter, - const Iterator begin, - const Iterator end, - OutputIterator out) - { - std::size_t token_count = 0; - std::pair range(begin,begin); - - while (end != range.second) - { - if (delimiter(*range.second)) - { - (*out) = range; - ++out; - while ((end != ++range.second) && delimiter(*range.second)); - range.first = range.second; - if (end != range.second) - ++range.second; - ++token_count; - } - else - ++range.second; - } - - if ((range.first != range.second) || delimiter(*(range.second - 1))) - { - (*out) = range; - ++out; - ++token_count; - } - - return token_count; - } - } - - template - inline std::size_t split(const DelimiterPredicate& delimiter, - const Iterator begin, - const Iterator end, - OutputIterator out, - const split_options::type split_option = split_options::default_mode) - { - if (begin == end) return 0; - const bool compress_delimiters = split_options::perform_compress_delimiters(split_option); - const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option); - const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option); - const bool include_delimiters = include_1st_delimiter || include_all_delimiters; - - if (compress_delimiters && (!include_delimiters)) - { - return details::split_compress_delimiters(delimiter,begin,end,out); - } - - std::size_t token_count = 0; - std::pair range(begin,begin); - - while (end != range.second) - { - if (delimiter(*range.second)) - { - if (include_delimiters) - { - if (include_1st_delimiter) - ++range.second; - else if (include_all_delimiters) - while ((end != range.second) && delimiter(*range.second)) ++range.second; - (*out) = range; - ++out; - if ((!include_all_delimiters) && compress_delimiters) - while ((end != range.second) && delimiter(*range.second)) ++range.second; - } - else - { - (*out) = range; - ++out; - ++range.second; - } - ++token_count; - range.first = range.second; - } - else - ++range.second; - } - - if ((range.first != range.second) || delimiter(*(range.second - 1))) - { - (*out) = range; - ++out; - ++token_count; - } - - return token_count; - } - - template - inline std::size_t split(const DelimiterPredicate& delimiter, - const std::pair& range, - OutputIterator out, - const split_options::type split_option = split_options::default_mode) - { - return split(delimiter, - range.first,range.second, - out, - split_option); - } - - template - inline std::size_t split(const char* delimiters, - const std::pair& range, - OutputIterator out, - const split_options::type split_option = split_options::default_mode) - { - if (1 == details::strnlength(delimiters,256)) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - out, - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - out, - split_option); - } - - template - inline std::size_t split(const std::string& delimiters, - const std::pair& range, - OutputIterator out, - const split_options::type split_option = split_options::default_mode) - { - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - out, - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - out, - split_option); - } - - template - inline std::size_t split(const char* delimiters, - const std::string& str, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - if (1 == details::strnlength(delimiters,256)) - return split(single_delimiter_predicate(delimiters[0]), - str.data(), str.data() + str.size(), - out, - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - str.data(), str.data() + str.size(), - out, - split_option); - } - - template - inline std::size_t split(const std::string& delimiters, - const std::string& str, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - str.data(), str.data() + str.size(), - out, - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - str.data(), str.data() + str.size(), - out, - split_option); - } - - template - inline std::size_t split(const std::string::value_type delimiter, - const std::string& str, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - return split(single_delimiter_predicate(delimiter), - str.data(), str.data() + str.size(), - out, - split_option); - } - - template class Sequence> - inline std::size_t split(const char* delimiters, - const std::string& str, - Sequence,Allocator>& sequence, - const split_options::type& split_option = split_options::default_mode) - { - if (1 == details::strnlength(delimiters,256)) - return split(single_delimiter_predicate(delimiters[0]), - str.data(), str.data() + str.size(), - std::back_inserter(sequence), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - str.data(), str.data() + str.size(), - std::back_inserter(sequence), - split_option); - } - - template class Sequence> - inline std::size_t split(const std::string& delimiters, - const std::string& str, - Sequence,Allocator>& sequence, - const split_options::type& split_option = split_options::default_mode) - { - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - str.data(), str.data() + str.size(), - std::back_inserter(sequence), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - str.data(), str.data() + str.size(), - std::back_inserter(sequence), - split_option); - } - - template - inline std::size_t split(const DelimiterPredicate& delimiter, - const std::string& str, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - return split(delimiter, - str.data(), str.data() + str.size(), - out, - split_option); - } - - template - inline std::size_t split_n(const DelimiterPredicate& delimiter, - const Iterator begin, - const Iterator end, - const std::size_t& token_count, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - if (0 == token_count) return 0; - if (begin == end) return 0; - std::size_t match_count = 0; - std::pair range(begin,begin); - const bool compress_delimiters = split_options::perform_compress_delimiters(split_option); - const bool include_1st_delimiter = split_options::perform_include_1st_delimiter(split_option); - const bool include_all_delimiters = (!include_1st_delimiter) && split_options::perform_include_all_delimiters(split_option); - const bool include_delimiters = include_1st_delimiter || include_all_delimiters; - - while (end != range.second) - { - if (delimiter(*range.second)) - { - if (include_delimiters) - { - ++range.second; - (*out) = range; - ++out; - if (++match_count >= token_count) - return match_count; - if (compress_delimiters) - while ((end != range.second) && delimiter(*range.second)) ++range.second; - } - else - { - (*out) = range; - ++out; - if (++match_count >= token_count) - return match_count; - if (compress_delimiters) - while ((end != (++range.second)) && delimiter(*range.second)) ; - else - ++range.second; - } - range.first = range.second; - } - else - ++range.second; - } - - if ((range.first != range.second) || delimiter(*(range.second - 1))) - { - (*out) = range; - ++out; - ++match_count; - } - - return match_count; - } - - template - inline std::size_t split_n(const char* delimiters, - const std::string& str, - const std::size_t& token_count, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - return split_n(multiple_char_delimiter_predicate(delimiters), - str.data(), str.data() + str.size(), - token_count, - out, - split_option); - } - - template - inline std::size_t split_n(const std::string& delimiters, - const std::string& str, - const std::size_t& token_count, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - if (1 == delimiters.size()) - return split_n(single_delimiter_predicate(delimiters[0]), - str.data(), str.data() + str.size(), - token_count, - out, - split_option); - else - return split_n(multiple_char_delimiter_predicate(delimiters), - str.data(), str.data() + str.size(), - token_count, - out, - split_option); - } - - template - inline std::size_t split_n(const std::string& delimiters, - const InputIterator begin, - const InputIterator end, - const std::size_t& token_count, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - token_count, - out, - split_option); - else - return split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - token_count, - out, - split_option); - } - - template - inline std::size_t split_n(const std::string::value_type delimiter, - const std::string& str, - const std::size_t& token_count, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - return split_n(single_delimiter_predicate(delimiter), - str.data(),str.data() + str.size(), - token_count, - out, - split_option); - } - - template - inline std::size_t split_n(const DelimiterPredicate& delimiter, - const std::string& str, - const std::size_t& token_count, - OutputIterator out, - const split_options::type& split_option = split_options::default_mode) - { - return split_n(delimiter, - str.data(),str.data() + str.size(), - token_count, - out, - split_option); - } - - #ifdef strtk_enable_regex - - static const std::string uri_expression ("((https?|ftp)\\://((\\[?(\\d{1,3}\\.){3}\\d{1,3}\\]?)|(([-a-zA-Z0-9]+\\.)+[a-zA-Z]{2,4}))(\\:\\d+)?(/[-a-zA-Z0-9._?,+&%$#=~\\\\]+)*/?)"); - static const std::string email_expression ("([\\w\\-\\.]+)@((\\[([0-9]{1,3}\\.){3}[0-9]{1,3}\\])|(([\\w\\-]+\\.)+)([a-zA-Z]{2,4}))"); - static const std::string ip_expression ("(([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+)\\.([0-2]*[0-9]+[0-9]+))"); - static const std::string ieee754_expression ("([-+]?((\\.[0-9]+|[0-9]+\\.[0-9]+)([eE][-+][0-9]+)?|[0-9]+))"); - - namespace regex_match_mode - { - enum type - { - match_all = 0, - match_1 = 1, - match_2 = 2, - match_3 = 3, - match_4 = 4, - match_5 = 5, - match_6 = 6, - match_7 = 7, - match_8 = 8, - match_9 = 9 - }; - } - - template - inline std::size_t split_regex(const boost::regex& delimiter_expression, - const InputIterator begin, - const InputIterator end, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - boost::regex_iterator itr(begin,end,delimiter_expression); - boost::regex_iterator itr_end; - std::pair range(begin,begin); - std::size_t match_count = 0; - while (itr_end != itr) - { - range.first = (*itr)[mode].first; - range.second = (*itr)[mode].second; - (*out) = range; - ++out; - ++itr; - ++match_count; - } - return match_count; - } - - template - inline std::size_t split_regex(const std::string& delimiter_expression, - const InputIterator begin, - const InputIterator end, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - const boost::regex regex_expression(delimiter_expression); - return split_regex(regex_expression, - begin,end, - out, - mode); - } - - template - inline std::size_t split_regex(const std::string& delimiter_expression, - const std::string& text, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - return split_regex(delimiter_expression, - text.begin(),text.end(), - out, - mode); - } - - template - inline std::size_t split_regex(const boost::regex& delimiter_expression, - const std::string& text, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - return split_regex(delimiter_expression, - text.begin(),text.end(), - out, - mode); - } - - template - inline std::size_t split_regex_n(const boost::regex& delimiter_expression, - const InputIterator begin, - const InputIterator end, - const std::size_t& token_count, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - boost::sregex_iterator itr(begin,end,delimiter_expression); - const boost::sregex_iterator itr_end; - std::pair range(begin,begin); - std::size_t match_count = 0; - while (itr_end != itr) - { - range.first = (*itr)[mode].first; - range.second = (*itr)[mode].second; - (*out) = range; - ++out; - ++itr; - if (++match_count >= token_count) - return match_count; - } - return match_count; - } - - template - inline std::size_t split_regex_n(const std::string& delimiter_expression, - const InputIterator begin, - const InputIterator end, - const std::size_t& token_count, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - const boost::regex regex_expression(delimiter_expression); - return split_regex_n(regex_expression, - begin,end, - token_count, - out, - mode); - } - - template - inline std::size_t split_regex_n(const std::string& delimiter_expression, - const std::string& text, - const std::size_t& token_count, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - return split_regex_n(delimiter_expression, - text.begin(),text.end(), - token_count, - out, - mode); - } - - template - inline std::size_t split_regex_n(const boost::regex& delimiter_expression, - const std::string& text, - const std::size_t& token_count, - OutputIterator out, - const regex_match_mode::type mode = regex_match_mode::match_all) - { - return split_regex_n(delimiter_expression, - text.begin(),text.end(), - token_count, - out, - mode); - } - - #endif // strtk_enable_regex - - template - class offset_predicate - { - public: - - offset_predicate(const int offset_list[], const bool rotate = false) - : rotate_(rotate), - current_index_(0) - { - std::copy(offset_list, offset_list + offset_list_size, offset_list_); - offset_list_[offset_list_size] = 0; - } - - inline bool operator!() const - { - return (0 == offset_list_size); - } - - inline void reset() const - { - current_index_ = 0; - } - - inline std::size_t size() const - { - return offset_list_size; - } - - inline int next() const - { - int result = offset_list_[current_index_++]; - if (rotate_ && (current_index_ >= offset_list_size)) - { - current_index_ = 0; - } - return result; - } - - private: - - bool rotate_; - mutable std::size_t current_index_; - int offset_list_[offset_list_size + 1]; - }; - - inline offset_predicate<12> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const int& v7, const int& v8, const int& v9, - const int& v10, const int& v11, const int& v12, - const bool& rotate = false) - { - const int offset_list[12] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12 }; - return offset_predicate<12>(offset_list,rotate); - } - - inline offset_predicate<11> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const int& v7, const int& v8, const int& v9, - const int& v10, const int& v11, - const bool& rotate = false) - { - const int offset_list[11] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11 }; - return offset_predicate<11>(offset_list,rotate); - } - - inline offset_predicate<10> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const int& v7, const int& v8, const int& v9, - const int& v10, const bool& rotate = false) - { - const int offset_list[10] = { v1, v2, v3, v4, v5, v6, v7, v8, v9, v10 }; - return offset_predicate<10>(offset_list,rotate); - } - - inline offset_predicate<9> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const int& v7, const int& v8, const int& v9, - const bool& rotate = false) - { - const int offset_list[9] = { v1, v2, v3, v4, v5, v6, v7, v8, v9 }; - return offset_predicate<9>(offset_list,rotate); - } - - inline offset_predicate<8> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const int& v7, const int& v8, const bool& rotate = false) - { - const int offset_list[8] = { v1, v2, v3, v4, v5, v6, v7, v8 }; - return offset_predicate<8>(offset_list,rotate); - } - - inline offset_predicate<7> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const int& v7, const bool& rotate = false) - { - const int offset_list[7] = { v1, v2, v3, v4, v5, v6, v7 }; - return offset_predicate<7>(offset_list,rotate); - } - - inline offset_predicate<6> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const int& v6, - const bool& rotate = false) - { - const int offset_list[6] = { v1, v2, v3, v4, v5, v6 }; - return offset_predicate<6>(offset_list,rotate); - } - - inline offset_predicate<5> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const int& v5, const bool& rotate = false) - { - const int offset_list[5] = { v1, v2, v3, v4, v5 }; - return offset_predicate<5>(offset_list,rotate); - } - - inline offset_predicate<4> offsets(const int& v1, const int& v2, const int& v3, - const int& v4, const bool& rotate = false) - { - const int offset_list[4] = { v1, v2, v3, v4 }; - return offset_predicate<4>(offset_list,rotate); - } - - inline offset_predicate<3> offsets(const int& v1, const int& v2, const int& v3, - const bool& rotate = false) - { - const int offset_list[3] = { v1, v2, v3 }; - return offset_predicate<3>(offset_list,rotate); - } - - inline offset_predicate<2> offsets(const int& v1, const int& v2, const bool& rotate = false) - { - const int offset_list[2] = { v1, v2 }; - return offset_predicate<2>(offset_list,rotate); - } - - inline offset_predicate<1> offsets(const int& v1, - const bool& rotate = false) - { - const int offset_list[1] = { v1 }; - return offset_predicate<1>(offset_list,rotate); - } - - template - inline std::size_t offset_splitter(const InputIterator begin, - const InputIterator end, - const OffsetPredicate& offset, - OutputIterator out) - { - std::size_t length = 0; - if (0 == (length = std::distance(begin,end))) return 0; - std::pair range(begin,begin); - std::size_t match_count = 0; - int offset_length = 0; - std::size_t increment_amount = 0; - while ((end != range.second) && (0 < (offset_length = offset.next()))) - { - increment_amount = std::min(length,offset_length); - range.first = range.second; - range.second += increment_amount; - length -= increment_amount; - (*out) = range; - ++out; - ++match_count; - } - return match_count; - } - - template - inline std::size_t offset_splitter(const std::string& str, - const OffsetPredicate& offset, - OutputIterator out) - { - return offset_splitter(str.data(),str.data() + str.size(),offset,out); - } - - template - inline bool split_pair(const InputIterator begin, - const InputIterator end, - const Predicate& delimiter, - OutputPair& v1, - OutputPair& v2) - { - if (0 == std::distance(begin,end)) return false; - - InputIterator itr = begin; - - while (end != itr) - { - if (delimiter(*itr)) - { - v1 = std::make_pair(begin,itr); - ++itr; - if (0 != std::distance(itr,end)) - { - v2 = std::make_pair(itr,end); - return true; - } - else - return false; - } - else - ++itr; - } - - return false; - } - - inline bool split_pair(const std::string::value_type delimiter, - const std::string& str, - std::pair& v1, - std::pair& v2) - { - return split_pair(str.data(), - str.data() + str.size(), - single_delimiter_predicate(delimiter), - v1, - v2); - } - - template - inline bool split_pair(const DelimiterPredicate& delimiter, - const std::string& str, - std::pair& v1, - std::pair& v2) - { - return split_pair(str.data(), - str.data() + str.size(), - delimiter, - v1, - v2); - } - - template - inline std::size_t for_each_token(const std::string& buffer, - const std::string& delimiters, - Function function) - { - return split(delimiters, - buffer, - strtk::functional_inserter(function)); - } - - template - inline std::size_t for_each_token(const std::string& buffer, - const char* delimiters, - Function function) - { - return split(delimiters, - buffer, - strtk::functional_inserter(function)); - } - - template - inline std::size_t count_consecutive_duplicates(const InputIterator begin, const InputIterator end) - { - if (std::distance(begin,end) < 2) return 0; - InputIterator prev = begin; - InputIterator itr = begin; - std::size_t count = 0; - while (end != ++itr) - { - if ((*prev) == (*itr)) - ++count; - else - prev = itr; - } - return count; - } - - template class Sequence> - inline T min_of_cont(const Sequence& sequence) - { - return (*std::min_element(sequence.begin(),sequence.end())); - } - - template - inline T min_of_cont(const std::set& set) - { - return (*set.begin()); - } - - template - inline T min_of_cont(const std::multiset& multiset) - { - return (*multiset.begin()); - } - - template class Sequence> - inline T max_of_cont(const Sequence& sequence) - { - return (*std::max_element(sequence.begin(),sequence.end())); - } - - template - inline T max_of_cont(const std::set& set) - { - return (*set.rbegin()); - } - - template - inline T max_of_cont(const std::multiset& multiset) - { - return (*multiset.rbegin()); - } - - template - inline void min_max_of_range(const InputIterator begin, const InputIterator end, - typename std::iterator_traits::value_type& min_value, - typename std::iterator_traits::value_type& max_value) - { - min_value = *begin; - max_value = *begin; - InputIterator itr = begin; - while (end != ++itr) - { - if (*itr < min_value) - min_value = (*itr); - else if (*itr > max_value) - max_value = (*itr); - } - } - - template class Sequence> - inline void min_max_of_cont(const Sequence& sequence, - T& min_value, - T& max_value) - { - min_max_of_range(sequence.begin(),sequence.end(), - min_value, - max_value); - } - - template - inline void min_max_of_cont(const std::set& set, - T& min_value, - T& max_value) - { - min_value = (*set.begin()); - max_value = (*set.rbegin()); - } - - template - inline void min_max_of_cont(const std::multiset& multiset, - T& min_value, - T& max_value) - { - min_value = (*multiset.begin()); - max_value = (*multiset.rbegin()); - } - - template - inline void lexicographically_canonicalize(Iterator begin, Iterator end) - { - typedef typename std::iterator_traits::value_type type; - typedef typename std::pair iter_type; - typedef typename std::list itr_list_type; - itr_list_type itr_list; - - type smallest = (*std::min_element(begin,end)); - - for (Iterator itr = begin; itr != end; ++itr) - { - if (*itr == smallest) itr_list.push_back(std::make_pair(itr,itr)); - } - - while (itr_list.size() > 1) - { - typename itr_list_type::iterator itr = itr_list.begin(); - while (itr_list.end() != itr) - { - ++(*itr).first; - if (end == (*itr).first) - itr = itr_list.erase(itr); - else - ++itr; - } - - smallest = *(*itr_list.begin()).first; - - for (itr = (++itr_list.begin()); itr != itr_list.end(); ++itr) - { - if (*(*itr).first < smallest) - { - smallest = *(*itr).first; - } - } - - itr = itr_list.begin(); - while (itr_list.end() != itr) - { - if (*(*itr).first != smallest) - itr = itr_list.erase(itr); - else - ++itr; - } - - itr = itr_list.begin(); - while (itr_list.end() != itr) - { - if (end == (*itr).first) - itr = itr_list.erase(itr); - else - ++itr; - } - - } - - std::rotate(begin,(*itr_list.begin()).second,end); - } - - inline void lexicographically_canonicalize(std::string& str) - { - lexicographically_canonicalize(const_cast(str.data()), - const_cast(str.data() + str.size())); - } - - template class Sequence> - inline void lexicographically_canonicalize(Sequence& sequence) - { - lexicographically_canonicalize(sequence.begin(),sequence.end()); - } - - inline const char* first_non_repeated_char(const char* begin, const char* end) - { - static const std::size_t lut_size = 256; - unsigned long long int lut[lut_size]; - - std::fill_n(lut,lut_size,std::numeric_limits::max()); - - static const unsigned long long int not_yet_encountered = std::numeric_limits::max(); - static const unsigned long long int repeated = not_yet_encountered - 1; - - const char* itr = begin; - unsigned long long int position = 0; - while (end != itr) - { - unsigned long long int& element = lut[static_cast(*itr)]; - if (not_yet_encountered == element) - { - element = position; - } - else if (element < repeated) - { - element = repeated; - } - ++itr; - ++position; - } - - position = repeated; - - for (std::size_t i = 0; i < lut_size; ++i) - { - if (lut[i] < position) - position = lut[i]; - } - - return (repeated != position) ? (begin + position) : end; - } - - inline const unsigned char* first_non_repeated_char(const unsigned char* begin, const unsigned char* end) - { - char * b = reinterpret_cast(const_cast(begin)); - char * e = reinterpret_cast(const_cast(end)); - return const_cast(reinterpret_cast(const_cast(first_non_repeated_char(b,e)))); - } - - inline std::size_t first_non_repeated_char(const std::string& str) - { - if (str.empty()) - return static_cast(std::string::npos); - const char* itr = first_non_repeated_char(str.data(),str.data() + str.size()); - if ((str.data() + str.size()) != itr) - return static_cast(itr - str.data()); - else - return static_cast(std::string::npos); - } - - inline void convert_bin_to_hex(const unsigned char* begin, const unsigned char* end, unsigned char* out) - { - static const unsigned short hex_lut[] = - { - 0x3030, 0x3130, 0x3230, 0x3330, 0x3430, 0x3530, 0x3630, 0x3730, - 0x3830, 0x3930, 0x4130, 0x4230, 0x4330, 0x4430, 0x4530, 0x4630, - 0x3031, 0x3131, 0x3231, 0x3331, 0x3431, 0x3531, 0x3631, 0x3731, - 0x3831, 0x3931, 0x4131, 0x4231, 0x4331, 0x4431, 0x4531, 0x4631, - 0x3032, 0x3132, 0x3232, 0x3332, 0x3432, 0x3532, 0x3632, 0x3732, - 0x3832, 0x3932, 0x4132, 0x4232, 0x4332, 0x4432, 0x4532, 0x4632, - 0x3033, 0x3133, 0x3233, 0x3333, 0x3433, 0x3533, 0x3633, 0x3733, - 0x3833, 0x3933, 0x4133, 0x4233, 0x4333, 0x4433, 0x4533, 0x4633, - 0x3034, 0x3134, 0x3234, 0x3334, 0x3434, 0x3534, 0x3634, 0x3734, - 0x3834, 0x3934, 0x4134, 0x4234, 0x4334, 0x4434, 0x4534, 0x4634, - 0x3035, 0x3135, 0x3235, 0x3335, 0x3435, 0x3535, 0x3635, 0x3735, - 0x3835, 0x3935, 0x4135, 0x4235, 0x4335, 0x4435, 0x4535, 0x4635, - 0x3036, 0x3136, 0x3236, 0x3336, 0x3436, 0x3536, 0x3636, 0x3736, - 0x3836, 0x3936, 0x4136, 0x4236, 0x4336, 0x4436, 0x4536, 0x4636, - 0x3037, 0x3137, 0x3237, 0x3337, 0x3437, 0x3537, 0x3637, 0x3737, - 0x3837, 0x3937, 0x4137, 0x4237, 0x4337, 0x4437, 0x4537, 0x4637, - 0x3038, 0x3138, 0x3238, 0x3338, 0x3438, 0x3538, 0x3638, 0x3738, - 0x3838, 0x3938, 0x4138, 0x4238, 0x4338, 0x4438, 0x4538, 0x4638, - 0x3039, 0x3139, 0x3239, 0x3339, 0x3439, 0x3539, 0x3639, 0x3739, - 0x3839, 0x3939, 0x4139, 0x4239, 0x4339, 0x4439, 0x4539, 0x4639, - 0x3041, 0x3141, 0x3241, 0x3341, 0x3441, 0x3541, 0x3641, 0x3741, - 0x3841, 0x3941, 0x4141, 0x4241, 0x4341, 0x4441, 0x4541, 0x4641, - 0x3042, 0x3142, 0x3242, 0x3342, 0x3442, 0x3542, 0x3642, 0x3742, - 0x3842, 0x3942, 0x4142, 0x4242, 0x4342, 0x4442, 0x4542, 0x4642, - 0x3043, 0x3143, 0x3243, 0x3343, 0x3443, 0x3543, 0x3643, 0x3743, - 0x3843, 0x3943, 0x4143, 0x4243, 0x4343, 0x4443, 0x4543, 0x4643, - 0x3044, 0x3144, 0x3244, 0x3344, 0x3444, 0x3544, 0x3644, 0x3744, - 0x3844, 0x3944, 0x4144, 0x4244, 0x4344, 0x4444, 0x4544, 0x4644, - 0x3045, 0x3145, 0x3245, 0x3345, 0x3445, 0x3545, 0x3645, 0x3745, - 0x3845, 0x3945, 0x4145, 0x4245, 0x4345, 0x4445, 0x4545, 0x4645, - 0x3046, 0x3146, 0x3246, 0x3346, 0x3446, 0x3546, 0x3646, 0x3746, - 0x3846, 0x3946, 0x4146, 0x4246, 0x4346, 0x4446, 0x4546, 0x4646 - }; - - for (const unsigned char* itr = begin; end != itr; ++itr) - { - *reinterpret_cast(out) = hex_lut[(*itr)]; - out += sizeof(unsigned short); - } - } - - inline void convert_bin_to_hex(const char* begin, const char* end, char* out) - { - convert_bin_to_hex(reinterpret_cast(begin), - reinterpret_cast(end), - reinterpret_cast(out)); - } - - inline void convert_bin_to_hex(const std::pair& r, unsigned char* out) - { - convert_bin_to_hex(r.first,r.second,out); - } - - inline void convert_bin_to_hex(const std::pair& r, unsigned char* out) - { - convert_bin_to_hex(r.first,r.second,out); - } - - inline void convert_bin_to_hex(const std::pair& r, char* out) - { - convert_bin_to_hex(r.first,r.second,out); - } - - inline void convert_bin_to_hex(const std::string& binary_data, std::string& output) - { - output.resize(binary_data.size() * 2); - convert_bin_to_hex(binary_data.data(), - binary_data.data() + binary_data.size(), - const_cast(output.data())); - } - - inline std::string convert_bin_to_hex(const std::string& binary_data) - { - std::string output; - convert_bin_to_hex(binary_data,output); - return output; - } - - inline bool convert_hex_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out) - { - const std::size_t length = std::distance(begin,end); - if (0 == length) - return false; - else if (1 == (length % 2)) - return false; - static const unsigned char hex_to_bin[] = - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 - 0x07 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 - 0x0F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 - 0x17 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 - 0x1F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 - 0x27 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 - 0x2F - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37 - 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 - 0x3F - 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x40 - 0x47 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 - 0x4F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 - 0x57 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 - 0x5F - 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00, // 0x60 - 0x67 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 - 0x6F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 - 0x77 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 - 0x7F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 - 0x87 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 - 0x8F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 - 0x97 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 - 0x9F - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 - 0xA7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 - 0xAF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 - 0xB7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 - 0xBF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 - 0xC7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 - 0xCF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 - 0xD7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 - 0xDF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 - 0xE7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 - 0xEF - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 - 0xF7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0xF8 - 0xFF - }; - - const unsigned char* itr = begin; - while (end != itr) - { - *reinterpret_cast(out) = static_cast(hex_to_bin[itr[0]] << 4 | hex_to_bin[itr[1]]); - ++out; - itr += 2; - } - return true; - } - - inline bool convert_hex_to_bin(const char* begin, const char* end, char* out) - { - return convert_hex_to_bin(reinterpret_cast(begin), - reinterpret_cast(end), - reinterpret_cast(out)); - } - - inline bool convert_hex_to_bin(const std::pair& r, unsigned char* out) - { - return convert_hex_to_bin(r.first,r.second,out); - } - - inline bool convert_hex_to_bin(const std::pair& r, unsigned char* out) - { - return convert_hex_to_bin(r.first,r.second,out); - } - - inline bool convert_hex_to_bin(const std::pair& r, char* out) - { - return convert_hex_to_bin(r.first,r.second,out); - } - - inline bool convert_hex_to_bin(const std::pair& r, char* out) - { - return convert_hex_to_bin(r.first,r.second,out); - } - - inline bool convert_hex_to_bin(const std::string& hex_data, std::string& output) - { - if (hex_data.empty() || (1 == (hex_data.size() % 2))) - return false; - output.resize(hex_data.size() >> 1); - return convert_hex_to_bin(hex_data.data(), - hex_data.data() + hex_data.size(), - const_cast(output.data())); - } - - inline std::size_t convert_bin_to_base64(const unsigned char* begin, const unsigned char* end, unsigned char* out) - { - static const unsigned char bin_to_base64 [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - - const std::size_t length = std::distance(begin,end); - std::size_t rounds = length / 3; - const unsigned char* itr = begin; - for (std::size_t i = 0; i < rounds; ++i) - { - unsigned int block = *(itr++) << 16; - block |= *(itr++) << 8; - block |= *(itr++) ; - *(out++) = bin_to_base64[( block >> 18 ) & 0x3F]; - *(out++) = bin_to_base64[( block >> 12 ) & 0x3F]; - *(out++) = bin_to_base64[( block >> 6 ) & 0x3F]; - *(out++) = bin_to_base64[( block ) & 0x3F]; - } - - if ((rounds = (length % 3)) > 0) - { - switch (rounds) - { - case 1 : { - unsigned int block = (unsigned char) (*itr) << 16; - *(out++) = bin_to_base64[( block >> 18 ) & 0x3F]; - *(out++) = bin_to_base64[( block >> 12 ) & 0x3F]; - *(out++) = '='; - *(out++) = '='; - } - break; - - case 2 : { - unsigned int block = *(itr++) << 16; - block |= *(itr++) << 8; - *(out++) = bin_to_base64[( block >> 18 ) & 0x3F]; - *(out++) = bin_to_base64[( block >> 12 ) & 0x3F]; - *(out++) = bin_to_base64[( block >> 6 ) & 0x3F]; - *(out++) = '='; - } - break; - } - } - return static_cast((length / 3) * 4) + ((length % 3) > 0 ? 4 : 0); - } - - inline std::size_t convert_bin_to_base64(const char* begin, const char* end, char* out) - { - return convert_bin_to_base64(reinterpret_cast(begin), - reinterpret_cast(end), - reinterpret_cast(out)); - } - - inline void convert_bin_to_base64(const std::string& binary_data, std::string& output) - { - output.resize(std::max(4,binary_data.size() << 1)); - std::size_t resize = convert_bin_to_base64(binary_data.data(), - binary_data.data() + binary_data.size(), - const_cast(output.data())); - output.resize(resize); - } - - inline std::size_t convert_base64_to_bin(const unsigned char* begin, const unsigned char* end, unsigned char* out) - { - static const unsigned char base64_to_bin[] = - { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x00 - 0x07 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27 - 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, // 0x28 - 0x2F - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 - 0x37 - 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F - 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 - 0x47 - 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 - 0x4F - 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 - 0x57 - 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F - 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 - 0x67 - 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 - 0x6F - 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 - 0x77 - 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF - }; - - const unsigned char* end_itr = end; - - if ('=' == *(end - 2)) - end_itr = end - 2; - else if ('=' == *(end - 1)) - end_itr = end - 1; - - const std::size_t length = std::distance(begin,end_itr); - const std::size_t rounds = length / 4; - const unsigned char* itr = begin; - - for (std::size_t i = 0; i < rounds; ++i) - { - unsigned int block = base64_to_bin[*(itr++)] << 18; - block |= base64_to_bin[*(itr++)] << 12; - block |= base64_to_bin[*(itr++)] << 6; - block |= base64_to_bin[*(itr++)]; - - *(out++) = static_cast(( block >> 16 ) & 0xFF); - *(out++) = static_cast(( block >> 8 ) & 0xFF); - *(out++) = static_cast(( block ) & 0xFF); - } - - const std::size_t remainder = (length % 4); - if (remainder > 0) - { - switch (remainder) - { - case 2 : { - unsigned int block = base64_to_bin[*(itr++)] << 18; - block |= base64_to_bin[*(itr++)] << 12; - (*out) = static_cast(( block >> 16 ) & 0xFF); - } - break; - - case 3 : { - unsigned int block = base64_to_bin[*(itr++)] << 18; - block |= base64_to_bin[*(itr++)] << 12; - block |= base64_to_bin[*(itr++)] << 6; - *(out++) = static_cast(( block >> 16 ) & 0xFF); - *(out ) = static_cast(( block >> 8 ) & 0xFF); - } - break; - } - } - - return static_cast((3 * length) / 4); - } - - inline std::size_t convert_base64_to_bin(const char* begin, const char* end, char* out) - { - return convert_base64_to_bin(reinterpret_cast(begin), - reinterpret_cast(end), - reinterpret_cast(out)); - } - - inline void convert_base64_to_bin(const std::string& binary_data, std::string& output) - { - output.resize(binary_data.size()); - std::size_t resize = convert_base64_to_bin(binary_data.data(), - binary_data.data() + binary_data.size(), - const_cast(output.data())); - output.resize(resize); - } - - inline void convert_to_printable_chars(unsigned char* begin, unsigned char* end) - { - static const unsigned char printable_char_table[] = - { - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x00 - 0x07 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x08 - 0x0F - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x10 - 0x17 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x18 - 0x1F - 0x2E, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, // 0x20 - 0x27 - 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x28 - 0x2F - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x30 - 0x37 - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x38 - 0x3F - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, // 0x40 - 0x47 - 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x48 - 0x4F - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, // 0x50 - 0x57 - 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, // 0x58 - 0x5F - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, // 0x60 - 0x67 - 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x68 - 0x6F - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, // 0x70 - 0x77 - 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x2E, // 0x78 - 0x7F - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x80 - 0x87 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x88 - 0x8F - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x90 - 0x97 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0x98 - 0x9F - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA0 - 0xA7 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xA8 - 0xAF - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB0 - 0xB7 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xB8 - 0xBF - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC0 - 0xC7 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xC8 - 0xCF - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD0 - 0xD7 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xD8 - 0xDF - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE0 - 0xE7 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xE8 - 0xEF - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, // 0xF0 - 0xF7 - 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E // 0xF8 - 0xFF - }; - unsigned char* itr = begin; - while (end != itr) - { - (*itr) = printable_char_table[static_cast((*itr))]; - ++itr; - } - } - - inline void convert_to_printable_chars(char* begin, char* end) - { - convert_to_printable_chars(reinterpret_cast(begin), - reinterpret_cast(end)); - } - - inline void convert_to_printable_chars(std::string& str) - { - convert_to_printable_chars(reinterpret_cast(const_cast(str.data())), - reinterpret_cast(const_cast(str.data() + str.size()))); - } - - inline void convert_to_uppercase(unsigned char* begin, unsigned char* end) - { - std::transform(begin,end,begin,::toupper); - /* - unsigned char* itr = begin; - while (end != itr) - { - //(*itr) = std::toupper((*itr), std::locale::classic()); - (*itr) = static_cast(::toupper(static_cast(*itr))); - ++itr; - } - */ - } - - inline void convert_to_uppercase(char* begin, char* end) - { - convert_to_uppercase(reinterpret_cast(begin), - reinterpret_cast(end)); - } - - inline void convert_to_uppercase(std::string& str) - { - convert_to_uppercase(reinterpret_cast(const_cast(str.data())), - reinterpret_cast(const_cast(str.data() + str.size()))); - } - - inline void convert_to_lowercase(unsigned char* begin, unsigned char* end) - { - std::transform(begin,end,begin,::tolower); - /* - unsigned char* itr = begin; - while (end != itr) - { - //(*itr) = std::tolower((*itr), std::locale::classic()); - (*itr) = static_cast(::tolower(static_cast(*itr))); - ++itr; - } - */ - } - - inline void convert_to_lowercase(char* begin, char* end) - { - convert_to_lowercase(reinterpret_cast(begin), - reinterpret_cast(end)); - } - - inline void convert_to_lowercase(const char* begin, const char* end) - { - convert_to_lowercase(const_cast(begin),const_cast(end)); - } - - inline void convert_to_lowercase(std::string& str) - { - convert_to_lowercase(reinterpret_cast(const_cast(str.data())), - reinterpret_cast(const_cast(str.data() + str.size()))); - } - - inline std::string as_lowercase(const std::string& str) - { - std::string result = str; - convert_to_lowercase(result); - return result; - } - - inline std::string as_uppercase(const std::string& str) - { - std::string result = str; - convert_to_uppercase(result); - return result; - } - - inline bool twoway_bitwise_interleave(const unsigned char* begin1, const unsigned char* end1, - const unsigned char* begin2, const unsigned char* end2, - unsigned char* out) - { - if (std::distance(begin1,end1) != std::distance(begin2,end2)) - { - return false; - } - - static const std::size_t interleave_table_size = 256; - static const unsigned short interleave_table[interleave_table_size] = - { - 0x0000, 0x0001, 0x0004, 0x0005, 0x0010, 0x0011, 0x0014, 0x0015, // 0x00 - 0x07 - 0x0040, 0x0041, 0x0044, 0x0045, 0x0050, 0x0051, 0x0054, 0x0055, // 0x08 - 0x0F - 0x0100, 0x0101, 0x0104, 0x0105, 0x0110, 0x0111, 0x0114, 0x0115, // 0x10 - 0x17 - 0x0140, 0x0141, 0x0144, 0x0145, 0x0150, 0x0151, 0x0154, 0x0155, // 0x18 - 0x1F - 0x0400, 0x0401, 0x0404, 0x0405, 0x0410, 0x0411, 0x0414, 0x0415, // 0x20 - 0x27 - 0x0440, 0x0441, 0x0444, 0x0445, 0x0450, 0x0451, 0x0454, 0x0455, // 0x28 - 0x2F - 0x0500, 0x0501, 0x0504, 0x0505, 0x0510, 0x0511, 0x0514, 0x0515, // 0x30 - 0x37 - 0x0540, 0x0541, 0x0544, 0x0545, 0x0550, 0x0551, 0x0554, 0x0555, // 0x38 - 0x3F - 0x1000, 0x1001, 0x1004, 0x1005, 0x1010, 0x1011, 0x1014, 0x1015, // 0x40 - 0x47 - 0x1040, 0x1041, 0x1044, 0x1045, 0x1050, 0x1051, 0x1054, 0x1055, // 0x48 - 0x4F - 0x1100, 0x1101, 0x1104, 0x1105, 0x1110, 0x1111, 0x1114, 0x1115, // 0x50 - 0x57 - 0x1140, 0x1141, 0x1144, 0x1145, 0x1150, 0x1151, 0x1154, 0x1155, // 0x58 - 0x5F - 0x1400, 0x1401, 0x1404, 0x1405, 0x1410, 0x1411, 0x1414, 0x1415, // 0x60 - 0x67 - 0x1440, 0x1441, 0x1444, 0x1445, 0x1450, 0x1451, 0x1454, 0x1455, // 0x68 - 0x6F - 0x1500, 0x1501, 0x1504, 0x1505, 0x1510, 0x1511, 0x1514, 0x1515, // 0x70 - 0x77 - 0x1540, 0x1541, 0x1544, 0x1545, 0x1550, 0x1551, 0x1554, 0x1555, // 0x78 - 0x7F - 0x4000, 0x4001, 0x4004, 0x4005, 0x4010, 0x4011, 0x4014, 0x4015, // 0x80 - 0x87 - 0x4040, 0x4041, 0x4044, 0x4045, 0x4050, 0x4051, 0x4054, 0x4055, // 0x88 - 0x8F - 0x4100, 0x4101, 0x4104, 0x4105, 0x4110, 0x4111, 0x4114, 0x4115, // 0x90 - 0x97 - 0x4140, 0x4141, 0x4144, 0x4145, 0x4150, 0x4151, 0x4154, 0x4155, // 0x98 - 0x9F - 0x4400, 0x4401, 0x4404, 0x4405, 0x4410, 0x4411, 0x4414, 0x4415, // 0xA0 - 0xA7 - 0x4440, 0x4441, 0x4444, 0x4445, 0x4450, 0x4451, 0x4454, 0x4455, // 0xA8 - 0xAF - 0x4500, 0x4501, 0x4504, 0x4505, 0x4510, 0x4511, 0x4514, 0x4515, // 0xB0 - 0xB7 - 0x4540, 0x4541, 0x4544, 0x4545, 0x4550, 0x4551, 0x4554, 0x4555, // 0xB8 - 0xBF - 0x5000, 0x5001, 0x5004, 0x5005, 0x5010, 0x5011, 0x5014, 0x5015, // 0xC0 - 0xC7 - 0x5040, 0x5041, 0x5044, 0x5045, 0x5050, 0x5051, 0x5054, 0x5055, // 0xC8 - 0xCF - 0x5100, 0x5101, 0x5104, 0x5105, 0x5110, 0x5111, 0x5114, 0x5115, // 0xD0 - 0xD7 - 0x5140, 0x5141, 0x5144, 0x5145, 0x5150, 0x5151, 0x5154, 0x5155, // 0xD8 - 0xDF - 0x5400, 0x5401, 0x5404, 0x5405, 0x5410, 0x5411, 0x5414, 0x5415, // 0xE0 - 0xE7 - 0x5440, 0x5441, 0x5444, 0x5445, 0x5450, 0x5451, 0x5454, 0x5455, // 0xE8 - 0xEF - 0x5500, 0x5501, 0x5504, 0x5505, 0x5510, 0x5511, 0x5514, 0x5515, // 0xF0 - 0xF7 - 0x5540, 0x5541, 0x5544, 0x5545, 0x5550, 0x5551, 0x5554, 0x5555 // 0xF8 - 0xFF - }; - - const unsigned char* itr1 = begin1; - const unsigned char* itr2 = begin2; - while (end1 != itr1) - { - *(reinterpret_cast(out)) = (interleave_table[*(itr2++)] << 1); - *(reinterpret_cast(out)) |= interleave_table[*(itr1++)]; - out += 2; - } - return true; - } - - inline bool twoway_bitwise_interleave(const char* begin1, const char* end1, - const char* begin2, const char* end2, - char* out) - { - return twoway_bitwise_interleave(reinterpret_cast(begin1), - reinterpret_cast(end1), - reinterpret_cast(begin2), - reinterpret_cast(end2), - reinterpret_cast(out)); - } - - inline bool twoway_bitwise_interleave(const std::string& str1, - const std::string& str2, - std::string& out) - { - if (str1.size() != str2.size()) - { - return false; - } - out.resize(str1.size()); - return twoway_bitwise_interleave(str1.data(),str1.data() + str1.size(), - str2.data(),str2.data() + str2.size(), - const_cast(out.data())); - } - - template - struct interleave_ary; - - template<> struct interleave_ary { typedef unsigned short type; }; - template<> struct interleave_ary { typedef unsigned int type; }; - template<> struct interleave_ary { typedef unsigned long long int type; }; - - template - inline void create_nway_interleave_table(typename interleave_ary::type table[256]) - { - typedef typename interleave_ary::type type; - const type diff = static_cast(n - 1); - for (type i = static_cast(0); i < static_cast(256); ++i) - { - table[i] = 0x00; - for (type j = static_cast(0); j < static_cast(8); ++j) - { - table[i] |= (i & (1 << j)) << (j * diff); - } - } - } - - namespace bitwise_operation { enum type { eAND, eOR, eXOR }; } - - inline void bitwise_transform(const bitwise_operation::type& operation, - const unsigned char* begin1, const unsigned char* end1, - const unsigned char* begin2, - unsigned char* out) - { - const unsigned char* itr1 = begin1; - const unsigned char* itr2 = begin2; - - switch (operation) - { - case bitwise_operation::eAND : while (itr1 != end1) { *(out++) = *(itr1++) & *(itr2++); } return; - case bitwise_operation::eOR : while (itr1 != end1) { *(out++) = *(itr1++) | *(itr2++); } return; - case bitwise_operation::eXOR : while (itr1 != end1) { *(out++) = *(itr1++) ^ *(itr2++); } return; - } - } - - inline void bitwise_transform(const bitwise_operation::type& operation, - const char* begin1, const char* end1, - const char* begin2, - char* out) - { - bitwise_transform(operation, - reinterpret_cast(begin1), - reinterpret_cast(end1), - reinterpret_cast(begin2), - reinterpret_cast(out)); - } - - inline void bitwise_transform(const bitwise_operation::type& operation, - const std::string& str1, - const std::string& str2, - std::string& out) - { - if (str1.size() != str2.size()) return; - out.resize(str1.size()); - bitwise_transform(operation, - str1.data(),str1.data() + str1.size(), - str2.data(), - const_cast(out.data())); - } - - inline std::size_t high_bit_count(const unsigned char c) - { - static const std::size_t high_bits_in_char[256] = - { - 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7, - 4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8 - }; - return high_bits_in_char[c]; - } - - inline std::size_t high_bit_count(const unsigned short& s) - { - const unsigned char* ptr = reinterpret_cast(&s); - return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)); - } - - inline std::size_t high_bit_count(const unsigned int& i) - { - const unsigned char* ptr = reinterpret_cast(&i); - return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) + - high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3)); - } - - inline std::size_t high_bit_count(const long long int& ll) - { - const unsigned char* ptr = reinterpret_cast(&ll); - return high_bit_count(*(ptr + 0)) + high_bit_count(*(ptr + 1)) + - high_bit_count(*(ptr + 2)) + high_bit_count(*(ptr + 3)) + - high_bit_count(*(ptr + 4)) + high_bit_count(*(ptr + 5)) + - high_bit_count(*(ptr + 6)) + high_bit_count(*(ptr + 7)); - } - - inline std::size_t high_bit_count(const unsigned char* begin, const unsigned char* end) - { - std::size_t count = 0; - const unsigned char* itr = begin; - while (end != itr) - { - count += high_bit_count(*itr++); - } - return count; - } - - inline std::size_t high_bit_count(const char* begin, const char* end) - { - return high_bit_count(reinterpret_cast(begin), - reinterpret_cast(end)); - - } - - inline std::size_t high_bit_count(const std::string& str) - { - return high_bit_count(str.data(),str.data() + str.size()); - } - - inline bool bit_state(const std::size_t& index, const unsigned char* ptr) - { - static const unsigned char bit_mask[] = - { - 0x01, //00000001 - 0x02, //00000010 - 0x04, //00000100 - 0x08, //00001000 - 0x10, //00010000 - 0x20, //00100000 - 0x40, //01000000 - 0x80 //10000000 - }; - return (0 != (ptr[(index >> 3)] & bit_mask[index & 7])); - } - - inline void set_bit_high(const std::size_t& index, unsigned char* const ptr) - { - static const unsigned char bit_mask[] = - { - 0x01, //00000001 - 0x02, //00000010 - 0x04, //00000100 - 0x08, //00001000 - 0x10, //00010000 - 0x20, //00100000 - 0x40, //01000000 - 0x80 //10000000 - }; - ptr[(index >> 3)] |= bit_mask[index & 7]; - } - - inline void set_bit_low(const std::size_t& index, unsigned char* const ptr) - { - static const unsigned char bit_mask[] = - { - 0xFE, //11111110 - 0xFD, //11111101 - 0xFB, //11111011 - 0xF7, //11110111 - 0xEF, //11101111 - 0xDF, //11011111 - 0xBF, //10111111 - 0x7F //01111111 - }; - ptr[(index >> 3)] &= bit_mask[index & 7]; - } - - inline std::size_t hamming_distance(const unsigned char* begin1, const unsigned char* end1, - const unsigned char* begin2, const unsigned char* end2) - { - if (std::distance(begin1,end1) != std::distance(begin2,end2)) - { - return std::numeric_limits::max(); - } - - std::size_t distance = 0; - const unsigned char* itr1 = begin1; - const unsigned char* itr2 = begin2; - - while (end1 != itr1) - { - distance += high_bit_count(static_cast(((*itr1++) ^ (*itr2++)) & 0xFF)); - } - - return distance; - } - - inline std::size_t hamming_distance(const char* begin1, const char* end1, - const char* begin2, const char* end2) - { - return hamming_distance(reinterpret_cast(begin1), - reinterpret_cast(end1), - reinterpret_cast(begin2), - reinterpret_cast(end2)); - } - - inline std::size_t hamming_distance(const std::string& str1, const std::string& str2) - { - return hamming_distance(str1.data(), str1.data() + str1.size(), - str2.data(), str2.data() + str2.size()); - } - - template - inline std::size_t hamming_distance_elementwise(const Iterator begin1, const Iterator end1, - const Iterator begin2, const Iterator end2) - { - if (std::distance(begin1,end1) != std::distance(begin2,end2)) - { - return std::numeric_limits::max(); - } - - std::size_t distance = 0; - Iterator itr1 = begin1; - Iterator itr2 = begin2; - - while (end1 != itr1) - { - if ((*itr1) != (*itr2)) - ++distance; - } - - return distance; - } - - inline std::size_t hamming_distance_elementwise(const std::string& str1, const std::string& str2) - { - return hamming_distance_elementwise(str1.data(), str1.data() + str1.size(), - str2.data(), str2.data() + str2.size()); - } - - class token_grid - { - public: - - typedef const unsigned char* iterator_t; - typedef unsigned int index_t; - typedef std::pair range_t; - typedef std::deque token_list_t; - typedef std::pair row_index_range_t; - typedef std::deque row_index_t; - typedef std::pair row_range_t; - typedef std::pair col_range_t; - - private: - - struct store - { - store() - : max_column(0) - {} - - token_list_t token_list; - row_index_t row_index; - std::size_t max_column; - - inline void clear() - { - token_list.clear(); - row_index.clear(); - } - - inline range_t operator()(const std::size_t& col, const std::size_t& row) const - { - if (row < row_index.size()) - { - const row_index_range_t& r = row_index[row]; - if (col < (r.second - r.first + 1)) - return *(token_list.begin() + (r.first + col)); - else - return null_range(); - } - else - return null_range(); - } - - inline bool remove_row(const std::size_t& row) - { - if (row >= row_index.size()) return false; - row_index_range_t& r = row_index[row]; - std::size_t number_of_tokens = r.second - r.first + 1; - token_list_t::iterator remove_begin = token_list.begin() + r.first; - token_list_t::iterator remove_end = token_list.begin() + r.first + number_of_tokens; - token_list.erase(remove_begin,remove_end); - row_index.erase(row_index.begin() + row); - for (std::size_t i = row; i < row_index.size(); ++i) - { - row_index_range_t& r = row_index[i]; - r.first -= static_cast(number_of_tokens); - r.second -= static_cast(number_of_tokens); - } - return true; - } - - inline std::size_t token_count(const row_index_range_t& r) const - { - return (r.second - r.first + 1); - } - - inline std::size_t token_count(const std::size_t& index) const - { - return token_count(row_index[index]); - } - - inline bool remove_row_range(const std::size_t& r0, const std::size_t& r1) - { - if (r0 > r1) - return false; - else if (r0 >= row_index.size()) - return false; - else if (r1 >= row_index.size()) - return false; - std::size_t number_of_tokens = 0; - for (std::size_t i = r0; i <= r1; ++i) - { - row_index_range_t& r = row_index[i]; - number_of_tokens += token_count(r); - } - row_index_range_t rr0 = row_index[r0]; - token_list_t::iterator remove_begin = token_list.begin() + rr0.first; - token_list_t::iterator remove_end = token_list.begin() + rr0.first + number_of_tokens; - token_list.erase(remove_begin,remove_end); - row_index.erase(row_index.begin() + r0,row_index.begin() + r0 + (r1 - r0 + 1)); - for (std::size_t i = r0; i < row_index.size(); ++i) - { - row_index_range_t& r = row_index[i]; - r.first -= static_cast(number_of_tokens); - r.second -= static_cast(number_of_tokens); - } - return true; - } - - struct remove_column_impl - { - std::size_t column; - std::size_t counter; - std::size_t remainder; - std::size_t current_row; - - inline void update(store& idx) - { - current_row++; - while (current_row < idx.row_index.size()) - { - std::size_t number_of_tokens = idx.token_count(current_row); - if (number_of_tokens > column) - break; - counter += number_of_tokens; - ++current_row; - } - if (current_row < idx.row_index.size()) - { - counter += column + remainder; - row_index_range_t& r = idx.row_index[current_row]; - remainder = (r.second - r.first) - column; - } - else - counter = std::numeric_limits::max(); - } - - inline void process(store& idx) - { - token_list_t::iterator itr1 = idx.token_list.begin(); - token_list_t::iterator itr2 = idx.token_list.begin(); - token_list_t::iterator end = idx.token_list.end(); - counter = 0; - remainder = 0; - current_row = static_cast(-1); - update(idx); - while (end != itr1) - { - while ((end != itr1) && (0 != counter)) - { - if (itr1 != itr2) - { - (*itr2) = (*itr1); - } - ++itr1; - ++itr2; - --counter; - } - if (0 == counter) - { - update(idx); - ++itr1; - } - } - std::size_t remove_count = 0; - idx.max_column = std::numeric_limits::min(); - for (std::size_t i = 0; i < idx.row_index.size(); ++i) - { - row_index_range_t& r = idx.row_index[i]; - std::size_t token_count = (r.second - r.first + 1); - r.first -= static_cast(remove_count); - if (token_count > column) - { - ++remove_count; - } - r.second -= static_cast(remove_count); - token_count = (r.second - r.first + 1); - if (token_count > idx.max_column) - idx.max_column = token_count; - } - idx.token_list.resize(idx.token_list.size() - remove_count); - } - }; - - inline bool remove_column(const std::size_t& column) - { - if (column >= max_column) return false; - remove_column_impl rc; - rc.column = column; - rc.process(*this); - return true; - } - - inline static range_t null_range() - { - static const range_t null_range_ = range_t(reinterpret_cast(0), - reinterpret_cast(0)); - return null_range_; - } - - }; - - template - struct row_processor - { - row_processor(store& idx, - DelimiterPredicate& tp, - const split_options::type split_mode = split_options::compress_delimiters) - : idx_(idx), - row_start_index_(0), - row_end_index_(0), - token_predicate_(tp), - split_mode_(split_mode) - { - idx_.max_column = std::numeric_limits::min(); - } - - inline void operator()(const range_t& range) - { - if (0 == std::distance(range.first,range.second)) - return; - row_start_index_ = static_cast(idx_.token_list.size()); - std::size_t token_count = split(token_predicate_, - range.first,range.second, - std::back_inserter(idx_.token_list), - split_mode_); - row_end_index_ = row_start_index_ + token_count - 1; - idx_.row_index.push_back(std::make_pair(row_start_index_,row_end_index_)); - if (token_count > idx_.max_column) - idx_.max_column = token_count; - } - - row_processor operator=(const row_processor&); - - store& idx_; - index_t row_start_index_; - index_t row_end_index_; - DelimiterPredicate& token_predicate_; - split_options::type split_mode_; - }; - - public: - - inline row_range_t range(std::size_t lower_bound, - std::size_t upper_bound = std::numeric_limits::max()) const - { - if (upper_bound == std::numeric_limits::max()) - { - upper_bound = dsv_index_.token_list.size(); - } - else if (upper_bound > dsv_index_.token_list.size()) - { - return row_range_t(std::numeric_limits::max(),std::numeric_limits::max()); - } - else if (lower_bound > upper_bound) - { - return row_range_t(std::numeric_limits::max(),std::numeric_limits::max()); - } - return row_range_t(lower_bound,upper_bound); - } - - struct options - { - options() - : row_split_option(split_options::compress_delimiters), - column_split_option(split_options::compress_delimiters), - row_delimiters("\n\r"), - column_delimiters(",|;\t "), - support_dquotes(false), - trim_dquotes(false) - {} - - options(split_options::type sro, - split_options::type sco, - const std::string& rd, - const std::string& cd, - const bool support_dq = false, - const bool trim_dq = false) - : row_split_option(sro), - column_split_option(sco), - row_delimiters(rd), - column_delimiters(cd), - support_dquotes(support_dq), - trim_dquotes(trim_dq) - {} - - inline options& set_column_split_option(const split_options::type& option) - { - column_split_option = option; - return *this; - } - - inline options& set_row_split_option(const split_options::type& option) - { - row_split_option = option; - return *this; - } - - inline options& set_column_delimiters(const std::string& delimiters) - { - column_delimiters = delimiters; - return *this; - } - - inline options& set_row_delimiters(const std::string& delimiters) - { - row_delimiters = delimiters; - return *this; - } - - split_options::type row_split_option; - split_options::type column_split_option; - std::string row_delimiters; - std::string column_delimiters; - bool support_dquotes; - bool trim_dquotes; - }; - - class row_type - { - private: - - typedef std::pair row_pair_type; - - public: - - row_type() - : index_(std::numeric_limits::max()), - size_(0) - {} - - row_type(const std::size_t& index, - const store& dsv_index) - : index_(index), - size_ (dsv_index.token_count(index)), - begin_(dsv_index.token_list.begin() + dsv_index.row_index[index].first) - {} - - inline bool is_null(const std::size_t& index) const - { - const range_t& range = *(begin_ + index); - return (0 == std::distance(range.first,range.second)); - } - - template - inline T operator[](const std::size_t& index) const - { - const range_t& range = *(begin_ + index); - return string_to_type_converter(range.first,range.second); - } - - template - inline T get(const std::size_t& index) const - { - return operator[](index); - } - - inline col_range_t all_columns() const - { - return col_range_t(0,static_cast(size())); - } - - inline range_t range() const - { - return range_t((*begin_).first,(*(begin_ + (size_ - 1))).second); - } - - inline range_t token(const std::size_t& index) const - { - return *(begin_ + index); - } - - inline std::size_t index() const - { - return index_; - } - - inline std::size_t size() const - { - return size_; - } - - inline std::size_t raw_length() const - { - std::size_t result = 0; - token_list_t::const_iterator itr = begin_; - for (std::size_t i = 0; i < size_; ++i, ++itr) - { - const range_t& range = (*itr); - result += std::distance(range.first,range.second); - } - return result; - } - - inline std::size_t raw_length(const std::size_t& column_index) const - { - const range_t& range = *(begin_ + column_index); - return std::distance(range.first,range.second); - } - - inline std::string as_string() const - { - std::string result; - result.reserve(std::distance(begin_->first,(begin_ + (size_ - 1))->second)); - token_list_t::const_iterator itr = begin_; - for (std::size_t i = 0; i < size_; ++i, ++itr) - { - const range_t& range = (*itr); - result.append(range.first,range.second); - } - return result; - } - - inline void as_string(std::string& out) const - { - out = as_string(); - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - const std::size_t& col4, const std::size_t& col5, - const std::size_t& col6, const std::size_t& col7, - const std::size_t& col8, const std::size_t& col9, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - if (!process(*(begin_ + col4),t4)) return false; - if (!process(*(begin_ + col5),t5)) return false; - if (!process(*(begin_ + col6),t6)) return false; - if (!process(*(begin_ + col7),t7)) return false; - if (!process(*(begin_ + col8),t8)) return false; - if (!process(*(begin_ + col9),t9)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - const std::size_t& col4, const std::size_t& col5, - const std::size_t& col6, const std::size_t& col7, - const std::size_t& col8, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - if (!process(*(begin_ + col4),t4)) return false; - if (!process(*(begin_ + col5),t5)) return false; - if (!process(*(begin_ + col6),t6)) return false; - if (!process(*(begin_ + col7),t7)) return false; - if (!process(*(begin_ + col8),t8)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - const std::size_t& col4, const std::size_t& col5, - const std::size_t& col6, const std::size_t& col7, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - if (!process(*(begin_ + col4),t4)) return false; - if (!process(*(begin_ + col5),t5)) return false; - if (!process(*(begin_ + col6),t6)) return false; - if (!process(*(begin_ + col7),t7)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - const std::size_t& col4, const std::size_t& col5, - const std::size_t& col6, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - if (!process(*(begin_ + col4),t4)) return false; - if (!process(*(begin_ + col5),t5)) return false; - if (!process(*(begin_ + col6),t6)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - const std::size_t& col4, const std::size_t& col5, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - if (!process(*(begin_ + col4),t4)) return false; - if (!process(*(begin_ + col5),t5)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - const std::size_t& col4, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - if (!process(*(begin_ + col4),t4)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, const std::size_t& col3, - T0& t0, T1& t1, T2& t2, T3& t3) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - if (!process(*(begin_ + col3),t3)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - const std::size_t& col2, - T0& t0, T1& t1, T2& t2) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - if (!process(*(begin_ + col2),t2)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col0, const std::size_t& col1, - T0& t0, T1& t1) const - { - if (!process(*(begin_ + col0),t0)) return false; - if (!process(*(begin_ + col1),t1)) return false; - return true; - } - - template - inline bool parse_with_index(const std::size_t& col, T& t) const - { - return process(*(begin_ + col),t); - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5, T6& t6, T7& t7, - T8& t8, T9& t9) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - if (!process(*(begin_ + 4),t4)) return false; - if (!process(*(begin_ + 5),t5)) return false; - if (!process(*(begin_ + 6),t6)) return false; - if (!process(*(begin_ + 7),t7)) return false; - if (!process(*(begin_ + 8),t8)) return false; - if (!process(*(begin_ + 9),t9)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5, T6& t6, T7& t7, - T8& t8) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - if (!process(*(begin_ + 4),t4)) return false; - if (!process(*(begin_ + 5),t5)) return false; - if (!process(*(begin_ + 6),t6)) return false; - if (!process(*(begin_ + 7),t7)) return false; - if (!process(*(begin_ + 8),t8)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5, T6& t6, T7& t7) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - if (!process(*(begin_ + 4),t4)) return false; - if (!process(*(begin_ + 5),t5)) return false; - if (!process(*(begin_ + 6),t6)) return false; - if (!process(*(begin_ + 7),t7)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5, T6& t6) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - if (!process(*(begin_ + 4),t4)) return false; - if (!process(*(begin_ + 5),t5)) return false; - if (!process(*(begin_ + 6),t6)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - if (!process(*(begin_ + 4),t4)) return false; - if (!process(*(begin_ + 5),t5)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - if (!process(*(begin_ + 4),t4)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2, T3& t3) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - if (!process(*(begin_ + 3),t3)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1, T2& t2) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - if (!process(*(begin_ + 2),t2)) return false; - return true; - } - - template - inline bool parse(T0& t0, T1& t1) const - { - if (!process(*(begin_ + 0),t0)) return false; - if (!process(*(begin_ + 1),t1)) return false; - return true; - } - - template - inline bool parse(T0& t) const - { - return process(*begin_,t); - } - - template - inline void parse(OutputIterator out) const - { - token_list_t::const_iterator itr = begin_; - const token_list_t::const_iterator end = begin_ + size_; - while (end != itr) - { - const range_t& range = (*itr); - *(out++) = string_to_type_converter(range.first,range.second); - ++itr; - } - } - - bool validate_column_range(const col_range_t& range) const - { - if ((range.first > size()) || (range.second > size())) - return false; - else if (range.first > range.second) - return false; - else - return true; - } - - col_range_t range(const std::size_t& lower_bound, - const std::size_t& upper_bound = std::numeric_limits::max()) const - { - if (std::numeric_limits::max() != upper_bound) - return col_range_t(lower_bound,upper_bound); - else - return col_range_t(lower_bound,static_cast(size())); - } - - template class Sequence> - inline bool parse(const col_range_t& range, - Sequence& sequence) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = (begin_ + range.first); - token_list_t::const_iterator end = (begin_ + range.second); - T t; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,t)) - sequence.push_back(t); - else - return false; - ++itr; - } - return true; - } - - template - inline bool parse(const col_range_t& range, - std::set& set) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = (begin_ + range.first); - token_list_t::const_iterator end = (begin_ + range.second); - T t; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,t)) - set.insert(t); - else - return false; - ++itr; - } - return true; - } - - template - inline bool parse(const col_range_t& range, - std::multiset& multiset) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = (begin_ + range.first); - token_list_t::const_iterator end = (begin_ + range.second); - T t; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,t)) - multiset.insert(t); - else - return false; - ++itr; - } - return true; - } - - template - inline bool parse(const col_range_t& range, - std::queue& queue) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = (begin_ + range.first); - token_list_t::const_iterator end = (begin_ + range.second); - T t; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,t)) - queue.push(t); - else - return false; - ++itr; - } - return true; - } - - template - inline bool parse(const col_range_t& range, - std::stack& stack) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = (begin_ + range.first); - token_list_t::const_iterator end = (begin_ + range.second); - T t; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,t)) - stack.push(t); - else - return false; - ++itr; - } - return true; - } - - template - inline bool parse(const col_range_t& range, - std::priority_queue& priority_queue) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = (begin_ + range.first); - token_list_t::const_iterator end = (begin_ + range.second); - T t; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,t)) - priority_queue.push(t); - else - return false; - ++itr; - } - return true; - } - - template class Sequence> - inline bool parse(Sequence& sequence) const - { - return parse(range(0),sequence); - } - - template - inline bool parse(std::set& set) const - { - return parse(range(0),set); - } - - template - inline bool parse(std::multiset& multiset) const - { - return parse(range(0),multiset); - } - - template - inline bool parse(std::queue& queue) const - { - return parse(range(0),queue); - } - - template - inline bool parse(std::stack& stack) const - { - return parse(range(0),stack); - } - - template - inline bool parse(std::priority_queue& priority_queue) const - { - return parse(range(0),priority_queue); - } - - template class Sequence> - inline std::size_t parse_n(const std::size_t& n, Sequence& sequence) const - { - if (0 == n) return 0; - T t; - std::size_t count = 0; - token_list_t::const_iterator itr = begin_; - const token_list_t::const_iterator end = begin_ + size_; - while (end != itr) - { - const range_t& range = (*itr); - if (!string_to_type_converter(range.first,range.second,t)) - return false; - else - sequence.push_back(t); - if (n == (++count)) - break; - ++itr; - } - return count; - } - - template - inline void parse_checked(OutputIterator out) const - { - T value; - token_list_t::const_iterator itr = begin_; - const token_list_t::const_iterator end = begin_ + size_; - while (end != itr) - { - const range_t& range = (*itr); - if (string_to_type_converter(range.first,range.second,value)) - { - *(out++) = value; - } - ++itr; - } - } - - template class Sequence> - inline void parse_checked(Sequence& sequence) const - { - parse_checked(std::back_inserter(sequence)); - } - - template - inline void parse_checked(std::set& set) const - { - parse_checked(std::inserter(set,set.end())); - } - - template - inline void parse_checked(std::multiset& multiset) const - { - parse_checked(std::inserter(multiset,multiset.end())); - } - - template - inline void parse_checked(std::queue& queue) const - { - parse_checked(push_inserter(queue)); - } - - template - inline void parse_checked(std::stack& stack) const - { - parse_checked(push_inserter(stack)); - } - - template - inline void parse_checked(std::priority_queue& priority_queue) const - { - parse_checked(push_inserter(priority_queue)); - } - - template - inline std::size_t for_each_column(const col_range_t& range, Function f) const - { - if (!validate_column_range(range)) - return false; - token_list_t::const_iterator itr = begin_ + range.first; - token_list_t::const_iterator end = begin_ + range.second; - std::size_t col_count = 0; - while (end != itr) - { - const range_t& range = (*itr); - f(range); - ++itr; - ++col_count; - } - return col_count; - } - - template - inline std::size_t for_each_column(Function f) const - { - return for_each_column(all_columns(),f); - } - - private: - - template - inline bool process(const range_t& range, T& t) const - { - return string_to_type_converter(range.first,range.second,t); - } - - private: - - std::size_t index_; - std::size_t size_; - token_list_t::const_iterator begin_; - }; - - token_grid() - : file_name_(""), - buffer_(0), - buffer_size_(0), - min_column_count_(0), - max_column_count_(0), - load_from_file_(false), - state_(false) - {} - - token_grid(const std::string& file_name, - const token_grid::options& options) - : file_name_(file_name), - buffer_(0), - buffer_size_(0), - min_column_count_(0), - max_column_count_(0), - options_(options), - load_from_file_(true), - state_(load()) - {} - - token_grid(const unsigned char* input_buffer, - const std::size_t& input_buffer_size, - const token_grid::options& options) - : file_name_(""), - buffer_(const_cast(input_buffer)), - buffer_size_(input_buffer_size), - min_column_count_(0), - max_column_count_(0), - options_(options), - load_from_file_(false), - state_(load()) - {} - - token_grid(const char* input_buffer, - const std::size_t& input_buffer_size, - const token_grid::options& options) - : file_name_(""), - buffer_(reinterpret_cast(const_cast(input_buffer))), - buffer_size_(input_buffer_size), - min_column_count_(0), - max_column_count_(0), - options_(options), - load_from_file_(false), - state_(load()) - {} - - token_grid(const std::string& input_buffer, - const std::size_t& input_buffer_size, - const token_grid::options& options) - : file_name_(""), - buffer_(reinterpret_cast(const_cast(input_buffer.data()))), - buffer_size_(input_buffer_size), - min_column_count_(0), - max_column_count_(0), - options_(options), - load_from_file_(false), - state_(load()) - {} - - token_grid(const std::string& file_name, - const std::string& column_delimiters = ",|;\t", - const std::string& row_delimiters = "\n\r") - : file_name_(file_name), - buffer_(0), - buffer_size_(0), - min_column_count_(0), - max_column_count_(0), - options_(split_options::compress_delimiters, - split_options::compress_delimiters, - row_delimiters, - column_delimiters), - load_from_file_(true), - state_(load()) - {} - - token_grid(const unsigned char* input_buffer, - const std::size_t& input_buffer_size, - const std::string& column_delimiters = ",|;\t", - const std::string& row_delimiters = "\n\r") - : file_name_(""), - buffer_(const_cast(input_buffer)), - buffer_size_(input_buffer_size), - min_column_count_(0), - max_column_count_(0), - options_(split_options::compress_delimiters, - split_options::compress_delimiters, - row_delimiters, - column_delimiters), - load_from_file_(false), - state_(load()) - {} - - token_grid(const char* input_buffer, - const std::size_t& input_buffer_size, - const std::string& column_delimiters = ",|;\t", - const std::string& row_delimiters = "\n\r") - : file_name_(""), - buffer_(reinterpret_cast(const_cast(input_buffer))), - buffer_size_(input_buffer_size), - min_column_count_(0), - max_column_count_(0), - options_(split_options::compress_delimiters, - split_options::compress_delimiters, - row_delimiters, - column_delimiters), - load_from_file_(false), - state_(load()) - {} - - token_grid(const std::string& input_buffer, - const std::size_t& input_buffer_size, - const std::string& column_delimiters = ",;|\t ", - const std::string& row_delimiters = "\n\r") - : file_name_(""), - buffer_(reinterpret_cast(const_cast(input_buffer.data()))), - buffer_size_(input_buffer_size), - min_column_count_(0), - max_column_count_(0), - options_(split_options::compress_delimiters, - split_options::compress_delimiters, - row_delimiters, - column_delimiters), - load_from_file_(false), - state_(load()) - {} - - ~token_grid() - { - if ((load_from_file_) && (0 != buffer_)) - { - delete [] buffer_; - buffer_ = 0; - } - } - - inline bool operator!() const - { - return !state_; - } - - inline std::string source_file() const - { - return file_name_; - } - - inline std::size_t row_count() const - { - return dsv_index_.row_index.size(); - } - - inline std::size_t min_column_count() const - { - return min_column_count_; - } - - inline std::size_t max_column_count() const - { - return max_column_count_; - } - - inline range_t token(const unsigned int& row, const std::size_t& col) const - { - return dsv_index_(col,row); - } - - template - inline T get(const unsigned int& row, const std::size_t& col) - { - range_t r = token(row,col); - return string_to_type_converter(r.first,r.second); - } - - inline row_type row(const unsigned int& row_index) const - { - return row_type(row_index,dsv_index_); - } - - inline row_range_t all_rows() const - { - return row_range_t(0,static_cast(dsv_index_.row_index.size())); - } - - template - inline bool extract_column_checked(const row_range_t& row_range, - const std::size_t& index, - OutputIterator out) const - { - if (index > max_column_count_) - return false; - else if (row_range_invalid(row_range)) - return false; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& row = dsv_index_.row_index[i]; - if (index < dsv_index_.token_count(row)) - { - dsv_index_.token_list.begin() + (row.first + index); - process_token_checked(*(dsv_index_.token_list.begin() + (row.first + index)),out); - } - } - return true; - } - - template - inline bool extract_column_checked(const std::size_t& index, - OutputIterator out) const - { - return extract_column_checked(all_rows(),index,out); - } - - template class Sequence> - inline void extract_column_checked(const std::size_t& index, - Sequence& sequence) const - { - extract_column_checked(index,back_inserter_with_valuetype(sequence)); - } - - template - inline void extract_column_checked(const std::size_t& index, - std::set& set) const - { - extract_column_checked(index,inserter_with_valuetype(set)); - } - - template - inline void extract_column_checked(const std::size_t& index, - std::multiset& multiset) const - { - extract_column_checked(index,inserter_with_valuetype(multiset)); - } - - template - inline bool extract_column(const row_range_t& row_range, - const std::size_t& index, - OutputIterator out) const - { - - if (index > max_column_count_) - return false; - else if (row_range_invalid(row_range)) - return false; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& row = dsv_index_.row_index[i]; - if (index < dsv_index_.token_count(row)) - { - process_token(*(dsv_index_.token_list.begin() + (row.first + index)),out); - } - } - return true; - } - - template - inline bool extract_column(const std::size_t& index, - OutputIterator out) const - { - return extract_column(all_rows(),index,out); - } - - template - inline bool extract_column(const row_range_t& row_range, - const std::size_t& index0, - const std::size_t& index1, - OutputIterator0 out0, - OutputIterator1 out1) const - { - if ((index0 > max_column_count_) || - (index1 > max_column_count_)) - return false; - else if (row_range_invalid(row_range)) - return false; - std::size_t max_index = std::max(index0,index1); - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& row = dsv_index_.row_index[i]; - if (max_index < dsv_index_.token_count(row)) - { - process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0); - process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1); - } - } - return true; - } - - template - inline bool extract_column(const row_range_t& row_range, - const std::size_t& index0, - const std::size_t& index1, - const std::size_t& index2, - OutputIterator0 out0, - OutputIterator1 out1, - OutputIterator2 out2) const - { - if ((index0 > max_column_count_) || - (index1 > max_column_count_) || - (index2 > max_column_count_)) - return false; - else if (row_range_invalid(row_range)) - return false; - std::size_t max_index = std::max(index0,std::max(index1,index2)); - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& row = dsv_index_.row_index[i]; - if (max_index < dsv_index_.token_count(row)) - { - process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0); - process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1); - process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2); - } - } - return true; - } - - template - inline bool extract_column(const row_range_t& row_range, - const std::size_t& index0, - const std::size_t& index1, - const std::size_t& index2, - const std::size_t& index3, - OutputIterator0 out0, - OutputIterator1 out1, - OutputIterator2 out2, - OutputIterator3 out3) const - { - if ((index0 > max_column_count_) || - (index1 > max_column_count_) || - (index2 > max_column_count_) || - (index3 > max_column_count_)) - return false; - else if (row_range_invalid(row_range)) - return false; - std::size_t max_index = std::max(std::max(index0,index1),std::max(index2,index3)); - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& row = dsv_index_.row_index[i]; - if (max_index < dsv_index_.token_count(row)) - { - process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0); - process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1); - process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2); - process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3); - } - } - return true; - } - - template - inline bool extract_column(const row_range_t& row_range, - const std::size_t& index0, - const std::size_t& index1, - const std::size_t& index2, - const std::size_t& index3, - const std::size_t& index4, - OutputIterator0 out0, - OutputIterator1 out1, - OutputIterator2 out2, - OutputIterator3 out3, - OutputIterator4 out4) const - { - if ((index0 > max_column_count_) || - (index1 > max_column_count_) || - (index2 > max_column_count_) || - (index3 > max_column_count_) || - (index4 > max_column_count_)) - return false; - else if (row_range_invalid(row_range)) - return false; - std::size_t max_index = std::max(index4,std::max(std::max(index0,index1),std::max(index2,index3))); - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& row = dsv_index_.row_index[i]; - if (max_index < dsv_index_.token_count(row)) - { - process_token(*(dsv_index_.token_list.begin() + (row.first + index0)),out0); - process_token(*(dsv_index_.token_list.begin() + (row.first + index1)),out1); - process_token(*(dsv_index_.token_list.begin() + (row.first + index2)),out2); - process_token(*(dsv_index_.token_list.begin() + (row.first + index3)),out3); - process_token(*(dsv_index_.token_list.begin() + (row.first + index4)),out4); - } - } - return true; - } - - inline void remove_row(const std::size_t& index) - { - if (index < dsv_index_.row_index.size()) - { - dsv_index_.remove_row(index); - } - } - - template - inline bool remove_row_if(const row_range_t& row_range, Predicate predicate) - { - if (row_range_invalid(row_range)) - return false; - std::size_t removed_token_count = 0; - std::deque remove_token_list; - std::deque remove_row_list; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - row_index_range_t& r = dsv_index_.row_index[i]; - std::size_t temp_r_first = r.first - removed_token_count; - row_type row(i,dsv_index_); - if (predicate(row)) - { - remove_row_list.push_back(i); - for (std::size_t j = r.first; j <= r.second; ++j) - { - remove_token_list.push_back(j); - } - removed_token_count += row.size(); - } - r.first = static_cast(temp_r_first); - r.second -= static_cast(removed_token_count); - } - for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i) - { - row_index_range_t& r = dsv_index_.row_index[i]; - r.first -= static_cast(removed_token_count); - r.second -= static_cast(removed_token_count); - } - if (!remove_row_list.empty()) - { - remove_inplace(index_remover(remove_row_list),dsv_index_.row_index); - } - if (!remove_token_list.empty()) - { - remove_inplace(index_remover(remove_token_list),dsv_index_.token_list); - } - return true; - } - - template - inline bool remove_row_if(Predicate predicate) - { - return remove_row_if(all_rows(),predicate); - } - - template - inline std::size_t remove_token_if(const row_range_t& row_range, Predicate predicate) - { - if (row_range_invalid(row_range)) - return 0; - std::size_t removed_token_count = 0; - std::deque remove_token_list; - std::deque remove_row_list; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - row_index_range_t& r = dsv_index_.row_index[i]; - std::size_t temp_r_first = r.first - removed_token_count; - row_type row(i,dsv_index_); - for (std::size_t j = 0; j < row.size(); ++j) - { - if (predicate(row.token(j))) - { - remove_token_list.push_back(r.first + j); - ++removed_token_count; - } - } - r.first = static_cast(temp_r_first); - r.second -= static_cast(removed_token_count); - if (0 == dsv_index_.token_count(r)) - { - remove_row_list.push_back(i); - } - } - for (std::size_t i = row_range.second; i < dsv_index_.row_index.size(); ++i) - { - row_index_range_t& r = dsv_index_.row_index[i]; - r.first -= static_cast(removed_token_count); - r.second -= static_cast(removed_token_count); - } - if (!remove_row_list.empty()) - { - remove_inplace(index_remover(remove_row_list),dsv_index_.row_index); - } - if (!remove_token_list.empty()) - { - remove_inplace(index_remover(remove_token_list),dsv_index_.token_list); - } - if (!remove_token_list.empty()) - { - update_minmax_columns(); - } - return remove_token_list.size(); - } - - inline std::size_t remove_empty_tokens(const row_range_t& range) - { - return remove_token_if(range,is_empty_token()); - } - - inline std::size_t remove_empty_tokens() - { - return remove_empty_tokens(all_rows()); - } - - inline void enforce_column_count(const row_range_t& row_range, - const std::size_t& column_count) - { - if (row_range_invalid(row_range)) - return; - remove_row_if(insufficient_number_of_columns(column_count)); - min_column_count_ = column_count; - max_column_count_ = column_count; - } - - inline void enforce_column_count(const std::size_t& column_count) - { - enforce_column_count(all_rows(),column_count); - } - - inline void enforce_min_max_column_count(const row_range_t& row_range, - const std::size_t& min_column_count, - const std::size_t& max_column_count) - { - if (row_range_invalid(row_range)) - return; - remove_row_if(insufficient_number_of_minmax_columns(min_column_count,max_column_count)); - min_column_count_ = min_column_count; - max_column_count_ = max_column_count; - } - - inline void enforce_min_max_column_count(const std::size_t& min_column_count, - const std::size_t& max_column_count) - { - enforce_min_max_column_count(all_rows(),min_column_count,max_column_count); - } - - inline void clear(const bool force_delete_buffer = false) - { - if (load_from_file_ || force_delete_buffer) - delete[] buffer_; - buffer_ = 0; - buffer_size_ = 0; - dsv_index_.clear(); - min_column_count_ = 0; - max_column_count_ = 0; - state_ = false; - file_name_ = ""; - } - - inline std::size_t column_width(const std::size_t& col, - const row_range_t& row_range) const - { - if (col > max_column_count_) - return 0; - else if (row_range_invalid(row_range)) - return 0; - std::size_t result = 0; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& r = dsv_index_.row_index[i]; - if (col < dsv_index_.token_count(r)) - { - const range_t& range = *(dsv_index_.token_list.begin() + r.first + col); - result = std::max(std::distance(range.first,range.second),result); - } - } - return result; - } - - inline std::size_t column_width(const std::size_t& col) const - { - return column_width(col,all_rows()); - } - - template class Sequence> - inline void get_column_widths(Sequence& columns) - { - for (std::size_t c = 0; c < max_column_count(); ++c) - { - columns.push_back(column_width(c)); - } - } - - template class Sequence> - inline void get_column_widths(Sequence,Allocator>& columns) - { - for (std::size_t c = 0; c < max_column_count(); ++c) - { - columns.push_back(std::make_pair(c,column_width(c))); - } - } - - template - inline std::size_t accumulate_row(const std::size_t& row, T& result) const - { - if (row >= dsv_index_.row_index.size()) - return 0; - const row_index_range_t& r = dsv_index_.row_index[row]; - token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first; - token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + 1; - std::size_t process_count = 0; - T current_value = T(); - while (end != itr) - { - if (string_to_type_converter((*itr).first,(*itr).second,current_value)) - { - result += current_value; - ++process_count; - } - else - return 0; - ++itr; - } - return process_count; - } - - template - inline std::size_t accumulate_column(const std::size_t& col, - const row_range_t& row_range, - T& result) const - { - if (col > max_column_count_) - return 0; - else if (row_range_invalid(row_range)) - return 0; - std::size_t process_count = 0; - T current_value = T(); - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& r = dsv_index_.row_index[i]; - if (col < dsv_index_.token_count(r)) - { - const range_t& range = *(dsv_index_.token_list.begin() + r.first + col); - if (string_to_type_converter(range.first,range.second,current_value)) - result += current_value; - else - return 0; - } - ++process_count; - } - return process_count; - } - - template - inline std::size_t accumulate_column(const std::size_t& col, T& result) const - { - return accumulate_column(col,all_rows(),result); - } - - template - inline std::size_t accumulate_column(const std::size_t& col, - const row_range_t& row_range, - Predicate p, - T& result) const - { - if (col > max_column_count_) - return 0; - else if (row_range_invalid(row_range)) - return 0; - std::size_t process_count = 0; - T current_value = T(); - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& r = dsv_index_.row_index[i]; - if (col < dsv_index_.token_count(r)) - { - row_type row = row_type(i,dsv_index_); - if (p(row)) - { - const range_t& range = row.token(col); - if (string_to_type_converter(range.first,range.second,current_value)) - { - result += current_value; - ++process_count; - } - else - return 0; - } - } - - } - return process_count; - } - - template - inline std::size_t accumulate_column(const std::size_t& col, - Predicate p, - T& result) const - { - return accumulate_column(col,all_rows(),p,result); - } - - inline bool join_row(const std::size_t& row, - const std::string& delimiter, - std::string& result) - { - if (row >= dsv_index_.row_index.size()) - return false; - const row_index_range_t& r = dsv_index_.row_index[row]; - token_list_t::const_iterator itr = dsv_index_.token_list.begin() + r.first; - token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0); - result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second)); - bool appended = false; - while (end != itr) - { - if (!delimiter.empty() && appended) - result.append(delimiter); - appended = false; - if ((*itr).first != (*itr).second) - { - result.append((*itr).first,(*itr).second); - appended = true; - } - ++itr; - } - return true; - } - - template - inline bool join_row(const std::size_t& row, - Predicate predicate, - const std::string& delimiter, - std::string& result) - { - if (row >= dsv_index_.row_index.size()) - return false; - const row_index_range_t& r = dsv_index_.row_index[row]; - token_list_t::const_iterator itr = (dsv_index_.token_list.begin() + r.first); - token_list_t::const_iterator end = dsv_index_.token_list.begin() + r.second + (row < (dsv_index_.row_index.size() - 1) ? 1 : 0); - result.reserve(delimiter.size() * dsv_index_.token_count(r) + std::distance(itr->first,end->second)); - bool appended = false; - while (end != itr) - { - if (!delimiter.empty() && appended) - result.append(delimiter); - appended = false; - if ((*itr).first != (*itr).second) - { - if (predicate(*itr)) - { - result.append((*itr).first,(*itr).second); - appended = true; - } - } - ++itr; - } - return true; - } - - template - inline bool join_row(const std::size_t& row, - Predicate predicate, - const char* delimiter, - std::string& result) - { - return join_row(row,predicate,std::string(delimiter),result); - } - - inline bool join_column(const std::size_t& col, - const row_range_t& row_range, - const std::string& delimiter, - std::string& result) const - { - if (col > max_column_count_) - return false; - else if (row_range_invalid(row_range)) - return false; - bool appended = false; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& r = dsv_index_.row_index[i]; - if (col < dsv_index_.token_count(r)) - { - row_type row = row_type(i,dsv_index_); - const range_t& range = row.token(col); - if (!delimiter.empty() && appended) - result.append(delimiter); - appended = false; - if (range.first != range.second) - { - result.append(range.first,range.second); - appended = true; - } - } - } - return true; - } - - inline bool join_column(const std::size_t& col, - const std::string& delimiter, - std::string& result) const - { - return join_column(col,all_rows(),delimiter,result); - } - - template - inline bool join_column(const std::size_t& col, - const row_range_t& row_range, - Predicate predicate, - const std::string& delimiter, - std::string& result) const - { - if (col > max_column_count_) - return false; - else if (row_range_invalid(row_range)) - return false; - bool appended = false; - const std::size_t pre_end_index = row_range.second - 1; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - const row_index_range_t& r = dsv_index_.row_index[i]; - if (col < dsv_index_.token_count(r)) - { - row_type row = row_type(i,dsv_index_); - const range_t& range = row.token(col); - if (!delimiter.empty() && appended && (pre_end_index != i)) - result.append(delimiter); - appended = false; - if (range.first != range.second) - { - if (predicate(row)) - { - result.append(range.first,range.second); - appended = true; - } - } - } - } - return true; - } - - template - inline bool join_column(const std::size_t& col, - Predicate p, - const std::string& delimiter, - std::string& result) const - { - return join_column(col,all_rows(),p,delimiter,result); - } - - template - inline bool sequential_partition(const row_range_t& row_range, - TransitionPredicate p, - Function f) - { - if (row_range_invalid(row_range)) - return false; - row_range_t r(row_range.first,row_range.first); - for (row_range_t::first_type i = row_range.first; i < row_range.second; ++i) - { - if (p(row_type(i,dsv_index_))) - { - if (r.first != r.second) - { - r.second = i; - if (!f(*this,r)) - return false; - } - r.first = r.second; - } - else - r.second = i; - } - if (r.first != row_range.second) - { - r.second = row_range.second; - if (!f(*this,r)) - return false; - } - return true; - } - - template - inline bool sequential_partition(TransitionPredicate p, Function f) - { - return sequential_partition(all_rows(),p,f); - } - - static inline token_grid::options default_options() - { - return options(); - } - - template - inline std::size_t for_each_row(const row_range_t& row_range, Function f) const - { - if (row_range_invalid(row_range)) - return 0; - std::size_t row_count = 0; - for (std::size_t i = row_range.first; i < row_range.second; ++i) - { - f(row_type(i,dsv_index_)); - ++row_count; - } - return row_count; - } - - template - inline std::size_t for_each_row(Function f) const - { - return for_each_row(all_rows(),f); - } - - bool load(const std::string& file_name, - const token_grid::options& options) - { - file_name_ = file_name; - if ((load_from_file_) && (0 != buffer_)) - { - delete [] buffer_; - buffer_ = 0; - } - buffer_size_ = 0; - min_column_count_ = 0; - max_column_count_ = 0; - options_ = options; - load_from_file_ = true; - state_ = load(); - if (state_) - return true; - else - { - file_name_ = ""; - if ((load_from_file_) && (0 != buffer_)) - { - delete [] buffer_; - buffer_ = 0; - } - return false; - } - } - - bool load(unsigned char* buffer, - const std::size_t buffer_size, - const token_grid::options& options) - { - file_name_ = ""; - if ((load_from_file_) && (0 != buffer_)) - { - delete [] buffer_; - buffer_ = 0; - } - min_column_count_ = 0; - max_column_count_ = 0; - options_ = options; - load_from_file_ = false; - buffer_ = buffer; - buffer_size_ = buffer_size; - state_ = load(); - if (state_) - return true; - else - { - file_name_ = ""; - if ((load_from_file_) && (0 != buffer_)) - { - delete [] buffer_; - buffer_ = 0; - } - return false; - } - } - - private: - - token_grid(const token_grid& tg); - token_grid& operator=(const token_grid& tg); - - struct is_empty_token - { - inline bool operator()(const range_t& r) const - { - return r.first == r.second; - } - }; - - struct insufficient_number_of_columns - { - insufficient_number_of_columns(const std::size_t& noc) - : num_of_cols(noc) - {} - - inline bool operator()(const row_type& row) const - { - return (num_of_cols != row.size()); - } - - std::size_t num_of_cols; - }; - - struct insufficient_number_of_minmax_columns - { - insufficient_number_of_minmax_columns(const std::size_t& min_col, const std::size_t& max_col) - : min_column_count(min_col), - max_column_count(max_col) - {} - - inline bool operator()(const row_type& row) const - { - return (row.size() < min_column_count) || (max_column_count < row.size()); - } - - std::size_t min_column_count; - std::size_t max_column_count; - }; - - class double_quotes_predicate - { - public: - - double_quotes_predicate(const std::string& delimiters) - : in_bracket_range_(false), - mdp_(delimiters) - {} - - inline bool operator()(const unsigned char c) const - { - if ('"' == c) - { - in_bracket_range_ = !in_bracket_range_; - return false; - } - else if (in_bracket_range_) - return false; - else - return mdp_(c); - } - - inline void reset() - { - in_bracket_range_ = false; - } - - private: - - mutable bool in_bracket_range_; - mutable strtk::multiple_char_delimiter_predicate mdp_; - }; - - inline bool load() - { - if (load_from_file_ && !load_buffer_from_file()) - return false; - - dsv_index_.token_list.clear(); - dsv_index_.row_index.clear(); - - multiple_char_delimiter_predicate text_newline_predicate(options_.row_delimiters); - - if (!options_.support_dquotes) - { - multiple_char_delimiter_predicate token_predicate(options_.column_delimiters); - strtk::split(text_newline_predicate, - buffer_, buffer_ + buffer_size_, - strtk::functional_inserter( - row_processor(dsv_index_,token_predicate,options_.column_split_option)), - strtk::split_options::compress_delimiters); - } - else - { - double_quotes_predicate token_predicate_dblq(options_.column_delimiters); - strtk::split(text_newline_predicate, - buffer_, buffer_ + buffer_size_, - strtk::functional_inserter( - row_processor(dsv_index_,token_predicate_dblq,options_.column_split_option)), - strtk::split_options::compress_delimiters); - - if (options_.trim_dquotes) - { - for (std::size_t i = 0; i < dsv_index_.token_list.size(); ++i) - { - if ( - ((*(dsv_index_.token_list[i].first )) == '"') && - ((*(dsv_index_.token_list[i].second - 1)) == '"') - ) - { - ++dsv_index_.token_list[i].first; - --dsv_index_.token_list[i].second; - } - } - } - } - update_minmax_columns(); - return true; - } - - inline bool load_buffer_from_file() - { - std::ifstream stream(file_name_.c_str(),std::ios::binary); - if (!stream) - return false; - stream.seekg (0,std::ios::end); - buffer_size_ = static_cast(stream.tellg()); - if (0 == buffer_size_) - return false; - stream.seekg (0,std::ios::beg); - buffer_ = new unsigned char[buffer_size_]; - stream.read(reinterpret_cast(buffer_),static_cast(buffer_size_)); - stream.close(); - return true; - } - - template - inline void process_token(const range_t& range, OutputIterator out) const - { - typedef typename std::iterator_traits::value_type output_type; - (*out) = string_to_type_converter(range.first,range.second); - ++out; - } - - template - inline void process_token_checked(const range_t& range, OutputIterator out) const - { - typedef typename std::iterator_traits::value_type output_type; - output_type value; - if (string_to_type_converter(range.first,range.second,value)) - { - (*out) = value; - ++out; - } - } - - inline bool row_range_invalid(const row_range_t& row_range) const - { - if (row_range.first > dsv_index_.row_index.size()) - return true; - else if (row_range.second > dsv_index_.row_index.size()) - return true; - else if (row_range.first > row_range.second) - return true; - else - return false; - } - - inline void update_minmax_columns() - { - min_column_count_ = std::numeric_limits::max(); - max_column_count_ = std::numeric_limits::min(); - for (std::size_t i = 0; i < dsv_index_.row_index.size(); ++i) - { - const row_index_range_t& r = dsv_index_.row_index[i]; - const std::size_t number_of_tokens = dsv_index_.token_count(r); - if (number_of_tokens > max_column_count_) - max_column_count_ = number_of_tokens; - if (number_of_tokens < min_column_count_) - min_column_count_ = number_of_tokens; - } - } - - private: - - store dsv_index_; - std::string file_name_; - unsigned char* buffer_; - std::size_t buffer_size_; - std::size_t min_column_count_; - std::size_t max_column_count_; - options options_; - bool load_from_file_; - bool state_; - }; - - template - inline bool convert_string_range(const std::pair& range, T& t) - { - if (range.first == range.second) return false; - t = string_to_type_converter(std::string(range.first,range.second)); - return true; - } - - struct empty_range - { - public: - - template - inline bool operator()(const InputIterator begin, const InputIterator end) - { - return (0 == std::distance(begin,end)); - } - }; - - struct nonempty_range - { - public: - - template - inline bool operator()(const InputIterator begin, const InputIterator end) - { - return (0 != std::distance(begin,end)); - } - }; - - template - struct filter_non_empty_range - { - public: - - filter_non_empty_range(OutputIterator out) - : out_(out) - {} - - template - inline void operator() (const std::pair& range) - { - if (range.first != range.second) - { - *out_++ = range; - } - } - - private: - - OutputIterator out_; - }; - - template - struct filter_on_wildcard_match - { - public: - - filter_on_wildcard_match(const std::string& match_pattern, - OutputPredicate& predicate, - bool allow_through_on_match = true) - : allow_through_on_match_(allow_through_on_match), - match_pattern_(match_pattern), - predicate_(predicate) - {} - - template - inline void operator() (const std::pair& range) const - { - if (match(match_pattern_.begin(),match_pattern_.end(),range.first,range.second,'*','?') ^ allow_through_on_match_) - { - predicate_(range); - } - } - - inline void operator() (const std::string& s) const - { - if (match(match_pattern_,s) ^ allow_through_on_match_) - { - predicate_(s); - } - } - - private: - - filter_on_wildcard_match(const filter_on_wildcard_match& fom); - filter_on_wildcard_match& operator=(const filter_on_wildcard_match& fom); - - bool allow_through_on_match_; - std::string match_pattern_; - OutputPredicate& predicate_; - }; - - template - struct filter_on_match - { - public: - - filter_on_match(const std::string* begin, const std::string* end, - OutputPredicate predicate, - bool case_insensitive, - bool allow_through_on_match = true) - : case_insensitive_(case_insensitive), - allow_through_on_match_(allow_through_on_match), - begin_(begin), - end_(end), - predicate_(predicate) - {} - - template - inline void operator() (const std::pair& range) const - { - for (const std::string* itr = begin_; end_ != itr; ++itr) - { - if ((case_insensitive_ && - (imatch((*itr).data(),(*itr).data() + (*itr).size(),range.first,range.second))) || - (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),range.first))) - { - if (allow_through_on_match_) - { - predicate_(range); - } - return; - } - } - - if (!allow_through_on_match_) - { - predicate_(range); - return; - } - } - - inline void operator() (const std::string& s) const - { - for (const std::string* itr = begin_; end_ != itr; ++itr) - { - if ((case_insensitive_ && - (imatch((*itr).begin(),(*itr).end(),s.begin(),s.end()))) || - (!case_insensitive_ && std::equal((*itr).begin(),(*itr).end(),s.begin()))) - { - if (allow_through_on_match_) - { - predicate_(s); - return; - } - } - } - - if (!allow_through_on_match_) - { - predicate_(s); - return; - } - } - - private: - - filter_on_match& operator=(const filter_on_match& fom); - - private: - - bool case_insensitive_; - bool allow_through_on_match_; - const std::string* begin_; - const std::string* end_; - OutputPredicate predicate_; - }; - - template - inline void skip_while_matching(Iterator& itr, - const Iterator& end, - const MatchPredicate& predicate) - { - while (end != itr) - { - if (predicate(*itr)) - ++itr; - else - break; - } - } - - template - struct size_equal_to - { - template - inline bool operator()(const Iterator begin, const Iterator end) const - { - return length == std::distance(begin,end); - } - - template - inline bool operator()(const std::pair& range) const - { - return length == std::distance(range.first,range.second); - } - - template class Sequence> - inline bool operator()(const Sequence& sequence) const - { - return length == sequence.size(); - } - - template - inline bool operator()(const std::set& set) const - { - return length == set.size(); - } - - template - inline bool operator()(const std::multiset& multiset) const - { - return length == multiset.size(); - } - - inline bool operator()(const std::string& str) const - { - return length == str.size(); - } - }; - - template - struct size_less_than - { - template - inline bool operator()(const Iterator begin, const Iterator end) const - { - return std::distance(begin,end) < static_cast::difference_type>(length); - } - - template - inline bool operator()(const std::pair& range) const - { - return std::distance(range.first,range.second) < static_cast::difference_type>(length); - } - - template class Sequence> - inline bool operator()(const Sequence& sequence) const - { - return sequence.size() < length; - } - - template - inline bool operator()(const std::set& set) const - { - return set.size() < length; - } - - template - inline bool operator()(const std::multiset& multiset) const - { - return multiset.size() < length; - } - - inline bool operator()(const std::string& str) const - { - return str.size() < length; - } - }; - - template - struct size_greater_than - { - template - inline bool operator()(const Iterator begin, const Iterator end) const - { - return std::distance(begin,end) > static_cast::difference_type>(length); - } - - template - inline bool operator()(const std::pair& range) const - { - return std::distance(range.first,range.second) > static_cast::difference_type>(length); - } - - template class Sequence> - inline bool operator()(const Sequence& sequence) const - { - return sequence.size() > length; - } - - template - inline bool operator()(const std::set& set) const - { - return set.size() > length; - } - - template - inline bool operator()(const std::multiset& multiset) const - { - return multiset.size() > length; - } - - inline bool operator()(const std::string& str) const - { - return str.size() > length; - } - }; - - struct size_is_even - { - template - inline bool operator()(const Iterator begin, const Iterator end) const - { - return 0 == (std::distance(begin,end) % 2); - } - - template - inline bool operator()(const std::pair& range) const - { - return 0 == (std::distance(range.first,range.second) % 2); - } - - template class Sequence> - inline bool operator()(const Sequence& sequence) const - { - return 0 == (sequence.size() % 2); - } - - template - inline bool operator()(const std::set& set) const - { - return 0 == (set.size() % 2); - } - - template - inline bool operator()(const std::multiset& multiset) const - { - return 0 == (multiset.size() % 2); - } - - inline bool operator()(const std::string& str) const - { - return 0 == (str.size() % 2); - } - }; - - struct size_is_odd - { - template - inline bool operator()(const Iterator begin, const Iterator end) const - { - return 0 != (std::distance(begin,end) % 2); - } - - template - inline bool operator()(const std::pair& range) const - { - return 0 != (std::distance(range.first,range.second) % 2); - } - - template class Sequence> - inline bool operator()(const Sequence& sequence) const - { - return 0 != (sequence.size() % 2); - } - - template - inline bool operator()(const std::set& set) const - { - return 0 != (set.size() % 2); - } - - template - inline bool operator()(const std::multiset& multiset) const - { - return 0 != (multiset.size() % 2); - } - - inline bool operator()(const std::string& str) const - { - return 0 != (str.size() % 2); - } - }; - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10, T11& t11, T12& t12) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 12; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t12)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10, T11& t11) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 11; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 10; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 9; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 8; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 7; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 6; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 5; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 4; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 3; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 2; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; - return true; - } - - template - inline bool parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - T& t) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - static const std::size_t token_count = 1; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - iterator_type token_list[token_count]; - const std::size_t parsed_token_count = split_n(delimiters, - begin,end, - token_count, - token_list, - split_options::compress_delimiters); - if (token_count > parsed_token_count) - return false; - iterator_type_ptr itr = token_list; - return string_to_type_converter((*itr).first,(*itr).second,t); - } - - template class Sequence> - inline std::size_t parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - begin,end, - range_to_type_back_inserter(sequence), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - begin, end, - range_to_type_back_inserter(sequence), - split_option); - } - - template - inline std::size_t parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - begin,end, - range_to_type_inserter(set), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - begin,end, - range_to_type_inserter(set), - split_option); - } - - template - inline std::size_t parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - begin,end, - range_to_type_inserter(multiset), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - begin,end, - range_to_type_inserter(multiset), - split_option); - } - - template - inline std::size_t parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - begin,end, - range_to_type_push_inserter(queue), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - begin,end, - range_to_type_push_inserter(queue), - split_option); - } - - template - inline std::size_t parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - begin,end, - range_to_type_push_inserter(stack), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - begin, end, - range_to_type_push_inserter(stack), - split_option); - } - - template - inline std::size_t parse(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - begin,end, - range_to_type_push_inserter(priority_queue), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - begin,end, - range_to_type_push_inserter(priority_queue), - split_option); - } - - template class Sequence> - inline std::size_t parse(const std::pair& range, - const std::string& delimiters, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - range_to_type_back_inserter(sequence), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - range_to_type_back_inserter(sequence), - split_option); - } - - template - inline std::size_t parse(const std::pair& range, - const std::string& delimiters, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - range_to_type_inserter(set), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - range_to_type_inserter(set), - split_option); - } - - template - inline std::size_t parse(const std::pair& range, - const std::string& delimiters, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - range_to_type_inserter(multiset), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - range_to_type_inserter(multiset), - split_option); - } - - template - inline std::size_t parse(const std::pair& range, - const std::string& delimiters, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - range_to_type_push_inserter(queue), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - range_to_type_push_inserter(queue), - split_option); - } - - template - inline std::size_t parse(const std::pair& range, - const std::string& delimiters, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - range_to_type_push_inserter(stack), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - range_to_type_push_inserter(stack), - split_option); - } - - template - inline std::size_t parse(const std::pair& range, - const std::string& delimiters, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - details::convert_type_assert(); - if (1 == delimiters.size()) - return split(single_delimiter_predicate(delimiters[0]), - range.first,range.second, - range_to_type_push_inserter(priority_queue), - split_option); - else - return split(multiple_char_delimiter_predicate(delimiters), - range.first,range.second, - range_to_type_push_inserter(priority_queue), - split_option); - } - - namespace details - { - class container_adder - { - private: - - class container_adder_base - { - public: - - typedef const char* itr_type; - - virtual ~container_adder_base(){} - - template - inline bool add(const InputIterator begin, const InputIterator end) const - { - return add_impl(begin,end); - } - - template - inline bool add(const std::pair& range) const - { - return add(range.first,range.second); - } - - protected: - - virtual bool add_impl(const itr_type begin, const itr_type end) const = 0; - - }; - - template class Sequence> - class sequence_adder_impl : public container_adder_base - { - public: - - typedef Sequence sequence_t; - - sequence_adder_impl(sequence_t& seq) - : sequence_(seq) - {} - - protected: - - bool add_impl(const itr_type begin, const itr_type end) const - { - T t; - if (!string_to_type_converter(begin,end,t)) return false; - sequence_.push_back(t); - return true; - } - - private: - - sequence_adder_impl operator=(const sequence_adder_impl&); - - sequence_t& sequence_; - }; - - template class Set> - class set_adder_impl : public container_adder_base - { - public: - - set_adder_impl(Set& set) - : set_(set) - {} - - bool add_impl(const itr_type begin, const itr_type end) const - { - T t; - if (!string_to_type_converter(begin,end,t)) return false; - set_.insert(t); - return true; - } - - private: - - set_adder_impl operator=(const set_adder_impl&); - - Set& set_; - }; - - template - class pq_adder_impl : public container_adder_base - { - public: - - pq_adder_impl(std::priority_queue& pq) - : pq_(pq) - {} - - bool add_impl(const itr_type begin, const itr_type end) const - { - T t; - if (!string_to_type_converter(begin,end,t)) return false; - pq_.push(t); - return true; - } - - private: - - pq_adder_impl operator=(const pq_adder_impl&); - - std::priority_queue& pq_; - }; - - template class SContainer> - class stack_queue_adder_impl : public container_adder_base - { - public: - - stack_queue_adder_impl(SContainer& container) - : container_(container) - {} - - bool add_impl(const itr_type begin, const itr_type end) const - { - T t; - if (!string_to_type_converter(begin,end,t)) return false; - container_.push(t); - return true; - } - - private: - - stack_queue_adder_impl operator=(const stack_queue_adder_impl&); - - SContainer& container_; - }; - - public: - - template - container_adder(std::vector& vec) - : container_adder_base_(new(buffer)sequence_adder_impl(vec)) - {} - - template - container_adder(std::deque& deq) - : container_adder_base_(new(buffer)sequence_adder_impl(deq)) - {} - - template - container_adder(std::list& list) - : container_adder_base_(new(buffer)sequence_adder_impl(list)) - {} - - template - container_adder(std::set& set) - : container_adder_base_(new(buffer)set_adder_impl(set)) - {} - - template - container_adder(std::multiset& multiset) - : container_adder_base_(new(buffer)set_adder_impl(multiset)) - {} - - template - container_adder(std::priority_queue& pq) - : container_adder_base_(new(buffer)pq_adder_impl(pq)) - {} - - template - container_adder(std::queue& queue) - : container_adder_base_(new(buffer)stack_queue_adder_impl(queue)) - {} - - template - container_adder(std::stack& stack) - : container_adder_base_(new(buffer)stack_queue_adder_impl(stack)) - {} - - template - inline bool add(InputIterator begin, InputIterator end) const - { - return container_adder_base_->add(begin,end); - } - - template - inline bool add(std::pair& range) const - { - return add(range.first,range.second); - } - - template - inline bool operator()(const InputIterator begin, const InputIterator end) - { - InputIterator itr = begin; - while (end != itr) - { - if (!add(*itr)) return false; - ++itr; - } - return true; - } - - private: - - mutable container_adder_base* container_adder_base_; - unsigned char buffer[64]; - }; - - template - struct ca_type { typedef T& type; }; - - template - struct ca_type { typedef details::container_adder type; }; - - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, - T8& t8, T9& t9, T10& t10, T11& t11, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 12) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t11)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 11) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second, t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second, t9)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t10)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 10) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t9)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 9) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t8)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 8) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t7)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 7) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t6)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 6) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t5)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 5) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t4)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 4) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t3)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, T2& t2, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 3) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - if (!string_to_type_converter((*itr).first,(*itr).second,t2)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template - inline bool parse(const InputIterator begin, const InputIterator end, - const std::string& delimiters, - T1& t1, - details::container_adder ca) - { - typedef typename details::is_valid_iterator::type itr_type; - typedef std::pair iterator_type; - typedef typename std::deque::iterator iterator_type_ptr; - details::convert_type_assert(); - std::deque token_list; - if (1 == delimiters.size()) - split(single_delimiter_predicate(delimiters[0]), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - else - split(multiple_char_delimiter_predicate(delimiters), - begin,end, - std::back_inserter(token_list), - split_options::compress_delimiters); - if (token_list.size() < 2) return false; - iterator_type_ptr itr = token_list.begin(); - if (!string_to_type_converter((*itr).first,(*itr).second,t1)) return false; ++itr; - return ca(itr,token_list.end()); - } - - template class Sequence> - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - const std::size_t original_size = sequence.size(); - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_type_back_inserter(sequence), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_type_back_inserter(sequence), - split_option); - return sequence.size() - original_size; - } - - template - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - const std::size_t original_size = set.size(); - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_type_inserter(set), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_type_inserter(set), - split_option); - return set.size() - original_size; - } - - template - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - const std::size_t original_size = multiset.size(); - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_type_inserter(multiset), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_type_inserter(multiset), - split_option); - return multiset.size() - original_size; - } - - template - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - const std::size_t original_size = queue.size(); - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_type_push_inserter(queue), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_type_push_inserter(queue), - split_option); - return queue.size() - original_size; - } - - template - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - const std::size_t original_size = stack.size(); - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_type_push_inserter(stack), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_type_push_inserter(stack), - split_option); - return stack.size() - original_size; - } - - template - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - const std::size_t original_size = priority_queue.size(); - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_type_push_inserter(priority_queue), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_type_push_inserter(priority_queue), - split_option); - return priority_queue.size() - original_size; - } - - template - inline std::size_t parse_n(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - T* out, - const split_options::type& split_option = split_options::compress_delimiters) - { - typedef typename details::is_valid_iterator::type itr_type; - std::size_t insert_count = 0; - details::convert_type_assert(); - if (1 == delimiters.size()) - split_n(single_delimiter_predicate(delimiters[0]), - begin,end, - n, - range_to_ptr_type(out,insert_count), - split_option); - else - split_n(multiple_char_delimiter_predicate(delimiters), - begin,end, - n, - range_to_ptr_type(out,insert_count), - split_option); - return insert_count; - } - - template class Sequence> - inline std::size_t parse_n(const std::pair& range, - const std::string& delimiters, - const std::size_t& n, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(range.first,range.second,delimiters,n,sequence,split_option); - } - - template - inline std::size_t parse_n(const std::pair& range, - const std::string& delimiters, - const std::size_t& n, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(range.first,range.second,delimiters,n,set,split_option); - } - - template - inline std::size_t parse_n(const std::pair& range, - const std::string& delimiters, - const std::size_t& n, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(range.first,range.second,delimiters,n,multiset,split_option); - } - - template - inline std::size_t parse_n(const std::pair& range, - const std::string& delimiters, - const std::size_t& n, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(range.first,range.second,delimiters,n,queue,split_option); - } - - template - inline std::size_t parse_n(const std::pair& range, - const std::string& delimiters, - const std::size_t& n, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(range.first,range.second,delimiters,n,stack,split_option); - } - - template - inline std::size_t parse_n(const std::pair& range, - const std::string& delimiters, - const std::size_t& n, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(range.first,range.second,delimiters,n,priority_queue,split_option); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10, T11& t11, T12& t12) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11, - typename details::ca_type::result_t>::type(t12)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10, T11& t11) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6,t7,t8,t9,t10, - typename details::ca_type::result_t>::type(t11)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6,t7,t8,t9, - typename details::ca_type::result_t>::type(t10)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6,t7,t8, - typename details::ca_type::result_t>::type(t9)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6,t7, - typename details::ca_type::result_t>::type(t8)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6, - typename details::ca_type::result_t>::type(t7)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5, - typename details::ca_type::result_t>::type(t6)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4, - typename details::ca_type::result_t>::type(t5)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3, - typename details::ca_type::result_t>::type(t4)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2, - typename details::ca_type::result_t>::type(t3)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T1& t1, T2& t2) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - t1, - typename details::ca_type::result_t>::type(t2)); - } - - template - inline bool parse(const std::string& data, - const std::string& delimiters, - T& t) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - typename details::ca_type::result_t>::type(t)); - } - - template class Sequence> - inline std::size_t parse(const std::string& data, - const std::string& delimiters, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - sequence, - split_option); - } - - template - inline std::size_t parse(const std::string& data, - const std::string& delimiters, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - set, - split_option); - } - - template - inline std::size_t parse(const std::string& data, - const std::string& delimiters, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - multiset, - split_option); - } - - template - inline std::size_t parse(const std::string& data, - const std::string& delimiters, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - queue, - split_option); - } - - template - inline std::size_t parse(const std::string& data, - const std::string& delimiters, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - stack, - split_option); - } - - template - inline std::size_t parse(const std::string& data, - const std::string& delimiters, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(data.data(), - data.data() + data.size(), - delimiters, - priority_queue, - split_option); - } - - template class Sequence> - inline std::size_t parse(const int& argc, char* argv[], - Sequence& sequence, - const bool break_on_fail = true) - { - T tmp; - for (int i = 0; i < argc; ++i) - { - if (!string_to_type_converter(std::string(argv[i]),tmp)) - { - if (break_on_fail) - return i; - else - continue; - } - sequence.push_back(tmp); - } - return argc; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9) - - { - if (9 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result; - if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result; - if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result; - if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result; - if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result; - if (!string_to_type_converter(std::string(argv[8]),t9)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - - { - if (8 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result; - if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result; - if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result; - if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result; - if (!string_to_type_converter(std::string(argv[7]),t8)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7) - - { - if (7 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result; - if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result; - if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result; - if (!string_to_type_converter(std::string(argv[6]),t7)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6) - - { - if (6 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result; - if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result; - if (!string_to_type_converter(std::string(argv[5]),t6)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) - { - if (5 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result; - if (!string_to_type_converter(std::string(argv[4]),t5)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3, T4& t4) - { - if (4 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - if (!string_to_type_converter(std::string(argv[3]),t4)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2, T3& t3) - { - if (3 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - if (!string_to_type_converter(std::string(argv[2]),t3)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1, T2& t2) - { - if (2 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - if (!string_to_type_converter(std::string(argv[1]),t2)) return result; ++result; - return result; - } - - template - inline std::size_t parse(const int& argc, char* argv[], - T1& t1) - { - if (1 != argc) return 0; - std::size_t result = 0; - if (!string_to_type_converter(std::string(argv[0]),t1)) return result; ++result; - return result; - } - - #define strtk_parse_begin(Type) \ - namespace strtk { \ - bool parse(const std::string& data, const std::string& delimiters, Type& t)\ - { return parse(data,delimiters \ - - #define strtk_parse_type(T) \ - ,t.T \ - - #define strtk_parse_hex_type(T) \ - ,t.T \ - - #define strtk_parse_ignore_token() \ - ,ignore_token() \ - - #define strtk_parse_end() \ - );}} \ - - template class Sequence> - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - sequence, - split_option); - } - - template - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - set, - split_option); - } - - template - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - multiset, - split_option); - } - - template - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - queue, - split_option); - } - - template - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - stack, - split_option); - } - - template - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - priority_queue, - split_option); - } - - template - inline std::size_t parse_n(const std::string& data, - const std::string& delimiters, - const std::size_t& n, - T* out, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - out, - split_option); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7, T8& t8, T9& t9, T10& t10, T11& t11, T12& t12) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6, - t7,t8,t9,t10,t11,t12); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7, T8& t8, T9& t9, T10& t10, T11& t11) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6, - t7,t8,t9,t10,t11); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7, T8& t8, T9& t9, T10& t10) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6, - t7,t8,t9,t10); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7, T8& t8, T9& t9) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6, - t7,t8,t9); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7, T8& t8) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6, - t7,t8); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6,t7); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5,t6); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4,t5); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3, T4& t4) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3,t4); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2, T3& t3) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2,t3); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1, T2& t2) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1,t2); - } - - template - inline bool parse_line(std::ifstream& stream, - const std::string& delimiters, - T1& t1) - { - if (!stream) - return false; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return false; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - t1); - } - - template class Sequence> - inline std::size_t parse_line(std::ifstream& stream, - const std::string& delimiters, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - sequence, - split_option); - } - - template - inline std::size_t parse_line(std::ifstream& stream, - const std::string& delimiters, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - set, - split_option); - } - - template - inline std::size_t parse_line(std::ifstream& stream, - const std::string& delimiters, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - multiset, - split_option); - } - - template - inline std::size_t parse_line(std::ifstream& stream, - const std::string& delimiters, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - queue, - split_option); - } - - template - inline std::size_t parse_line(std::ifstream& stream, - const std::string& delimiters, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - stack, - split_option); - } - - template - inline std::size_t parse_line(std::ifstream& stream, - const std::string& delimiters, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return false; - return strtk::parse(data.data(), - data.data() + data.size(), - delimiters, - priority_queue, - split_option); - } - - template class Sequence> - inline std::size_t parse_line_n(std::ifstream& stream, - const std::string& delimiters, - const std::size_t& n, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return 0; - return strtk::parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - sequence, - split_option); - } - - template - inline std::size_t parse_line_n(std::ifstream& stream, - const std::string& delimiters, - const std::size_t& n, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return 0; - return strtk::parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - set, - split_option); - } - - template - inline std::size_t parse_line_n(std::ifstream& stream, - const std::string& delimiters, - const std::size_t& n, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return 0; - return strtk::parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - multiset, - split_option); - } - - template - inline std::size_t parse_line_n(std::ifstream& stream, - const std::string& delimiters, - const std::size_t& n, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return 0; - return strtk::parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - queue, - split_option); - } - - template - inline std::size_t parse_line_n(std::ifstream& stream, - const std::string& delimiters, - const std::size_t& n, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return 0; - return strtk::parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - stack, - split_option); - } - - template - inline std::size_t parse_line_n(std::ifstream& stream, - const std::string& delimiters, - const std::size_t& n, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - - { - if (!stream) - return 0; - std::string data; - data.reserve(strtk::one_kilobyte); - if (!std::getline(stream,data)) - return 0; - if (data.empty() || delimiters.empty()) - return 0; - return strtk::parse_n(data.data(), - data.data() + data.size(), - delimiters, - n, - priority_queue, - split_option); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10, const T11& t11, const T12& t12) - { - output += type_to_string( t1); output += delimiter; - output += type_to_string( t2); output += delimiter; - output += type_to_string( t3); output += delimiter; - output += type_to_string( t4); output += delimiter; - output += type_to_string( t5); output += delimiter; - output += type_to_string( t6); output += delimiter; - output += type_to_string( t7); output += delimiter; - output += type_to_string( t8); output += delimiter; - output += type_to_string( t9); output += delimiter; - output += type_to_string(t10); output += delimiter; - output += type_to_string(t11); output += delimiter; - output += type_to_string(t12); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10, const T11& t11) - { - output += type_to_string( t1); output += delimiter; - output += type_to_string( t2); output += delimiter; - output += type_to_string( t3); output += delimiter; - output += type_to_string( t4); output += delimiter; - output += type_to_string( t5); output += delimiter; - output += type_to_string( t6); output += delimiter; - output += type_to_string( t7); output += delimiter; - output += type_to_string( t8); output += delimiter; - output += type_to_string( t9); output += delimiter; - output += type_to_string(t10); output += delimiter; - output += type_to_string(t11); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); output += delimiter; - output += type_to_string(t5); output += delimiter; - output += type_to_string(t6); output += delimiter; - output += type_to_string(t7); output += delimiter; - output += type_to_string(t8); output += delimiter; - output += type_to_string(t9); output += delimiter; - output += type_to_string(t10); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); output += delimiter; - output += type_to_string(t5); output += delimiter; - output += type_to_string(t6); output += delimiter; - output += type_to_string(t7); output += delimiter; - output += type_to_string(t8); output += delimiter; - output += type_to_string(t9); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); output += delimiter; - output += type_to_string(t5); output += delimiter; - output += type_to_string(t6); output += delimiter; - output += type_to_string(t7); output += delimiter; - output += type_to_string(t8); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); output += delimiter; - output += type_to_string(t5); output += delimiter; - output += type_to_string(t6); output += delimiter; - output += type_to_string(t7); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); output += delimiter; - output += type_to_string(t5); output += delimiter; - output += type_to_string(t6); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); output += delimiter; - output += type_to_string(t5); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3, const T4& t4) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); output += delimiter; - output += type_to_string(t4); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2, const T3& t3) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); output += delimiter; - output += type_to_string(t3); - } - - template - inline void construct(std::string& output, - const std::string& delimiter, - const T1& t1, const T2& t2) - { - output += type_to_string(t1); output += delimiter; - output += type_to_string(t2); - } - - template - inline void join(std::string& output, - const std::string& delimiter, - const InputIterator begin, - const InputIterator end) - { - InputIterator itr = begin; - while (end != itr) - { - output += type_to_string(*itr); - if (end == (++itr)) - break; - else - output += delimiter; - } - } - - template - inline void join(std::string& output, - const std::string& delimiter, - const std::pair& range) - { - InputIterator itr = range.first; - while (range.second != itr) - { - output += type_to_string(*itr); - if (range.second == (++itr)) - break; - else - output += delimiter; - } - } - - template class Sequence> - inline void join(std::string& output, - const std::string& delimiter, - const Sequence& sequence) - { - join(output,delimiter,sequence.begin(),sequence.end()); - } - - template - inline void join(std::string& output, - const std::string& delimiter, - const std::set& set) - { - join(output,delimiter,set.begin(),set.end()); - } - - template - inline void join(std::string& output, - const std::string& delimiter, - const std::multiset& multiset) - { - join(output,delimiter,multiset.begin(),multiset.end()); - } - - inline void join(std::string& output, - const std::string& delimiter, - int argc, char* argv[]) - { - for (int i = 0; i < argc; ++i) - { - output += argv[i]; - if (i < (argc - 1)) - output += delimiter; - } - } - - template - inline std::string join(const std::string& delimiter, - const InputIterator begin, - const InputIterator end) - { - std::string output; - output.reserve(one_kilobyte); - join(output,delimiter,begin,end); - return output; - } - - template - inline std::string join(const std::string& delimiter, - const std::pair& range) - { - std::string output; - output.reserve(one_kilobyte); - join(output,delimiter,range.first,range.second); - return output; - } - - template class Sequence> - inline std::string join(const std::string& delimiter, - const Sequence& sequence) - { - if (sequence.empty()) - return ""; - else - return join(delimiter,sequence.begin(),sequence.end()); - } - - template - inline std::string join(const std::string& delimiter, - const std::set& set) - { - if (set.empty()) - return ""; - else - return join(delimiter,set.begin(),set.end()); - } - - template - inline std::string join(const std::string& delimiter, - const std::multiset& multiset) - { - if (multiset.empty()) - return ""; - else - return join(delimiter,multiset.begin(),multiset.end()); - } - - inline std::string join(const std::string& delimiter, int argc, char* argv[]) - { - std::string result; - result.reserve(one_kilobyte); - join(result,delimiter,argc,argv); - return result; - } - - template - inline void join_if(std::string& output, - const std::string& delimiter, - Predicate predicate, - const InputIterator begin, - const InputIterator end) - { - InputIterator itr = begin; - bool first_time = true; - while (end != itr) - { - if (predicate(*itr)) - { - if (!first_time) - output += delimiter; - else - first_time = false; - output += type_to_string(*itr); - } - if (end == (++itr)) - break; - } - } - - template - inline void join_if(std::string& output, - const std::string& delimiter, - Predicate predicate, - const std::pair& range) - { - InputIterator itr = range.first; - bool first_time = true; - while (range.second != itr) - { - if (predicate(*itr)) - { - if (!first_time) - output += delimiter; - else - first_time = false; - output += type_to_string(*itr); - } - if (range.second == (++itr)) - break; - } - } - - template class Sequence> - inline void join_if(std::string& output, - const std::string& delimiter, - Predicate predicate, - const Sequence& sequence) - { - join_if(output,delimiter,predicate,sequence.begin(),sequence.end()); - } - - template - inline void join_if(std::string& output, - const std::string& delimiter, - Predicate predicate, - const std::set& set) - { - join_if(output,delimiter,predicate,set.begin(),set.end()); - } - - template - inline void join_if(std::string& output, - const std::string& delimiter, - Predicate predicate, - const std::multiset& multiset) - { - join_if(output,delimiter,predicate,multiset.begin(),multiset.end()); - } - - template - inline std::string join_if(const std::string& delimiter, - Predicate predicate, - const InputIterator begin, - const InputIterator end) - { - std::string output; - output.reserve(one_kilobyte); - join_if(output,delimiter,predicate,begin,end); - return output; - } - - template - inline std::string join_if(const std::string& delimiter, - Predicate predicate, - const std::pair& range) - { - std::string output; - output.reserve(one_kilobyte); - join_if(output,delimiter,predicate,range.first,range.second); - return output; - } - - template class Sequence> - inline std::string join_if(const std::string& delimiter, - Predicate predicate, - const Sequence& sequence) - { - return join(delimiter,predicate,sequence.begin(),sequence.end()); - } - - template - inline std::string join_if(const std::string& delimiter, - Predicate predicate, - const std::set& set) - { - return join_if(delimiter,predicate,set.begin(),set.end()); - } - - template - inline std::string join_if(const std::string& delimiter, - Predicate predicate, - const std::multiset& multiset) - { - return join_if(delimiter,predicate,multiset.begin(),multiset.end()); - } - - class build_string - { - public: - - build_string(const std::size_t& initial_size = 64) - { - data_.reserve(initial_size); - } - - template - inline build_string& operator << (const T& t) - { - data_ += type_to_string(t); - return (*this); - } - - inline build_string& operator << (const std::string& s) - { - data_ += s; - return (*this); - } - - inline std::string to_str() const - { - return data_; - } - - inline operator const char* () const - { - return data_.data(); - } - - private: - - std::string data_; - }; - - inline void replicate(const std::size_t& n, - const std::string& str, - std::string& output) - { - if (0 == n) return; - output.reserve(output.size() + (str.size() * n)); - for (std::size_t i = 0; i < n; ++i) - { - output.append(str); - } - } - - inline std::string replicate(const std::size_t& n, - const std::string& str) - { - std::string output; - replicate(n,str,output); - return output; - } - - inline void replicate_inplace(const std::size_t& n, - std::string& str) - { - std::string temp_str = str; - str.reserve(str.size() + (str.size() * n)); - - for (std::size_t i = 0; i < n; ++i) - { - str.append(temp_str); - } - } - - template - inline void bracketize(std::string& output, - const std::string& pre, - const std::string& post, - const InputIterator begin, - const InputIterator end) - { - InputIterator itr = begin; - std::string s; - s.reserve(one_kilobyte); - while (end != itr) - { - s.clear(); - s.append(pre); - s.append(type_to_string(*itr)); - s.append(post); - output.append(s); - ++itr; - } - } - - template class Sequence> - inline void bracketize(std::string& output, - const std::string& pre, - const std::string& post, - Sequence& sequence) - { - bracketize(output,pre,post,sequence.begin(),sequence.end()); - } - - template - inline void bracketize(std::string& output, - const std::string& pre, - const std::string& post, - std::set& set) - { - bracketize(output,pre,post,set.begin(),set.end()); - } - - template - inline void bracketize(std::string& output, - const std::string& pre, - const std::string& post, - std::multiset& multiset) - { - bracketize(output,pre,post,multiset.begin(),multiset.end()); - } - - template - inline std::string bracketize(const std::string& pre, - const std::string& post, - const InputIterator begin, - const InputIterator end) - { - std::string output; - output.reserve(one_kilobyte); - bracketize(output,pre,post,begin,end); - return output; - } - - template class Sequence> - inline std::string bracketize(const std::string& pre, - const std::string& post, - Sequence& sequence) - { - return bracketize(pre,post,sequence.begin(),sequence.end()); - } - - template - inline std::string bracketize(const std::string& pre, - const std::string& post, - std::set& set) - { - return bracketize(pre,post,set.begin(),set.end()); - } - - template - inline std::string bracketize(const std::string& pre, - const std::string& post, - std::multiset& multiset) - { - return bracketize(pre,post,multiset.begin(),multiset.end()); - } - - template - struct interval_inserter - { - typedef T type; - - interval_inserter(const std::size_t& interval, const T& t) - : count_(0), - interval_(interval), - t_(t) - {} - - inline bool operator()(const type&) - { - if (++count_ == interval_) - { - count_ = 0; - return true; - } - else - return false; - } - - inline T operator()() - { - return t_; - } - - private: - - std::size_t count_; - std::size_t interval_; - T t_; - }; - - template - inline std::size_t inserter(Inserter ins, - const InputIterator begin, const InputIterator end, - OutputIterator out) - { - std::size_t size = 0; - InputIterator itr = begin; - while (end != itr) - { - (*out) = (*itr); - ++out; - if (ins(*itr++)) - { - (*out) = ins(); - ++out; - size += 2; - } - else - ++size; - } - return size; - } - - template - inline void iota(Iterator begin, Iterator end, T value) - { - Iterator itr = begin; - while (end != itr) - { - (*itr) = value++; - ++itr; - } - } - - template - inline void iota(typename range::adapter& r, T value) - { - iota(r.begin(),r.end(),value); - } - - template class Sequence> - inline void iota(Sequence& sequence, std::size_t count, T value) - { - while (count) - { - sequence.push_back(value++); - --count; - } - } - - template - inline void iota(std::set& set, std::size_t count, T value) - { - while (count) - { - set.insert(value++); - --count; - } - } - - template - inline void iota(std::multiset& multiset, std::size_t count, T value) - { - while (count) - { - multiset.insert(value++); - --count; - } - } - - template - inline void iota(std::size_t count, T value, OutputIterator out) - { - while (count) - { - (*out) = value++; - ++out; - --count; - } - } - - template class Sequence> - inline void iota(Sequence& sequence, const T& value) - { - strtk::iota(sequence.begin(),sequence.end(),value); - } - - template - inline void iota(std::set& set, const T& value) - { - strtk::iota(set.begin(),set.end(),value); - } - - template - inline void iota(std::multiset& multiset, const T& value) - { - strtk::iota(multiset.begin(),multiset.end(),value); - } - - template - inline void cut(const std::size_t& r0, const std::size_t& r1, - const InputIterator begin, InputIterator end, - OutputIterator out) - { - // static assert: InputIterator must be of type std::string - InputIterator itr = begin; - while (end != itr) - { - const std::string& s = (*itr); - ++itr; - if (s.size() < r0) - continue; - (*out++) = s.substr(r0,std::min(r1,s.size()) - r0); - } - } - - template class Sequence, - typename OutputIterator> - inline void cut(const std::size_t& r0, const std::size_t& r1, - const Sequence& sequence, - OutputIterator out) - { - cut(r0,r1,sequence.begin(),sequence.end(),out); - } - - template - inline void cut_inplace(const std::size_t& r0, const std::size_t& r1, - const Iterator begin, const Iterator end) - { - // static assert: InputIterator must be of type std::string - Iterator itr = begin; - while (end != itr) - { - if ((*itr).size() >= r0) - { - (*itr) = (*itr).substr(r0,std::min(r1,(*itr).size()) - r0); - } - ++itr; - } - } - - template class Sequence> - inline void cut(const std::size_t& r0, const std::size_t& r1, - const Sequence& sequence) - { - cut(r0,r1,sequence.begin(),sequence.end()); - } - - template - inline void cut(const std::size_t& r0, const std::size_t& r1, - const std::set& set) - { - cut(r0,r1,set.begin(),set.end()); - } - - template - inline void cut(const std::size_t& r0, const std::size_t& r1, - const std::multiset& multiset) - { - cut(r0,r1,multiset.begin(),multiset.end()); - } - - class translation_table - { - public: - - translation_table(const std::string& itable, const std::string& otable) - { - if (itable.size() != otable.size()) - { - throw std::runtime_error("translation_table() - Input/Output table size mismatch."); - } - strtk::iota(table_, table_ + 256, static_cast(0)); - for (std::size_t i = 0; i < itable.size(); ++i) - { - table_[static_cast(itable[i])] = static_cast(otable[i]); - } - } - - inline char operator()(const char c) const - { - return static_cast(table_[static_cast(c)]); - } - - inline unsigned char operator()(const unsigned char c) const - { - return static_cast(table_[static_cast(c)]); - } - - private: - - unsigned char table_[256]; - }; - - inline std::string translate(const translation_table& trans_table, const std::string& s) - { - std::string result = s; - std::transform(result.begin(),result.end(),result.begin(),trans_table); - return result; - } - - inline void translate_inplace(const translation_table& trans_table, std::string& s) - { - std::transform(s.begin(),s.end(),s.begin(),trans_table); - } - - #ifdef strtk_enable_random - inline void generate_random_data(unsigned char* data, - std::size_t length, - unsigned int pre_gen_cnt = 0, - unsigned int seed = magic_seed) - { - boost::mt19937 rng(static_cast(seed)); - boost::uniform_int dist(std::numeric_limits::min(),std::numeric_limits::max()); - boost::variate_generator > rnd(rng,dist); - - if (pre_gen_cnt > 0) - { - while (pre_gen_cnt--) rnd(); - } - - unsigned char* itr = data; - unsigned int* x = 0; - while (length >= sizeof(unsigned int)) - { - x = reinterpret_cast(itr); - (*x) = rnd(); - itr += sizeof(unsigned int); - length -= sizeof(unsigned int); - } - - if (length > 0) - { - itr -= (sizeof(unsigned int) - length); - x = reinterpret_cast(itr); - (*x) = rnd(); - } - } - - namespace details - { - struct rand_int_type_tag {}; - struct rand_real_type_tag {}; - - template struct supported_random_type {}; - - #define strtk_register_rand_int_type_tag(T) \ - template<> struct supported_random_type { typedef rand_int_type_tag type; enum { value = true }; }; - - #define strtk_register_rand_real_type_tag(T) \ - template<> struct supported_random_type { typedef rand_real_type_tag type; enum { value = true }; }; - - strtk_register_rand_int_type_tag(char) - strtk_register_rand_int_type_tag(unsigned char) - - strtk_register_rand_int_type_tag(short) - strtk_register_rand_int_type_tag(int) - strtk_register_rand_int_type_tag(long) - strtk_register_rand_int_type_tag(unsigned short) - strtk_register_rand_int_type_tag(unsigned int) - strtk_register_rand_int_type_tag(unsigned long) - - strtk_register_rand_real_type_tag(float) - strtk_register_rand_real_type_tag(double) - strtk_register_rand_real_type_tag(long double) - - #undef strtk_register_rand_int_type_tag - #undef strtk_register_rand_real_type_tag - - template - inline void generate_random_values_impl(const std::size_t& count, - const T& min, - const T& max, - OutputIterator out, - RandomNumberGenerator& rng, - rand_int_type_tag) - { - // Note: The implied range will be: [min,max] - using namespace boost; - variate_generator > rnd(rng,uniform_int(min,max)); - for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ; - } - - template - inline void generate_random_values_impl(const std::size_t& count, - const T& min, - const T& max, - OutputIterator out, - RandomNumberGenerator& rng, - rand_real_type_tag) - { - // Note: The implied range will be: [min,max) - using namespace boost; - variate_generator > rnd(rng,uniform_real(min,max)); - for (std::size_t i = 0; i < count; ++i, *out++ = rnd()) ; - } - - } // namespace details - - class uniform_real_rng - { - private: - - typedef boost::mt19937 rng_type; - typedef boost::variate_generator > variate_type; - - public: - - uniform_real_rng(const std::size_t& seed = magic_seed, - std::size_t pregen = 0) - : rng_(static_cast(seed)), - rnd_(rng_,boost::uniform_real(0.0,1.0)) - { - while (pregen--) rng_(); - } - - inline double operator()() - { - return rnd_(); - } - - private: - - rng_type rng_; - variate_type rnd_; - }; - - template - inline void generate_random_values(const std::size_t& count, - const T& min, - const T& max, - OutputIterator out, - const std::size_t& seed = magic_seed, - const std::size_t& pregen = 0) - { - typename details::supported_random_type::type type; - boost::mt19937 rng(static_cast(seed)); - for (std::size_t i = 0; i++ < pregen; rng()) ; - generate_random_values_impl(count,min,max,out,rng,type); - } - - template class Sequence> - inline void generate_random_values(const std::size_t& count, - const T& min, - const T& max, - Sequence& sequence, - const std::size_t& seed = magic_seed, - const std::size_t& pregen = 0) - { - typename details::supported_random_type::type type; - boost::mt19937 rng(static_cast(seed)); - for (std::size_t i = 0; i++ < pregen; rng()) ; - generate_random_values_impl(count,min,max,std::back_inserter(sequence),rng,type); - } - - template - inline void random_permutation(const Iterator begin, const Iterator end, - RandomNumberGenerator& rng, - OutputIterator out) - { - const std::size_t size = std::distance(begin,end); - if ((rng. min() < 0.0) || (rng.max() > 1.0)) return; - std::deque index; - for (std::size_t i = 0; i < size; index.push_back(i++)) ; - while (!index.empty()) - { - std::size_t idx = static_cast(index.size() * rng()); - (*out) = *(begin + index[idx]); - index.erase(index.begin() + idx); - ++out; - } - } - - template - inline void random_permutation(const Iterator begin, const Iterator end, - OutputIterator out, - const std::size_t& seed = magic_seed, - const std::size_t& pregen = 0) - { - boost::mt19937 rng(static_cast(seed)); - for (std::size_t i = 0; i++ < pregen; rng()) ; - boost::uniform_real dist(0.0,1.0); - boost::variate_generator > rnd(rng,dist); - random_permutation(begin,end,rnd,out); - } - - template class Sequence, - typename OutputIterator> - inline void random_permutation(const Sequence& sequence, - OutputIterator out, - const std::size_t& seed = magic_seed, - const std::size_t& pregen = 0) - { - random_permutation(sequence.begin(),sequence.end(),out,seed,pregen); - } - - template - inline bool random_combination(const Iterator begin, const Iterator end, - std::size_t set_size, - RandomNumberGenerator& rng, - OutputIterator out) - { - const std::size_t size = std::distance(begin,end); - if ((size < set_size) || (rng. min() < 0.0) || (rng.max() > 1.0)) return false; - std::deque index; - for (std::size_t i = 0; i < size; index.push_back(i++)) ; - while (set_size) - { - std::size_t idx = static_cast(index.size() * rng()); - (*out) = *(begin + index[idx]); - index.erase(index.begin() + idx); - ++out; - --set_size; - } - return true; - } - - template - inline void random_combination(const Iterator begin, const Iterator end, - const std::size_t& set_size, - OutputIterator out, - const std::size_t& seed = magic_seed, - const std::size_t& pregen = 0) - { - boost::mt19937 rng(static_cast(seed)); - for (std::size_t i = 0; i++ < pregen; rng()) ; - boost::uniform_real dist(0.0,1.0); - boost::variate_generator > rnd(rng,dist); - random_combination(begin,end,set_size,rnd,out); - } - - template class Sequence, - typename OutputIterator> - inline void random_combination(const Sequence& sequence, - const std::size_t& set_size, - OutputIterator out, - const std::size_t& seed = magic_seed, - const std::size_t& pregen = 0) - { - random_combination(sequence.begin(),sequence.end(),set_size,out,seed,pregen); - } - - template - inline std::size_t select_k_randomly(const Iterator begin, const Iterator end, - const std::size_t k, - OutputIterator out, - RandomNumberGenerator& rng) - { - typedef typename std::iterator_traits::value_type T; - std::vector selection; - selection.resize(k); - Iterator itr = begin; - std::size_t index = 0; - while ((index < k) && (end != itr)) - { - selection[index] = (*itr); - ++index; - ++itr; - } - if (0 == index) - return 0; - else if (index < k) - { - std::copy(selection.begin(),selection.begin() + index, out); - return index; - } - double n = k + 1; - while (end != itr) - { - if (rng() < (k / n)) - { - selection[static_cast(rng() * k)] = (*itr); - } - ++itr; - ++n; - } - std::copy(selection.begin(),selection.end(),out); - return k; - } - - template - inline void select_1_randomly(const Iterator begin, const Iterator end, - OutputIterator out, - RandomNumberGenerator& rng) - { - typedef typename std::iterator_traits::value_type T; - T selection; - if (begin == end) - return; - Iterator itr = begin; - std::size_t n = 0; - while (end != itr) - { - if (rng() < (1.0 / ++n)) - { - selection = (*itr); - } - ++itr; - } - (*out) = selection; - ++out; - } - #endif // strtk_enable_random - - template - inline bool next_combination(const Iterator first, Iterator k, const Iterator last) - { - /* Credits: Thomas Draper */ - if ((first == last) || (first == k) || (last == k)) - return false; - Iterator itr1 = first; - Iterator itr2 = last; - ++itr1; - if (last == itr1) - return false; - itr1 = last; - --itr1; - itr1 = k; - --itr2; - while (first != itr1) - { - if (*--itr1 < (*itr2)) - { - Iterator j = k; - while (!((*itr1) < (*j))) ++j; - std::iter_swap(itr1,j); - ++itr1; - ++j; - itr2 = k; - std::rotate(itr1,j,last); - while (last != j) - { - ++j; - ++itr2; - } - std::rotate(k,itr2,last); - return true; - } - } - std::rotate(first,k,last); - return false; - } - - template class Sequence> - inline bool next_combination(Sequence& sequence, const std::size_t& size) - { - return next_combination(sequence.begin(), sequence.begin() + size, sequence.end()); - } - - template - inline void for_each_permutation(Iterator begin, Iterator end, Function function) - { - do - { - function(begin,end); - } - while (std::next_permutation(begin,end)); - } - - template - inline bool for_each_permutation_conditional(Iterator begin, Iterator end, Function function) - { - do - { - if (!function(begin,end)) - return false; - } - while (std::next_permutation(begin,end)); - return true; - } - - namespace details - { - /* - Credits: - (C) Copyright Howard Hinnant 2005-2011. - Use, modification and distribution are subject to the Boost Software License, - Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at - http://www.boost.org/LICENSE_1_0.txt). - */ - template - static inline void rotate_discontinuous(Iterator first1, Iterator last1, - typename std::iterator_traits::difference_type d1, - Iterator first2, Iterator last2, - typename std::iterator_traits::difference_type d2) - { - using std::swap; - if (d1 <= d2) - std::rotate(first2, std::swap_ranges(first1, last1, first2), last2); - else - { - Iterator i1 = last1; - while (first2 != last2) - { - swap(*--i1,*--last2); - } - std::rotate(first1, i1, last1); - } - } - - template - inline void combine_discontinuous(Iterator first1, Iterator last1, typename std::iterator_traits::difference_type d1, - Iterator first2, Iterator last2, typename std::iterator_traits::difference_type d2, - Function& f, - typename std::iterator_traits::difference_type d = 0) - { - typedef typename std::iterator_traits::difference_type D; - using std::swap; - if ((0 == d1) || (0 == d2)) - return f(); - if (1 == d1) - { - Iterator i2 = first2; - while (i2 != last2) - { - f(); - swap(*first1, *i2); - ++i2; - } - } - else - { - Iterator f1p = first1; - std::advance(f1p,1); - Iterator i2 = first2; - D d22 = d2; - while (i2 != last2) - { - combine_discontinuous(f1p, last1, d1 - 1, i2, last2, d22, f, d + 1); - swap(*first1, *i2); - ++i2; - --d22; - } - } - f(); - if (0 != d) - { - Iterator f2p = first2; - std::advance(f2p,1); - rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1); - } - else - rotate_discontinuous(first1, last1, d1, first2, last2, d2); - } - - template - inline bool combine_discontinuous_conditional(Iterator first1, Iterator last1, typename std::iterator_traits::difference_type d1, - Iterator first2, Iterator last2, typename std::iterator_traits::difference_type d2, - Function& f, - typename std::iterator_traits::difference_type d = 0) - { - typedef typename std::iterator_traits::difference_type D; - using std::swap; - if (d1 == 0 || d2 == 0) - return f(); - if (d1 == 1) - { - for (Iterator i2 = first2; i2 != last2; ++i2) - { - if (!f()) - return false; - swap(*first1, *i2); - } - } - else - { - Iterator f1p = first1; - std::advance(f1p,1); - Iterator i2 = first2; - for (D d22 = d2; i2 != last2; ++i2, --d22) - { - if (!combine_discontinuous_conditional(f1p, last1, d1-1, i2, last2, d22, f, d + 1)) - return false; - swap(*first1, *i2); - } - } - if (!f()) - return false; - if (d != 0) - { - Iterator f2p = first2; - std::advance(f2p,1); - rotate_discontinuous(first1, last1, d1, f2p, last2, d2 - 1); - } - else - rotate_discontinuous(first1, last1, d1, first2, last2, d2); - return true; - } - - template - class bound_range - { - public: - - bound_range(Function f, Iterator first, Iterator last) - : f_(f), - first_(first), - last_(last) - {} - - inline void operator()() - { - f_(first_,last_); - } - - private: - - inline bound_range& operator=(const bound_range&); - - Function f_; - Iterator first_; - Iterator last_; - }; - - template - class bound_range_conditional - { - public: - - bound_range_conditional(Function f, Iterator first, Iterator last) - : f_(f), - first_(first), - last_(last) - {} - - inline bool operator()() - { - return f_(first_,last_); - } - - private: - - inline bound_range_conditional& operator=(const bound_range_conditional&); - - Function f_; - Iterator first_; - Iterator last_; - }; - - } - - template - inline void for_each_combination(Iterator begin, Iterator end, - const std::size_t& size, - Function function) - { - if (static_cast::difference_type>(size) > std::distance(begin,end)) - return; - Iterator mid = begin + size; - details::bound_range func(function,begin,mid); - details::combine_discontinuous(begin, mid, - std::distance(begin,mid), - mid, end, - std::distance(mid,end), - func); - } - - template - inline void for_each_combination_conditional(Iterator begin, Iterator end, - const std::size_t& size, - Function function) - { - if (static_cast::difference_type>(size) > std::distance(begin,end)) - return; - Iterator mid = begin + size; - details::bound_range_conditional func(function,begin,mid); - details::combine_discontinuous_conditional(begin, mid, - std::distance(begin,mid), - mid, end, - std::distance(mid,end), - func); - } - - inline unsigned long long int n_choose_k(const unsigned long long int& n, const unsigned long long int& k) - { - if (n < k) return 0; - if (0 == n) return 0; - if (0 == k) return 1; - if (n == k) return 1; - if (1 == k) return n; - - typedef unsigned long long int value_type; - - class n_choose_k_impl - { - public: - - n_choose_k_impl(value_type* table, const value_type& dimension) - : table_(table), - dimension_(dimension / 2) - {} - - inline value_type& lookup(const value_type& n, const value_type& k) - { - const std::size_t difference = static_cast(n - k); - return table_[static_cast((dimension_ * n) + std::min(k,difference))]; - } - - inline value_type compute(const value_type& n, const value_type& k) - { - // n-Choose-k = (n-1)-Choose-(k-1) + (n-1)-Choose-k - if ((0 == k) || (k == n)) - return 1; - value_type v1 = lookup(n - 1,k - 1); - if (0 == v1) - v1 = lookup(n - 1,k - 1) = compute(n - 1,k - 1); - value_type v2 = lookup(n - 1,k); - if (0 == v2) - v2 = lookup(n - 1,k) = compute(n - 1,k); - return v1 + v2; - } - - value_type* table_; - const value_type dimension_; - - private: - - inline n_choose_k_impl& operator=(const n_choose_k_impl&) - { - return *this; - } - }; - - static const std::size_t static_table_dim = 100; - static const std::size_t static_table_size = static_cast((static_table_dim * static_table_dim) / 2); - static value_type static_table[static_table_size]; - static bool static_table_initialized = false; - - if (!static_table_initialized && (n <= static_table_dim)) - { - std::fill_n(static_table,static_table_size,0); - static_table_initialized = true; - } - - const std::size_t table_size = static_cast(n * (n / 2) + (n & 1)); - - unsigned long long int dimension = static_table_dim; - value_type* table = 0; - - if (table_size <= static_table_size) - table = static_table; - else - { - dimension = n; - table = new value_type[table_size]; - std::fill_n(table,table_size,0ULL); - } - - value_type result = n_choose_k_impl(table,dimension).compute(n,k); - - if (table != static_table) - delete [] table; - - return result; - } - - inline void initialize_n_choose_k() - { - const unsigned long long int max_n = 100ULL; - for (unsigned long long int n = 0; n < max_n; ++n) - { - for (unsigned long long int k = 0; k < max_n; ++k) - { - n_choose_k(n,k); - } - } - } - - template - inline void nth_combination_sequence(unsigned long long int n, - const std::size_t& r, - const std::size_t& k, - OutputIterator out, - const bool complete_index = true) - { - //Compute the indicies for the n'th combination of r-choose-k - //n must be in the range [0,r-choose-k) - typedef unsigned long long int value_type; - - std::vector index_list(k,0); - value_type j = 0; - value_type x = 0; - ++n; - - for (std::size_t i = 1; i <= (k - 1); ++i) - { - index_list[i - 1] = 0; - if (1 < i) - { - index_list[i - 1] = index_list[i - 2]; - } - - do - { - index_list[i - 1] += 1; - j = n_choose_k(r - index_list[i - 1], k - i); - x += j; - } - while (n > x); - x -= j; - } - - index_list[k - 1] = index_list[k - 2] + static_cast(n) - static_cast(x); - for (std::size_t i = 0; i < index_list.size(); --index_list[i++]); - - std::copy(index_list.begin(),index_list.end(),out); - - if (complete_index) - { - std::vector exist_table(r,0); - - for (std::size_t i = 0; i < index_list.size(); ++i) - { - exist_table[index_list[i]] = 1; - } - - for (std::size_t i = 0; i < exist_table.size(); ++i) - { - if (0 == exist_table[i]) - { - (*out) = i; - ++out; - } - } - } - } - - template - inline void nth_combination_sequence(const std::size_t& n, - const std::size_t& k, - const InputIterator begin, - const InputIterator end, - OutputIterator out, - const bool complete_index = true) - { - const std::size_t length = std::distance(begin,end); - std::vector index_list; - nth_combination_sequence(n,length,k,std::back_inserter(index_list),complete_index); - for (std::size_t i = 0; i < index_list.size(); ++i) - { - (*out) = *(begin + index_list[i]); - ++out; - } - } - - template - inline void nth_permutation_sequence(std::size_t n, const std::size_t k, OutputIterator out) - { - //Note: n in [0,k!) - std::vector factorid (k,0); - std::vector permutate(k,0); - - factorid[0] = 1; - for (std::size_t i = 1; i < k; ++i) - { - factorid[i] = factorid[i - 1] * i; - } - - for (std::size_t i = 0; i < k; ++i) - { - permutate[i] = n / factorid[k - i - 1]; - n = n % factorid[k - i - 1]; - } - - for (std::size_t i = k - 1; i > 0; --i) - { - for (int j = static_cast(i - 1); j >= 0; --j) - { - if (permutate[j] <= permutate[i]) - { - ++permutate[i]; - } - } - } - - for (std::size_t i = 0; i < k; ++i) - { - *(out++) = permutate[i]; - } - } - - template - inline void nth_permutation_sequence(std::size_t n, - const InputIterator begin, - const InputIterator end, - OutputIterator out) - { - const std::size_t size = std::distance(begin,end); - std::vector index_list(size,0); - nth_permutation_sequence(n,size,index_list.begin()); - for (std::size_t i = 0; i < size; ++i) - { - *(out++) = (begin + index_list[i]); - } - } - - inline std::string nth_permutation_sequence(const std::size_t& n, const std::string& s) - { - std::vector index_list(s.size(),0); - nth_permutation_sequence(n,s.size(),index_list.begin()); - std::string result; - result.reserve(s.size()); - for (std::size_t i = 0; i < index_list.size(); ++i) - { - result += s[index_list[i]]; - } - return result; - } - - template - class combination_iterator : public std::iterator, - void, - void> - { - public: - - typedef Iterator iterator; - typedef const iterator const_iterator; - typedef std::pair range_type; - - explicit inline combination_iterator(const std::size_t& k, - iterator begin, iterator end, - const bool sorted = true) - : begin_(begin), - end_(end), - middle_(begin + k), - current_combination_(begin_,middle_) - { - if (!sorted) - { - std::sort(begin,end); - } - } - - template class Sequence> - explicit inline combination_iterator(const std::size_t& k, - Sequence& seq, - const bool sorted = true) - : begin_(seq.begin()), - end_(seq.end()), - middle_(begin_ + k), - current_combination_(begin_,middle_) - { - if (!sorted) - { - std::sort(begin_,end_); - } - } - - explicit inline combination_iterator(const std::size_t& k, - std::string& str, - const bool sorted = true) - : begin_(const_cast(str.data())), - end_(const_cast(str.data() + str.size())), - middle_(begin_ + k), - current_combination_(begin_,middle_) - { - if (!sorted) - { - std::sort(begin_,end_); - } - } - - inline combination_iterator(iterator end) - : begin_(end), - end_(end), - middle_(end), - current_combination_(end,end) - {} - - inline combination_iterator(const std::string& str) - : begin_(const_cast(str.data() + str.size())), - end_(begin_), - middle_(end_), - current_combination_(end_,end_) - {} - - template class Sequence> - explicit inline combination_iterator(Sequence& seq) - : begin_(seq.end()), - end_(seq.end()), - middle_(end_), - current_combination_(end_,end_) - {} - - inline combination_iterator& operator++() - { - if (begin_ != end_) - { - if (!next_combination(begin_,middle_,end_)) - { - begin_ = middle_ = end_; - } - } - return (*this); - } - - inline combination_iterator operator++(int) - { - combination_iterator tmp = *this; - this->operator++(); - return tmp; - } - - inline combination_iterator& operator+=(const int inc) - { - if (inc > 0) - { - for (int i = 0; i < inc; ++i, ++(*this)) ; - } - return (*this); - } - - inline range_type operator*() const - { - return current_combination_; - } - - inline bool operator==(const combination_iterator& itr) const - { - return (begin_ == itr.begin_ ) && - (end_ == itr.end_ ) && - (middle_ == itr.middle_); - } - - inline bool operator!=(const combination_iterator& itr) const - { - return !operator==(itr); - } - - protected: - - iterator begin_; - iterator end_; - iterator middle_; - range_type current_combination_; - }; - - namespace fast - { - /* - Note: The following routines perform no sanity checks at all - upon the input data. Hence they should only be used with - data that is known to be completely 'valid'. - */ - namespace details - { - - template - struct all_digits_check_impl - { - static inline bool process(Iterator) - { - throw std::runtime_error("all_digits_check_impl - unsupported value for N."); - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - all_digits_check_impl::process(itr + 1); - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - all_digits_check_impl::process(itr + 1); - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - all_digits_check_impl::process(itr + 1); - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10 && - static_cast(itr[ 2] - '0') < 10 && - static_cast(itr[ 3] - '0') < 10 && - static_cast(itr[ 4] - '0') < 10 && - static_cast(itr[ 5] - '0') < 10 && - static_cast(itr[ 6] - '0') < 10 && - static_cast(itr[ 7] - '0') < 10 && - static_cast(itr[ 8] - '0') < 10 && - static_cast(itr[ 9] - '0') < 10 && - static_cast(itr[10] - '0') < 10 && - static_cast(itr[11] - '0') < 10 && - static_cast(itr[12] - '0') < 10 && - static_cast(itr[13] - '0') < 10 && - static_cast(itr[14] - '0') < 10 && - static_cast(itr[15] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10 && - static_cast(itr[ 2] - '0') < 10 && - static_cast(itr[ 3] - '0') < 10 && - static_cast(itr[ 4] - '0') < 10 && - static_cast(itr[ 5] - '0') < 10 && - static_cast(itr[ 6] - '0') < 10 && - static_cast(itr[ 7] - '0') < 10 && - static_cast(itr[ 8] - '0') < 10 && - static_cast(itr[ 9] - '0') < 10 && - static_cast(itr[10] - '0') < 10 && - static_cast(itr[11] - '0') < 10 && - static_cast(itr[12] - '0') < 10 && - static_cast(itr[13] - '0') < 10 && - static_cast(itr[14] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10 && - static_cast(itr[ 2] - '0') < 10 && - static_cast(itr[ 3] - '0') < 10 && - static_cast(itr[ 4] - '0') < 10 && - static_cast(itr[ 5] - '0') < 10 && - static_cast(itr[ 6] - '0') < 10 && - static_cast(itr[ 7] - '0') < 10 && - static_cast(itr[ 8] - '0') < 10 && - static_cast(itr[ 9] - '0') < 10 && - static_cast(itr[10] - '0') < 10 && - static_cast(itr[11] - '0') < 10 && - static_cast(itr[12] - '0') < 10 && - static_cast(itr[13] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10 && - static_cast(itr[ 2] - '0') < 10 && - static_cast(itr[ 3] - '0') < 10 && - static_cast(itr[ 4] - '0') < 10 && - static_cast(itr[ 5] - '0') < 10 && - static_cast(itr[ 6] - '0') < 10 && - static_cast(itr[ 7] - '0') < 10 && - static_cast(itr[ 8] - '0') < 10 && - static_cast(itr[ 9] - '0') < 10 && - static_cast(itr[10] - '0') < 10 && - static_cast(itr[11] - '0') < 10 && - static_cast(itr[12] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10 && - static_cast(itr[ 2] - '0') < 10 && - static_cast(itr[ 3] - '0') < 10 && - static_cast(itr[ 4] - '0') < 10 && - static_cast(itr[ 5] - '0') < 10 && - static_cast(itr[ 6] - '0') < 10 && - static_cast(itr[ 7] - '0') < 10 && - static_cast(itr[ 8] - '0') < 10 && - static_cast(itr[ 9] - '0') < 10 && - static_cast(itr[10] - '0') < 10 && - static_cast(itr[11] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10 && - static_cast(itr[ 2] - '0') < 10 && - static_cast(itr[ 3] - '0') < 10 && - static_cast(itr[ 4] - '0') < 10 && - static_cast(itr[ 5] - '0') < 10 && - static_cast(itr[ 6] - '0') < 10 && - static_cast(itr[ 7] - '0') < 10 && - static_cast(itr[ 8] - '0') < 10 && - static_cast(itr[ 9] - '0') < 10 && - static_cast(itr[10] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10 && - static_cast(itr[4] - '0') < 10 && - static_cast(itr[5] - '0') < 10 && - static_cast(itr[6] - '0') < 10 && - static_cast(itr[7] - '0') < 10 && - static_cast(itr[8] - '0') < 10 && - static_cast(itr[9] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10 && - static_cast(itr[4] - '0') < 10 && - static_cast(itr[5] - '0') < 10 && - static_cast(itr[6] - '0') < 10 && - static_cast(itr[7] - '0') < 10 && - static_cast(itr[8] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10 && - static_cast(itr[4] - '0') < 10 && - static_cast(itr[5] - '0') < 10 && - static_cast(itr[6] - '0') < 10 && - static_cast(itr[7] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10 && - static_cast(itr[4] - '0') < 10 && - static_cast(itr[5] - '0') < 10 && - static_cast(itr[6] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10 && - static_cast(itr[4] - '0') < 10 && - static_cast(itr[5] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10 && - static_cast(itr[4] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10 && - static_cast(itr[3] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return - static_cast(itr[0] - '0') < 10 && - static_cast(itr[1] - '0') < 10 && - static_cast(itr[2] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10 && - static_cast(itr[ 1] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator itr) - { - return static_cast(itr[ 0] - '0') < 10; - } - }; - - template - struct all_digits_check_impl - { - static inline bool process(Iterator) - { - return false; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator, T&) - { throw std::runtime_error("numeric_convert_impl::process( - unsupported value for N."); } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - strtk::fast::details::numeric_convert_impl::process(itr + 1,t); - t += static_cast((itr[0] - '0') * 1000000000000000000LL); - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - strtk::fast::details::numeric_convert_impl::process(itr + 1,t); - t += static_cast((itr[0] - '0') * 100000000000000000LL); - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - numeric_convert_impl::process(itr + 1,t); - t += static_cast((itr[0] - '0') * 10000000000000000LL); - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[ 0] - '0') * 1000000000000000LL); - x += static_cast((itr[ 1] - '0') * 100000000000000LL); - x += static_cast((itr[ 2] - '0') * 10000000000000LL); - x += static_cast((itr[ 3] - '0') * 1000000000000LL); - x += static_cast((itr[ 4] - '0') * 100000000000LL); - x += static_cast((itr[ 5] - '0') * 10000000000LL); - x += static_cast((itr[ 6] - '0') * 1000000000LL); - x += static_cast((itr[ 7] - '0') * 100000000LL); - x += static_cast((itr[ 8] - '0') * 10000000LL); - x += static_cast((itr[ 9] - '0') * 1000000LL); - x += static_cast((itr[10] - '0') * 100000LL); - x += static_cast((itr[11] - '0') * 10000LL); - x += static_cast((itr[12] - '0') * 1000LL); - x += static_cast((itr[13] - '0') * 100LL); - x += static_cast((itr[14] - '0') * 10LL); - x += static_cast((itr[15] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[ 0] - '0') * 100000000000000LL); - x += static_cast((itr[ 1] - '0') * 10000000000000LL); - x += static_cast((itr[ 2] - '0') * 1000000000000LL); - x += static_cast((itr[ 3] - '0') * 100000000000LL); - x += static_cast((itr[ 4] - '0') * 10000000000LL); - x += static_cast((itr[ 5] - '0') * 1000000000LL); - x += static_cast((itr[ 6] - '0') * 100000000LL); - x += static_cast((itr[ 7] - '0') * 10000000LL); - x += static_cast((itr[ 8] - '0') * 1000000LL); - x += static_cast((itr[ 9] - '0') * 100000LL); - x += static_cast((itr[10] - '0') * 10000LL); - x += static_cast((itr[11] - '0') * 1000LL); - x += static_cast((itr[12] - '0') * 100LL); - x += static_cast((itr[13] - '0') * 10LL); - x += static_cast((itr[14] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[ 0] - '0') * 10000000000000LL); - x += static_cast((itr[ 1] - '0') * 1000000000000LL); - x += static_cast((itr[ 2] - '0') * 100000000000LL); - x += static_cast((itr[ 3] - '0') * 10000000000LL); - x += static_cast((itr[ 4] - '0') * 1000000000LL); - x += static_cast((itr[ 5] - '0') * 100000000LL); - x += static_cast((itr[ 6] - '0') * 10000000LL); - x += static_cast((itr[ 7] - '0') * 1000000LL); - x += static_cast((itr[ 8] - '0') * 100000LL); - x += static_cast((itr[ 9] - '0') * 10000LL); - x += static_cast((itr[10] - '0') * 1000LL); - x += static_cast((itr[11] - '0') * 100LL); - x += static_cast((itr[12] - '0') * 10LL); - x += static_cast((itr[13] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[ 0] - '0') * 1000000000000LL); - x += static_cast((itr[ 1] - '0') * 100000000000LL); - x += static_cast((itr[ 2] - '0') * 10000000000LL); - x += static_cast((itr[ 3] - '0') * 1000000000LL); - x += static_cast((itr[ 4] - '0') * 100000000LL); - x += static_cast((itr[ 5] - '0') * 10000000LL); - x += static_cast((itr[ 6] - '0') * 1000000LL); - x += static_cast((itr[ 7] - '0') * 100000LL); - x += static_cast((itr[ 8] - '0') * 10000LL); - x += static_cast((itr[ 9] - '0') * 1000LL); - x += static_cast((itr[10] - '0') * 100LL); - x += static_cast((itr[11] - '0') * 10LL); - x += static_cast((itr[12] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[ 0] - '0') * 100000000000LL); - x += static_cast((itr[ 1] - '0') * 10000000000LL); - x += static_cast((itr[ 2] - '0') * 1000000000LL); - x += static_cast((itr[ 3] - '0') * 100000000LL); - x += static_cast((itr[ 4] - '0') * 10000000LL); - x += static_cast((itr[ 5] - '0') * 1000000LL); - x += static_cast((itr[ 6] - '0') * 100000LL); - x += static_cast((itr[ 7] - '0') * 10000LL); - x += static_cast((itr[ 8] - '0') * 1000LL); - x += static_cast((itr[ 9] - '0') * 100LL); - x += static_cast((itr[10] - '0') * 10LL); - x += static_cast((itr[11] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[ 0] - '0') * 10000000000LL); - x += static_cast((itr[ 1] - '0') * 1000000000LL); - x += static_cast((itr[ 2] - '0') * 100000000LL); - x += static_cast((itr[ 3] - '0') * 10000000LL); - x += static_cast((itr[ 4] - '0') * 1000000LL); - x += static_cast((itr[ 5] - '0') * 100000LL); - x += static_cast((itr[ 6] - '0') * 10000LL); - x += static_cast((itr[ 7] - '0') * 1000LL); - x += static_cast((itr[ 8] - '0') * 100LL); - x += static_cast((itr[ 9] - '0') * 10LL); - x += static_cast((itr[10] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 1000000000); - x += static_cast((itr[1] - '0') * 100000000); - x += static_cast((itr[2] - '0') * 10000000); - x += static_cast((itr[3] - '0') * 1000000); - x += static_cast((itr[4] - '0') * 100000); - x += static_cast((itr[5] - '0') * 10000); - x += static_cast((itr[6] - '0') * 1000); - x += static_cast((itr[7] - '0') * 100); - x += static_cast((itr[8] - '0') * 10); - x += static_cast((itr[9] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 100000000); - x += static_cast((itr[1] - '0') * 10000000); - x += static_cast((itr[2] - '0') * 1000000); - x += static_cast((itr[3] - '0') * 100000); - x += static_cast((itr[4] - '0') * 10000); - x += static_cast((itr[5] - '0') * 1000); - x += static_cast((itr[6] - '0') * 100); - x += static_cast((itr[7] - '0') * 10); - x += static_cast((itr[8] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 10000000); - x += static_cast((itr[1] - '0') * 1000000); - x += static_cast((itr[2] - '0') * 100000); - x += static_cast((itr[3] - '0') * 10000); - x += static_cast((itr[4] - '0') * 1000); - x += static_cast((itr[5] - '0') * 100); - x += static_cast((itr[6] - '0') * 10); - x += static_cast((itr[7] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 1000000); - x += static_cast((itr[1] - '0') * 100000); - x += static_cast((itr[2] - '0') * 10000); - x += static_cast((itr[3] - '0') * 1000); - x += static_cast((itr[4] - '0') * 100); - x += static_cast((itr[5] - '0') * 10); - x += static_cast((itr[6] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 100000); - x += static_cast((itr[1] - '0') * 10000); - x += static_cast((itr[2] - '0') * 1000); - x += static_cast((itr[3] - '0') * 100); - x += static_cast((itr[4] - '0') * 10); - x += static_cast((itr[5] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 10000); - x += static_cast((itr[1] - '0') * 1000); - x += static_cast((itr[2] - '0') * 100); - x += static_cast((itr[3] - '0') * 10); - x += static_cast((itr[4] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 1000); - x += static_cast((itr[1] - '0') * 100); - x += static_cast((itr[2] - '0') * 10); - x += static_cast((itr[3] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 100); - x += static_cast((itr[1] - '0') * 10); - x += static_cast((itr[2] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - T x = static_cast((itr[0] - '0') * 10); - x += static_cast((itr[1] - '0') ); - t = x; - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator itr, T& t) - { - t = static_cast((itr[0] - '0')); - } - }; - - template - struct numeric_convert_impl - { - static inline void process(Iterator, T& t) - { - t = 0; - } - }; - - template - inline bool negate(T&, NoneSignedTag) - { - return false; - } - - template - inline bool negate(T& t, strtk::details::signed_type_tag) - { - t = -t; - return true; - } - - } // namespace details - - template - inline bool all_digits_check(Iterator itr) - { - typedef typename strtk::details::is_valid_iterator::type itr_type; - strtk::details::convert_type_assert(); - return details::all_digits_check_impl::process(itr); - } - - template - inline bool all_digits_check(const std::string& s) - { - return all_digits_check(s.data()); - } - - template - inline bool all_digits_check(const std::size_t& n, Iterator itr) - { - switch (n) - { - case 0 : return details::all_digits_check_impl::process(itr); - case 1 : return details::all_digits_check_impl::process(itr); - case 2 : return details::all_digits_check_impl::process(itr); - case 3 : return details::all_digits_check_impl::process(itr); - case 4 : return details::all_digits_check_impl::process(itr); - case 5 : return details::all_digits_check_impl::process(itr); - case 6 : return details::all_digits_check_impl::process(itr); - case 7 : return details::all_digits_check_impl::process(itr); - case 8 : return details::all_digits_check_impl::process(itr); - case 9 : return details::all_digits_check_impl::process(itr); - case 10 : return details::all_digits_check_impl::process(itr); - case 11 : return details::all_digits_check_impl::process(itr); - case 12 : return details::all_digits_check_impl::process(itr); - case 13 : return details::all_digits_check_impl::process(itr); - case 14 : return details::all_digits_check_impl::process(itr); - case 15 : return details::all_digits_check_impl::process(itr); - case 16 : return details::all_digits_check_impl::process(itr); - case 17 : return details::all_digits_check_impl::process(itr); - case 18 : return details::all_digits_check_impl::process(itr); - case 19 : return details::all_digits_check_impl::process(itr); - default : return false; - } - } - - template - inline bool all_digits_check(Iterator begin, Iterator end) - { - return all_digits_check(std::distance(begin,end),begin); - } - - inline bool all_digits_check(const std::string& s) - { - return all_digits_check(s.size(),s.data()); - } - - template - inline bool signed_all_digits_check(Iterator itr) - { - if (('-' == (*itr)) || ('+' == (*itr))) - return all_digits_check((itr + 1)); - else - return all_digits_check(itr); - } - - template - inline bool signed_all_digits_check(const std::size_t& n, Iterator itr) - { - if (('-' == (*itr)) || ('+' == (*itr))) - return all_digits_check(n - 1,(itr + 1)); - else - return all_digits_check(n,itr); - } - - template - inline bool signed_all_digits_check(const std::string& s) - { - return signed_all_digits_check(s.data()); - } - - template - inline bool signed_all_digits_check(Iterator begin, Iterator end) - { - return signed_all_digits_check(std::distance(begin,end),begin); - } - - inline bool signed_all_digits_check(const std::string& s) - { - return signed_all_digits_check(s.size(),s.data()); - } - - template - inline void numeric_convert(Iterator itr, T& t, const bool digit_check = false) - { - typedef typename strtk::details::is_valid_iterator::type itr_type; - strtk::details::convert_type_assert(); - if (digit_check) - { - if (!all_digits_check(itr)) - { - t = 0; - return; - } - } - - details::numeric_convert_impl::process(itr,t); - } - - template - inline void numeric_convert(const std::string& s, T& t, const bool digit_check = false) - { - numeric_convert(s.data(),t,digit_check); - } - - template - inline bool numeric_convert(const std::size_t& n, - Iterator itr, T& t, - const bool digit_check = false) - { - if (digit_check) - { - if (!all_digits_check(n,itr)) - { - return false; - } - } - - switch (n) - { - case 0 : details::numeric_convert_impl::process(itr,t); return true; - case 1 : details::numeric_convert_impl::process(itr,t); return true; - case 2 : details::numeric_convert_impl::process(itr,t); return true; - case 3 : details::numeric_convert_impl::process(itr,t); return true; - case 4 : details::numeric_convert_impl::process(itr,t); return true; - case 5 : details::numeric_convert_impl::process(itr,t); return true; - case 6 : details::numeric_convert_impl::process(itr,t); return true; - case 7 : details::numeric_convert_impl::process(itr,t); return true; - case 8 : details::numeric_convert_impl::process(itr,t); return true; - case 9 : details::numeric_convert_impl::process(itr,t); return true; - case 10 : details::numeric_convert_impl::process(itr,t); return true; - case 11 : details::numeric_convert_impl::process(itr,t); return true; - case 12 : details::numeric_convert_impl::process(itr,t); return true; - case 13 : details::numeric_convert_impl::process(itr,t); return true; - case 14 : details::numeric_convert_impl::process(itr,t); return true; - case 15 : details::numeric_convert_impl::process(itr,t); return true; - case 16 : details::numeric_convert_impl::process(itr,t); return true; - case 17 : details::numeric_convert_impl::process(itr,t); return true; - case 18 : details::numeric_convert_impl::process(itr,t); return true; - case 19 : details::numeric_convert_impl::process(itr,t); return true; - default : return false; - } - } - - template - inline void numeric_convert(const std::string& s, T& t, const bool digit_check = false) - { - numeric_convert(s.size(),s.data(),t,digit_check); - } - - template - inline void signed_numeric_convert(Iterator itr, T& t, const bool digit_check = false) - { - if ('-' == (*itr)) - { - numeric_convert((itr + 1),t,digit_check); - typename strtk::details::supported_conversion_to_type::type type; - details::negate(t,type); - } - else if ('+' == (*itr)) - { - numeric_convert((itr + 1),t,digit_check); - } - else - numeric_convert(itr,t,digit_check); - } - - template - inline bool signed_numeric_convert(const std::size_t& n, - Iterator itr, - T& t, - const bool digit_check = false) - { - if ('-' == (*itr)) - { - bool result = numeric_convert((n - 1),(itr + 1),t,digit_check); - typename strtk::details::supported_conversion_to_type::type type; - return details::negate(t,type) && result; - } - else if ('+' == (*itr)) - { - return numeric_convert((n - 1),(itr + 1),t,digit_check); - } - else - return numeric_convert(n,itr,t,digit_check); - } - - template - inline void signed_numeric_convert(const std::string& s, - T& t, - const bool digit_check = false) - { - signed_numeric_convert(s.data(),t,digit_check); - } - - template - inline bool signed_numeric_convert(const std::string& s, - T& t, - const bool digit_check = false) - { - return signed_numeric_convert(s.size(),s.data(),t,digit_check); - } - - } // namespace fast - - namespace binary - { - - namespace details - { - namespace details_endian - { - #if (defined(__LITTLE_ENDIAN__)) ||\ - (defined(WIN32)) ||\ - (defined(__MINGW32_VERSION)) ||\ - (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) - static const bool __le_result = true; - static const bool __be_result = false; - #else - static const bool __le_result = false; - static const bool __be_result = true; - #endif - } - - static inline bool is_little_endian() - { - //Is the current architecture/platform little-endian? - return details_endian::__le_result; - } - - static inline bool is_big_endian() - { - return details_endian::__be_result; - } - - static inline unsigned short convert(const unsigned short v) - { - //static_assert(2 == sizeof(v),""); - return ((v >> 8) & 0x00FF) | ((v << 8) & 0xFFFF); - } - - static inline unsigned int convert(const unsigned int v) - { - //static_assert(4 == sizeof(v),""); - return ((v >> 24) & 0x000000FF) | ((v << 24) & 0x0000FF00) | - ((v << 8) & 0x00FF0000) | ((v >> 8) & 0xFF000000); - } - - static inline unsigned long long int convert(const unsigned long long int v) - { - //static_assert(8 == sizeof(v),""); - return ((v >> 56) & 0x00000000000000FFLL) | ((v << 56) & 0xFF00000000000000LL) | - ((v >> 40) & 0x000000000000FF00LL) | ((v << 40) & 0x00FF000000000000LL) | - ((v >> 24) & 0x0000000000FF0000LL) | ((v << 24) & 0x0000FF0000000000LL) | - ((v >> 8) & 0x00000000FF000000LL) | ((v << 8) & 0x000000FF00000000LL) ; - } - - static inline short convert(const short v) - { - return static_cast(convert(static_cast(v))); - } - - static inline int convert(const int v) - { - return static_cast(convert(static_cast(v))); - } - - static inline long long int convert(const long long int v) - { - return static_cast(convert(static_cast(v))); - } - - static inline unsigned short convert_to_be(const unsigned short v) - { - return (is_little_endian()) ? convert(v) : v; - } - - static inline unsigned int convert_to_be(const unsigned int v) - { - return (is_little_endian()) ? convert(v) : v; - } - - static inline unsigned long long int convert_to_be(const unsigned long long int v) - { - return (is_little_endian()) ? convert(v) : v; - } - - static inline short convert_to_be(const short v) - { - return (is_little_endian()) ? convert(v) : v; - } - - static inline int convert_to_be(const int v) - { - return (is_little_endian()) ? convert(v) : v; - } - - static inline long long int convert_to_be(const long long int v) - { - return (is_little_endian()) ? convert(v) : v; - } - - static inline unsigned short convert_to_le(const unsigned short v) - { - return (is_big_endian()) ? convert(v) : v; - } - - static inline unsigned int convert_to_le(const unsigned int v) - { - return (is_big_endian()) ? convert(v) : v; - } - - static inline unsigned long long int convert_to_le(const unsigned long long int v) - { - return (is_big_endian()) ? convert(v) : v; - } - - static inline short convert_to_le(const short v) - { - return (is_big_endian()) ? convert(v) : v; - } - - static inline int convert_to_le(const int v) - { - return (is_big_endian()) ? convert(v) : v; - } - - static inline unsigned long long int convert_to_le(const long long int v) - { - return (is_big_endian()) ? convert(v) : v; - } - - class marker - { - private: - - typedef std::pair mark_type; - - public: - - inline bool reset(std::size_t& v1, char*& v2) - { - if (stack_.empty()) - return false; - v1 = stack_.top().first; - v2 = stack_.top().second; - stack_.pop(); - return true; - } - - inline void mark(const std::size_t& v1,char* v2) - { - stack_.push(std::make_pair(v1,v2)); - } - - private: - - std::stack stack_; - }; - - } - - class reader - { - public: - - // should be sourced from cstdint - typedef unsigned int uint32_t; - typedef unsigned short uint16_t; - typedef unsigned char uint8_t; - typedef unsigned long long int uint64_t; - - template - reader(T* buffer, - const std::size_t& buffer_length) - : original_buffer_(reinterpret_cast(buffer)), - buffer_(reinterpret_cast(buffer)), - buffer_length_(buffer_length * sizeof(T)), - amount_read_sofar_(0) - {} - - inline bool operator!() const - { - return (0 == buffer_length_) || - (0 == original_buffer_) || - (0 == buffer_); - } - - inline void reset(const bool clear_buffer = false) - { - amount_read_sofar_ = 0; - buffer_ = original_buffer_; - if (clear_buffer) - clear(); - } - - inline std::size_t position() const - { - return amount_read_sofar_; - } - - inline const char* position_ptr() const - { - return buffer_ ; - } - - inline std::size_t amount_read() - { - return amount_read_sofar_; - } - - inline bool rewind(const std::size_t& n_bytes) - { - if (n_bytes <= amount_read_sofar_) - { - amount_read_sofar_ -= n_bytes; - buffer_ -= n_bytes; - return true; - } - else - return false; - } - - inline bool seek(const int& n_bytes) - { - if (n_bytes < 0) - return rewind(-n_bytes); - else if (n_bytes > 0) - { - if ((amount_read_sofar_ + n_bytes) <= buffer_length_) - { - amount_read_sofar_ += n_bytes; - buffer_ += n_bytes; - return true; - } - else - return false; - } - else - return true; - } - - inline void clear() - { - reset(); - std::memset(buffer_,0x00,buffer_length_); - } - - template - inline bool operator()(T*& data, uint32_t& length, const bool read_length = true) - { - if (read_length && !operator()(length)) - return false; - - const std::size_t raw_size = length * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - if (read_length) - { - data = new T[length]; - } - std::copy(buffer_, buffer_ + raw_size, reinterpret_cast(data)); - buffer_ += raw_size; - amount_read_sofar_ += raw_size; - return true; - } - - template - inline bool operator()(T*& data, uint64_t& length, const bool read_length = true) - { - uint32_t l = 0; - if (read_length) - l = static_cast(length); - if (!operator()(data,l,read_length)) - return false; - if (read_length) - length = l; - return true; - } - - inline bool operator()(std::string& output) - { - uint32_t length = 0; - if (!operator()(length)) - return false; - - if (!buffer_capacity_ok(length)) - return false; - - output.resize(length); - std::copy(buffer_, - buffer_ + length, - const_cast(output.data())); - buffer_ += length; - amount_read_sofar_ += length; - return true; - } - - template - inline bool operator()(std::pair& p) - { - if (!operator()(p.first)) - return false; - if (!operator()(p.second)) - return false; - return true; - } - - template class Sequence> - inline bool operator()(Sequence& seq) - { - uint32_t size = 0; - if (!read_pod(size)) - return false; - - const std::size_t raw_size = size * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - T t = T(); - - for (std::size_t i = 0; i < size; ++i) - { - if (operator()(t)) - seq.push_back(t); - else - return false; - } - return true; - } - - template - inline bool operator()(std::vector& vec) - { - uint32_t size = 0; - if (!read_pod(size)) - return false; - const std::size_t raw_size = size * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - vec.resize(size); - return selector::type::batch_vector_read(*this,size,vec,false); - } - - template - inline bool operator()(std::set& set) - { - uint32_t size = 0; - if (!read_pod(size)) - return false; - - const std::size_t raw_size = size * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - T t; - for (std::size_t i = 0; i < size; ++i) - { - if (!operator()(t)) - return false; - set.insert(t); - } - - return true; - } - - template - inline bool operator()(std::multiset& multiset) - { - uint32_t size = 0; - if (!read_pod(size)) - return false; - - const std::size_t raw_size = size * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - T t; - for (std::size_t i = 0; i < size; ++i) - { - if (!operator()(t)) - return false; - multiset.insert(t); - } - - return true; - } - - inline bool operator()(std::ifstream& stream, const std::size_t& length) - { - if (length > buffer_length_) return false; - stream.read(original_buffer_,static_cast(length)); - return true; - } - - inline bool operator()(std::ifstream& stream) - { - if (0 == amount_read_sofar_) return false; - stream.read(original_buffer_,static_cast(amount_read_sofar_)); - return true; - } - - template - inline bool operator()(T& output) - { - return selector::type::run(*this,output); - } - - template - inline bool operator()(const T& output) - { - return selector::type::run(*this,const_cast(output)); - } - - template - inline bool be_to_native(T& output) - { - //From big-endian to native - if (details::is_little_endian()) - { - if (!operator()(output)) return false; - output = details::convert(output); - return true; - } - else - return operator()(output); - } - - template - inline bool le_to_native(T& output) - { - //From little-endian to native - if (details::is_little_endian()) - return operator()(output); - else - { - if (!operator()(output)) return false; - output = details::convert(output); - return true; - } - } - - template - inline bool operator()(T (&output)[N]) - { - const std::size_t raw_size = N * sizeof(T); - if (buffer_capacity_ok(raw_size)) - { - std::copy(buffer_, - buffer_ + raw_size, - reinterpret_cast(output)); - buffer_ += raw_size; - amount_read_sofar_ += raw_size; - return true; - } - else - return false; - } - - template - inline bool operator()(T& output, const std::size_t& size) - { - if (buffer_capacity_ok(size)) - { - bool result = strtk::string_to_type_converter(buffer_,buffer_ + size,output); - buffer_ += size; - amount_read_sofar_ += size; - return result; - } - else - return false; - } - - inline void mark() - { - marker_.mark(amount_read_sofar_,buffer_); - } - - inline bool reset_to_mark() - { - return marker_.reset(amount_read_sofar_,buffer_); - } - - private: - - reader(); - reader(const reader& s); - reader& operator=(const reader& s); - - inline bool buffer_capacity_ok(const std::size_t& required_read_qty) - { - return ((required_read_qty + amount_read_sofar_) <= buffer_length_); - } - - template - struct selector - { - private: - - template - struct selector_impl - { - template - static inline bool run(Reader& r, T& t) - { - return t(r); - } - - template - static inline bool batch_vector_read(Reader& r, - const std::size_t& size, - std::vector& v, - const bool) - { - T t; - for (std::size_t i = 0; i < size; ++i) - { - if (r.operator()(t)) - v[i] = t; - else - return false; - } - return true; - } - }; - - template - struct selector_impl - { - template - static inline bool run(Reader& r, - T& t, - const bool perform_buffer_capacity_check = true) - { - return r.read_pod(t,perform_buffer_capacity_check); - } - - template - static inline bool batch_vector_read(Reader& r, - const std::size_t& size, - std::vector& v, - const bool) - { - const std::size_t raw_size = sizeof(T) * size; - char* ptr = const_cast(reinterpret_cast(&v[0])); - std::copy(r.buffer_, r.buffer_ + raw_size, ptr); - r.buffer_ += raw_size; - r.amount_read_sofar_ += raw_size; - return true; - } - }; - - public: - - typedef selector_impl::result_t> type; - }; - - template - inline bool read_pod(T& data, const bool perform_buffer_capacity_check = true) - { - static const std::size_t data_length = sizeof(T); - if (perform_buffer_capacity_check) - { - if (!buffer_capacity_ok(data_length)) - return false; - } - data = (*reinterpret_cast(buffer_)); - buffer_ += data_length; - amount_read_sofar_ += data_length; - return true; - } - - char* const original_buffer_; - char* buffer_; - std::size_t buffer_length_; - std::size_t amount_read_sofar_; - details::marker marker_; - }; - - class writer - { - public: - - // should be sourced from cstdint - typedef unsigned int uint32_t; - typedef unsigned short uint16_t; - typedef unsigned char uint8_t; - typedef unsigned long long int uint64_t; - - template - writer(T* buffer, const std::size_t& buffer_length) - : original_buffer_(reinterpret_cast(buffer)), - buffer_(reinterpret_cast(buffer)), - buffer_length_(buffer_length * sizeof(T)), - amount_written_sofar_(0) - {} - - inline bool operator!() const - { - return (0 == buffer_length_) || - (0 == original_buffer_) || - (0 == buffer_); - } - - inline void reset(const bool clear_buffer = false) - { - amount_written_sofar_ = 0; - buffer_ = original_buffer_; - if (clear_buffer) - clear(); - } - - inline std::size_t position() const - { - return amount_written_sofar_; - } - - inline const char* position_ptr() const - { - return buffer_ ; - } - - inline std::size_t amount_written() const - { - return amount_written_sofar_; - } - - inline void clear() - { - reset(); - std::memset(buffer_,0x00,buffer_length_); - } - - template - inline bool operator()(const T (&data)[N], const bool write_length = false) - { - if (write_length && !operator()(N)) - return false; - - const std::size_t raw_size = N * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - const char* ptr = reinterpret_cast(data); - std::copy(ptr, ptr + raw_size, buffer_); - buffer_ += raw_size; - amount_written_sofar_ += raw_size; - return true; - } - - template - inline bool operator()(const T* data, const uint32_t& length, const bool write_length = true) - { - if (write_length && !operator()(length)) - return false; - - const std::size_t raw_size = length * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - const char* ptr = reinterpret_cast(data); - std::copy(ptr, ptr + raw_size, buffer_); - buffer_ += raw_size; - amount_written_sofar_ += raw_size; - return true; - } - - template - inline bool operator()(const T* data, const uint64_t& length, const bool write_length = true) - { - return operator()(data,static_cast(length),write_length); - } - - template - inline bool operator()(const T* data, const uint16_t& length, const bool write_length = true) - { - return operator()(data,static_cast(length),write_length); - } - - template - inline bool operator()(const T* data, const uint8_t& length, const bool write_length = true) - { - return operator()(data,static_cast(length),write_length); - } - - template - inline bool operator()(const std::pair& p) - { - if (!operator()(p.first)) - return false; - if (!operator()(p.second)) - return false; - return true; - } - - inline bool operator()(const std::string& input) - { - return operator()(input.data(),static_cast(input.size())); - } - - template class Sequence> - inline bool operator()(const Sequence& seq) - { - const uint32_t size = static_cast(seq.size()); - if (!operator()(size)) - return false; - - typename Sequence::const_iterator itr = seq.begin(); - typename Sequence::const_iterator end = seq.end(); - while (end != itr) - { - if (!operator()(*itr)) - return false; - ++itr; - } - return true; - } - - template - inline bool operator()(const std::vector& vec) - { - const uint32_t size = static_cast(vec.size()); - const std::size_t raw_size = (size * sizeof(T)); - if (!buffer_capacity_ok(raw_size + sizeof(size))) - return false; - if (!operator()(size)) - return false; - return selector::type::batch_vector_writer(*this,raw_size,vec); - } - - template - inline bool operator()(const std::set& set) - { - const uint32_t size = static_cast(set.size()); - if (!operator()(size)) - return false; - - const std::size_t raw_size = size * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - typename std::set::const_iterator itr = set.begin(); - typename std::set::const_iterator end = set.end(); - while (end != itr) - { - if (!operator()(*itr)) - return false; - ++itr; - } - return true; - } - - template - inline bool operator()(const std::multiset& multiset) - { - const uint32_t size = static_cast(multiset.size()); - if (!operator()(size)) - return false; - - const std::size_t raw_size = size * sizeof(T); - if (!buffer_capacity_ok(raw_size)) - return false; - - typename std::multiset::const_iterator itr = multiset.begin(); - typename std::multiset::const_iterator end = multiset.end(); - while (end != itr) - { - if (!operator()(*itr)) - return false; - ++itr; - } - return true; - } - - inline std::size_t operator()(std::ofstream& stream) - { - stream.write(original_buffer_,static_cast(amount_written_sofar_)); - return amount_written_sofar_; - } - - template - inline bool operator()(const T& input) - { - return selector::type::run(*this,input); - } - - template - inline bool native_to_be(const T& input) - { - //From native to big-endian - if (details::is_little_endian()) - { - return operator()(details::convert(input)); - } - else - return operator()(input); - } - - template - inline bool native_to_le(const T& input) - { - //From native to little-endian - if (details::is_little_endian()) - return operator()(input); - else - return operator()(details::convert(input)); - } - - enum padding_mode - { - right_padding = 0, - left_padding = 1 - }; - - template - inline bool operator()(const T& input, - const std::size_t& size, - const padding_mode pmode, - const char padding = ' ') - { - if (amount_written_sofar_ + size <= buffer_length_) - { - std::string s; - s.reserve(size); - if (!strtk::type_to_string(input,s)) - return false; - else if (s.size() > size) - return false; - else if (s.size() < size) - { - if (right_padding == pmode) - s.resize(size - s.size(),padding); - else - s = std::string(size - s.size(),padding) + s; - } - return operator()(s.data(),static_cast(size),false); - } - else - return false; - } - - inline void mark() - { - marker_.mark(amount_written_sofar_,buffer_); - } - - inline bool reset_to_mark() - { - return marker_.reset(amount_written_sofar_,buffer_); - } - - private: - - writer(); - writer(const writer& s); - writer& operator=(const writer& s); - - inline bool buffer_capacity_ok(const std::size_t& required_write_qty) - { - return ((required_write_qty + amount_written_sofar_) <= buffer_length_); - } - - template - struct selector - { - private: - - template - struct selector_impl - { - template - static inline bool run(Writer& w, const T& t) - { - return t(w); - } - - template - static inline bool batch_vector_writer(Writer& w, - const std::size_t&, - const std::vector& v) - { - for (std::size_t i = 0; i < v.size(); ++i) - { - if (w.operator()(v[i])) - continue; - else - return false; - } - return true; - } - }; - - template - struct selector_impl - { - template - static inline bool run(Writer& w, const T& t) - { - return w.write_pod(t); - } - - template - static inline bool batch_vector_writer(Writer& w, - const std::size_t& raw_size, - const std::vector& v) - { - const char* ptr = reinterpret_cast(&v[0]); - std::copy(ptr, ptr + raw_size, w.buffer_); - w.buffer_ += raw_size; - w.amount_written_sofar_ += raw_size; - return true; - } - }; - - public: - - typedef selector_impl::result_t> type; - }; - - template - inline bool write_pod(const T& data, const bool perform_buffer_capacity_check = true) - { - static const std::size_t data_length = sizeof(T); - if (perform_buffer_capacity_check) - { - if ((data_length + amount_written_sofar_) > buffer_length_) - { - return false; - } - } - *(reinterpret_cast(buffer_)) = data; - buffer_ += data_length; - amount_written_sofar_ += data_length; - return true; - } - - char* const original_buffer_; - char* buffer_; - std::size_t buffer_length_; - std::size_t amount_written_sofar_; - details::marker marker_; - }; - - #define strtk_binary_reader_begin() \ - bool operator()(strtk::binary::reader& reader)\ - { return true \ - - #define strtk_binary_reader(T) \ - && reader(T) \ - - #define strtk_binary_reader_end() \ - ;} \ - - #define strtk_binary_writer_begin() \ - bool operator()(strtk::binary::writer& writer) const\ - { return true \ - - #define strtk_binary_writer(T) \ - && writer(T) \ - - #define strtk_binary_writer_end() \ - ;} \ - - namespace details - { - template - class short_string_impl - { - public: - - short_string_impl() - : s(0) - {} - - short_string_impl(std::string& str) - : s(&str) - {} - - inline void clear() - { - s = 0; - } - - inline short_string_impl& set(std::string& str) - { - s = &str; - return *this; - } - - inline bool operator()(reader& r) - { - if (0 == s) - return false; - size_type size = 0; - if (!r(size)) - return false; - s->resize(size); - char* ptr = const_cast(s->data()); - strtk::binary::reader::uint32_t length = size; - if (!r(ptr,length,false)) - return false; - return true; - } - - inline bool operator()(writer& w) const - { - if (0 == s) - return false; - if (s->size() > std::numeric_limits::max()) - return false; - const size_type size = static_cast(s->size()); - if (!w(size)) - return false; - if (!w(s->data(),size, false)) - return false; - return true; - } - - private: - - short_string_impl& operator=(const short_string_impl&); - mutable std::string* s; - }; - } - - typedef details::short_string_impl short_string; - typedef details::short_string_impl pascal_string; - - } // namespace binary - - class ignore_token - { - public: - - template - inline ignore_token& operator=(const std::pair&) - { - return (*this); - } - - inline ignore_token& operator=(const std::string&) - { - return (*this); - } - }; - - template - class hex_to_number_sink - { - // static_assert for T either int or unsigned int and alike (could use a concept) - private: - - struct hex_value_check - { - inline bool operator()(const unsigned char c) const - { - return (('0' <= c) && (c <= '9')) || - (('A' <= c) && (c <= 'F')) || - (('a' <= c) && (c <= 'f')); - } - - inline bool operator()(const char c) const - { - return (*this)(static_cast(c)); - } - }; - - public: - - hex_to_number_sink(T& t) - : valid_(false), - t_(&t) - {} - - hex_to_number_sink(const hex_to_number_sink& hns) - : valid_(hns.valid), - t_(hns.t_) - {} - - inline hex_to_number_sink& operator=(const hex_to_number_sink& hns) - { - valid_ = hns.valid_; - t_ = hns.t_; - return (*this); - } - - template - inline hex_to_number_sink& operator=(const std::pair& s) - { - std::size_t offset = 0; - const std::size_t size = std::distance(s.first,s.second); - if ((size > 2) && ((*s.first) == '0') && (((*(s.first + 1)) == 'x') || ((*(s.first + 1)) == 'X'))) - offset = 2; - if ((size - offset) > (2 * sizeof(T))) - return (*this); - - const std::size_t buffer_size = 2 * sizeof(T); - const std::size_t buffer_offset = ((size - offset) % 2); - char buffer[buffer_size] = { '0' }; - if (!range_only_contains(hex_value_check(),s.first + offset,s.first + size)) - { - valid_ = false; - return (*this); - } - - std::copy(s.first + offset, s.first + size, buffer + buffer_offset); - (*t_) = 0; - valid_= convert_hex_to_bin(buffer, - buffer + (size - offset) + buffer_offset, - reinterpret_cast(t_)); - reverse_bytes(); - return (*this); - } - - inline hex_to_number_sink& operator=(const std::string& s) - { - return this->operator =(std::make_pair(s.data(),s.data() + s.size())); - } - - inline bool valid() const - { - return valid_; - } - - private: - - inline void reverse_bytes() - { - unsigned char* itr1 = reinterpret_cast(t_); - unsigned char* itr2 = itr1 + (sizeof(T) - 1); - while (itr1 < itr2) - { - std::swap(*itr1,*itr2); - ++itr1; - --itr2; - } - } - - private: - - bool valid_; - T* t_; - }; - - template - class base64_to_number_sink - { - // static_assert for T either int or unsigned int and alike (could use a concept) - private: - - struct base64_value_check - { - inline bool operator()(const unsigned char c) const - { - return (('0' <= c) && (c <= '9')) || - (('A' <= c) && (c <= 'Z')) || - (('a' <= c) && (c <= 'z')) || - ('+' == c) || - ('/' == c) || - ('=' == c); - } - - inline bool operator()(const char c) const - { - return (*this)(static_cast(c)); - } - }; - - public: - - base64_to_number_sink(T& t) - : valid_(false), - t_(&t) - {} - - base64_to_number_sink(const base64_to_number_sink& bns) - : valid_(bns.valid), - t_(bns.t_) - {} - - inline base64_to_number_sink& operator=(const base64_to_number_sink& bns) - { - valid_ = bns.valid_; - t_ = bns.t_; - return (*this); - } - - inline base64_to_number_sink& operator=(const std::string& s) - { - if (!range_only_contains(base64_value_check(),s.data(),s.data() + s.size())) - { - valid_ = false; - return (*this); - } - - (*t_) = T(0); - convert_base64_to_bin(s.data(), - s.data() + s.size(), - reinterpret_cast(t_)); - reverse_bytes(); - return (*this); - } - - template - inline base64_to_number_sink& operator=(const std::pair& s) - { - if (!range_only_contains(base64_value_check(),s.first,s.second)) - { - valid_ = false; - return (*this); - } - - (*t_) = T(0); - convert_base64_to_bin(s.first, s.second,reinterpret_cast(t_)); - reverse_bytes(); - return (*this); - } - - inline bool valid() const - { - return valid_; - } - - private: - - inline void reverse_bytes() - { - unsigned char* itr1 = reinterpret_cast(t_); - unsigned char* itr2 = itr1 + (sizeof(T) - 1); - while (itr1 < itr2) - { - std::swap(*itr1,*itr2); - ++itr1; - --itr2; - } - } - - private: - - bool valid_; - T* t_; - }; - - class hex_to_string_sink - { - public: - - hex_to_string_sink(std::string& s) - : valid_(false), - s_(s) - {} - - hex_to_string_sink(const hex_to_string_sink& hss) - : valid_(hss.valid_), - s_(hss.s_) - {} - - inline hex_to_string_sink& operator=(const hex_to_string_sink& hss) - { - valid_ = hss.valid_; - s_ = hss.s_; - return (*this); - } - - template - inline hex_to_string_sink& operator=(const std::pair& s) - { - const std::size_t size = std::distance(s.first,s.second); - std::size_t offset = 0; - if ((size > 2) && ((*s.first) == '0') && (((*(s.first + 1)) == 'x') || ((*(s.first + 1)) == 'X'))) - offset = 2; - if ((size - offset) < 2) - { - valid_ = false; - return (*this); - } - s_.resize((size - offset) / 2); - valid_ = convert_hex_to_bin(s.first + offset, - s.second, - const_cast(s_.data())); - return (*this); - } - - inline hex_to_string_sink& operator=(const std::string& s) - { - return this->operator=(std::make_pair(const_cast(s.data()), - const_cast(s.data() + s.size()))); - } - - inline bool valid() const - { - return valid_; - } - - private: - - bool valid_; - std::string& s_; - }; - - template - class truncated_int - { - public: - - truncated_int() - : t_(0), - fractional_size_(std::numeric_limits::max()) - {} - - truncated_int& fractional_size(const std::size_t& size) - { - fractional_size_ = size; - return *this; - } - - truncated_int& fractional_unknown_size() - { - fractional_size_ = std::numeric_limits::max(); - return *this; - } - - truncated_int& operator()(T& t) - { - t_ = &t; - return *this; - } - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - if (0 == t_) - return false; - - const std::size_t size = std::distance(begin,end); - - if (std::numeric_limits::max() != fractional_size_) - { - if (size < (fractional_size_ + 1)) - return false; - else - return strtk::string_to_type_converter(begin, begin + (size - (fractional_size_ + 1)),(*t_)); - } - - typedef typename std::iterator_traits::value_type value_type; - const value_type fullstop = value_type('.'); - InputIterator new_end = std::find(begin,end,fullstop); - return strtk::string_to_type_converter(begin,new_end,(*t_)); - } - - private: - - T* t_; - std::size_t fractional_size_; - }; - - namespace details - { - - template class Sequence> - inline std::size_t parse_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(begin,end,delimiters,sequence,split_option); - } - - template - inline std::size_t parse_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(begin,end,delimiters,set,split_option); - } - - template - inline std::size_t parse_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(begin,end,delimiters,multiset,split_option); - } - - template - inline std::size_t parse_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(begin,end,delimiters,queue,split_option); - } - - template - inline std::size_t parse_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(begin,end,delimiters,stack,split_option); - } - - template - inline std::size_t parse_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse(begin,end,delimiters,priority_queue,split_option); - } - - template class Sequence> - inline std::size_t parse_n_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - Sequence& sequence, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(begin,end,delimiters,n,sequence,split_option); - } - - template - inline std::size_t parse_n_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::set& set, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(begin,end,delimiters,n,set,split_option); - } - - template - inline std::size_t parse_n_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::multiset& multiset, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(begin,end,delimiters,n,multiset,split_option); - } - - template - inline std::size_t parse_n_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::queue& queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(begin,end,delimiters,n,queue,split_option); - } - - template - inline std::size_t parse_n_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::stack& stack, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(begin,end,delimiters,n,stack,split_option); - } - - template - inline std::size_t parse_n_stl_container_proxy(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const std::size_t& n, - std::priority_queue& priority_queue, - const split_options::type& split_option = split_options::compress_delimiters) - { - return parse_n(begin,end,delimiters,n,priority_queue,split_option); - } - - } // namespace details - - template - class sink_type - { - public: - - typedef typename Container::value_type value_type; - - inline sink_type(const std::string& delimiters, - const split_options::type& split_option = split_options::compress_delimiters) - : delimiters_(delimiters), - split_option_(split_option), - container_(0), - element_count_(std::numeric_limits::max()) - {} - - inline sink_type(Container& container, - const std::string& delimiters, - const split_options::type& split_option = split_options::compress_delimiters) - : delimiters_(delimiters), - split_option_(split_option), - container_(&container) - {} - - inline sink_type& count(const std::size_t& element_count = std::numeric_limits::max()) - { - element_count_ = element_count; - return (*this); - } - - inline sink_type& operator()(Container& container, - const std::string& delimiters = "", - const split_options::type& split_option = split_options::compress_delimiters) - { - container_ = (&container); - if (!delimiters.empty()) - delimiters_ = delimiters; - split_option_ = split_option; - return (*this); - } - - template - inline bool parse(InputIterator begin, InputIterator end) - { - if (container_) - { - if (std::numeric_limits::max() == element_count_) - return (details::parse_stl_container_proxy - (begin,end,delimiters_,(*container_),split_option_) > 0); - else - return (details::parse_n_stl_container_proxy - (begin,end,delimiters_,element_count_,(*container_),split_option_) == element_count_); - } - else - return false; - } - - sink_type& reference() - { - return *this; - } - - private: - - std::string delimiters_; - split_options::type split_option_; - Container* container_; - std::size_t element_count_; - }; - - template struct vector_sink { typedef sink_type > type; }; - template struct deque_sink { typedef sink_type > type; }; - template struct list_sink { typedef sink_type > type; }; - template struct set_sink { typedef sink_type > type; }; - template struct multiset_sink { typedef sink_type > type; }; - template struct queue_sink { typedef sink_type > type; }; - template struct stack_sink { typedef sink_type > type; }; - template struct priority_queue_sink { typedef sink_type > type; }; - - namespace text - { - inline std::string center(const std::size_t& width, - const std::string::value_type& pad, - const std::string& str) - { - if (str.size() >= width) return str; - const std::size_t pad_count = width - str.size(); - const std::size_t pad_count_2 = (pad_count >> 1) + (pad_count & 1); - return std::string(pad_count >> 1,pad) + str + std::string(pad_count_2,pad); - } - - inline std::string right_align(const std::size_t& width, - const std::string::value_type& pad, - const std::string& str) - { - if (str.size() >= width) return str; - return std::string(width - str.size(),pad) + str; - } - - inline std::string left_align(const std::size_t& width, - const std::string::value_type& pad, - const std::string& str) - { - if (str.size() >= width) return str; - return str + std::string(width - str.size(),pad); - } - - template - inline std::string center(const std::size_t& width, - const std::string::value_type& pad, - const T& t) - { - return center(width,pad,type_to_string(t)); - } - - template - inline std::string right_align(const std::size_t& width, - const std::string::value_type& pad, - const T& t) - { - return right_align(width,pad,type_to_string(t)); - } - - template - inline std::string left_align(const std::size_t& width, - const std::string::value_type& pad, - const T& t) - { - return left_align(width,pad,type_to_string(t)); - } - - template - inline std::string center(const std::size_t& width, const T& t) - { - return center(width,' ',type_to_string(t)); - } - - template - inline std::string right_align(const std::size_t& width, const T& t) - { - return right_align(width,' ',type_to_string(t)); - } - - template - inline std::string left_align(const std::size_t& width, const T& t) - { - return left_align(width,' ',type_to_string(t)); - } - - inline std::string remaining_string(const std::size_t& index, - const std::string& str) - { - return (index < str.size()) ? str.substr(index,str.size() - index) : str; - } - - inline void remaining_string(const std::size_t& index, - const std::string& str, - std::string& result) - { - result = (index < str.size()) ? str.substr(index,str.size() - index) : str; - } - - inline bool is_letter(const char c) - { - return (('A' <= c) && ( c <= 'Z')) || (('a' <= c) && ( c <= 'z')); - } - - inline bool is_lowercase_letter(const char c) - { - return (('a' <= c) && ( c <= 'z')); - } - - inline bool is_uppercase_letter(const char c) - { - return (('A' <= c) && ( c <= 'Z')); - } - - inline bool is_digit(const char c) - { - return (('0' <= c) && ( c <= '9')); - } - - inline bool is_hex_digit(const char c) - { - return (('0' <= c) && (c <= '9')) || - (('A' <= c) && (c <= 'F')) || - (('a' <= c) && (c <= 'f')); - } - - inline bool is_letter_or_digit(const char c) - { - return (is_letter(c) || is_digit(c)); - } - - inline bool is_all_letters(const std::string& s) - { - for (std::size_t i = 0; i < s.size(); ++i) - { - if (!is_letter(s[i])) - return false; - } - return true; - } - - inline bool is_all_digits(const std::string& s) - { - for (std::size_t i = 0; i < s.size(); ++i) - { - if (!is_digit(s[i])) - return false; - } - return true; - } - - inline void swap_inplace(std::string& s, const std::size_t& i0, const std::size_t& i1) - { - if (i0 >= s.size()) return; - if (i1 >= s.size()) return; - std::swap(s[i0],s[i1]); - } - - inline std::string swap(const std::string& s, const std::size_t& i0, const std::size_t& i1) - { - std::string result = s; - swap_inplace(result,i0,i1); - return result; - } - - inline void remove_inplace(std::string& s, const std::size_t& index) - { - if (index >= s.size()) - return; - std::memcpy(const_cast(s.data() + index), const_cast(s.data() + (index + 1)), s.size() - index); - s.resize(s.size() - 1); - } - - inline std::string remove(const std::string& s, const std::size_t& index) - { - std::string result = s; - remove_inplace(result,index); - return result; - } - - inline void insert_inplace(std::string& s, const std::size_t& index, const char c) - { - s.resize(s.size() + 1); - std::memcpy(const_cast(s.data() + index + 1), const_cast(s.data() + (index)), s.size() - index); - s[index] = c; - } - - inline std::string insert(const std::string& s, const std::size_t& index, const char c) - { - std::string result = s; - insert_inplace(result,index,c); - return result; - } - - } // namespace text - - namespace find_mode - { - enum type - { - exactly_n, - atleast_n - }; - } - - namespace find_type - { - enum type - { - digits, - letters, - lowercase_letters, - uppercase_letters, - letters_digits - }; - } - - namespace details - { - template - struct range_type - { - typedef typename std::pair type; - }; - - template - inline typename range_type::type find_exactly_n_consecutive_values(const std::size_t n, - Predicate p, - Iterator itr, - const Iterator end, - const bool stateful_predicate = false) - { - if (static_cast(std::distance(itr,end)) < n) - return typename range_type::type(end,end); - std::size_t count = n; - while (end != itr) - { - if (p(*itr)) - { - if (0 != --count) - ++itr; - else - { - std::advance(itr,1 - n); - return typename range_type::type(itr,itr + n); - } - } - else - { - ++itr; - while ((end != itr) && !p(*itr)) - ++itr; - if (!stateful_predicate) - count = n; - else - { - --count; - ++itr; - } - } - } - return typename range_type::type(end,end); - } - - template - inline typename range_type::type find_atleast_n_consecutive_values(const std::size_t n, - Predicate p, - Iterator itr, - const Iterator end) - { - if (static_cast(std::distance(itr,end)) < n) - return typename range_type::type(end,end); - std::size_t count = 0; - while (end != itr) - { - if (p(*itr)) - { - ++count; - ++itr; - } - else - { - if (count >= n) - { - std::advance(itr,-static_cast(count)); - return typename range_type::type(itr,itr + count); - } - while ((end != itr) && !p(*itr)) - ++itr; - count = 0; - } - } - if (count >= n) - { - std::advance(itr,-static_cast(count)); - return typename range_type::type(itr,itr + count); - } - else - return typename range_type::type(end,end); - } - - template - inline typename range_type::type find_exactly_n_consecutive_values(const std::size_t n, - Predicate p, - typename details::range_type::type range, - const bool stateful_predicate = false) - { - return find_exactly_n_consecutive_values(n,p,range.first,range.second,stateful_predicate); - } - - template - inline typename range_type::type find_atleast_n_consecutive_values(const std::size_t n, - Predicate p, - typename details::range_type::type range) - { - return find_atleast_n_consecutive_values(n,p,range.first,range.second); - } - - template - inline typename range_type::type find_n_consecutive_values(const std::size_t n, - find_mode::type mode, - Predicate p, - Iterator itr, - const Iterator end) - { - switch (mode) - { - case find_mode::exactly_n : return find_exactly_n_consecutive_values(n,p,itr,end); - case find_mode::atleast_n : return find_atleast_n_consecutive_values(n,p,itr,end); - default : return typename range_type::type(end,end); - } - } - - template - inline bool match_exactly_n_consecutive_values(const std::size_t n, - Predicate p, - Iterator itr, - const Iterator end) - { - if (static_cast(std::distance(itr,end)) < n) - return false; - std::size_t count = n; - while (end != itr) - { - if (p(*itr)) - { - if (0 == --count) - return true; - else - ++itr; - } - else - return false; - } - return false; - } - - template - inline bool match_atleast_n_consecutive_values(const std::size_t n, - Predicate p, - Iterator itr, - const Iterator end) - { - if (static_cast(std::distance(itr,end)) < n) - return false; - std::size_t count = 0; - while (end != itr) - { - if (p(*itr)) - { - ++count; - ++itr; - } - else if (count >= n) - return true; - else - return false; - } - return false; - } - - template - inline bool match_n_consecutive_values(const std::size_t n, - find_mode::type mode, - Predicate p, - Iterator itr, - const Iterator end) - { - switch (mode) - { - case find_mode::exactly_n : return match_exactly_n_consecutive_values(n,p,itr,end); - case find_mode::atleast_n : return match_atleast_n_consecutive_values(n,p,itr,end); - default : return false; - } - } - - } - - template - inline typename details::range_type::type find_n_consecutive(const std::size_t n, - find_type::type type, - find_mode::type mode, - typename details::range_type::type range) - { - switch (type) - { - case find_type::digits : return details::find_n_consecutive_values(n, - mode, - strtk::text::is_digit, - range.first,range.second); - - case find_type::letters : return details::find_n_consecutive_values(n, - mode, - strtk::text::is_letter, - range.first,range.second); - - case find_type::lowercase_letters : return details::find_n_consecutive_values(n, - mode, - strtk::text::is_lowercase_letter, - range.first,range.second); - - case find_type::uppercase_letters : return details::find_n_consecutive_values(n, - mode, - strtk::text::is_uppercase_letter, - range.first,range.second); - - case find_type::letters_digits : return details::find_n_consecutive_values(n, - mode, - strtk::text::is_letter_or_digit, - range.first,range.second); - - default : return typename details::range_type::type(range.second,range.second); - } - } - - template - inline bool match_n_consecutive(const std::size_t n, - find_type::type type, - find_mode::type mode, - typename details::range_type::type range) - { - switch (type) - { - case find_type::digits : return details::match_n_consecutive_values(n, - mode, - strtk::text::is_digit, - range.first,range.second); - - case find_type::letters : return details::match_n_consecutive_values(n, - mode, - strtk::text::is_letter, - range.first,range.second); - - case find_type::lowercase_letters : return details::match_n_consecutive_values(n, - mode, - strtk::text::is_lowercase_letter, - range.first,range.second); - - case find_type::uppercase_letters : return details::match_n_consecutive_values(n, - mode, - strtk::text::is_uppercase_letter, - range.first,range.second); - - case find_type::letters_digits : return details::match_n_consecutive_values(n, - mode, - strtk::text::is_letter_or_digit, - range.first,range.second); - - default : return false; - } - } - - template - inline std::size_t split_on_consecutive(const std::size_t n, - Predicate p, - char* begin, - char* end, - OutputIterator out, - const bool stateful_predicate = false) - { - if (0 == n) return 0; - typedef char* iterator_type; - typedef details::range_type::type range_type; - range_type itr_range(begin,end); - std::size_t match_count = 0; - while (end != itr_range.first) - { - range_type found_itr = - details::find_exactly_n_consecutive_values(n, - p, - itr_range, - stateful_predicate); - - if ((end == found_itr.first) && (found_itr.first == found_itr.second)) - { - break; - } - else - { - (*out) = found_itr; - ++out; - ++match_count; - itr_range.first = found_itr.second; - } - } - return match_count; - } - - template - inline std::size_t split_on_consecutive(const std::size_t n, - const std::size_t m, - Predicate p, - char* begin, - char* end, - OutputIterator out) - { - if (0 == n) return 0; - typedef char* iterator_type; - typedef details::range_type::type range_type; - range_type itr_range(begin,end); - std::size_t match_count = 0; - while ((end != itr_range.first) && (match_count <= n)) - { - range_type found_itr = details::find_exactly_n_consecutive_values(m,p,itr_range); - if ((end == found_itr.first) && (found_itr.first == found_itr.second)) - { - break; - } - else - { - (*out) = found_itr; - ++out; - ++match_count; - itr_range.first = found_itr.second; - } - } - return match_count; - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - const find_type::type type, - const find_mode::type mode, - char* begin, - char* end, - OutputIterator out) - { - if (0 == n) return 0; - typedef char* iterator_type; - typedef details::range_type::type range_type; - range_type itr_range(begin,end); - std::size_t match_count = 0; - while (end != itr_range.first) - { - range_type found_itr = find_n_consecutive(n,type,mode,itr_range); - if ((end == found_itr.first) && (found_itr.first == found_itr.second)) - { - break; - } - else - { - (*out) = found_itr; - ++out; - ++match_count; - itr_range.first = found_itr.second; - } - } - return match_count; - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - const find_type::type type, - const find_mode::type mode, - char* begin, - char* end, - OutputIterator out) - { - if (0 == n) return 0; - typedef char* iterator_type; - typedef details::range_type::type range_type; - range_type itr_range(begin,end); - std::size_t match_count = 0; - while ((end != itr_range.first) && (match_count <= n)) - { - range_type found_itr = find_n_consecutive(m,type,mode,itr_range); - if ((end == found_itr.first) && (found_itr.first == found_itr.second)) - { - break; - } - else - { - (*out) = found_itr; - ++out; - ++match_count; - itr_range.first = found_itr.second; - } - } - return match_count; - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - const find_type::type type, - const find_mode::type mode, - const char* begin, - const char* end, - OutputIterator out) - { - return split_on_consecutive(n, - type, - mode, - const_cast(begin), - const_cast(end), - out); - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - const find_type::type type, - const find_mode::type mode, - const unsigned char* begin, - const unsigned char* end, - OutputIterator out) - { - return split_on_consecutive(n, - type, - mode, - reinterpret_cast(begin), - reinterpret_cast(end), - out); - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - const find_type::type type, - const find_mode::type mode, - const std::string& str, - OutputIterator out) - { - return split_on_consecutive(n, - type, - mode, - str.data(), - str.data() + str.size(), - out); - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - const find_type::type type, - const find_mode::type mode, - const char* begin, - const char* end, - OutputIterator out) - { - return split_on_consecutive_n(n, - m, - type, - mode, - const_cast(begin), - const_cast(end), - out); - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - const find_type::type type, - const find_mode::type mode, - const unsigned char* begin, - const unsigned char* end, - OutputIterator out) - { - return split_on_consecutive_n(n, - m, - type, - mode, - reinterpret_cast(begin), - reinterpret_cast(end), - out); - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - const find_type::type type, - const find_mode::type mode, - const std::string& str, - OutputIterator out) - { - return split_on_consecutive_n(n, - m, - type, - mode, - str.data(), - str.data() + str.size(), - out); - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - Predicate p, - const char* begin, - const char* end, - OutputIterator out, - const bool stateful_predicate = false) - { - return split_on_consecutive(n, - p, - const_cast(begin), - const_cast(end), - out, - stateful_predicate); - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - Predicate p, - const unsigned char* begin, - const unsigned char* end, - OutputIterator out, - const bool stateful_predicate = false) - { - return split_on_consecutive(n, - p, - reinterpret_cast(begin), - reinterpret_cast(end), - out, - stateful_predicate); - } - - template - inline std::size_t split_on_consecutive(const std::size_t& n, - Predicate p, - const std::string& str, - OutputIterator out, - const bool stateful_predicate = false) - { - return split_on_consecutive(n, - p, - str.data(), - str.data() + str.size(), - out, - stateful_predicate); - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - Predicate p, - const char* begin, - const char* end, - OutputIterator out) - { - return split_on_consecutive_n(n, - m, - p, - const_cast(begin), - const_cast(end), - out); - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - Predicate p, - const unsigned char* begin, - const unsigned char* end, - OutputIterator out) - { - return split_on_consecutive_n(n, - m, - p, - reinterpret_cast(begin), - reinterpret_cast(end), - out); - } - - template - inline std::size_t split_on_consecutive_n(const std::size_t& n, - const std::size_t& m, - Predicate p, - const std::string& str, - OutputIterator out) - { - return split_on_consecutive_n(n, - m, - p, - str.data(), - str.data() + str.size(), - out); - } - - // Required for broken versions of GCC pre 4.5 - namespace util { class value; } - - namespace details - { - - class expect_impl - { - public: - - expect_impl(const std::string& s) - : s_(s) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - if (static_cast(std::distance(begin,end)) != s_.size()) - return false; - else - return std::equal(s_.data(),s_.data() + s_.size(),begin); - } - - inline expect_impl& ref() - { - return (*this); - } - - inline void set_value(const std::string& s) - { - s_ = s; - } - - private: - - std::string s_; - }; - - class iexpect_impl - { - public: - - iexpect_impl(const std::string& s) - : s_(s) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - if (static_cast(std::distance(begin,end)) != s_.size()) - return false; - else - return std::equal(s_.data(),s_.data() + s_.size(),begin,imatch_char); - } - - inline iexpect_impl& ref() - { - return (*this); - } - - inline void set_value(const std::string& s) - { - s_ = s; - } - - private: - - std::string s_; - }; - - class like_impl - { - public: - - like_impl(const std::string& s) - : s_(s) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - typedef typename std::iterator_traits::value_type value_type; - static const value_type zero_or_more = value_type('*'); - static const value_type zero_or_one = value_type('?'); - return strtk::match(s_.data(),s_.data() + s_.size(),begin,end,zero_or_more,zero_or_one); - } - - inline like_impl& ref() - { - return (*this); - } - - inline void set_pattern(const std::string& s) - { - s_ = s; - } - - private: - - std::string s_; - }; - - template - class inrange_impl - { - public: - - inrange_impl(T& t, const T& low, const T& hi) - : t_(&t), - low_(low), - hi_(hi) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - T temp; - if (!strtk::string_to_type_converter(begin,end,temp)) - return false; - else if (temp < low_) - return false; - else if (temp > hi_) - return false; - (*t_) = temp; - return true; - } - - inline inrange_impl& ref() - { - return (*this); - } - - inline void set_low_hi(const T& low, const T& hi) - { - low_ = low; - hi_ = hi; - } - - private: - - T* t_; - T low_; - T hi_; - }; - - namespace trim_details - { - template - struct convert_impl - { - template - static bool execute(InputIterator begin, InputIterator end, - const std::string& rem_chars, - std::size_t mode, - Type& t) - { - std::string s; - if (!strtk::string_to_type_converter(begin,end,s)) - return false; - switch (mode) - { - case 0 : remove_leading_trailing(rem_chars,s); break; - case 1 : remove_leading (rem_chars,s); break; - case 2 : remove_trailing (rem_chars,s); break; - default : return false; - } - return strtk::string_to_type_converter(s,t); - } - }; - - template <> - struct convert_impl - { - template - static bool execute(InputIterator begin, InputIterator end, - const std::string& rem_chars, - std::size_t mode, - std::string& t) - { - if (!strtk::string_to_type_converter(begin,end,t)) - return false; - switch (mode) - { - case 0 : remove_leading_trailing(rem_chars,t); break; - case 1 : remove_leading (rem_chars,t); break; - case 2 : remove_trailing (rem_chars,t); break; - default : return false; - } - return true; - } - }; - } - - template - class trim_impl - { - public: - - trim_impl(const std::size_t mode, - T& t, - const std::string& rem_chars = " ") - : mode_(mode), - t_(&t), - rem_chars_(rem_chars) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - return trim_details::convert_impl::execute(begin,end,rem_chars_,mode_,(*t_)); - } - - inline trim_impl& ref() - { - return (*this); - } - - private: - - std::size_t mode_; - T* t_; - std::string rem_chars_; - }; - - class conv_to_lcase_impl - { - public: - - conv_to_lcase_impl(std::string& s) - : s_(&s) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - std::string& s = (*s_); - s.assign(begin,end); - convert_to_lowercase(s); - return true; - } - - inline conv_to_lcase_impl& ref() - { - return (*this); - } - - private: - - std::string* s_; - }; - - class conv_to_ucase_impl - { - public: - - conv_to_ucase_impl(std::string& s) - : s_(&s) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - std::string& s = (*s_); - s.assign(begin,end); - convert_to_uppercase(s); - return true; - } - - inline conv_to_ucase_impl& ref() - { - return (*this); - } - - private: - - std::string* s_; - }; - - class fill_array_impl - { - public: - - fill_array_impl(unsigned char* data, const std::size_t& size) - : data_(data), - size_(size) - {} - - template - inline bool operator()(InputIterator begin, InputIterator end) - { - const std::size_t range_size = static_cast(std::distance(begin,end)); - if (range_size != size_) - return false; - std::memcpy(data_,begin,range_size); - return true; - } - - inline fill_array_impl& ref() - { - return (*this); - } - - inline fill_array_impl& set(unsigned char* data, const std::size_t& size) - { - data_ = data; - size_ = size; - return (*this); - } - - inline fill_array_impl& set(char* data, const std::size_t& size) - { - data_ = reinterpret_cast(data); - size_ = size; - return (*this); - } - - inline fill_array_impl& set_data(unsigned char* data) - { - data_ = data; - return (*this); - } - - inline fill_array_impl& set_data(char* data) - { - data_ = reinterpret_cast(data); - return (*this); - } - - inline fill_array_impl& set_size(const std::size_t& size) - { - size_ = size; - return (*this); - } - - private: - - unsigned char* data_; - std::size_t size_; - }; - } - - inline details::expect_impl expect(const std::string& s) - { - return details::expect_impl(s); - } - - inline details::iexpect_impl iexpect(const std::string& s) - { - return details::iexpect_impl(s); - } - - inline details::like_impl like(const std::string& s) - { - return details::like_impl(s); - } - - template - inline details::inrange_impl inrange(T& t, const T0& low, const T1& hi) - { - return details::inrange_impl(t,T(low),T(hi)); - } - - template - inline details::trim_impl trim(const std::string& rem_chars, T& t) - { - return details::trim_impl(0,t,rem_chars); - } - - template - inline details::trim_impl trim_leading(const std::string& rem_chars, T& t) - { - return details::trim_impl(1,t,rem_chars); - } - - template - inline details::trim_impl trim_trailing(const std::string& rem_chars, T& t) - { - return details::trim_impl(2,t,rem_chars); - } - - inline details::conv_to_lcase_impl as_lcase(std::string& s) - { - return details::conv_to_lcase_impl(s); - } - - inline details::conv_to_ucase_impl as_ucase(std::string& s) - { - return details::conv_to_ucase_impl(s); - } - - inline details::fill_array_impl fill_array(unsigned char* data, const std::size_t& size) - { - return details::fill_array_impl(data,size); - } - - inline details::fill_array_impl fill_array(char* data, const std::size_t& size) - { - return details::fill_array_impl(reinterpret_cast(data),size); - } - - template - inline details::fill_array_impl fill_array(unsigned char (&data)[N]) - { - return details::fill_array_impl(data,N); - } - - template - inline details::fill_array_impl fill_array(char (&data)[N]) - { - return details::fill_array_impl(reinterpret_cast(data),N); - } - - inline details::fill_array_impl fill_array(std::string& data, const std::size_t& size) - { - return fill_array(const_cast(data.data()),size); - } - - inline details::fill_array_impl fill_array(std::string& data) - { - return fill_array(const_cast(data.data()),data.size()); - } - - namespace details - { - static const unsigned char digit_table[] = - { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xFF - 0x07 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x08 - 0x0F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x10 - 0x17 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x18 - 0x1F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x20 - 0x27 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x28 - 0x2F - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, // 0x30 - 0x37 - 0x08, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x38 - 0x3F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x40 - 0x47 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x48 - 0x4F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x50 - 0x57 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x58 - 0x5F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x60 - 0x67 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x68 - 0x6F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x70 - 0x77 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x78 - 0x7F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x80 - 0x87 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x88 - 0x8F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x90 - 0x97 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0x98 - 0x9F - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA0 - 0xA7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xA8 - 0xAF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB0 - 0xB7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xB8 - 0xBF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC0 - 0xC7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xC8 - 0xCF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD0 - 0xD7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xD8 - 0xDF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 - 0xE7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE8 - 0xEF - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xF0 - 0xF7 - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF // 0xF8 - 0xFF - }; - - static const std::size_t digit_table_size = sizeof(digit_table) / sizeof(unsigned char); - - template - static inline bool is_invalid_digit(const T& t) - { - static const unsigned int invalid_digit = 0xFF; - return (static_cast(invalid_digit) == t); - } - - template - static inline bool is_valid_digit(const T& t) - { - static const unsigned int invalid_digit = 0xFF; - return (static_cast(invalid_digit) != t); - } - - static const unsigned char digitr[] = - { - "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" - }; - - static const unsigned char rev_3digit_lut[] = - { - "000001002003004005006007008009010011012013014015016017018019020021022023024" - "025026027028029030031032033034035036037038039040041042043044045046047048049" - "050051052053054055056057058059060061062063064065066067068069070071072073074" - "075076077078079080081082083084085086087088089090091092093094095096097098099" - "100101102103104105106107108109110111112113114115116117118119120121122123124" - "125126127128129130131132133134135136137138139140141142143144145146147148149" - "150151152153154155156157158159160161162163164165166167168169170171172173174" - "175176177178179180181182183184185186187188189190191192193194195196197198199" - "200201202203204205206207208209210211212213214215216217218219220221222223224" - "225226227228229230231232233234235236237238239240241242243244245246247248249" - "250251252253254255256257258259260261262263264265266267268269270271272273274" - "275276277278279280281282283284285286287288289290291292293294295296297298299" - "300301302303304305306307308309310311312313314315316317318319320321322323324" - "325326327328329330331332333334335336337338339340341342343344345346347348349" - "350351352353354355356357358359360361362363364365366367368369370371372373374" - "375376377378379380381382383384385386387388389390391392393394395396397398399" - "400401402403404405406407408409410411412413414415416417418419420421422423424" - "425426427428429430431432433434435436437438439440441442443444445446447448449" - "450451452453454455456457458459460461462463464465466467468469470471472473474" - "475476477478479480481482483484485486487488489490491492493494495496497498499" - "500501502503504505506507508509510511512513514515516517518519520521522523524" - "525526527528529530531532533534535536537538539540541542543544545546547548549" - "550551552553554555556557558559560561562563564565566567568569570571572573574" - "575576577578579580581582583584585586587588589590591592593594595596597598599" - "600601602603604605606607608609610611612613614615616617618619620621622623624" - "625626627628629630631632633634635636637638639640641642643644645646647648649" - "650651652653654655656657658659660661662663664665666667668669670671672673674" - "675676677678679680681682683684685686687688689690691692693694695696697698699" - "700701702703704705706707708709710711712713714715716717718719720721722723724" - "725726727728729730731732733734735736737738739740741742743744745746747748749" - "750751752753754755756757758759760761762763764765766767768769770771772773774" - "775776777778779780781782783784785786787788789790791792793794795796797798799" - "800801802803804805806807808809810811812813814815816817818819820821822823824" - "825826827828829830831832833834835836837838839840841842843844845846847848849" - "850851852853854855856857858859860861862863864865866867868869870871872873874" - "875876877878879880881882883884885886887888889890891892893894895896897898899" - "900901902903904905906907908909910911912913914915916917918919920921922923924" - "925926927928929930931932933934935936937938939940941942943944945946947948949" - "950951952953954955956957958959960961962963964965966967968969970971972973974" - "975976977978979980981982983984985986987988989990991992993994995996997998999" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - }; - - static const unsigned char rev_2digit_lut[] = - { - "0001020304050607080910111213141516171819" - "2021222324252627282930313233343536373839" - "4041424344454647484950515253545556575859" - "6061626364656667686970717273747576777879" - "8081828384858687888990919293949596979899" - "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" - }; - - #define strtk_register_pod_type(T) \ - template<> struct is_pod{ typedef yes_t result_t; enum {result = true }; }; \ - template<> struct is_pod{ typedef yes_t result_t; enum {result = true }; }; \ - template<> struct is_pod{ typedef yes_t result_t; enum {result = true }; }; \ - template<> struct is_pod{ typedef yes_t result_t; enum {result = true }; };\ - - strtk_register_pod_type(bool) - strtk_register_pod_type(signed char) - strtk_register_pod_type(char) - strtk_register_pod_type(short) - strtk_register_pod_type(int) - strtk_register_pod_type(long int) - strtk_register_pod_type(long long int) - strtk_register_pod_type(unsigned char) - strtk_register_pod_type(unsigned short) - strtk_register_pod_type(unsigned int) - strtk_register_pod_type(unsigned long int) - strtk_register_pod_type(unsigned long long int) - strtk_register_pod_type(float) - strtk_register_pod_type(double) - strtk_register_pod_type(long double) - - #undef strtk_register_pod_type - - template - struct numeric { enum { length = 0, size = 32, bound_length = 0, min_exp = 0, max_exp = 0 }; }; - - template<> struct numeric { enum { length = 5, size = 16, bound_length = 4}; }; - template<> struct numeric { enum { length = 5, size = 16, bound_length = 4}; }; - - template<> struct numeric { enum { length = 10, size = 16, bound_length = 9}; }; - template<> struct numeric { enum { length = 10, size = 16, bound_length = 9}; }; - - template<> struct numeric { enum { length = 10, size = 16, bound_length = 9}; }; - template<> struct numeric { enum { length = 10, size = 16, bound_length = 9}; }; - - template<> struct numeric { enum { length = 19, size = 24, bound_length = 18}; }; - template<> struct numeric { enum { length = 20, size = 24, bound_length = 19}; }; - - template<> struct numeric { enum { min_exp = -37, max_exp = +38, precision = 10}; }; - template<> struct numeric { enum { min_exp = -307, max_exp = +308, precision = 15}; }; - - template struct ldt {}; - template <> struct ldt { enum { i = -308, a = +308, p = 15}; }; //64-bit - template <> struct ldt { enum { i = -4931, a = +4931, p = 18}; }; //80-bit - template <> struct ldt { enum { i = -4931, a = +4931, p = 22}; }; //96-bit - template <> struct ldt { enum { i = -4931, a = +4931, p = 34}; }; //128-bit - - template<> - struct numeric - { - typedef ldt ld; - enum { min_exp = ld::i, max_exp = ld::a, precision = ld::p}; - }; - - #define strtk_register_unsigned_type_tag(T) \ - template<> struct supported_conversion_to_type { typedef unsigned_type_tag type; }; \ - template<> struct supported_conversion_from_type { typedef unsigned_type_tag type; };\ - - #define strtk_register_signed_type_tag(T) \ - template<> struct supported_conversion_to_type{ typedef signed_type_tag type; }; \ - template<> struct supported_conversion_from_type { typedef signed_type_tag type; }; \ - - #define strtk_register_real_type_tag(T) \ - template<> struct supported_conversion_to_type{ typedef real_type_tag type; }; - - #define strtk_register_byte_type_tag(T) \ - template<> struct supported_conversion_to_type{ typedef byte_type_tag type; }; \ - template<> struct supported_conversion_from_type { typedef byte_type_tag type; };\ - - #define strtk_register_hex_number_type_tag(T) \ - template<> struct supported_conversion_to_type{ typedef hex_number_type_tag type; }; - - template<> struct supported_conversion_to_type{ typedef hex_string_type_tag type; }; - - #define strtk_register_base64_type_tag(T) \ - template<> struct supported_conversion_to_type{ typedef base64_type_tag type; }; - - #define strtk_register_supported_iterator_type(T) \ - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef bool_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef stdstring_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef value_type_tag type; }; - template<> struct supported_conversion_from_type { typedef value_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef expect_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef expect_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef like_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef fillchararray_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef lcase_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - template<> struct supported_conversion_to_type { typedef ucase_type_tag type; }; - template<> struct supported_iterator_type { enum { value = true }; }; - - #define strtk_register_truncint_type_tag(T) \ - template<> struct supported_conversion_to_type > { typedef truncint_type_tag type; };\ - template<> struct supported_iterator_type > { enum { value = true }; }; - - #define strtk_register_inrange_type_tag(T) \ - template<> struct supported_conversion_to_type > { typedef inrange_type_tag type; };\ - template<> struct supported_iterator_type > { enum { value = true }; }; - - #define strtk_register_trim_type_tag(T) \ - template<> struct supported_conversion_to_type > { typedef trim_type_tag type; };\ - template<> struct supported_iterator_type > { enum { value = true }; }; - - #define strtk_register_stdstring_range_type_tag(T) \ - template<> struct supported_conversion_to_type< std::pair >{ typedef stdstring_range_type_tag type; }; - - #define strtk_register_sink_type_tag(T) \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_to_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; }; \ - template<> struct supported_conversion_from_type > > { typedef sink_type_tag type; };\ - - #define strtk_register_stl_container_to_string_conv_type_tag(T) \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; }; \ - template<> struct supported_conversion_from_type > { typedef stl_seq_type_tag type; };\ - - template<> struct supported_conversion_to_type{ typedef ignore_token_type_tag type; }; - - #define strtk_register_sequence_iterator_type(sequence) \ - strtk_register_supported_iterator_type(sequence::iterator) \ - strtk_register_supported_iterator_type(sequence::const_iterator) \ - strtk_register_supported_iterator_type(sequence::iterator) \ - strtk_register_supported_iterator_type(sequence::const_iterator)\ - - strtk_register_unsigned_type_tag(unsigned short) - strtk_register_unsigned_type_tag(unsigned int) - strtk_register_unsigned_type_tag(unsigned long) - strtk_register_unsigned_type_tag(unsigned long long int) - - strtk_register_signed_type_tag(short) - strtk_register_signed_type_tag(int) - strtk_register_signed_type_tag(long) - strtk_register_signed_type_tag(long long) - - strtk_register_real_type_tag(float) - strtk_register_real_type_tag(double) - strtk_register_real_type_tag(long double) - - strtk_register_byte_type_tag(unsigned char) - strtk_register_byte_type_tag(signed char) - strtk_register_byte_type_tag(char) - - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - strtk_register_hex_number_type_tag(hex_to_number_sink) - - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - strtk_register_base64_type_tag(base64_to_number_sink) - - strtk_register_stdstring_range_type_tag(std::string::iterator) - strtk_register_stdstring_range_type_tag(std::string::const_iterator) - strtk_register_stdstring_range_type_tag(char*) - strtk_register_stdstring_range_type_tag(signed char*) - strtk_register_stdstring_range_type_tag(unsigned char*) - strtk_register_stdstring_range_type_tag(const char*) - strtk_register_stdstring_range_type_tag(const unsigned char*) - - strtk_register_supported_iterator_type(char*) - strtk_register_supported_iterator_type(signed char*) - strtk_register_supported_iterator_type(unsigned char*) - strtk_register_supported_iterator_type(const char*) - strtk_register_supported_iterator_type(const signed char*) - strtk_register_supported_iterator_type(const unsigned char*) - strtk_register_supported_iterator_type(std::string::iterator) - strtk_register_supported_iterator_type(std::string::const_iterator) - - strtk_register_sequence_iterator_type(std::vector) - strtk_register_sequence_iterator_type(std::deque) - - strtk_register_sink_type_tag(float) - strtk_register_sink_type_tag(double) - strtk_register_sink_type_tag(long double) - strtk_register_sink_type_tag(signed char) - strtk_register_sink_type_tag(char) - strtk_register_sink_type_tag(short) - strtk_register_sink_type_tag(int) - strtk_register_sink_type_tag(long) - strtk_register_sink_type_tag(long long) - strtk_register_sink_type_tag(unsigned char) - strtk_register_sink_type_tag(unsigned short) - strtk_register_sink_type_tag(unsigned int) - strtk_register_sink_type_tag(unsigned long) - strtk_register_sink_type_tag(unsigned long long int) - strtk_register_sink_type_tag(std::string) - - strtk_register_stl_container_to_string_conv_type_tag(float) - strtk_register_stl_container_to_string_conv_type_tag(double) - strtk_register_stl_container_to_string_conv_type_tag(long double) - strtk_register_stl_container_to_string_conv_type_tag(signed char) - strtk_register_stl_container_to_string_conv_type_tag(char) - strtk_register_stl_container_to_string_conv_type_tag(short) - strtk_register_stl_container_to_string_conv_type_tag(int) - strtk_register_stl_container_to_string_conv_type_tag(long) - strtk_register_stl_container_to_string_conv_type_tag(long long) - strtk_register_stl_container_to_string_conv_type_tag(unsigned char) - strtk_register_stl_container_to_string_conv_type_tag(unsigned short) - strtk_register_stl_container_to_string_conv_type_tag(unsigned int) - strtk_register_stl_container_to_string_conv_type_tag(unsigned long) - strtk_register_stl_container_to_string_conv_type_tag(unsigned long long int) - strtk_register_stl_container_to_string_conv_type_tag(std::string) - - strtk_register_inrange_type_tag(float) - strtk_register_inrange_type_tag(double) - strtk_register_inrange_type_tag(long double) - strtk_register_inrange_type_tag(signed char) - strtk_register_inrange_type_tag(char) - strtk_register_inrange_type_tag(short) - strtk_register_inrange_type_tag(int) - strtk_register_inrange_type_tag(long) - strtk_register_inrange_type_tag(long long) - strtk_register_inrange_type_tag(unsigned char) - strtk_register_inrange_type_tag(unsigned short) - strtk_register_inrange_type_tag(unsigned int) - strtk_register_inrange_type_tag(unsigned long) - strtk_register_inrange_type_tag(unsigned long long int) - strtk_register_inrange_type_tag(std::string) - - strtk_register_trim_type_tag(float) - strtk_register_trim_type_tag(double) - strtk_register_trim_type_tag(long double) - strtk_register_trim_type_tag(signed char) - strtk_register_trim_type_tag(char) - strtk_register_trim_type_tag(short) - strtk_register_trim_type_tag(int) - strtk_register_trim_type_tag(long) - strtk_register_trim_type_tag(long long) - strtk_register_trim_type_tag(unsigned char) - strtk_register_trim_type_tag(unsigned short) - strtk_register_trim_type_tag(unsigned int) - strtk_register_trim_type_tag(unsigned long) - strtk_register_trim_type_tag(unsigned long long int) - strtk_register_trim_type_tag(std::string) - - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - strtk_register_trim_type_tag(truncated_int) - - strtk_register_truncint_type_tag(short) - strtk_register_truncint_type_tag(int) - strtk_register_truncint_type_tag(long) - strtk_register_truncint_type_tag(long long) - strtk_register_truncint_type_tag(unsigned short) - strtk_register_truncint_type_tag(unsigned int) - strtk_register_truncint_type_tag(unsigned long) - strtk_register_truncint_type_tag(unsigned long long int) - - #define strtk_register_userdef_type_sink(T) \ - namespace strtk { namespace details { strtk_register_sink_type_tag(T) }} - - #undef strtk_register_unsigned_type_tag - #undef strtk_register_signed_type_tag - #undef strtk_register_real_type_tag - #undef strtk_register_byte_type_tag - #undef strtk_register_hex_number_type_tag - #undef strtk_register_base64_type_tag - #undef strtk_register_supported_iterator_type - #undef strtk_register_stdstring_range_type_tag - #undef strtk_register_sequence_iterator_type - #undef strtk_register_stl_container_to_string_conv_type_tag - #undef strtk_register_inrange_type_tag - #undef strtk_register_trim_type_tag - #undef strtk_register_truncint_type_tag - - template - struct precision - { static void set(std::iostream&) {} }; - - #define strtk_register_iostream_precision(T) \ - template<> struct precision { static void set(std::iostream& s, const std::streamsize& p = 10) { s.precision(p);} }; - - strtk_register_iostream_precision(float) - strtk_register_iostream_precision(double) - strtk_register_iostream_precision(long double) - - #undef strtk_register_iostream_precision - - template - inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, T& t, not_supported_type_tag) - { - #ifdef strtk_enable_lexical_cast - try - { - t = boost::lexical_cast(std::string(begin,end)); - } - catch (const boost::bad_lexical_cast&) - { - return false; - } - begin = end; - return true; - #else - try - { - std::stringstream ss(std::string(begin,end)); - ss >> t; - } - catch (const std::exception&) - { - return false; - } - begin = end; - return true; - #endif - } - - template - inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, strtk::util::value& v, value_type_tag) - { - return v(begin,end); - } - - template - inline bool string_to_type_converter_impl(Iterator& begin, const Iterator end, std::string& t, stdstring_type_tag) - { - t.assign(begin,end); - begin = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Expect& t, expect_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Like& t, like_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, InRange& t, inrange_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, TrimToken& t, trim_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, CaseToken& t, lcase_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, CaseToken& t, ucase_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Array& t, fillchararray_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, TruncatedInt& t, truncint_type_tag) - { - if (!t(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& result, unsigned_type_tag) - { - if (end == itr_external) return false; - - Iterator itr = itr_external; - - if ('+' == (*itr)) - ++itr; - - if (end == itr) - return false; - - while ((end != itr) && ('0' == (*itr))) ++itr; - const std::size_t length = std::distance(itr,end); - - if (length > numeric::length) - return false; - - static const std::size_t bound_length = numeric::bound_length; - T t = 0; - - if (0 != length) - { - std::size_t interim_length = std::min(bound_length,length); - const Iterator interim_end = itr + interim_length; - unsigned int digit[8]; - T t0 = 0; - T t1 = 0; - T t2 = 0; - T t3 = 0; - - //Needed for incompetent and broken msvc compiler versions - #ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable: 4127) - #endif - - while (interim_length > 7) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9) || - ((digit[2] = (itr[2] - '0')) > 9) || - ((digit[3] = (itr[3] - '0')) > 9) || - ((digit[4] = (itr[4] - '0')) > 9) || - ((digit[5] = (itr[5] - '0')) > 9) || - ((digit[6] = (itr[6] - '0')) > 9) || - ((digit[7] = (itr[7] - '0')) > 9)) - return false; - else - { - t0 = static_cast(digit[0] * 10000000 + digit[1] * 1000000); - t1 = static_cast(digit[2] * 100000 + digit[3] * 10000); - t2 = static_cast(digit[4] * 1000 + digit[5] * 100); - t3 = static_cast(digit[6] * 10 + digit[7] ); - t = t0 + t1 + t2 + t3 + static_cast(t * 100000000); - itr += 8; - interim_length -= 8; - } - } - - while (interim_length > 3) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9) || - ((digit[2] = (itr[2] - '0')) > 9) || - ((digit[3] = (itr[3] - '0')) > 9)) - return false; - else - { - t1 = static_cast(digit[0] * 1000 + digit[1] * 100); - t2 = static_cast(digit[2] * 10 + digit[3] ); - t3 = static_cast(t * 10000 ); - t = t1 + t2 + t3; - itr += 4; - interim_length -= 4; - } - } - - while (interim_length > 1) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9)) - return false; - else - { - t1 = static_cast(digit[0] * 10 + digit[1]); - t2 = static_cast(t * 100 ); - t = t1 + t2; - itr += 2; - interim_length -= 2; - } - } - - //Needed for incompetent and broken msvc compiler versions. - #ifdef _MSC_VER - #pragma warning(pop) - #endif - - if (interim_length) - { - if ((digit[0] = (itr[0] - '0')) < 10) - { - t = static_cast(digit[0] + t * 10); - ++itr; - } - else - return false; - } - - if (interim_end != end) - { - if (1 == std::distance(interim_end,end)) - { - typedef unsigned long long int num_type; - static const num_type max = static_cast(std::numeric_limits::max()); - static const num_type penultimate_bound = static_cast(max / 10); - static const num_type final_digit = static_cast(max % 10); - - digit[0] = static_cast(*itr - '0'); - if (digit[0] <= 9) - { - if (t > penultimate_bound) - return false; - else if ((penultimate_bound == t) && (final_digit < digit[0])) - return false; - t = static_cast(digit[0] + t * 10); - } - else - return false; - } - else - return false; - } - } - - result = static_cast(t); - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& result, signed_type_tag) - { - if (end == itr_external) return false; - - Iterator itr = itr_external; - - bool negative = false; - - if ('+' == (*itr)) - ++itr; - else if ('-' == (*itr)) - { - ++itr; - negative = true; - } - - if (end == itr) return false; - - while ((end != itr) && ('0' == (*itr))) ++itr; - - const std::size_t length = std::distance(itr,end); - - if (length > numeric::length) - return false; - - static const std::size_t bound_length = numeric::bound_length; - T t = 0; - - if (0 != length) - { - std::size_t interim_length = std::min(bound_length,length); - const Iterator interim_end = itr + interim_length; - unsigned int digit[8]; - T t0 = 0; - T t1 = 0; - T t2 = 0; - T t3 = 0; - - //Needed for incompetent and broken msvc compiler versions - #ifdef _MSC_VER - #pragma warning(push) - #pragma warning(disable: 4127) - #endif - - while (interim_length > 7) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9) || - ((digit[2] = (itr[2] - '0')) > 9) || - ((digit[3] = (itr[3] - '0')) > 9) || - ((digit[4] = (itr[4] - '0')) > 9) || - ((digit[5] = (itr[5] - '0')) > 9) || - ((digit[6] = (itr[6] - '0')) > 9) || - ((digit[7] = (itr[7] - '0')) > 9) ) - return false; - else - { - t0 = static_cast(digit[0] * 10000000 + digit[1] * 1000000); - t1 = static_cast(digit[2] * 100000 + digit[3] * 10000); - t2 = static_cast(digit[4] * 1000 + digit[5] * 100); - t3 = static_cast(digit[6] * 10 + digit[7] ); - t = t0 + t1 + t2 + t3 + static_cast(t * 100000000); - itr += 8; - interim_length -= 8; - } - } - - while (interim_length > 3) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9) || - ((digit[2] = (itr[2] - '0')) > 9) || - ((digit[3] = (itr[3] - '0')) > 9) ) - return false; - else - { - t0 = static_cast(digit[0] * 1000 + digit[1] * 100); - t1 = static_cast(digit[2] * 10 + digit[3] ); - t = t0 + t1 + static_cast(t * 10000); - itr += 4; - interim_length -= 4; - } - } - - while (interim_length > 2) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9) || - ((digit[2] = (itr[2] - '0')) > 9)) - return false; - else - { - t0 = static_cast(digit[0] * 100 + digit[1] * 10); - t1 = static_cast(t * 1000 + digit[2] ); - t = t0 + t1; - itr += 3; - interim_length -= 3; - } - } - - while (interim_length > 1) - { - if (((digit[0] = (itr[0] - '0')) > 9) || - ((digit[1] = (itr[1] - '0')) > 9)) - return false; - else - { - t0 = static_cast(digit[0] * 10 + digit[1]); - t = t0 + static_cast(t * 100); - itr += 2; - interim_length -= 2; - } - } - - //Needed for incompetent and broken msvc compiler versions. - #ifdef _MSC_VER - #pragma warning(pop) - #endif - - if (interim_length) - { - if ((digit[0] = (itr[0] - '0')) < 10) - { - t = static_cast(digit[0] + t * 10); - ++itr; - } - else - return false; - } - - if (interim_end != end) - { - if (1 == std::distance(interim_end,end)) - { - typedef unsigned long long int num_type; - static const num_type max = static_cast(std::numeric_limits::max()); - static const num_type min = static_cast(static_cast(-1) * std::numeric_limits::min()); - static const num_type positive_penultimate_bound = static_cast(max / 10); - static const num_type negative_penultimate_bound = static_cast(min / 10); - static const num_type positive_final_digit = static_cast(max % 10); - static const num_type negative_final_digit = static_cast(min % 10); - - digit[0] = static_cast(*itr - '0'); - - if (digit[0] < 10) - { - if (negative) - { - if (static_cast(t) > negative_penultimate_bound) - return false; - else if ( - (negative_penultimate_bound == static_cast(t)) && - (negative_final_digit < digit[0]) - ) - return false; - } - else - { - if (static_cast(t) > positive_penultimate_bound) - return false; - else if ( - (positive_penultimate_bound == static_cast(t)) && - (positive_final_digit < digit[0]) - ) - return false; - } - t = static_cast(digit[0] + t * 10); - } - else - return false; - } - else - return false; - } - } - itr_external = itr; - result = static_cast((negative) ? -t : t); - return true; - } - - template - inline bool string_to_type_converter_impl_ref(Iterator& itr, const Iterator end, T& result, signed_type_tag) - { - if (end == itr) return false; - - T t = 0; - bool negative = false; - - if ('+' == (*itr)) - ++itr; - else if ('-' == (*itr)) - { - ++itr; - negative = true; - } - - if (end == itr) - return false; - - unsigned int digit_count = 0; - while ((end != itr) && ('0' == (*itr))) ++itr; - - bool return_result = true; - while (end != itr) - { - const unsigned char digit = (*itr - '0'); - if (digit > 9) - { - return_result = false; - break; - } - - if ((++digit_count) <= numeric::bound_length) - { - t *= 10; - t += digit; - } - else - { - typedef unsigned long long int base_type; - static const base_type max_limit = +std::numeric_limits::max(); - static const base_type min_limit = -std::numeric_limits::min(); - base_type tmp = static_cast(t) * 10 + digit; - if (negative && static_cast(tmp) > min_limit) - return_result = false; - else if (static_cast(tmp) > max_limit) - return_result = false; - t = static_cast(tmp); - } - ++itr; - } - - result = static_cast((negative) ? -t : t); - return return_result; - } - - template - inline bool parse_nan(Iterator& itr, const Iterator end, T& t) - { - typedef typename std::iterator_traits::value_type type; - static const std::size_t nan_length = 3; - if (std::distance(itr,end) != static_cast(nan_length)) - return false; - if (static_cast('n') == (*itr)) - { - if ((static_cast('a') != *(itr + 1)) || (static_cast('n') != *(itr + 2))) - { - return false; - } - } - else if ((static_cast('A') != *(itr + 1)) || (static_cast('N') != *(itr + 2))) - { - return false; - } - t = std::numeric_limits::quiet_NaN(); - return true; - } - - template - inline bool parse_inf(Iterator& itr, const Iterator end, T& t, bool negative) - { - static const char inf_uc[] = "INFINITY"; - static const char inf_lc[] = "infinity"; - static const std::size_t inf_length = 8; - const std::size_t length = std::distance(itr,end); - if ((3 != length) && (inf_length != length)) - return false; - const char* inf_itr = ('i' == (*itr)) ? inf_lc : inf_uc; - while (end != itr) - { - if (*inf_itr == static_cast(*itr)) - { - ++itr; - ++inf_itr; - continue; - } - else - return false; - } - if (negative) - t = -std::numeric_limits::infinity(); - else - t = std::numeric_limits::infinity(); - return true; - } - - template struct real_type {}; - template <> struct real_type { typedef double type; }; - template <> struct real_type { typedef double type; }; - template <> struct real_type { typedef long double type; }; - - template - inline bool string_to_type_converter_impl(Iterator& itr_external, const Iterator end, T& t, real_type_tag) - { - typedef typename real_type::type real_t; - if (end == itr_external) return false; - Iterator itr = itr_external; - real_t d = real_t(0); - bool negative = false; - if ('+' == (*itr)) - ++itr; - else if ('-' == (*itr)) - { - ++itr; - negative = true; - } - - if (end == itr) - return false; - - if (('I' <= (*itr)) && ((*itr) <= 'n')) - { - if (('i' == (*itr)) || ('I' == (*itr))) - { - return parse_inf(itr,end,t,negative); - } - else if (('n' == (*itr)) || ('N' == (*itr))) - { - return parse_nan(itr,end,t); - } - else - return false; - } - - bool instate = false; - int pre_decimal = 0; - - if ('.' != (*itr)) - { - const Iterator curr = itr; - while ((end != itr) && ('0' == (*itr))) ++itr; - const Iterator post_zero_cull_itr = itr; - unsigned char digit = 0; - - #define parse_digit_1 \ - if ((digit = static_cast((*itr) - '0')) < 10) { d *= real_t(10); d += digit; } else break; if (end == ++itr) break; \ - - #define parse_digit_2 \ - if ((digit = static_cast((*itr) - '0')) < 10) { d *= real_t(10); d += digit; } else break; ++itr;\ - - while (end != itr) - { - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_2 - } - #undef parse_digit_1 - #undef parse_digit_2 - if (curr != itr) instate = true; - pre_decimal = static_cast(std::distance(post_zero_cull_itr,itr)); - } - - int exponent = 0; - - if (end != itr) - { - if ('.' == (*itr)) - { - ++itr; - const Iterator curr = itr; - unsigned char digit = 0; - - #define parse_digit_1 \ - if ((digit = static_cast((*itr) - '0')) < 10) { d *= real_t(10); d += digit; } else break; if (end == ++itr) break; \ - - #define parse_digit_2 \ - if ((digit = static_cast((*itr) - '0')) < 10) { d *= real_t(10); d += digit; } else break; ++itr;\ - - while (end != itr) - { - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_1 - parse_digit_2 - } - #undef parse_digit_1 - #undef parse_digit_2 - if (curr != itr) instate = true; - exponent -= static_cast(std::distance(curr,itr)); - } - - if (end != itr) - { - typename std::iterator_traits::value_type c = (*itr); - - if (('e' == c) || ('E' == c)) - { - ++itr; - int exp = 0; - if (!details::string_to_type_converter_impl_ref(itr,end,exp,details::signed_type_tag())) - { - if (end == itr) - return false; - else - c = (*itr); - } - - if ((exp < numeric::min_exp) || (numeric::max_exp < exp)) - return false; - - exponent += exp; - } - - if (('f' == c) || ('F' == c) || ('l' == c) || ('L' == c)) - ++itr; - else if ('#' == c) - { - ++itr; - if (end == itr) - return false; - if ((10.0 != d) || (exponent != -1)) - return false; - if (('I' <= (*itr)) && ((*itr) <= 'n')) - { - if (('i' == (*itr)) || ('I' == (*itr))) - { - return parse_inf(itr,end,t,negative); - } - else if (('n' == (*itr)) || ('N' == (*itr))) - { - return parse_nan(itr,end,t); - } - else - return false; - } - return false; - } - } - } - - if ((end != itr) || (!instate)) - return false; - - if (0 != exponent) - { - if ( - (std::numeric_limits::max_exponent10 < (exponent + pre_decimal)) || - (std::numeric_limits::min_exponent10 > (exponent + pre_decimal)) - ) - { - return false; - } - - const int e = std::abs(exponent); - static const double fract10[] = - { - 0.0, - 1.0E+001, 1.0E+002, 1.0E+003, 1.0E+004, 1.0E+005, 1.0E+006, 1.0E+007, 1.0E+008, 1.0E+009, 1.0E+010, - 1.0E+011, 1.0E+012, 1.0E+013, 1.0E+014, 1.0E+015, 1.0E+016, 1.0E+017, 1.0E+018, 1.0E+019, 1.0E+020, - 1.0E+021, 1.0E+022, 1.0E+023, 1.0E+024, 1.0E+025, 1.0E+026, 1.0E+027, 1.0E+028, 1.0E+029, 1.0E+030, - 1.0E+031, 1.0E+032, 1.0E+033, 1.0E+034, 1.0E+035, 1.0E+036, 1.0E+037, 1.0E+038, 1.0E+039, 1.0E+040, - 1.0E+041, 1.0E+042, 1.0E+043, 1.0E+044, 1.0E+045, 1.0E+046, 1.0E+047, 1.0E+048, 1.0E+049, 1.0E+050, - 1.0E+051, 1.0E+052, 1.0E+053, 1.0E+054, 1.0E+055, 1.0E+056, 1.0E+057, 1.0E+058, 1.0E+059, 1.0E+060, - 1.0E+061, 1.0E+062, 1.0E+063, 1.0E+064, 1.0E+065, 1.0E+066, 1.0E+067, 1.0E+068, 1.0E+069, 1.0E+070, - 1.0E+071, 1.0E+072, 1.0E+073, 1.0E+074, 1.0E+075, 1.0E+076, 1.0E+077, 1.0E+078, 1.0E+079, 1.0E+080, - 1.0E+081, 1.0E+082, 1.0E+083, 1.0E+084, 1.0E+085, 1.0E+086, 1.0E+087, 1.0E+088, 1.0E+089, 1.0E+090, - 1.0E+091, 1.0E+092, 1.0E+093, 1.0E+094, 1.0E+095, 1.0E+096, 1.0E+097, 1.0E+098, 1.0E+099, 1.0E+100, - 1.0E+101, 1.0E+102, 1.0E+103, 1.0E+104, 1.0E+105, 1.0E+106, 1.0E+107, 1.0E+108, 1.0E+109, 1.0E+110, - 1.0E+111, 1.0E+112, 1.0E+113, 1.0E+114, 1.0E+115, 1.0E+116, 1.0E+117, 1.0E+118, 1.0E+119, 1.0E+120, - 1.0E+121, 1.0E+122, 1.0E+123, 1.0E+124, 1.0E+125, 1.0E+126, 1.0E+127, 1.0E+128, 1.0E+129, 1.0E+130, - 1.0E+131, 1.0E+132, 1.0E+133, 1.0E+134, 1.0E+135, 1.0E+136, 1.0E+137, 1.0E+138, 1.0E+139, 1.0E+140, - 1.0E+141, 1.0E+142, 1.0E+143, 1.0E+144, 1.0E+145, 1.0E+146, 1.0E+147, 1.0E+148, 1.0E+149, 1.0E+150, - 1.0E+151, 1.0E+152, 1.0E+153, 1.0E+154, 1.0E+155, 1.0E+156, 1.0E+157, 1.0E+158, 1.0E+159, 1.0E+160, - 1.0E+161, 1.0E+162, 1.0E+163, 1.0E+164, 1.0E+165, 1.0E+166, 1.0E+167, 1.0E+168, 1.0E+169, 1.0E+170, - 1.0E+171, 1.0E+172, 1.0E+173, 1.0E+174, 1.0E+175, 1.0E+176, 1.0E+177, 1.0E+178, 1.0E+179, 1.0E+180, - 1.0E+181, 1.0E+182, 1.0E+183, 1.0E+184, 1.0E+185, 1.0E+186, 1.0E+187, 1.0E+188, 1.0E+189, 1.0E+190, - 1.0E+191, 1.0E+192, 1.0E+193, 1.0E+194, 1.0E+195, 1.0E+196, 1.0E+197, 1.0E+198, 1.0E+199, 1.0E+200, - 1.0E+201, 1.0E+202, 1.0E+203, 1.0E+204, 1.0E+205, 1.0E+206, 1.0E+207, 1.0E+208, 1.0E+209, 1.0E+210, - 1.0E+211, 1.0E+212, 1.0E+213, 1.0E+214, 1.0E+215, 1.0E+216, 1.0E+217, 1.0E+218, 1.0E+219, 1.0E+220, - 1.0E+221, 1.0E+222, 1.0E+223, 1.0E+224, 1.0E+225, 1.0E+226, 1.0E+227, 1.0E+228, 1.0E+229, 1.0E+230, - 1.0E+231, 1.0E+232, 1.0E+233, 1.0E+234, 1.0E+235, 1.0E+236, 1.0E+237, 1.0E+238, 1.0E+239, 1.0E+240, - 1.0E+241, 1.0E+242, 1.0E+243, 1.0E+244, 1.0E+245, 1.0E+246, 1.0E+247, 1.0E+248, 1.0E+249, 1.0E+250, - 1.0E+251, 1.0E+252, 1.0E+253, 1.0E+254, 1.0E+255, 1.0E+256, 1.0E+257, 1.0E+258, 1.0E+259, 1.0E+260, - 1.0E+261, 1.0E+262, 1.0E+263, 1.0E+264, 1.0E+265, 1.0E+266, 1.0E+267, 1.0E+268, 1.0E+269, 1.0E+270, - 1.0E+271, 1.0E+272, 1.0E+273, 1.0E+274, 1.0E+275, 1.0E+276, 1.0E+277, 1.0E+278, 1.0E+279, 1.0E+280, - 1.0E+281, 1.0E+282, 1.0E+283, 1.0E+284, 1.0E+285, 1.0E+286, 1.0E+287, 1.0E+288, 1.0E+289, 1.0E+290, - 1.0E+291, 1.0E+292, 1.0E+293, 1.0E+294, 1.0E+295, 1.0E+296, 1.0E+297, 1.0E+298, 1.0E+299, 1.0E+300, - 1.0E+301, 1.0E+302, 1.0E+303, 1.0E+304, 1.0E+305, 1.0E+306, 1.0E+307, 1.0E+308 - }; - - static const std::size_t fract10_size = sizeof(fract10) / sizeof(double); - - if (d != real_t(0)) - { - if (static_cast(e) < fract10_size) - { - if (exponent > 0) - d *= fract10[e]; - else - d /= fract10[e]; - } - else - d *= std::pow(real_t(10), real_t(10) * exponent); - } - } - - t = static_cast((negative) ? -d : d); - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, T& t, byte_type_tag) - { - if (1 != std::distance(itr,end)) - return false; - t = static_cast(*itr); - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, bool& t, bool_type_tag) - { - if (1 != std::distance(itr,end)) - return false; - t = (('0' == (*itr)) ? false : true); - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, IgnoreTokenType&, ignore_token_type_tag) - { - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, HexSinkType& t, hex_number_type_tag) - { - t = std::pair(itr,end); - if (!t.valid()) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, HexSinkType& t, hex_string_type_tag) - { - t = std::pair(itr,end); - if (!t.valid()) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, Base64SinkType& t, base64_type_tag) - { - t = std::pair(itr,end); - if (!t.valid()) - return false; - itr = end; - return true; - } - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, SinkType& t, sink_type_tag) - { - if (!t.parse(itr,end)) - return false; - itr = end; - return true; - } - - template - inline bool type_to_string_converter_impl(const T& t, std::string& s, not_supported_type_tag) - { - #ifdef strtk_enable_lexical_cast - try - { - s = boost::lexical_cast(t); - } - catch (const boost::bad_lexical_cast&) - { - return false; - } - #else - try - { - std::stringstream ss; - precision::set(ss); - ss << t; - s = ss.str(); - } - catch (const std::exception&) - { - return false; - } - #endif - return true; - } - - template - inline bool type_to_string_converter_impl(T value, std::string& result, unsigned_type_tag) - { - static const std::size_t radix = 10; - static const std::size_t radix_sqr = radix * radix; - static const std::size_t radix_cube = radix * radix * radix; - static const std::size_t buffer_size = ((strtk::details::numeric::size < 16) ? 16 : 32); - unsigned char buffer[buffer_size]; - unsigned char* itr = buffer + buffer_size; - - if (value) - { - while (value >= static_cast(radix_sqr)) - { - itr -= 3; - T temp_v = value / radix_cube; - memcpy(itr,&details::rev_3digit_lut[3 * (value - (temp_v * radix_cube))],3); - value = temp_v; - } - - while (value >= static_cast(radix)) - { - itr -= 2; - T temp_v = value / radix_sqr; - memcpy(itr,&details::rev_2digit_lut[2 * (value - (temp_v * radix_sqr))],2); - value = temp_v; - } - - if (value) - { - *(--itr) = static_cast('0' + value); - } - } - else - *(--itr) = '0'; - - result.assign(reinterpret_cast(itr), (buffer + buffer_size) - itr); - return true; - } - - template - struct tsci_type {}; - - #define define_tsci_type(Type,ReType) \ - template <> \ - struct tsci_type \ - { \ - typedef ReType type; \ - }; \ - - define_tsci_type(short ,unsigned short ) - define_tsci_type(int ,unsigned int ) - define_tsci_type(long ,unsigned long ) - define_tsci_type(long long,unsigned long long) - - #undef define_tsci_type - - template - inline bool type_to_string_converter_impl(T valuex, std::string& result, signed_type_tag) - { - static const std::size_t radix = 10; - static const std::size_t radix_sqr = radix * radix; - static const std::size_t radix_cube = radix * radix * radix; - static const std::size_t buffer_size = ((strtk::details::numeric::size < 16) ? 16 : 32); - unsigned char buffer[buffer_size]; - unsigned char* itr = buffer + buffer_size; - bool negative = (valuex < 0); - typedef typename tsci_type::type TT; - TT value = (negative) ? -valuex : valuex; - - if (value) - { - while (value >= static_cast(radix_sqr)) - { - itr -= 3; - T temp_v = value / radix_cube; - memcpy(itr,&details::rev_3digit_lut[3 * (value - (temp_v * radix_cube))],3); - value = temp_v; - } - - while (value >= static_cast(radix)) - { - itr -= 2; - T temp_v = value / radix_sqr; - memcpy(itr,&details::rev_2digit_lut[2 * (value - (temp_v * radix_sqr))],2); - value = temp_v; - } - - if (value) - { - *(--itr) = static_cast('0' + value); - } - - if (negative) - { - *(--itr) = '-'; - } - } - else - *(--itr) = '0'; - - result.assign(reinterpret_cast(itr), (buffer + buffer_size) - itr); - return true; - } - - template - inline bool type_to_string_converter_impl(const T& value, std::string& result, byte_type_tag) - { - result.resize(1); - result[0] = static_cast(value); - return true; - } - - inline bool type_to_string_converter_impl(const bool& value, std::string& result, bool_type_tag) - { - result.resize(1); - result[0] = value ? '1' : '0'; - return true; - } - - inline bool type_to_string_converter_impl(const std::string& value, std::string& result, stdstring_type_tag) - { - result = value; - return true; - } - - template - inline bool type_to_string_converter_impl(const std::pair& range, std::string& result, stdstring_range_type_tag) - { - result.assign(range.first,range.second); - return true; - } - - template - inline bool type_to_string_converter_impl(const SinkType&, std::string&, sink_type_tag) - { - //Generic conversion not supported for sinks. Use joins or custom converters. - return false; - } - - template - inline bool type_to_string_converter_impl(const STLContainerType&, std::string&, stl_seq_type_tag) - { - //Generic conversion not supported for stl containers. Use joins or custom converters. - return false; - } - - template - inline std::string type_name() - { - static const std::string s("Unknown"); - return s; - } - - #define strtk_register_type_name(Type) \ - template <> inline std::string type_name() { static const std::string s(#Type); return s; } - - strtk_register_type_name(signed char) - strtk_register_type_name(unsigned char) - strtk_register_type_name(short) - strtk_register_type_name(int) - strtk_register_type_name(long) - strtk_register_type_name(long long) - strtk_register_type_name(unsigned short) - strtk_register_type_name(unsigned int) - strtk_register_type_name(unsigned long) - strtk_register_type_name(unsigned long long int) - strtk_register_type_name(double) - strtk_register_type_name(float) - strtk_register_type_name(long double) - strtk_register_type_name(std::string) - - #undef strtk_register_type_name - - template - inline std::string type_name(const T&) - { - static const std::string s = type_name(); - return s; - } - - template - inline std::string type_name(const std::pair& p) - { - static const std::string s = std::string("std::pair<" + - type_name(p.first) + - "," + - type_name(p.second) + - ">"); - return s; - } - - template - inline std::size_t type_length() - { - return numeric::length; - } - - template - inline std::size_t type_length(const T&) - { - return type_length(); - } - - inline std::size_t type_length(const std::string& s) - { - return s.size(); - } - - template - inline std::size_t type_length(const std::pair&) - { - return type_length() + type_length(); - } - - } // namespace details - - template - inline std::string type_name(const T& t) - { - static const std::string s = details::type_name(t); - return s; - } - - template - inline std::string type_name(const T(&)[N]) - { - static const std::string s = details::type_name() + - std::string("[") + type_to_string(N) + std::string("]"); - return s; - } - - template - inline std::string type_name(const std::pair& p) - { - static const std::string s = std::string("std::pair<" + - type_name(p.first) + - "," + - type_name(p.second) + - ">"); - return s; - } - - #define strtk_register_sequence_type_name(Type) \ - template \ - inline std::string type_name(const Type&) \ - { \ - static const std::string s = std::string(#Type) + std::string("<" + details::type_name() + ">");\ - return s; \ - } \ - - #define strtk_register_set_type_name(Type) \ - template \ - inline std::string type_name(const Type&) \ - { \ - static const std::string s = std::string(#Type) + std::string("<" + details::type_name() + ">");\ - return s; \ - } \ - - strtk_register_sequence_type_name(std::vector) - strtk_register_sequence_type_name(std::deque) - strtk_register_sequence_type_name(std::list) - strtk_register_set_type_name(std::set) - strtk_register_set_type_name(std::multiset) - - template - inline std::size_t type_length() - { - return details::type_length(); - } - - template - inline std::size_t type_length(const T&) - { - return type_length(); - } - - class ext_string - { - public: - - explicit ext_string() - {} - - explicit ext_string(const std::string& s) - : s_(s) - {} - - explicit ext_string(const char* s) - : s_(s) - {} - - explicit ext_string(const range::adapter& r) - : s_(r.begin(),r.end()) - {} - - ext_string(const ext_string& es) - : s_(es.s_) - {} - - template - inline ext_string& operator << (const T& t) - { - s_ += type_to_string(t); - return (*this); - } - - inline operator std::string () const - { - return s_; - } - - inline std::string clone() const - { - return s_; - } - - inline const std::string& as_string() const - { - return s_; - } - - inline std::string& as_string() - { - return s_; - } - - template - inline T as_type() const - { - return string_to_type_converter(s_); - } - - template - inline bool as_type(T& t) const - { - return string_to_type_converter(s_,t); - } - - inline bool imatch(const std::string& s) const - { - return strtk::imatch(s_,s); - } - - inline bool imatch(const ext_string& es) const - { - return strtk::imatch(s_,es.s_); - } - - inline ext_string& to_lowercase() - { - convert_to_lowercase(s_); - return (*this); - } - - inline ext_string& to_uppercase() - { - convert_to_uppercase(s_); - return (*this); - } - - template - inline ext_string& remove_leading(const Predicate& p) - { - if (s_.empty()) return (*this); - strtk::remove_leading(p,s_); - return (*this); - } - - inline ext_string& remove_leading(const std::string& removal_set) - { - if (removal_set.empty()) - return (*this); - else if (1 == removal_set.size()) - strtk::remove_leading(single_delimiter_predicate(removal_set[0]),s_); - else - strtk::remove_leading(multiple_char_delimiter_predicate(removal_set),s_); - return (*this); - } - - template - inline ext_string& remove_trailing(const Predicate& p) - { - if (s_.empty()) return (*this); - strtk::remove_trailing(p,s_); - return (*this); - } - - inline ext_string& remove_trailing(const std::string& removal_set) - { - if (removal_set.empty()) - return (*this); - else if (1 == removal_set.size()) - strtk::remove_trailing(single_delimiter_predicate(removal_set[0]),s_); - else - strtk::remove_trailing(multiple_char_delimiter_predicate(removal_set),s_); - return (*this); - } - - template - inline ext_string& operator += (const T& t) - { - s_.append(type_to_string(t)); - return (*this); - } - - inline ext_string& operator -= (const std::string& pattern) - { - replace(pattern,""); - return (*this); - } - - inline ext_string& operator *= (const std::size_t& n) - { - strtk::replicate_inplace(n,s_); - return (*this); - } - - inline void replace(const std::string& pattern, const std::string& replace_pattern) - { - std::string result; - result.reserve(s_.size()); - strtk::replace_pattern(s_,pattern,replace_pattern,result); - s_.assign(result); - } - - template - inline std::size_t split(const DelimiterPredicate& p, - OutputIterator out, - const split_options::type split_option = split_options::default_mode) const - { - return strtk::split(p,s_,out,split_option); - } - - template class Sequence> - inline std::size_t split(const DelimiterPredicate& p, - Sequence& seq, - const split_options::type split_option = split_options::default_mode) const - { - return strtk::split(p,s_,range_to_type_back_inserter(seq),split_option); - } - - template - inline std::size_t split_n(const DelimiterPredicate& p, - const std::size_t& n, - OutputIterator out, - const split_options::type split_option = split_options::default_mode) const - { - return strtk::split_n(p,s_,n,out,split_option); - } - - template class Sequence> - inline std::size_t split_n(const DelimiterPredicate& p, - const std::size_t& n, - Sequence& seq, - const split_options::type split_option = split_options::default_mode) const - { - return strtk::split_n(p,s_,n,range_to_type_back_inserter(seq),split_option); - } - - template class Sequence> - inline std::size_t parse(const std::string& delimiters, Sequence& seq) const - { - return strtk::parse(s_,delimiters,seq); - } - - template class Sequence> - inline std::size_t parse(const char* delimiters, Sequence& seq) const - { - return parse(std::string(delimiters),seq); - } - - friend inline ext_string operator * (const std::size_t& n, const ext_string& s); - friend inline ext_string operator * (const ext_string& s, const std::size_t& n); - - template - friend inline ext_string operator + (const ext_string& s, const T& t); - - template - friend inline ext_string operator + (const T& t, const ext_string& s); - - friend inline ext_string operator - (const ext_string& s, const std::string& pattern); - friend inline ext_string operator - (const ext_string& s, const char* pattern); - friend inline ext_string operator - (const ext_string& s, const ext_string& pattern); - - static inline ext_string all_digits() - { - static const ext_string digits("0123456789"); - return digits; - } - - static inline ext_string all_letters() - { - static const ext_string letters("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"); - return letters; - } - - static inline ext_string all_lowercase_letters() - { - static const ext_string letters("abcdefghijklmnopqrstuvwxyz"); - return letters; - } - - static inline ext_string all_uppercase_letters() - { - static const ext_string letters("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); - return letters; - } - - static inline ext_string all_chars() - { - ext_string s; - s.as_string().resize(256); - strtk::iota(s.as_string().begin(), - s.as_string().end(), - static_cast(0x00)); - return s; - } - - private: - - std::string s_; - }; - - inline ext_string operator * (const std::size_t& n, const ext_string& s) - { - return ext_string(replicate(n, s.s_)); - } - - inline ext_string operator * (const ext_string& s, const std::size_t& n) - { - return ext_string(replicate(n, s.s_)); - } - - template - inline ext_string operator + (const ext_string& s, const T& t) - { - return ext_string(s.s_ + type_to_string(t)); - } - - template - inline ext_string operator + (const T& t, const ext_string& s) - { - return ext_string(type_to_string(t) + s.s_); - } - - inline ext_string operator - (const ext_string& s, const std::string& pattern) - { - std::string tmp; - tmp.reserve(s.s_.size()); - remove_pattern(s,pattern,tmp); - return ext_string(tmp); - } - - inline ext_string operator - (const ext_string& s, const char* pattern) - { - return s - std::string(pattern); - } - - inline ext_string operator - (const ext_string& s, const ext_string& pattern) - { - return s - std::string(pattern.as_string()); - } - - static inline std::ostream& operator<<(std::ostream& os, const ext_string& es) - { - return (os << es.as_string()); - } - - namespace fileio - { - - inline bool file_exists(const std::string& file_name) - { - std::ifstream file(file_name.c_str(), std::ios::binary); - return ((!file) ? false : true); - } - - inline std::size_t file_size(const std::string& file_name) - { - std::ifstream file(file_name.c_str(),std::ios::binary); - if (!file) return 0; - file.seekg (0, std::ios::end); - return static_cast(file.tellg()); - } - - inline bool load_file(const std::string& file_name, char* buffer, std::size_t buffer_size) - { - std::ifstream in_stream(file_name.c_str(),std::ios::binary); - if (!in_stream) return false; - in_stream.read(buffer,static_cast(buffer_size)); - in_stream.close(); - return true; - } - - inline bool load_file(const std::string& file_name, std::string& buffer) - { - buffer.resize(file_size(file_name)); - return load_file(file_name,const_cast(buffer.data()),buffer.size()); - } - - inline bool write_file(const std::string& file_name, char* buffer, const std::size_t& buffer_size) - { - std::ofstream out_stream(file_name.c_str(),std::ios::binary); - if (!out_stream) return false; - out_stream.write(buffer,static_cast(buffer_size)); - out_stream.close(); - return true; - } - - inline bool write_file(const std::string& file_name, const std::string& buffer) - { - return write_file(file_name,const_cast(buffer.data()),buffer.size()); - } - - inline bool copy_file(const std::string& src_file_name, const std::string& dest_file_name) - { - std::ifstream src_file(src_file_name.c_str(),std::ios::binary); - std::ofstream dest_file(dest_file_name.c_str(),std::ios::binary); - if (!src_file) return false; - if (!dest_file) return false; - - static const std::size_t block_size = 16 * one_kilobyte; - char buffer[block_size]; - - std::size_t remaining_bytes = file_size(src_file_name); - - while (remaining_bytes >= block_size) - { - src_file.read(&buffer[0],static_cast(block_size)); - dest_file.write(&buffer[0],static_cast(block_size)); - remaining_bytes -= block_size; - } - - if (remaining_bytes > 0) - { - src_file.read(&buffer[0],static_cast(remaining_bytes)); - dest_file.write(&buffer[0],static_cast(remaining_bytes)); - remaining_bytes = 0; - } - - src_file.close(); - dest_file.close(); - return true; - } - - inline bool concatenate(const std::string& file_name1, - const std::string& file_name2, - const std::string& output_file_name) - { - std::ifstream file1(file_name1.c_str(),std::ios::binary); - std::ifstream file2(file_name2.c_str(),std::ios::binary); - std::ofstream out_file(output_file_name.c_str(),std::ios::binary); - - if (!file1 || !file2 || !out_file) return false; - - static const std::size_t block_size = 16 * one_kilobyte; - char buffer[block_size]; - unsigned int round = 0; - std::size_t remaining_bytes = 0; - - while (round < 2) - { - std::ifstream& input_stream = ((0 == round) ? file1 : file2); - remaining_bytes = ((0 == round) ? file_size(file_name1) : file_size(file_name2)); - - while (remaining_bytes >= block_size) - { - input_stream.read(&buffer[0],static_cast(block_size)); - out_file.write(&buffer[0],static_cast(block_size)); - remaining_bytes -= block_size; - } - - if (remaining_bytes > 0) - { - input_stream.read(&buffer[0],static_cast(remaining_bytes)); - out_file.write(&buffer[0],static_cast(remaining_bytes)); - remaining_bytes = 0; - } - - input_stream.close(); - ++round; - } - out_file.close(); - return true; - } - - inline bool files_identical(const std::string& file_name1, const std::string& file_name2) - { - std::ifstream file1(file_name1.c_str(),std::ios::binary); - std::ifstream file2(file_name2.c_str(),std::ios::binary); - if (!file1) return false; - if (!file2) return false; - if (file_size(file_name1) != file_size(file_name2)) return false; - - static const std::size_t block_size = 16 * one_kilobyte; - char buffer1[block_size]; - char buffer2[block_size]; - - std::size_t remaining_bytes = file_size(file_name1); - - while (remaining_bytes >= block_size) - { - file1.read(&buffer1[0],static_cast(block_size)); - file2.read(&buffer2[0],static_cast(block_size)); - if (0 != std::memcmp(buffer1,buffer2,block_size)) - return false; - remaining_bytes -= block_size; - } - - if (remaining_bytes > 0) - { - file1.read(&buffer1[0],static_cast(remaining_bytes)); - file2.read(&buffer2[0],static_cast(remaining_bytes)); - if (0 != std::memcmp(buffer1,buffer2,remaining_bytes)) - return false; - remaining_bytes = 0; - } - - file1.close(); - file2.close(); - - return true; - } - - namespace details - { - template - inline bool read_pod_proxy(std::ifstream& stream, T& t) - { - return (false == stream.read(reinterpret_cast(&t), - static_cast(sizeof(T))).fail()); - } - - template - inline bool write_pod_proxy(std::ofstream& stream, const T& t) - { - return (false == stream.write(reinterpret_cast(&t), - static_cast(sizeof(T))).fail()); - } - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10) - { - return details::read_pod_proxy(stream, t1) && - details::read_pod_proxy(stream, t2) && - details::read_pod_proxy(stream, t3) && - details::read_pod_proxy(stream, t4) && - details::read_pod_proxy(stream, t5) && - details::read_pod_proxy(stream, t6) && - details::read_pod_proxy(stream, t7) && - details::read_pod_proxy(stream, t8) && - details::read_pod_proxy(stream, t9) && - details::read_pod_proxy(stream,t10); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3) && - details::read_pod_proxy(stream,t4) && - details::read_pod_proxy(stream,t5) && - details::read_pod_proxy(stream,t6) && - details::read_pod_proxy(stream,t7) && - details::read_pod_proxy(stream,t8) && - details::read_pod_proxy(stream,t9); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3) && - details::read_pod_proxy(stream,t4) && - details::read_pod_proxy(stream,t5) && - details::read_pod_proxy(stream,t6) && - details::read_pod_proxy(stream,t7) && - details::read_pod_proxy(stream,t8); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3) && - details::read_pod_proxy(stream,t4) && - details::read_pod_proxy(stream,t5) && - details::read_pod_proxy(stream,t6) && - details::read_pod_proxy(stream,t7); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3) && - details::read_pod_proxy(stream,t4) && - details::read_pod_proxy(stream,t5) && - details::read_pod_proxy(stream,t6); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3) && - details::read_pod_proxy(stream,t4) && - details::read_pod_proxy(stream,t5); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3, T4& t4) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3) && - details::read_pod_proxy(stream,t4); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2, T3& t3) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2) && - details::read_pod_proxy(stream,t3); - } - - template - inline bool read_pod(std::ifstream& stream, - T1& t1, T2& t2) - { - return details::read_pod_proxy(stream,t1) && - details::read_pod_proxy(stream,t2); - } - - template - inline bool read_pod(std::ifstream& stream, T& t) - { - return details::read_pod_proxy(stream,t); - } - - template - inline bool read_pod(std::ifstream& stream, T (&t)[N]) - { - return (false != stream.read(reinterpret_cast(&t[0]),sizeof(T) * N).fail()); - } - - template class Sequence> - inline bool read_pod(std::ifstream& stream, - const std::size_t& count, - Sequence& sequence) - { - T t; - for (std::size_t i = 0; i < count; ++i) - { - if (details::read_pod_proxy(stream,t)) - sequence.push_back(t); - else - return false; - } - return true; - } - - template - inline bool read_pod(std::ifstream& stream, - const std::size_t& count, - std::set& set) - { - T t; - for (std::size_t i = 0; i < count; ++i) - { - if (details::read_pod_proxy(stream,t)) - set.insert(t); - else - return false; - } - return true; - } - - template - inline bool read_pod(std::ifstream& stream, - const std::size_t& count, - std::multiset& multiset) - { - T t; - for (std::size_t i = 0; i < count; ++i) - { - if (details::read_pod_proxy(stream,t)) - multiset.insert(t); - else - return false; - } - return true; - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10) - { - return details::write_pod_proxy(stream, t1) && - details::write_pod_proxy(stream, t2) && - details::write_pod_proxy(stream, t3) && - details::write_pod_proxy(stream, t4) && - details::write_pod_proxy(stream, t5) && - details::write_pod_proxy(stream, t6) && - details::write_pod_proxy(stream, t7) && - details::write_pod_proxy(stream, t8) && - details::write_pod_proxy(stream, t9) && - details::write_pod_proxy(stream,t10); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3) && - details::write_pod_proxy(stream,t4) && - details::write_pod_proxy(stream,t5) && - details::write_pod_proxy(stream,t6) && - details::write_pod_proxy(stream,t7) && - details::write_pod_proxy(stream,t8) && - details::write_pod_proxy(stream,t9); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3) && - details::write_pod_proxy(stream,t4) && - details::write_pod_proxy(stream,t5) && - details::write_pod_proxy(stream,t6) && - details::write_pod_proxy(stream,t7) && - details::write_pod_proxy(stream,t8); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3) && - details::write_pod_proxy(stream,t4) && - details::write_pod_proxy(stream,t5) && - details::write_pod_proxy(stream,t6) && - details::write_pod_proxy(stream,t7); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3) && - details::write_pod_proxy(stream,t4) && - details::write_pod_proxy(stream,t5) && - details::write_pod_proxy(stream,t6); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3) && - details::write_pod_proxy(stream,t4) && - details::write_pod_proxy(stream,t5); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3, const T4& t4) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3) && - details::write_pod_proxy(stream,t4); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2, const T3& t3) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2) && - details::write_pod_proxy(stream,t3); - } - - template - inline bool write_pod(std::ofstream& stream, - const T1& t1, const T2& t2) - { - return details::write_pod_proxy(stream,t1) && - details::write_pod_proxy(stream,t2); - } - - template - inline bool write_pod(std::ofstream& stream, const T& t) - { - return details::write_pod_proxy(stream,t); - } - - template - inline bool write_pod(std::ofstream& stream, T (&t)[N]) - { - return (false != stream.write(reinterpret_cast(&t[0]),sizeof(T) * N).fail()); - } - - template class Sequence> - inline bool write_pod(std::ofstream& stream, - const Sequence& sequence) - { - typename Sequence::iterator itr = sequence.begin(); - typename Sequence::iterator end = sequence.end(); - while (end != itr) - { - if (details::write_pod_proxy(stream,*itr)) - ++itr; - else - return false; - } - } - - template - inline bool write_pod(std::ofstream& stream, - const std::set& set) - { - typename std::set::iterator itr = set.begin(); - typename std::set::iterator end = set.end(); - while (end != itr) - { - if (details::write_pod_proxy(stream,*itr)) - ++itr; - else - return false; - } - } - - template - inline bool write_pod(std::ofstream& stream, - const std::multiset& multiset) - { - typename std::multiset::iterator itr = multiset.begin(); - typename std::multiset::iterator end = multiset.end(); - while (end != itr) - { - if (details::write_pod_proxy(stream,*itr)) - ++itr; - else - return false; - } - } - - inline bool read_at_offset(std::ifstream& stream, - const std::size_t& offset, - char* buffer, - const std::size_t& buffer_size) - { - if (!stream) return false; - stream.seekg(static_cast(offset),std::ios_base::beg); - if (stream.fail()) return false; - stream.read(buffer,static_cast(buffer_size)); - if (stream.fail()) return false; - stream.close(); - return true; - } - - inline bool read_at_offset(const std::string& file_name, - const std::size_t& offset, - char* buffer, - const std::size_t& buffer_size) - { - std::ifstream stream(file_name.c_str(), std::ios::in | std::ios::binary); - if (!stream) return false; - return read_at_offset(stream,offset,buffer,buffer_size); - } - - inline bool read_at_offset(const std::string& file_name, - const std::size_t& offset, - std::string& buffer, - const std::size_t& buffer_size) - { - std::ifstream stream(file_name.c_str(), std::ios::in | std::ios::binary); - if (!stream) return false; - buffer.resize(buffer_size); - return read_at_offset(stream, - offset, - const_cast(buffer.data()), - buffer_size); - } - - } // namespace fileio - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10, T11& t11, T12& t12) - { - t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1); - t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2); - t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3); - t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4); - t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5); - t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6); - t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7); - t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8); - t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9); - t10 = (*reinterpret_cast(data)); data += sizeof(T10); - t11 = (*reinterpret_cast(data)); data += sizeof(T11); - t12 = (*reinterpret_cast(data)); data += sizeof(T12); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10, T11& t11) - { - t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1); - t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2); - t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3); - t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4); - t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5); - t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6); - t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7); - t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8); - t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9); - t10 = (*reinterpret_cast(data)); data += sizeof(T10); - t11 = (*reinterpret_cast(data)); data += sizeof(T11); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9, T10& t10) - { - t1 = (*reinterpret_cast< T1*>(data)); data += sizeof( T1); - t2 = (*reinterpret_cast< T2*>(data)); data += sizeof( T2); - t3 = (*reinterpret_cast< T3*>(data)); data += sizeof( T3); - t4 = (*reinterpret_cast< T4*>(data)); data += sizeof( T4); - t5 = (*reinterpret_cast< T5*>(data)); data += sizeof( T5); - t6 = (*reinterpret_cast< T6*>(data)); data += sizeof( T6); - t7 = (*reinterpret_cast< T7*>(data)); data += sizeof( T7); - t8 = (*reinterpret_cast< T8*>(data)); data += sizeof( T8); - t9 = (*reinterpret_cast< T9*>(data)); data += sizeof( T9); - t10 = (*reinterpret_cast(data)); data += sizeof(T10); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - t4 = (*reinterpret_cast(data)); data += sizeof(T4); - t5 = (*reinterpret_cast(data)); data += sizeof(T5); - t6 = (*reinterpret_cast(data)); data += sizeof(T6); - t7 = (*reinterpret_cast(data)); data += sizeof(T7); - t8 = (*reinterpret_cast(data)); data += sizeof(T8); - t9 = (*reinterpret_cast(data)); data += sizeof(T9); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - t4 = (*reinterpret_cast(data)); data += sizeof(T4); - t5 = (*reinterpret_cast(data)); data += sizeof(T5); - t6 = (*reinterpret_cast(data)); data += sizeof(T6); - t7 = (*reinterpret_cast(data)); data += sizeof(T7); - t8 = (*reinterpret_cast(data)); data += sizeof(T8); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - t4 = (*reinterpret_cast(data)); data += sizeof(T4); - t5 = (*reinterpret_cast(data)); data += sizeof(T5); - t6 = (*reinterpret_cast(data)); data += sizeof(T6); - t7 = (*reinterpret_cast(data)); data += sizeof(T7); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - t4 = (*reinterpret_cast(data)); data += sizeof(T4); - t5 = (*reinterpret_cast(data)); data += sizeof(T5); - t6 = (*reinterpret_cast(data)); data += sizeof(T6); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - t4 = (*reinterpret_cast(data)); data += sizeof(T4); - t5 = (*reinterpret_cast(data)); data += sizeof(T5); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3, T4& t4) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - t4 = (*reinterpret_cast(data)); data += sizeof(T4); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2, T3& t3) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - t3 = (*reinterpret_cast(data)); data += sizeof(T3); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1, T2& t2) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - t2 = (*reinterpret_cast(data)); data += sizeof(T2); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, - T1& t1) - { - t1 = (*reinterpret_cast(data)); data += sizeof(T1); - return data; - } - - template - inline unsigned char* read_pod(unsigned char* data, T (&t)[N]) - { - T* begin = reinterpret_cast(data); - T* end = begin + N; - std::copy(begin,end,&t[0]); - return data + (N * sizeof(T)); - } - - template class Sequence> - inline unsigned char* read_pod(unsigned char* data, - const std::size_t& n, - const Sequence& sequence) - { - T* ptr = reinterpret_cast(data); - std::copy(ptr, ptr + n, std::back_inserter(sequence)); - return data + (sequence.size() * sizeof(T)); - } - - template - inline unsigned char* read_pod(unsigned char* data, - const std::size_t& n, - const std::set& set) - { - T* ptr = reinterpret_cast(data); - std::copy(ptr, ptr + n, std::inserter(set,set.begin())); - return data + (set.size() * sizeof(T)); - } - - template - inline unsigned char* read_pod(unsigned char* data, - const std::size_t& n, - const std::multiset& multiset) - { - T* ptr = reinterpret_cast(data); - std::copy(ptr, ptr + n, std::inserter(multiset,multiset.begin())); - return data + (multiset.size() * sizeof(T)); - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10, const T11& t11, const T12& t12) - { - (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1); - (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2); - (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3); - (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4); - (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5); - (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6); - (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7); - (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8); - (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9); - (*reinterpret_cast(data)) = t10; data += sizeof(T10); - (*reinterpret_cast(data)) = t11; data += sizeof(T11); - (*reinterpret_cast(data)) = t12; data += sizeof(T12); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10, const T11& t11) - { - (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1); - (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2); - (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3); - (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4); - (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5); - (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6); - (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7); - (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8); - (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9); - (*reinterpret_cast(data)) = t10; data += sizeof(T10); - (*reinterpret_cast(data)) = t11; data += sizeof(T11); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9, const T10& t10) - { - (*reinterpret_cast< T1*>(data)) = t1; data += sizeof( T1); - (*reinterpret_cast< T2*>(data)) = t2; data += sizeof( T2); - (*reinterpret_cast< T3*>(data)) = t3; data += sizeof( T3); - (*reinterpret_cast< T4*>(data)) = t4; data += sizeof( T4); - (*reinterpret_cast< T5*>(data)) = t5; data += sizeof( T5); - (*reinterpret_cast< T6*>(data)) = t6; data += sizeof( T6); - (*reinterpret_cast< T7*>(data)) = t7; data += sizeof( T7); - (*reinterpret_cast< T8*>(data)) = t8; data += sizeof( T8); - (*reinterpret_cast< T9*>(data)) = t9; data += sizeof( T9); - (*reinterpret_cast(data)) = t10; data += sizeof(T10); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8, - const T9& t9) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - (*reinterpret_cast(data)) = t4; data += sizeof(T4); - (*reinterpret_cast(data)) = t5; data += sizeof(T5); - (*reinterpret_cast(data)) = t6; data += sizeof(T6); - (*reinterpret_cast(data)) = t7; data += sizeof(T7); - (*reinterpret_cast(data)) = t8; data += sizeof(T8); - (*reinterpret_cast(data)) = t9; data += sizeof(T9); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7, const T8& t8) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - (*reinterpret_cast(data)) = t4; data += sizeof(T4); - (*reinterpret_cast(data)) = t5; data += sizeof(T5); - (*reinterpret_cast(data)) = t6; data += sizeof(T6); - (*reinterpret_cast(data)) = t7; data += sizeof(T7); - (*reinterpret_cast(data)) = t8; data += sizeof(T8); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6, const T7& t7) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - (*reinterpret_cast(data)) = t4; data += sizeof(T4); - (*reinterpret_cast(data)) = t5; data += sizeof(T5); - (*reinterpret_cast(data)) = t6; data += sizeof(T6); - (*reinterpret_cast(data)) = t7; data += sizeof(T7); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5, const T6& t6) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - (*reinterpret_cast(data)) = t4; data += sizeof(T4); - (*reinterpret_cast(data)) = t5; data += sizeof(T5); - (*reinterpret_cast(data)) = t6; data += sizeof(T6); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4, - const T5& t5) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - (*reinterpret_cast(data)) = t4; data += sizeof(T4); - (*reinterpret_cast(data)) = t5; data += sizeof(T5); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3, const T4& t4) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - (*reinterpret_cast(data)) = t4; data += sizeof(T4); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2, const T3& t3) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - (*reinterpret_cast(data)) = t3; data += sizeof(T3); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1, const T2& t2) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - (*reinterpret_cast(data)) = t2; data += sizeof(T2); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, - const T1& t1) - { - (*reinterpret_cast(data)) = t1; data += sizeof(T1); - return data; - } - - template - inline unsigned char* write_pod(unsigned char* data, const T (&t)[N]) - { - T* ptr = reinterpret_cast(data); - std::copy(t,t + N,ptr); - return data + (N * sizeof(T)); - } - - template class Sequence> - inline unsigned char* write_pod(unsigned char* data, - const Sequence& sequence) - { - T* ptr = reinterpret_cast(data); - std::copy(sequence.begin(),sequence.end(),ptr); - return data + (sequence.size() * sizeof(T)); - } - - template - inline unsigned char* write_pod(unsigned char* data, - const std::set& set) - { - T* ptr = reinterpret_cast(data); - std::copy(set.begin(),set.end(),ptr); - return data + (set.size() * sizeof(T)); - } - - template - inline unsigned char* write_pod(unsigned char* data, - const std::multiset& multiset) - { - T* ptr = reinterpret_cast(data); - std::copy(multiset.begin(),multiset.end(),ptr); - return data + (multiset.size() * sizeof(T)); - } - - class string_condition - { - private: - - typedef const unsigned char* itr_type; - - inline bool condition_equal(const itr_type begin, const itr_type end) const - { - if (s.size() == static_cast(std::distance(begin,end))) - { - return std::equal(s_begin,s_end,begin); - } - else - return false; - } - - inline bool condition_notequal(const itr_type begin, const itr_type end) const - { - if (s.size() == static_cast(std::distance(begin,end))) - { - return !std::equal(s_begin,s_end,begin); - } - else - return true; - } - - inline bool condition_like(const itr_type begin, const itr_type end) const - { - return match(s_begin,s_end,begin,end,(unsigned char)'*',(unsigned char)'?'); - } - - inline bool condition_begins_with(const itr_type begin, const itr_type end) const - { - if (s.size() == static_cast(std::distance(begin,end))) - { - return strtk::begins_with(s_begin,s_end,begin,end); - } - else - return false; - } - - inline bool condition_ends_with(const itr_type begin, const itr_type end) const - { - if (s.size() == static_cast(std::distance(begin,end))) - { - return strtk::ends_with(s_begin,s_end,begin,end); - } - else - return false; - } - - inline bool condition_within(const itr_type begin, const itr_type end) const - { - if (s.size() <= static_cast(std::distance(begin,end))) - { - return (end != std::search(begin,end,s_begin,s_end)); - } - else - return false; - } - - inline bool condition_notwithin(const itr_type begin, const itr_type end) const - { - if (s.size() <= static_cast(std::distance(begin,end))) - { - return (end == std::search(begin,end,s_begin,s_end)); - } - else - return true; - } - - typedef bool (string_condition::*condition_method)(const itr_type begin, const itr_type end) const; - - public: - - enum condition_type - { - equal = 0, - notequal = 1, - like = 2, - begins_with = 4, - ends_with = 8, - within = 16, - notwithin = 32 - }; - - inline explicit string_condition(condition_type cond_type, const std::string& str) - : cond_type_(cond_type), - s(str), - s_begin(reinterpret_cast(s.data())), - s_end(reinterpret_cast(s.data() + str.size())), - condition_method_(0) - { - switch (cond_type_) - { - case equal : condition_method_ = &string_condition::condition_equal; - break; - case notequal : condition_method_ = &string_condition::condition_notequal; - break; - case like : condition_method_ = &string_condition::condition_like; - break; - case begins_with : condition_method_ = &string_condition::condition_begins_with; - break; - case ends_with : condition_method_ = &string_condition::condition_ends_with; - break; - case within : condition_method_ = &string_condition::condition_within; - break; - case notwithin : condition_method_ = &string_condition::condition_notwithin; - break; - } - } - - template - inline bool operator()(const Iterator begin, const Iterator end) - { - return ((*this).*condition_method_)(begin,end); - } - - inline bool operator()(const std::string& str) - { - return operator()(reinterpret_cast(str.data()), - reinterpret_cast(str.data() + str.size())); - } - - private: - - condition_type cond_type_; - std::string s; - const unsigned char* s_begin; - const unsigned char* s_end; - condition_method condition_method_; - }; - - namespace trie - { - template - class prefix - { - - template ::value_type> - struct node - { - public: - - typedef KeyValue key_value_t; - typedef Value value_t; - - typedef node node_t; - typedef node_t* node_ptr; - typedef const node_ptr const_node_ptr; - - typedef std::vector node_list_t; - typedef typename node_list_t::const_iterator node_list_iterator; - - explicit node(const key_value_t& key_value) - : key_value_(key_value), - value_holder_(false) - {} - - node(const key_value_t& key_value, const value_t& v) - : key_value_(key_value), - value_holder_(true), - value_(v) - {} - - ~node() - { - if (!node_list_.empty()) - { - node_list_iterator itr = node_list_.begin(); - node_list_iterator end = node_list_.end(); - while (end != itr) - { - delete (*itr); - ++itr; - } - } - } - - inline node_ptr get_node(const key_value_t& key_value) - { - if (node_list_.empty()) - return 0; - node_list_iterator itr = node_list_.begin(); - const node_list_iterator end = node_list_.end(); - while (end != itr) - { - if (key_value == (*itr)->key_value_) - return (*itr); - else - ++itr; - } - return 0; - } - - inline void assign_value(const value_t& v) - { - value_ = v; - value_holder_ = true; - } - - inline void add_node(node_ptr n) - { - node_list_.push_back(n); - } - - inline bool value_holder() const - { - return value_holder_; - } - - inline const value_t& value() const - { - return value_; - } - - inline const key_value_t& key() const - { - return key_value_; - } - - private: - - node(const node_t& n); - node_t& operator=(const node_t& n); - - key_value_t key_value_; - bool value_holder_; - value_t value_; - node_list_t node_list_; - }; - - public: - - //typedef KeyIterator key_iterator_t; - typedef typename std::iterator_traits::value_type key_value_t; - typedef ValueType value_t; - - typedef node node_t; - typedef node_t* node_ptr; - - prefix() - : head_(0) - {} - - template - inline void insert(const key_iterator_t begin, - const key_iterator_t end, - const value_t& v) - { - if (0 == std::distance(begin,end)) - return; - - key_iterator_t itr = begin; - key_value_t key = (*itr); - node_ptr parent = 0; - node_ptr next_node = 0; - node_ptr n = head_ = ((0 == head_) ? new node_t(*itr) : head_); - - while (end != itr) - { - key = (*itr); - if (0 == (next_node = n->get_node(key))) - { - n->add_node(next_node = new node_t(key)); - } - parent = n; - n = next_node; - ++itr; - } - - parent->assign_value(v); - } - - template - inline bool find(const key_iterator_t begin, - const key_iterator_t end, - value_t& v) const - { - if ((0 == head_) || (0 == std::distance(begin,end))) - return false; - key_iterator_t itr = begin; - node_ptr parent = head_; - node_ptr n = head_; - while (end != itr) - { - node_ptr next_node = n->get_node(*itr); - if (0 == next_node) - return false; - parent = n; - n = next_node; - ++itr; - } - if (!parent->value_holder()) - return false; - v = parent->value(); - return true; - } - - template - inline bool find_prefix(const key_iterator_t begin, const key_iterator_t end) const - { - if ((0 == head_) || (0 == std::distance(begin,end))) - return false; - - key_iterator_t itr = begin; - node_ptr n = head_; - - while (end != itr) - { - if (0 == (n = n->get_node(*itr))) - return false; - ++itr; - } - - return true; - } - - ~prefix() - { - delete head_; - } - - private: - - node_ptr head_; - }; - - template - inline void insert(prefix& trie, - const std::string& key, - const Value& value = Value(0)) - { - trie.insert(key.begin(),key.end(),value); - } - - template - inline void insert(prefix& trie, - const char* key, - const Value& value = Value(0)) - { - trie.insert(std::string(key),value); - } - - template - inline bool find(prefix& trie, - const std::string& key, - Value& v) - { - return trie.find(key.begin(),key.end(),v); - } - - template - inline bool find(prefix& trie, - const char* key, - Value& v) - { - return trie.find_prefix(trie,std::string(key),v); - } - - template - inline bool find_prefix(prefix& trie, - const std::string& key) - { - return trie.find_prefix(key.begin(),key.end()); - } - - template - inline bool find_prefix(prefix& trie, - const char* key) - { - return trie.find_prefix(trie,std::string(key)); - } - - } // namespace trie - - template - struct prefix_trie - { - typedef trie::prefix type; - typedef trie::prefix std_string; - typedef trie::prefix char_ptr; - typedef trie::prefix const_char_ptr; - typedef trie::prefix uchar_ptr; - typedef trie::prefix const_uchar_ptr; - }; - - namespace bloom - { - - static const std::size_t bits_per_char = 0x08; // 8 bits in 1 char(unsigned) - static const unsigned char bit_mask[bits_per_char] = { - 0x01, //00000001 - 0x02, //00000010 - 0x04, //00000100 - 0x08, //00001000 - 0x10, //00010000 - 0x20, //00100000 - 0x40, //01000000 - 0x80 //10000000 - }; - - class parameters - { - public: - - parameters() - : minimum_size(1), - maximum_size(std::numeric_limits::max()), - minimum_number_of_hashes(1), - maximum_number_of_hashes(std::numeric_limits::max()), - projected_element_count(10000), - false_positive_probability(1.0 / projected_element_count), - random_seed(0xA5A5A5A55A5A5A5AULL) - {} - - virtual ~parameters() - {} - - inline bool operator!() - { - return (minimum_size > maximum_size) || - (minimum_number_of_hashes > maximum_number_of_hashes) || - (minimum_number_of_hashes < 1) || - (0 == maximum_number_of_hashes) || - (0 == projected_element_count) || - (false_positive_probability < 0.0) || - (std::numeric_limits::infinity() == std::abs(false_positive_probability)) || - (0 == random_seed) || - (0xFFFFFFFFFFFFFFFFULL == random_seed); - } - - //Allowed min/max size of the bloom filter in bits - unsigned long long int minimum_size; - unsigned long long int maximum_size; - - //Allowed min/max number of hash functions - unsigned int minimum_number_of_hashes; - unsigned int maximum_number_of_hashes; - - //The approximate number of elements to be inserted - //into the bloom filter, should be within one order - //of magnitude. The default is 10000. - unsigned long long int projected_element_count; - - //The approximate false positive probability expected - //from the bloom filter. The default is the reciprocal - //of the projected_element_count. - double false_positive_probability; - - unsigned long long int random_seed; - - inline bool operator()(strtk::binary::reader& reader) - { - return reader(minimum_size) && - reader(maximum_size) && - reader(minimum_number_of_hashes) && - reader(maximum_number_of_hashes) && - reader(projected_element_count) && - reader(false_positive_probability) && - reader(random_seed); - } - - inline bool operator()(strtk::binary::writer& writer) - { - return writer(minimum_size) && - writer(maximum_size) && - writer(minimum_number_of_hashes) && - writer(maximum_number_of_hashes) && - writer(projected_element_count) && - writer(false_positive_probability) && - writer(random_seed); - } - - struct optimal_parameters_t - { - optimal_parameters_t() - : number_of_hashes(0), - table_size(0) - {} - - unsigned int number_of_hashes; - unsigned long long int table_size; - }; - - optimal_parameters_t optimal_parameters; - - virtual bool compute_optimal_parameters() - { - /* - Note: - The following will attempt to find the number of hash functions - and minimum amount of storage bits required to construct a bloom - filter consistent with the user defined false positive probability - and estimated element insertion count. - */ - - if (!(*this)) - return false; - - double min_m = std::numeric_limits::infinity(); - double min_k = 0.0; - double curr_m = 0.0; - double k = 1.0; - - while (k < 1000.0) - { - double numerator = -k * projected_element_count; - double denominator = std::log(1.0 - std::pow(false_positive_probability, 1.0 / k)); - curr_m = numerator / denominator; - if (curr_m < min_m) - { - min_m = curr_m; - min_k = k; - } - k += 1.0; - } - - optimal_parameters_t& optp = optimal_parameters; - - optp.number_of_hashes = static_cast(min_k); - optp.table_size = static_cast(min_m); - optp.table_size += (((optp.table_size % bits_per_char) != 0) ? (bits_per_char - (optp.table_size % bits_per_char)) : 0); - - if (optp.number_of_hashes < minimum_number_of_hashes) - optp.number_of_hashes = minimum_number_of_hashes; - else if (optp.number_of_hashes > maximum_number_of_hashes) - optp.number_of_hashes = maximum_number_of_hashes; - - if (optp.table_size < minimum_size) - optp.table_size = minimum_size; - else if (optp.table_size > maximum_size) - optp.table_size = maximum_size; - - return true; - } - - }; - - class filter - { - protected: - - typedef unsigned int bloom_type; - typedef unsigned char cell_type; - - public: - - filter() - : bit_table_(0), - salt_count_(0), - table_size_(0), - raw_table_size_(0), - projected_element_count_(0), - inserted_element_count_(0), - random_seed_(0), - desired_false_positive_probability_(0.0) - {} - - filter(const parameters& p) - : bit_table_(0), - projected_element_count_(p.projected_element_count), - inserted_element_count_(0), - random_seed_((p.random_seed * 0xA5A5A5A5) + 1), - desired_false_positive_probability_(p.false_positive_probability) - { - salt_count_ = p.optimal_parameters.number_of_hashes; - table_size_ = p.optimal_parameters.table_size; - generate_unique_salt(); - raw_table_size_ = table_size_ / bits_per_char; - bit_table_ = new cell_type[static_cast(raw_table_size_)]; - std::fill_n(bit_table_,raw_table_size_,0x00); - } - - filter(const filter& filter) - { - this->operator=(filter); - } - - inline bool operator == (const filter& f) const - { - if (this != &f) - { - return - (salt_count_ == f.salt_count_) && - (table_size_ == f.table_size_) && - (raw_table_size_ == f.raw_table_size_) && - (projected_element_count_ == f.projected_element_count_) && - (inserted_element_count_ == f.inserted_element_count_) && - (random_seed_ == f.random_seed_) && - (desired_false_positive_probability_ == f.desired_false_positive_probability_) && - (salt_ == f.salt_) && - std::equal(f.bit_table_,f.bit_table_ + raw_table_size_,bit_table_); - } - else - return true; - } - - inline bool operator != (const filter& f) const - { - return !operator==(f); - } - - inline filter& operator = (const filter& f) - { - if (this != &f) - { - salt_count_ = f.salt_count_; - table_size_ = f.table_size_; - raw_table_size_ = f.raw_table_size_; - projected_element_count_ = f.projected_element_count_; - inserted_element_count_ = f.inserted_element_count_; - random_seed_ = f.random_seed_; - desired_false_positive_probability_ = f.desired_false_positive_probability_; - delete[] bit_table_; - bit_table_ = new cell_type[static_cast(raw_table_size_)]; - std::copy(f.bit_table_,f.bit_table_ + raw_table_size_,bit_table_); - salt_ = f.salt_; - } - return *this; - } - - virtual ~filter() - { - delete[] bit_table_; - } - - inline bool operator!() const - { - return (0 == table_size_); - } - - inline void clear() - { - std::fill_n(bit_table_,raw_table_size_,0x00); - inserted_element_count_ = 0; - } - - inline void insert(const unsigned char* key_begin, const std::size_t& length) - { - std::size_t bit_index = 0; - std::size_t bit = 0; - for (std::size_t i = 0; i < salt_.size(); ++i) - { - compute_indices(hash_ap(key_begin,length,salt_[i]),bit_index,bit); - bit_table_[bit_index / bits_per_char] |= bit_mask[bit]; - } - ++inserted_element_count_; - } - - template - inline void insert(const T& t) - { - // Note: T must be a C++ POD type. - insert(reinterpret_cast(&t),sizeof(T)); - } - - inline void insert(const std::string& key) - { - insert(reinterpret_cast(key.data()),key.size()); - } - - inline void insert(const char* data, const std::size_t& length) - { - insert(reinterpret_cast(data),length); - } - - template - inline void insert(const InputIterator begin, const InputIterator end) - { - InputIterator itr = begin; - while (end != itr) - { - insert(*(itr++)); - } - } - - inline virtual bool contains(const unsigned char* key_begin, const std::size_t length) const - { - std::size_t bit_index = 0; - std::size_t bit = 0; - for (std::size_t i = 0; i < salt_.size(); ++i) - { - compute_indices(hash_ap(key_begin,length,salt_[i]),bit_index,bit); - if ((bit_table_[bit_index / bits_per_char] & bit_mask[bit]) != bit_mask[bit]) - { - return false; - } - } - return true; - } - - template - inline bool contains(const T& t) const - { - return contains(reinterpret_cast(&t),static_cast(sizeof(T))); - } - - inline bool contains(const std::string& key) const - { - return contains(reinterpret_cast(key.data()),key.size()); - } - - inline bool contains(const char* data, const std::size_t& length) const - { - return contains(reinterpret_cast(data),length); - } - - template - inline InputIterator contains_all(const InputIterator begin, const InputIterator end) const - { - InputIterator itr = begin; - while (end != itr) - { - if (!contains(*itr)) - { - return itr; - } - ++itr; - } - return end; - } - - template - inline InputIterator contains_none(const InputIterator begin, const InputIterator end) const - { - InputIterator itr = begin; - while (end != itr) - { - if (contains(*itr)) - { - return itr; - } - ++itr; - } - return end; - } - - inline virtual unsigned long long int size() const - { - return table_size_; - } - - inline std::size_t element_count() const - { - return inserted_element_count_; - } - - inline double effective_fpp() const - { - /* - Note: - The effective false positive probability is calculated using the - designated table size and hash function count in conjunction with - the current number of inserted elements - not the user defined - predicated/expected number of inserted elements. - */ - return std::pow(1.0 - std::exp(-1.0 * salt_.size() * inserted_element_count_ / size()), 1.0 * salt_.size()); - } - - inline filter& operator &= (const filter& f) - { - /* intersection */ - if ( - (salt_count_ == f.salt_count_) && - (table_size_ == f.table_size_) && - (random_seed_ == f.random_seed_) - ) - { - for (std::size_t i = 0; i < raw_table_size_; ++i) - { - bit_table_[i] &= f.bit_table_[i]; - } - } - return *this; - } - - inline filter& operator |= (const filter& f) - { - /* union */ - if ( - (salt_count_ == f.salt_count_) && - (table_size_ == f.table_size_) && - (random_seed_ == f.random_seed_) - ) - { - for (std::size_t i = 0; i < raw_table_size_; ++i) - { - bit_table_[i] |= f.bit_table_[i]; - } - } - return *this; - } - - inline filter& operator ^= (const filter& f) - { - /* difference */ - if ( - (salt_count_ == f.salt_count_) && - (table_size_ == f.table_size_) && - (random_seed_ == f.random_seed_) - ) - { - for (std::size_t i = 0; i < raw_table_size_; ++i) - { - bit_table_[i] ^= f.bit_table_[i]; - } - } - return *this; - } - - inline const cell_type* table() const - { - return bit_table_; - } - - inline bool write_to_file(const std::string& file_name) const - { - if (0 == table_size_) - return false; - const std::size_t buffer_size = sizeof( salt_count_) + - sizeof( table_size_) + - sizeof( raw_table_size_) + - sizeof( projected_element_count_) + - sizeof( inserted_element_count_) + - sizeof( random_seed_) + - sizeof(desired_false_positive_probability_) + - salt_count_ * sizeof( bloom_type) + - static_cast(raw_table_size_) * - sizeof(cell_type) + - 64; // handle array sizes etc. - std::ofstream ostream(file_name.c_str(),std::ios::binary); - if (!ostream) - return false; - unsigned char* buffer = new unsigned char[buffer_size]; - strtk::binary::writer writer(buffer,buffer_size); - writer.reset(true); - bool result = writer(salt_count_) && - writer(table_size_) && - writer(raw_table_size_) && - writer(projected_element_count_) && - writer(inserted_element_count_) && - writer(random_seed_) && - writer(desired_false_positive_probability_) && - writer(salt_) && - writer(bit_table_,raw_table_size_); - if (result) - { - writer(ostream); - } - ostream.close(); - delete[] buffer; - return result; - } - - inline bool read_from_file(const std::string& file_name) - { - std::ifstream istream(file_name.c_str(),std::ios::binary); - if (!istream) - return false; - salt_count_ = 0; - table_size_ = 0; - raw_table_size_ = 0; - projected_element_count_ = 0; - inserted_element_count_ = 0; - random_seed_ = 0; - desired_false_positive_probability_ = 0.0; - salt_.clear(); - if (0 != bit_table_) - delete [] bit_table_; - bit_table_= 0; - const std::size_t buffer_size = strtk::fileio::file_size(file_name); - unsigned char* buffer = new unsigned char[buffer_size]; - strtk::binary::reader reader(buffer,buffer_size); - reader.reset(true); - reader(istream,buffer_size); - istream.close(); - bool result = reader(salt_count_) && - reader(table_size_) && - reader(raw_table_size_) && - reader(projected_element_count_) && - reader(inserted_element_count_) && - reader(random_seed_) && - reader(desired_false_positive_probability_) && - reader(salt_) && - reader(bit_table_,raw_table_size_); - delete[] buffer; - return result; - } - - inline std::size_t hash_count() - { - return salt_.size(); - } - - protected: - - inline virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const - { - bit_index = static_cast(hash % table_size_); - bit = bit_index % bits_per_char; - } - - void generate_unique_salt() - { - /* - Note: - A distinct hash function need not be implementation-wise - distinct. In the current implementation "seeding" a common - hash function with different values seems to be adequate. - */ - const unsigned int predef_salt_count = 128; - static const bloom_type predef_salt[predef_salt_count] = - { - 0xAAAAAAAA, 0x55555555, 0x33333333, 0xCCCCCCCC, - 0x66666666, 0x99999999, 0xB5B5B5B5, 0x4B4B4B4B, - 0xAA55AA55, 0x55335533, 0x33CC33CC, 0xCC66CC66, - 0x66996699, 0x99B599B5, 0xB54BB54B, 0x4BAA4BAA, - 0xAA33AA33, 0x55CC55CC, 0x33663366, 0xCC99CC99, - 0x66B566B5, 0x994B994B, 0xB5AAB5AA, 0xAAAAAA33, - 0x555555CC, 0x33333366, 0xCCCCCC99, 0x666666B5, - 0x9999994B, 0xB5B5B5AA, 0xFFFFFFFF, 0xFFFF0000, - 0xB823D5EB, 0xC1191CDF, 0xF623AEB3, 0xDB58499F, - 0xC8D42E70, 0xB173F616, 0xA91A5967, 0xDA427D63, - 0xB1E8A2EA, 0xF6C0D155, 0x4909FEA3, 0xA68CC6A7, - 0xC395E782, 0xA26057EB, 0x0CD5DA28, 0x467C5492, - 0xF15E6982, 0x61C6FAD3, 0x9615E352, 0x6E9E355A, - 0x689B563E, 0x0C9831A8, 0x6753C18B, 0xA622689B, - 0x8CA63C47, 0x42CC2884, 0x8E89919B, 0x6EDBD7D3, - 0x15B6796C, 0x1D6FDFE4, 0x63FF9092, 0xE7401432, - 0xEFFE9412, 0xAEAEDF79, 0x9F245A31, 0x83C136FC, - 0xC3DA4A8C, 0xA5112C8C, 0x5271F491, 0x9A948DAB, - 0xCEE59A8D, 0xB5F525AB, 0x59D13217, 0x24E7C331, - 0x697C2103, 0x84B0A460, 0x86156DA9, 0xAEF2AC68, - 0x23243DA5, 0x3F649643, 0x5FA495A8, 0x67710DF8, - 0x9A6C499E, 0xDCFB0227, 0x46A43433, 0x1832B07A, - 0xC46AFF3C, 0xB9C8FFF0, 0xC9500467, 0x34431BDF, - 0xB652432B, 0xE367F12B, 0x427F4C1B, 0x224C006E, - 0x2E7E5A89, 0x96F99AA5, 0x0BEB452A, 0x2FD87C39, - 0x74B2E1FB, 0x222EFD24, 0xF357F60C, 0x440FCB1E, - 0x8BBE030F, 0x6704DC29, 0x1144D12F, 0x948B1355, - 0x6D8FD7E9, 0x1C11A014, 0xADD1592F, 0xFB3C712E, - 0xFC77642F, 0xF9C4CE8C, 0x31312FB9, 0x08B0DD79, - 0x318FA6E7, 0xC040D23D, 0xC0589AA7, 0x0CA5C075, - 0xF874B172, 0x0CF914D5, 0x784D3280, 0x4E8CFEBC, - 0xC569F575, 0xCDB2A091, 0x2CC016B4, 0x5C5F4421 - }; - - if (salt_count_ <= predef_salt_count) - { - std::copy(predef_salt, - predef_salt + salt_count_, - std::back_inserter(salt_)); - for (unsigned int i = 0; i < salt_.size(); ++i) - { - /* - Note: - This is done to integrate the user defined random seed, - so as to allow for the generation of unique bloom filter - instances. - */ - salt_[i] = salt_[i] * salt_[(i + 3) % salt_.size()] + static_cast(random_seed_); - } - } - else - { - std::copy(predef_salt,predef_salt + predef_salt_count,std::back_inserter(salt_)); - srand(static_cast(random_seed_)); - while (salt_.size() < salt_count_) - { - bloom_type current_salt = static_cast(rand()) * static_cast(rand()); - if (0 == current_salt) continue; - if (salt_.end() == std::find(salt_.begin(), salt_.end(), current_salt)) - { - salt_.push_back(current_salt); - } - } - } - } - - inline bloom_type hash_ap(const unsigned char* begin, std::size_t remaining_length, bloom_type hash) const - { - const unsigned char* itr = begin; - unsigned int loop = 0; - while (remaining_length >= 8) - { - const unsigned int& i1 = *(reinterpret_cast(itr)); itr += sizeof(unsigned int); - const unsigned int& i2 = *(reinterpret_cast(itr)); itr += sizeof(unsigned int); - hash ^= (hash << 7) ^ i1 * (hash >> 3) ^ - (~((hash << 11) + (i2 ^ (hash >> 5)))); - remaining_length -= 8; - } - if (remaining_length) - { - if (remaining_length >= 4) - { - const unsigned int& i = *(reinterpret_cast(itr)); - if (loop & 0x01) - hash ^= (hash << 7) ^ i * (hash >> 3); - else - hash ^= (~((hash << 11) + (i ^ (hash >> 5)))); - ++loop; - remaining_length -= 4; - itr += sizeof(unsigned int); - } - if (remaining_length >= 2) - { - const unsigned short& i = *(reinterpret_cast(itr)); - if (loop & 0x01) - hash ^= (hash << 7) ^ i * (hash >> 3); - else - hash ^= (~((hash << 11) + (i ^ (hash >> 5)))); - ++loop; - remaining_length -= 2; - itr += sizeof(unsigned short); - } - if (remaining_length) - { - hash += ((*itr) ^ (hash * 0xA5A5A5A5)) + loop; - } - } - return hash; - } - - std::vector salt_; - unsigned char* bit_table_; - unsigned int salt_count_; - unsigned long long int table_size_; - unsigned long long int raw_table_size_; - unsigned long long int projected_element_count_; - unsigned int inserted_element_count_; - unsigned long long int random_seed_; - double desired_false_positive_probability_; - }; - - inline filter operator & (const filter& a, const filter& b) - { - filter result = a; - result &= b; - return result; - } - - inline filter operator | (const filter& a, const filter& b) - { - filter result = a; - result |= b; - return result; - } - - inline filter operator ^ (const filter& a, const filter& b) - { - filter result = a; - result ^= b; - return result; - } - - class compressible_filter : public filter - { - public: - - compressible_filter(const parameters& p) - : filter(p) - { - size_list.push_back(table_size_); - } - - inline virtual unsigned long long int size() const - { - return size_list.back(); - } - - inline bool compress(const double& percentage) - { - if ((0.0 >= percentage) || (percentage >= 100.0)) - { - return false; - } - - unsigned long long int original_table_size = size_list.back(); - unsigned long long int new_table_size = static_cast((size_list.back() * (1.0 - (percentage / 100.0)))); - new_table_size -= (((new_table_size % bits_per_char) != 0) ? (new_table_size % bits_per_char) : 0); - - if ((bits_per_char > new_table_size) || (new_table_size >= original_table_size)) - { - return false; - } - - desired_false_positive_probability_ = effective_fpp(); - cell_type* tmp = new cell_type[static_cast(new_table_size / bits_per_char)]; - std::copy(bit_table_, bit_table_ + (new_table_size / bits_per_char), tmp); - cell_type* itr = bit_table_ + (new_table_size / bits_per_char); - cell_type* end = bit_table_ + (original_table_size / bits_per_char); - cell_type* itr_tmp = tmp; - - while (end != itr) - { - *(itr_tmp++) |= (*itr++); - } - - delete[] bit_table_; - bit_table_ = tmp; - size_list.push_back(new_table_size); - - return true; - } - - private: - - inline virtual void compute_indices(const bloom_type& hash, std::size_t& bit_index, std::size_t& bit) const - { - bit_index = hash; - for (std::size_t i = 0; i < size_list.size(); ++i) - { - bit_index %= size_list[i]; - } - bit = bit_index % bits_per_char; - } - - std::vector size_list; - }; - - } - - namespace details - { - - inline void compute_pod_hash(const char data[], unsigned int& hash) - { - hash ^= ((hash << 7) ^ data[0] * (hash >> 3)); - hash ^= ~((hash << 11) + (data[1] ^ (hash >> 5))); - } - - inline void compute_pod_hash(const unsigned char data[], unsigned int& hash) - { - hash ^= ((hash << 7) ^ data[0] * (hash >> 3)); - hash ^= ~((hash << 11) + (data[1] ^ (hash >> 5))); - } - - inline void compute_pod_hash(const int& data, unsigned int& hash) - { - const unsigned char* itr = reinterpret_cast(&data); - hash ^= ((hash << 7) ^ itr[0] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[2] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5))); - } - - inline void compute_pod_hash(const unsigned int& data, unsigned int& hash) - { - compute_pod_hash(static_cast(data),hash); - } - - inline void compute_pod_hash(const unsigned long long int& data, unsigned int& hash) - { - const unsigned char* itr = reinterpret_cast(&data); - hash ^= ((hash << 7) ^ itr[0] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[2] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[4] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[5] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[6] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[7] ^ (hash >> 5))); - } - - inline void compute_pod_hash(const double& data, unsigned int& hash) - { - const unsigned char* itr = reinterpret_cast(&data); - hash ^= ((hash << 7) ^ itr[0] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[1] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[2] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[3] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[4] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[5] ^ (hash >> 5))); - hash ^= ((hash << 7) ^ itr[6] * (hash >> 3)); - hash ^= ~((hash << 11) + (itr[7] ^ (hash >> 5))); - } - - template - inline void compute_block(Iterator itr, std::size_t& length, unsigned int& hash) - { - while (length >= block_size) - { - for (std::size_t i = 0; i < block_size; ++i, ++itr) - { - compute_pod_hash((*itr),hash); - } - length -= block_size; - } - } - - template - inline void compute_block(unsigned char* itr, std::size_t& length, unsigned int& hash) - { - unsigned int local_hash = hash; - while (length >= block_size) - { - for (std::size_t i = 0; i < block_size; ++i, ++itr) - { - compute_pod_hash((*itr),local_hash); - } - length -= block_size; - } - hash = local_hash; - } - - template - inline void compute_block(char* itr, std::size_t& length, unsigned int& hash) - { - compute_block(reinterpret_cast(itr),length,hash); - } - - static const unsigned int hash_seed = 0xAAAAAAAA; - - template - inline void hash(const Iterator itr, std::size_t length, unsigned int& hash_value) - { - if (length >= 64) compute_block<64>(itr,length,hash_value); - if (length >= 32) compute_block<32>(itr,length,hash_value); - if (length >= 16) compute_block<16>(itr,length,hash_value); - if (length >= 8) compute_block< 8>(itr,length,hash_value); - if (length >= 4) compute_block< 4>(itr,length,hash_value); - if (length >= 2) compute_block< 2>(itr,length,hash_value); - if (length == 0) compute_block< 1>(itr,length,hash_value); - } - - } // namespace details - - template - inline unsigned int hash(const Iterator itr, - std::size_t length, - unsigned int seed = details::hash_seed) - { - unsigned int hash_value = seed; - details::hash(itr,length,hash_value); - return hash_value; - } - - inline unsigned int hash(const std::string& s, unsigned int seed = details::hash_seed) - { - unsigned int hash_value = seed; - return hash(s.begin(),s.size(),hash_value); - } - - template class Sequence> - inline unsigned int hash(const Sequence& sequence, unsigned int seed = details::hash_seed) - { - unsigned int hash_value = seed; - return hash(sequence.begin(),sequence.size(),hash_value); - } - - namespace util - { - template - class scoped_restore - { - public: - - scoped_restore(T& t, const bool restore = true) - : restore_(restore), - reference_(t), - copy_(t) - {} - - ~scoped_restore() - { - if (restore_) - { - reference_ = copy_; - } - } - - inline bool& restore() - { - return restore_; - } - - private: - - scoped_restore(const scoped_restore&); - scoped_restore& operator=(const scoped_restore&); - - bool restore_; - T& reference_; - T copy_; - }; - - template - class attribute - { - public: - - attribute() - : initialised_(false) - {} - - attribute(const T& t) - { - assign(t); - prev_t_ = t; - } - - inline attribute& operator=(const T& t) - { - prev_t_ = t_; - assign(t); - return *this; - } - - inline bool operator==(const T& t) - { - return initialised_ && (t_ == t); - } - - template - inline bool operator!=(const TConvertibleType& t) - { - return !(operator==(t)); - } - - inline T& operator()() - { - return t_; - } - - inline const T& operator()() const - { - return t_; - } - - inline operator T() const - { - return t_; - } - - inline operator T() - { - return t_; - } - - inline bool initialised() const - { - return initialised_; - } - - inline bool& initialised() - { - return initialised_; - } - - inline bool changed() const - { - return (initialised_ && (t_ != prev_t_)); - } - - inline const T& value() const - { - return t_; - } - - inline T& value() - { - return t_; - } - - inline const T& previous() const - { - return prev_t_; - } - - inline T& previous() - { - return prev_t_; - } - - private: - - inline void assign(const T& t) - { - t_ = t; - initialised_ = true; - } - - T t_; - T prev_t_; - bool initialised_; - }; - - inline bool operator==(const char* s, const attribute& attrib) - { - return attrib.value() == s; - } - - inline bool operator!=(const char* s, const attribute& attrib) - { - return !(s == attrib.value()); - } - - template - static inline std::ostream& operator<<(std::ostream& os, const attribute& attrib) - { - return (os << attrib.value()); - } - - class semantic_action_impl - { - private: - - class function_holder_base - { - public: - - typedef const unsigned char* itr_type; - - virtual ~function_holder_base(){} - - virtual bool operator()(itr_type begin, itr_type end) const = 0; - - inline bool operator()(const char* begin, const char* end) const - { - return operator()(reinterpret_cast(begin), - reinterpret_cast(end)); - } - - template - inline bool operator()(const std::pair& p) const - { - return operator()(p.first,p.second); - } - }; - - template - class function_holder : public function_holder_base - { - public: - - explicit function_holder(Function& f) - : function_(&f) - {} - - inline virtual bool operator()(itr_type begin, itr_type end) const - { - return (*function_)(begin,end); - } - - private: - - Function* function_; - }; - - public: - - semantic_action_impl() - : function_holder_(0) - { - std::fill_n(function_holder_buffer_,sizeof(function_holder_buffer_),0x00); - } - - template - inline explicit semantic_action_impl(const Function& f) - { - std::fill_n(function_holder_buffer_,sizeof(function_holder_buffer_),0x00); - assign(f); - } - - inline bool operator!() const - { - return (0 == function_holder_); - } - - inline bool operator==(const semantic_action_impl& sa) const - { - return (0 != function_holder_) && - (0 != sa.function_holder_) && - (function_holder_ == sa.function_holder_); - } - - template - inline bool operator()(InputIterator begin, InputIterator end) const - { - if (0 != function_holder_) - return (*function_holder_).operator()(begin,end); - else - return false; - } - - template - inline bool operator()(const std::pair& r) const - { - return operator()(r.first,r.second); - } - - inline bool operator()(const std::string& s) const - { - return operator()(s.data(),s.data() + s.size()); - } - - template - inline void assign(Function& f) - { - static const std::size_t type_size = sizeof(function_holder(f)); - function_holder_ = construct::type(f,function_holder_buffer_); - } - - inline semantic_action_impl& ref() - { - return (*this); - } - - private: - - typedef function_holder_base* function_holder_ptr; - - inline semantic_action_impl& operator=(const semantic_action_impl&); - - template - struct construct - { - inline static function_holder_ptr type(Function&, unsigned char*) - { - return reinterpret_cast(0); - } - }; - - template - struct construct - { - inline static function_holder_ptr type(Function& f, unsigned char* buffer) - { - return new(buffer)function_holder(f); - } - }; - - function_holder_ptr function_holder_; - enum { function_holder_buffer_size = 64 }; - unsigned char function_holder_buffer_[function_holder_buffer_size]; - }; - - template - inline semantic_action_impl semantic_action(Function& f) - { - return semantic_action_impl(f); - } - - } // namespace util - - namespace details - { - #define strtk_register_attribute_type_tag(T) \ - template<> struct supported_conversion_to_type< strtk::util::attribute >{ typedef attribute_type_tag type; }; \ - template<> struct supported_conversion_from_type< strtk::util::attribute > { typedef attribute_type_tag type; };\ - - strtk_register_attribute_type_tag(unsigned short) - strtk_register_attribute_type_tag(unsigned int) - strtk_register_attribute_type_tag(unsigned long) - strtk_register_attribute_type_tag(unsigned long long int) - strtk_register_attribute_type_tag(short) - strtk_register_attribute_type_tag(int) - strtk_register_attribute_type_tag(long) - strtk_register_attribute_type_tag(long long) - strtk_register_attribute_type_tag(float) - strtk_register_attribute_type_tag(double) - strtk_register_attribute_type_tag(long double) - strtk_register_attribute_type_tag(unsigned char) - strtk_register_attribute_type_tag(signed char) - strtk_register_attribute_type_tag(char) - strtk_register_attribute_type_tag(std::string) - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, strtk::util::attribute& result, attribute_type_tag) - { - if (strtk::string_to_type_converter(itr,end,result.value())) - { - result.initialised() = true; - return true; - } - else - return false; - } - - template - inline bool type_to_string_converter_impl(const strtk::util::attribute& attrib, std::string& result, attribute_type_tag) - { - if (!attrib.initialised()) - return false; - return strtk::type_to_string(attrib.value(),result); - } - - #undef strtk_register_attribute_type_tag - - template<> struct supported_conversion_to_type < strtk::util::semantic_action_impl > { typedef semantic_action_type_tag type; }; - template<> struct supported_conversion_from_type< strtk::util::semantic_action_impl > { typedef semantic_action_type_tag type; }; - - template - inline bool string_to_type_converter_impl(Iterator& itr, const Iterator end, strtk::util::semantic_action_impl& result, semantic_action_type_tag) - { - return result(itr,end); - } - - inline bool type_to_string_converter_impl(const strtk::util::semantic_action_impl&, std::string& result, semantic_action_type_tag) - { - static std::string result_str = "semantic_action"; - result = result_str; - return true; - } - - } // namespace details - - namespace util - { - class value - { - private: - - class type_holder_base - { - public: - - typedef const unsigned char* itr_type; - - virtual ~type_holder_base(){} - - virtual bool operator()(itr_type begin, itr_type end) const = 0; - - virtual bool to_string(std::string& s) const = 0; - - inline bool operator()(const char* begin, const char* end) const - { - return operator()(reinterpret_cast(begin), - reinterpret_cast(end)); - } - - template - inline bool operator()(const std::pair& p) const - { - return operator()(p.first,p.second); - } - }; - - template - class type_holder : public type_holder_base - { - public: - - typedef T* type_ptr; - - explicit type_holder(T& t) - : value_ptr_(&t) - {} - - inline virtual bool operator()(itr_type begin, itr_type end) const - { - return strtk::string_to_type_converter(begin,end,(*value_ptr_)); - } - - inline virtual bool to_string(std::string& s) const - { - return strtk::type_to_string((*value_ptr_),s); - } - - inline operator T() const - { - return (*value_ptr_); - } - - private: - - type_ptr value_ptr_; - }; - - public: - - value() - : type_holder_(0) - { - std::fill_n(type_holder_buffer_,sizeof(type_holder_buffer_),0x00); - } - - template - inline explicit value(T& t) - { - std::fill_n(type_holder_buffer_,sizeof(type_holder_buffer_),0x00); - assign(t); - } - - inline bool operator!() const - { - return (0 == type_holder_); - } - - inline bool operator==(const value& v) const - { - return (0 != type_holder_) && - (0 != v.type_holder_) && - (type_holder_ == v.type_holder_); - } - - inline value& operator=(const value& v) - { - if (&v != this) - { - if (0 != v.type_holder_) - { - std::copy(v.type_holder_buffer_, - v.type_holder_buffer_ + type_holder_buffer_size, - type_holder_buffer_); - type_holder_ = reinterpret_cast(type_holder_buffer_); - } - } - return *this; - } - - template - inline bool operator()(InputIterator begin, InputIterator end) const - { - if (0 != type_holder_) - return (*type_holder_).operator()(begin,end); - else - return false; - } - - template - inline bool operator()(const std::pair& r) const - { - return operator()(r.first,r.second); - } - - inline bool operator()(const std::string& s) const - { - return operator()(s.data(),s.data() + s.size()); - } - - template - inline void assign(T& t) - { - static const std::size_t type_size = sizeof(type_holder(t)); - type_holder_ = construct::type(t,type_holder_buffer_); - } - - inline bool to_string(std::string& s) const - { - if (0 != type_holder_) - return (*type_holder_).to_string(s); - else - return false; - } - - template - inline operator T() const - { - if (0 != type_holder_) - return (*type_holder_); - else - return T(); - } - - private: - - typedef type_holder_base* type_holder_ptr; - - template - struct construct - { - inline static type_holder_ptr type(T&, unsigned char*) - { - return reinterpret_cast(0); - } - }; - - template - struct construct - { - inline static type_holder_ptr type(T& t, unsigned char* buffer) - { - return new(buffer)type_holder(t); - } - }; - - type_holder_ptr type_holder_; - enum { type_holder_buffer_size = 2 * sizeof(type_holder) }; - unsigned char type_holder_buffer_[type_holder_buffer_size]; - }; - - template - inline void make_key_list(const std::map& map, - OutputIterator out) - { - if (map.empty()) return; - typedef typename std::map map_type; - typename map_type::const_iterator itr = map.begin(); - typename map_type::const_iterator end = map.end(); - while (end != itr) - { - *out++ = (itr++)->first; - } - } - - template - inline void make_key_list(const std::map& map, - std::set& set) - { - make_key_list(map,std::inserter(set,set.begin())); - } - - template - inline void make_key_list(const std::map& map, - std::multiset& multiset) - { - make_key_list(map,std::inserter(multiset,multiset.begin())); - } - - template class Sequence> - inline void make_key_list(const std::map& map, - Sequence& sequence) - { - make_key_list(map,std::back_inserter(sequence)); - } - - template - inline void make_value_list(const std::multimap& map, - const Key& key, - OutputIterator out) - { - if (map.empty()) return; - typedef typename std::multimap map_type; - typename map_type::const_iterator itr = map.find(key); - typename map_type::const_iterator end = map.end(); - while ((end != itr) && (key == itr->first)) - { - *out++ = (itr++)->second; - } - } - - template class Sequence> - inline void make_value_list(const std::multimap& map, - const Key& key, - Sequence& sequence) - { - make_value_list(map,key,std::back_inserter(sequence)); - } - - template class Sequence> - inline void delete_all(Sequence& sequence) - { - typename Sequence::iterator itr = sequence.begin(); - typename Sequence::iterator end = sequence.end(); - while (end != itr) - { - delete (*itr); - ++itr; - } - sequence.clear(); - } - - template - inline void delete_all(std::map& cont) - { - typename std::map::iterator itr = cont.begin(); - typename std::map::iterator end = cont.end(); - while (end != itr) - { - delete (*itr).second; - ++itr; - } - cont.clear(); - } - - template - inline void delete_all(std::multimap& cont) - { - typename std::multimap::iterator itr = cont.begin(); - typename std::multimap::iterator end = cont.end(); - while (end != itr) - { - delete (*itr).second; - ++itr; - } - cont.clear(); - } - - template - inline void delete_all(std::set& cont) - { - typename std::set::iterator itr = cont.begin(); - typename std::set::iterator end = cont.end(); - while (end != itr) - { - delete (*itr); - ++itr; - } - cont.clear(); - } - - template - inline void delete_all(std::multiset& cont) - { - typename std::multiset::iterator itr = cont.begin(); - typename std::multiset::iterator end = cont.end(); - while (end != itr) - { - delete (*itr); - ++itr; - } - cont.clear(); - } - - template class Sequence> - inline void delete_if(const Predicate& p, - Sequence& sequence) - { - typename Sequence::iterator itr = sequence.begin(); - while (sequence.end() != itr) - { - if (p(*itr)) - { - delete (*itr); - itr = sequence.erase(itr); - } - else - ++itr; - } - } - - template - inline void delete_if(const Predicate& p, - std::map& cont) - { - typename std::map::iterator itr = cont.begin(); - while (cont.end() != itr) - { - if (p(*itr)) - { - delete (*itr).second; - itr = cont.erase(itr); - } - else - ++itr; - } - } - - template - inline void delete_if(const Predicate& p, - std::multimap& cont) - { - typename std::multimap::iterator itr = cont.begin(); - while (cont.end() != itr) - { - if (p(*itr)) - { - delete (*itr).second; - itr = cont.erase(itr); - } - else - ++itr; - } - } - - template - inline void delete_if(const Predicate& p, - std::set& cont) - { - typename std::set::iterator itr = cont.begin(); - while (cont.end() != itr) - { - if (p(*itr)) - { - delete (*itr).second; - itr = cont.erase(itr); - } - else - ++itr; - } - } - - template - inline void delete_if(const Predicate& p, - std::multiset& cont) - { - typename std::multiset::iterator itr = cont.begin(); - while (cont.end() != itr) - { - if (p(*itr)) - { - delete (*itr).second; - itr = cont.erase(itr); - } - else - ++itr; - } - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9, const T& v10, const T& v11) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); sequence.push_back(v6); - sequence.push_back(v7); sequence.push_back(v8); - sequence.push_back(v9); sequence.push_back(v10); - sequence.push_back(v11); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9, const T& v10) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); sequence.push_back(v6); - sequence.push_back(v7); sequence.push_back(v8); - sequence.push_back(v9); sequence.push_back(v10); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); sequence.push_back(v6); - sequence.push_back(v7); sequence.push_back(v8); - sequence.push_back(v9); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); sequence.push_back(v6); - sequence.push_back(v7); sequence.push_back(v8); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); sequence.push_back(v6); - sequence.push_back(v7); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); sequence.push_back(v6); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - sequence.push_back(v5); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3, const T& v4) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); sequence.push_back(v4); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2, const T& v3) - { - sequence.push_back(v1); sequence.push_back(v2); - sequence.push_back(v3); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1, const T& v2) - { - sequence.push_back(v1); sequence.push_back(v2); - } - - template class Sequence> - inline void push_back(Sequence& sequence, - const T& v1) - { - sequence.push_back(v1); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9, const T& v10) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); set.insert(v8); - set.insert(v9); set.insert(v10); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); set.insert(v8); - set.insert(v9); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); set.insert(v8); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3, const T& v4) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2, const T& v3) - { - set.insert(v1); set.insert(v2); - set.insert(v3); - } - - template - inline void push_back(std::set& set, - const T& v1, const T& v2) - { - set.insert(v1); set.insert(v2); - } - - template - inline void push_back(std::set& set, - const T& v1) - { - set.insert(v1); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9, const T& v10) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); set.insert(v8); - set.insert(v9); set.insert(v10); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8, - const T& v9) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); set.insert(v8); - set.insert(v9); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7, const T& v8) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); set.insert(v8); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6, const T& v7) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - set.insert(v7); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5, const T& v6) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); set.insert(v6); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4, - const T& v5) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - set.insert(v5); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3, const T& v4) - { - set.insert(v1); set.insert(v2); - set.insert(v3); set.insert(v4); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2, const T& v3) - { - set.insert(v1); set.insert(v2); - set.insert(v3); - } - - template - inline void push_back(std::multiset& set, - const T& v1, const T& v2) - { - set.insert(v1); set.insert(v2); - } - - template - inline void push_back(std::multiset& set, - const T& v1) - { - set.insert(v1); - } - - template class Sequence> - inline void clear(Sequence& sequence) - { - sequence.clear(); - } - - template - inline void clear(std::set& set) - { - std::set null_set; - std::swap(set,null_set); - } - - template - inline void clear(std::multiset& multiset) - { - std::multiset null_set; - std::swap(multiset,null_set); - } - - template - inline void clear(std::queue& queue) - { - std::queue null_que; - std::swap(queue,null_que); - } - - template - inline void clear(std::stack& stack) - { - std::stack null_stack; - std::swap(stack,null_stack); - } - - template - inline void clear(std::priority_queue& priority_queue) - { - std::priority_queue null_pqueue; - std::swap(priority_queue,null_pqueue); - } - - } // namespace util - - namespace details - { - template - struct column_list_impl - { - enum { size = N }; - std::size_t index_list[N]; - }; - - template - class column_selector_base - { - public: - - typedef column_selector_base csb_t; - typedef column_list_impl column_list_t; - - column_selector_base(const column_list_t& column_list) - : column_list_(column_list), - current_index_(0), - target_index_(column_list_.index_list[0]), - col_list_index_(0), - error_count_(0) - {} - - inline csb_t& operator*() - { - return (*this); - } - - inline csb_t& operator++() - { - return (*this); - } - - inline csb_t operator++(int) - { - return (*this); - } - - template - inline csb_t& operator=(const std::pair& r) - { - process(r); - return (*this); - } - - void reset() - { - current_index_ = 0; - col_list_index_ = 0; - target_index_ = column_list_.index_list[0]; - error_count_ = 0; - } - - protected: - - class colsel_value_list - { - public: - - typedef std::pair value_t; - - colsel_value_list() - : current_index(0) - { - static const value_t null_value(strtk::util::value(),false); - std::fill_n(value_list,N,null_value); - } - - template - inline void register_value(T& t) - { - if (current_index < N) - { - value_list[current_index].first.assign(t); - value_list[current_index].second = false; - ++current_index; - } - } - - std::size_t current_index; - value_t value_list[N]; - }; - - template - inline void process(const std::pair& r) - { - if (current_index_ > target_index_) - return; - else if (current_index_ == target_index_) - { - typename colsel_value_list::value_t& v = cvl_.value_list[col_list_index_]; - if (true != (v.second = v.first(r.first,r.second))) - { - ++error_count_; - } - ++col_list_index_; - if (col_list_index_ < column_list_t::size) - target_index_ = column_list_.index_list[col_list_index_]; - else - target_index_ = std::numeric_limits::max(); - } - ++current_index_; - } - - inline colsel_value_list& cvl() - { - return cvl_; - } - - const column_list_t& column_list_; - std::size_t current_index_; - std::size_t target_index_; - std::size_t col_list_index_; - std::size_t error_count_; - colsel_value_list cvl_; - - private: - - csb_t& operator=(const csb_t& csb); - }; - - template - class column_selector_impl - : public column_selector_base,12> - { - public: - - typedef column_selector_base,12> csb_t; - typedef column_list_impl<12> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, - T10& t10, T11& t11) - : csb_t(column_list) - { - csb_t::cvl().register_value( t0); csb_t::cvl().register_value( t1); - csb_t::cvl().register_value( t2); csb_t::cvl().register_value( t3); - csb_t::cvl().register_value( t4); csb_t::cvl().register_value( t5); - csb_t::cvl().register_value( t6); csb_t::cvl().register_value( t7); - csb_t::cvl().register_value( t8); csb_t::cvl().register_value( t9); - csb_t::cvl().register_value(t10); csb_t::cvl().register_value(t11); - } - }; - - template - class column_selector_impl - : public column_selector_base,11> - { - public: - - typedef column_selector_base,11> csb_t; - typedef column_list_impl<11> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, - T10& t10) - : csb_t(column_list) - { - csb_t::cvl().register_value( t0); csb_t::cvl().register_value( t1); - csb_t::cvl().register_value( t2); csb_t::cvl().register_value( t3); - csb_t::cvl().register_value( t4); csb_t::cvl().register_value( t5); - csb_t::cvl().register_value( t6); csb_t::cvl().register_value( t7); - csb_t::cvl().register_value( t8); csb_t::cvl().register_value( t9); - csb_t::cvl().register_value(t10); - } - }; - - template - class column_selector_impl - : public column_selector_base,10> - { - public: - - typedef column_selector_base,10> csb_t; - typedef column_list_impl<10> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5); - csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7); - csb_t::cvl().register_value(t8); csb_t::cvl().register_value(t9); - } - }; - - template - class column_selector_impl - : public column_selector_base,9> - { - public: - - typedef column_selector_base,9> csb_t; - typedef column_list_impl<9> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5); - csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7); - csb_t::cvl().register_value(t8); - } - }; - - template - class column_selector_impl - : public column_selector_base,8> - { - public: - - typedef column_selector_base,8> csb_t; - typedef column_list_impl<8> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5, T6& t6, T7& t7) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5); - csb_t::cvl().register_value(t6); csb_t::cvl().register_value(t7); - } - }; - - template - class column_selector_impl - : public column_selector_base,7> - { - public: - - typedef column_selector_base,7> csb_t; - typedef column_list_impl<7> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, T3& t3, - T4& t4, T5& t5, T6& t6) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5); - csb_t::cvl().register_value(t6); - } - }; - - template - class column_selector_impl - : public column_selector_base,6> - { - public: - - typedef column_selector_base,6> csb_t; - typedef column_list_impl<6> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, - T3& t3, T4& t4, T5& t5) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - csb_t::cvl().register_value(t4); csb_t::cvl().register_value(t5); - } - }; - - template - class column_selector_impl - : public column_selector_base,5> - { - public: - - typedef column_selector_base,5> csb_t; - typedef column_list_impl<5> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, - T3& t3, T4& t4) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - csb_t::cvl().register_value(t4); - } - }; - - template - class column_selector_impl - : public column_selector_base,4> - { - public: - - typedef column_selector_base,4> csb_t; - typedef column_list_impl<4> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2, T3& t3) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); csb_t::cvl().register_value(t3); - } - }; - - template - class column_selector_impl - : public column_selector_base,3> - { - public: - - typedef column_selector_base,3> csb_t; - typedef column_list_impl<3> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1, T2& t2) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - csb_t::cvl().register_value(t2); - } - }; - - template - class column_selector_impl - : public column_selector_base,2> - { - public: - - typedef column_selector_base,2> csb_t; - typedef column_list_impl<2> column_list_t; - - column_selector_impl(const column_list_t& column_list, - T1& t0, T1& t1) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); csb_t::cvl().register_value(t1); - } - }; - - template - class column_selector_impl - : public column_selector_base,1> - { - public: - - typedef column_selector_base,1> csb_t; - typedef column_list_impl<1> column_list_t; - - column_selector_impl(const column_list_t& column_list, T0& t0) - : csb_t(column_list) - { - csb_t::cvl().register_value(t0); - } - }; - - } - - inline details::column_list_impl<12> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5, - const std::size_t& idx6, const std::size_t& idx7, - const std::size_t& idx8, const std::size_t& idx9, - const std::size_t& idx10, const std::size_t& idx11) - { - details::column_list_impl<12> cli; - cli.index_list[ 0] = idx0; cli.index_list[ 1] = idx1; - cli.index_list[ 2] = idx2; cli.index_list[ 3] = idx3; - cli.index_list[ 4] = idx4; cli.index_list[ 5] = idx5; - cli.index_list[ 6] = idx6; cli.index_list[ 7] = idx7; - cli.index_list[ 8] = idx8; cli.index_list[ 9] = idx9; - cli.index_list[10] = idx10; cli.index_list[11] = idx11; - return cli; - } - - inline details::column_list_impl<11> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5, - const std::size_t& idx6, const std::size_t& idx7, - const std::size_t& idx8, const std::size_t& idx9, - const std::size_t& idx10) - { - details::column_list_impl<11> cli; - cli.index_list[ 0] = idx0; cli.index_list[1] = idx1; - cli.index_list[ 2] = idx2; cli.index_list[3] = idx3; - cli.index_list[ 4] = idx4; cli.index_list[5] = idx5; - cli.index_list[ 6] = idx6; cli.index_list[7] = idx7; - cli.index_list[ 8] = idx8; cli.index_list[9] = idx9; - cli.index_list[10] = idx10; - return cli; - } - - inline details::column_list_impl<10> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5, - const std::size_t& idx6, const std::size_t& idx7, - const std::size_t& idx8, const std::size_t& idx9) - { - details::column_list_impl<10> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - cli.index_list[4] = idx4; cli.index_list[5] = idx5; - cli.index_list[6] = idx6; cli.index_list[7] = idx7; - cli.index_list[8] = idx8; cli.index_list[9] = idx9; - return cli; - } - - inline details::column_list_impl<9> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5, - const std::size_t& idx6, const std::size_t& idx7, - const std::size_t& idx8) - { - details::column_list_impl<9> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - cli.index_list[4] = idx4; cli.index_list[5] = idx5; - cli.index_list[6] = idx6; cli.index_list[7] = idx7; - cli.index_list[8] = idx8; - return cli; - } - - inline details::column_list_impl<8> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5, - const std::size_t& idx6, const std::size_t& idx7) - { - details::column_list_impl<8> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - cli.index_list[4] = idx4; cli.index_list[5] = idx5; - cli.index_list[6] = idx6; cli.index_list[7] = idx7; - return cli; - } - - inline details::column_list_impl<7> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5, - const std::size_t& idx6) - { - details::column_list_impl<7> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - cli.index_list[4] = idx4; cli.index_list[5] = idx5; - cli.index_list[6] = idx6; - return cli; - } - - inline details::column_list_impl<6> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4, const std::size_t& idx5) - { - details::column_list_impl<6> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - cli.index_list[4] = idx4; cli.index_list[5] = idx5; - return cli; - } - - inline details::column_list_impl<5> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3, - const std::size_t& idx4) - { - details::column_list_impl<5> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - cli.index_list[4] = idx4; - return cli; - } - - inline details::column_list_impl<4> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2, const std::size_t& idx3) - { - details::column_list_impl<4> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; cli.index_list[3] = idx3; - return cli; - } - - inline details::column_list_impl<3> - column_list(const std::size_t& idx0, const std::size_t& idx1, - const std::size_t& idx2) - { - details::column_list_impl<3> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - cli.index_list[2] = idx2; - return cli; - } - - inline details::column_list_impl<2> - column_list(const std::size_t& idx0, const std::size_t& idx1) - { - details::column_list_impl<2> cli; - cli.index_list[0] = idx0; cli.index_list[1] = idx1; - return cli; - } - - inline details::column_list_impl<1> - column_list(const std::size_t& idx0) - { - details::column_list_impl<1> cli; - cli.index_list[0] = idx0; - return cli; - } - - inline details::column_list_impl<12> column_list(const std::size_t (&idx)[12]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5], - idx[6],idx[7],idx[8],idx[9],idx[10],idx[11]); - } - - inline details::column_list_impl<11> column_list(const std::size_t (&idx)[11]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5], - idx[6],idx[7],idx[8],idx[9],idx[10]); - } - - inline details::column_list_impl<10> column_list(const std::size_t (&idx)[10]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5], - idx[6],idx[7],idx[8],idx[9]); - } - - inline details::column_list_impl<9> column_list(const std::size_t (&idx)[9]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5], - idx[6],idx[7],idx[8]); - } - - inline details::column_list_impl<8> column_list(const std::size_t (&idx)[8]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5], - idx[6],idx[7]); - } - - inline details::column_list_impl<7> column_list(const std::size_t (&idx)[7]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5],idx[6]); - } - - inline details::column_list_impl<6> column_list(const std::size_t (&idx)[6]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4],idx[5]); - } - - inline details::column_list_impl<5> column_list(const std::size_t (&idx)[5]) - { - return column_list(idx[0],idx[1],idx[2],idx[3],idx[4]); - } - - inline details::column_list_impl<4> column_list(const std::size_t (&idx)[4]) - { - return column_list(idx[0],idx[1],idx[2],idx[3]); - } - - inline details::column_list_impl<3> column_list(const std::size_t (&idx)[3]) - { - return column_list(idx[0],idx[1],idx[2]); - } - - inline details::column_list_impl<2> column_list(const std::size_t (&idx)[2]) - { - return column_list(idx[0],idx[1]); - } - - inline details::column_list_impl<1> column_list(const std::size_t (&idx)[1]) - { - return column_list(idx[0]); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<11>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, T11& t11) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<11>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9, T10& t10) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<10>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8,t9); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<9>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5,t6,t7,t8); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<8>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5,t6,t7); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<7>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5,t6); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<6>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4,t5); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<5>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3,t4); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<4>& col_list, - T0& t0, T1& t1, T2& t2, T3& t3) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2,t3); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<3>& col_list, - T0& t0, T1& t1, T2& t2) - { - return - details::column_selector_impl - - (col_list,t0,t1,t2); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<2>& col_list, - T0& t0, T1& t1) - { - return - details::column_selector_impl - - (col_list,t0,t1); - } - - template - inline typename details::column_selector_impl - column_selector(const details::column_list_impl<1>& col_list, T0& t0) - { - return - details::column_selector_impl - - (col_list,t0); - } - - namespace details - { - template - inline Iterator inc(Iterator itr, const std::size_t& n) - { - std::advance(itr,n); - return itr; - } - - //Single type column selectors - template - struct compose_st_selector_impl - {}; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<1> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<2> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<3> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<4> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<5> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<6> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<7> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<8> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6),*inc(b,7)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<9> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7],seq[8]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6),*inc(b,7),*inc(b,8)); - } - }; - - template - struct compose_st_selector_impl - { - typedef column_selector_impl type; - typedef column_list_impl<10> column_list_t; - - template class Sequence> - static inline type create(const column_list_t& col_list, Sequence& seq) - { - return type(col_list,seq[0],seq[1],seq[2],seq[3],seq[4],seq[5],seq[6],seq[7],seq[8],seq[9]); - } - - template - static inline type create(const column_list_t& col_list, std::list& list) - { - typename std::list::iterator b = list.begin(); - return type(col_list,*(b),*inc(b,1),*inc(b,2),*inc(b,3),*inc(b,4),*inc(b,5),*inc(b,6),*inc(b,7),*inc(b,8),*inc(b,9)); - } - }; - - } - - template class Sequence> - inline typename details::compose_st_selector_impl::type - column_selector(const details::column_list_impl& col_list, Sequence& seq) - { - if (seq.size() >= N) - { - typedef typename details::compose_st_selector_impl composer_t; - return composer_t::create(col_list,seq); - } - else - throw std::invalid_argument("column_selector(sequence/list) - size < N!"); - } - - namespace details - { - - template - class column_selector_iterator_impl - { - public: - - typedef column_selector_iterator_impl csii_t; - typedef details::column_list_impl column_list_t; - typedef std::pair iterator_type; - typedef iterator_type* iterator_type_ptr; - - column_selector_iterator_impl(const details::column_list_impl& column_list,iterator_type (&token_list)[N]) - : column_list_(column_list), - token_list_(token_list), - current_index_(0), - target_index_(column_list_.index_list[0]), - col_list_index_(0) - {} - - inline csii_t& operator*() - { - return (*this); - } - - inline csii_t& operator++() - { - return (*this); - } - - inline csii_t operator++(int) - { - return (*this); - } - - template - inline csii_t& operator=(const std::pair& r) - { - if (current_index_ == target_index_) - { - token_list_[col_list_index_] = r; - ++col_list_index_; - if (col_list_index_ < column_list_t::size) - target_index_ = column_list_.index_list[col_list_index_]; - else - target_index_ = std::numeric_limits::max(); - } - ++current_index_; - return (*this); - } - - private: - - csii_t& operator=(const csii_t& csb); - - const column_list_t& column_list_; - iterator_type_ptr token_list_; - std::size_t current_index_; - std::size_t target_index_; - std::size_t col_list_index_; - }; - - } - - #define strtk_parse_col_token(Index) \ - if (!string_to_type_converter(token_list[Index].first,token_list[Index].second,t##Index)) return false; - - #define strtk_parse_col_token_seq(Index) \ - if (!string_to_type_converter(token_list[Index].first,token_list[Index].second,seq[Index])) return false; - - #define strtk_parse_columns_impl(NN) \ - static const std::size_t N = NN; \ - typedef typename details::is_valid_iterator::type itr_type; \ - typedef std::pair iterator_type; \ - typedef details::column_selector_iterator_impl csii_t; \ - const std::size_t token_count = (column_list.index_list[N - 1] + 1); \ - details::convert_type_assert(); \ - iterator_type token_list[N]; \ - csii_t csii(column_list,token_list); \ - const std::size_t parsed_token_count = split_n \ - (delimiters,begin,end,token_count,csii,split_options::compress_delimiters);\ - if (token_count > parsed_token_count) return false; \ - - #define strk_parse_col_seq \ - return parse_columns(data.data(),data.data() + data.size(),delimiters,column_list,seq); - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<12>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9, T10& t10, T11& t11) - { - strtk_parse_columns_impl(12) - strtk_parse_col_token( 0) strtk_parse_col_token( 1) - strtk_parse_col_token( 2) strtk_parse_col_token( 3) - strtk_parse_col_token( 4) strtk_parse_col_token( 5) - strtk_parse_col_token( 6) strtk_parse_col_token( 7) - strtk_parse_col_token( 8) strtk_parse_col_token( 9) - strtk_parse_col_token(10) strtk_parse_col_token(11) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<11>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9, T10& t10) - { - strtk_parse_columns_impl(11) - strtk_parse_col_token( 0) strtk_parse_col_token(1) - strtk_parse_col_token( 2) strtk_parse_col_token(3) - strtk_parse_col_token( 4) strtk_parse_col_token(5) - strtk_parse_col_token( 6) strtk_parse_col_token(7) - strtk_parse_col_token( 8) strtk_parse_col_token(9) - strtk_parse_col_token(10) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<10>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, - T6& t6, T7& t7, T8& t8, T9& t9) - { - strtk_parse_columns_impl(10) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - strtk_parse_col_token(4) strtk_parse_col_token(5) - strtk_parse_col_token(6) strtk_parse_col_token(7) - strtk_parse_col_token(8) strtk_parse_col_token(9) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<9>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, - T7& t7, T8& t8) - { - strtk_parse_columns_impl(9) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - strtk_parse_col_token(4) strtk_parse_col_token(5) - strtk_parse_col_token(6) strtk_parse_col_token(7) - strtk_parse_col_token(8) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<8>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) - { - strtk_parse_columns_impl(8) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - strtk_parse_col_token(4) strtk_parse_col_token(5) - strtk_parse_col_token(6) strtk_parse_col_token(7) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<7>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) - { - strtk_parse_columns_impl(7) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - strtk_parse_col_token(4) strtk_parse_col_token(5) - strtk_parse_col_token(6) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<6>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) - { - strtk_parse_columns_impl(6) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - strtk_parse_col_token(4) strtk_parse_col_token(5) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<5>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) - { - strtk_parse_columns_impl(5) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - strtk_parse_col_token(4) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<4>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3) - { - strtk_parse_columns_impl(4) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) strtk_parse_col_token(3) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<3>& column_list, - T0& t0, T1& t1, T2& t2) - { - strtk_parse_columns_impl(3) - strtk_parse_col_token(0) strtk_parse_col_token(1) - strtk_parse_col_token(2) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<2>& column_list, - T0& t0, T1& t1) - { - strtk_parse_columns_impl(2) - strtk_parse_col_token(0) strtk_parse_col_token(1) - return true; - } - - template - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<1>& column_list, - T0& t0) - { - strtk_parse_columns_impl(1) - strtk_parse_col_token(0) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<12>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(12) - strtk_parse_col_token_seq( 0) strtk_parse_col_token_seq( 1) - strtk_parse_col_token_seq( 2) strtk_parse_col_token_seq( 3) - strtk_parse_col_token_seq( 4) strtk_parse_col_token_seq( 5) - strtk_parse_col_token_seq( 6) strtk_parse_col_token_seq( 7) - strtk_parse_col_token_seq( 8) strtk_parse_col_token_seq( 9) - strtk_parse_col_token_seq(10) strtk_parse_col_token_seq(11) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<11>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(11) - strtk_parse_col_token_seq( 0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq( 2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq( 4) strtk_parse_col_token_seq(5) - strtk_parse_col_token_seq( 6) strtk_parse_col_token_seq(7) - strtk_parse_col_token_seq( 8) strtk_parse_col_token_seq(9) - strtk_parse_col_token_seq(10) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<10>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(10) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5) - strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7) - strtk_parse_col_token_seq(8) strtk_parse_col_token_seq(9) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<9>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(9) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5) - strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7) - strtk_parse_col_token_seq(8) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<8>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(8) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5) - strtk_parse_col_token_seq(6) strtk_parse_col_token_seq(7) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<7>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(7) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5) - strtk_parse_col_token_seq(6) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<6>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(6) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq(4) strtk_parse_col_token_seq(5) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<5>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(5) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - strtk_parse_col_token_seq(4) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<4>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(4) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) strtk_parse_col_token_seq(3) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<3>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(3) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - strtk_parse_col_token_seq(2) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<2>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(2) - strtk_parse_col_token_seq(0) strtk_parse_col_token_seq(1) - return true; - } - - template class Sequence> - inline bool parse_columns(const InputIterator begin, - const InputIterator end, - const std::string& delimiters, - const details::column_list_impl<1>& column_list, - Sequence& seq) - { - strtk_parse_columns_impl(1) - strtk_parse_col_token_seq(0) - return true; - } - - #undef strtk_parse_col_token - #undef strtk_parse_col_token_seq - #undef strtk_parse_columns_impl - - #define strtk_parse_col_begin() \ - return parse_columns(data.data(), \ - data.data() + data.size(),delimiters,\ - column_list, \ - - #define strtk_parse_col_end() ); - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<12>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, - T10& t10, T11& t11) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<11>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, T9& t9, - T10& t10) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<10>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8, - T9& t9) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5,t6,t7,t8,t9 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<9>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7, T8& t8) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5,t6,t7,t8 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<8>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6, T7& t7) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5,t6,t7 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<7>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5, T6& t6) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5,t6 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<6>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, - T5& t5) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4,t5 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<5>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3, T4& t4) - { - strtk_parse_col_begin() - t0,t1,t2,t3,t4 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<4>& column_list, - T0& t0, T1& t1, T2& t2, T3& t3) - { - strtk_parse_col_begin() - t0,t1,t2,t3 - strtk_parse_col_end(); - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<3>& column_list, - T0& t0, T1& t1, T2& t2) - { - strtk_parse_col_begin() - t0,t1,t2 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<2>& column_list, - T0& t0, T1& t1) - { - strtk_parse_col_begin() - t0,t1 - strtk_parse_col_end() - } - - template - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<1>& column_list, - T& t) - { - strtk_parse_col_begin() - t - strtk_parse_col_end() - } - - #undef strtk_parse_col_begin - #undef strtk_parse_col_end - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<12>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<11>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<10>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<9>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<8>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<7>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<6>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<5>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<4>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<3>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<2>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - template class Sequence> - inline bool parse_columns(const std::string& data, - const std::string& delimiters, - const details::column_list_impl<1>& column_list, - Sequence& seq) - { - strk_parse_col_seq - } - - #undef strk_parse_col_seq - - namespace details - { - typedef const unsigned char* ptr; - - template - bool cmpimpl(ptr c1, ptr c2) { return (*reinterpret_cast(c1)) == (*reinterpret_cast(c2)); } - - template - struct size_impl { static inline bool cmp(ptr,ptr) { return true; } }; - - template <> - struct size_impl<8> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl(c1,c2); } }; - - template <> - struct size_impl<4> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl(c1,c2); } }; - - template <> - struct size_impl<2> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl(c1,c2); } }; - - template <> - struct size_impl<1> { static inline bool cmp(ptr c1, ptr c2) { return cmpimpl(c1,c2); } }; - - template - struct next_size { enum { size = (N >= 8) ? 8 : ((N >= 4) ? 4 : ((N >= 2) ? 2 : 1)) }; }; - - template - struct memcmp_n_impl - { - static inline bool process(details::ptr c1, details::ptr c2) - { - static const std::size_t size = details::next_size::size; - return details::size_impl::cmp(c1,c2) && memcmp_n_impl::process(c1 + size, c2 + size); - } - - static inline bool process(const char* c1, const char* c2) - { - return memcmp_n_impl::process(reinterpret_cast(c1),reinterpret_cast(c2)); - } - - template - static inline bool process(const unsigned char (&c1)[K1], const unsigned char (&c2)[K2]) - { - return memcmp_n_impl::process(static_cast(c1),static_cast(c2)); - } - }; - - template<> struct memcmp_n_impl<0> { static inline bool process(ptr,ptr) { return true; } }; - } - - template - inline bool memcmp_n(details::ptr c1, details::ptr c2) - { - return details::memcmp_n_impl::process(c1,c2); - } - - template - inline bool memcmp_n(const char* c1, const char* c2) - { - return details::memcmp_n_impl::process(c1,c2); - } - - template - inline bool memcmp_n(const unsigned char (&c1)[K1], const unsigned char (&c2)[K2]) - { - return details::memcmp_n_impl::process(c1,c2); - } - - namespace details - { - inline bool type_to_string_converter_impl(const strtk::util::value& v, std::string& result, value_type_tag) - { - return v.to_string(result); - } - } - - template - inline std::size_t distance(const std::pair& p) - { - return std::distance(p.first,p.second); - } - - template - inline std::pair make_pair(const std::string& s) - { - return std::make_pair( - reinterpret_cast(const_cast(s.data())), - reinterpret_cast(const_cast(s.data() + s.size()))); - } - - template - inline std::pair make_pair(const std::pair p) - { - return std::make_pair( - reinterpret_cast(const_cast(p.first)), - reinterpret_cast(const_cast(p.second))); - } - - template - inline std::pair make_pair(const std::string& s) - { - return make_pair(s); - } - - template - inline std::pair make_pair(const std::pair& p) - { - return make_pair(p); - } - - template - inline std::pair make_pair(const strtk::range::string& range) - { - return std::make_pair( - reinterpret_cast(const_cast(range.begin())), - reinterpret_cast(const_cast(range.end()))); - } - - template - inline std::string make_string(const unsigned char (&s)[N], const std::size_t& length = N) - { - static const std::string null_string; - if (N < length) - return null_string; - else - return std::string(&s[0],&s[0] + length); - } - - template - inline std::string make_string(const char (&s)[N], const std::size_t& length = N) - { - static const std::string null_string; - if (N < length) - return null_string; - else - return std::string(&s[0],&s[0] + length); - } - - inline std::string make_string(const std::pair& range) - { - return std::string(range.first,range.second); - } - - template - inline bool clear_array(T (&a)[N], const T& t, const std::size_t& length = N) - { - if (N < length) - return false; - else - std::fill_n(&a[0],length,t); - return true; - } - - template - inline bool set_array(unsigned char (&a)[N], - const std::string& s, - const bool pad = false, - const unsigned char padding = '0') - { - if (N < s.size()) - return false; - std::copy(s.data(),s.data() + s.size(), &a[0]); - if ((s.size() < N) && pad) - std::fill_n(&a[s.size()],N - s.size(),padding); - return true; - } - - template - inline bool set_array(unsigned char (&dest)[N], - unsigned char (&src)[M], - const bool pad = false, - const unsigned char padding = '0') - { - if (N < M) - return false; - std::copy(src,src + N, &dest[0]); - if ((M < N) && pad) - std::fill_n(&dest[M],N - M,padding); - return true; - } - - inline void reverse(const std_string::iterator_type& range) - { - char* begin = const_cast(range.first); - char* end = const_cast(range.second); - std::reverse(begin,end); - } - - template - inline void reverse(const range::adapter& r) - { - T* begin = const_cast(r.begin()); - T* end = const_cast(r.end()); - std::reverse(begin,end); - } - - template - inline void reverse(const range::adapter& r) - { - T* begin = const_cast(r.begin()); - T* end = const_cast(r.end()); - std::reverse(begin,end); - } - - inline void reverse(std::string& s) - { - std::reverse(s.begin(),s.end()); - } - - inline void fill(std::string& s, const std::string::value_type v) - { - std::fill(const_cast(s.data()),const_cast(s.data() + s.size()), v); - } - - inline void fill(const std::pair& range, char v) - { - char* begin = const_cast(range.first); - char* end = const_cast(range.second); - std::fill(begin,end,v); - } - - template - inline void fill(const range::adapter& r, const typename range::adapter::value_type& v) - { - char* begin = const_cast(r.begin()); - char* end = const_cast(r.end()); - std::fill(begin,end,v); - } - - inline void fill(const std_string::iterator_type& range, const std::string::value_type& v) - { - char* begin = const_cast(range.first); - char* end = const_cast(range.second); - std::fill(begin,end,v); - } - - template class Sequence> - inline void fill(Sequence& seq, const T& t) - { - if (seq.empty()) - return; - std::fill_n(seq.begin(),seq.size(),t); - } - - namespace keyvalue - { - template - struct options - { - typedef CharType char_type; - - options() - : pair_block_delimiter(0), - pair_delimiter(0) - {} - - char_type pair_block_delimiter; - char_type pair_delimiter; - }; - - template - class parser - { - public: - - typedef unsigned char char_type; - typedef std::pair range_type; - - template - parser(const Options& opts) - : options_(opts), - kv_map_(opts), - pair_block_sdp_(options_.pair_block_delimiter), - pair_delimiter_sdp_(options_.pair_delimiter) - { - const std::size_t pair_list_default_size = 32; - pair_list_.reserve(pair_list_default_size); - } - - template - inline bool register_keyvalue(const typename KeyValueMap::key_type& key, T& t) - { - return kv_map_.register_keyvalue(key,t); - } - - inline bool operator()(const range_type& data, const bool ignore_failures = false) - { - if (!ignore_failures) - { - pair_list_.clear(); - const std::size_t pair_count = split(pair_block_sdp_, - data.first, - data.second, - std::back_inserter(pair_list_)); - - if (0 == pair_count) - return false; - - range_type key_range; - range_type value_range; - - for (std::size_t i = 0; i < pair_count; ++i) - { - const range_type& r = pair_list_[i]; - if (0 == std::distance(r.first,r.second)) - continue; - else if (!split_pair(r.first,r.second, - pair_delimiter_sdp_, - key_range,value_range)) - return false; - else if (!kv_map_(key_range,value_range)) - return false; - } - return true; - } - else - { - parse_failures_ = 0; - pair_token_processor processor(*this); - split(pair_block_sdp_, - data.first, - data.second, - strtk::functional_inserter(processor)); - return true; - } - } - - inline bool operator()(const std::string& s, const bool ignore_failures = false) - { - return operator()(strtk::make_pair(s),ignore_failures); - } - - inline std::size_t failure_count() const - { - return parse_failures_; - } - - private: - - class pair_token_processor - { - public: - - pair_token_processor(parser& p) - : parser_(p) - {} - - inline void operator()(const range_type& r) - { - if (r.first == r.second) - return; - if (split_pair(r.first,r.second, - parser_.pair_delimiter_sdp_, - key_range, - value_range)) - { - if (parser_.kv_map_(key_range,value_range)) - return; - } - ++parser_.parse_failures_; - } - - private: - - pair_token_processor operator=(const pair_token_processor&); - - parser& parser_; - range_type key_range; - range_type value_range; - }; - - options options_; - std::size_t parse_failures_; - KeyValueMap kv_map_; - single_delimiter_predicate pair_block_sdp_; - single_delimiter_predicate pair_delimiter_sdp_; - std::vector pair_list_; - }; - - class uintkey_map - { - private: - - typedef unsigned char char_type; - typedef strtk::keyvalue::options general_options; - - public: - - typedef unsigned int key_type; - - struct options : public general_options - { - options() - : general_options(), - key_count(0) - {} - - std::size_t key_count; - }; - - template - uintkey_map(const Options& options) - { - value_lut_.resize(options.key_count,strtk::util::value()); - } - - virtual ~uintkey_map() - {} - - template - inline bool operator()(const Range& key_range, const Range& value_range) - { - std::size_t key = 0; - if (!fast::numeric_convert(distance(key_range),key_range.first,key,true)) - return false; - if (key >= value_lut_.size()) - return false; - const strtk::util::value& v = value_lut_[key]; - if (!v) - return false; - else - return v(value_range); - } - - template - inline bool register_keyvalue(const key_type& key, T& t) - { - if (key < value_lut_.size()) - { - strtk::util::value& v = value_lut_[key]; - if (!v) - v = strtk::util::value(t); - else - v.assign(t); - return true; - } - else - return false; - } - - private: - - std::vector value_lut_; - }; - - namespace details - { - template - struct keygen - { - static inline KType transform(const Range&) - { - return KType(); - } - }; - - template - struct keygen - { - static inline std::string transform(const Range& key_range) - { - return std::string(key_range.first,key_range.second); - } - }; - - template - struct keygen - { - static inline unsigned int transform(const Range& key_range) - { - unsigned int result = 0; - if (strtk::fast::numeric_convert(std::distance(key_range.first,key_range.second),key_range.first,result,true)) - return result; - else - return std::numeric_limits::max(); - } - }; - - struct no_op_validator - { - template - inline bool operator()(const Range&) - { - return true; - } - }; - } - - template , - typename KeyValidator = details::no_op_validator, - typename ValueValidator = details::no_op_validator> - class key_map - { - public: - - typedef KeyType key_type; - typedef MapType map_type; - typedef KeyValidator key_validator_type; - typedef ValueValidator value_validator_type; - - template - key_map(const Options&) - {} - - virtual ~key_map() - {} - - template - inline bool operator()(const Range& key_range, const Range& value_range) - { - if (!key_validator_(key_range)) - return false; - if (!val_validator_(value_range)) - return false; - typename map_type::iterator itr = value_map_.find(details::keygen::transform(key_range)); - if (value_map_.end() == itr) - return false; - const util::value& v = (*itr).second; - if (!v) - return false; - else - return v(value_range); - } - - template - inline bool register_keyvalue(const key_type& key, T& t) - { - strtk::util::value& v = value_map_[key]; - if (!v) - v = strtk::util::value(t); - else - v.assign(t); - return true; - } - - private: - - map_type value_map_; - key_validator_type key_validator_; - value_validator_type val_validator_; - }; - - typedef key_map stringkey_map; - - } -} // namespace strtk - -namespace -{ - - static inline std::ostream& operator<<(std::ostream& os, - const strtk::std_string::tokenizer >::type::iterator& range) - { - os << std::string((*range).first,(*range).second); - return os; - } - - static inline std::ostream& operator<<(std::ostream& os, - const strtk::std_string::tokenizer >::type::iterator& range) - { - os << std::string((*range).first,(*range).second); - return os; - } - - static inline std::ostream& operator<<(std::ostream& os, - const strtk::std_string::tokenizer::type::iterator& range) - { - os << std::string((*range).first,(*range).second); - return os; - } - - #define strtk_register_pair_to_ostream(Iterator) \ - static inline std::ostream& operator<<(std::ostream& os, const std::pair& range)\ - { os << std::string(range.first,range.second); return os; } \ - static inline std::ostream& operator<<(std::ostream& os, std::pair& range) \ - { os << std::string(range.first,range.second); return os; } \ - - strtk_register_pair_to_ostream(char*) - strtk_register_pair_to_ostream(unsigned char*) - strtk_register_pair_to_ostream(const char*) - strtk_register_pair_to_ostream(const unsigned char*) - strtk_register_pair_to_ostream(std::string::iterator) - strtk_register_pair_to_ostream(std::string::const_iterator) - strtk_register_pair_to_ostream(const std::string::iterator) - strtk_register_pair_to_ostream(const std::string::const_iterator) - - #undef strtk_register_pair_to_ostream - -} // namespace anonymous - -#if 0 - -#ifdef WIN32 - #ifndef NOMINMAX - #define NOMINMAX - #endif - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - #include -#else - #include - #include -#endif -namespace strtk -{ - namespace util - { - class timer - { - public: - - #ifdef WIN32 - timer() - : in_use_(false) - { - QueryPerformanceFrequency(&clock_frequency_); - } - - inline void start() - { - in_use_ = true; - QueryPerformanceCounter(&start_time_); - } - - inline void stop() - { - QueryPerformanceCounter(&stop_time_); - in_use_ = false; - } - - inline double time() const - { - return (1.0 * (stop_time_.QuadPart - start_time_.QuadPart)) / (1.0 * clock_frequency_.QuadPart); - } - - #else - - timer() - : in_use_(false) - { - start_time_.tv_sec = 0; - start_time_.tv_usec = 0; - stop_time_.tv_sec = 0; - stop_time_.tv_usec = 0; - } - - inline void start() - { - in_use_ = true; - gettimeofday(&start_time_,0); - } - - inline void stop() - { - gettimeofday(&stop_time_, 0); - in_use_ = false; - } - - inline unsigned long long int usec_time() const - { - if (!in_use_) - { - if (stop_time_.tv_sec >= start_time_.tv_sec) - { - return 1000000 * (stop_time_.tv_sec - start_time_.tv_sec ) + - (stop_time_.tv_usec - start_time_.tv_usec); - } - else - return std::numeric_limits::max(); - } - else - return std::numeric_limits::max(); - } - - inline double time() const - { - return usec_time() * 0.000001; - } - - #endif - - inline bool in_use() const - { - return in_use_; - } - - private: - - bool in_use_; - - #ifdef WIN32 - LARGE_INTEGER start_time_; - LARGE_INTEGER stop_time_; - LARGE_INTEGER clock_frequency_; - #else - struct timeval start_time_; - struct timeval stop_time_; - #endif - }; - - class scoped_timer - { - public: - - scoped_timer(double& time_value) - : time_value_(time_value) - { - t_.start(); - } - - ~scoped_timer() - { - t_.stop(); - time_value_ = t_.time(); - } - - private: - - scoped_timer(const scoped_timer&); - scoped_timer& operator=(const scoped_timer&); - - double& time_value_; - timer t_; - }; - - } // namespace util - - namespace information - { - static const char* library = "String Toolkit"; - static const char* version = "2.718281828459045235360287471352662497757247093699959574"; - static const char* date = "20140118"; - - static inline std::string data() - { - static const std::string info_str = std::string(library) + - std::string(" v") + std::string(version) + - std::string(" (") + date + std::string(")"); - return info_str; - } - - } // namespace information - -} // namespace strtk - -#endif - -#endif \ No newline at end of file