1212# pragma once
1313#endif
1414
15- #include < boost/aligned_storage.hpp>
16- #include < boost/core/explicit_operator_bool.hpp>
15+ #include < boost/core/noncopyable.hpp>
1716
1817#include < boost/iterator/iterator_facade.hpp>
1918#include < boost/assert.hpp>
2019
20+ #include < boost/aligned_storage.hpp>
21+ #include < boost/core/explicit_operator_bool.hpp>
22+
2123#include < iosfwd>
2224#include < string>
2325
8284
8385namespace boost { namespace stacktrace {
8486
85- class stacktrace ;
86-
87- class frame {
88- void * frame_no_;
89- public:
90- };
91-
92- // typedef std::string frame;
93-
94- // / @cond
95- namespace detail {
96-
97- class iterator : public boost ::iterator_facade<
98- iterator,
99- const frame,
100- boost::random_access_traversal_tag>
101- {
102- typedef boost::iterator_facade<
103- iterator,
104- const frame,
105- boost::random_access_traversal_tag
106- > base_t ;
107-
108- const stacktrace* impl_;
109- std::size_t frame_no_;
110-
111- iterator (const stacktrace* impl, std::size_t frame_no) BOOST_NOEXCEPT
112- : impl_(impl)
113- , frame_no_(frame_no)
114- {}
115-
116- friend class ::boost::stacktrace::stacktrace;
117- friend class ::boost::iterators::iterator_core_access;
118-
119- const frame& dereference () const ; /* {
120- return (*impl_)[frame_no_];
121- }*/
122-
123- bool equal (const iterator& it) const BOOST_NOEXCEPT {
124- return impl_ == it.impl_ && frame_no_ == it.frame_no_ ;
125- }
126-
127- void increment () BOOST_NOEXCEPT {
128- ++frame_no_;
129- }
130-
131- void decrement () BOOST_NOEXCEPT {
132- --frame_no_;
133- }
134-
135- void advance (std::size_t n) BOOST_NOEXCEPT {
136- frame_no_ += n;
137- }
138-
139- base_t ::difference_type distance_to (const iterator& it) const {
140- BOOST_ASSERT (impl_ == it.impl_ );
141- return it.frame_no_ - frame_no_;
142- }
143- public:
144-
145- };
146-
147- } // namespace detail
148- // / @endcond
149-
15087class stacktrace {
15188#ifdef BOOST_STACKTRACE_LINK
15289 BOOST_STATIC_CONSTEXPR std::size_t max_implementation_size = sizeof (void *) * 110u ;
15390 boost::aligned_storage<max_implementation_size>::type impl_;
15491#else
15592 boost::stacktrace::detail::backtrace_holder impl_;
15693#endif
157-
15894 std::size_t hash_code_;
15995
96+ BOOST_STACKTRACE_FUNCTION std::string get_name (std::size_t frame_no) const ;
97+ BOOST_STACKTRACE_FUNCTION std::string get_source_file (std::size_t frame_no) const ;
98+ BOOST_STACKTRACE_FUNCTION std::size_t get_source_line (std::size_t frame_no) const BOOST_NOEXCEPT;
99+
160100public:
101+ class frame {
102+ const stacktrace* impl_;
103+ const std::size_t frame_no_;
104+
105+ frame (const stacktrace* impl, std::size_t frame_no) BOOST_NOEXCEPT
106+ : impl_(impl)
107+ , frame_no_(frame_no)
108+ {}
109+
110+ friend class ::boost::stacktrace::stacktrace;
111+ public:
112+ std::string name () const ;
113+ std::string source_file () const ;
114+ std::size_t source_line () const BOOST_NOEXCEPT;
115+ };
116+
117+ class iterator : public boost ::iterator_facade<
118+ iterator,
119+ const frame,
120+ boost::random_access_traversal_tag,
121+ frame>
122+ {
123+ typedef boost::iterator_facade<
124+ iterator,
125+ const frame,
126+ boost::random_access_traversal_tag
127+ > base_t ;
128+
129+ const stacktrace* impl_;
130+ std::size_t frame_no_;
131+
132+ iterator (const stacktrace* impl, std::size_t frame_no) BOOST_NOEXCEPT
133+ : impl_(impl)
134+ , frame_no_(frame_no)
135+ {}
136+
137+ friend class ::boost::stacktrace::stacktrace;
138+ friend class ::boost::iterators::iterator_core_access;
139+
140+ frame dereference () const {
141+ return (*impl_)[frame_no_];
142+ }
143+
144+ bool equal (const iterator& it) const BOOST_NOEXCEPT {
145+ return impl_ == it.impl_ && frame_no_ == it.frame_no_ ;
146+ }
147+
148+ void increment () BOOST_NOEXCEPT {
149+ ++frame_no_;
150+ }
151+
152+ void decrement () BOOST_NOEXCEPT {
153+ --frame_no_;
154+ }
155+
156+ void advance (std::size_t n) BOOST_NOEXCEPT {
157+ frame_no_ += n;
158+ }
159+
160+ base_t ::difference_type distance_to (const iterator& it) const {
161+ BOOST_ASSERT (impl_ == it.impl_ );
162+ return it.frame_no_ - frame_no_;
163+ }
164+ };
165+
161166 typedef frame value_type;
162- typedef boost::stacktrace::detail::iterator iterator;
163167 typedef iterator const_iterator;
164168 typedef std::reverse_iterator<iterator> reverse_iterator;
165169 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -200,7 +204,9 @@ class stacktrace {
200204 // / @throws std::bad_alloc if not enough memory to construct resulting string.
201205 // /
202206 // / @b Complexity: Amortized O(1), O(1) for noop backend.
203- BOOST_STACKTRACE_FUNCTION std::string operator [](std::size_t frame_no) const ;
207+ frame operator [](std::size_t frame_no) const {
208+ return frame (this , frame_no);
209+ }
204210
205211 // / @cond
206212 bool operator !() const BOOST_NOEXCEPT {
@@ -232,6 +238,17 @@ class stacktrace {
232238 }
233239};
234240
241+ inline std::string stacktrace::frame::name () const {
242+ return impl_->get_name (frame_no_);
243+ }
244+ inline std::string stacktrace::frame::source_file () const {
245+ return impl_->get_source_file (frame_no_);
246+ }
247+ inline std::size_t stacktrace::frame::source_line () const BOOST_NOEXCEPT {
248+ return impl_->get_source_line (frame_no_);
249+ }
250+
251+
235252// / Additional comparison operators for stacktraces that have amortized O(1) complexity.
236253inline bool operator > (const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return rhs < lhs; }
237254inline bool operator <=(const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return !(lhs > rhs); }
@@ -243,6 +260,12 @@ inline std::size_t hash_value(const stacktrace& st) BOOST_NOEXCEPT {
243260 return st.hash_code ();
244261}
245262
263+ // / Outputs stacktrace in a human readable format to output stream.
264+ template <class CharT , class TraitsT >
265+ std::basic_ostream<CharT, TraitsT>& operator <<(std::basic_ostream<CharT, TraitsT>& os, const stacktrace::frame& f) {
266+ return os << f.name ();
267+ }
268+
246269// / Outputs stacktrace in a human readable format to output stream.
247270template <class CharT , class TraitsT >
248271std::basic_ostream<CharT, TraitsT>& operator <<(std::basic_ostream<CharT, TraitsT>& os, const stacktrace& bt) {
0 commit comments