susumu.yata
null+****@clear*****
Sat Jun 29 00:18:25 JST 2013
susumu.yata 2013-06-29 00:18:25 +0900 (Sat, 29 Jun 2013) New Revision: 87208b8dff875b45bffc0fc90724d2b2a327ec1c https://github.com/groonga/grnxx/commit/87208b8dff875b45bffc0fc90724d2b2a327ec1c Message: Fix wrong guard macros. Added files: lib/grnxx/string_builder2.cpp lib/grnxx/string_builder2.hpp Modified files: lib/grnxx/broken_down_time.cpp lib/grnxx/broken_down_time.hpp lib/grnxx/duration.hpp lib/grnxx/periodic_clock.cpp lib/grnxx/periodic_clock.hpp lib/grnxx/stopwatch.hpp lib/grnxx/system_clock.cpp lib/grnxx/system_clock.hpp lib/grnxx/time.hpp Modified: lib/grnxx/broken_down_time.cpp (+1 -1) =================================================================== --- lib/grnxx/broken_down_time.cpp 2013-06-28 23:45:20 +0900 (0ec4d33) +++ lib/grnxx/broken_down_time.cpp 2013-06-29 00:18:25 +0900 (14fad5c) @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Brazil, Inc. + Copyright (C) 2012-2013 Brazil, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public Modified: lib/grnxx/broken_down_time.hpp (+4 -4) =================================================================== --- lib/grnxx/broken_down_time.hpp 2013-06-28 23:45:20 +0900 (b8476e1) +++ lib/grnxx/broken_down_time.hpp 2013-06-29 00:18:25 +0900 (7ec2275) @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Brazil, Inc. + Copyright (C) 2012-2013 Brazil, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRNXX_TIME_BROKEN_DOWN_TIME_HPP -#define GRNXX_TIME_BROKEN_DOWN_TIME_HPP +#ifndef GRNXX_BROKEN_DOWN_TIME_HPP +#define GRNXX_BROKEN_DOWN_TIME_HPP #include "grnxx/features.hpp" @@ -45,4 +45,4 @@ StringBuilder &operator<<(StringBuilder &builder, const BrokenDownTime &time); } // namespace grnxx -#endif // GRNXX_TIME_BROKEN_DOWN_TIME_HPP +#endif // GRNXX_BROKEN_DOWN_TIME_HPP Modified: lib/grnxx/duration.hpp (+3 -3) =================================================================== --- lib/grnxx/duration.hpp 2013-06-28 23:45:20 +0900 (f5391a1) +++ lib/grnxx/duration.hpp 2013-06-29 00:18:25 +0900 (f734d53) @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRNXX_TIME_DURATION_HPP -#define GRNXX_TIME_DURATION_HPP +#ifndef GRNXX_DURATION_HPP +#define GRNXX_DURATION_HPP #include "grnxx/features.hpp" @@ -169,4 +169,4 @@ StringBuilder &operator<<(StringBuilder &builder, Duration duration); } // namespace grnxx -#endif // GRNXX_TIME_DURATION_HPP +#endif // GRNXX_DURATION_HPP Modified: lib/grnxx/periodic_clock.cpp (+1 -1) =================================================================== --- lib/grnxx/periodic_clock.cpp 2013-06-28 23:45:20 +0900 (bf5e228) +++ lib/grnxx/periodic_clock.cpp 2013-06-29 00:18:25 +0900 (6d84332) @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Brazil, Inc. + Copyright (C) 2012-2013 Brazil, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public Modified: lib/grnxx/periodic_clock.hpp (+4 -4) =================================================================== --- lib/grnxx/periodic_clock.hpp 2013-06-28 23:45:20 +0900 (9c28aa8) +++ lib/grnxx/periodic_clock.hpp 2013-06-29 00:18:25 +0900 (75391eb) @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Brazil, Inc. + Copyright (C) 2012-2013 Brazil, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRNXX_TIME_PERIODIC_CLOCK_HPP -#define GRNXX_TIME_PERIODIC_CLOCK_HPP +#ifndef GRNXX_PERIODIC_CLOCK_HPP +#define GRNXX_PERIODIC_CLOCK_HPP #include "grnxx/features.hpp" @@ -42,4 +42,4 @@ class PeriodicClock { } // namespace grnxx -#endif // GRNXX_TIME_PERIODIC_CLOCK_HPP +#endif // GRNXX_PERIODIC_CLOCK_HPP Modified: lib/grnxx/stopwatch.hpp (+3 -3) =================================================================== --- lib/grnxx/stopwatch.hpp 2013-06-28 23:45:20 +0900 (4bc571f) +++ lib/grnxx/stopwatch.hpp 2013-06-29 00:18:25 +0900 (13edbac) @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRNXX_TIME_STOPWATCH_HPP -#define GRNXX_TIME_STOPWATCH_HPP +#ifndef GRNXX_STOPWATCH_HPP +#define GRNXX_STOPWATCH_HPP #include "grnxx/features.hpp" @@ -58,4 +58,4 @@ class Stopwatch { } // namespace grnxx -#endif // GRNXX_TIME_STOPWATCH_HPP +#endif // GRNXX_STOPWATCH_HPP Added: lib/grnxx/string_builder2.cpp (+187 -0) 100644 =================================================================== --- /dev/null +++ lib/grnxx/string_builder2.cpp 2013-06-29 00:18:25 +0900 (a711970) @@ -0,0 +1,187 @@ +/* + Copyright (C) 2012-2013 Brazil, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "grnxx/string_builder.hpp" + +#include <cmath> + +#include "grnxx/intrinsic.hpp" + +namespace grnxx { + +StringBuilder::StringBuilder(size_t size, StringBuilderFlags flags) + : buf_((size != 0) ? (new (std::nothrow) char[size]) : nullptr), + begin_(buf_.get()), + end_(buf_ ? (begin_ + size - 1) : nullptr), + ptr_(begin_), + flags_(flags), + failed_(!buf_) { + if (buf_) { + *ptr_ = '\0'; + } +} + +bool StringBuilder::resize_buf(size_t size) { + if (size < STRING_BUILDER_BUF_SIZE_MIN) { + size = STRING_BUILDER_BUF_SIZE_MIN; + } else { + size = size_t(1) << (bit_scan_reverse(size - 1) + 1); + } + + std::unique_ptr<char[]> new_buf(new (std::nothrow) char[size]); + if (!new_buf) { + return false; + } + + const size_t length = ptr_ - begin_; + std::memcpy(new_buf.get(), begin_, length); + ptr_ = new_buf.get() + length; + begin_ = new_buf.get(); + end_ = new_buf.get() + size - 1; + buf_ = std::move(new_buf); + return true; +} + +StringBuilder &operator<<(StringBuilder &builder, long long value) { + if (!builder) { + return builder; + } + + char buf[32]; + char *ptr = buf; + char *left = ptr; + if (value >= 0) { + do { + *ptr++ = static_cast<char>('0' + (value % 10)); + value /= 10; + } while (value != 0); + } else { + *ptr++ = '-'; + ++left; + + do { + // C++11 always rounds the result toward 0. + *ptr++ = static_cast<char>('0' - (value % 10)); + value /= 10; + } while (value != 0); + } + + char *right = ptr - 1; + while (left < right) { + using std::swap; + swap(*left++, *right--); + } + + return builder.append(buf, ptr - buf); +} +StringBuilder &operator<<(StringBuilder &builder, unsigned long long value) { + if (!builder) { + return builder; + } + + char buf[32]; + char *ptr = buf; + do { + *ptr++ = static_cast<char>('0' + (value % 10)); + value /= 10; + } while (value != 0); + + char *left = buf; + char *right = ptr - 1; + while (left < right) { + using std::swap; + swap(*left++, *right--); + } + + return builder.append(buf, ptr - buf); +} + +StringBuilder &operator<<(StringBuilder &builder, float value) { + return builder << static_cast<double>(value); +} + +StringBuilder &operator<<(StringBuilder &builder, double value) { + if (!builder) { + return builder; + } + + switch (std::fpclassify(value)) { + case FP_NORMAL: + case FP_SUBNORMAL: + case FP_ZERO: { + break; + } + case FP_INFINITE: { + if (value > 0) { + return builder.append("inf", 3); + } else { + return builder.append("-inf", 4); + } + } + case FP_NAN: + default: { + return builder.append("nan", 3); + } + } + + // The maximum value of double-precision floating point number (IEEE754) + // is 1.797693134862316E+308. + char buf[512]; + int length = std::snprintf(buf, sizeof(buf), "%f", value); + if (length < 0) { + return builder.append("n/a", 3); + } + if (static_cast<size_t>(length) >= sizeof(buf)) { + length = sizeof(buf) - 1; + } + return builder.append(buf, length); +} + +StringBuilder &operator<<(StringBuilder &builder, const void *value) { + if (!builder) { + return builder; + } + if (!value) { + return builder.append("nullptr", 7); + } + + char buf[(sizeof(value) * 2) + 2]; + buf[0] = '0'; + buf[1] = 'x'; + + uintptr_t address = reinterpret_cast<uintptr_t>(value); + for (size_t i = 2; i < sizeof(buf); ++i) { + const uintptr_t digit = address >> ((sizeof(value) * 8) - 4); + buf[i] = static_cast<char>( + (digit < 10) ? ('0' + digit) : ('A' + digit - 10)); + address <<= 4; + } + return builder.append(buf, sizeof(buf)); +} + +StringBuilder &operator<<(StringBuilder &builder, const Bytes &bytes) { + // TODO: StringBuilder should support const uint_8 *. + return builder.append(reinterpret_cast<const char *>(bytes.data()), + bytes.size()); +} + +StringBuilder &operator<<(StringBuilder &builder, + const std::exception &exception) { + return builder << "{ what = " << exception.what() << " }"; +} + +} // namespace grnxx Added: lib/grnxx/string_builder2.hpp (+298 -0) 100644 =================================================================== --- /dev/null +++ lib/grnxx/string_builder2.hpp 2013-06-29 00:18:25 +0900 (c6f0d22) @@ -0,0 +1,298 @@ +/* + Copyright (C) 2012-2013 Brazil, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#ifndef GRNXX_STRING_BUILDER_HPP +#define GRNXX_STRING_BUILDER_HPP + +#include "grnxx/features.hpp" + +#include <cstring> +#include <exception> +#include <memory> + +#include "grnxx/bytes.hpp" +#include "grnxx/flags_impl.hpp" +#include "grnxx/types.hpp" + +namespace grnxx { + +constexpr size_t STRING_BUILDER_BUF_SIZE_MIN = 64; + +class StringBuilder; +typedef FlagsImpl<StringBuilder> StringBuilderFlags; + +constexpr StringBuilderFlags STRING_BUILDER_AUTO_RESIZE = + StringBuilderFlags::define(0x01); + +class StringBuilder { + public: + explicit StringBuilder(StringBuilderFlags flags = StringBuilderFlags::none()) + : buf_(), + begin_(nullptr), + end_(nullptr), + ptr_(nullptr), + flags_(flags), + failed_(false) {} + + explicit StringBuilder(size_t size, + StringBuilderFlags flags = StringBuilderFlags::none()); + + template <size_t T> + explicit StringBuilder(char (&buf)[T], + StringBuilderFlags flags = StringBuilderFlags::none()) + : buf_(), + begin_(buf), + end_(buf + T - 1), + ptr_(buf), + flags_(flags), + failed_(false) { + *ptr_ = '\0'; + } + + StringBuilder(char *buf, size_t size, + StringBuilderFlags flags = StringBuilderFlags::none()) + : buf_(), + begin_(buf), + end_(buf + size - 1), + ptr_(buf), + flags_(flags), + failed_(false) { + *ptr_ = '\0'; + } + + ~StringBuilder() {} + + StringBuilder(StringBuilder &&rhs) + : buf_(std::move(rhs.buf_)), + begin_(std::move(rhs.begin_)), + end_(std::move(rhs.end_)), + ptr_(std::move(rhs.ptr_)), + flags_(std::move(rhs.flags_)), + failed_(std::move(rhs.failed_)) {} + + StringBuilder &operator=(StringBuilder &&rhs) { + buf_ = std::move(rhs.buf_); + begin_ = std::move(rhs.begin_); + end_ = std::move(rhs.end_); + ptr_ = std::move(rhs.ptr_); + flags_ = std::move(rhs.flags_); + failed_ = std::move(rhs.failed_); + return *this; + } + + explicit operator bool() const { + return !failed_; + } + + // For one-liners. + StringBuilder &builder() { + return *this; + } + + // Append a character. + StringBuilder &append(int byte) { + if (failed_) { + return *this; + } + + if (ptr_ == end_) { + if ((~flags_ & STRING_BUILDER_AUTO_RESIZE) || + !resize_buf(this->length() + 2)) { + failed_ = true; + return *this; + } + } + + *ptr_ = static_cast<char>(byte); + *++ptr_ = '\0'; + return *this; + } + + // Append a sequence of the same character. + StringBuilder &append(int byte, size_t length) { + if (failed_ || (length == 0)) { + return *this; + } + + const size_t size_left = end_ - ptr_; + if (length > size_left) { + if ((~flags_ & STRING_BUILDER_AUTO_RESIZE) || + !resize_buf(this->length() + length + 1)) { + length = size_left; + failed_ = true; + if (length == 0) { + return *this; + } + } + } + + std::memset(ptr_, byte, length); + ptr_ += length; + *ptr_ = '\0'; + return *this; + } + + // Append a sequence of length characters. + StringBuilder &append(const char *ptr, size_t length) { + if (failed_ || !ptr || (length == 0)) { + return *this; + } + + const size_t size_left = end_ - ptr_; + if (length > size_left) { + if ((~flags_ & STRING_BUILDER_AUTO_RESIZE) || + !resize_buf(this->length() + length + 1)) { + length = size_left; + failed_ = true; + } + } + + std::memcpy(ptr_, ptr, length); + ptr_ += length; + *ptr_ = '\0'; + return *this; + } + + StringBuilder &resize(size_t length) { + const size_t size_left = end_ - ptr_; + if (length > size_left) { + if ((~flags_ & STRING_BUILDER_AUTO_RESIZE) || + !resize_buf(length + 1)) { + length = size_left; + failed_ = true; + } + } + ptr_ = begin_ + length; + *ptr_ = '\0'; + return *this; + } + + const char &operator[](size_t i) const { + return begin_[i]; + } + char &operator[](size_t i) { + return begin_[i]; + } + + Bytes bytes() const { + return Bytes(c_str(), length()); + } + const char *c_str() const { + return begin_ ? begin_ : ""; + } + size_t length() const { + return ptr_ - begin_; + } + + void swap(StringBuilder &rhs) { + using std::swap; + swap(buf_, rhs.buf_); + swap(begin_, rhs.begin_); + swap(end_, rhs.end_); + swap(ptr_, rhs.ptr_); + swap(flags_, rhs.flags_); + swap(failed_, rhs.failed_); + } + + private: + std::unique_ptr<char[]> buf_; + char *begin_; + char *end_; + char *ptr_; + StringBuilderFlags flags_; + bool failed_; + + // Resize buf_ to greater than or equal to size bytes. + bool resize_buf(size_t size); + + StringBuilder(const StringBuilder &); + StringBuilder &operator=(const StringBuilder &); +}; + +inline void swap(StringBuilder &lhs, StringBuilder &rhs) { + lhs.swap(rhs); +} + +// Characters. +inline StringBuilder &operator<<(StringBuilder &builder, char value) { + return builder.append(value); +} + +// Signed integers. +StringBuilder &operator<<(StringBuilder &builder, long long value); + +inline StringBuilder &operator<<(StringBuilder &builder, signed char value) { + return builder << static_cast<long long>(value); +} +inline StringBuilder &operator<<(StringBuilder &builder, short value) { + return builder << static_cast<long long>(value); +} +inline StringBuilder &operator<<(StringBuilder &builder, int value) { + return builder << static_cast<long long>(value); +} +inline StringBuilder &operator<<(StringBuilder &builder, long value) { + return builder << static_cast<long long>(value); +} + +// Unsigned integers. +StringBuilder &operator<<(StringBuilder &builder, unsigned long long value); + +inline StringBuilder &operator<<(StringBuilder &builder, unsigned char value) { + return builder << static_cast<unsigned long long>(value); +} +inline StringBuilder &operator<<(StringBuilder &builder, unsigned short value) { + return builder << static_cast<unsigned long long>(value); +} +inline StringBuilder &operator<<(StringBuilder &builder, unsigned int value) { + return builder << static_cast<unsigned long long>(value); +} +inline StringBuilder &operator<<(StringBuilder &builder, unsigned long value) { + return builder << static_cast<unsigned long long>(value); +} + +// Floating point numbers. +StringBuilder &operator<<(StringBuilder &builder, float value); +StringBuilder &operator<<(StringBuilder &builder, double value); + +// Boolean values (true/false). +inline StringBuilder &operator<<(StringBuilder &builder, bool value) { + return value ? builder.append("true", 4) : builder.append("false", 5); +} + +// Pointers. +StringBuilder &operator<<(StringBuilder &builder, const void *value); + +// Zero-terminated strings. +inline StringBuilder &operator<<(StringBuilder &builder, const char *value) { + if (!builder) { + return builder; + } + if (!value) { + return builder.append("nullptr", 7); + } + return builder.append(value, std::strlen(value)); +} + +StringBuilder &operator<<(StringBuilder &builder, const Bytes &bytes); + +// Exceptions. +StringBuilder &operator<<(StringBuilder &builder, + const std::exception &exception); + +} // namespace grnxx + +#endif // GRNXX_STRING_BUILDER_HPP Modified: lib/grnxx/system_clock.cpp (+1 -1) =================================================================== --- lib/grnxx/system_clock.cpp 2013-06-28 23:45:20 +0900 (89995c1) +++ lib/grnxx/system_clock.cpp 2013-06-29 00:18:25 +0900 (39d390a) @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Brazil, Inc. + Copyright (C) 2012-2013 Brazil, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public Modified: lib/grnxx/system_clock.hpp (+4 -4) =================================================================== --- lib/grnxx/system_clock.hpp 2013-06-28 23:45:20 +0900 (7051ac2) +++ lib/grnxx/system_clock.hpp 2013-06-29 00:18:25 +0900 (9f46332) @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Brazil, Inc. + Copyright (C) 2012-2013 Brazil, Inc. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRNXX_TIME_SYSTEM_CLOCK_HPP -#define GRNXX_TIME_SYSTEM_CLOCK_HPP +#ifndef GRNXX_SYSTEM_CLOCK_HPP +#define GRNXX_SYSTEM_CLOCK_HPP #include "grnxx/features.hpp" @@ -31,4 +31,4 @@ class SystemClock { } // namespace grnxx -#endif // GRNXX_TIME_SYSTEM_CLOCK_HPP +#endif // GRNXX_SYSTEM_CLOCK_HPP Modified: lib/grnxx/time.hpp (+3 -3) =================================================================== --- lib/grnxx/time.hpp 2013-06-28 23:45:20 +0900 (b0f0fc6) +++ lib/grnxx/time.hpp 2013-06-29 00:18:25 +0900 (d6af5cd) @@ -15,8 +15,8 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GRNXX_TIME_TIME_HPP -#define GRNXX_TIME_TIME_HPP +#ifndef GRNXX_TIME_HPP +#define GRNXX_TIME_HPP #include "grnxx/features.hpp" @@ -111,4 +111,4 @@ StringBuilder &operator<<(StringBuilder &builder, Time time); } // namespace grnxx -#endif // GRNXX_TIME_TIME_HPP +#endif // GRNXX_TIME_HPP -------------- next part -------------- HTML����������������������������...Download