capture_list.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #ifndef BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED
  2. #define BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED
  3. // Copyright 2018-2024 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. #include <boost/leaf/detail/print.hpp>
  8. #if BOOST_LEAF_CFG_CAPTURE
  9. #include <iosfwd>
  10. namespace boost { namespace leaf {
  11. class error_id;
  12. namespace detail
  13. {
  14. struct BOOST_LEAF_SYMBOL_VISIBLE tls_tag_id_factory_current_id;
  15. class capture_list
  16. {
  17. capture_list( capture_list const & ) = delete;
  18. capture_list & operator=( capture_list const & ) = delete;
  19. protected:
  20. class node
  21. {
  22. friend class capture_list;
  23. virtual void unload( int err_id ) = 0;
  24. #if BOOST_LEAF_CFG_DIAGNOSTICS
  25. virtual void print(std::ostream &, error_id const & to_print, char const * & prefix) const = 0;
  26. #endif
  27. protected:
  28. virtual ~node() noexcept
  29. {
  30. };
  31. node * next_;
  32. BOOST_LEAF_CONSTEXPR explicit node( node * * & last ) noexcept:
  33. next_(nullptr)
  34. {
  35. BOOST_LEAF_ASSERT(last != nullptr);
  36. *last = this;
  37. last = &next_;
  38. }
  39. } * first_;
  40. template <class F>
  41. BOOST_LEAF_CONSTEXPR void for_each( F f ) const
  42. {
  43. for( node * p=first_; p; p=p->next_ )
  44. f(*p);
  45. }
  46. public:
  47. BOOST_LEAF_CONSTEXPR explicit capture_list( node * first ) noexcept:
  48. first_(first)
  49. {
  50. }
  51. BOOST_LEAF_CONSTEXPR capture_list( capture_list && other ) noexcept:
  52. first_(other.first_)
  53. {
  54. other.first_ = nullptr;
  55. }
  56. ~capture_list() noexcept
  57. {
  58. for( node const * p = first_; p; )
  59. {
  60. node const * n = p -> next_;
  61. delete p;
  62. p = n;
  63. }
  64. }
  65. void unload( int const err_id )
  66. {
  67. capture_list moved(first_);
  68. first_ = nullptr;
  69. tls::write_uint<detail::tls_tag_id_factory_current_id>(unsigned(err_id));
  70. moved.for_each(
  71. [err_id]( node & n )
  72. {
  73. n.unload(err_id); // last node may throw
  74. } );
  75. }
  76. template <class CharT, class Traits>
  77. void print(std::basic_ostream<CharT, Traits> & os, error_id const & to_print, char const * & prefix) const
  78. {
  79. #if BOOST_LEAF_CFG_DIAGNOSTICS
  80. if( first_ )
  81. {
  82. for_each(
  83. [&os, &to_print, &prefix]( node const & n )
  84. {
  85. n.print(os, to_print, prefix);
  86. } );
  87. }
  88. #else
  89. (void) os;
  90. (void) prefix;
  91. (void) to_print;
  92. #endif
  93. }
  94. };
  95. }
  96. } }
  97. #endif
  98. #endif // BOOST_LEAF_DETAIL_CAPTURE_LIST_HPP_INCLUDED