Skip to content

Commit ad62203

Browse files
authored
CXX-3232 add bsoncxx v1 declarations (#1412)
1 parent bccac0e commit ad62203

File tree

26 files changed

+3354
-57
lines changed

26 files changed

+3354
-57
lines changed

.evergreen/scripts/abidiff-test.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ echo "---" >>cxx-noabi/mongocxx.txt
5454

5555
# Allow task to upload the diff reports despite failed status.
5656
echo "Comparing stable ABI for bsoncxx..."
57-
if ! abidiff "${abi_flags[@]:?}" install/old/lib/libbsoncxx.so install/new/lib/libbsoncxx.so >>cxx-abi/bsoncxx.txt; then
57+
abidiff "${abi_flags[@]:?}" install/old/lib/libbsoncxx.so install/new/lib/libbsoncxx.so >>cxx-abi/bsoncxx.txt && ret="$?" || ret="$?"
58+
if (("$ret" & 0x03)); then # ABIDIFF_ERROR (1) | ABIDIFF_USAGE_ERROR (2)
59+
echo "abidiff error" >&2
60+
exit 1
61+
elif (("$ret" & 0x08)); then # ABIDIFF_ABI_INCOMPATIBLE_CHANGE (8).
5862
declare status
5963
status='{"status":"failed", "type":"test", "should_continue":true, "desc":"abidiff returned an error for bsoncxx (stable)"}'
6064
curl -sS -d "${status:?}" -H "Content-Type: application/json" -X POST localhost:2285/task_status || true
@@ -63,7 +67,11 @@ echo "Comparing stable ABI for bsoncxx... done."
6367

6468
# Allow task to upload the diff reports despite failed status.
6569
echo "Comparing stable ABI for mongocxx..."
66-
if ! abidiff "${abi_flags[@]:?}" install/old/lib/libmongocxx.so install/new/lib/libmongocxx.so >>cxx-abi/mongocxx.txt; then
70+
abidiff "${abi_flags[@]:?}" install/old/lib/libmongocxx.so install/new/lib/libmongocxx.so >>cxx-abi/mongocxx.txt && ret="$?" || ret="$?"
71+
if (("$ret" & 0x03)); then # ABIDIFF_ERROR (1) | ABIDIFF_USAGE_ERROR (2)
72+
echo "abidiff error" >&2
73+
exit 1
74+
elif (("$ret" & 0x08)); then # ABIDIFF_ABI_INCOMPATIBLE_CHANGE (8)
6775
declare status
6876
status='{"status":"failed", "type":"test", "should_continue":true, "desc":"abidiff returned an error for mongocxx (stable)"}'
6977
curl -sS -d "${status:?}" -H "Content-Type: application/json" -X POST localhost:2285/task_status || true

src/bsoncxx/include/bsoncxx/v1/array/value.hpp

Lines changed: 184 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020

2121
#include <bsoncxx/v1/detail/prelude.hpp>
2222

23+
#include <bsoncxx/v1/array/view.hpp>
24+
#include <bsoncxx/v1/config/export.hpp>
25+
#include <bsoncxx/v1/document/value.hpp>
26+
27+
#include <cstdint>
28+
#include <type_traits>
29+
#include <utility>
30+
2331
namespace bsoncxx {
2432
namespace v1 {
2533
namespace array {
@@ -29,7 +37,178 @@ namespace array {
2937
///
3038
/// @attention This feature is experimental! It is not ready for use!
3139
///
32-
class value {};
40+
class value {
41+
private:
42+
v1::document::value _value;
43+
44+
template <typename T>
45+
struct is_valid_deleter : std::is_constructible<v1::document::value, std::uint8_t*, T> {};
46+
47+
public:
48+
/// @copydoc v1::document::value::deleter_type
49+
using deleter_type = v1::document::value::deleter_type;
50+
51+
/// @copydoc v1::document::value::default_deleter_type
52+
using default_deleter_type = v1::document::value::default_deleter_type;
53+
54+
/// @copydoc v1::document::value::unique_ptr_type
55+
using unique_ptr_type = v1::document::value::unique_ptr_type;
56+
57+
/// @copydoc v1::document::view::const_iterator
58+
using const_iterator = v1::document::view::const_iterator;
59+
60+
/// @copydoc v1::document::view::iterator
61+
using iterator = const_iterator;
62+
63+
/// @copydoc v1::document::value::~value()
64+
~value() = default;
65+
66+
/// @copydoc v1::document::value::value(v1::document::value&& other) noexcept
67+
value(value&& other) noexcept = default;
68+
69+
/// @copydoc v1::document::value::operator=(v1::document::value&& other) noexcept
70+
value& operator=(value&& other) noexcept = default;
71+
72+
/// @copydoc v1::document::value::value(v1::document::value const& other)
73+
value(value const& other) : _value(other._value) {}
74+
75+
/// @copydoc v1::document::value::operator=(v1::document::view view)
76+
value& operator=(v1::array::view view) {
77+
this->reset(view);
78+
return *this;
79+
}
80+
81+
/// @copydoc v1::document::value::operator=(v1::document::value const& other)
82+
value& operator=(value const& other) {
83+
_value = other._value;
84+
return *this;
85+
}
86+
87+
/// @copydoc v1::document::value::value()
88+
value() = default;
89+
90+
/// @copydoc v1::document::value::value(std::uint8_t* data, Deleter deleter)
91+
template <typename Deleter, detail::enable_if_t<is_valid_deleter<Deleter>::value>* = nullptr>
92+
value(std::uint8_t* data, Deleter deleter) : _value{data, std::move(deleter)} {}
93+
94+
/// @copydoc v1::document::value::value(std::uint8_t* data, std::size_t length, Deleter deleter)
95+
template <typename Deleter, detail::enable_if_t<is_valid_deleter<Deleter>::value>* = nullptr>
96+
value(std::uint8_t* data, std::size_t length, Deleter deleter) : _value{data, length, std::move(deleter)} {}
97+
98+
/// @copydoc v1::document::value::value(std::uint8_t* data)
99+
explicit value(std::uint8_t* data) : _value{data} {}
100+
101+
/// @copydoc v1::document::value::value(std::uint8_t* data, std::size_t length)
102+
value(std::uint8_t* data, std::size_t length) : _value{data, length} {}
103+
104+
/// @copydoc v1::document::value::value(v1::document::value::unique_ptr_type ptr)
105+
explicit value(unique_ptr_type ptr) : _value{std::move(ptr)} {}
106+
107+
/// @copydoc v1::document::value::value(v1::document::value::unique_ptr_type ptr, std::size_t length)
108+
value(unique_ptr_type ptr, std::size_t length) : _value{std::move(ptr), length} {}
109+
110+
/// @copydoc v1::document::value::value(v1::document::view view)
111+
explicit value(v1::array::view view) : _value{view} {}
112+
113+
/// @copydoc v1::document::value::get_deleter() const
114+
deleter_type const& get_deleter() const {
115+
return _value.get_deleter();
116+
}
117+
118+
/// @copydoc v1::document::value::release()
119+
unique_ptr_type release() {
120+
return _value.release();
121+
}
122+
123+
/// @copydoc v1::document::value::reset(v1::document::value v)
124+
void reset(value v) {
125+
_value = std::move(v._value);
126+
}
127+
128+
/// @copydoc v1::document::value::reset(v1::document::view v)
129+
void reset(v1::array::view v) {
130+
*this = value{v};
131+
}
132+
133+
///
134+
/// Return a view of the BSON bytes as an array.
135+
///
136+
v1::array::view view() const {
137+
return v1::array::view{_value.data()};
138+
}
139+
140+
///
141+
/// Implicitly convert to `this->view()`.
142+
///
143+
/* explicit(false) */ operator v1::array::view() const {
144+
return this->view();
145+
}
146+
147+
/// @copydoc v1::array::view::cbegin() const
148+
v1::array::view::const_iterator cbegin() const {
149+
return this->view().cbegin();
150+
}
151+
152+
/// @copydoc v1::array::view::cend() const
153+
v1::array::view::const_iterator cend() const {
154+
return this->view().cend();
155+
}
156+
157+
/// @copydoc v1::array::view::begin() const
158+
v1::array::view::const_iterator begin() const {
159+
return this->view().begin();
160+
}
161+
162+
/// @copydoc v1::array::view::end() const
163+
v1::array::view::const_iterator end() const {
164+
return this->view().end();
165+
}
166+
167+
/// @copydoc v1::array::view::find(std::uint32_t i) const
168+
v1::array::view::const_iterator find(std::uint32_t i) const {
169+
return this->view().find(i);
170+
}
171+
172+
/// @copydoc v1::array::view::operator[](std::uint32_t i) const
173+
v1::element::view operator[](std::uint32_t i) const {
174+
return this->view()[i];
175+
}
176+
177+
/// @copydoc v1::array::view::data() const
178+
std::uint8_t const* data() const {
179+
return this->view().data();
180+
}
181+
182+
/// @copydoc v1::array::view::size() const
183+
std::size_t size() const {
184+
return this->view().size();
185+
}
186+
187+
/// @copydoc v1::array::view::length() const
188+
std::size_t length() const {
189+
return this->view().length();
190+
}
191+
192+
/// @copydoc v1::array::view::empty() const
193+
bool empty() const {
194+
return this->view().empty();
195+
}
196+
197+
/// @copydoc v1::array::view::operator bool() const
198+
explicit operator bool() const {
199+
return this->view().operator bool();
200+
}
201+
202+
/// @copydoc v1::array::view::operator==(v1::array::view lhs, v1::array::view rhs)
203+
friend bool operator==(value const& lhs, value const& rhs) {
204+
return lhs.view() == rhs.view();
205+
}
206+
207+
/// @copydoc v1::array::view::operator!=(v1::array::view lhs, v1::array::view rhs)
208+
friend bool operator!=(value const& lhs, value const& rhs) {
209+
return !(lhs == rhs);
210+
}
211+
};
33212

34213
} // namespace array
35214
} // namespace v1
@@ -41,3 +220,7 @@ class value {};
41220
/// @file
42221
/// Provides @ref bsoncxx::v1::array::value.
43222
///
223+
/// @par Includes
224+
/// - @ref bsoncxx/v1/array/view.hpp
225+
/// - @ref bsoncxx/v1/document/value.hpp
226+
///

src/bsoncxx/include/bsoncxx/v1/array/view.hpp

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,143 @@
2020

2121
#include <bsoncxx/v1/detail/prelude.hpp>
2222

23+
#include <bsoncxx/v1/config/export.hpp>
24+
#include <bsoncxx/v1/document/view.hpp>
25+
#include <bsoncxx/v1/element/view.hpp>
26+
27+
#include <cstddef>
28+
#include <cstdint>
29+
2330
namespace bsoncxx {
2431
namespace v1 {
2532
namespace array {
2633

2734
///
2835
/// A non-owning, read-only BSON array.
2936
///
37+
/// An "invalid" view, as indicated by @ref operator bool() const, does not satisfy the minimum requirements of a valid
38+
/// BSON document, which are that:
39+
///
40+
/// - @ref data() is not null, and
41+
/// - @ref size() is not less than `5` (the minimum size of a BSON document).
42+
///
43+
/// The BSON bytes being represented is only validated as minimally required to satisfy a requested operation. When an
44+
/// operation is not satisfiable due to invalid data, the operation will throw an @ref bsoncxx::v1::exception with @ref
45+
/// bsoncxx::v1::document::view::errc::invalid_data.
46+
///
3047
/// @attention This feature is experimental! It is not ready for use!
3148
///
32-
class view {};
49+
class view {
50+
public:
51+
/// @copydoc v1::document::view::const_iterator
52+
using const_iterator = v1::document::view::const_iterator;
53+
54+
/// @copydoc v1::document::view::iterator
55+
using iterator = const_iterator;
56+
57+
private:
58+
v1::document::view _view;
59+
60+
public:
61+
/// @copydoc v1::document::view::view()
62+
view() = default;
63+
64+
/// @copydoc v1::document::view::view(std::uint8_t const* data)
65+
explicit view(std::uint8_t const* data) : _view{data} {}
66+
67+
/// @copydoc v1::document::view::view(std::uint8_t const* data, std::size_t length)
68+
view(std::uint8_t const* data, std::size_t length) : _view{data, length} {}
69+
70+
/// @copydoc v1::document::view::data() const
71+
std::uint8_t const* data() const {
72+
return _view.data();
73+
}
74+
75+
/// @copydoc v1::document::view::size() const
76+
std::size_t size() const {
77+
return _view.size();
78+
}
79+
80+
/// @copydoc v1::document::view::length() const
81+
std::size_t length() const {
82+
return _view.length();
83+
}
84+
85+
/// @copydoc v1::document::view::empty() const
86+
bool empty() const {
87+
return _view.empty();
88+
}
89+
90+
/// @copydoc v1::document::view::operator bool() const
91+
explicit operator bool() const {
92+
return _view.operator bool();
93+
}
94+
95+
/// @copydoc v1::document::view::cbegin() const
96+
const_iterator cbegin() const {
97+
return _view.cbegin();
98+
}
99+
100+
/// @copydoc v1::document::view::cend() const
101+
const_iterator cend() const {
102+
return {};
103+
}
104+
105+
/// @copydoc v1::document::view::cbegin() const
106+
const_iterator begin() const {
107+
return this->cbegin();
108+
}
109+
110+
/// @copydoc v1::document::view::cend() const
111+
const_iterator end() const {
112+
return this->cend();
113+
}
114+
115+
///
116+
/// Return a const iterator to the element within the represented BSON array at index `i` via key string comparison.
117+
///
118+
/// If this view is invalid or the requested field is not found, returns an end iterator.
119+
///
120+
/// @par Complexity
121+
/// Linear.
122+
///
123+
/// @exception bsoncxx::v1::exception with @ref bsoncxx::v1::document::view::errc::invalid_data if this operation
124+
/// failed due to invalid BSON bytes.
125+
///
126+
BSONCXX_ABI_EXPORT_CDECL(const_iterator) find(std::uint32_t i) const;
127+
128+
///
129+
/// Return the first element within the represented BSON array whose key compares equal to `i`.
130+
///
131+
/// @returns An invalid element if this view is invalid or the requested field is not found.
132+
///
133+
/// @par Complexity
134+
/// Linear.
135+
///
136+
/// @exception bsoncxx::v1::exception with @ref bsoncxx::v1::document::view::errc::invalid_data if this operation
137+
/// failed due to invalid BSON bytes.
138+
///
139+
v1::element::view operator[](std::uint32_t i) const {
140+
return *(this->find(i));
141+
}
142+
143+
///
144+
/// Implicitly convert to a @ref bsoncxx::v1::document::view.
145+
///
146+
/* explicit(false) */ operator v1::document::view() const {
147+
return _view;
148+
}
149+
150+
/// @copydoc v1::document::view::operator==(v1::document::view lhs, v1::document::view rhs)
151+
friend bool operator==(view lhs, view rhs) {
152+
return lhs._view == rhs._view;
153+
}
154+
155+
/// @copydoc v1::document::view::operator!=(v1::document::view lhs, v1::document::view rhs)
156+
friend bool operator!=(view lhs, view rhs) {
157+
return !(lhs == rhs);
158+
}
159+
};
33160

34161
} // namespace array
35162
} // namespace v1
@@ -41,3 +168,7 @@ class view {};
41168
/// @file
42169
/// Provides @ref bsoncxx::v1::array::view.
43170
///
171+
/// @par Includes
172+
/// - @ref bsoncxx/v1/document/view.hpp
173+
/// - @ref bsoncxx/v1/element/view.hpp
174+
///

0 commit comments

Comments
 (0)