Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libcifpp
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open
libcifpp
Commits
766d5a4d
Commit
766d5a4d
authored
Oct 05, 2020
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
case insensitve match, when defined by dictionary
parent
1f24937e
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
119 additions
and
43 deletions
+119
-43
include/cif++/Cif++.hpp
+93
-24
include/cif++/CifValidator.hpp
+2
-2
src/Cif++.cpp
+15
-8
src/CifValidator.cpp
+8
-8
test/unit-test.cpp
+1
-1
No files found.
include/cif++/Cif++.hpp
View file @
766d5a4d
...
@@ -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
>
...
...
include/cif++/CifValidator.hpp
View file @
766d5a4d
...
@@ -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
,
pt
Numb
Char
,
UChar
,
Numb
};
};
DDL_PrimitiveType
mapToPrimitiveType
(
const
std
::
string
&
s
);
DDL_PrimitiveType
mapToPrimitiveType
(
const
std
::
string
&
s
);
...
...
src/Cif++.cpp
View file @
766d5a4d
...
@@ -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
)
{
{
...
...
src/CifValidator.cpp
View file @
766d5a4d
...
@@ -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
=
pt
Char
;
result
=
DDL_PrimitiveType
::
Char
;
else
if
(
iequals
(
s
,
"uchar"
))
else
if
(
iequals
(
s
,
"uchar"
))
result
=
pt
UChar
;
result
=
DDL_PrimitiveType
::
UChar
;
else
if
(
iequals
(
s
,
"numb"
))
else
if
(
iequals
(
s
,
"numb"
))
result
=
pt
Numb
;
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
pt
Numb
:
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
pt
UChar
:
case
DDL_PrimitiveType
:
:
UChar
:
case
pt
Char
:
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
==
pt
UChar
)
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
,
pt
Char
,
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
)
...
...
test/unit-test.cpp
View file @
766d5a4d
...
@@ -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
u
char
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
'[][_,.;:"&<>()/\{}'`~!@#$%A-Za-z0-9*|+-]*'
; code item types/single words, case insensitive
; code item types/single words, case insensitive
;
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment