Creating JUCE String just to use String comparison functions bad idea?


#1

Here are some of my own string char functions

bool CHAR::isAnyOf(const char& c, String list)
{
	for (auto p = list.getCharPointer(); !p.isEmpty(); ++p)	if (c == *p) return true;
	return false;
}
bool CHAR::isUpper(const char& c)
{
	return c >= 'A' && c <= 'Z';
}
bool CHAR::isLower(const char& c)
{
	return c >= 'a' && c <= 'z';
}

bool STR::isInt(const String& s)
{
	if (!s.length()) return false;
	auto p = s.getCharPointer();
	if (*p == '-' || *p == '+') ++p;
	while (!p.isEmpty() && CHAR::isDigit(*p)) ++p;
	return p.isEmpty();
}

I would like to add functionality to do case insensitive comparisons, especially for “isAnyOf”, but being a noob I don’t quite have a grasp of best practices. I know you can run into trouble if you want to see if a character is capitol (return c >= 'A' && c <= 'Z';) and you get a non-ascii character. So I had an idea of creating String objects for everything and then using various String functions, but I figured that would be inefficient… I wonder why there’s aren’t static string functions so I can just do something like String::hasAnyOf(input_string, tokens, case-insensitive).

What’s the best way to do all this with JUCE? I think my main problem here is I need functions to compare char with char, string with string, string with char, etc, and String class doesn’t have char comparison functions, so I’d have to convert char to String before comparing.


#2

I think CharacterFunctions probably already includes versions of most of those functions.

Re: whether it’s OK to create a String just for comparison: Sure, if code conciseness is more important than performance at that point, go ahead. But if performance matters, you might want to use a faster, more verbose method.

Also note that you can wrap a raw char pointer in a class such as StringRef or CharPointer_UTF8 and use that to provide a bunch of string-like methods without any overhead at all.


#3

thanks!

since there’s no String::containsCharIgnoreCase, is this the best use of JUCE classes? I want to avoid unecessary object creation if possible, efficiency is needed. Also I’m confused as to why CharPointer_UTF8 is used in String and CharacterFunctions… should I not be using juce_wchar? Also, I’d use StringRef but being a noob not sure how to avoid using brackets i.e. myStringRef[i]

bool CHAR::isAnyOf_i(const juce_wchar& c, const String& list)
{
	for (auto p = list.getCharPointer(); !p.isEmpty(); ++p)
		if (CharacterFunctions::compareIgnoreCase(c, (juce_wchar)*p) == 0) 
			return true;
	return false;
}

Edit: Oh StringRef [] operator returns juce_wchar, that’s a helpful clue.
Edit: Hmm, can’t convert juce_wchar to CharPointer_UTF8

As suggested by another member, I should be using http://site.icu-project.org/ to do comparing, sorting, upper/lower case stuff so this all might be pointless.

Edit: Oh I could do this for now:

bool CHAR::isAnyOf_i(const juce_wchar& c, const String& list)
{
	return list.containsIgnoreCase(toS(c));
}