Skip to content

Commit f0a8656

Browse files
committed
interop with boost::intrusive_ptr
1 parent c465260 commit f0a8656

File tree

11 files changed

+1041
-86
lines changed

11 files changed

+1041
-86
lines changed

CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,21 +92,30 @@ set(
9292
Boost::preprocessor
9393
)
9494

95+
if (BOOST_OPENMETHOD_BUILD_TESTS OR BOOST_OPENMETHOD_MRDOCS_BUILD)
96+
list(APPEND BOOST_OPENMETHOD_DEPENDENCIES Boost::smart_ptr)
97+
endif()
9598

9699
foreach (BOOST_OPENMETHOD_DEPENDENCY ${BOOST_OPENMETHOD_DEPENDENCIES})
97100
if (BOOST_OPENMETHOD_DEPENDENCY MATCHES "^[ ]*Boost::([A-Za-z0-9_]+)[ ]*$")
98101
list(APPEND BOOST_OPENMETHOD_INCLUDE_LIBRARIES ${CMAKE_MATCH_1})
99102
endif ()
100103
endforeach ()
104+
101105
# Conditional dependencies
106+
if (BOOST_OPENMETHOD_MRDOCS_BUILD)
107+
list(APPEND BOOST_OPENMETHOD_INCLUDE_LIBRARIES smart_ptr)
108+
endif()
109+
102110
if (NOT BOOST_OPENMETHOD_MRDOCS_BUILD)
103-
if (BUILD_TESTING OR BOOST_OPENMETHOD_BUILD_TESTS)
111+
if (BOOST_OPENMETHOD_BUILD_TESTS)
104112
set(BOOST_OPENMETHOD_UNIT_TEST_LIBRARIES test)
105113
if (BOOST_OPENMETHOD_BUILD_EXAMPLES)
106114
set(BOOST_OPENMETHOD_EXAMPLE_LIBRARIES dll)
107115
endif()
108116
endif()
109117
endif()
118+
110119
# Complete dependency list
111120
set(BOOST_INCLUDE_LIBRARIES ${BOOST_OPENMETHOD_INCLUDE_LIBRARIES} ${BOOST_OPENMETHOD_UNIT_TEST_LIBRARIES} ${BOOST_OPENMETHOD_EXAMPLE_LIBRARIES})
112121
set(BOOST_EXCLUDE_LIBRARIES openmethod)

doc/modules/ROOT/examples/matrix.cpp

Lines changed: 83 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -3,146 +3,153 @@
33
// See accompanying file LICENSE_1_0.txt
44
// or copy at http://www.boost.org/LICENSE_1_0.txt)
55

6+
// https://godbolt.org/z/r6o4f171r
7+
68
#include <iostream>
79
#include <memory>
810
#include <string>
911
#include <typeinfo>
1012

1113
#include <boost/openmethod.hpp>
14+
#include <boost/openmethod/policies/static_rtti.hpp>
1215
#include <boost/openmethod/initialize.hpp>
13-
#include <boost/openmethod/interop/std_shared_ptr.hpp>
1416

15-
using std::make_shared;
16-
using std::shared_ptr;
1717
using std::string;
1818

19-
using boost::openmethod::make_shared_virtual;
20-
using boost::openmethod::shared_virtual_ptr;
21-
using boost::openmethod::virtual_ptr;
19+
using namespace boost::openmethod::aliases;
2220

23-
struct matrix {
24-
virtual ~matrix() {
25-
}
26-
virtual auto at(int row, int col) const -> double = 0;
27-
// ...
21+
struct abstract {
22+
int ref_count = 0;
2823
};
2924

30-
struct dense_matrix : matrix {
31-
virtual auto at(int /*row*/, int /*col*/) const -> double {
32-
return 0;
25+
struct registry
26+
: boost::openmethod::registry<boost::openmethod::policies::static_rtti> {};
27+
28+
template<class Rep>
29+
using matrix_ptr = boost::openmethod::virtual_ptr<Rep, registry>;
30+
31+
BOOST_OPENMETHOD(destroy, (matrix_ptr<abstract>), void, registry);
32+
33+
class matrix {
34+
matrix_ptr<abstract> rep_;
35+
36+
explicit matrix(matrix_ptr<abstract> rep) : rep_(rep) {
37+
++rep_->ref_count;
38+
39+
if (--rep->ref_count == 0) {
40+
destroy(rep);
41+
}
3342
}
34-
};
3543

36-
struct diagonal_matrix : matrix {
37-
virtual auto at(int /*row*/, int /*col*/) const -> double {
38-
return 0;
44+
public:
45+
matrix(const matrix&) = default;
46+
matrix& operator=(const matrix&) = default;
47+
48+
auto rep() const -> matrix_ptr<abstract> {
49+
return rep_;
3950
}
40-
};
4151

42-
BOOST_OPENMETHOD_CLASSES(matrix, dense_matrix, diagonal_matrix);
52+
template<class Rep, class... Args>
53+
static matrix make(Args&&... args) {
54+
return matrix(
55+
boost::openmethod::final_virtual_ptr<registry>(
56+
*new Rep(std::forward<Args>(args)...)));
57+
}
58+
};
4359

44-
BOOST_OPENMETHOD(to_json, (virtual_ptr<const matrix>), string);
60+
struct dense : abstract {
61+
static constexpr const char* type = "dense";
62+
};
4563

46-
BOOST_OPENMETHOD_OVERRIDE(to_json, (virtual_ptr<const dense_matrix>), string) {
47-
return "json for dense matrix...";
64+
BOOST_OPENMETHOD_OVERRIDE(destroy, (matrix_ptr<dense> rep), void) {
65+
delete rep.get();
4866
}
4967

50-
BOOST_OPENMETHOD_OVERRIDE(
51-
to_json, (virtual_ptr<const diagonal_matrix>), string) {
52-
return "json for diagonal matrix...";
68+
struct diagonal : abstract {
69+
static constexpr const char* type = "diagonal";
70+
};
71+
72+
BOOST_OPENMETHOD_OVERRIDE(destroy, (matrix_ptr<diagonal> rep), void) {
73+
delete rep.get();
5374
}
5475

76+
BOOST_OPENMETHOD_CLASSES(abstract, dense, diagonal, registry);
77+
5578
// -----------------------------------------------------------------------------
5679
// matrix * matrix
5780

5881
BOOST_OPENMETHOD(
59-
times, (shared_virtual_ptr<const matrix>, shared_virtual_ptr<const matrix>),
60-
shared_virtual_ptr<const matrix>);
82+
times, (matrix_ptr<abstract>, matrix_ptr<abstract>), matrix, registry);
6183

62-
// catch-all matrix * matrix -> dense_matrix
84+
// catch-all matrix * matrix -> dense
6385
BOOST_OPENMETHOD_OVERRIDE(
64-
times,
65-
(shared_virtual_ptr<const matrix> /*a*/,
66-
shared_virtual_ptr<const matrix> /*b*/),
67-
shared_virtual_ptr<const dense_matrix>) {
68-
return make_shared<const dense_matrix>();
86+
times, (matrix_ptr<abstract> /*a*/, matrix_ptr<abstract> /*b*/), matrix) {
87+
return matrix::make<dense>();
6988
}
7089

71-
// diagonal_matrix * diagonal_matrix -> diagonal_matrix
90+
// diagonal * diagonal -> diagonal
7291
BOOST_OPENMETHOD_OVERRIDE(
73-
times,
74-
(shared_virtual_ptr<const diagonal_matrix> /*a*/,
75-
shared_virtual_ptr<const diagonal_matrix> /*b*/),
76-
shared_virtual_ptr<const diagonal_matrix>) {
77-
return make_shared_virtual<diagonal_matrix>();
92+
times, (matrix_ptr<diagonal> /*a*/, matrix_ptr<diagonal> /*b*/), matrix) {
93+
return matrix::make<diagonal>();
7894
}
7995

80-
inline auto operator*(shared_ptr<const matrix> a, shared_ptr<const matrix> b)
81-
-> shared_virtual_ptr<const matrix> {
82-
return times(a, b);
96+
inline auto operator*(matrix a, matrix b) -> matrix {
97+
return times(a.rep(), b.rep());
8398
}
8499

85100
// -----------------------------------------------------------------------------
86101
// scalar * matrix
87102

88-
BOOST_OPENMETHOD(
89-
times, (double, shared_virtual_ptr<const matrix>),
90-
shared_virtual_ptr<const matrix>);
103+
BOOST_OPENMETHOD(times, (double, matrix_ptr<abstract>), matrix, registry);
91104

92-
// catch-all matrix * scalar -> dense_matrix
105+
// catch-all matrix * scalar -> dense
93106
BOOST_OPENMETHOD_OVERRIDE(
94-
times, (double /*a*/, shared_virtual_ptr<const matrix> /*b*/),
95-
shared_virtual_ptr<const dense_matrix>) {
96-
return make_shared_virtual<dense_matrix>();
107+
times, (double /*a*/, matrix_ptr<abstract> /*b*/), matrix) {
108+
return matrix::make<dense>();
97109
}
98110

99111
BOOST_OPENMETHOD_OVERRIDE(
100-
times, (double /*a*/, shared_virtual_ptr<const diagonal_matrix> /*b*/),
101-
shared_virtual_ptr<const diagonal_matrix>) {
102-
return make_shared_virtual<diagonal_matrix>();
112+
times, (double /*a*/, matrix_ptr<diagonal> /*b*/), matrix) {
113+
return matrix::make<diagonal>();
103114
}
104115

105116
// -----------------------------------------------------------------------------
106117
// matrix * scalar
107118

108119
// just swap
109-
inline auto times(shared_virtual_ptr<const matrix> a, double b)
110-
-> shared_virtual_ptr<const matrix> {
120+
inline auto times(matrix_ptr<abstract> a, double b) -> matrix {
111121
return times(b, a);
112122
}
113123

114124
// -----------------------------------------------------------------------------
115125
// main
116126

117-
#define check(expr) \
118-
{ \
119-
if (!(expr)) { \
120-
cerr << #expr << " failed\n"; \
121-
} \
122-
}
127+
BOOST_OPENMETHOD(write, (matrix_ptr<abstract>), string, registry);
128+
129+
inline auto operator<<(std::ostream& os, matrix a) -> std::ostream& {
130+
return os << write(a.rep());
131+
}
132+
133+
BOOST_OPENMETHOD_OVERRIDE(write, (matrix_ptr<dense>), string) {
134+
return "a dense matrix";
135+
}
136+
137+
BOOST_OPENMETHOD_OVERRIDE(write, (matrix_ptr<diagonal>), string) {
138+
return "a diagonal matrix";
139+
}
123140

124141
auto main() -> int {
125142
using std::cerr;
126143
using std::cout;
127144

128-
boost::openmethod::initialize();
145+
boost::openmethod::initialize<registry>();
129146

130-
shared_ptr<const matrix> a = make_shared<dense_matrix>();
131-
shared_ptr<const matrix> b = make_shared<diagonal_matrix>();
147+
matrix a = matrix::make<dense>();
148+
matrix b = matrix::make<diagonal>();
132149
double s = 1;
133150

134-
#ifdef BOOST_CLANG
135-
#pragma clang diagnostic ignored "-Wpotentially-evaluated-expression"
136-
#endif
137-
138-
check(typeid(*times(a, a)) == typeid(dense_matrix));
139-
check(typeid(*times(a, b)) == typeid(dense_matrix));
140-
check(typeid(*times(b, b)) == typeid(diagonal_matrix));
141-
check(typeid(*times(s, a)) == typeid(dense_matrix));
142-
check(typeid(*times(s, b)) == typeid(diagonal_matrix));
143-
144-
cout << to_json(*a) << "\n"; // json for dense matrix
145-
cout << to_json(*b) << "\n"; // json for diagonal matrix
151+
cout << a << "\n";
152+
cout << b << "\n";
146153

147154
return 0;
148155
}

0 commit comments

Comments
 (0)