$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r73669 - in trunk: boost/fusion/algorithm/query/ext_ libs/fusion/test/algorithm/ext_
From: eric_at_[hidden]
Date: 2011-08-11 13:49:03
Author: eric_niebler
Date: 2011-08-11 13:49:02 EDT (Thu, 11 Aug 2011)
New Revision: 73669
URL: http://svn.boost.org/trac/boost/changeset/73669
Log:
fix find_s and find_if_s to return the end iterator when item not found
Text files modified: 
   trunk/boost/fusion/algorithm/query/ext_/find_if_s.hpp |    41 ++++++++++++++++++++++++++++++++++----  
   trunk/boost/fusion/algorithm/query/ext_/find_s.hpp    |    42 +++++++++++++++++++++++++++++++++++---- 
   trunk/libs/fusion/test/algorithm/ext_/find_if_s.cpp   |     7 ++++++                                  
   trunk/libs/fusion/test/algorithm/ext_/find_s.cpp      |     7 ++++++                                  
   4 files changed, 87 insertions(+), 10 deletions(-)
Modified: trunk/boost/fusion/algorithm/query/ext_/find_if_s.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/query/ext_/find_if_s.hpp	(original)
+++ trunk/boost/fusion/algorithm/query/ext_/find_if_s.hpp	2011-08-11 13:49:02 EDT (Thu, 11 Aug 2011)
@@ -9,6 +9,7 @@
 
 #include <boost/type_traits/remove_const.hpp>
 #include <boost/fusion/algorithm/query/find_if.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
 #include <boost/fusion/view/ext_/segmented_fold_until.hpp>
 
 namespace boost { namespace fusion { namespace detail
@@ -39,7 +40,7 @@
                         iterator_type,
                         typename result_of::end<Range>::type
                     >,
-                    fusion::result<segmented_iterator_type, continue_>, // NOT FOUND
+                    fusion::result<typename remove_const<State>::type, continue_>, // NOT FOUND
                     fusion::result<segmented_iterator_type, break_>     // FOUND
                 >::type
             type;
@@ -47,7 +48,29 @@
 
         template<typename Range, typename State, typename Context>
         typename result<segmented_find_if_fun(Range&, State const&, Context const&)>::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<Range, Pred>::type,
+                    typename result_of::end<Range>::type
+                >::type
+            not_found;
+
+            return call(rng, state, context, not_found());
+        }
+
+    private:
+        template<typename Range, typename State, typename Context>
+        typename result<segmented_find_if_fun(Range&, State const&, Context const&)>::type
+        call(Range&, State const& state, Context const&, mpl::true_) const
+        {
+            return state;
+        }
+
+        template<typename Range, typename State, typename Context>
+        typename result<segmented_find_if_fun(Range&, State const&, Context const&)>::type
+        call(Range& rng, State const&, Context const& context, mpl::false_) const
         {
             return fusion::make_segmented_iterator(fusion::find_if<Pred>(rng), context);
         }
@@ -61,7 +84,10 @@
     {
         template <typename Sequence, typename Pred>
         struct find_if_s
-          : result_of::segmented_fold_until<Sequence, void_, detail::segmented_find_if_fun<Pred> >
+          : result_of::segmented_fold_until<
+                Sequence,
+                typename result_of::end<Sequence>::type,
+                detail::segmented_find_if_fun<Pred> >
         {};
     }
 
@@ -69,14 +95,19 @@
     typename result_of::find_if_s<Sequence, Pred>::type
     find_if_s(Sequence& seq)
     {
-        return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_if_fun<Pred>());
+        return fusion::segmented_fold_until(
+            seq,
+            fusion::end(seq),
+            detail::segmented_find_if_fun<Pred>());
     }
 
     template <typename Pred, typename Sequence>
     typename result_of::find_if_s<Sequence const, Pred>::type
     find_if_s(Sequence const& seq)
     {
-        return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_if_fun<Pred>());
+        return fusion::segmented_fold_until(
+            seq, fusion::end(seq),
+            detail::segmented_find_if_fun<Pred>());
     }
 }}
 
Modified: trunk/boost/fusion/algorithm/query/ext_/find_s.hpp
==============================================================================
--- trunk/boost/fusion/algorithm/query/ext_/find_s.hpp	(original)
+++ trunk/boost/fusion/algorithm/query/ext_/find_s.hpp	2011-08-11 13:49:02 EDT (Thu, 11 Aug 2011)
@@ -9,6 +9,7 @@
 
 #include <boost/type_traits/remove_const.hpp>
 #include <boost/fusion/algorithm/query/find.hpp>
+#include <boost/fusion/sequence/intrinsic/end.hpp>
 #include <boost/fusion/view/ext_/segmented_fold_until.hpp>
 
 namespace boost { namespace fusion { namespace detail
@@ -39,7 +40,7 @@
                         iterator_type,
                         typename result_of::end<Range>::type
                     >,
-                    fusion::result<segmented_iterator_type, continue_>, // NOT FOUND
+                    fusion::result<typename remove_const<State>::type, continue_>, // NOT FOUND
                     fusion::result<segmented_iterator_type, break_>     // FOUND
                 >::type
             type;
@@ -47,7 +48,29 @@
 
         template<typename Range, typename State, typename Context>
         typename result<segmented_find_fun(Range&, State const&, Context const&)>::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<Range, T>::type,
+                    typename result_of::end<Range>::type
+                >::type
+            not_found;
+
+            return call(rng, state, context, not_found());
+        }
+
+    private:
+        template<typename Range, typename State, typename Context>
+        typename result<segmented_find_fun(Range&, State const&, Context const&)>::type
+        call(Range&, State const&state, Context const&, mpl::true_) const
+        {
+            return state;
+        }
+
+        template<typename Range, typename State, typename Context>
+        typename result<segmented_find_fun(Range&, State const&, Context const&)>::type
+        call(Range& rng, State const&, Context const& context, mpl::false_) const
         {
             return fusion::make_segmented_iterator(fusion::find<T>(rng), context);
         }
@@ -61,7 +84,10 @@
     {
         template <typename Sequence, typename T>
         struct find_s
-          : result_of::segmented_fold_until<Sequence, void_, detail::segmented_find_fun<T> >
+          : result_of::segmented_fold_until<
+                Sequence,
+                typename result_of::end<Sequence>::type,
+                detail::segmented_find_fun<T> >
         {};
     }
 
@@ -69,14 +95,20 @@
     typename result_of::find_s<Sequence, T>::type
     find_s(Sequence& seq)
     {
-        return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_fun<T>());
+        return fusion::segmented_fold_until(
+            seq,
+            fusion::end(seq),
+            detail::segmented_find_fun<T>());
     }
 
     template <typename T, typename Sequence>
     typename result_of::find_s<Sequence const, T>::type
     find_s(Sequence const& seq)
     {
-        return fusion::segmented_fold_until(seq, void_(), detail::segmented_find_fun<T>());
+        return fusion::segmented_fold_until(
+            seq,
+            fusion::end(seq),
+            detail::segmented_find_fun<T>());
     }
 }}
 
Modified: trunk/libs/fusion/test/algorithm/ext_/find_if_s.cpp
==============================================================================
--- trunk/libs/fusion/test/algorithm/ext_/find_if_s.cpp	(original)
+++ trunk/libs/fusion/test/algorithm/ext_/find_if_s.cpp	2011-08-11 13:49:02 EDT (Thu, 11 Aug 2011)
@@ -13,6 +13,8 @@
 #include <boost/mpl/placeholders.hpp>
 #include <boost/type_traits/is_same.hpp>
 
+struct not_there {};
+
 template<typename Tree>
 void 
 process_tree(Tree const &tree)
@@ -22,6 +24,7 @@
 
     typedef typename fusion::result_of::find_if_s<Tree const, is_same<_,short> >::type short_iter;
     typedef typename fusion::result_of::find_if_s<Tree const, is_same<_,float> >::type float_iter;
+    typedef typename fusion::result_of::find_if_s<Tree const, is_same<_,not_there> >::type not_there_iter;
 
     // find_if_s of a segmented data structure returns generic
     // segmented iterators
@@ -31,6 +34,10 @@
     // 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<is_same<_,not_there> >(tree);
+    BOOST_TEST((nti == fusion::end(tree)));
 }
 
 int
Modified: trunk/libs/fusion/test/algorithm/ext_/find_s.cpp
==============================================================================
--- trunk/libs/fusion/test/algorithm/ext_/find_s.cpp	(original)
+++ trunk/libs/fusion/test/algorithm/ext_/find_s.cpp	2011-08-11 13:49:02 EDT (Thu, 11 Aug 2011)
@@ -11,6 +11,8 @@
 #include <boost/fusion/container/ext_/tree.hpp>
 #include <boost/fusion/container/generation/make_vector.hpp>
 
+struct not_there {};
+
 template<typename Tree>
 void 
 process_tree(Tree const &tree)
@@ -19,6 +21,7 @@
 
     typedef typename fusion::result_of::find_s<Tree const, short>::type short_iter;
     typedef typename fusion::result_of::find_s<Tree const, float>::type float_iter;
+    typedef typename fusion::result_of::find_s<Tree const, not_there>::type not_there_iter;
 
     // find_if_s of a segmented data structure returns generic
     // segmented iterators
@@ -28,6 +31,10 @@
     // 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<not_there>(tree);
+    BOOST_TEST((nti == fusion::end(tree)));
 }
 
 int