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