Chris@16
|
1 // last_value function object (documented as part of Boost.Signals)
|
Chris@16
|
2
|
Chris@16
|
3 // Copyright Frank Mori Hess 2007.
|
Chris@16
|
4 // Copyright Douglas Gregor 2001-2003. Use, modification and
|
Chris@16
|
5 // distribution is subject to the Boost Software License, Version
|
Chris@16
|
6 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
7 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
8
|
Chris@16
|
9 // For more information, see http://www.boost.org
|
Chris@16
|
10
|
Chris@16
|
11 #ifndef BOOST_SIGNALS2_LAST_VALUE_HPP
|
Chris@16
|
12 #define BOOST_SIGNALS2_LAST_VALUE_HPP
|
Chris@16
|
13
|
Chris@16
|
14 #include <boost/optional.hpp>
|
Chris@16
|
15 #include <boost/signals2/expired_slot.hpp>
|
Chris@16
|
16 #include <boost/throw_exception.hpp>
|
Chris@16
|
17 #include <stdexcept>
|
Chris@16
|
18
|
Chris@16
|
19 namespace boost {
|
Chris@16
|
20 namespace signals2 {
|
Chris@16
|
21
|
Chris@16
|
22 // no_slots_error is thrown when we are unable to generate a return value
|
Chris@16
|
23 // due to no slots being connected to the signal.
|
Chris@16
|
24 class no_slots_error: public std::exception
|
Chris@16
|
25 {
|
Chris@16
|
26 public:
|
Chris@16
|
27 virtual const char* what() const throw() {return "boost::signals2::no_slots_error";}
|
Chris@16
|
28 };
|
Chris@16
|
29
|
Chris@16
|
30 template<typename T>
|
Chris@16
|
31 class last_value {
|
Chris@16
|
32 public:
|
Chris@16
|
33 typedef T result_type;
|
Chris@16
|
34
|
Chris@16
|
35 template<typename InputIterator>
|
Chris@16
|
36 T operator()(InputIterator first, InputIterator last) const
|
Chris@16
|
37 {
|
Chris@16
|
38 if(first == last)
|
Chris@16
|
39 {
|
Chris@16
|
40 boost::throw_exception(no_slots_error());
|
Chris@16
|
41 }
|
Chris@16
|
42 optional<T> value;
|
Chris@16
|
43 while (first != last)
|
Chris@16
|
44 {
|
Chris@16
|
45 try
|
Chris@16
|
46 {
|
Chris@16
|
47 value = *first;
|
Chris@16
|
48 }
|
Chris@16
|
49 catch(const expired_slot &) {}
|
Chris@16
|
50 ++first;
|
Chris@16
|
51 }
|
Chris@16
|
52 if(value) return value.get();
|
Chris@16
|
53 boost::throw_exception(no_slots_error());
|
Chris@16
|
54 }
|
Chris@16
|
55 };
|
Chris@16
|
56
|
Chris@16
|
57 template<>
|
Chris@16
|
58 class last_value<void> {
|
Chris@16
|
59 public:
|
Chris@16
|
60 typedef void result_type;
|
Chris@16
|
61 template<typename InputIterator>
|
Chris@16
|
62 result_type operator()(InputIterator first, InputIterator last) const
|
Chris@16
|
63 {
|
Chris@16
|
64 while (first != last)
|
Chris@16
|
65 {
|
Chris@16
|
66 try
|
Chris@16
|
67 {
|
Chris@16
|
68 *first;
|
Chris@16
|
69 }
|
Chris@16
|
70 catch(const expired_slot &) {}
|
Chris@16
|
71 ++first;
|
Chris@16
|
72 }
|
Chris@16
|
73 return;
|
Chris@16
|
74 }
|
Chris@16
|
75 };
|
Chris@16
|
76 } // namespace signals2
|
Chris@16
|
77 } // namespace boost
|
Chris@16
|
78 #endif // BOOST_SIGNALS2_LAST_VALUE_HPP
|