diff --git a/Builds/VisualStudio2012/beast.vcxproj b/Builds/VisualStudio2012/beast.vcxproj
index 9082fd54f..98652f38e 100644
--- a/Builds/VisualStudio2012/beast.vcxproj
+++ b/Builds/VisualStudio2012/beast.vcxproj
@@ -129,7 +129,6 @@
-
@@ -237,6 +236,8 @@
+
+
diff --git a/Builds/VisualStudio2012/beast.vcxproj.filters b/Builds/VisualStudio2012/beast.vcxproj.filters
index 2a04302ff..00d3da713 100644
--- a/Builds/VisualStudio2012/beast.vcxproj.filters
+++ b/Builds/VisualStudio2012/beast.vcxproj.filters
@@ -935,6 +935,12 @@
beast_core\containers\detail
+
+ beast_core\text
+
+
+ beast_core\text
+
diff --git a/modules/beast_core/beast_core.h b/modules/beast_core/beast_core.h
index 2ac12c9fd..babc3c9e7 100644
--- a/modules/beast_core/beast_core.h
+++ b/modules/beast_core/beast_core.h
@@ -271,6 +271,8 @@ extern BEAST_API void BEAST_CALLTYPE logAssertion (char const* file, int line) n
#include "containers/beast_LockFreeStack.h"
#include "threads/beast_SpinDelay.h"
#include "memory/beast_StaticObject.h"
+# include "text/StringCharPointerType.h"
+# include "text/StringFromNumber.h"
#include "text/beast_String.h"
#include "memory/beast_MemoryAlignment.h"
#include "memory/beast_CacheLine.h"
diff --git a/modules/beast_core/text/StringCharPointerType.h b/modules/beast_core/text/StringCharPointerType.h
new file mode 100644
index 000000000..37e82b7b2
--- /dev/null
+++ b/modules/beast_core/text/StringCharPointerType.h
@@ -0,0 +1,54 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Portions of this file are from JUCE.
+ Copyright (c) 2013 - Raw Material Software Ltd.
+ Please visit http://www.juce.com
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_STRINGCHARPOINTERTYPE_H_INCLUDED
+#define BEAST_STRINGCHARPOINTERTYPE_H_INCLUDED
+
+/** This is the character encoding type used internally to store the string.
+
+ By setting the value of BEAST_STRING_UTF_TYPE to 8, 16, or 32, you can change the
+ internal storage format of the String class. UTF-8 uses the least space (if your strings
+ contain few extended characters), but call operator[] involves iterating the string to find
+ the required index. UTF-32 provides instant random access to its characters, but uses 4 bytes
+ per character to store them. UTF-16 uses more space than UTF-8 and is also slow to index,
+ but is the native wchar_t format used in Windows.
+
+ It doesn't matter too much which format you pick, because the toUTF8(), toUTF16() and
+ toUTF32() methods let you access the string's content in any of the other formats.
+*/
+#if (BEAST_STRING_UTF_TYPE == 32)
+typedef CharPointer_UTF32 StringCharPointerType;
+
+#elif (BEAST_STRING_UTF_TYPE == 16)
+typedef CharPointer_UTF16 StringCharPointerType;
+
+#elif (BEAST_STRING_UTF_TYPE == 8)
+typedef CharPointer_UTF8 StringCharPointerType;
+
+#else
+#error "You must set the value of BEAST_STRING_UTF_TYPE to be either 8, 16, or 32!"
+
+#endif
+
+#endif
+
diff --git a/modules/beast_core/text/StringFromNumber.h b/modules/beast_core/text/StringFromNumber.h
new file mode 100644
index 000000000..b5f58fca8
--- /dev/null
+++ b/modules/beast_core/text/StringFromNumber.h
@@ -0,0 +1,159 @@
+//------------------------------------------------------------------------------
+/*
+ This file is part of Beast: https://github.com/vinniefalco/Beast
+ Copyright 2013, Vinnie Falco
+
+ Portions of this file are from JUCE.
+ Copyright (c) 2013 - Raw Material Software Ltd.
+ Please visit http://www.beast.com
+
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*/
+//==============================================================================
+
+#ifndef BEAST_CORE_STRINGFROMNUMBER_H_INCLUDED
+#define BEAST_CORE_STRINGFROMNUMBER_H_INCLUDED
+
+// This is private!
+//
+class NumberToStringConverters
+{
+public:
+ enum
+ {
+ charsNeededForInt = 32,
+ charsNeededForDouble = 48
+ };
+
+ // pass in a pointer to the END of a buffer..
+ template
+ static char* printDigits (char* t, Type v) noexcept
+ {
+ *--t = 0;
+ do
+ {
+ *--t = '0' + (char) (v % 10);
+ v /= 10;
+ }
+ while (v > 0);
+ return t;
+ }
+
+#ifdef _MSC_VER
+#pragma warning (push)
+#pragma warning (disable: 4127) // conditional expression is constant
+#pragma warning (disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
+#endif
+ // pass in a pointer to the END of a buffer..
+ template
+ static char* numberToString (char* t, IntegerType const n) noexcept
+ {
+ if (std::numeric_limits ::is_signed)
+ {
+ if (n >= 0)
+ return printDigits (t, static_cast (n));
+
+ // NB: this needs to be careful not to call
+ // -std::numeric_limits::min(),
+ // which has undefined behaviour
+ //
+ t = printDigits (t, static_cast (-(n + 1)) + 1);
+ *--t = '-';
+ return t;
+ }
+ return printDigits (t, n);
+ }
+#ifdef _MSC_VER
+#pragma warning (pop)
+#endif
+
+ struct StackArrayStream : public std::basic_streambuf >
+ {
+ explicit StackArrayStream (char* d)
+ {
+ imbue (std::locale::classic());
+ setp (d, d + charsNeededForDouble);
+ }
+
+ size_t writeDouble (double n, int numDecPlaces)
+ {
+ {
+ std::ostream o (this);
+
+ if (numDecPlaces > 0)
+ o.precision ((std::streamsize) numDecPlaces);
+
+ o << n;
+ }
+
+ return (size_t) (pptr() - pbase());
+ }
+ };
+
+ static char* doubleToString (char* buffer,
+ const int numChars, double n, int numDecPlaces, size_t& len) noexcept
+ {
+ if (numDecPlaces > 0 && numDecPlaces < 7 && n > -1.0e20 && n < 1.0e20)
+ {
+ char* const end = buffer + numChars;
+ char* t = end;
+ int64 v = (int64) (pow (10.0, numDecPlaces) * std::abs (n) + 0.5);
+ *--t = (char) 0;
+
+ while (numDecPlaces >= 0 || v > 0)
+ {
+ if (numDecPlaces == 0)
+ *--t = '.';
+
+ *--t = (char) ('0' + (v % 10));
+
+ v /= 10;
+ --numDecPlaces;
+ }
+
+ if (n < 0)
+ *--t = '-';
+
+ len = (size_t) (end - t - 1);
+ return t;
+ }
+
+ StackArrayStream strm (buffer);
+ len = strm.writeDouble (n, numDecPlaces);
+ bassert (len <= charsNeededForDouble);
+ return buffer;
+ }
+
+ static StringCharPointerType createFromFixedLength (
+ const char* const src, const size_t numChars);
+
+ template
+ static StringCharPointerType createFromInteger (const IntegerType number)
+ {
+ char buffer [charsNeededForInt];
+ char* const end = buffer + numElementsInArray (buffer);
+ char* const start = numberToString (end, number);
+ return createFromFixedLength (start, (size_t) (end - start - 1));
+ }
+
+ static StringCharPointerType createFromDouble (
+ const double number, const int numberOfDecimalPlaces)
+ {
+ char buffer [charsNeededForDouble];
+ size_t len;
+ char* const start = doubleToString (buffer, numElementsInArray (buffer), (double) number, numberOfDecimalPlaces, len);
+ return createFromFixedLength (start, len);
+ }
+};
+
+#endif
diff --git a/modules/beast_core/text/beast_String.cpp b/modules/beast_core/text/beast_String.cpp
index ac3c46a56..dbaa2f0b5 100644
--- a/modules/beast_core/text/beast_String.cpp
+++ b/modules/beast_core/text/beast_String.cpp
@@ -235,13 +235,24 @@ private:
StringHolder StringHolder::empty;
const String String::empty;
-//==============================================================================
+//------------------------------------------------------------------------------
+
+StringCharPointerType NumberToStringConverters::createFromFixedLength (
+ const char* const src, const size_t numChars)
+{
+ return StringHolder::createFromFixedLength (src, numChars);
+}
+
+//------------------------------------------------------------------------------
+
void String::preallocateBytes (const size_t numBytesNeeded)
{
- text = StringHolder::makeUniqueWithByteSize (text, numBytesNeeded + sizeof (CharPointerType::CharType));
+ text = StringHolder::makeUniqueWithByteSize (
+ text, numBytesNeeded + sizeof (CharPointerType::CharType));
}
//==============================================================================
+
String::String() noexcept : text (StringHolder::getEmpty())
{
}
@@ -356,130 +367,7 @@ String String::charToString (const beast_wchar character)
}
//==============================================================================
-namespace NumberToStringConverters
-{
- enum
- {
- charsNeededForInt = 32,
- charsNeededForDouble = 48
- };
- template
- static char* printDigits (char* t, Type v) noexcept
- {
- *--t = 0;
-
- do
- {
- *--t = '0' + (char) (v % 10);
- v /= 10;
-
- } while (v > 0);
-
- return t;
- }
-
-#ifdef _MSC_VER
-#pragma warning (push)
-#pragma warning (disable: 4127) // conditional expression is constant
-#pragma warning (disable: 4146) // unary minus operator applied to unsigned type, result still unsigned
-#endif
- // pass in a pointer to the END of a buffer..
- template
- static char* numberToString (char* t, IntegerType const n) noexcept
- {
- if (std::numeric_limits ::is_signed)
- {
- if (n >= 0)
- return printDigits (t, static_cast (n));
-
- // NB: this needs to be careful not to call -std::numeric_limits::min(),
- // which has undefined behaviour
- t = printDigits (t, static_cast (-(n + 1)) + 1);
- *--t = '-';
- return t;
- }
- return printDigits (t, n);
- }
-#ifdef _MSC_VER
-#pragma warning (pop)
-#endif
-
- struct StackArrayStream : public std::basic_streambuf >
- {
- explicit StackArrayStream (char* d)
- {
- imbue (std::locale::classic());
- setp (d, d + charsNeededForDouble);
- }
-
- size_t writeDouble (double n, int numDecPlaces)
- {
- {
- std::ostream o (this);
-
- if (numDecPlaces > 0)
- o.precision ((std::streamsize) numDecPlaces);
-
- o << n;
- }
-
- return (size_t) (pptr() - pbase());
- }
- };
-
- static char* doubleToString (char* buffer, const int numChars, double n, int numDecPlaces, size_t& len) noexcept
- {
- if (numDecPlaces > 0 && numDecPlaces < 7 && n > -1.0e20 && n < 1.0e20)
- {
- char* const end = buffer + numChars;
- char* t = end;
- int64 v = (int64) (pow (10.0, numDecPlaces) * std::abs (n) + 0.5);
- *--t = (char) 0;
-
- while (numDecPlaces >= 0 || v > 0)
- {
- if (numDecPlaces == 0)
- *--t = '.';
-
- *--t = (char) ('0' + (v % 10));
-
- v /= 10;
- --numDecPlaces;
- }
-
- if (n < 0)
- *--t = '-';
-
- len = (size_t) (end - t - 1);
- return t;
- }
-
- StackArrayStream strm (buffer);
- len = strm.writeDouble (n, numDecPlaces);
- bassert (len <= charsNeededForDouble);
- return buffer;
- }
-
- template
- static String::CharPointerType createFromInteger (const IntegerType number)
- {
- char buffer [charsNeededForInt];
- char* const end = buffer + numElementsInArray (buffer);
- char* const start = numberToString (end, number);
- return StringHolder::createFromFixedLength (start, (size_t) (end - start - 1));
- }
-
- static String::CharPointerType createFromDouble (const double number, const int numberOfDecimalPlaces)
- {
- char buffer [charsNeededForDouble];
- size_t len;
- char* const start = doubleToString (buffer, numElementsInArray (buffer), (double) number, numberOfDecimalPlaces, len);
- return StringHolder::createFromFixedLength (start, len);
- }
-}
-
-//==============================================================================
String::String (const int number) : text (NumberToStringConverters::createFromInteger (number)) {}
String::String (const unsigned int number) : text (NumberToStringConverters::createFromInteger (number)) {}
String::String (const short number) : text (NumberToStringConverters::createFromInteger ((int) number)) {}
@@ -492,40 +380,6 @@ String::String (const double number) : text (NumberToStringConverters::c
String::String (const float number, const int numberOfDecimalPlaces) : text (NumberToStringConverters::createFromDouble ((double) number, numberOfDecimalPlaces)) {}
String::String (const double number, const int numberOfDecimalPlaces) : text (NumberToStringConverters::createFromDouble (number, numberOfDecimalPlaces)) {}
-template
-String String::fromNumber (Number number, int)
-{
- return String (NumberToStringConverters::createFromInteger (number), FromNumber ());
-}
-
-template <>
-String String::fromNumber (float number, int numberOfDecimalPlaces)
-{
- if (numberOfDecimalPlaces == 0)
- number = std::floor (number);
-
- return String (NumberToStringConverters::createFromDouble (
- number, numberOfDecimalPlaces));
-}
-
-template <>
-String String::fromNumber (double number, int numberOfDecimalPlaces)
-{
- if (numberOfDecimalPlaces == 0)
- number = std::floor (number);
-
- return String (NumberToStringConverters::createFromDouble (
- number, numberOfDecimalPlaces));
-}
-
-template String String::fromNumber (int16, int);
-template String String::fromNumber (int32, int);
-template String String::fromNumber (int64, int);
-template String String::fromNumber (uint16, int);
-template String String::fromNumber (uint32, int);
-template String String::fromNumber (uint64, int);
-template String String::fromNumber (std::size_t, int);
-
//==============================================================================
int String::length() const noexcept
{
diff --git a/modules/beast_core/text/beast_String.h b/modules/beast_core/text/beast_String.h
index 980ea4cd5..aeff8329f 100644
--- a/modules/beast_core/text/beast_String.h
+++ b/modules/beast_core/text/beast_String.h
@@ -153,27 +153,8 @@ public:
*/
static const String empty;
- /** This is the character encoding type used internally to store the string.
-
- By setting the value of BEAST_STRING_UTF_TYPE to 8, 16, or 32, you can change the
- internal storage format of the String class. UTF-8 uses the least space (if your strings
- contain few extended characters), but call operator[] involves iterating the string to find
- the required index. UTF-32 provides instant random access to its characters, but uses 4 bytes
- per character to store them. UTF-16 uses more space than UTF-8 and is also slow to index,
- but is the native wchar_t format used in Windows.
-
- It doesn't matter too much which format you pick, because the toUTF8(), toUTF16() and
- toUTF32() methods let you access the string's content in any of the other formats.
- */
- #if (BEAST_STRING_UTF_TYPE == 32)
- typedef CharPointer_UTF32 CharPointerType;
- #elif (BEAST_STRING_UTF_TYPE == 16)
- typedef CharPointer_UTF16 CharPointerType;
- #elif (BEAST_STRING_UTF_TYPE == 8)
- typedef CharPointer_UTF8 CharPointerType;
- #else
- #error "You must set the value of BEAST_STRING_UTF_TYPE to be either 8, 16, or 32!"
- #endif
+ /** This is the character encoding type used internally to store the string. */
+ typedef StringCharPointerType CharPointerType;
//==============================================================================
/** Generates a probably-unique 32-bit hashcode from this string. */
@@ -1215,7 +1196,36 @@ private:
operator bool() const noexcept { return false; }
};
-//==============================================================================
+//------------------------------------------------------------------------------
+
+template
+inline String String::fromNumber (Number number, int)
+{
+ return String (NumberToStringConverters::createFromInteger
+ (number), FromNumber ());
+}
+
+template <>
+inline String String::fromNumber (float number, int numberOfDecimalPlaces)
+{
+ if (numberOfDecimalPlaces == 0)
+ number = std::floor (number);
+ return String (NumberToStringConverters::createFromDouble (
+ number, numberOfDecimalPlaces));
+}
+
+template <>
+inline String String::fromNumber (double number, int numberOfDecimalPlaces)
+{
+ if (numberOfDecimalPlaces == 0)
+ number = std::floor (number);
+
+ return String (NumberToStringConverters::createFromDouble (
+ number, numberOfDecimalPlaces));
+}
+
+//------------------------------------------------------------------------------
+
/** Concatenates two strings. */
BEAST_API String BEAST_CALLTYPE operator+ (const char* string1, const String& string2);
/** Concatenates two strings. */