Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Tiago Peixoto
graph-tool
Commits
051c267f
Commit
051c267f
authored
Oct 26, 2015
by
Tiago Peixoto
Browse files
Remove more recursions in nested_for_each()
This reduces even more compilation time and memory use.
parent
09db85b3
Pipeline
#62
failed with stage
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/graph/graph_filtering.hh
View file @
051c267f
...
...
@@ -377,43 +377,27 @@ struct action_wrap
:
_a
(
a
),
_g
(
g
),
_max_v
(
max_v
),
_max_e
(
max_e
)
{}
template
<
class
Type
>
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
vertex_index_map_t
>&
uncheck
(
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
vertex_index_map_t
>&
a
,
boost
::
mpl
::
true_
)
const
{
return
a
;
}
template
<
class
Type
>
boost
::
unchecked_vector_property_map
<
Type
,
GraphInterface
::
vertex_index_map_t
>
uncheck
(
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
vertex_index_map_t
>
a
,
boost
::
mpl
::
false_
)
const
auto
uncheck
(
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
vertex_index_map_t
>
a
,
boost
::
mpl
::
false_
)
const
{
return
a
.
get_unchecked
(
_max_v
);
}
template
<
class
Type
>
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
edge_index_map_t
>&
uncheck
(
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
edge_index_map_t
>&
a
,
boost
::
mpl
::
true_
)
const
{
return
a
;
}
template
<
class
Type
>
boost
::
unchecked_vector_property_map
<
Type
,
GraphInterface
::
edge_index_map_t
>
uncheck
(
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
edge_index_map_t
>
a
,
boost
::
mpl
::
false_
)
const
auto
uncheck
(
boost
::
checked_vector_property_map
<
Type
,
GraphInterface
::
edge_index_map_t
>
a
,
boost
::
mpl
::
false_
)
const
{
return
a
.
get_unchecked
(
_max_e
);
}
template
<
class
Type
>
scalarS
<
typename
Type
::
unchecked_t
>
auto
uncheck
(
scalarS
<
Type
>
a
,
boost
::
mpl
::
false_
)
const
{
return
scalarS
<
typename
Type
::
unchecked_t
>
(
uncheck
(
a
.
_pmap
,
boost
::
mpl
::
false_
()));
return
scalarS
<
typename
Type
::
unchecked_t
>
(
uncheck
(
a
.
_pmap
,
boost
::
mpl
::
false_
()));
}
//no op
...
...
@@ -422,14 +406,10 @@ struct action_wrap
void
operator
()()
const
{};
template
<
class
T1
>
void
operator
()(
T1
*
a1
)
const
{
_a
(
*
a1
);
}
template
<
class
T1
,
class
...
Ts
>
void
operator
()(
T1
*
a1
,
Ts
&&
...
as
)
const
{
_a
(
*
a1
,
uncheck
(
std
::
forward
<
Ts
>
(
as
),
Wrap
())...);
}
Action
_a
;
...
...
src/graph/mpl_nested_loop.hh
View file @
051c267f
...
...
@@ -54,105 +54,95 @@ namespace mpl
//
// The code above will run iterate through all combinations of foo::operator(T1,
// T2, T3) and call the one that corresponds to the actual types stored in x, y,
// and z. If the types are not found during iteration, we have found = true,
// otherwise found = false. This provides a more general compile-time to
// and z. If the types are not found during iteration, we have found =
=
true,
// otherwise found =
=
false. This provides a more general compile-time to
// run-time bridge than the simpler mpl::for_each().
template
<
class
Action
,
class
T
>
struct
bind_arg
struct
stop_iteration
:
public
std
::
exception
{};
// this is a functor wrapper that will perform an any_cast<> in each in an array
// of arguments according to the called types. If the cast is successful, the
// function will be called with those types, and stop_iteration will be thrown.
template
<
class
Action
,
std
::
size_t
N
>
struct
all_any_cast
{
bind_arg
(
Action
a
,
any
&
arg
,
bool
&
found
)
:
_a
(
a
),
_arg
(
arg
),
_found
(
found
)
{}
all_any_cast
(
Action
a
,
std
::
array
<
any
,
N
>&
args
)
:
_a
(
a
),
_arg
s
(
arg
s
)
{}
template
<
class
...
Ts
>
__attribute__
((
always_inline
))
void
operator
()(
Ts
&&
...
arg
s
)
const
void
operator
()(
Ts
&&
...
v
s
)
const
{
T
*
v
=
const_cast
<
T
*>
(
any_cast
<
T
>
(
&
_arg
));
if
(
v
!=
0
)
_a
(
*
v
,
args
...);
dispatch
(
std
::
make_index_sequence
<
sizeof
...(
Ts
)
>
(),
std
::
forward
<
Ts
>
(
vs
)...);
}
template
<
std
::
size_t
...
Idx
,
class
...
Ts
>
__attribute__
((
always_inline
))
void
operator
()(
)
const
void
dispatch
(
std
::
index_sequence
<
Idx
...
>
,
Ts
&&
...
)
const
{
T
*
v
=
const_cast
<
T
*>
(
any_cast
<
T
>
(
&
_arg
));
if
(
v
!=
0
)
try
{
_a
(
*
v
);
_found
=
true
;
_a
(
any_cast
<
Ts
&>
(
_args
[
Idx
])...
);
throw
stop_iteration
()
;
}
catch
(
bad_any_cast
)
{}
}
Action
_a
;
any
&
_arg
;
bool
&
_found
;
std
::
array
<
any
,
N
>&
_args
;
};
// recursion-free variadic version of for_each
template
<
class
...
>
struct
for_each_variadic
;
template
<
class
Action
>
struct
dispatch
template
<
class
F
,
class
...
Ts
>
struct
for_each_variadic
<
F
,
std
::
tuple
<
Ts
...
>>
{
dispatch
(
Action
a
,
any
*
args
,
bool
&
found
)
:
_a
(
a
),
_args
(
args
),
_found
(
found
)
{}
template
<
class
T
>
__attribute__
((
always_inline
))
auto
get_next
()
const
{
bind_arg
<
Action
,
T
>
a
(
_a
,
*
_args
,
_found
);
return
dispatch
<
bind_arg
<
Action
,
T
>>
(
a
,
_args
+
1
,
_found
);
}
template
<
class
T
>
__attribute__
((
always_inline
))
void
operator
()(
T
)
const
void
operator
()(
F
f
)
{
bind_arg
<
Action
,
T
>
a
(
_a
,
*
_args
,
_found
)
;
a
()
;
auto
call
=
[
&
](
auto
&&
arg
){
f
(
std
::
forward
<
decltype
(
arg
)
>
(
arg
));
return
0
;}
;
(
void
)
std
::
initializer_list
<
int
>
{
call
(
Ts
())...}
;
}
__attribute__
((
always_inline
))
void
operator
()()
const
{
_a
();
}
Action
_a
;
any
*
_args
;
bool
&
_found
;
};
template
<
class
F
>
inline
void
for_each_pack
(
F
)
{}
;
// convert mpl sequence to std::tuple
template
<
class
T
,
class
R
>
struct
to_tuple_imp
;
template
<
class
F
,
class
T
,
class
...
Ts
>
inline
void
for_each_pack
(
F
f
)
template
<
class
...
Ts
,
class
X
>
struct
to_tuple_imp
<
std
::
tuple
<
Ts
...
>
,
X
>
{
f
(
T
());
for_each_pack
<
F
,
Ts
...
>
(
f
);
typedef
std
::
tuple
<
Ts
...,
X
>
type
;
};
template
<
class
F
,
class
Seq
,
class
Iter
,
class
...
Ts
>
inline
void
for_each_alt
(
F
f
,
Iter
)
template
<
class
Seq
>
struct
to_tuple
{
for_each_alt
<
F
,
Seq
,
typename
next
<
Iter
>::
type
,
Ts
...,
typename
deref
<
Iter
>::
type
>
(
f
,
typename
next
<
Iter
>::
type
());
}
typedef
typename
mpl
::
fold
<
Seq
,
std
::
tuple
<>
,
to_tuple_imp
<
mpl
::
_1
,
mpl
::
_2
>>::
type
type
;
};
// nested type loops via variadic templates
template
<
class
...
>
struct
inner_loop
{};
template
<
class
F
,
class
Seq
,
class
Iter
,
class
...
Ts
>
inline
void
for_each_alt
(
F
f
,
typename
end
<
Seq
>::
type
)
template
<
class
Action
,
class
...
Ts
>
struct
inner_loop
<
Action
,
std
::
tuple
<
Ts
...
>>
{
for_each_pack
<
F
,
Ts
...
>
(
f
);
}
inner_loop
(
Action
a
)
:
_a
(
a
)
{}
template
<
class
TR1
,
class
...
TRS
,
class
Action
>
void
nested_for_each_imp
(
Action
a
);
template
<
class
T
>
__attribute__
((
always_inline
))
void
operator
()(
T
)
const
{
_a
(
Ts
()...,
T
());
}
// innermost loop
Action
_a
;
};
template
<
class
Action
,
class
...
TRS
>
struct
inner_loop
template
<
class
Action
,
class
...
Ts
,
class
TR1
,
class
...
TRS
>
struct
inner_loop
<
Action
,
std
::
tuple
<
Ts
...
>
,
TR1
,
TRS
...
>
{
inner_loop
(
Action
a
)
:
_a
(
a
)
{}
...
...
@@ -160,33 +150,32 @@ struct inner_loop
__attribute__
((
always_inline
))
void
operator
()(
T
)
const
{
nested_for_each_imp
<
TRS
...
>
(
_a
.
template
get_next
<
T
>());
typedef
inner_loop
<
Action
,
std
::
tuple
<
Ts
...,
T
>
,
TRS
...
>
inner_loop_t
;
typedef
typename
to_tuple
<
TR1
>::
type
tr_tuple
;
for_each_variadic
<
inner_loop_t
,
tr_tuple
>
()(
inner_loop_t
(
_a
));
}
Action
_a
;
};
template
<
class
TR1
,
class
...
TRS
,
class
Action
>
void
nested_for_each_imp
(
Action
a
)
{
for_each_alt
<
inner_loop
<
Action
,
TRS
...
>
,
TR1
,
typename
begin
<
TR1
>::
type
>
(
inner_loop
<
Action
,
TRS
...
>
(
a
),
typename
begin
<
TR1
>::
type
());
}
template
<
class
Action
>
void
nested_for_each_imp
(
Action
a
)
{
a
();
}
// final function
template
<
class
...
TRS
,
class
Action
,
class
...
Args
>
template
<
class
TR1
,
class
...
TRS
,
class
Action
,
class
...
Args
>
bool
nested_for_each
(
Action
a
,
Args
...
args
)
{
bool
found
=
false
;
std
::
array
<
any
,
sizeof
...(
args
)
>
as
{{
args
...}};
auto
b
=
dispatch
<
Action
>
(
a
,
&
as
[
0
],
found
);
nested_for_each_imp
<
TRS
...
>
(
b
);
return
found
;
auto
b
=
all_any_cast
<
Action
,
sizeof
...(
args
)
>
(
a
,
as
);
try
{
typedef
decltype
(
b
)
action_t
;
typedef
typename
to_tuple
<
TR1
>::
type
tr_tuple
;
typedef
inner_loop
<
action_t
,
std
::
tuple
<>
,
TRS
...
>
inner_loop_t
;
for_each_variadic
<
inner_loop_t
,
tr_tuple
>
()(
inner_loop_t
(
b
));
return
false
;
}
catch
(
stop_iteration
&
)
{
return
true
;
}
}
}
// mpl namespace
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new 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