last_value.hpp 2.2 KB

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