Skip to content

Commit b8dcd2b

Browse files
committed
Working version of iterator and frame
1 parent bd59ec8 commit b8dcd2b

4 files changed

Lines changed: 115 additions & 75 deletions

File tree

include/boost/stacktrace.hpp

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
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

@@ -82,84 +84,86 @@
8284

8385
namespace 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-
15087
class 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+
160100
public:
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.
236253
inline bool operator> (const stacktrace& lhs, const stacktrace& rhs) BOOST_NOEXCEPT { return rhs < lhs; }
237254
inline 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.
247270
template <class CharT, class TraitsT>
248271
std::basic_ostream<CharT, TraitsT>& operator<<(std::basic_ostream<CharT, TraitsT>& os, const stacktrace& bt) {

include/boost/stacktrace/detail/stacktrace.ipp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,19 @@ std::size_t stacktrace::size() const BOOST_NOEXCEPT {
5151
return impl_.size();
5252
}
5353

54-
std::string stacktrace::operator[](std::size_t frame) const {
54+
std::string stacktrace::get_name(std::size_t frame) const {
5555
return impl_.get_frame(frame);
5656
}
5757

58+
59+
std::string stacktrace::get_source_file(std::size_t frame) const {
60+
return std::string();
61+
}
62+
63+
std::size_t stacktrace::get_source_line(std::size_t frame) const BOOST_NOEXCEPT {
64+
return 0;
65+
}
66+
5867
bool stacktrace::operator< (const stacktrace& rhs) const BOOST_NOEXCEPT {
5968
return hash_code_ < rhs.hash_code_ || (hash_code_ == rhs.hash_code_ && impl_ < rhs.impl_);
6069
}

src/stacktrace_src.ipp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,18 @@ std::size_t stacktrace::size() const BOOST_NOEXCEPT {
6666
return boost::stacktrace::detail::to_bt(impl_).size();
6767
}
6868

69-
std::string stacktrace::operator[](std::size_t frame) const {
69+
std::string stacktrace::get_name(std::size_t frame) const {
7070
return boost::stacktrace::detail::to_bt(impl_).get_frame(frame);
7171
}
7272

73+
std::string stacktrace::get_source_file(std::size_t frame) const {
74+
return std::string();
75+
}
76+
77+
std::size_t stacktrace::get_source_line(std::size_t frame) const BOOST_NOEXCEPT {
78+
return 0;
79+
}
80+
7381
bool stacktrace::operator< (const stacktrace& rhs) const BOOST_NOEXCEPT {
7482
return hash_code_ < rhs.hash_code_
7583
|| (hash_code_ == rhs.hash_code_ && boost::stacktrace::detail::to_bt(impl_) < boost::stacktrace::detail::to_bt(rhs.impl_))

test/test_noop.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ BOOST_SYMBOL_IMPORT stacktrace return_from_nested_namespaces();
1515

1616
void test_deeply_nested_namespaces() {
1717
BOOST_TEST(return_from_nested_namespaces().size() == 0);
18-
BOOST_TEST(return_from_nested_namespaces()[0] == "");
18+
BOOST_TEST(return_from_nested_namespaces()[0].name() == "");
1919
}
2020

2121
void test_nested() {
2222
std::pair<stacktrace, stacktrace> res = foo2(15);
2323

2424
BOOST_TEST(res.first.size() == 0);
25-
BOOST_TEST(res.first[0] == "");
25+
BOOST_TEST(res.first[0].name() == "");
2626
BOOST_TEST(res.second.size() == 0);
27-
BOOST_TEST(res.second[0] == "");
27+
BOOST_TEST(res.second[0].name() == "");
2828
}
2929

3030

0 commit comments

Comments
 (0)