Commit 766d5a4d by Maarten L. Hekkelman

case insensitve match, when defined by dictionary

parent 1f24937e
...@@ -365,20 +365,36 @@ namespace detail ...@@ -365,20 +365,36 @@ namespace detail
return result; return result;
} }
template<typename T, std::enable_if_t<std::is_same_v<std::remove_cv_t<T>, std::string>, int> = 0> template<typename T, std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
int compare(const T& value) const int compare(const T& rhs) const
{
return -rhs.compare(c_str());
}
template<typename T, std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
int icompare(const T& rhs) const
{ {
return cif::icompare(c_str(), value.c_str()); return cif::icompare(c_str(), rhs);
} }
// int compare(const char* rhs) const
// {
// return std::strcmp(c_str(), rhs);
// }
// int icompare(const char* rhs) const
// {
// return cif::icompare(c_str(), rhs);
// }
int compare(const ItemReference& rhs) const int compare(const ItemReference& rhs) const
{ {
return std::strcmp(c_str(), rhs.c_str()); return std::strcmp(c_str(), rhs.c_str());
} }
int icompare(const std::string& value) const int icompare(const ItemReference& rhs) const
{ {
return cif::icompare(c_str(), value.c_str()); return cif::icompare(c_str(), rhs.c_str());
} }
// empty means either null or unknown // empty means either null or unknown
...@@ -818,12 +834,13 @@ struct KeyCompareConditionImpl : public ConditionImpl ...@@ -818,12 +834,13 @@ struct KeyCompareConditionImpl : public ConditionImpl
virtual bool test(const Category& c, const Row& r) const virtual bool test(const Category& c, const Row& r) const
{ {
return mComp(c, r); return mComp(c, r, mCaseInsensitive);
} }
std::string mItemTag; std::string mItemTag;
size_t mItemIx; size_t mItemIx;
std::function<bool(const Category&, const Row&)> mComp; bool mCaseInsensitive = false;
std::function<bool(const Category&, const Row&, bool)> mComp;
}; };
struct KeyMatchesConditionImpl : public ConditionImpl struct KeyMatchesConditionImpl : public ConditionImpl
...@@ -998,15 +1015,21 @@ struct Key ...@@ -998,15 +1015,21 @@ struct Key
template<typename T> template<typename T>
Condition operator==(const Key& key, const T& v) Condition operator==(const Key& key, const T& v)
{ {
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r) return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return r[tag].compare(v) > 0; })); { return r[tag].compare(v) == 0; }));
} }
inline Condition operator==(const Key& key, const char* v) inline Condition operator==(const Key& key, const char* v)
{ {
std::string value(v ? v : ""); std::string value(v ? v : "");
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, value](const Category& c, const Row& r) return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, value](const Category& c, const Row& r, bool icase)
{ return r[tag].compare(value) == 0; })); { return (icase ? r[tag].icompare(value) : r[tag].compare(value)) == 0; }));
}
inline Condition operator==(const Key& key, const std::string& v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].icompare(v) : r[tag].compare(v)) == 0; }));
} }
inline Condition operator==(const Key& key, const detail::ItemReference& v) inline Condition operator==(const Key& key, const detail::ItemReference& v)
...@@ -1014,8 +1037,8 @@ inline Condition operator==(const Key& key, const detail::ItemReference& v) ...@@ -1014,8 +1037,8 @@ inline Condition operator==(const Key& key, const detail::ItemReference& v)
if (v.empty()) if (v.empty())
return Condition(new detail::KeyIsEmptyConditionImpl(key.mItemTag)); return Condition(new detail::KeyIsEmptyConditionImpl(key.mItemTag));
else else
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r) return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return r[tag].compare(v); })); { return icase ? r[tag].icompare(v) : r[tag].compare(v); }));
} }
inline Condition operator==(const Key& key, const Empty&) inline Condition operator==(const Key& key, const Empty&)
...@@ -1038,7 +1061,7 @@ inline Condition operator!=(const Key& key, const char* v) ...@@ -1038,7 +1061,7 @@ inline Condition operator!=(const Key& key, const char* v)
template<typename T> template<typename T>
Condition operator>(const Key& key, const T& v) Condition operator>(const Key& key, const T& v)
{ {
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r) return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return r[tag].compare(v) > 0; })); { return r[tag].compare(v) > 0; }));
} }
...@@ -1063,6 +1086,62 @@ Condition operator<=(const Key& key, const T& v) ...@@ -1063,6 +1086,62 @@ Condition operator<=(const Key& key, const T& v)
{ return r[tag].compare(v) <= 0; })); { return r[tag].compare(v) <= 0; }));
} }
template<typename T>
Condition operator>(const Key& key, const char* v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].template icompare<std::string>(v) : r[tag].template compare<std::string>(v)) > 0; }));
}
template<typename T>
Condition operator>=(const Key& key, const char* v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].template icompare<std::string>(v) : r[tag].template compare<std::string>(v)) >= 0; }));
}
template<typename T>
Condition operator<(const Key& key, const char* v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].template icompare<std::string>(v) : r[tag].template compare<std::string>(v)) < 0; }));
}
template<typename T>
Condition operator<=(const Key& key, const char* v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].template icompare<std::string>(v) : r[tag].template compare<std::string>(v)) <= 0; }));
}
template<typename T>
Condition operator>(const Key& key, const std::string& v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].icompare(v) : r[tag].compare(v)) > 0; }));
}
template<typename T>
Condition operator>=(const Key& key, const std::string& v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].icompare(v) : r[tag].compare(v)) >= 0; }));
}
template<typename T>
Condition operator<(const Key& key, const std::string& v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].icompare(v) : r[tag].compare(v)) < 0; }));
}
template<typename T>
Condition operator<=(const Key& key, const std::string& v)
{
return Condition(new detail::KeyCompareConditionImpl(key.mItemTag, [tag = key.mItemTag, v](const Category& c, const Row& r, bool icase)
{ return (icase ? r[tag].icompare(v) : r[tag].compare(v)) <= 0; }));
}
template<> template<>
inline inline
Condition operator==(const Key& key, const std::regex& rx) Condition operator==(const Key& key, const std::regex& rx)
...@@ -1670,16 +1749,6 @@ inline void swap(cif::detail::ItemReference& a, cif::detail::ItemReference& b) ...@@ -1670,16 +1749,6 @@ inline void swap(cif::detail::ItemReference& a, cif::detail::ItemReference& b)
a.swap(b); a.swap(b);
} }
namespace detail
{
inline void KeyCompareConditionImpl::prepare(const Category& c)
{
mItemIx = c.getColumnIndex(mItemTag);
}
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
template<typename RowType> template<typename RowType>
......
...@@ -50,9 +50,9 @@ class ValidationError : public std::exception ...@@ -50,9 +50,9 @@ class ValidationError : public std::exception
// -------------------------------------------------------------------- // --------------------------------------------------------------------
enum DDL_PrimitiveType enum class DDL_PrimitiveType
{ {
ptChar, ptUChar, ptNumb Char, UChar, Numb
}; };
DDL_PrimitiveType mapToPrimitiveType(const std::string& s); DDL_PrimitiveType mapToPrimitiveType(const std::string& s);
......
...@@ -569,14 +569,21 @@ void Datablock::write(std::ostream& os, const std::vector<std::string>& order) ...@@ -569,14 +569,21 @@ void Datablock::write(std::ostream& os, const std::vector<std::string>& order)
namespace detail namespace detail
{ {
// void ConditionImpl::prepare(const Category& c) void KeyCompareConditionImpl::prepare(const Category& c)
// { {
// auto cv = c.getCatValidator(); mItemIx = c.getColumnIndex(mItemTag);
// if (cv)
// { auto cv = c.getCatValidator();
// auto iv = cv->getValidatorForItem(mItemTag); if (cv)
// } {
// } auto iv = cv->getValidatorForItem(mItemTag);
if (iv != nullptr and iv->mType != nullptr)
{
auto type = iv->mType;
mCaseInsensitive = type->mPrimitiveType == DDL_PrimitiveType::UChar;
}
}
}
void KeyIsEmptyConditionImpl::prepare(const Category& c) void KeyIsEmptyConditionImpl::prepare(const Category& c)
{ {
......
...@@ -53,11 +53,11 @@ DDL_PrimitiveType mapToPrimitiveType(const std::string& s) ...@@ -53,11 +53,11 @@ DDL_PrimitiveType mapToPrimitiveType(const std::string& s)
{ {
DDL_PrimitiveType result; DDL_PrimitiveType result;
if (iequals(s, "char")) if (iequals(s, "char"))
result = ptChar; result = DDL_PrimitiveType::Char;
else if (iequals(s, "uchar")) else if (iequals(s, "uchar"))
result = ptUChar; result = DDL_PrimitiveType::UChar;
else if (iequals(s, "numb")) else if (iequals(s, "numb"))
result = ptNumb; result = DDL_PrimitiveType::Numb;
else else
throw ValidationError("Not a known primitive type"); throw ValidationError("Not a known primitive type");
return result; return result;
...@@ -79,7 +79,7 @@ int ValidateType::compare(const char* a, const char* b) const ...@@ -79,7 +79,7 @@ int ValidateType::compare(const char* a, const char* b) const
{ {
switch (mPrimitiveType) switch (mPrimitiveType)
{ {
case ptNumb: case DDL_PrimitiveType::Numb:
{ {
double da = strtod(a, nullptr); double da = strtod(a, nullptr);
double db = strtod(b, nullptr); double db = strtod(b, nullptr);
...@@ -95,8 +95,8 @@ int ValidateType::compare(const char* a, const char* b) const ...@@ -95,8 +95,8 @@ int ValidateType::compare(const char* a, const char* b) const
break; break;
} }
case ptUChar: case DDL_PrimitiveType::UChar:
case ptChar: case DDL_PrimitiveType::Char:
{ {
// CIF is guaranteed to have ascii only, therefore this primitive code will do // CIF is guaranteed to have ascii only, therefore this primitive code will do
// also, we're collapsing spaces // also, we're collapsing spaces
...@@ -119,7 +119,7 @@ int ValidateType::compare(const char* a, const char* b) const ...@@ -119,7 +119,7 @@ int ValidateType::compare(const char* a, const char* b) const
char ca = *ai; char ca = *ai;
char cb = *bi; char cb = *bi;
if (mPrimitiveType == ptUChar) if (mPrimitiveType == DDL_PrimitiveType::UChar)
{ {
ca = toupper(ca); ca = toupper(ca);
cb = toupper(cb); cb = toupper(cb);
...@@ -238,7 +238,7 @@ const ValidateType* Validator::getValidatorForType(std::string typeCode) const ...@@ -238,7 +238,7 @@ const ValidateType* Validator::getValidatorForType(std::string typeCode) const
{ {
const ValidateType* result = nullptr; const ValidateType* result = nullptr;
auto i = mTypeValidators.find(ValidateType{ typeCode, ptChar, std::regex() }); auto i = mTypeValidators.find(ValidateType{ typeCode, DDL_PrimitiveType::Char, std::regex() });
if (i != mTypeValidators.end()) if (i != mTypeValidators.end())
result = &*i; result = &*i;
else if (VERBOSE > 4) else if (VERBOSE > 4)
......
...@@ -318,7 +318,7 @@ data_test_dict.dic ...@@ -318,7 +318,7 @@ data_test_dict.dic
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*' '[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
; code item types/single words ... ; code item types/single words ...
; ;
ucode char ucode uchar
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*' '[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
; code item types/single words, case insensitive ; code item types/single words, case insensitive
; ;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment