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
6f93fa37
Commit
6f93fa37
authored
Nov 04, 2020
by
Maarten L. Hekkelman
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
new conditional iterator type
parent
598f953c
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
425 additions
and
183 deletions
+425
-183
include/cif++/Cif++.hpp
+221
-80
include/cif++/Structure.hpp
+47
-50
src/Structure.cpp
+62
-51
test/unit-test.cpp
+95
-2
No files found.
include/cif++/Cif++.hpp
View file @
6f93fa37
...
...
@@ -574,7 +574,7 @@ namespace detail
}
template
<
typename
...
Ts
>
auto
tie
(
Ts
&
...
v
)
->
detail
::
tieWrap
<
Ts
&
...
>
auto
tie
(
Ts
&
...
v
)
{
return
detail
::
tieWrap
<
Ts
&
...
>
(
std
::
forward
<
Ts
&>
(
v
)...);
}
...
...
@@ -682,16 +682,21 @@ class Row
return
detail
::
ItemReference
(
itemTag
.
c_str
(),
column
,
*
this
);
}
template
<
typename
...
Ts
,
size_t
N
>
std
::
tuple
<
Ts
...
>
get
(
char
const
*
const
(
&
columns
)[
N
])
{
static_assert
(
sizeof
...(
Ts
)
==
N
,
"Number of columns should be equal to number of types to return"
);
std
::
array
<
size_t
,
N
>
cix
;
for
(
size_t
i
=
0
;
i
<
N
;
++
i
)
cix
[
i
]
=
ColumnForItemTag
(
columns
[
i
]);
return
detail
::
getRowResult
<
Ts
...
>
(
*
this
,
std
::
move
(
cix
));
}
template
<
typename
...
C
>
auto
get
(
C
...
columns
)
const
->
detail
::
getRowResult
<
C
...
>
auto
get
(
C
...
columns
)
const
{
std
::
array
<
size_t
,
sizeof
...(
C
)
>
cix
;
auto
c
=
cix
.
begin
();
for
(
auto
col
:
{
columns
...
})
*
c
++
=
ColumnForItemTag
(
col
);
return
detail
::
getRowResult
<
C
...
>
(
*
this
,
std
::
move
(
cix
));
return
detail
::
getRowResult
<
C
...
>
(
*
this
,
{
ColumnForItemTag
(
columns
)...
});
}
void
assign
(
const
std
::
vector
<
Item
>&
values
);
...
...
@@ -751,9 +756,9 @@ struct AllConditionImpl : public ConditionImpl
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"*"
;
}
};
struct
o
rConditionImpl
;
struct
a
ndConditionImpl
;
struct
n
otConditionImpl
;
struct
O
rConditionImpl
;
struct
A
ndConditionImpl
;
struct
N
otConditionImpl
;
}
...
...
@@ -805,9 +810,9 @@ class Condition
friend
Condition
operator
||
(
Condition
&&
a
,
Condition
&&
b
);
friend
Condition
operator
&&
(
Condition
&&
a
,
Condition
&&
b
);
friend
struct
detail
::
o
rConditionImpl
;
friend
struct
detail
::
a
ndConditionImpl
;
friend
struct
detail
::
n
otConditionImpl
;
friend
struct
detail
::
O
rConditionImpl
;
friend
struct
detail
::
A
ndConditionImpl
;
friend
struct
detail
::
N
otConditionImpl
;
void
swap
(
Condition
&
rhs
)
{
...
...
@@ -901,11 +906,11 @@ struct KeyMatchesConditionImpl : public ConditionImpl
};
template
<
typename
T
>
struct
a
nyIsConditionImpl
:
public
ConditionImpl
struct
A
nyIsConditionImpl
:
public
ConditionImpl
{
typedef
T
valueType
;
a
nyIsConditionImpl
(
const
valueType
&
value
)
A
nyIsConditionImpl
(
const
valueType
&
value
)
:
mValue
(
value
)
{}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
;
...
...
@@ -917,9 +922,9 @@ struct anyIsConditionImpl : public ConditionImpl
valueType
mValue
;
};
struct
a
nyMatchesConditionImpl
:
public
ConditionImpl
struct
A
nyMatchesConditionImpl
:
public
ConditionImpl
{
a
nyMatchesConditionImpl
(
const
std
::
regex
&
rx
)
A
nyMatchesConditionImpl
(
const
std
::
regex
&
rx
)
:
mRx
(
rx
)
{}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
;
...
...
@@ -931,31 +936,16 @@ struct anyMatchesConditionImpl : public ConditionImpl
std
::
regex
mRx
;
};
struct
allConditionImpl
:
public
ConditionImpl
{
allConditionImpl
()
{}
virtual
bool
test
(
const
Category
&
c
,
const
Row
&
r
)
const
{
return
true
;
}
virtual
void
str
(
std
::
ostream
&
os
)
const
{
os
<<
"*"
;
}
};
struct
andConditionImpl
:
public
ConditionImpl
struct
AndConditionImpl
:
public
ConditionImpl
{
a
ndConditionImpl
(
Condition
&&
a
,
Condition
&&
b
)
A
ndConditionImpl
(
Condition
&&
a
,
Condition
&&
b
)
:
mA
(
nullptr
),
mB
(
nullptr
)
{
std
::
swap
(
mA
,
a
.
mImpl
);
std
::
swap
(
mB
,
b
.
mImpl
);
}
~
a
ndConditionImpl
()
~
A
ndConditionImpl
()
{
delete
mA
;
delete
mB
;
...
...
@@ -985,16 +975,16 @@ struct andConditionImpl : public ConditionImpl
ConditionImpl
*
mB
;
};
struct
o
rConditionImpl
:
public
ConditionImpl
struct
O
rConditionImpl
:
public
ConditionImpl
{
o
rConditionImpl
(
Condition
&&
a
,
Condition
&&
b
)
O
rConditionImpl
(
Condition
&&
a
,
Condition
&&
b
)
:
mA
(
nullptr
),
mB
(
nullptr
)
{
std
::
swap
(
mA
,
a
.
mImpl
);
std
::
swap
(
mB
,
b
.
mImpl
);
}
~
o
rConditionImpl
()
~
O
rConditionImpl
()
{
delete
mA
;
delete
mB
;
...
...
@@ -1024,15 +1014,15 @@ struct orConditionImpl : public ConditionImpl
ConditionImpl
*
mB
;
};
struct
n
otConditionImpl
:
public
ConditionImpl
struct
N
otConditionImpl
:
public
ConditionImpl
{
n
otConditionImpl
(
Condition
&&
a
)
N
otConditionImpl
(
Condition
&&
a
)
:
mA
(
nullptr
)
{
std
::
swap
(
mA
,
a
.
mImpl
);
}
~
n
otConditionImpl
()
~
N
otConditionImpl
()
{
delete
mA
;
}
...
...
@@ -1062,7 +1052,7 @@ struct notConditionImpl : public ConditionImpl
inline
Condition
operator
&&
(
Condition
&&
a
,
Condition
&&
b
)
{
if
(
a
.
mImpl
and
b
.
mImpl
)
return
Condition
(
new
detail
::
a
ndConditionImpl
(
std
::
move
(
a
),
std
::
move
(
b
)));
return
Condition
(
new
detail
::
A
ndConditionImpl
(
std
::
move
(
a
),
std
::
move
(
b
)));
if
(
a
.
mImpl
)
return
Condition
(
std
::
move
(
a
));
return
Condition
(
std
::
move
(
b
));
...
...
@@ -1071,7 +1061,7 @@ inline Condition operator&&(Condition&& a, Condition&& b)
inline
Condition
operator
||
(
Condition
&&
a
,
Condition
&&
b
)
{
if
(
a
.
mImpl
and
b
.
mImpl
)
return
Condition
(
new
detail
::
o
rConditionImpl
(
std
::
move
(
a
),
std
::
move
(
b
)));
return
Condition
(
new
detail
::
O
rConditionImpl
(
std
::
move
(
a
),
std
::
move
(
b
)));
if
(
a
.
mImpl
)
return
Condition
(
std
::
move
(
a
));
return
Condition
(
std
::
move
(
b
));
...
...
@@ -1117,13 +1107,13 @@ inline Condition operator==(const Key& key, const Empty&)
template
<
typename
T
>
Condition
operator
!=
(
const
Key
&
key
,
const
T
&
v
)
{
return
Condition
(
new
detail
::
n
otConditionImpl
(
operator
==
(
key
,
v
)));
return
Condition
(
new
detail
::
N
otConditionImpl
(
operator
==
(
key
,
v
)));
}
inline
Condition
operator
!=
(
const
Key
&
key
,
const
char
*
v
)
{
std
::
string
value
(
v
?
v
:
""
);
return
Condition
(
new
detail
::
n
otConditionImpl
(
operator
==
(
key
,
value
)));
return
Condition
(
new
detail
::
N
otConditionImpl
(
operator
==
(
key
,
value
)));
}
template
<
typename
T
>
...
...
@@ -1185,7 +1175,7 @@ struct any
template
<
typename
T
>
Condition
operator
==
(
const
T
&
v
)
const
{
return
Condition
(
new
detail
::
a
nyIsConditionImpl
<
T
>
(
v
));
return
Condition
(
new
detail
::
A
nyIsConditionImpl
<
T
>
(
v
));
}
};
...
...
@@ -1193,17 +1183,17 @@ template<>
inline
Condition
any
::
operator
==
(
const
std
::
regex
&
rx
)
const
{
return
Condition
(
new
detail
::
a
nyMatchesConditionImpl
(
rx
));
return
Condition
(
new
detail
::
A
nyMatchesConditionImpl
(
rx
));
}
inline
Condition
All
()
{
return
Condition
(
new
detail
::
a
llConditionImpl
());
return
Condition
(
new
detail
::
A
llConditionImpl
());
}
inline
Condition
Not
(
Condition
&&
cond
)
{
return
Condition
(
new
detail
::
n
otConditionImpl
(
std
::
move
(
cond
)));
return
Condition
(
new
detail
::
N
otConditionImpl
(
std
::
move
(
cond
)));
}
// -----------------------------------------------------------------------
...
...
@@ -1262,30 +1252,139 @@ class iterator_impl
// --------------------------------------------------------------------
// Iterator proxy to iterate over a subset of rows selected by a Condition
template
<
typename
RowType
>
// template<typename RowType, typename...>
// class conditional_iterator_proxy;
// template<typename RowType>
// class conditional_iterator_proxy<RowType>
// {
// public:
// using base_iterator = iterator_impl<RowType>;
// class conditional_iterator_impl
// {
// public:
// using iterator_category = std::forward_iterator_tag;
// using value_type = RowType;
// using difference_type = std::ptrdiff_t;
// using pointer = RowType*;
// using reference = RowType&;
// conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond);
// conditional_iterator_impl(const conditional_iterator_impl& i) = default;
// conditional_iterator_impl& operator=(const conditional_iterator_impl& i) = default;
// virtual ~conditional_iterator_impl() = default;
// reference operator*() { return *mBegin; }
// pointer operator->() { return &*mBegin; }
// conditional_iterator_impl& operator++()
// {
// while (mBegin != mEnd)
// {
// if (++mBegin == mEnd)
// break;
// if ((*mCondition)(*mCat, *mBegin))
// break;
// }
// return *this;
// }
// conditional_iterator_impl operator++(int)
// {
// conditional_iterator_impl result(*this);
// this->operator++();
// return result;
// }
// bool operator==(const conditional_iterator_impl& rhs) const { return mBegin == rhs.mBegin; }
// bool operator!=(const conditional_iterator_impl& rhs) const { return mBegin != rhs.mBegin; }
// private:
// Category* mCat;
// base_iterator mBegin, mEnd;
// const Condition* mCondition;
// };
// using iterator = conditional_iterator_impl;
// using reference = typename iterator::reference;
// conditional_iterator_proxy(Category& cat, base_iterator pos, Condition&& cond);
// conditional_iterator_proxy(conditional_iterator_proxy&& p);
// conditional_iterator_proxy& operator=(conditional_iterator_proxy&& p);
// conditional_iterator_proxy(const conditional_iterator_proxy&) = delete;
// conditional_iterator_proxy& operator=(const conditional_iterator_proxy&) = delete;
// iterator begin() const;
// iterator end() const;
// bool empty() const;
// explicit operator bool() const { return not empty(); }
// size_t size() const { return std::distance(begin(), end()); }
// RowType front() { return *begin(); }
// Category& category() const { return *mCat;}
// void swap(conditional_iterator_proxy& rhs);
// private:
// Category* mCat;
// Condition mCondition;
// base_iterator mCBegin, mCEnd;
// };
// --------------------------------------------------------------------
// special case, returns tuples instead of a row
template
<
typename
RowType
,
typename
...
Ts
>
class
conditional_iterator_proxy
{
public
:
using
base_iterator
=
iterator_impl
<
RowType
>
;
static
constexpr
const
size_t
N
=
sizeof
...(
Ts
);
class
conditional_iterator_impl
{
public
:
using
iterator_category
=
std
::
forward_iterator_tag
;
using
value_type
=
RowType
;
using
value_type
=
std
::
conditional_t
<
N
==
0
,
RowType
,
std
::
tuple
<
Ts
...
>>
;
using
difference_type
=
std
::
ptrdiff_t
;
using
pointer
=
RowT
ype
*
;
using
reference
=
RowT
ype
&
;
using
pointer
=
value_t
ype
*
;
using
reference
=
value_t
ype
&
;
conditional_iterator_impl
(
Category
&
cat
,
base_iterator
pos
,
const
Condition
&
cond
);
// conditional_iterator_impl(Category& cat, base_iterator pos, const Condition& cond);
conditional_iterator_impl
(
Category
&
cat
,
base_iterator
pos
,
const
Condition
&
cond
,
std
::
array
<
size_t
,
N
>
columns
);
conditional_iterator_impl
(
const
conditional_iterator_impl
&
i
)
=
default
;
conditional_iterator_impl
&
operator
=
(
const
conditional_iterator_impl
&
i
)
=
default
;
virtual
~
conditional_iterator_impl
()
=
default
;
reference
operator
*
()
{
return
*
mBegin
;
}
pointer
operator
->
()
{
return
&*
mBegin
;
}
reference
operator
*
()
{
if
constexpr
(
N
==
0
)
return
*
mBegin
;
else
return
mCurrent
;
}
pointer
operator
->
()
{
if
constexpr
(
N
==
0
)
return
&*
mBegin
;
else
return
&
mCurrent
;
}
conditional_iterator_impl
&
operator
++
()
{
...
...
@@ -1295,7 +1394,11 @@ class conditional_iterator_proxy
break
;
if
((
*
mCondition
)(
*
mCat
,
*
mBegin
))
{
if
constexpr
(
N
!=
0
)
mCurrent
=
get
(
*
mBegin
,
std
::
make_index_sequence
<
N
>
());
break
;
}
}
return
*
this
;
...
...
@@ -1312,15 +1415,25 @@ class conditional_iterator_proxy
bool
operator
!=
(
const
conditional_iterator_impl
&
rhs
)
const
{
return
mBegin
!=
rhs
.
mBegin
;
}
private
:
template
<
std
::
size_t
...
Is
>
std
::
tuple
<
Ts
...
>
get
(
Row
row
,
std
::
index_sequence
<
Is
...
>
)
const
{
return
std
::
tuple
<
Ts
...
>
{
row
[
mCix
[
Is
]].
template
as
<
Ts
>
()...};
}
Category
*
mCat
;
base_iterator
mBegin
,
mEnd
;
const
Condition
*
mCondition
;
value_type
mCurrent
;
std
::
array
<
size_t
,
N
>
mCix
;
};
using
iterator
=
conditional_iterator_impl
;
using
reference
=
typename
iterator
::
reference
;
conditional_iterator_proxy
(
Category
&
cat
,
base_iterator
pos
,
Condition
&&
cond
);
conditional_iterator_proxy
(
Category
&
cat
,
base_iterator
pos
,
Condition
&&
cond
,
char
const
*
const
columns
[
N
]);
conditional_iterator_proxy
(
conditional_iterator_proxy
&&
p
);
conditional_iterator_proxy
&
operator
=
(
conditional_iterator_proxy
&&
p
);
...
...
@@ -1347,6 +1460,7 @@ class conditional_iterator_proxy
Category
*
mCat
;
Condition
mCondition
;
base_iterator
mCBegin
,
mCEnd
;
std
::
array
<
size_t
,
N
>
mCix
;
};
// --------------------------------------------------------------------
...
...
@@ -1551,6 +1665,18 @@ class Category
return
{
*
this
,
pos
,
std
::
forward
<
Condition
>
(
cond
)
};
}
template
<
typename
...
Ts
,
size_t
N
>
conditional_iterator_proxy
<
Row
,
Ts
...
>
find
(
Condition
&&
cond
,
char
const
*
const
(
&
columns
)[
N
])
{
static_assert
(
sizeof
...(
Ts
)
==
N
,
"The number of column titles should be equal to the number of types to return"
);
return
{
*
this
,
begin
(),
std
::
forward
<
Condition
>
(
cond
),
columns
};
}
// conditional_iterator_proxy<Row> find(const_iterator pos, Condition&& cond)
// {
// return { *this, pos, std::forward<Condition>(cond) };
// }
bool
exists
(
Condition
&&
cond
)
const
;
RowSet
orderBy
(
const
std
::
string
&
Item
)
...
...
@@ -1733,7 +1859,7 @@ namespace detail
template
<
typename
T
>
inline
bool
a
nyIsConditionImpl
<
T
>::
test
(
const
Category
&
c
,
const
Row
&
r
)
const
bool
A
nyIsConditionImpl
<
T
>::
test
(
const
Category
&
c
,
const
Row
&
r
)
const
{
bool
result
=
false
;
for
(
auto
&
f
:
c
.
fields
())
...
...
@@ -1752,7 +1878,7 @@ bool anyIsConditionImpl<T>::test(const Category& c, const Row& r) const
return
result
;
}
inline
bool
a
nyMatchesConditionImpl
::
test
(
const
Category
&
c
,
const
Row
&
r
)
const
inline
bool
A
nyMatchesConditionImpl
::
test
(
const
Category
&
c
,
const
Row
&
r
)
const
{
bool
result
=
false
;
for
(
auto
&
f
:
c
.
fields
())
...
...
@@ -1787,26 +1913,32 @@ inline void swap(cif::detail::ItemReference& a, cif::detail::ItemReference& b)
// --------------------------------------------------------------------
template
<
typename
RowType
>
conditional_iterator_proxy
<
RowType
>::
conditional_iterator_impl
::
conditional_iterator_impl
(
Category
&
cat
,
base_iterator
pos
,
const
Condition
&
cond
)
:
mCat
(
&
cat
),
mBegin
(
pos
),
mEnd
(
cat
.
end
()),
mCondition
(
&
cond
)
template
<
typename
RowType
,
typename
...
Ts
>
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
conditional_iterator_impl
::
conditional_iterator_impl
(
Category
&
cat
,
base_iterator
pos
,
const
Condition
&
cond
,
std
::
array
<
size_t
,
N
>
cix
)
:
mCat
(
&
cat
),
mBegin
(
pos
),
mEnd
(
cat
.
end
()),
mCondition
(
&
cond
)
,
mCix
(
cix
)
{
// skip until the first row matching cond
while
(
mBegin
!=
mEnd
and
not
(
*
mCondition
)(
*
mCat
,
*
mBegin
))
++
mBegin
;
if
constexpr
(
N
!=
0
)
{
if
(
mBegin
!=
mEnd
)
mCurrent
=
get
(
*
mBegin
,
std
::
make_index_sequence
<
N
>
());
}
}
template
<
typename
RowType
>
conditional_iterator_proxy
<
RowType
>::
conditional_iterator_proxy
(
conditional_iterator_proxy
&&
p
)
:
mCat
(
nullptr
),
mCBegin
(
p
.
mCBegin
),
mCEnd
(
p
.
mCEnd
)
template
<
typename
RowType
,
typename
...
Ts
>
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
conditional_iterator_proxy
(
conditional_iterator_proxy
&&
p
)
:
mCat
(
nullptr
),
mCBegin
(
p
.
mCBegin
),
mCEnd
(
p
.
mCEnd
)
,
mCix
(
p
.
mCix
)
{
std
::
swap
(
mCat
,
p
.
mCat
);
mCondition
.
swap
(
p
.
mCondition
);
}
template
<
typename
RowType
>
conditional_iterator_proxy
<
RowType
>::
conditional_iterator_proxy
(
Category
&
cat
,
base_iterator
pos
,
Condition
&&
cond
)
template
<
typename
RowType
,
typename
...
Ts
>
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
conditional_iterator_proxy
(
Category
&
cat
,
base_iterator
pos
,
Condition
&&
cond
)
:
mCat
(
&
cat
),
mCondition
(
std
::
move
(
cond
))
,
mCBegin
(
pos
)
,
mCEnd
(
cat
.
end
())
...
...
@@ -1817,38 +1949,47 @@ conditional_iterator_proxy<RowType>::conditional_iterator_proxy(Category& cat, b
++
mCBegin
;
}
template
<
typename
RowType
>
conditional_iterator_proxy
<
RowType
>&
conditional_iterator_proxy
<
RowType
>::
operator
=
(
conditional_iterator_proxy
&&
p
)
template
<
typename
RowType
,
typename
...
Ts
>
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
conditional_iterator_proxy
(
Category
&
cat
,
base_iterator
pos
,
Condition
&&
cond
,
const
char
*
const
columns
[
N
])
:
conditional_iterator_proxy
(
cat
,
pos
,
std
::
forward
<
Condition
>
(
cond
))
{
for
(
size_t
i
=
0
;
i
<
N
;
++
i
)
mCix
[
i
]
=
mCat
->
getColumnIndex
(
columns
[
i
]);
}
template
<
typename
RowType
,
typename
...
Ts
>
conditional_iterator_proxy
<
RowType
,
Ts
...
>&
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
operator
=
(
conditional_iterator_proxy
&&
p
)
{
swap
(
p
);
return
*
this
;
}
template
<
typename
RowType
>
typename
conditional_iterator_proxy
<
RowType
>::
iterator
conditional_iterator_proxy
<
RowType
>::
begin
()
const
template
<
typename
RowType
,
typename
...
Ts
>
typename
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
iterator
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
begin
()
const
{
return
iterator
(
*
mCat
,
mCBegin
,
mCondition
);
return
iterator
(
*
mCat
,
mCBegin
,
mCondition
,
mCix
);
}
template
<
typename
RowType
>
typename
conditional_iterator_proxy
<
RowType
>::
iterator
conditional_iterator_proxy
<
RowType
>::
end
()
const
template
<
typename
RowType
,
typename
...
Ts
>
typename
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
iterator
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
end
()
const
{
return
iterator
(
*
mCat
,
mCEnd
,
mCondition
);
return
iterator
(
*
mCat
,
mCEnd
,
mCondition
,
mCix
);
}
template
<
typename
RowType
>
bool
conditional_iterator_proxy
<
RowType
>::
empty
()
const
template
<
typename
RowType
,
typename
...
Ts
>
bool
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
empty
()
const
{
return
mCBegin
==
mCEnd
;
}
template
<
typename
RowType
>
void
conditional_iterator_proxy
<
RowType
>::
swap
(
conditional_iterator_proxy
&
rhs
)
template
<
typename
RowType
,
typename
...
Ts
>
void
conditional_iterator_proxy
<
RowType
,
Ts
...
>::
swap
(
conditional_iterator_proxy
&
rhs
)
{
std
::
swap
(
mCat
,
rhs
.
mCat
);
mCondition
.
swap
(
rhs
.
mCondition
);
std
::
swap
(
mCBegin
,
rhs
.
mCBegin
);
std
::
swap
(
mCEnd
,
rhs
.
mCEnd
);
std
::
swap
(
mCix
,
rhs
.
mCix
);
}
}
...
...
include/cif++/Structure.hpp
View file @
6f93fa37
...
...
@@ -443,6 +443,7 @@ class Structure
std
::
list
<
Polymer
>&
polymers
()
{
return
mPolymers
;
}
const
std
::
vector
<
Residue
>&
nonPolymers
()
const
{
return
mNonPolymers
;
}
const
std
::
vector
<
Residue
>&
branchResidues
()
const
{
return
mBranchResidues
;
}
Atom
getAtomByID
(
std
::
string
id
)
const
;
// Atom getAtomByLocation(Point pt, float maxDistance) const;
...
...
@@ -450,10 +451,6 @@ class Structure
Atom
getAtomByLabel
(
const
std
::
string
&
atomID
,
const
std
::
string
&
asymID
,
const
std
::
string
&
compID
,
int
seqID
,
const
std
::
string
&
altID
=
""
);
// Atom getAtomByAuth(const std::string& atomID, const std::string& asymID,
// const std::string& compID, int seqID, const std::string& altID = "",
// const std::string& pdbxAuthInsCode = "");
const
Residue
&
getResidue
(
const
std
::
string
&
asymID
,
const
std
::
string
&
compID
,
int
seqID
)
const
;
// map between auth and label locations
...
...
@@ -487,65 +484,65 @@ class Structure
/// Will asssign new atom_id's to all atoms. Be carefull
void
sortAtoms
();
// iterator for all residues
//
//
iterator for all residues
class
residue_iterator
:
public
std
::
iterator
<
std
::
forward_iterator_tag
,
const
Residue
>
{
public
:
typedef
std
::
iterator
<
std
::
forward_iterator_tag
,
const
Residue
>
baseType
;
typedef
typename
baseType
::
pointer
pointer
;
typedef
typename
baseType
::
reference
reference
;
//
class residue_iterator : public std::iterator<std::forward_iterator_tag, const Residue>
//
{
//
public:
//
typedef std::iterator<std::forward_iterator_tag, const Residue> baseType;
//
typedef typename baseType::pointer pointer;
//
typedef typename baseType::reference reference;
typedef
std
::
list
<
Polymer
>::
const_iterator
poly_iterator
;
//
typedef std::list<Polymer>::const_iterator poly_iterator;
residue_iterator
(
const
Structure
*
s
,
poly_iterator
polyIter
,
size_t
polyResIndex
,
size_t
nonPolyIndex
);
//
residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex);
reference
operator
*
();
pointer
operator
->
();
//
reference operator*();
//
pointer operator->();
residue_iterator
&
operator
++
();
residue_iterator
operator
++
(
int
);
//
residue_iterator& operator++();
//
residue_iterator operator++(int);
bool
operator
==
(
const
residue_iterator
&
rhs
)
const
;
bool
operator
!=
(
const
residue_iterator
&
rhs
)
const
;
//
bool operator==(const residue_iterator& rhs) const;
//
bool operator!=(const residue_iterator& rhs) const;
private
:
const
Structure
&
mStructure
;
poly_iterator
mPolyIter
;
size_t
mPolyResIndex
;
size_t
mNonPolyIndex
;
};
class
residue_view
{
public
:
residue_view
(
const
Structure
*
s
)
:
mStructure
(
s
)
{}
residue_view
(
const
residue_view
&
rhs
)
:
mStructure
(
rhs
.
mStructure
)
{}
residue_view
&
operator
=
(
residue_view
&
rhs
)
{
mStructure
=
rhs
.
mStructure
;
return
*
this
;
}
//
private:
//
const Structure& mStructure;
//
poly_iterator mPolyIter;
//
size_t mPolyResIndex;
//
size_t mNonPolyIndex;
//
};
//
class residue_view
//
{
//
public:
//
residue_view(const Structure* s) : mStructure(s) {}
//
residue_view(const residue_view& rhs) : mStructure(rhs.mStructure) {}
//
residue_view& operator=(residue_view& rhs)
//
{
//
mStructure = rhs.mStructure;
//
return *this;
//
}
residue_iterator
begin
()
const
{
return
residue_iterator
(
mStructure
,
mStructure
->
mPolymers
.
begin
(),
0
,
0
);
}
residue_iterator
end
()
const
{
return
residue_iterator
(
mStructure
,
mStructure
->
mPolymers
.
end
(),
0
,
mStructure
->
mNonPolymers
.
size
());
}
size_t
size
()
const
{
size_t
ps
=
std
::
accumulate
(
mStructure
->
mPolymers
.
begin
(),
mStructure
->
mPolymers
.
end
(),
0UL
,
[](
size_t
s
,
auto
&
p
)
{
return
s
+
p
.
size
();
});
return
ps
+
mStructure
->
mNonPolymers
.
size
();
}
//
residue_iterator begin() const { return residue_iterator(mStructure, mStructure->mPolymers.begin(), 0, 0); }
//
residue_iterator end() const { return residue_iterator(mStructure, mStructure->mPolymers.end(), 0, mStructure->mNonPolymers.size()); }
//
size_t size() const
//
{
//
size_t ps = std::accumulate(mStructure->mPolymers.begin(), mStructure->mPolymers.end(), 0UL, [](size_t s, auto& p) { return s + p.size(); });
//
return ps + mStructure->mNonPolymers.size();
//
}
private
:
const
Structure
*
mStructure
;
};
//
private:
//
const Structure* mStructure;
//
};
residue_view
residues
()
const
{
return
residue_view
(
this
);
}
//
residue_view residues() const { return residue_view(this); }
private
:
friend
Polymer
;
friend
Residue
;
friend
residue_view
;
friend
residue_iterator
;
//
friend residue_view;
//
friend residue_iterator;
cif
::
Category
&
category
(
const
char
*
name
)
const
;
cif
::
Datablock
&
datablock
()
const
;
...
...
@@ -560,7 +557,7 @@ class Structure
AtomView
mAtoms
;
std
::
vector
<
size_t
>
mAtomIndex
;
std
::
list
<
Polymer
>
mPolymers
;
std
::
vector
<
Residue
>
mNonPolymers
;
std
::
vector
<
Residue
>
mNonPolymers
,
mBranchResidues
;
};
}
src/Structure.cpp
View file @
6f93fa37
...
...
@@ -1732,6 +1732,17 @@ void Structure::loadData()
else
if
(
mNonPolymers
.
empty
()
or
mNonPolymers
.
back
().
asymID
()
!=
asymID
)
mNonPolymers
.
emplace_back
(
*
this
,
monID
,
asymID
);
}
auto
&
branchScheme
=
category
(
"pdbx_branch_scheme"
);
for
(
auto
&
r
:
branchScheme
)
{
std
::
string
asymID
,
monID
,
num
;
cif
::
tie
(
asymID
,
monID
,
num
)
=
r
.
get
(
"asym_id"
,
"mon_id"
,
"num"
);
mBranchResidues
.
emplace_back
(
*
this
,
monID
,
asymID
,
num
);
}
}
void
Structure
::
updateAtomIndex
()
...
...
@@ -2038,64 +2049,64 @@ void Structure::insertCompound(const std::string& compoundID, bool isEntity)
}
}
// --------------------------------------------------------------------
//
//
--------------------------------------------------------------------
Structure
::
residue_iterator
::
residue_iterator
(
const
Structure
*
s
,
poly_iterator
polyIter
,
size_t
polyResIndex
,
size_t
nonPolyIndex
)
:
mStructure
(
*
s
),
mPolyIter
(
polyIter
),
mPolyResIndex
(
polyResIndex
),
mNonPolyIndex
(
nonPolyIndex
)
{
while
(
mPolyIter
!=
mStructure
.
mPolymers
.
end
()
and
mPolyResIndex
==
mPolyIter
->
size
())
++
mPolyIter
;
}
//
Structure::residue_iterator::residue_iterator(const Structure* s, poly_iterator polyIter, size_t polyResIndex, size_t nonPolyIndex)
//
: mStructure(*s), mPolyIter(polyIter), mPolyResIndex(polyResIndex), mNonPolyIndex(nonPolyIndex)
//
{
//
while (mPolyIter != mStructure.mPolymers.end() and mPolyResIndex == mPolyIter->size())
//
++mPolyIter;
//
}
auto
Structure
::
residue_iterator
::
operator
*
()
->
reference
{
if
(
mPolyIter
!=
mStructure
.
mPolymers
.
end
())
return
(
*
mPolyIter
)[
mPolyResIndex
];
else
return
mStructure
.
mNonPolymers
[
mNonPolyIndex
];
}
//
auto Structure::residue_iterator::operator*() -> reference
//
{
//
if (mPolyIter != mStructure.mPolymers.end())
//
return (*mPolyIter)[mPolyResIndex];
//
else
//
return mStructure.mNonPolymers[mNonPolyIndex];
//
}
auto
Structure
::
residue_iterator
::
operator
->
()
->
pointer
{
if
(
mPolyIter
!=
mStructure
.
mPolymers
.
end
())
return
&
(
*
mPolyIter
)[
mPolyResIndex
];
else
return
&
mStructure
.
mNonPolymers
[
mNonPolyIndex
];
}
//
auto Structure::residue_iterator::operator->() -> pointer
//
{
//
if (mPolyIter != mStructure.mPolymers.end())
//
return &(*mPolyIter)[mPolyResIndex];
//
else
//
return &mStructure.mNonPolymers[mNonPolyIndex];
//
}
Structure
::
residue_iterator
&
Structure
::
residue_iterator
::
operator
++
()
{
if
(
mPolyIter
!=
mStructure
.
mPolymers
.
end
())
{
++
mPolyResIndex
;
if
(
mPolyResIndex
>=
mPolyIter
->
size
())
{
++
mPolyIter
;
mPolyResIndex
=
0
;
}
}
else
++
mNonPolyIndex
;
return
*
this
;
}
//
Structure::residue_iterator& Structure::residue_iterator::operator++()
//
{
//
if (mPolyIter != mStructure.mPolymers.end())
//
{
//
++mPolyResIndex;
//
if (mPolyResIndex >= mPolyIter->size())
//
{
//
++mPolyIter;
//
mPolyResIndex = 0;
//
}
//
}
//
else
//
++mNonPolyIndex;
//
return *this;
//
}
Structure
::
residue_iterator
Structure
::
residue_iterator
::
operator
++
(
int
)
{
auto
result
=
*
this
;
operator
++
();
return
result
;
}
//
Structure::residue_iterator Structure::residue_iterator::operator++(int)
//
{
//
auto result = *this;
//
operator++();
//
return result;
//
}
bool
Structure
::
residue_iterator
::
operator
==
(
const
Structure
::
residue_iterator
&
rhs
)
const
{
return
mPolyIter
==
rhs
.
mPolyIter
and
mPolyResIndex
==
rhs
.
mPolyResIndex
and
mNonPolyIndex
==
rhs
.
mNonPolyIndex
;
}
//
bool Structure::residue_iterator::operator==(const Structure::residue_iterator& rhs) const
//
{
//
return mPolyIter == rhs.mPolyIter and mPolyResIndex == rhs.mPolyResIndex and mNonPolyIndex == rhs.mNonPolyIndex;
//
}
bool
Structure
::
residue_iterator
::
operator
!=
(
const
Structure
::
residue_iterator
&
rhs
)
const
{
return
mPolyIter
!=
rhs
.
mPolyIter
or
mPolyResIndex
!=
rhs
.
mPolyResIndex
or
mNonPolyIndex
!=
rhs
.
mNonPolyIndex
;
}
//
bool Structure::residue_iterator::operator!=(const Structure::residue_iterator& rhs) const
//
{
//
return mPolyIter != rhs.mPolyIter or mPolyResIndex != rhs.mPolyResIndex or mNonPolyIndex != rhs.mNonPolyIndex;
//
}
// --------------------------------------------------------------------
...
...
test/unit-test.cpp
View file @
6f93fa37
...
...
@@ -1073,4 +1073,98 @@ _cat_2.parent_id3
cat1
.
erase
(
cif
::
Key
(
"id"
)
==
30
);
BOOST_CHECK
(
cat1
.
size
()
==
0
);
BOOST_CHECK
(
cat2
.
size
()
==
0
);
}
\ No newline at end of file
}
// --------------------------------------------------------------------
BOOST_AUTO_TEST_CASE
(
c1
)
{
cif
::
VERBOSE
=
1
;
auto
f
=
R"(data_TEST
#
loop_
_test.id
_test.name
1 aap
2 noot
3 mies
4 .
5 ?
)"
_cf
;
auto
&
db
=
f
.
firstDatablock
();
for
(
auto
r
:
db
[
"test"
].
find
(
cif
::
Key
(
"id"
)
==
1
))
{
const
auto
&
[
id
,
name
]
=
r
.
get
<
int
,
std
::
string
>
({
"id"
,
"name"
});
BOOST_CHECK
(
id
==
1
);
BOOST_CHECK
(
name
==
"aap"
);
}
for
(
auto
r
:
db
[
"test"
].
find
(
cif
::
Key
(
"id"
)
==
4
))
{
const
auto
&
[
id
,
name
]
=
r
.
get
<
int
,
std
::
string
>
({
"id"
,
"name"
});
BOOST_CHECK
(
id
==
4
);
BOOST_CHECK
(
name
.
empty
());
}
for
(
auto
r
:
db
[
"test"
].
find
(
cif
::
Key
(
"id"
)
==
5
))
{
const
auto
&
[
id
,
name
]
=
r
.
get
<
int
,
std
::
string
>
({
"id"
,
"name"
});
BOOST_CHECK
(
id
==
5
);
BOOST_CHECK
(
name
.
empty
());
}
// optional
for
(
auto
r
:
db
[
"test"
])
{
const
auto
&
[
id
,
name
]
=
r
.
get
<
int
,
std
::
optional
<
std
::
string
>>
({
"id"
,
"name"
});
switch
(
id
)
{
case
1
:
BOOST_CHECK
(
name
==
"aap"
);
break
;
case
2
:
BOOST_CHECK
(
name
==
"noot"
);
break
;
case
3
:
BOOST_CHECK
(
name
==
"mies"
);
break
;
case
4
:
case
5
:
BOOST_CHECK
(
not
name
);
break
;
default
:
BOOST_CHECK
(
false
);
}
}
}
BOOST_AUTO_TEST_CASE
(
c2
)
{
cif
::
VERBOSE
=
1
;
auto
f
=
R"(data_TEST
#
loop_
_test.id
_test.name
1 aap
2 noot
3 mies
4 .
5 ?
)"
_cf
;
auto
&
db
=
f
.
firstDatablock
();
// query tests
for
(
const
auto
&
[
id
,
name
]
:
db
[
"test"
].
find
<
int
,
std
::
optional
<
std
::
string
>>
(
cif
::
All
(),
{
"id"
,
"name"
}))
{
switch
(
id
)
{
case
1
:
BOOST_CHECK
(
name
==
"aap"
);
break
;
case
2
:
BOOST_CHECK
(
name
==
"noot"
);
break
;
case
3
:
BOOST_CHECK
(
name
==
"mies"
);
break
;
case
4
:
case
5
:
BOOST_CHECK
(
not
name
);
break
;
default
:
BOOST_CHECK
(
false
);
}
}
}
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