last_value.hpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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/optional.hpp>
  12. #include <boost/signals2/expired_slot.hpp>
  13. #include <boost/throw_exception.hpp>
  14. #include <stdexcept>
  15. namespace boost {
  16. namespace signals2 {
  17. // no_slots_error is thrown when we are unable to generate a return value
  18. // due to no slots being connected to the signal.
  19. class no_slots_error: public std::exception
  20. {
  21. public:
  22. virtual const char* what() const throw() {return "boost::signals2::no_slots_error";}
  23. };
  24. template<typename T>
  25. class last_value {
  26. public:
  27. typedef T result_type;
  28. template<typename InputIterator>
  29. T operator()(InputIterator first, InputIterator last) const
  30. {
  31. if(first == last)
  32. {
  33. boost::throw_exception(no_slots_error());
  34. }
  35. optional<T> value;
  36. while (first != last)
  37. {
  38. BOOST_TRY
  39. {
  40. value = *first;
  41. }
  42. BOOST_CATCH(const expired_slot &) {}
  43. BOOST_CATCH_END
  44. ++first;
  45. }
  46. if(value) return value.get();
  47. boost::throw_exception(no_slots_error());
  48. }
  49. };
  50. template<>
  51. class last_value<void> {
  52. public:
  53. typedef void result_type;
  54. template<typename InputIterator>
  55. result_type operator()(InputIterator first, InputIterator last) const
  56. {
  57. while (first != last)
  58. {
  59. BOOST_TRY
  60. {
  61. *first;
  62. }
  63. BOOST_CATCH(const expired_slot &) {}
  64. BOOST_CATCH_END
  65. ++first;
  66. }
  67. return;
  68. }
  69. };
  70. } // namespace signals2
  71. } // namespace boost
  72. #endif // BOOST_SIGNALS2_LAST_VALUE_HPP