Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91863408
test_iterators.cc
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Fri, Nov 15, 06:31
Size
10 KB
Mime Type
text/x-c++
Expires
Sun, Nov 17, 06:31 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
22336512
Attached To
rAKA akantu
test_iterators.cc
View Options
/**
* @file test_zip_iterator.cc
*
* @author Nicolas Richart <nicolas.richart@epfl.ch>
*
* @date creation: Fri Jul 21 2017
* @date last modification: Fri Dec 08 2017
*
* @brief test the zip container and iterator
*
* @section LICENSE
*
* Copyright (©) 2016-2018 EPFL (Ecole Polytechnique Fédérale de Lausanne)
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* akantu-iterators is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* akantu-iterators is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with akantu-iterators. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "aka_iterators.hh"
/* -------------------------------------------------------------------------- */
#include <gtest/gtest.h>
#include <vector>
/* -------------------------------------------------------------------------- */
using
namespace
aka
;
/* -------------------------------------------------------------------------- */
// Non Trivial class that counts moves and copies
template
<
class
T
>
class
A
{
public
:
A
()
=
default
;
A
(
T
a
)
:
a
(
a
){};
A
(
const
A
&
other
)
:
a
(
other
.
a
),
copy_counter
(
other
.
copy_counter
+
1
),
move_counter
(
other
.
move_counter
)
{}
A
&
operator
=
(
const
A
&
other
)
{
if
(
this
!=
&
other
)
{
a
=
other
.
a
;
copy_counter
=
other
.
copy_counter
+
1
;
}
return
*
this
;
}
A
(
A
&&
other
)
:
a
(
std
::
move
(
other
.
a
)),
copy_counter
(
std
::
move
(
other
.
copy_counter
)),
move_counter
(
std
::
move
(
other
.
move_counter
)
+
1
)
{}
A
&
operator
=
(
A
&&
other
)
{
if
(
this
!=
&
other
)
{
a
=
std
::
move
(
other
.
a
);
copy_counter
=
std
::
move
(
other
.
copy_counter
);
move_counter
=
std
::
move
(
other
.
move_counter
)
+
1
;
}
return
*
this
;
}
A
&
operator
*=
(
const
T
&
b
)
{
a
*=
b
;
return
*
this
;
}
T
a
{};
size_t
copy_counter
{
0
};
size_t
move_counter
{
0
};
};
template
<
typename
T
>
struct
C
{
struct
iterator
{
using
reference
=
A
<
T
>
;
using
difference_type
=
void
;
using
iterator_category
=
std
::
input_iterator_tag
;
using
value_type
=
A
<
T
>
;
using
pointer
=
A
<
T
>
*
;
iterator
(
T
pos
)
:
pos
(
std
::
move
(
pos
))
{}
A
<
T
>
operator
*
()
{
return
A
<
int
>
(
pos
);
}
bool
operator
!=
(
const
iterator
&
other
)
const
{
return
pos
!=
other
.
pos
;
}
bool
operator
==
(
const
iterator
&
other
)
const
{
return
pos
==
other
.
pos
;
}
iterator
&
operator
++
()
{
++
pos
;
return
*
this
;
}
T
pos
;
};
C
(
T
begin_
,
T
end_
)
:
begin_
(
std
::
move
(
begin_
)),
end_
(
std
::
move
(
end_
))
{}
iterator
begin
()
{
return
iterator
(
begin_
);
}
iterator
end
()
{
return
iterator
(
end_
);
}
T
begin_
,
end_
;
};
class
TestZipFixutre
:
public
::
testing
::
Test
{
protected
:
void
SetUp
()
override
{
a
.
reserve
(
size
);
b
.
reserve
(
size
);
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
a
.
emplace_back
(
i
);
b
.
emplace_back
(
i
+
size
);
}
}
template
<
typename
A
,
typename
B
>
void
check
(
A
&&
a
,
B
&&
b
,
size_t
pos
,
size_t
nb_copy
,
size_t
nb_move
)
{
EXPECT_EQ
(
pos
,
a
.
a
);
EXPECT_EQ
(
nb_copy
,
a
.
copy_counter
);
EXPECT_EQ
(
nb_move
,
a
.
move_counter
);
EXPECT_FLOAT_EQ
(
pos
+
this
->
size
,
b
.
a
);
EXPECT_EQ
(
nb_copy
,
b
.
copy_counter
);
EXPECT_EQ
(
nb_move
,
b
.
move_counter
);
}
protected
:
size_t
size
{
20
};
std
::
vector
<
A
<
int
>>
a
{};
std
::
vector
<
A
<
float
>>
b
{};
};
TEST_F
(
TestZipFixutre
,
SimpleTest
)
{
size_t
i
=
0
;
for
(
auto
&&
pair
:
zip
(
this
->
a
,
this
->
b
))
{
this
->
check
(
std
::
get
<
0
>
(
pair
),
std
::
get
<
1
>
(
pair
),
i
,
0
,
0
);
++
i
;
}
}
TEST_F
(
TestZipFixutre
,
ConstTest
)
{
size_t
i
=
0
;
const
auto
&
ca
=
this
->
a
;
const
auto
&
cb
=
this
->
b
;
for
(
auto
&&
pair
:
zip
(
ca
,
cb
))
{
this
->
check
(
std
::
get
<
0
>
(
pair
),
std
::
get
<
1
>
(
pair
),
i
,
0
,
0
);
EXPECT_EQ
(
true
,
std
::
is_const
<
std
::
remove_reference_t
<
decltype
(
std
::
get
<
0
>
(
pair
))
>>::
value
);
EXPECT_EQ
(
true
,
std
::
is_const
<
std
::
remove_reference_t
<
decltype
(
std
::
get
<
1
>
(
pair
))
>>::
value
);
++
i
;
}
}
TEST_F
(
TestZipFixutre
,
MixteTest
)
{
size_t
i
=
0
;
const
auto
&
cb
=
this
->
b
;
for
(
auto
&&
pair
:
zip
(
a
,
cb
))
{
this
->
check
(
std
::
get
<
0
>
(
pair
),
std
::
get
<
1
>
(
pair
),
i
,
0
,
0
);
EXPECT_EQ
(
false
,
std
::
is_const
<
std
::
remove_reference_t
<
decltype
(
std
::
get
<
0
>
(
pair
))
>>::
value
);
EXPECT_EQ
(
true
,
std
::
is_const
<
std
::
remove_reference_t
<
decltype
(
std
::
get
<
1
>
(
pair
))
>>::
value
);
++
i
;
}
}
TEST_F
(
TestZipFixutre
,
MoveTest
)
{
size_t
i
=
0
;
for
(
auto
&&
pair
:
zip
(
C
<
int
>
(
0
,
this
->
size
),
C
<
int
>
(
this
->
size
,
2
*
this
->
size
)))
{
this
->
check
(
std
::
get
<
0
>
(
pair
),
std
::
get
<
1
>
(
pair
),
i
,
0
,
1
);
++
i
;
}
}
TEST_F
(
TestZipFixutre
,
Bidirectional
)
{
auto
_zip
=
zip
(
a
,
b
);
auto
begin
=
_zip
.
begin
();
auto
it
=
begin
;
++
it
;
EXPECT_EQ
(
begin
,
--
it
);
it
=
begin
;
EXPECT_EQ
(
begin
,
it
++
);
EXPECT_EQ
(
begin
,
--
it
);
auto
it2
=
it
=
begin
;
++
it
;
++
it2
;
EXPECT_EQ
(
it2
,
it
--
);
EXPECT_EQ
(
begin
,
it
);
}
TEST_F
(
TestZipFixutre
,
RandomAccess
)
{
auto
_zip
=
zip
(
a
,
b
);
auto
begin
=
_zip
.
begin
();
auto
end
=
_zip
.
end
();
auto
&&
val5
=
begin
[
5
];
this
->
check
(
std
::
get
<
0
>
(
val5
),
std
::
get
<
1
>
(
val5
),
5
,
0
,
0
);
auto
&&
val13
=
begin
[
13
];
this
->
check
(
std
::
get
<
0
>
(
val13
),
std
::
get
<
1
>
(
val13
),
13
,
0
,
0
);
EXPECT_EQ
(
end
-
begin
,
a
.
size
());
auto
it
=
++
begin
;
EXPECT_EQ
(
begin
+
1
,
++
it
);
EXPECT_EQ
(
begin
,
it
-
1
);
}
TEST_F
(
TestZipFixutre
,
Cat
)
{
size_t
i
=
0
;
for
(
auto
&&
data
:
make_zip_cat
(
zip
(
a
,
b
),
zip
(
a
,
b
)))
{
this
->
check
(
std
::
get
<
0
>
(
data
),
std
::
get
<
1
>
(
data
),
i
,
0
,
0
);
this
->
check
(
std
::
get
<
2
>
(
data
),
std
::
get
<
3
>
(
data
),
i
,
0
,
0
);
++
i
;
}
}
TEST
(
TestNamedZipFixutre
,
Simple
)
{
std
::
vector
<
int
>
a
{
0
,
10
,
20
,
30
,
40
};
std
::
vector
<
int
>
b
{
0
,
1
,
2
,
3
,
4
};
using
namespace
tuple
;
for
(
auto
&&
data
:
named_zip
(
get
<
"a"
_h
>
()
=
a
,
get
<
"b"
_h
>
()
=
b
))
{
auto
&
a
=
tuple
::
get
<
"a"
_h
>
(
data
);
auto
&
b
=
tuple
::
get
<
"b"
_h
>
(
data
);
b
*=
10
;
EXPECT_EQ
(
b
,
a
);
}
for
(
auto
&&
data
:
named_zip
(
get
<
"a"
_h
>
()
=
a
,
get
<
"b"
_h
>
()
=
b
))
{
auto
&
a
=
tuple
::
get
<
"a"
_h
>
(
data
);
auto
&
b
=
tuple
::
get
<
"b"
_h
>
(
data
);
EXPECT_EQ
(
b
,
a
);
}
}
/* -------------------------------------------------------------------------- */
TEST
(
TestArangeIterator
,
Stop
)
{
size_t
ref_i
=
0
;
for
(
auto
i
:
arange
(
10
))
{
EXPECT_EQ
(
ref_i
,
i
);
++
ref_i
;
}
}
TEST
(
TestArangeIterator
,
StartStop
)
{
size_t
ref_i
=
1
;
for
(
auto
i
:
arange
(
1
,
10
))
{
EXPECT_EQ
(
ref_i
,
i
);
++
ref_i
;
}
}
TEST
(
TestArangeIterator
,
StartStopStep
)
{
size_t
ref_i
=
1
;
for
(
auto
i
:
arange
(
1
,
22
,
2
))
{
EXPECT_EQ
(
ref_i
,
i
);
ref_i
+=
2
;
}
}
TEST
(
TestArangeIterator
,
StartStopStepZipped
)
{
int
ref_i1
=
-
1
,
ref_i2
=
1
;
for
(
auto
&&
i
:
zip
(
arange
(
-
1
,
-
10
,
-
1
),
arange
(
1
,
18
,
2
)))
{
EXPECT_EQ
(
ref_i1
,
std
::
get
<
0
>
(
i
));
EXPECT_EQ
(
ref_i2
,
std
::
get
<
1
>
(
i
));
ref_i1
+=
-
1
;
ref_i2
+=
2
;
}
}
/* -------------------------------------------------------------------------- */
TEST
(
TestEnumerateIterator
,
SimpleTest
)
{
std
::
vector
<
int
>
a
{
0
,
10
,
20
,
30
,
40
};
std
::
vector
<
int
>
b
{
0
,
2
,
4
,
6
,
8
};
for
(
auto
&&
data
:
enumerate
(
a
,
b
))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
)
*
10
,
std
::
get
<
1
>
(
data
));
EXPECT_EQ
(
std
::
get
<
0
>
(
data
)
*
2
,
std
::
get
<
2
>
(
data
));
}
}
/* -------------------------------------------------------------------------- */
TEST
(
TestTransformAdaptor
,
Keys
)
{
std
::
map
<
std
::
string
,
int
>
map
{
{
"1"
,
1
},
{
"2"
,
2
},
{
"3"
,
3
},
{
"3"
,
3
},
{
"4"
,
4
}};
char
counter
=
'1'
;
for
(
auto
&&
key
:
make_keys_adaptor
(
map
))
{
EXPECT_EQ
(
counter
,
key
[
0
]);
++
counter
;
}
}
TEST
(
TestTransformAdaptor
,
Values
)
{
std
::
map
<
std
::
string
,
int
>
map
{
{
"1"
,
1
},
{
"2"
,
2
},
{
"3"
,
3
},
{
"3"
,
3
},
{
"4"
,
4
}};
int
counter
=
1
;
for
(
auto
&&
value
:
make_values_adaptor
(
map
))
{
EXPECT_EQ
(
counter
,
value
);
++
counter
;
}
}
static
int
plus1
(
int
value
)
{
return
value
+
1
;
}
struct
Plus
{
Plus
(
int
a
)
:
a
(
a
)
{}
int
operator
()(
int
b
)
{
return
a
+
b
;
}
private
:
int
a
{
0
};
};
TEST
(
TestTransformAdaptor
,
Lambda
)
{
auto
&&
container
=
arange
(
10
);
for
(
auto
&&
data
:
zip
(
container
,
make_transform_adaptor
(
container
,
[](
auto
&&
value
)
{
return
value
+
1
;
})))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
)
+
1
,
std
::
get
<
1
>
(
data
));
}
}
TEST
(
TestTransformAdaptor
,
LambdaLambda
)
{
std
::
map
<
std
::
string
,
int
>
map
{
{
"1"
,
1
},
{
"2"
,
2
},
{
"3"
,
3
},
{
"3"
,
3
},
{
"4"
,
4
}};
int
counter
=
1
;
for
(
auto
&&
data
:
make_transform_adaptor
(
make_values_adaptor
(
map
),
[](
auto
&&
value
)
{
return
value
+
1
;
}))
{
EXPECT_EQ
(
counter
+
1
,
data
);
++
counter
;
}
auto
&&
container
=
arange
(
10
);
for
(
auto
&&
data
:
zip
(
container
,
make_transform_adaptor
(
container
,
[](
auto
&&
value
)
{
return
value
+
1
;
})))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
)
+
1
,
std
::
get
<
1
>
(
data
));
}
}
TEST
(
TestTransformAdaptor
,
Function
)
{
auto
&&
container
=
arange
(
10
);
for
(
auto
&&
data
:
zip
(
container
,
make_transform_adaptor
(
container
,
plus1
)))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
)
+
1
,
std
::
get
<
1
>
(
data
));
}
}
TEST
(
TestTransformAdaptor
,
Functor
)
{
auto
&&
container
=
arange
(
10
);
for
(
auto
&&
data
:
zip
(
container
,
make_transform_adaptor
(
container
,
Plus
(
1
))))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
)
+
1
,
std
::
get
<
1
>
(
data
));
}
}
/* -------------------------------------------------------------------------- */
TEST
(
TestFilteredIterator
,
Simple
)
{
std
::
vector
<
int
>
values
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
};
std
::
vector
<
int
>
filter_
{
1
,
3
,
4
,
10
,
8
,
6
};
for
(
auto
&&
data
:
zip
(
filter_
,
filter
(
filter_
,
values
)))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
),
std
::
get
<
1
>
(
data
));
}
}
/* -------------------------------------------------------------------------- */
TEST
(
TestFilteredIterator
,
Temporary
)
{
std
::
vector
<
int
>
filter_
{
1
,
3
,
4
,
10
,
8
,
6
};
for
(
auto
&&
data
:
zip
(
filter_
,
filter
(
filter_
,
std
::
vector
<
int
>
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
})))
{
EXPECT_EQ
(
std
::
get
<
0
>
(
data
),
std
::
get
<
1
>
(
data
));
}
}
Event Timeline
Log In to Comment