Browse Source

Moved String Implementations around, moved repeated code (i.e: getWord) to templates, updated other code to be compatible to chagnes. CString_Strict is now typedef'd to CString_Type.

release/0.19
JustinAJ 11 years ago
parent
commit
342c948b49
  1. 217
      Jupiter/CString.h
  2. 854
      Jupiter/CString_Imp.h
  3. 2
      Jupiter/File.cpp
  4. 2
      Jupiter/IRC_Client.cpp
  5. 7
      Jupiter/Jupiter.vcxproj
  6. 21
      Jupiter/Jupiter.vcxproj.filters
  7. 34
      Jupiter/Shift_String.h
  8. 40
      Jupiter/Shift_String_Imp.h
  9. 101
      Jupiter/String_Type.h
  10. 438
      Jupiter/String_Type_Imp.h
  11. BIN
      Release/Jupiter.lib
  12. 1
      Tester/Tester.vcxproj

217
Jupiter/CString.h

@ -30,8 +30,7 @@
namespace Jupiter
{
/**
* @brief Provides the basis for CString classes by providing the implementations for many abstract methods in String_Type.
* Note: This is an abstract type.
* @brief Provides the basis for CString classes by providing a minimalist implementation (i.e: no extra variables).
*
* @param T Element type which the CString will store. Defaults to char.
*/
@ -62,24 +61,6 @@ namespace Jupiter
*/
bool remove(const T &value);
/** Assignment Operators */
inline CString_Type<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T right) { this->set(right); return *this; };
};
/**
* @brief Provides a "strict" CString implementation that's more optimized for minimal memory usage.
* Note: This recreates the underlying C-style string with every concatenation.
*
* @param T Element type which the CString will store. Defaults to char.
*/
template<typename T = char> class CString_Strict : public CString_Type<T>
{
public:
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
@ -108,7 +89,7 @@ namespace Jupiter
* @param ... Inputs to match the format specifiers.
* @return String containing the new format.
*/
static CString_Strict Format(const T *format, ...);
static CString_Type Format(const T *format, ...);
/**
* @brief Creates a partial copy of the string.
@ -116,7 +97,7 @@ namespace Jupiter
* @param pos Position in the string to start copying from.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> substring(size_t pos) const;
CString_Type<T> substring(size_t pos) const;
/**
* @brief Creates a partial copy of the string.
@ -125,7 +106,7 @@ namespace Jupiter
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> substring(size_t pos, size_t length) const;
CString_Type<T> substring(size_t pos, size_t length) const;
/**
* @brief Creates a partial copy of the string.
@ -134,7 +115,8 @@ namespace Jupiter
* @param pos Position in the string to start copying from.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> substring(const Jupiter::String_Type<T> &in, size_t pos);
static CString_Type<T> substring(const Jupiter::String_Type<T> &in, size_t pos);
static CString_Type<T> substring(const T *in, size_t pos);
/**
* @brief Creates a partial copy of the string.
@ -144,7 +126,8 @@ namespace Jupiter
* @param length Number of characters to copy.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> substring(const Jupiter::String_Type<T> &in, size_t pos, size_t length);
static CString_Type<T> substring(const Jupiter::String_Type<T> &in, size_t pos, size_t length);
static CString_Type<T> substring(const T *in, size_t pos, size_t length);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
@ -153,7 +136,7 @@ namespace Jupiter
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> getWord(size_t pos, const T *whitespace) const;
CString_Type<T> getWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
@ -163,7 +146,7 @@ namespace Jupiter
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> getWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
static CString_Type<T> getWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of an input string, based on a set of tokens.
@ -173,7 +156,7 @@ namespace Jupiter
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> getWord(const T *in, size_t pos, const T *whitespace);
static CString_Type<T> getWord(const T *in, size_t pos, const T *whitespace);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
@ -182,7 +165,7 @@ namespace Jupiter
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
CString_Strict<T> gotoWord(size_t pos, const T *whitespace) const;
CString_Type<T> gotoWord(size_t pos, const T *whitespace) const;
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
@ -192,7 +175,7 @@ namespace Jupiter
* @param whitespace A string of tokens used to deliminate words.
* @return String containing a partial copy of the original string.
*/
static CString_Strict<T> gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
static CString_Type<T> gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Copies the data from the input string to the CString.
@ -205,26 +188,6 @@ namespace Jupiter
size_t set(const T *in);
size_t set(const T in);
/**
* @brief Sets the string buffer.
* Note: This class will free the buffer for you when it's done.
*
* @param in New buffer to be used.
* @return The length of the string.
*/
size_t setString(T *in);
/**
* @brief Sets the string buffer.
* Note: This class will free the buffer for you when it's done. DO NOT DELETE THE INPUT BUFFER.
* Note: This method is unique to the CString_Strict template class, and does not appear in CString_Loose.
*
* @param in New buffer to be used.
* @param size At least the number of characters in the buffer, not including the null-terminator.
* @return The length of the string.
*/
size_t setString(T *in, size_t size);
/**
* @brief Copies the data from the input string and concatenates it to the end of CString.
*
@ -236,56 +199,68 @@ namespace Jupiter
size_t concat(const T *in);
size_t concat(const T in);
/** Assignment Operators */
inline CString_Type<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Type<T> &operator=(const T right) { this->set(right); return *this; };
static const Jupiter::CString_Type<T> empty; /** Empty instantation of CString_Type */
/** Default Constructor */
CString_Strict();
CString_Type();
/** Copy Constructors */
CString_Strict(const String_Type<T> &in);
CString_Strict(const std::basic_string<T> &in);
CString_Strict(const T *in);
CString_Strict(size_t size);
/**
* @brief Size hint constructor.
* Note: For the CString_Type base class, this is only truly useful internally.
*
* @param size Minimum number of elements the string must be able to hold.
*/
CString_Type(size_t size);
/** Destructor */
virtual ~CString_Strict();
/** Move Constructor */
CString_Type(CString_Type<T> &&source);
/** Assignment Operators */
inline CString_Strict<T> &operator=(const CString_Strict<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const CString_Type<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const String_Type<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const std::basic_string<T> &right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const T *right) { this->set(right); return *this; };
inline CString_Strict<T> &operator=(const T right) { this->set(right); return *this; };
};
/** Copy Constructors */
CString_Type(const String_Type<T> &in);
CString_Type(const std::basic_string<T> &in);
CString_Type(const T *in);
protected:
/**
* @brief Provides a "loose" CString implementation that's more optimized for repeated concatenations.
* Note: The underlying C-style string will always have a size which is a power of 2, but no fewer than 8 elements.
* @brief Sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param T Element type which the CString will store. Defaults to char.
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
template<typename T = char> class CString_Loose : public CString_Type<T>
{
public:
virtual bool setBufferSize(size_t len);
/**
* @brief Sets the CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
* @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
size_t vformat(const T *format, va_list args);
virtual bool setBufferSizeNoCopy(size_t len);
/** Dummy constructor to prevent string initialization */
CString_Type(Jupiter::String_Constructor_Base &) {};
};
template<typename T = char> using CString_Strict = CString_Type<T>;
/**
* @brief Appends to a CString's contents based on the format string and input variables.
* Note: Format specifiers similar to printf. Returns 0 for any type other than char and wchar_t.
* @brief Provides a "loose" CString implementation that's more optimized for repeated concatenations.
* Note: The underlying C-style string will always have a size which is a power of 2, but no fewer than 8 elements.
*
* @param format Format that the string is compared against.
* @param ... Inputs to match the format specifiers.
* @return Number of characters written.
* @param T Element type which the CString will store. Defaults to char.
*/
size_t avformat(const T *format, va_list args);
template<typename T = char> class CString_Loose : public CString_Type<T>
{
public:
/**
* @brief Sets the CString's contents based on the format string and input variables.
@ -322,6 +297,7 @@ namespace Jupiter
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> substring(const Jupiter::String_Type<T> &in, size_t pos);
static CString_Loose<T> substring(const T *in, size_t pos);
/**
* @brief Creates a partial copy of the string.
@ -332,6 +308,7 @@ namespace Jupiter
* @return String containing a partial copy of the original string.
*/
static CString_Loose<T> substring(const Jupiter::String_Type<T> &in, size_t pos, size_t length);
static CString_Loose<T> substring(const T *in, size_t pos, size_t length);
/**
* @brief Creates a partial copy of the string, based on a set of tokens.
@ -383,48 +360,26 @@ namespace Jupiter
*/
static CString_Loose<T> gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
/**
* @brief Copies the data from the input string to the CString.
*
* @param in String containing the data to be copied.
* @return New size of the CString.
*/
size_t set(const CString_Loose &in);
size_t set(const String_Type<T> &in);
size_t set(const std::basic_string<T> &in);
size_t set(const T *in);
size_t set(const T in);
/**
* @brief Copies the data from the input string and concatenats it to the end of CString.
*
* @param in String containing the data to be concatenated.
* @return New size of the CString.
*/
size_t concat(const String_Type<T> &in);
size_t concat(const std::basic_string<T> &in);
size_t concat(const T *in);
size_t concat(const T in);
/** Default constructor */
CString_Loose();
/**
* @brief Size hint constructor.
*
* @param size Minimum size of new string's buffer.
* @param size Minimum number of elements the string must be able to hold.
*/
CString_Loose(size_t size);
/** Move Constructor */
CString_Loose(CString_Loose<T> &&source);
/** Copy Constructors */
CString_Loose(const CString_Loose &in);
CString_Loose(const String_Type<T> &in);
CString_Loose(const std::basic_string<T> &in);
CString_Loose(const T *in);
/** Destructor */
virtual ~CString_Loose();
static const Jupiter::CString_Loose<T> empty; /** Empty instantation of CString_Loose */
static const size_t start_size = 8; /** Starting size for loose CStrings. */
/** Assignment Operators */
@ -436,6 +391,28 @@ namespace Jupiter
inline CString_Loose<T> &operator=(const T right) { this->set(right); return *this; };
protected:
/**
* @brief Sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSize(size_t len);
/**
* @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSizeNoCopy(size_t len);
/** Dummy constructor to prevent string initialization */
CString_Loose(Jupiter::String_Constructor_Base &) {};
size_t strSize; /** Size of underlying C-string buffer */
};
@ -445,12 +422,6 @@ namespace Jupiter
/** Definition of a Loose Wide CString */
typedef CString_Loose<wchar_t> WCStringL;
/** Definition of a Strict CString. */
typedef CString_Strict<char> CStringS;
/** Definition of a Strict Wide CString */
typedef CString_Strict<wchar_t> WCStringS;
/** Definition of a CString. */
typedef CStringL CString;
@ -463,14 +434,20 @@ namespace Jupiter
/** Generic Wide CString Type */
typedef CString_Type<wchar_t> WCStringType;
/** Definition of a Strict CString. */
typedef CStringType CStringS;
/** Definition of a Strict Wide CString */
typedef WCStringType WCStringS;
/** Empty String constants */
static const Jupiter::CStringS emptyCStringS;
static const Jupiter::CStringL emptyCStringL;
static const Jupiter::CStringS &emptyCStringS = Jupiter::CStringS::empty;
static const Jupiter::CStringL &emptyCStringL = Jupiter::CStringL::empty;
static const Jupiter::CStringType &emptyCString = emptyCStringS;
static const Jupiter::StringType &emptyString = emptyCString;
}
/** Implementation for CString_Type, CString_Strict, and CString_Loose. Very scary. */
/** Implementation for CString_Type and CString_Loose. Very scary. */
#include "CString_Imp.h"
#endif // _CSTRING_H_HEADER

854
Jupiter/CString_Imp.h

File diff suppressed because it is too large

2
Jupiter/File.cpp

@ -28,7 +28,7 @@ int64_t getFileSize(const char *file)
const size_t defaultBufferSize = 8192;
template class JUPITER_API Jupiter::CString_Strict<char>;
template class JUPITER_API Jupiter::CString_Type<char>;
struct JUPITER_API Jupiter::File::Data
{

2
Jupiter/IRC_Client.cpp

@ -30,7 +30,7 @@
Jupiter::INIFile _Config;
Jupiter::INIFile *Jupiter::IRC::Client::Config = &_Config;
template class JUPITER_API Jupiter::CString_Strict<char>;
template class JUPITER_API Jupiter::CString_Type<char>;
template class JUPITER_API Jupiter::ArrayList<Jupiter::IRC::Client::User>;
template class JUPITER_API Jupiter::ArrayList<Jupiter::IRC::Client::Channel>;

7
Jupiter/Jupiter.vcxproj

@ -74,6 +74,8 @@
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<ExceptionHandling>Async</ExceptionHandling>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<DisableSpecificWarnings>4505</DisableSpecificWarnings>
<C99Support>true</C99Support>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -133,8 +135,13 @@
<ClInclude Include="Rehash.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="SecureSocket.h" />
<ClInclude Include="Shift_String.h" />
<ClInclude Include="Shift_String_Imp.h" />
<ClInclude Include="SLList.h" />
<ClInclude Include="Socket.h" />
<ClInclude Include="String.h" />
<ClInclude Include="String_Imp.h" />
<ClInclude Include="String_Type_Imp.h" />
<ClInclude Include="String_Type.h" />
<ClInclude Include="TCPSocket.h" />
<ClInclude Include="Thinker.h" />

21
Jupiter/Jupiter.vcxproj.filters

@ -57,9 +57,6 @@
<ClCompile Include="IRC.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
<ClCompile Include="IRC_Client.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
<ClCompile Include="IRC_Server.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
@ -102,6 +99,9 @@
<ClCompile Include="Base64C.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="IRC_Client.cpp">
<Filter>Source Files\IRC</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Functions.h">
@ -188,6 +188,21 @@
<ClInclude Include="InvalidIndex.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="String_Type_Imp.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="Shift_String.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="Shift_String_Imp.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="String.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
<ClInclude Include="String_Imp.h">
<Filter>Header Files\Strings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Jupiter.rc">

34
Jupiter/Shift_String.h

@ -62,7 +62,41 @@ namespace Jupiter
*/
virtual bool remove(const T &value);
/**
* @brief Default constructor for the Shift_String_Type class.
*/
Shift_String_Type() {}
/**
* @brief Move constructor for the Shift_String_Type class.
*/
Shift_String_Type(Jupiter::Shift_String_Type<T> &&source);
/**
* @brief Destructor for the Shift_String_Type class.
*/
virtual ~Shift_String_Type();
protected:
/**
* @brief Sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSize(size_t len);
/**
* @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This still empties the string if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSizeNoCopy(size_t len);
T *base; /** Base pointer for the underlying String's memory allocation */
};
}

40
Jupiter/Shift_String_Imp.h

@ -24,6 +24,17 @@
* Note: Modification of this file is not supported in any way.
*/
template<typename T> Jupiter::Shift_String_Type<T>::Shift_String_Type(Jupiter::Shift_String_Type<T> &&source) : Jupiter::String_Type<T>(std::move(source))
{
Jupiter::Shift_String_Type<T>::base = source.base;
source.base = nullptr;
}
template<typename T> Jupiter::Shift_String_Type<T>::~Shift_String_Type()
{
if (Jupiter::Shift_String_Type<T>::base != nullptr) delete[] Jupiter::Shift_String_Type<T>::base;
}
template<typename T> size_t Jupiter::Shift_String_Type<T>::shiftLeft(size_t len)
{
size_t offset = Jupiter::String_Type<T>::str - Jupiter::Shift_String_Type<T>::base;
@ -53,4 +64,33 @@ template<typename T> bool Jupiter::Shift_String_Type<T>::remove(const T &value)
return Jupiter::String_Type<T>::remove(value);
}
template<typename T> bool Jupiter::Shift_String_Type<T>::setBufferSize(size_t len)
{
if (len > Jupiter::String_Type<T>::length)
{
T *ptr = new T[len];
for (unsigned int i = 0; i < Jupiter::String_Type<T>::length; i++) ptr[i] = Jupiter::String_Type<T>::str[i];
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = ptr;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
}
return false;
}
template<typename T> bool Jupiter::Shift_String_Type<T>::setBufferSizeNoCopy(size_t len)
{
if (len > Jupiter::String_Type<T>::length)
{
Jupiter::String_Type<T>::length = 0;
delete[] Jupiter::Shift_String_Type<T>::base;
Jupiter::Shift_String_Type<T>::base = new T[len];
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return true;
}
Jupiter::String_Type<T>::length = 0;
Jupiter::String_Type<T>::str = Jupiter::Shift_String_Type<T>::base;
return false;
}
#endif // _SHIFT_STRING_IMP_H_HEADER

101
Jupiter/String_Type.h

@ -232,10 +232,10 @@ namespace Jupiter
* @param in String containing the data to be copied.
* @return New size of the String.
*/
virtual size_t set(const String_Type<T> &in) = 0;
virtual size_t set(const std::basic_string<T> &in) = 0;
virtual size_t set(const T *in) = 0;
virtual size_t set(const T in) = 0;
virtual size_t set(const String_Type<T> &in);
virtual size_t set(const std::basic_string<T> &in);
virtual size_t set(const T *in);
virtual size_t set(const T in);
/**
* @brief Copies the data from the input string and concatenates it to the end of String.
@ -243,16 +243,66 @@ namespace Jupiter
* @param in String containing the data to be concatenated.
* @return New size of the CString.
*/
virtual size_t concat(const String_Type<T> &in) = 0;
virtual size_t concat(const std::basic_string<T> &in) = 0;
virtual size_t concat(const T *in) = 0;
virtual size_t concat(const T in) = 0;
virtual size_t concat(const String_Type<T> &in);
virtual size_t concat(const std::basic_string<T> &in);
virtual size_t concat(const T *in);
virtual size_t concat(const T in);
/**
* @brief Copies a part of an input string and returns it in an output type.
*
* @param R Type to return. Must be a subclass of String_Type.
*
* @param in String to get a partial copy of.
* @param pos Position to start copying from.
* @return Partial copy of the input string.
*/
template<template<typename> class R> static R<T> substring(const Jupiter::String_Type<T> &in, size_t pos);
template<template<typename> class R> static R<T> substring(const T *in, size_t pos);
/**
* @brief Copies a part of an input string and returns it in an output type.
*
* @param R Type to return. Must be a subclass of String_Type.
*
* @param in String to get a partial copy of.
* @param pos Position to start copying from.
* @param len Number of elements to copy.
* @return Partial copy of the input string.
*/
template<template<typename> class R> static R<T> substring(const Jupiter::String_Type<T> &in, size_t pos, size_t len);
template<template<typename> class R> static R<T> substring(const T *in, size_t pos, size_t len);
/**
* @brief Copies a "word" from an input string and returns it in an output type.
*
* @param R Type to return. Must be a subclass of String_Type.
*
* @param in String to get a partial copy of.
* @param pos Index of the word to copy.
* @param whitespace String of characters that are to be considered whitespace.
* @return Copy of the word at the specified index on success, an empty string otherwise.
*/
template<template<typename> class R> static R<T> getWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
template<template<typename> class R> static R<T> getWord(const T *in, size_t pos, const T *whitespace);
/**
* @brief Copies a part of an input string starting at a specified "word" and returns it in an output type.
*
* @param R Type to return. Must be a subclass of String_Type.
*
* @param in String to get a partial copy of.
* @param pos Index of the word to start copying from.
* @param whitespace String of characters that are to be considered whitespace.
* @return Copy of the string starting at the specified word on success, an empty string otherwise.
*/
template<template<typename> class R> static R<T> gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace);
template<template<typename> class R> static R<T> gotoWord(const T *in, size_t pos, const T *whitespace);
/** Access operator */
inline T &operator[](size_t index) { return Jupiter::String_Type<T>::get(index); };
// Mutative operators.
// Note: All extending classes must overload operator= for its own type.
/** Mutative operators */
inline String_Type<T> &operator+=(const String_Type<T> &right) { this->concat(right); return *this; };
inline String_Type<T> &operator+=(const std::basic_string<T> &right) { this->concat(right); return *this; };
inline String_Type<T> &operator+=(const T *right) { this->concat(right); return *this; };
@ -263,7 +313,7 @@ namespace Jupiter
inline String_Type<T> &operator=(const T *right) { this->set(right); return *this; };
inline String_Type<T> &operator=(const T right) { this->set(right); return *this; };
// Comparative operators.
/** Comparative operators */
inline bool operator==(const String_Type<T> &right)const{ return this->equals(right); }
inline bool operator==(const std::basic_string<T> &right)const{ return this->equals(right); }
inline bool operator==(const T *right)const{ return this->equals(right); }
@ -289,6 +339,16 @@ namespace Jupiter
inline bool operator>=(const T *right)const{ return !operator<(right); }
inline bool operator>=(const T right)const{ return !operator<(right); }
/**
* @brief Default constructor for the String_Type class.
*/
String_Type() {}
/**
* @brief Move constructor for the String_Type class.
*/
String_Type(Jupiter::String_Type<T> &&source);
/**
* The following constructors should exist:
* A default constructor
@ -299,6 +359,25 @@ namespace Jupiter
*/
protected:
/**
* @brief Sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSize(size_t len) = 0;
/**
* @brief Empties the string, and sets the internal buffer to be at least large enough to old a specified number of elements.
* Note: This does nothing if len is less than the string's current length.
*
* @param len Minimum number of elements the string buffer must be able to hold.
* @return True if a new buffer was allocated, false otherwise.
*/
virtual bool setBufferSizeNoCopy(size_t len) = 0;
T *str; /** Pointer for the underlying string of elements */
size_t length; /** Number of representable elements in the string */
};

438
Jupiter/String_Type_Imp.h

@ -32,6 +32,12 @@
* String_Type
*/
template<typename T> Jupiter::String_Type<T>::String_Type(Jupiter::String_Type<T> &&source)
{
Jupiter::String_Type<T>::str = source.str;
source.str = nullptr;
}
template<typename T> T &Jupiter::String_Type<T>::get(size_t index) const
{
return Jupiter::String_Type<T>::str[index];
@ -74,7 +80,19 @@ template<typename T> int Jupiter::String_Type<T>::compare(const Jupiter::String_
template<typename T> int Jupiter::String_Type<T>::compare(const std::basic_string<T> &in) const
{
return Jupiter::String_Type<T>::compare(in.c_str());
// rewrite to compare multiple bytes at a time.
size_t index = 0;
while (Jupiter::String_Type<T>::str[index] == in.at(index))
{
index++;
if (index == in.size())
{
if (index == Jupiter::String_Type<T>::length) return 0;
return 1;
}
if (index == Jupiter::String_Type<T>::length) return 0 - in.at(index);
}
return Jupiter::String_Type<T>::str[index] - in.at(index);
}
template<typename T> int Jupiter::String_Type<T>::compare(const T *s2) const
@ -126,7 +144,14 @@ template<typename T> bool Jupiter::String_Type<T>::equals(const Jupiter::String_
template<typename T> bool Jupiter::String_Type<T>::equals(const std::basic_string<T> &in) const
{
if (Jupiter::String_Type<T>::length != in.size()) return false;
return Jupiter::String_Type<T>::equals(in.c_str());
// rewrite to compare multiple bytes at a time.
size_t index = 0;
while (index != Jupiter::String_Type<T>::length)
{
if (Jupiter::String_Type<T>::str[index] != in.at(index)) return false;
index++;
}
return true;
}
template<typename T> bool Jupiter::String_Type<T>::equals(const T *in) const
@ -152,35 +177,54 @@ template<typename T> bool Jupiter::String_Type<T>::equals(std::nullptr_t) const
// equalsi()
template<> bool inline Jupiter::String_Type<char>::equalsi(const Jupiter::String_Type<char> &in) const
{
if (Jupiter::String_Type<char>::length != in.size()) return false;
for (size_t index = 0; index != Jupiter::String_Type<char>::length; index++)
{
if (toupper(Jupiter::String_Type<char>::str[index]) != toupper(in.str[index])) return false;
}
return true;
}
template<> bool inline Jupiter::String_Type<wchar_t>::equalsi(const Jupiter::String_Type<wchar_t> &in) const
{
if (Jupiter::String_Type<wchar_t>::length != in.size()) return false;
for (size_t index = 0; index != Jupiter::String_Type<wchar_t>::length; index++)
{
if (towupper(Jupiter::String_Type<wchar_t>::str[index]) != towupper(in.str[index])) return false;
}
return true;
}
template<typename T> bool Jupiter::String_Type<T>::equalsi(const Jupiter::String_Type<T> &in) const
{
return false; // Concept of "case" not supported for type.
return Jupiter::String_Type<T>::equals(in); // Concept of "case" not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::equalsi(const Jupiter::String_Type<char> &in) const
template<> bool inline Jupiter::String_Type<char>::equalsi(const std::basic_string<char> &in) const
{
if (Jupiter::String_Type<char>::length != in.size()) return false;
for (size_t index = 0; index != Jupiter::String_Type<char>::length; index++)
{
if (toupper(Jupiter::String_Type<char>::str[index]) != toupper(in.str[index])) return false;
if (toupper(Jupiter::String_Type<char>::str[index]) != toupper(in.at(index))) return false;
}
return true;
}
template<> bool inline Jupiter::String_Type<wchar_t>::equalsi(const Jupiter::String_Type<wchar_t> &in) const
template<> bool inline Jupiter::String_Type<wchar_t>::equalsi(const std::basic_string<wchar_t> &in) const
{
if (Jupiter::String_Type<wchar_t>::length != in.size()) return false;
for (size_t index = 0; index != Jupiter::String_Type<wchar_t>::length; index++)
{
if (toupper(Jupiter::String_Type<wchar_t>::str[index]) != toupper(in.str[index])) return false;
if (towupper(Jupiter::String_Type<wchar_t>::str[index]) != towupper(in.at(index))) return false;
}
return true;
}
template<typename T> bool Jupiter::String_Type<T>::equalsi(const std::basic_string<T> &in) const
{
if (Jupiter::String_Type<T>::length != in.size()) return false;
return Jupiter::String_Type<T>::equalsi(in.c_str());
return Jupiter::String_Type<T>::equals(in); // Concept of "case" not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::equalsi(const char *in) const
@ -207,7 +251,7 @@ template<> bool inline Jupiter::String_Type<wchar_t>::equalsi(const wchar_t *in)
template<typename T> bool Jupiter::String_Type<T>::equalsi(const T *in) const
{
return false; // Concept of "case" not supported for type.
return Jupiter::String_Type<T>::equals(in); // Concept of "case" not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::equalsi(const char &in) const
@ -222,7 +266,7 @@ template<> bool inline Jupiter::String_Type<wchar_t>::equalsi(const wchar_t &in)
template<typename T> bool Jupiter::String_Type<T>::equalsi(const T &in) const
{
return false; // Concept of "case" not supported for type.
return Jupiter::String_Type<T>::equals(in); // Concept of "case" not supported for type.
}
template<typename T> bool Jupiter::String_Type<T>::equalsi(const std::nullptr_t) const
@ -232,11 +276,6 @@ template<typename T> bool Jupiter::String_Type<T>::equalsi(const std::nullptr_t)
// match()
template<typename T> bool Jupiter::String_Type<T>::match(const Jupiter::String_Type<T> &format) const
{
return false; // Wildcard matching not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::match(const Jupiter::String_Type<char> &format) const
{
size_t index = 0;
@ -297,9 +336,74 @@ template<> bool inline Jupiter::String_Type<wchar_t>::match(const Jupiter::Strin
return index == Jupiter::String_Type<wchar_t>::length;
}
template<typename T> bool Jupiter::String_Type<T>::match(const Jupiter::String_Type<T> &format) const
{
return false; // Wildcard matching not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::match(const std::basic_string<char> &format) const
{
size_t index = 0;
size_t formatIndex = 0;
while (formatIndex != format.size())
{
if (format.at(formatIndex) == '*')
{
formatIndex++;
while (format.at(formatIndex) == '?')
{
if (Jupiter::String_Type<char>::str[index] == 0) return false;
formatIndex++;
index++;
}
if (format.at(formatIndex) == 0) return true;
if (format.at(formatIndex) == '*') continue;
while (format.at(formatIndex) != Jupiter::String_Type<char>::str[index])
{
if (Jupiter::String_Type<char>::str[index] == 0) return false;
index++;
}
}
else if (format.at(formatIndex) != '?' && format.at(formatIndex) != Jupiter::String_Type<char>::str[index]) return false;
formatIndex++;
index++;
}
return index == Jupiter::String_Type<char>::length;
}
template<> bool inline Jupiter::String_Type<wchar_t>::match(const std::basic_string<wchar_t> &format) const
{
size_t index = 0;
size_t formatIndex = 0;
while (formatIndex != format.size())
{
if (format.at(formatIndex) == '*')
{
formatIndex++;
while (format.at(formatIndex) == '?')
{
if (Jupiter::String_Type<wchar_t>::str[index] == 0) return false;
formatIndex++;
index++;
}
if (format.at(formatIndex) == 0) return true;
if (format.at(formatIndex) == '*') continue;
while (format.at(formatIndex) != Jupiter::String_Type<wchar_t>::str[index])
{
if (Jupiter::String_Type<wchar_t>::str[index] == 0) return false;
index++;
}
}
else if (format.at(formatIndex) != '?' && format.at(formatIndex) != Jupiter::String_Type<wchar_t>::str[index]) return false;
formatIndex++;
index++;
}
return index == Jupiter::String_Type<wchar_t>::length;
}
template<typename T> bool Jupiter::String_Type<T>::match(const std::basic_string<T> &format) const
{
return Jupiter::String_Type<T>::match(format.c_str());
return false; // Wildcard matching not supported for type.
}
template<> inline bool Jupiter::String_Type<char>::match(const char *format) const
@ -362,7 +466,7 @@ template<> inline bool Jupiter::String_Type<wchar_t>::match(const wchar_t *forma
template<typename T> bool Jupiter::String_Type<T>::match(const T *format) const
{
return false; // Type is not comparable to wildcards.
return false; // Wildcard matching not supported for type.
}
// matchi()
@ -433,12 +537,76 @@ template<> bool inline Jupiter::String_Type<wchar_t>::matchi(const Jupiter::Stri
template<typename T> bool Jupiter::String_Type<T>::matchi(const Jupiter::String_Type<T> &format) const
{
return false;
return false; // Wildcard matching not supported for type. Concept of "case" not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::matchi(const std::basic_string<char> &format) const
{
int fUpper;
size_t index = 0;
size_t formatIndex = 0;
while (formatIndex != format.size())
{
if (format.at(formatIndex) == L'*')
{
formatIndex++;
while (format.at(formatIndex) == L'?')
{
if (Jupiter::String_Type<char>::str[index] == 0) return false;
formatIndex++;
index++;
}
if (format.at(formatIndex) == 0) return true;
if (format.at(formatIndex) == '*') continue;
fUpper = toupper(format.at(formatIndex));
while (fUpper != toupper(Jupiter::String_Type<char>::str[index]))
{
if (Jupiter::String_Type<char>::str[index] == 0) return false;
index++;
}
}
else if (format.at(formatIndex) != L'?' && toupper(format.at(formatIndex)) != toupper(Jupiter::String_Type<char>::str[index])) return false;
formatIndex++;
index++;
}
return index == Jupiter::String_Type<char>::length;
}
template<> bool inline Jupiter::String_Type<wchar_t>::matchi(const std::basic_string<wchar_t> &format) const
{
wint_t fUpper;
size_t index = 0;
size_t formatIndex = 0;
while (formatIndex != format.size())
{
if (format.at(formatIndex) == L'*')
{
formatIndex++;
while (format.at(formatIndex) == L'?')
{
if (Jupiter::String_Type<wchar_t>::str[index] == 0) return false;
formatIndex++;
index++;
}
if (format.at(formatIndex) == 0) return true;
if (format.at(formatIndex) == '*') continue;
fUpper = towupper(format.at(formatIndex));
while (fUpper != towupper(Jupiter::String_Type<wchar_t>::str[index]))
{
if (Jupiter::String_Type<wchar_t>::str[index] == 0) return false;
index++;
}
}
else if (format.at(formatIndex) != L'?' && towupper(format.at(formatIndex)) != towupper(Jupiter::String_Type<wchar_t>::str[index])) return false;
formatIndex++;
index++;
}
return index == Jupiter::String_Type<wchar_t>::length;
}
template<typename T> bool Jupiter::String_Type<T>::matchi(const std::basic_string<T> &format) const
{
return Jupiter::String_Type<T>::matchi(format.c_str());
return false; // Wildcard matching not supported for type. Concept of "case" not supported for type.
}
template<> bool inline Jupiter::String_Type<char>::matchi(const char *format) const
@ -505,7 +673,7 @@ template<> bool inline Jupiter::String_Type<wchar_t>::matchi(const wchar_t *form
template<typename T> bool Jupiter::String_Type<T>::matchi(const T *format) const
{
return false; // Type is not comparable to wildcards. Concept of "case" not supported for type.
return false; // Wildcard matching not supported for type. Concept of "case" not supported for type.
}
// wordCount()
@ -582,7 +750,6 @@ template<typename T> size_t Jupiter::String_Type<T>::println(FILE *out) const
{
size_t r = Jupiter::String_Type<T>::print(out);
if (r != Jupiter::String_Type<T>::length) return r;
// This may change to simply '\n' at a later date.
if (fputs("\r\n", out) != EOF) r += 2;
return r;
}
@ -692,4 +859,231 @@ template<typename T> bool Jupiter::String_Type<T>::remove(const T &value)
return false;
}
template<typename T> size_t Jupiter::String_Type<T>::set(const String_Type<T> &in)
{
this->setBufferSizeNoCopy(in.size());
for (Jupiter::String_Type<T>::length = 0; Jupiter::String_Type<T>::length < in.size() != 0; Jupiter::String_Type<T>::length++)
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = in.get(Jupiter::String_Type<T>::length);
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::String_Type<T>::set(const std::basic_string<T> &in)
{
this->setBufferSizeNoCopy(in.size());
for (Jupiter::String_Type<T>::length = 0; Jupiter::String_Type<T>::length < in.size(); Jupiter::String_Type<T>::length++)
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = in.at(Jupiter::String_Type<T>::length);
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::String_Type<T>::set(const T *in)
{
size_t nLen = Jupiter::strlen<T>(in);
this->setBufferSizeNoCopy(nLen);
for (Jupiter::String_Type<T>::length = 0; *in != 0; Jupiter::String_Type<T>::length++, in++) Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = *in;
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::String_Type<T>::set(const T in)
{
this->setBufferSizeNoCopy(1);
*Jupiter::String_Type<T>::str = in;
return Jupiter::String_Type<T>::length = 1;
}
template<typename T> size_t Jupiter::String_Type<T>::concat(const String_Type<T> &in)
{
size_t nSize = Jupiter::String_Type<T>::length + in.size();
const T *inData = in.ptr();
this->setBufferSize(nSize);
while (Jupiter::String_Type<T>::length != nSize)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = *inData;
Jupiter::String_Type<T>::length++;
inData++;
}
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::String_Type<T>::concat(const std::basic_string<T> &in)
{
size_t nSize = Jupiter::String_Type<T>::length + in.size();
const T *inData = in.data();
this->setBufferSize(nSize);
while (Jupiter::String_Type<T>::length != nSize)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = *inData;
Jupiter::String_Type<T>::length++;
inData++;
}
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::String_Type<T>::concat(const T *in)
{
size_t nSize = Jupiter::String_Type<T>::length + Jupiter::strlen<T>(in);
this->setBufferSize(nSize);
while (*in != 0)
{
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = *in;
Jupiter::String_Type<T>::length++;
in++;
}
return Jupiter::String_Type<T>::length;
}
template<typename T> size_t Jupiter::String_Type<T>::concat(const T c)
{
this->setBufferSize(Jupiter::String_Type<T>::length + 1);
Jupiter::String_Type<T>::str[Jupiter::String_Type<T>::length] = c;
return ++Jupiter::String_Type<T>::length;
}
/**
* IMPLEMENTATION:
* String helper templates
*/
// substring
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::substring(const Jupiter::String_Type<T> &in, size_t pos)
{
if (pos >= in.size()) return R<T>();
R<T> r = R<T>(in.size() - pos);
for (r.length = 0; pos + r.length != in.size(); r.length++) r.str[r.length] = in.get(pos + r.length);
return r;
}
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::substring(const Jupiter::String_Type<T> &in, size_t pos, size_t len)
{
if (pos + len >= in.size()) return R<T>::substring(in, pos);
R<T> r = R<T>(len);
for (r.length = 0; r.length != len; r.length++) r.str[r.length] = in.get(pos + r.length);
return r;
}
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::substring(const T *in, size_t pos)
{
size_t strLen = Jupiter::strlen<T>(in);
if (pos >= strLen) return R<T>();
R<T> r = R<T>(strLen - pos);
in += pos;
for (r.length = 0; *in != 0; r.length++, in++) r.str[r.length] = *in;
return r;
}
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::substring(const T *in, size_t pos, size_t len)
{
R<T> r = R<T>(len);
in += pos;
for (r.length = 0; r.length != len; r.length++, in++) r.str[r.length] = *in;
return r;
}
// getWord
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::getWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace)
{
unsigned int x = 0;
unsigned int y = 1;
for (unsigned int i = 0; i < pos || y == 1; x++)
{
if (x == in.size()) return R<T>();
if (Jupiter::strpbrk<T>(whitespace, in.get(x)) != nullptr)
{
if (y != 1)
{
y = 1;
i++;
}
}
else
{
if (i >= pos) break;
y = 0;
}
}
for (y = x; y != in.size() && Jupiter::strpbrk<T>(whitespace, in.get(y)) == nullptr; y++);
return R<T>::substring(in, x, y - x);
}
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::getWord(const T *in, size_t pos, const T *whitespace)
{
unsigned int x = 0;
unsigned int y = 1;
for (unsigned int i = 0; i < pos || y == 1; x++)
{
if (in[x] == 0) return R<T>();
if (Jupiter::strpbrk<T>(whitespace, in[x]) != nullptr)
{
if (y != 1)
{
y = 1;
i++;
}
}
else
{
if (i >= pos) break;
y = 0;
}
}
for (y = x; in[y] != 0 && Jupiter::strpbrk<T>(whitespace, in[y]) == nullptr; y++);
return R<T>::substring(in, x, y - x);
}
// gotoWord
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::gotoWord(const Jupiter::String_Type<T> &in, size_t pos, const T *whitespace)
{
unsigned int x = 0;
bool y = true;
for (unsigned int i = 0; i < pos || y == true; x++)
{
if (x == in.size()) return R<T>();
if (Jupiter::strpbrk<T>(whitespace, in.get(x)) != nullptr)
{
if (y != true)
{
y = true;
i++;
}
}
else
{
if (i >= pos) break;
y = false;
}
}
return R<T>::substring(in, x);
}
template<typename T> template<template<typename> class R> R<T> Jupiter::String_Type<T>::gotoWord(const T *in, size_t pos, const T *whitespace)
{
unsigned int x = 0;
bool y = true;
for (unsigned int i = 0; i < pos || y == true; x++)
{
if (in[x] == 0) return R<T>();
if (Jupiter::strpbrk<T>(whitespace, in[x]) != nullptr)
{
if (y != true)
{
y = true;
i++;
}
}
else
{
if (i >= pos) break;
y = false;
}
}
return R<T>::substring(in, x);
}
namespace Jupiter
{
static struct String_Constructor_Base {} stringConstructorBase;
}
#endif // _STRING_TYPE_IMP_H_HEADER

BIN
Release/Jupiter.lib

Binary file not shown.

1
Tester/Tester.vcxproj

@ -73,6 +73,7 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<TargetMachine>MachineX86</TargetMachine>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

Loading…
Cancel
Save