capture_list.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. #ifndef BOOST_LEAF_DETAIL_CAPTURE_HPP_INCLUDED
  2. #define BOOST_LEAF_DETAIL_CAPTURE_HPP_INCLUDED
  3. // Copyright 2018-2023 Emil Dotchevski and Reverge Studios, Inc.
  4. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. #include <boost/leaf/config.hpp>
  7. #if BOOST_LEAF_CFG_CAPTURE
  8. #include <iosfwd>
  9. namespace boost { namespace leaf {
  10. namespace leaf_detail
  11. {
  12. struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id;
  13. class capture_list
  14. {
  15. capture_list( capture_list const & ) = delete;
  16. capture_list & operator=( capture_list const & ) = delete;
  17. protected:
  18. class node
  19. {
  20. friend class capture_list;
  21. virtual void unload( int err_id ) = 0;
  22. #if BOOST_LEAF_CFG_DIAGNOSTICS
  23. virtual void print( std::ostream &, int err_id_to_print ) const = 0;
  24. #endif
  25. protected:
  26. virtual ~node() noexcept
  27. {
  28. };
  29. node * next_;
  30. BOOST_LEAF_CONSTEXPR explicit node( node * * & last ) noexcept:
  31. next_(nullptr)
  32. {
  33. BOOST_LEAF_ASSERT(last != nullptr);
  34. *last = this;
  35. last = &next_;
  36. }
  37. } * first_;
  38. template <class F>
  39. BOOST_LEAF_CONSTEXPR void for_each( F f ) const
  40. {
  41. for( node * p=first_; p; p=p->next_ )
  42. f(*p);
  43. }
  44. public:
  45. BOOST_LEAF_CONSTEXPR explicit capture_list( node * first ) noexcept:
  46. first_(first)
  47. {
  48. }
  49. BOOST_LEAF_CONSTEXPR capture_list( capture_list && other ) noexcept:
  50. first_(other.first_)
  51. {
  52. other.first_ = nullptr;
  53. }
  54. ~capture_list() noexcept
  55. {
  56. for( node const * p = first_; p; )
  57. {
  58. node const * n = p -> next_;
  59. delete p;
  60. p = n;
  61. }
  62. }
  63. void unload( int const err_id )
  64. {
  65. capture_list moved(first_);
  66. first_ = nullptr;
  67. tls::write_uint<leaf_detail::tls_tag_id_factory_current_id>(unsigned(err_id));
  68. moved.for_each(
  69. [err_id]( node & n )
  70. {
  71. n.unload(err_id); // last node may throw
  72. } );
  73. }
  74. template <class CharT, class Traits>
  75. void print( std::basic_ostream<CharT, Traits> & os, char const * title, int const err_id_to_print ) const
  76. {
  77. BOOST_LEAF_ASSERT(title != nullptr);
  78. #if BOOST_LEAF_CFG_DIAGNOSTICS
  79. if( first_ )
  80. {
  81. os << title;
  82. for_each(
  83. [&os, err_id_to_print]( node const & n )
  84. {
  85. n.print(os, err_id_to_print);
  86. } );
  87. }
  88. #else
  89. (void) os;
  90. (void) title;
  91. (void) err_id_to_print;
  92. #endif
  93. }
  94. };
  95. }
  96. } }
  97. #endif
  98. #endif