Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 32 additions & 20 deletions src/libutil/strutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// https://github.com/AcademySoftwareFoundation/OpenImageIO


#include <algorithm>
#include <cmath>
#include <codecvt>
#include <cstdarg>
Expand All @@ -21,9 +22,6 @@
# include <xlocale.h>
#endif

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/find.hpp>

#include <OpenImageIO/dassert.h>
#include <OpenImageIO/platform.h>
#include <OpenImageIO/string_view.h>
Expand Down Expand Up @@ -527,7 +525,6 @@ Strutil::ends_with(string_view a, string_view b)
if (asize < bsize) // a can't start with b if a is smaller
return false;
return strncmp(a.data() + asize - bsize, b.data(), bsize) == 0;
// return boost::algorithm::ends_with(a, b);
}


Expand All @@ -539,27 +536,20 @@ Strutil::iends_with(string_view a, string_view b)
if (asize < bsize) // a can't start with b if a is smaller
return false;
return strncasecmp(a.data() + asize - bsize, b.data(), bsize) == 0;
// return boost::algorithm::iends_with(a, b, std::locale::classic());
}


bool
Strutil::contains(string_view a, string_view b)
{
return find(a, b) != string_view::npos;
// We used to use the boost contains, but it seems to be about 2x more
// expensive than (find() != npos).
// return boost::algorithm::contains(a, b);
}


bool
Strutil::icontains(string_view a, string_view b)
{
return ifind(a, b) != string_view::npos;
// We used to use the boost icontains, but it seems to be about 2x more
// expensive than (ifind() != npos).
// return boost::algorithm::icontains(a, b, std::locale::classic());
}


Expand Down Expand Up @@ -600,8 +590,19 @@ Strutil::ifind(string_view a, string_view b)
return string_view::npos;
if (b.empty())
return 0;
auto f = boost::algorithm::ifind_first(a, b, std::locale::classic());
return f.empty() ? string_view::npos : f.begin() - a.data();

if (b.size() <= a.size()) {
const char* start = a.data();
const char* last = a.data() + a.size() - b.size();
while (start <= last) {
if (Strutil::strncasecmp(start, b.data(), b.size()) == 0) {
return size_t(start - a.data());
}
start++;
}
}

return string_view::npos;
}


Expand All @@ -612,22 +613,36 @@ Strutil::irfind(string_view a, string_view b)
return string_view::npos;
if (b.empty())
return a.size();
auto f = boost::algorithm::ifind_last(a, b, std::locale::classic());
return f.empty() ? string_view::npos : f.begin() - a.data();

if (b.size() <= a.size()) {
const char* start = a.data() + (a.size() - b.size());
while (start >= a.data()) {
if (Strutil::strncasecmp(start, b.data(), b.size()) == 0) {
return size_t(start - a.data());
}
start--;
}
}

return string_view::npos;
}


void
Strutil::to_lower(std::string& a)
{
boost::algorithm::to_lower(a, std::locale::classic());
const std::locale& loc = std::locale::classic();
std::transform(a.cbegin(), a.cend(), a.begin(),
[&loc](char c) { return std::tolower(c, loc); });
}


void
Strutil::to_upper(std::string& a)
{
boost::algorithm::to_upper(a, std::locale::classic());
const std::locale& loc = std::locale::classic();
std::transform(a.cbegin(), a.cend(), a.begin(),
[&loc](char c) { return std::toupper(c, loc); });
}


Expand All @@ -636,16 +651,13 @@ bool
Strutil::StringIEqual::operator()(const char* a, const char* b) const noexcept
{
return Strutil::strcasecmp(a, b) == 0;
// return boost::algorithm::iequals(a, b, std::locale::classic());
}


bool
Strutil::StringILess::operator()(const char* a, const char* b) const noexcept
{
return Strutil::strcasecmp(a, b) < 0;
// return boost::algorithm::ilexicographical_compare(a, b,
// std::locale::classic());
}


Expand Down
4 changes: 4 additions & 0 deletions src/libutil/strutil_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -464,12 +464,16 @@ test_comparisons()
OIIO_CHECK_EQUAL(Strutil::ifind("abcdeabcde", "BC"), 1);
OIIO_CHECK_EQUAL(Strutil::ifind("abcdeabcde", "ac"), std::string::npos);
OIIO_CHECK_EQUAL(Strutil::ifind("abcdeabcde", ""), 0);
OIIO_CHECK_EQUAL(Strutil::ifind("Xabcdeabcde", "x"), 0);
OIIO_CHECK_EQUAL(Strutil::ifind("abcdeabcdeX", "x"), 10);
OIIO_CHECK_EQUAL(Strutil::ifind("", "abc"), std::string::npos);
OIIO_CHECK_EQUAL(Strutil::ifind("", ""), std::string::npos);
OIIO_CHECK_EQUAL(Strutil::irfind("abcdeabcde", "bc"), 6);
OIIO_CHECK_EQUAL(Strutil::irfind("abcdeabcde", "BC"), 6);
OIIO_CHECK_EQUAL(Strutil::irfind("abcdeabcde", "ac"), std::string::npos);
OIIO_CHECK_EQUAL(Strutil::irfind("abcdeabcde", ""), 10);
OIIO_CHECK_EQUAL(Strutil::irfind("Xabcdeabcde", "x"), 0);
OIIO_CHECK_EQUAL(Strutil::irfind("abcdeabcdeX", "x"), 10);
OIIO_CHECK_EQUAL(Strutil::irfind("", "abc"), std::string::npos);
OIIO_CHECK_EQUAL(Strutil::irfind("", ""), std::string::npos);

Expand Down