#pragma once #if __has_include() #define JVALIDATE_HAS_ICU #include #include #endif namespace jvalidate::detail { inline size_t length(std::string_view arg) { #ifdef JVALIDATE_HAS_ICU icu::UnicodeString ucs = icu::UnicodeString::fromUTF8(icu::StringPiece(arg)); return ucs.countChar32(); #else return arg.size(); #endif } inline std::string regex_escape(std::string_view arg) { #ifdef JVALIDATE_HAS_ICU icu::UnicodeString const ucs = icu::UnicodeString::fromUTF8(icu::StringPiece(arg)); if (ucs.countChar32() == arg.size()) { return std::string(arg); } UErrorCode status = U_ZERO_ERROR; std::unique_ptr iter( icu::BreakIterator::createCharacterInstance(NULL, status)); if (U_FAILURE(status)) { return std::string(arg); } icu::UnicodeString rval; iter->setText(ucs); int32_t start = iter->first(); int32_t end = iter->next(); while (end != icu::BreakIterator::DONE) { if (std::strchr("?*+", ucs.charAt(end))) { rval.append('('); rval.append(ucs, start, end - 1); rval.append(')'); rval.append(ucs.char32At(end)); end = iter->next(); } else { rval.append(ucs, start, end - 1); } start = end; end = iter->next(); } std::string out; return rval.toUTF8String(out); #else return std::string(arg); #endif } }