diff --git a/include/boost/fusion/algorithm/query/ext_/find_if_s.hpp b/include/boost/fusion/algorithm/query/ext_/find_if_s.hpp index 85c1fd86..70a484cc 100644 --- a/include/boost/fusion/algorithm/query/ext_/find_if_s.hpp +++ b/include/boost/fusion/algorithm/query/ext_/find_if_s.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace boost { namespace fusion { namespace detail @@ -39,7 +40,7 @@ namespace boost { namespace fusion { namespace detail iterator_type, typename result_of::end::type >, - fusion::result, // NOT FOUND + fusion::result::type, continue_>, // NOT FOUND fusion::result // FOUND >::type type; @@ -47,7 +48,29 @@ namespace boost { namespace fusion { namespace detail template typename result::type - operator()(Range& rng, State const&, Context const& context) const + operator()(Range& rng, State const& state, Context const& context) const + { + typedef + typename result_of::equal_to< + typename result_of::find_if::type, + typename result_of::end::type + >::type + not_found; + + return call(rng, state, context, not_found()); + } + + private: + template + typename result::type + call(Range&, State const& state, Context const&, mpl::true_) const + { + return state; + } + + template + typename result::type + call(Range& rng, State const&, Context const& context, mpl::false_) const { return fusion::make_segmented_iterator(fusion::find_if(rng), context); } @@ -61,7 +84,10 @@ namespace boost { namespace fusion { template struct find_if_s - : result_of::segmented_fold_until > + : result_of::segmented_fold_until< + Sequence, + typename result_of::end::type, + detail::segmented_find_if_fun > {}; } @@ -69,14 +95,19 @@ namespace boost { namespace fusion typename result_of::find_if_s::type find_if_s(Sequence& seq) { - return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_if_fun()); + return fusion::segmented_fold_until( + seq, + fusion::end(seq), + detail::segmented_find_if_fun()); } template typename result_of::find_if_s::type find_if_s(Sequence const& seq) { - return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_if_fun()); + return fusion::segmented_fold_until( + seq, fusion::end(seq), + detail::segmented_find_if_fun()); } }} diff --git a/include/boost/fusion/algorithm/query/ext_/find_s.hpp b/include/boost/fusion/algorithm/query/ext_/find_s.hpp index 8ccf202d..f95a230a 100644 --- a/include/boost/fusion/algorithm/query/ext_/find_s.hpp +++ b/include/boost/fusion/algorithm/query/ext_/find_s.hpp @@ -9,6 +9,7 @@ #include #include +#include #include namespace boost { namespace fusion { namespace detail @@ -39,7 +40,7 @@ namespace boost { namespace fusion { namespace detail iterator_type, typename result_of::end::type >, - fusion::result, // NOT FOUND + fusion::result::type, continue_>, // NOT FOUND fusion::result // FOUND >::type type; @@ -47,7 +48,29 @@ namespace boost { namespace fusion { namespace detail template typename result::type - operator()(Range& rng, State const&, Context const& context) const + operator()(Range& rng, State const&state, Context const& context) const + { + typedef + typename result_of::equal_to< + typename result_of::find::type, + typename result_of::end::type + >::type + not_found; + + return call(rng, state, context, not_found()); + } + + private: + template + typename result::type + call(Range&, State const&state, Context const&, mpl::true_) const + { + return state; + } + + template + typename result::type + call(Range& rng, State const&, Context const& context, mpl::false_) const { return fusion::make_segmented_iterator(fusion::find(rng), context); } @@ -61,7 +84,10 @@ namespace boost { namespace fusion { template struct find_s - : result_of::segmented_fold_until > + : result_of::segmented_fold_until< + Sequence, + typename result_of::end::type, + detail::segmented_find_fun > {}; } @@ -69,14 +95,20 @@ namespace boost { namespace fusion typename result_of::find_s::type find_s(Sequence& seq) { - return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_fun()); + return fusion::segmented_fold_until( + seq, + fusion::end(seq), + detail::segmented_find_fun()); } template typename result_of::find_s::type find_s(Sequence const& seq) { - return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_fun()); + return fusion::segmented_fold_until( + seq, + fusion::end(seq), + detail::segmented_find_fun()); } }} diff --git a/test/algorithm/ext_/find_if_s.cpp b/test/algorithm/ext_/find_if_s.cpp index 805fd599..d25dc0e6 100644 --- a/test/algorithm/ext_/find_if_s.cpp +++ b/test/algorithm/ext_/find_if_s.cpp @@ -13,6 +13,8 @@ #include #include +struct not_there {}; + template void process_tree(Tree const &tree) @@ -22,6 +24,7 @@ process_tree(Tree const &tree) typedef typename fusion::result_of::find_if_s >::type short_iter; typedef typename fusion::result_of::find_if_s >::type float_iter; + typedef typename fusion::result_of::find_if_s >::type not_there_iter; // find_if_s of a segmented data structure returns generic // segmented iterators @@ -31,6 +34,10 @@ process_tree(Tree const &tree) // they behave like ordinary Fusion iterators ... BOOST_TEST((*si == short('d'))); BOOST_TEST((*fi == float(1))); + + // Searching for something that's not there should return the end iterator. + not_there_iter nti = fusion::find_if_s >(tree); + BOOST_TEST((nti == fusion::end(tree))); } int diff --git a/test/algorithm/ext_/find_s.cpp b/test/algorithm/ext_/find_s.cpp index be5d332e..6c7428b8 100644 --- a/test/algorithm/ext_/find_s.cpp +++ b/test/algorithm/ext_/find_s.cpp @@ -11,6 +11,8 @@ #include #include +struct not_there {}; + template void process_tree(Tree const &tree) @@ -19,6 +21,7 @@ process_tree(Tree const &tree) typedef typename fusion::result_of::find_s::type short_iter; typedef typename fusion::result_of::find_s::type float_iter; + typedef typename fusion::result_of::find_s::type not_there_iter; // find_if_s of a segmented data structure returns generic // segmented iterators @@ -28,6 +31,10 @@ process_tree(Tree const &tree) // they behave like ordinary Fusion iterators ... BOOST_TEST((*si == short('d'))); BOOST_TEST((*fi == float(1))); + + // Searching for something that's not there should return the end iterator. + not_there_iter nti = fusion::find_s(tree); + BOOST_TEST((nti == fusion::end(tree))); } int