mongodb timeline 还在研究

暂时写这么点
This commit is contained in:
2023-05-29 18:12:22 +08:00
parent 996223d36c
commit 91bbb3e133
185 changed files with 32325 additions and 1 deletions

View File

@@ -8,6 +8,8 @@ add_subdirectory(MessageSystem)
add_subdirectory(MP)
add_subdirectory(MC/gui)
add_subdirectory(MC/api)
add_subdirectory(MDB/imm_mysqldb)
add_subdirectory(MDB/imm_mongodb)
add_subdirectory(TEST)

View File

@@ -0,0 +1,17 @@
project(imm_mongodb)
include_directories(${CMAKE_SOURCE_DIR}/MP)
include_directories(${CMAKE_SOURCE_DIR}/MDB/imm_mongodb)
link_directories(${CMAKE_SOURCE_DIR}/MDB/imm_mongodb/lib)
add_executable(imm_mongodb
MongoPool.cpp
test_link.cpp
)
target_link_libraries(imm_mongodb
libmongocxx.so
libbsoncxx.so
libbson-1.0.so
)

View File

@@ -0,0 +1,30 @@
//
// Created by dongl on 23-5-27.
//
#include "MongoPool.h"
#include "mongocxx/instance.hpp"
MongoPool::MongoPool() {
static mongocxx::instance instance{}; // This should be done only once.
uri = mongocxx::uri("mongodb://user_session:Aa316216@124.221.152.192:27017/?authSource=im_session");
}
mongocxx::pool::entry MongoPool::acquire() {
static auto mongoPool = new MongoPool();
return mongoPool->pool_fun(mongoPool)->acquire();
}
auto MongoPool::try_acquire() {
static auto mongoPool = new MongoPool();
return mongoPool->pool_fun(mongoPool)->try_acquire();
}
mongocxx::pool* MongoPool::pool_fun(MongoPool *mongoPool) {
static mongocxx::pool pool(mongoPool->uri);
return &pool;
}

View File

@@ -0,0 +1,26 @@
//
// Created by dongl on 23-5-27.
//
#ifndef IM2_MONGOPOOL_H
#define IM2_MONGOPOOL_H
#include <search.h>
#include <optional>
#include "mongocxx/pool.hpp"
class MongoPool {
public:
MongoPool();
static mongocxx::pool::entry acquire();
static auto try_acquire();
private:
mongocxx::pool* pool_fun(MongoPool* mongoPool);
private:
mongocxx::uri uri;
};
#endif //IM2_MONGOPOOL_H

View File

@@ -0,0 +1,127 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstddef>
#include <cstdint>
#include <bsoncxx/document/element.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace types {
namespace bson_value {
class view;
} // namespace bson_value
} // namespace types
namespace array {
///
/// A variant view type that accesses values in serialized BSON arrays.
///
/// Element functions as a variant type, where the kind of the element can be
/// interrogated by calling type() and a specific value can be extracted through
/// get_X() accessors.
///
class BSONCXX_API element : private document::element {
public:
element();
using document::element::operator bool;
using document::element::type;
using document::element::get_array;
using document::element::get_binary;
using document::element::get_bool;
using document::element::get_code;
using document::element::get_codewscope;
using document::element::get_date;
using document::element::get_dbpointer;
using document::element::get_decimal128;
using document::element::get_document;
using document::element::get_double;
using document::element::get_int32;
using document::element::get_int64;
using document::element::get_maxkey;
using document::element::get_minkey;
using document::element::get_null;
using document::element::get_oid;
using document::element::get_regex;
using document::element::get_string;
using document::element::get_symbol;
using document::element::get_timestamp;
using document::element::get_undefined;
using document::element::get_utf8;
using document::element::get_value;
using document::element::operator[];
using document::element::key;
using document::element::keylen;
using document::element::length;
using document::element::offset;
using document::element::raw;
private:
friend class view;
BSONCXX_PRIVATE explicit element(const std::uint8_t* raw,
std::uint32_t length,
std::uint32_t offset,
std::uint32_t keylen);
};
///
/// @{
///
/// Convenience methods to compare for equality against a bson_value.
///
/// Returns true if this element contains a bson_value that matches.
///
/// @relates element
///
BSONCXX_API bool BSONCXX_CALL operator==(const element& elem, const types::bson_value::view& v);
BSONCXX_API bool BSONCXX_CALL operator==(const types::bson_value::view& v, const element& elem);
///
/// @}
///
///
/// @{
///
/// Convenience methods to compare for equality against a bson_value.
///
/// Returns false if this element contains a bson_value that matches.
///
/// @relates element
///
BSONCXX_API bool BSONCXX_CALL operator!=(const element& elem, const types::bson_value::view& v);
BSONCXX_API bool BSONCXX_CALL operator!=(const types::bson_value::view& v, const element& elem);
///
/// @}
///
} // namespace array
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,120 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstdlib>
#include <memory>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace array {
///
/// A read-only BSON array that owns its underlying buffer. When a array::value goes
/// out of scope, the underlying buffer is freed. Generally this class should be used
/// sparingly; array::view should be used instead wherever possible.
///
class BSONCXX_API value {
public:
using deleter_type = void (*)(std::uint8_t*);
using unique_ptr_type = std::unique_ptr<uint8_t[], deleter_type>;
///
/// Constructs a value from a buffer.
/// This constructor transfers ownership of the buffer to the resulting
/// value. A user-provided deleter is used to destroy the buffer.
///
/// @param data
/// A pointer to a buffer containing a valid BSON array.
/// @param length
/// The length of the document.
/// @param dtor
/// A user provided deleter.
///
value(std::uint8_t* data, std::size_t length, deleter_type dtor);
///
/// Constructs a value from a std::unique_ptr to a buffer. The ownership
/// of the buffer is transferred to the resulting value.
///
/// @param ptr
/// A pointer to a buffer containing a valid BSON array.
/// @param length
/// The length of the document.
///
value(unique_ptr_type ptr, std::size_t length);
///
/// Constructs a value from a view of an array. The data referenced
/// by the array::view will be copied into a new buffer managed by the
/// constructed value.
///
/// @param view
/// A view of another array to copy.
///
explicit value(array::view view);
value(const value&);
value& operator=(const value&);
value(value&&) noexcept = default;
value& operator=(value&&) noexcept = default;
///
/// Get a view over the document owned by this value.
///
BSONCXX_INLINE array::view view() const noexcept;
///
/// Conversion operator that provides a view given a value.
///
/// @return A view over the value.
///
BSONCXX_INLINE operator array::view() const noexcept;
///
/// Transfer ownership of the underlying buffer to the caller.
///
/// @warning
/// After calling release() it is illegal to call any methods
/// on this class, unless it is subsequently moved into.
///
/// @return A std::unique_ptr with ownership of the buffer.
///
unique_ptr_type release();
private:
unique_ptr_type _data;
std::size_t _length{0};
};
BSONCXX_INLINE array::view value::view() const noexcept {
return array::view{static_cast<uint8_t*>(_data.get()), _length};
}
BSONCXX_INLINE value::operator array::view() const noexcept {
return view();
}
} // namespace array
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,200 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <bsoncxx/array/element.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace types {
namespace bson_value {
class view;
} // namespace bson_value
} // namespace types
namespace array {
///
/// A read-only, non-owning view of a BSON document.
///
class BSONCXX_API view {
public:
class BSONCXX_API const_iterator;
using iterator = const_iterator;
///
/// @returns A const_iterator to the first element of the array.
///
const_iterator cbegin() const;
///
/// @returns A const_iterator to the past-the-end element of the array.
///
const_iterator cend() const;
///
/// @returns A const_iterator to the first element of the array.
///
const_iterator begin() const;
///
/// @returns A const_iterator to the past-the-end element of the array.
///
const_iterator end() const;
///
/// Indexes into this BSON array. If the index is out-of-bounds, a past-the-end iterator
/// will be returned. As BSON represents arrays as documents, the runtime of find() is
/// linear in the length of the array.
///
/// @param i
/// The index of the element.
///
/// @return An iterator to the element if it exists, or the past-the-end iterator.
///
const_iterator find(std::uint32_t i) const;
///
/// Indexes into this BSON array. If the index is out-of-bounds, the invalid array::element
/// will be returned. As BSON represents arrays as documents, the runtime of operator[] is
/// linear in the length of the array.
///
/// @param i
/// The index of the element.
///
/// @return The element if it exists, or the invalid element.
///
element operator[](std::uint32_t i) const;
///
/// Default constructs a view. The resulting view will be initialized to point at
/// an empty BSON array.
///
view();
///
/// Constructs a view from a buffer. The caller is responsible for ensuring that
/// the lifetime of the resulting view is a subset of the buffer's.
///
/// @param data
/// A buffer containing a valid BSON array.
/// @param length
/// The size of the buffer, in bytes.
///
view(const std::uint8_t* data, std::size_t length);
///
/// Access the raw bytes of the underlying array.
///
/// @return A (non-owning) pointer to the view's buffer.
///
const std::uint8_t* data() const;
///
/// Gets the length of the underlying buffer.
///
/// @remark This is not the number of elements in the array.
/// To compute the number of elements, use std::distance.
///
/// @return The length of the array, in bytes.
///
std::size_t length() const;
///
/// Checks if the underlying buffer is empty, i.e. it is equivalent to
/// the trivial array '[]'.
///
/// @return true if the underlying document is empty.
///
bool empty() const;
///
/// Conversion operator unwrapping a document::view
///
operator document::view() const;
///
/// @{
///
/// Compare two views for (in)-equality
///
/// @relates view
///
friend BSONCXX_API bool BSONCXX_CALL operator==(view, view);
friend BSONCXX_API bool BSONCXX_CALL operator!=(view, view);
///
/// @}
///
private:
document::view _view;
};
///
/// A const iterator over the contents of an array view.
///
/// This iterator type provides a const forward iterator interface to array
/// view elements.
///
class BSONCXX_API view::const_iterator {
public:
///
/// std::iterator_traits
///
using value_type = element;
using reference = element&;
using pointer = element*;
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
const_iterator();
explicit const_iterator(const element& element);
reference operator*();
pointer operator->();
const_iterator& operator++();
const_iterator operator++(int);
///
/// @{
///
/// Compare two const_iterators for (in)-equality
///
/// @relates view::const_iterator
///
friend BSONCXX_API bool BSONCXX_CALL operator==(const const_iterator&, const const_iterator&);
friend BSONCXX_API bool BSONCXX_CALL operator!=(const const_iterator&, const const_iterator&);
///
/// @}
///
private:
element _element;
};
} // namespace array
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,34 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/array/value.hpp>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/view_or_value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace array {
using view_or_value = bsoncxx::view_or_value<array::view, array::value>;
} // namespace array
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,119 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/array/value.hpp>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/builder/basic/impl.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/basic/sub_array.hpp>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
///
/// A traditional builder-style interface for constructing
/// a BSON array.
///
class array : public sub_array {
public:
///
/// Default constructor
///
BSONCXX_INLINE array() : sub_array(&_core), _core(true) {}
///
/// Move constructor
///
BSONCXX_INLINE array(array&& arr) noexcept : sub_array(&_core), _core(std::move(arr._core)) {}
///
/// Move assignment operator
///
BSONCXX_INLINE array& operator=(array&& arr) noexcept {
_core = std::move(arr._core);
return *this;
}
///
/// @return A view of the BSON array.
///
BSONCXX_INLINE bsoncxx::array::view view() const {
return _core.view_array();
}
///
/// Conversion operator that provides a view of the current builder
/// contents.
///
/// @return A view of the current builder contents.
///
BSONCXX_INLINE operator bsoncxx::array::view() const {
return view();
}
///
/// Transfer ownership of the underlying array to the caller.
///
/// @return An array::value with ownership of the array.
///
/// @warning
/// After calling extract() it is illegal to call any methods
/// on this class, unless it is subsequenly moved into.
///
BSONCXX_INLINE bsoncxx::array::value extract() {
return _core.extract_array();
}
///
/// Reset the underlying BSON to an empty array.
///
BSONCXX_INLINE void clear() {
_core.clear();
}
private:
core _core;
};
///
/// Creates an array from a list of elements.
///
/// @param args
/// A variadiac list of elements. The types of the elements can be anything that
/// builder::basic::sub_array::append accepts.
///
/// @return
/// A bsoncxx::array::value containing the elements.
///
template <typename... Args>
bsoncxx::array::value BSONCXX_CALL make_array(Args&&... args) {
basic::array array;
array.append(std::forward<Args>(args)...);
return array.extract();
}
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,122 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/basic/impl.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/basic/sub_document.hpp>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
class array;
///
/// A traditional builder-style interface for constructing
/// a BSON document.
///
class document : public sub_document {
public:
///
/// Default constructor
///
BSONCXX_INLINE document() : sub_document(&_core), _core(false) {}
///
/// Move constructor
///
BSONCXX_INLINE document(document&& doc) noexcept
: sub_document(&_core), _core(std::move(doc._core)) {}
///
/// Move assignment operator
///
BSONCXX_INLINE document& operator=(document&& doc) noexcept {
_core = std::move(doc._core);
return *this;
}
///
/// @return A view of the BSON document.
///
BSONCXX_INLINE bsoncxx::document::view view() const {
return _core.view_document();
}
///
/// Conversion operator that provides a view of the current builder
/// contents.
///
/// @return A view of the current builder contents.
///
BSONCXX_INLINE operator bsoncxx::document::view() const {
return view();
}
///
/// Transfer ownership of the underlying document to the caller.
///
/// @return A document::value with ownership of the document.
///
/// @warning
/// After calling extract() it is illegal to call any methods
/// on this class, unless it is subsequently moved into.
///
BSONCXX_INLINE bsoncxx::document::value extract() {
return _core.extract_document();
}
///
/// Reset the underlying BSON to an empty document.
///
BSONCXX_INLINE void clear() {
_core.clear();
}
private:
core _core;
};
///
/// Creates a document from a list of key-value pairs.
///
/// @param args
/// A variadic list of key-value pairs. The types of the keys and values can be anything that
/// builder::basic::sub_document::append accepts.
///
/// @return
/// A bsoncxx::document::value containing the elements.
///
template <typename... Args>
bsoncxx::document::value BSONCXX_CALL make_document(Args&&... args) {
basic::document document;
document.append(std::forward<Args>(args)...);
return document.extract();
}
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,33 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/concatenate.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
using bsoncxx::builder::concatenate;
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,69 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/basic/sub_array.hpp>
#include <bsoncxx/builder/basic/sub_document.hpp>
#include <bsoncxx/util/functor.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
namespace impl {
template <typename T>
using takes_document = typename util::is_functor<T, void(sub_document)>;
template <typename T>
using takes_array = typename util::is_functor<T, void(sub_array)>;
template <typename T>
BSONCXX_INLINE typename std::enable_if<takes_document<T>::value, void>::type generic_append(
core* core, T&& func) {
core->open_document();
func(sub_document(core));
core->close_document();
}
template <typename T>
BSONCXX_INLINE typename std::enable_if<takes_array<T>::value, void>::type generic_append(core* core,
T&& func) {
core->open_array();
func(sub_array(core));
core->close_array();
}
template <typename T>
BSONCXX_INLINE
typename std::enable_if<!takes_document<T>::value && !takes_array<T>::value, void>::type
generic_append(core* core, T&& t) {
core->append(std::forward<T>(t));
}
template <typename T>
BSONCXX_INLINE void value_append(core* core, T&& t) {
generic_append(core, std::forward<T>(t));
}
} // namespace impl
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,40 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <tuple>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
///
/// Constructs a key-value pair from a string key
/// and a BSON value.
///
template <typename T, typename U>
BSONCXX_INLINE std::tuple<T&&, U&&> kvp(T&& t, U&& u) {
return std::tuple<T&&, U&&>(std::forward<T>(t), std::forward<U>(u));
}
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,86 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/basic/helpers.hpp>
#include <bsoncxx/builder/concatenate.hpp>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
namespace impl {
template <typename T>
void value_append(core* core, T&& t);
} // namespace impl
///
/// An internal class of builder::basic.
/// Users should almost always construct a builder::basic::array instead.
///
class sub_array {
public:
///
/// Default constructor
///
BSONCXX_INLINE sub_array(core* core) : _core(core) {}
///
/// Appends multiple BSON values.
///
template <typename Arg, typename... Args>
BSONCXX_INLINE void append(Arg&& a, Args&&... args) {
append_(std::forward<Arg>(a));
append(std::forward<Args>(args)...);
}
///
/// Inductive base-case for the variadic append(...)
///
BSONCXX_INLINE
void append() {}
private:
//
// Appends a BSON value.
//
template <typename T>
BSONCXX_INLINE void append_(T&& t) {
impl::value_append(_core, std::forward<T>(t));
}
//
// Concatenates another bson array directly.
//
BSONCXX_INLINE
void append_(concatenate_array array) {
_core->concatenate(array.view());
}
core* _core;
};
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,105 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/basic/helpers.hpp>
#include <bsoncxx/builder/concatenate.hpp>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace basic {
namespace impl {
template <typename T>
void value_append(core* core, T&& t);
} // namespace impl
///
/// An internal class of builder::basic.
/// Users should almost always construct a builder::basic::document instead.
///
class sub_document {
public:
BSONCXX_INLINE sub_document(core* core) : _core(core) {}
///
/// Appends multiple basic::kvp key-value pairs.
///
template <typename Arg, typename... Args>
BSONCXX_INLINE void append(Arg&& a, Args&&... args) {
append_(std::forward<Arg>(a));
append(std::forward<Args>(args)...);
}
///
/// Inductive base-case for the variadic append(...)
///
BSONCXX_INLINE
void append() {}
private:
//
// Appends a basic::kvp where the key is a non-owning string view.
//
template <typename K, typename V>
BSONCXX_INLINE typename std::enable_if<
std::is_same<typename std::decay<K>::type, stdx::string_view>::value>::type
append_(std::tuple<K, V>&& t) {
_core->key_view(std::forward<K>(std::get<0>(t)));
impl::value_append(_core, std::forward<V>(std::get<1>(t)));
}
//
// Appends a basic::kvp where the key is an owning STL string.
//
template <typename K, typename V>
BSONCXX_INLINE typename std::enable_if<
std::is_same<typename std::decay<K>::type, std::string>::value>::type
append_(std::tuple<K, V>&& t) {
_core->key_owned(std::forward<K>(std::get<0>(t)));
impl::value_append(_core, std::forward<V>(std::get<1>(t)));
}
//
// Appends a basic::kvp where the key is a string literal
//
template <std::size_t n, typename V>
BSONCXX_INLINE void append_(std::tuple<const char (&)[n], V>&& t) {
_core->key_view(stdx::string_view{std::get<0>(t), n - 1});
impl::value_append(_core, std::forward<V>(std::get<1>(t)));
}
//
// Concatenates another bson document directly.
//
BSONCXX_INLINE
void append_(concatenate_doc doc) {
_core->concatenate(doc);
}
core* _core;
};
} // namespace basic
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,122 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/array/view_or_value.hpp>
#include <bsoncxx/document/view_or_value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
///
/// Container to concatenate a document. Use it by constructing an instance with the
/// document to be concatenated, and pass it into a document stream builder.
///
struct concatenate_doc {
document::view_or_value doc;
// MSVC seems to need a hint that it should always
// inline this destructor.
BSONCXX_INLINE ~concatenate_doc() = default;
///
/// Conversion operator that provides a view of the wrapped concatenate
/// document.
///
/// @return A view of the wrapped concatenate document.
///
BSONCXX_INLINE operator document::view() const {
return doc;
}
///
/// Accessor that provides a view of the wrapped concatenate
/// document.
///
/// @return A view of the wrapped concatenate document.
///
BSONCXX_INLINE document::view view() const {
return doc;
}
};
///
/// Container to concatenate an array. Use this with the array stream builder in order
/// to pass an array into a new builder and append its values to the stream.
///
struct concatenate_array {
array::view_or_value array;
// MSVC seems to need a hint that it should always
// inline this destructor.
BSONCXX_INLINE ~concatenate_array() = default;
///
/// Conversion operator that provides a view of the wrapped concatenate
/// array.
///
/// @return A view of the wrapped concatenate array.
///
BSONCXX_INLINE operator array::view() const {
return array;
}
///
/// Accessor that provides a view of the wrapped concatenate
/// array.
///
/// @return A view of the wrapped concatenate array.
///
BSONCXX_INLINE array::view view() const {
return array;
}
};
///
/// Helper method to concatenate a document. Use this with the document stream
/// builder to merge an existing document's fields with a new document's.
///
/// @param doc A document to be concatenated.
///
/// @return concatenate_doc A concatenating struct.
///
/// @relatesalso concatenate_doc
///
BSONCXX_INLINE concatenate_doc concatenate(document::view_or_value doc) {
return {std::move(doc)};
}
///
/// Method to concatenate an array with a new array. Use this with the array stream
/// builder to merge an existing array's fields with a new array.
///
/// @param array An array to be concatenated.
///
/// @return concatenate_array A concatenating struct.
///
/// @relatesalso concatenate_array
///
BSONCXX_INLINE concatenate_array concatenate(array::view_or_value array) {
return {std::move(array)};
}
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,698 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <stdexcept>
#include <type_traits>
#include <bsoncxx/array/value.hpp>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/types.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
///
/// A low-level interface for constructing BSON documents and arrays.
///
/// @remark
/// Generally it is recommended to use the classes in builder::basic or builder::stream instead of
/// using this class directly. However, developers who wish to write their own abstractions may
/// find this class useful.
///
class BSONCXX_API core {
public:
class BSONCXX_PRIVATE impl;
///
/// Constructs an empty BSON datum.
///
/// @param is_array
/// True if the top-level BSON datum should be an array.
///
explicit core(bool is_array);
core(core&& rhs) noexcept;
core& operator=(core&& rhs) noexcept;
~core();
///
/// Appends a key passed as a non-owning stdx::string_view.
///
/// @remark
/// Use key_owned() unless you know what you are doing.
///
/// @warning
/// The caller must ensure that the lifetime of the backing string extends until the next
/// value is appended.
///
/// @param key
/// A null-terminated array of characters.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws bsoncxx::exception if the current BSON datum is an array or if the previous value
/// appended to the builder was also a key.
///
core& key_view(stdx::string_view key);
///
/// Appends a key passed as an STL string. Transfers ownership of the key to this class.
///
/// @param key
/// A string key.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws bsoncxx::exception if the current BSON datum is an array or if the previous value
/// appended to the builder was a key.
///
core& key_owned(std::string key);
///
/// Opens a sub-document within this BSON datum.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& open_document();
///
/// Opens a sub-array within this BSON datum.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& open_array();
///
/// Closes the current sub-document within this BSON datum.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws bsoncxx::exception if the current BSON datum is not an open sub-document.
///
core& close_document();
///
/// Closes the current sub-array within this BSON datum.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws bsoncxx::exception if the current BSON datum is not an open sub-array.
///
core& close_array();
///
/// Appends the keys from a BSON document into this BSON datum.
///
/// @note
/// If this BSON datum is a document, the original keys from `view` are kept. Otherwise (if
/// this BSON datum is an array), the original keys from `view` are discarded.
///
/// @note
/// This can be used with an array::view as well by converting it to a document::view first.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if one of the keys fails to append.
///
core& concatenate(const document::view& view);
///
/// Appends a BSON double.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the double fails to append.
///
core& append(const types::b_double& value);
///
/// Append a BSON UTF-8 string.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the string fails to append.
///
core& append(const types::b_string& value);
///
/// Appends a BSON document.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the document fails to append.
///
core& append(const types::b_document& value);
///
/// Appends a BSON array.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the array fails to append.
///
core& append(const types::b_array& value);
///
/// Appends a BSON binary datum.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the binary fails to append.
///
core& append(const types::b_binary& value);
///
/// Appends a BSON undefined.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if undefined fails to append.
///
core& append(const types::b_undefined& value);
///
/// Appends a BSON ObjectId.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the ObjectId fails to append.
///
core& append(const types::b_oid& value);
///
/// Appends a BSON boolean.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the boolean fails to append.
///
core& append(const types::b_bool& value);
///
/// Appends a BSON date.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the date fails to append.
///
core& append(const types::b_date& value);
///
/// Appends a BSON null.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if null fails to append.
///
core& append(const types::b_null& value);
///
/// Appends a BSON regex.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the regex fails to append.
///
core& append(const types::b_regex& value);
///
/// Appends a BSON DBPointer.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the DBPointer fails to append.
///
core& append(const types::b_dbpointer& value);
///
/// Appends a BSON JavaScript code.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the JavaScript code fails to append.
///
core& append(const types::b_code& value);
///
/// Appends a BSON symbol.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the symbol fails to append.
///
core& append(const types::b_symbol& value);
///
/// Appends a BSON JavaScript code with scope.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the JavaScript code with scope fails to append.
///
core& append(const types::b_codewscope& value);
///
/// Appends a BSON 32-bit signed integer.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the 32-bit signed integer fails to append.
///
core& append(const types::b_int32& value);
///
/// Appends a BSON replication timestamp.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the timestamp fails to append.
///
core& append(const types::b_timestamp& value);
///
/// Appends a BSON 64-bit signed integer.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the 64-bit signed integer fails to append.
///
core& append(const types::b_int64& value);
///
/// Appends a BSON Decimal128.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the Decimal128 fails to append.
///
core& append(const types::b_decimal128& value);
///
/// Appends a BSON min-key.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the min-key fails to append.
///
core& append(const types::b_minkey& value);
///
/// Appends a BSON max-key.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
/// bsoncxx::exception if the max-key fails to append.
///
core& append(const types::b_maxkey& value);
///
/// Appends a BSON variant value.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(const types::bson_value::view& value);
///
/// Appends an STL string as a BSON UTF-8 string.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(std::string str);
///
/// Appends a string view as a BSON UTF-8 string.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(stdx::string_view str);
///
/// Appends a char* or const char*.
///
/// We disable all other pointer types to prevent the surprising implicit conversion to bool.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
template <typename T>
BSONCXX_INLINE core& append(T* v) {
static_assert(std::is_same<typename std::remove_const<T>::type, char>::value,
"append is disabled for non-char pointer types");
append(types::b_string{v});
return *this;
}
///
/// Appends a native boolean as a BSON boolean.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(bool value);
///
/// Appends a native double as a BSON double.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(double value);
///
/// Appends a native int32_t as a BSON 32-bit signed integer.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(std::int32_t value);
///
/// Appends a native int64_t as a BSON 64-bit signed integer.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(std::int64_t value);
///
/// Appends an oid as a BSON ObjectId.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(const oid& value);
///
/// Appends a decimal128 object as a BSON Decimal128.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(decimal128 value);
///
/// Appends the given document view.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(document::view view);
///
/// Appends the given array view.
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws
/// bsoncxx::exception if the current BSON datum is a document that is waiting for a key to be
/// appended to start a new key/value pair.
///
core& append(array::view view);
///
/// Gets a view over the document.
///
/// @return A document::view of the internal BSON.
///
/// @pre
/// The top-level BSON datum should be a document that is not waiting for a key to be
/// appended to start a new key/value pair, and does contain any open sub-documents or open
/// sub-arrays.
///
/// @throws bsoncxx::exception if the precondition is violated.
///
document::view view_document() const;
///
/// Gets a view over the array.
///
/// @return An array::view of the internal BSON.
///
/// @pre
/// The top-level BSON datum should be an array that does not contain any open sub-documents
/// or open sub-arrays.
///
/// @throws bsoncxx::exception if the precondition is violated.
///
array::view view_array() const;
///
/// Transfers ownership of the underlying document to the caller.
///
/// @return A document::value with ownership of the document.
///
/// @pre
/// The top-level BSON datum should be a document that is not waiting for a key to be
/// appended to start a new key/value pair, and does not contain any open sub-documents or
/// open sub-arrays.
///
/// @throws bsoncxx::exception if the precondition is violated.
///
/// @warning
/// After calling extract_document() it is illegal to call any methods on this class, unless
/// it is subsequenly moved into.
///
document::value extract_document();
///
/// Transfers ownership of the underlying document to the caller.
///
/// @return A document::value with ownership of the document.
///
/// @pre
/// The top-level BSON datum should be an array that does not contain any open sub-documents
/// or open sub-arrays.
///
/// @throws bsoncxx::exception if the precondition is violated.
///
/// @warning
/// After calling extract_array() it is illegal to call any methods on this class, unless it
/// is subsequenly moved into.
///
array::value extract_array();
///
/// Deletes the contents of the underlying BSON datum. After calling clear(), the state of this
/// class will be the same as it was immediately after construction.
///
void clear();
private:
std::unique_ptr<impl> _impl;
};
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,188 @@
// Copyright 2020 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <sstream>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/exception/error_code.hpp>
#include <bsoncxx/exception/exception.hpp>
#include <bsoncxx/types/bson_value/value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
using namespace bsoncxx::types;
///
/// A JSON-like builder for creating documents and arrays.
///
class list {
using initializer_list_t = std::initializer_list<list>;
public:
///
/// Creates an empty document.
///
list() : list({}) {}
///
/// Creates a bsoncxx::builder::list from a value of type T. T must be a
/// bsoncxx::types::bson_value::value or implicitly convertible to a
/// bsoncxx::types::bson_value::value.
///
/// @param value
/// the BSON value
///
/// @see bsoncxx::types::bson_value::value.
///
template <typename T>
list(T value) : val{value} {}
///
/// Creates a BSON document, if possible. Otherwise, it will create a BSON array. A document is
/// possible if:
// 1. The initializer list's size is even; this implies a list of
// key-value pairs or an empty document if the size is zero.
// 2. Each 'key' is a string type. In a list of key-value pairs, the 'key' is every other
// element starting at the 0th element.
//
/// @param init
/// the initializer list used to construct the BSON document or array
///
/// @note
/// to enforce the creation of a BSON document or array use the bsoncxx::builder::document
/// or bsoncxx::builder::array constructor, respectively.
///
/// @see bsoncxx::builder::document
/// @see bsoncxx::builder::array
///
list(initializer_list_t init) : list(init, true, true) {}
///
/// Provides a view of the underlying BSON value.
///
/// @see bsoncxx::types::bson_value::view.
///
operator bson_value::view() {
return view();
}
///
/// Provides a view of the underlying BSON value.
///
/// @see bsoncxx::types::bson_value::view.
///
bson_value::view view() {
return val.view();
}
private:
bson_value::value val;
friend class document;
friend class array;
list(initializer_list_t init, bool type_deduction, bool is_array) : val{nullptr} {
std::stringstream err_msg{"cannot construct document"};
bool valid_document = false;
if (type_deduction || !is_array) {
valid_document = [&] {
if (init.size() % 2 != 0) {
err_msg << " : must be list of key-value pairs";
return false;
}
for (size_t i = 0; i < init.size(); i += 2) {
auto t = (begin(init) + i)->val.view().type();
if (t != type::k_utf8) {
err_msg << " : all keys must be string type. ";
err_msg << "Found type=" << to_string(t);
return false;
}
}
return true;
}();
}
if (valid_document) {
core _core{false};
for (size_t i = 0; i < init.size(); i += 2) {
_core.key_owned(std::string((begin(init) + i)->val.view().get_string().value));
_core.append((begin(init) + i + 1)->val);
}
val = bson_value::value(_core.extract_document());
} else if (type_deduction || is_array) {
core _core{true};
for (auto&& ele : init)
_core.append(ele.val);
val = bson_value::value(_core.extract_array());
} else {
throw bsoncxx::exception{error_code::k_unmatched_key_in_builder, err_msg.str()};
}
}
};
///
/// A JSON-like builder for creating documents.
///
class document : public list {
using initializer_list_t = std::initializer_list<list>;
public:
///
/// Creates an empty document.
///
document() : list({}, false, false){};
///
/// Creates a BSON document.
///
/// @param init
/// the initializer list used to construct the BSON document
///
/// @see bsoncxx::builder::list
/// @see bsoncxx::builder::array
///
document(initializer_list_t init) : list(init, false, false) {}
};
///
/// A JSON-like builder for creating arrays.
///
class array : public list {
using initializer_list_t = std::initializer_list<list>;
public:
///
/// Creates an empty array.
///
array() : list({}, false, true){};
///
/// Creates a BSON array.
///
/// @param init
/// the initializer list used to construct the BSON array
///
/// @see bsoncxx::builder::list
/// @see bsoncxx::builder::document
///
array(initializer_list_t init) : list(init, false, true) {}
};
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx

View File

@@ -0,0 +1,90 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/array/value.hpp>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/builder/stream/array_context.hpp>
#include <bsoncxx/builder/stream/key_context.hpp>
#include <bsoncxx/builder/stream/single_context.hpp>
#include <bsoncxx/builder/stream/value_context.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
///
/// A streaming interface for constructing
/// a BSON array.
///
/// @note Use of the stream builder is discouraged. See
/// http://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/working-with-bson/#stream-builder for more
/// details.
///
class array : public array_context<> {
public:
///
/// Default constructor.
///
BSONCXX_INLINE array() : array_context<>(&_core), _core(true) {}
///
/// @return A view of the BSON array.
///
BSONCXX_INLINE bsoncxx::array::view view() const {
return _core.view_array();
}
///
/// @return A view of the BSON array.
///
BSONCXX_INLINE operator bsoncxx::array::view() const {
return view();
}
///
/// Transfer ownership of the underlying array to the caller.
///
/// @return An array::value with ownership of the array.
///
/// @warning
/// After calling extract() it is illegal to call any methods
/// on this class, unless it is subsequenly moved into.
///
BSONCXX_INLINE bsoncxx::array::value extract() {
return _core.extract_array();
}
///
/// Reset the underlying BSON to an empty array.
///
BSONCXX_INLINE void clear() {
_core.clear();
}
private:
core _core;
};
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,202 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/array/value.hpp>
#include <bsoncxx/builder/concatenate.hpp>
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/builder/stream/closed_context.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/util/functor.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
template <class T>
class key_context;
class single_context;
///
/// A stream context which expects any number of values.
///
/// The template argument can be used to hold additional information about
/// containing documents or arrays. I.e. value_context<> implies that this array
/// is a sub_array in a document, while array_context would indicated a sub_array
/// in an array. These types can be nested, such that contextual parsing (for
/// key/value pairs) and depth (to prevent an invalid array_close) are enforced
/// by the type system.
///
/// I.e.
/// builder << array_context << array_context << ...;
///
/// This builds a bson array with successively higher index keys
///
template <class base = closed_context>
class array_context {
public:
///
/// Create an array_context given a core builder
///
/// @param core
/// The core builder to orchestrate
///
BSONCXX_INLINE array_context(core* core) : _core(core) {}
///
/// << operator for accepting a real value and appending it to the core
/// builder.
///
/// @param t
/// The value to append
///
template <class T>
BSONCXX_INLINE typename std::enable_if<
!(util::is_functor<T, void(array_context<>)>::value ||
util::is_functor<T, void(single_context)>::value ||
std::is_same<typename std::remove_reference<T>::type, const finalize_type>::value),
array_context>::type&
operator<<(T&& t) {
_core->append(std::forward<T>(t));
return *this;
}
///
/// << operator for accepting a callable of the form void(array_context) or
/// void(single_context) and invoking it to perform 1 or more value appends
/// to the core builder.
///
/// @param func
/// The callback to invoke
///
template <typename Func>
BSONCXX_INLINE typename std::enable_if<(util::is_functor<Func, void(array_context<>)>::value ||
util::is_functor<Func, void(single_context)>::value),
array_context>::type&
operator<<(Func&& func) {
func(*this);
return *this;
}
///
/// << operator for finalizing the stream.
///
/// This operation finishes all processing necessary to fully encode the
/// bson bytes and returns an owning value.
///
/// @param _
/// A finalize_type token
///
/// @return A value type which holds the complete bson document.
///
template <typename T>
BSONCXX_INLINE typename std::enable_if<
std::is_same<base, closed_context>::value &&
std::is_same<typename std::remove_reference<T>::type, const finalize_type>::value,
// TODO(MSVC): This should just be 'array::value', but
// VS2015U1 can't resolve the name.
bsoncxx::array::value>::type
operator<<(T&&) {
return _core->extract_array();
}
///
/// << operator for opening a new subdocument in the core builder.
///
/// @param _
/// An open_document_type token
///
BSONCXX_INLINE key_context<array_context> operator<<(const open_document_type) {
_core->open_document();
return wrap_document();
}
///
/// << operator for concatenating another array.
///
/// This operation concatenates all of the values from the passed document
/// into the current stream. Keys are adjusted to match the existing array.
///
/// @param array
/// An array to concatenate
///
BSONCXX_INLINE array_context operator<<(concatenate_array array) {
_core->concatenate(array.view());
return *this;
}
///
/// << operator for opening a new subarray in the core builder.
///
/// @param _
/// An open_document_type token
///
BSONCXX_INLINE array_context<array_context> operator<<(const open_array_type) {
_core->open_array();
return wrap_array();
}
///
/// << operator for closing a subarray in the core builder.
///
/// @param _
/// A close_array_type token
///
BSONCXX_INLINE base operator<<(const close_array_type) {
_core->close_array();
return unwrap();
}
///
/// Conversion operator which provides a rooted array context given any
/// stream currently in a nested array_context.
///
BSONCXX_INLINE operator array_context<>() {
return array_context<>(_core);
}
///
/// Conversion operator for single_context.
///
/// @relatesalso single_context
///
BSONCXX_INLINE operator single_context();
private:
BSONCXX_INLINE base unwrap() {
return base(_core);
}
BSONCXX_INLINE array_context<array_context> wrap_array() {
return array_context<array_context>(_core);
}
BSONCXX_INLINE key_context<array_context> wrap_document() {
return key_context<array_context>(_core);
}
core* _core;
};
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,43 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
class core;
namespace stream {
///
/// The closed_context, when used as a template parameter for array_context,
/// value_context or key_context, indicates that the document cannot be closed
/// further. This could indicate that the document is the root, or that the type
/// stack has been intentionally erased, as is the case when using callbacks in
/// the stream api.
///
struct closed_context {
closed_context(core*) {}
};
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,88 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/builder/stream/key_context.hpp>
#include <bsoncxx/builder/stream/single_context.hpp>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
///
/// A streaming interface for constructing
/// a BSON document.
///
/// @note Use of the stream builder is discouraged. See
/// http://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/working-with-bson/#stream-builder for more
/// details.
///
class document : public key_context<> {
public:
///
/// Default constructor.
///
BSONCXX_INLINE document() : key_context<>(&_core), _core(false) {}
///
/// @return A view of the BSON document.
///
BSONCXX_INLINE bsoncxx::document::view view() const {
return _core.view_document();
}
///
/// @return A view of the BSON document.
///
BSONCXX_INLINE operator bsoncxx::document::view() const {
return view();
}
///
/// Transfer ownership of the underlying document to the caller.
///
/// @return A document::value with ownership of the document.
///
/// @warning
/// After calling extract() it is illegal to call any methods
/// on this class, unless it is subsequenly moved into.
///
BSONCXX_INLINE bsoncxx::document::value extract() {
return _core.extract_document();
}
///
/// Reset the underlying BSON to an empty document.
///
BSONCXX_INLINE void clear() {
_core.clear();
}
private:
core _core;
};
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,98 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/concatenate.hpp>
#include <bsoncxx/document/view_or_value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
using bsoncxx::builder::concatenate;
///
/// The type of a stream manipulator to open a subdocument.
///
struct BSONCXX_API open_document_type {
constexpr open_document_type() {}
};
///
/// A stream manipulator to open a subdocument.
///
constexpr open_document_type open_document;
///
/// The type of a stream manipulator to close a subdocument.
///
struct BSONCXX_API close_document_type {
constexpr close_document_type() {}
};
///
/// A stream manipulator to close a subdocument.
///
constexpr close_document_type close_document;
///
/// The type of a stream manipulator to open a subarray.
///
struct BSONCXX_API open_array_type {
constexpr open_array_type() {}
};
///
/// A stream manipulator to open a subarray.
///
/// @see https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/working-with-bson/#builders for help
/// building arrays in loops.
///
constexpr open_array_type open_array;
///
/// The type of a stream manipulator to close a subarray.
///
struct BSONCXX_API close_array_type {
constexpr close_array_type() {}
};
///
/// A stream manipulator to close a subarray.
///
constexpr close_array_type close_array;
///
/// The type of a stream manipulator to finalize a document.
///
struct BSONCXX_API finalize_type {
constexpr finalize_type() {}
};
///
/// A stream manipulator to finalize a document. When finalize is passed,
/// the expression will evaluate to an owning document::value or array::value.
///
constexpr finalize_type finalize;
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,186 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/builder/stream/closed_context.hpp>
#include <bsoncxx/builder/stream/value_context.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/util/functor.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
///
/// A stream context which expects a key, which can later be followed by
/// value, then more key/value pairs.
///
/// The template argument can be used to hold additional information about
/// containing documents or arrays. I.e. value_context<> implies that this
/// document is a sub_document in a document, while array_context would
/// indicated a sub_document in an array. These types can be nested, such that
/// contextual parsing (for key/value pairs) and depth (to prevent an invalid
/// document_close) are enforced by the type system.
///
/// When in document context, the first parameter will be in key_context, then
/// in value_context, then in key_context, etc.
///
/// I.e.
/// builder << key_context << value_context << key_context << ...
///
template <class base = closed_context>
class key_context {
public:
///
/// Create a key_context given a core builder
///
/// @param core
/// The core builder to orchestrate
///
key_context(core* core) : _core(core) {}
///
/// << operator for accepting a literal key and appending it to the core
/// builder.
///
/// @param v
/// The key to append
///
/// @throws bsoncxx::exception if the previous value appended to the builder was also a key.
///
template <std::size_t n>
BSONCXX_INLINE value_context<key_context> operator<<(const char (&v)[n]) {
_core->key_view(stdx::string_view{v, n - 1});
return value_context<key_context>(_core);
}
///
/// << operator for accepting a std::string key and appending it to the core
/// builder.
///
/// @param str
/// The key to append
///
/// @throws bsoncxx::exception if the previous value appended to the builder was also a key.
///
BSONCXX_INLINE value_context<key_context> operator<<(std::string str) {
_core->key_owned(std::move(str));
return value_context<key_context>(_core);
}
///
/// << operator for accepting a stdx::string_view key and appending it to
/// the core builder.
///
/// @param str
/// The key to append
///
/// @throws bsoncxx::exception if the previous value appended to the builder was also a key.
///
BSONCXX_INLINE value_context<key_context> operator<<(stdx::string_view str) {
_core->key_view(std::move(str));
return value_context<key_context>(_core);
}
///
/// << operator for accepting a callable of the form void(key_context)
/// and invoking it to perform 1 or more key, value appends to the core
/// builder.
///
/// @param func
/// The callback to invoke
///
template <typename T>
BSONCXX_INLINE
typename std::enable_if<util::is_functor<T, void(key_context<>)>::value, key_context>::type&
operator<<(T&& func) {
func(*this);
return *this;
}
///
/// << operator for finalizing the stream.
///
/// This operation finishes all processing necessary to fully encode the
/// bson bytes and returns an owning value.
///
/// @param _
/// A finalize_type token
///
/// @return A value type which holds the complete bson document.
///
template <typename T>
BSONCXX_INLINE typename std::enable_if<
std::is_same<base, closed_context>::value &&
std::is_same<typename std::remove_reference<T>::type, const finalize_type>::value,
// TODO(MSVC): This should just be 'document::value', but
// VS2015U1 can't resolve the name.
bsoncxx::document::value>::type
operator<<(T&&) {
return _core->extract_document();
}
///
/// << operator for concatenating another document.
///
/// This operation concatenates all of the keys and values from the passed
/// document into the current stream.
///
/// @param doc
/// A document to concatenate
///
BSONCXX_INLINE key_context operator<<(concatenate_doc doc) {
_core->concatenate(doc);
return *this;
}
///
/// << operator for closing a subdocument in the core builder.
///
/// @param _
/// A close_document_type token
///
BSONCXX_INLINE base operator<<(const close_document_type) {
_core->close_document();
return unwrap();
}
///
/// Conversion operator which provides a rooted document given any stream
/// currently in a nested key_context.
///
BSONCXX_INLINE operator key_context<>() {
return key_context<>(_core);
}
private:
BSONCXX_INLINE base unwrap() {
return base(_core);
}
core* _core;
};
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,115 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/builder/stream/array_context.hpp>
#include <bsoncxx/builder/stream/key_context.hpp>
#include <bsoncxx/builder/stream/value_context.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
///
/// A stream context which appends a single value.
///
/// This type is useful as the argument to a callable passed to other stream
/// modes. Specifically, any callback that takes a single_context can be used to
/// write a value in value_context or array_context.
///
class single_context {
public:
///
/// Create a single_context given a core builder
///
/// @param core
/// The core builder to orchestrate
///
BSONCXX_INLINE single_context(core* core) : _core(core) {}
///
/// << operator for opening a new subdocument in the core builder.
///
/// @param _
/// An open_document_type token
///
BSONCXX_INLINE key_context<> operator<<(open_document_type) {
_core->open_document();
return wrap_document();
}
///
/// << operator for opening a new subarray in the core builder.
///
/// @param _
/// An open_array_type token
///
BSONCXX_INLINE array_context<> operator<<(open_array_type) {
_core->open_array();
return wrap_array();
}
///
/// << operator for accepting a real value and appending it to the core
/// builder.
///
/// @param t
/// The value to append
///
template <class T>
BSONCXX_INLINE void operator<<(T&& t) {
_core->append(std::forward<T>(t));
}
private:
BSONCXX_INLINE array_context<> wrap_array() {
return array_context<>(_core);
}
BSONCXX_INLINE key_context<> wrap_document() {
return key_context<>(_core);
}
core* _core;
};
///
/// Implementation of the single_context conversion operator for array_context.
///
template <class T>
BSONCXX_INLINE array_context<T>::operator single_context() {
return single_context(_core);
}
///
/// Implementation of the single_context conversion operator for value_context.
///
template <class T>
BSONCXX_INLINE value_context<T>::operator single_context() {
return single_context(_core);
}
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,145 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/builder/stream/array_context.hpp>
#include <bsoncxx/builder/stream/closed_context.hpp>
#include <bsoncxx/builder/stream/helpers.hpp>
#include <bsoncxx/util/functor.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace builder {
namespace stream {
///
/// A stream context which expects a value, which can later be followed by
/// more key/value pairs.
///
/// The template argument can be used to hold additional information about
/// containing documents or arrays. I.e. value_context<> implies that this
/// document is a sub_document in a document, while array_context would
/// indicated a sub_document in an array. These types can be nested, such that
/// contextual parsing (for key/value pairs) and depth (to prevent an invalid
/// document_close) are enforced by the type system.
///
/// When in document context, the first parameter will be in key_context, then
/// in value_context, then in key_context, etc.
///
/// I.e.
/// builder << key_context << value_context << key_context << ...
///
template <class base>
class value_context {
public:
///
/// Create a value_context given a core builder
///
/// @param core
/// The core builder to orchestrate
///
BSONCXX_INLINE value_context(core* core) : _core(core) {}
///
/// << operator for accepting a real value and appending it to the core
/// builder.
///
/// @param t
/// The value to append
///
template <class T>
BSONCXX_INLINE
typename std::enable_if<!util::is_functor<T, void(single_context)>::value, base>::type
operator<<(T&& t) {
_core->append(std::forward<T>(t));
return unwrap();
}
///
/// << operator for accepting a callable of the form void(single_context)
/// and invoking it to perform a value append to the core builder.
///
/// @param func
/// The callback to invoke
///
template <typename T>
BSONCXX_INLINE
typename std::enable_if<util::is_functor<T, void(single_context)>::value, base>::type
operator<<(T&& func) {
func(*this);
return unwrap();
}
///
/// << operator for opening a new subdocument in the core builder.
///
/// @param _
/// An open_document_type token
///
BSONCXX_INLINE key_context<base> operator<<(const open_document_type) {
_core->open_document();
return wrap_document();
}
///
/// << operator for opening a new subarray in the core builder.
///
/// @param _
/// An open_array_type token
///
BSONCXX_INLINE array_context<base> operator<<(const open_array_type) {
_core->open_array();
return wrap_array();
}
///
/// Conversion operator for single_context.
///
/// @relatesalso single_context
///
operator single_context();
#if !defined(_MSC_VER) && !defined(__INTEL_COMPILER)
// TODO(MSVC): Causes an ICE under VS2015U1
static_assert(
std::is_same<value_context, decltype(std::declval<value_context>() << 1 << "str")>::value,
"value_context must be templatized on a key_context");
#endif
private:
BSONCXX_INLINE base unwrap() {
return base(_core);
}
BSONCXX_INLINE array_context<base> wrap_array() {
return array_context<base>(_core);
}
BSONCXX_INLINE key_context<base> wrap_document() {
return key_context<base>(_core);
}
core* _core;
};
} // namespace stream
} // namespace builder
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,32 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#if defined(_MSC_VER)
// Disable MSVC warnings that cause a lot of noise related to DLL visibility
// for types that we don't control (like std::unique_ptr).
#pragma warning(push)
#pragma warning(disable : 4251 4275)
#define BSONCXX_INLINE inline BSONCXX_PRIVATE
#define BSONCXX_CALL __cdecl
#else
#define BSONCXX_INLINE inline BSONCXX_PRIVATE
#define BSONCXX_CALL
#endif

View File

@@ -0,0 +1,23 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/* #undef BSONCXX_POLY_USE_STD_EXPERIMENTAL */
#define BSONCXX_POLY_USE_MNMLSTC
/* #undef BSONCXX_POLY_USE_SYSTEM_MNMLSTC */
/* #undef BSONCXX_POLY_USE_BOOST */
/* #undef BSONCXX_POLY_USE_STD */
#define BSONCXX_INLINE_NAMESPACE_BEGIN inline namespace v_noabi {
#define BSONCXX_INLINE_NAMESPACE_END } // namespace v_noabi

View File

@@ -0,0 +1,42 @@
#ifndef BSONCXX_API_H
#define BSONCXX_API_H
#ifdef BSONCXX_STATIC
# define BSONCXX_API
# define BSONCXX_PRIVATE
#else
# ifndef BSONCXX_API
# ifdef BSONCXX_EXPORT
/* We are building this library */
# define BSONCXX_API __attribute__((visibility("default")))
# else
/* We are using this library */
# define BSONCXX_API __attribute__((visibility("default")))
# endif
# endif
# ifndef BSONCXX_PRIVATE
# define BSONCXX_PRIVATE __attribute__((visibility("hidden")))
# endif
#endif
#ifndef BSONCXX_DEPRECATED
# define BSONCXX_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef BSONCXX_DEPRECATED_EXPORT
# define BSONCXX_DEPRECATED_EXPORT BSONCXX_API BSONCXX_DEPRECATED
#endif
#ifndef BSONCXX_DEPRECATED_NO_EXPORT
# define BSONCXX_DEPRECATED_NO_EXPORT BSONCXX_PRIVATE BSONCXX_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef BSONCXX_NO_DEPRECATED
# define BSONCXX_NO_DEPRECATED
# endif
#endif
#endif /* BSONCXX_API_H */

View File

@@ -0,0 +1,74 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// compiler.hpp
#undef BSONCXX_INLINE
#pragma pop_macro("BSONCXX_INLINE")
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#undef BSONCXX_CALL
#pragma pop_macro("BSONCXX_CALL")
// src/bsoncxx/config/config.hpp.in
#undef BSONCXX_INLINE_NAMESPACE_BEGIN
#pragma pop_macro("BSONCXX_INLINE_NAMESPACE_BEGIN")
#undef BSONCXX_INLINE_NAMESPACE_END
#pragma pop_macro("BSONCXX_INLINE_NAMESPACE_END")
#undef BSONCXX_POLY_USE_MNMLSTC
#pragma pop_macro("BSONCXX_POLY_USE_MNMLSTC")
#undef BSONCXX_POLY_USE_STD_EXPERIMENTAL
#pragma pop_macro("BSONCXX_POLY_USE_STD_EXPERIMENTAL")
#undef BSONCXX_POLY_USE_SYSTEM_MNMLSTC
#pragma pop_macro("BSONCXX_POLY_USE_SYSTEM_MNMLSTC")
#undef BSONCXX_POLY_USE_BOOST
#pragma pop_macro("BSONCXX_POLY_USE_BOOST")
// src/bsoncxx/config/version.hpp.in
#undef BSONCXX_VERSION_EXTRA
#pragma pop_macro("BSONCXX_VERSION_EXTRA")
#undef BSONCXX_VERSION_MAJOR
#pragma pop_macro("BSONCXX_VERSION_MAJOR")
#undef BSONCXX_VERSION_MINOR
#pragma pop_macro("BSONCXX_VERSION_MINOR")
#undef BSONCXX_VERSION_PATCH
#pragma pop_macro("BSONCXX_VERSION_PATCH")
// src/bsoncxx/types.hpp
#ifdef BSONCXX_ENUM
static_assert(false, "BSONCXX_ENUM must be undef'ed");
#endif
#pragma pop_macro("BSONCXX_ENUM")
// export.hpp (generated by cmake)
#undef BSONCXX_API_H
#pragma pop_macro("BSONCXX_API_H")
#undef BSONCXX_API
#pragma pop_macro("BSONCXX_API")
#undef BSONCXX_PRIVATE
#pragma pop_macro("BSONCXX_PRIVATE")
#undef BSONCXX_DEPRECATED
#pragma pop_macro("BSONCXX_DEPRECATED")
#undef BSONCXX_DEPRECATED_EXPORT
#pragma pop_macro("BSONCXX_DEPRECATED_EXPORT")
#undef BSONCXX_DEPRECATED_NO_EXPORT
#pragma pop_macro("BSONCXX_DEPRECATED_NO_EXPORT")
#undef DEFINE_NO_DEPRECATED
#pragma pop_macro("DEFINE_NO_DEPRECATED")
#undef BSONCXX_NO_DEPRECATED
#pragma pop_macro("BSONCXX_NO_DEPRECATED")
// prelude.hpp
#undef BSONCXX_UNREACHABLE
#pragma pop_macro("BSONCXX_UNREACHABLE")

View File

@@ -0,0 +1,74 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// compiler.hpp
#pragma push_macro("BSONCXX_INLINE")
#undef BSONCXX_INLINE
#pragma push_macro("BSONCXX_CALL")
#undef BSONCXX_CALL
// src/bsoncxx/config/config.hpp.in
#pragma push_macro("BSONCXX_INLINE_NAMESPACE_BEGIN")
#undef BSONCXX_INLINE_NAMESPACE_BEGIN
#pragma push_macro("BSONCXX_INLINE_NAMESPACE_END")
#undef BSONCXX_INLINE_NAMESPACE_END
#pragma push_macro("BSONCXX_POLY_USE_MNMLSTC")
#undef BSONCXX_POLY_USE_MNMLSTC
#pragma push_macro("BSONCXX_POLY_USE_STD_EXPERIMENTAL")
#undef BSONCXX_POLY_USE_STD_EXPERIMENTAL
#pragma push_macro("BSONCXX_POLY_USE_SYSTEM_MNMLSTC")
#undef BSONCXX_POLY_USE_SYSTEM_MNMLSTC
#pragma push_macro("BSONCXX_POLY_USE_BOOST")
#undef BSONCXX_POLY_USE_BOOST
// src/bsoncxx/config/version.hpp.in
#pragma push_macro("BSONCXX_VERSION_EXTRA")
#undef BSONCXX_VERSION_EXTRA
#pragma push_macro("BSONCXX_VERSION_MAJOR")
#undef BSONCXX_VERSION_MAJOR
#pragma push_macro("BSONCXX_VERSION_MINOR")
#undef BSONCXX_VERSION_MINOR
#pragma push_macro("BSONCXX_VERSION_PATCH")
#undef BSONCXX_VERSION_PATCH
// src/bsoncxx/types.hpp
#pragma push_macro("BSONCXX_ENUM")
#undef BSONCXX_ENUM
// export.hpp (generated by cmake)
#pragma push_macro("BSONCXX_API_H")
#undef BSONCXX_API_H
#pragma push_macro("BSONCXX_API")
#undef BSONCXX_API
#pragma push_macro("BSONCXX_PRIVATE")
#undef BSONCXX_PRIVATE
#pragma push_macro("BSONCXX_DEPRECATED")
#undef BSONCXX_DEPRECATED
#pragma push_macro("BSONCXX_DEPRECATED_EXPORT")
#undef BSONCXX_DEPRECATED_EXPORT
#pragma push_macro("BSONCXX_DEPRECATED_NO_EXPORT")
#undef BSONCXX_DEPRECATED_NO_EXPORT
#pragma push_macro("DEFINE_NO_DEPRECATED")
#undef DEFINE_NO_DEPRECATED
#pragma push_macro("BSONCXX_NO_DEPRECATED")
#undef BSONCXX_NO_DEPRECATED
#include <bsoncxx/config/compiler.hpp>
#include <bsoncxx/config/config.hpp>
#include <bsoncxx/config/export.hpp>
#include <bsoncxx/config/version.hpp>
#pragma push_macro("BSONCXX_UNREACHABLE")
#undef BSONCXX_UNREACHABLE
#define BSONCXX_UNREACHABLE std::abort()

View File

@@ -0,0 +1,18 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#define BSONCXX_VERSION_MAJOR 3
#define BSONCXX_VERSION_MINOR 7
#define BSONCXX_VERSION_PATCH 1
#define BSONCXX_VERSION_EXTRA

View File

@@ -0,0 +1,100 @@
// Copyright 2016 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstdint>
#include <string>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
///
/// Represents an IEEE 754-2008 BSON Decimal128 value in a platform-independent way.
///
class BSONCXX_API decimal128 {
public:
///
/// Constructs a BSON Decimal128 value representing zero.
///
decimal128() = default;
///
/// Constructs a BSON Decimal128 from high and low 64-bit big-endian parts.
///
/// @param high
/// The high 64-bits.
/// @param low
/// The low 64-bits.
///
decimal128(uint64_t high, uint64_t low) noexcept : _high(high), _low(low) {}
///
/// Constructs a BSON Decimal128 from a string.
///
/// @param str
/// A string representation of a decimal number.
///
/// @throws bsoncxx::exception if the string isn't a valid BSON Decimal128
/// representation.
///
explicit decimal128(stdx::string_view str);
///
/// Converts this decimal128 value to a string representation.
///
/// @return A string representation of a IEEE 754-2008 decimal number.
///
std::string to_string() const;
///
/// @{
///
/// Relational operators for decimal128
///
/// @relates decimal128
///
friend BSONCXX_API bool BSONCXX_CALL operator==(const decimal128& lhs, const decimal128& rhs);
friend BSONCXX_API bool BSONCXX_CALL operator!=(const decimal128& lhs, const decimal128& rhs);
///
/// @}
///
///
/// Accessor for high 64 bits.
///
BSONCXX_INLINE uint64_t high() const {
return _high;
}
///
/// Accessor for low 64 bits.
///
BSONCXX_INLINE uint64_t low() const {
return _low;
}
private:
uint64_t _high = 0;
uint64_t _low = 0;
};
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,448 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstddef>
#include <cstdint>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
enum class type : std::uint8_t;
enum class binary_sub_type : std::uint8_t;
namespace types {
struct b_eod;
struct b_double;
struct b_string;
struct b_document;
struct b_array;
struct b_binary;
struct b_undefined;
struct b_oid;
struct b_bool;
struct b_date;
struct b_null;
struct b_regex;
struct b_dbpointer;
struct b_code;
struct b_symbol;
struct b_codewscope;
struct b_int32;
struct b_timestamp;
struct b_int64;
struct b_decimal128;
struct b_minkey;
struct b_maxkey;
namespace bson_value {
class value;
class view;
} // namespace bson_value
} // namespace types
namespace array {
class element;
} // namespace array
namespace document {
///
/// A variant view type that accesses values in serialized BSON documents.
///
/// Element functions as a variant type, where the kind of the element can be
/// interrogated by calling type(), the key can be extracted by calling key() and
/// a specific value can be extracted through get_X() accessors.
///
/// @relatesalso array::element
///
class BSONCXX_API element {
public:
///
/// Construct an invalid element.
///
/// This is useful when mapping the end iterator of a document or array
/// view.
///
element();
///
/// Conversion operator to bool which is true for valid elements
/// and false for invalid elements.
///
explicit operator bool() const;
///
/// Getter for the raw bson bytes the element points to.
///
/// @return a pointer to the raw bson bytes.
///
const std::uint8_t* raw() const;
///
/// Getter for length of the raw bson bytes the element points to.
///
/// @return a pointer to the length of the raw bson bytes.
///
std::uint32_t length() const;
///
/// Getter for the offset into the raw bson bytes the element points to.
///
/// @return the offset into the raw bson bytes.
///
std::uint32_t offset() const;
///
/// Getter for the type of the element.
///
/// @return the element's type.
///
/// @throws bsoncxx::exception if this element is invalid.
///
bsoncxx::type type() const;
///
/// Getter for the element's key.
///
/// @return the element's key.
///
/// @throws bsoncxx::exception if this element is invalid.
///
stdx::string_view key() const;
///
/// Getter for the element's key length.
///
/// @return the element's key length.
///
std::uint32_t keylen() const;
///
/// Getter for elements of the b_double type.
///
/// @throws bsoncxx::exception if this element is not a b_double.
///
/// @return the element's value.
///
types::b_double get_double() const;
///
/// Getter for elements of the b_string type.
///
/// @deprecated use document::element::get_string() instead.
///
/// @throws bsoncxx::exception if this element is not a b_string.
///
/// @return the element's value.
///
BSONCXX_DEPRECATED types::b_string get_utf8() const;
///
/// Getter for elements of the b_string type.
///
/// @throws bsoncxx::exception if this element is not a b_string.
///
/// @return the element's value.
///
types::b_string get_string() const;
///
/// Getter for elements of the b_document type.
///
/// @throws bsoncxx::exception if this element is not a b_document.
///
/// @return the element's value.
///
types::b_document get_document() const;
///
/// Getter for elements of the b_array type.
///
/// @throws bsoncxx::exception if this element is not a b_array.
///
/// @return the element's value.
///
types::b_array get_array() const;
///
/// Getter for elements of the b_binary type.
///
/// @throws bsoncxx::exception if this element is not a b_binary.
///
/// @return the element's value.
///
types::b_binary get_binary() const;
///
/// Getter for elements of the b_undefined type.
///
/// @throws bsoncxx::exception if this element is not a b_undefined.
///
/// @return the element's value.
///
types::b_undefined get_undefined() const;
///
/// Getter for elements of the b_oid type.
///
/// @throws bsoncxx::exception if this element is not a b_oid.
///
/// @return the element's value.
///
types::b_oid get_oid() const;
///
/// Getter for elements of the b_bool type.
///
/// @throws bsoncxx::exception if this element is not a b_bool.
///
/// @return the element's value.
///
types::b_bool get_bool() const;
///
/// Getter for elements of the b_date type.
///
/// @throws bsoncxx::exception if this element is not a b_date.
///
/// @return the element's value.
///
types::b_date get_date() const;
///
/// Getter for elements of the b_null type.
///
/// @throws bsoncxx::exception if this element is not a b_null.
///
/// @return the element's value.
///
types::b_null get_null() const;
///
/// Getter for elements of the b_regex type.
///
/// @throws bsoncxx::exception if this element is not a b_regex.
///
/// @return the element's value.
///
types::b_regex get_regex() const;
///
/// Getter for elements of the b_dbpointer type.
///
/// @throws bsoncxx::exception if this element is not a b_dbpointer.
///
/// @return the element's value.
///
types::b_dbpointer get_dbpointer() const;
///
/// Getter for elements of the b_code type.
///
/// @throws bsoncxx::exception if this element is not a b_code.
///
/// @return the element's value.
///
types::b_code get_code() const;
///
/// Getter for elements of the b_symbol type.
///
/// @throws bsoncxx::exception if this element is not a b_symbol.
///
/// @return the element's value.
///
types::b_symbol get_symbol() const;
///
/// Getter for elements of the b_codewscope type.
///
/// @throws bsoncxx::exception if this element is not a b_codewscope.
///
/// @return the element's value.
///
types::b_codewscope get_codewscope() const;
///
/// Getter for elements of the b_int32 type.
///
/// @throws bsoncxx::exception if this element is not a b_int32.
///
/// @return the element's value.
///
types::b_int32 get_int32() const;
///
/// Getter for elements of the b_timestamp type.
///
/// @throws bsoncxx::exception if this element is not a b_timestamp.
///
/// @return the element's value.
///
types::b_timestamp get_timestamp() const;
///
/// Getter for elements of the b_int64 type.
///
/// @throws bsoncxx::exception if this element is not a b_int64.
///
/// @return the element's value.
///
types::b_int64 get_int64() const;
///
/// Getter for elements of the b_decimal128 type.
///
/// @throws bsoncxx::exception if this element is not a b_decimal128.
///
/// @return the element's value.
///
types::b_decimal128 get_decimal128() const;
///
/// Getter for elements of the b_minkey type.
///
/// @throws bsoncxx::exception if this element is not a b_minkey.
///
/// @return the element's value.
///
types::b_minkey get_minkey() const;
///
/// Getter for elements of the b_maxkey type.
///
/// @throws bsoncxx::exception if this element is not a b_maxkey.
///
/// @return the element's value.
///
types::b_maxkey get_maxkey() const;
///
/// Getter for a types::bson_value::view variant wrapper of the value portion of the
/// element.
///
/// @return the element's value.
///
types::bson_value::view get_value() const;
///
/// Getter for a types::bson_value::value variant wrapper of the value portion of
/// the element. The returned object will make a copy of the buffer from this object.
///
/// @return an owning version of the element's value.
///
types::bson_value::value get_owning_value() const;
///
/// If this element is a document, finds the first element of the document
/// with the provided key. If there is no such element, an invalid
/// document::element will be returned. The runtime of operator[] is
/// linear in the length of the document.
///
/// If this element is not a document, an invalid document::element will
/// be returned.
///
/// @param key
/// The key to search for.
///
/// @return The matching element, if found, or an invalid element.
///
element operator[](stdx::string_view key) const;
///
/// If this element is an array, indexes into this BSON array. If the
/// index is out-of-bounds, an invalid array::element will be returned. As
/// BSON represents arrays as documents, the runtime of operator[] is
/// linear in the length of the array.
///
/// If this element is not an array, an invalid array::element will
/// be returned.
///
/// @param i
/// The index of the element.
///
/// @return The element if it exists, or an invalid element.
///
array::element operator[](std::uint32_t i) const;
private:
///
/// Construct an element as an offset into a buffer of bson bytes.
///
/// @param raw
/// A pointer to the raw bson bytes.
///
/// @param length
/// The size of the bson buffer.
///
/// @param offset
/// The element's offset into the buffer.
///
BSONCXX_PRIVATE explicit element(const std::uint8_t* raw,
std::uint32_t length,
std::uint32_t offset,
std::uint32_t keylen);
friend class view;
friend class array::element;
const std::uint8_t* _raw;
std::uint32_t _length;
std::uint32_t _offset;
std::uint32_t _keylen;
};
///
/// @{
///
/// Convenience methods to compare for equality against a bson_value.
///
/// Returns true if this element contains a bson_value that matches.
///
/// @relates element
///
BSONCXX_API bool BSONCXX_CALL operator==(const element& elem, const types::bson_value::view& v);
BSONCXX_API bool BSONCXX_CALL operator==(const types::bson_value::view& v, const element& elem);
///
/// @}
///
///
/// @{
///
/// Convenience methods to compare for equality against a bson_value.
///
/// Returns false if this element contains a bson_value that matches.
///
/// @relates element
///
BSONCXX_API bool BSONCXX_CALL operator!=(const element& elem, const types::bson_value::view& v);
BSONCXX_API bool BSONCXX_CALL operator!=(const types::bson_value::view& v, const element& elem);
///
/// @}
///
} // namespace document
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,265 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstdlib>
#include <memory>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace document {
///
/// A read-only BSON document that owns its underlying buffer. When a document::value goes
/// out of scope, the underlying buffer is freed. Generally this class should be used
/// sparingly; document::view should be used instead wherever possible.
///
class BSONCXX_API value {
public:
using deleter_type = void (*)(std::uint8_t*);
using unique_ptr_type = std::unique_ptr<uint8_t[], deleter_type>;
///
/// Constructs a value from a buffer.
/// This constructor transfers ownership of the buffer to the resulting
/// value. A user-provided deleter is used to destroy the buffer.
///
/// @param data
/// A pointer to a buffer containing a valid BSON document.
/// @param length
/// The length of the document.
/// @param dtor
/// A user provided deleter.
///
value(std::uint8_t* data, std::size_t length, deleter_type dtor);
///
/// Constructs a value from a std::unique_ptr to a buffer. The ownership
/// of the buffer is transferred to the constructed value.
///
/// @param ptr
/// A pointer to a buffer containing a valid BSON document.
/// @param length
/// The length of the document.
///
value(unique_ptr_type ptr, std::size_t length);
///
/// Constructs a value from a view of a document. The data referenced
/// by the document::view will be copied into a new buffer managed by the
/// constructed value.
///
/// @param view
/// A view of another document to copy.
///
explicit value(document::view view);
value(const value&);
value& operator=(const value&);
value(value&&) noexcept = default;
value& operator=(value&&) noexcept = default;
///
/// Constructor used for serialization of user objects. This uses argument-dependent lookup
/// to find the function declaration `void to_bson(T& t, bsoncxx::document::value doc)`.
///
/// @param t
/// A user-defined object to serialize into a BSON object.
///
template <typename T,
typename std::enable_if<!std::is_same<T, typename array::view>::value, int>::type = 0>
explicit value(const T& t) : value({}) {
to_bson(t, *this);
}
template <typename T>
value& operator=(const T& t) {
*this = value{t};
return *this;
}
///
/// @returns A const_iterator to the first element of the document.
///
document::view::const_iterator cbegin() const;
///
/// @returns A const_iterator to the past-the-end element of the document.
///
document::view::const_iterator cend() const;
///
/// @returns A const_iterator to the first element of the document.
///
document::view::const_iterator begin() const;
///
/// @returns A const_iterator to the past-the-end element of the document.
///
document::view::const_iterator end() const;
///
/// Finds the first element of the document with the provided key. If there is
/// no such element, the past-the-end iterator will be returned. The runtime of
/// find() is linear in the length of the document. This method only searches
/// the top-level document, and will not recurse to any subdocuments.
///
/// @remark In BSON, keys are not required to be unique. If there are multiple
/// elements with a matching key in the document, the first matching element from
/// the start will be returned.
///
/// @param key
/// The key to search for.
///
/// @return An iterator to the matching element, if found, or the past-the-end iterator.
///
document::view::const_iterator find(stdx::string_view key) const;
///
/// Finds the first element of the document with the provided key. If there is no
/// such element, the invalid document::element will be returned. The runtime of operator[]
/// is linear in the length of the document.
///
/// @param key
/// The key to search for.
///
/// @return The matching element, if found, or the invalid element.
///
element operator[](stdx::string_view key) const;
///
/// Access the raw bytes of the underlying document.
///
/// @return A pointer to the value's buffer.
///
const std::uint8_t* data() const;
///
/// Gets the length of the underlying buffer.
///
/// @remark This is not the number of elements in the document.
/// To compute the number of elements, use std::distance.
///
/// @return The length of the document, in bytes.
///
std::size_t length() const;
///
/// Checks if the underlying document is empty, i.e. it is equivalent to
/// the trivial document '{}'.
///
/// @return true if the underlying document is empty.
///
bool empty() const;
///
/// Get a view over the document owned by this value.
///
BSONCXX_INLINE document::view view() const noexcept;
///
/// Conversion operator that provides a view given a value.
///
/// @return A view over the value.
///
BSONCXX_INLINE operator document::view() const noexcept;
///
/// Constructs an object of type T from this document object. This method uses
/// argument-dependent lookup to find the function declaration
/// `void from_bson(T& t, const bsoncxx::document::view& doc)`.
///
/// @note Type T must be default-constructible. Otherwise, use `void get(T& t)`.
///
template <typename T>
T get() {
T temp{};
from_bson(temp, this->view());
return temp;
}
///
/// Constructs an object of type T from this document object. This method uses
/// argument-dependent lookup to find the function declaration
/// `void from_bson(T& t, const bsoncxx::document::view& doc)`.
///
/// @param t
/// The object to construct. The contents of the document object will be deserialized
/// into t.
///
template <typename T>
void get(T& t) {
from_bson(t, this->view());
}
///
/// Transfer ownership of the underlying buffer to the caller.
///
/// @warning
/// After calling release() it is illegal to call any methods
/// on this class, unless it is subsequently moved into.
///
/// @return A std::unique_ptr with ownership of the buffer.
///
unique_ptr_type release();
///
/// Replace the formerly-owned buffer with the new view.
/// This will make a copy of the passed-in view.
///
void reset(document::view view);
private:
unique_ptr_type _data;
std::size_t _length{0};
};
BSONCXX_INLINE document::view value::view() const noexcept {
return document::view{static_cast<uint8_t*>(_data.get()), _length};
}
BSONCXX_INLINE value::operator document::view() const noexcept {
return view();
}
///
/// @{
///
/// Compares two document values for (in)-equality.
///
/// @relates document::value
///
BSONCXX_INLINE bool operator==(const value& lhs, const value& rhs) {
return (lhs.view() == rhs.view());
}
BSONCXX_INLINE bool operator!=(const value& lhs, const value& rhs) {
return !(lhs == rhs);
}
///
/// @}
///
} // namespace document
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,194 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <bsoncxx/document/element.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace document {
///
/// A read-only, non-owning view of a BSON document.
///
class BSONCXX_API view {
public:
class BSONCXX_API const_iterator;
using iterator = const_iterator;
///
/// Default constructs a view. The resulting view will be initialized to point at
/// an empty BSON document.
///
view();
///
/// Constructs a view from a buffer. The caller is responsible for ensuring that
/// the lifetime of the resulting view is a subset of the buffer's.
///
/// @param data
/// A buffer containing a valid BSON document.
/// @param length
/// The size of the buffer, in bytes.
///
view(const std::uint8_t* data, std::size_t length);
///
/// @returns A const_iterator to the first element of the document.
///
const_iterator cbegin() const;
///
/// @returns A const_iterator to the past-the-end element of the document.
///
const_iterator cend() const;
///
/// @returns A const_iterator to the first element of the document.
///
const_iterator begin() const;
///
/// @returns A const_iterator to the past-the-end element of the document.
///
const_iterator end() const;
///
/// Finds the first element of the document with the provided key. If there is
/// no such element, the past-the-end iterator will be returned. The runtime of
/// find() is linear in the length of the document. This method only searches
/// the top-level document, and will not recurse to any subdocuments.
///
/// @remark In BSON, keys are not required to be unique. If there are multiple
/// elements with a matching key in the document, the first matching element from
/// the start will be returned.
///
/// @param key
/// The key to search for.
///
/// @return An iterator to the matching element, if found, or the past-the-end iterator.
///
const_iterator find(stdx::string_view key) const;
///
/// Finds the first element of the document with the provided key. If there is no
/// such element, the invalid document::element will be returned. The runtime of operator[]
/// is linear in the length of the document.
///
/// @param key
/// The key to search for.
///
/// @return The matching element, if found, or the invalid element.
///
element operator[](stdx::string_view key) const;
///
/// Access the raw bytes of the underlying document.
///
/// @return A (non-owning) pointer to the view's buffer.
///
const std::uint8_t* data() const;
///
/// Gets the length of the underlying buffer.
///
/// @remark This is not the number of elements in the document.
/// To compute the number of elements, use std::distance.
///
/// @return The length of the document, in bytes.
///
std::size_t length() const;
///
/// Checks if the underlying document is empty, i.e. it is equivalent to
/// the trivial document '{}'.
///
/// @return true if the underlying document is empty.
///
bool empty() const;
///
/// @{
///
/// Compare two document views for (in)-equality
///
/// @relates view
///
friend BSONCXX_API bool BSONCXX_CALL operator==(view, view);
friend BSONCXX_API bool BSONCXX_CALL operator!=(view, view);
///
/// @}
///
private:
const std::uint8_t* _data;
std::size_t _length;
};
///
/// A const iterator over the contents of a document view.
///
/// This iterator type provides a const forward iterator interface to document
/// view elements.
///
class BSONCXX_API view::const_iterator {
public:
///
/// std::iterator_traits
///
using value_type = element;
using reference = element&;
using pointer = element*;
using iterator_category = std::forward_iterator_tag;
using difference_type = std::ptrdiff_t;
const_iterator();
explicit const_iterator(const element& element);
reference operator*();
pointer operator->();
const_iterator& operator++();
const_iterator operator++(int);
///
/// @{
///
/// Compares two const_iterators for (in)-equality
///
/// @relates view::const_iterator
///
friend BSONCXX_API bool BSONCXX_CALL operator==(const const_iterator&, const const_iterator&);
friend BSONCXX_API bool BSONCXX_CALL operator!=(const const_iterator&, const const_iterator&);
///
/// @}
///
private:
element _element;
};
} // namespace document
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,33 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/view_or_value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace document {
using view_or_value = bsoncxx::view_or_value<document::view, document::value>;
} // namespace document
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,27 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BSONCXX_ENUM
#error "This header is only meant to be included as an X-macro over BSONCXX_ENUM"
#endif
BSONCXX_ENUM(binary, 0x00)
BSONCXX_ENUM(function, 0x01)
BSONCXX_ENUM(binary_deprecated, 0x02)
BSONCXX_ENUM(uuid_deprecated, 0x03)
BSONCXX_ENUM(uuid, 0x04)
BSONCXX_ENUM(md5, 0x05)
BSONCXX_ENUM(encrypted, 0x06)
BSONCXX_ENUM(column, 0x07)
BSONCXX_ENUM(user, 0x80)

View File

@@ -0,0 +1,39 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef BSONCXX_ENUM
#error "This header is only meant to be included as an X-macro over BSONCXX_ENUM"
#endif
BSONCXX_ENUM(double, 0x01)
BSONCXX_ENUM(string, 0x02)
BSONCXX_ENUM(document, 0x03)
BSONCXX_ENUM(array, 0x04)
BSONCXX_ENUM(binary, 0x05)
BSONCXX_ENUM(undefined, 0x06)
BSONCXX_ENUM(oid, 0x07)
BSONCXX_ENUM(bool, 0x08)
BSONCXX_ENUM(date, 0x09)
BSONCXX_ENUM(null, 0x0A)
BSONCXX_ENUM(regex, 0x0B)
BSONCXX_ENUM(dbpointer, 0x0C)
BSONCXX_ENUM(code, 0x0D)
BSONCXX_ENUM(symbol, 0x0E)
BSONCXX_ENUM(codewscope, 0x0F)
BSONCXX_ENUM(int32, 0x10)
BSONCXX_ENUM(timestamp, 0x11)
BSONCXX_ENUM(int64, 0x12)
BSONCXX_ENUM(decimal128, 0x13)
BSONCXX_ENUM(maxkey, 0x7F)
BSONCXX_ENUM(minkey, 0xFF)

View File

@@ -0,0 +1,129 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstdint>
#include <system_error>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
///
/// Enum representing the various error types that can occur while operating on BSON values.
///
enum class error_code : std::int32_t {
/// A new key was appended while building a subarray.
k_cannot_append_key_in_sub_array = 1,
/// A subarray was closed while building a subdocument.
k_cannot_close_array_in_sub_document,
/// A subdocument was closed while building a subarray.
k_cannot_close_document_in_sub_array,
/// An array operation was performed while building a document.
k_cannot_perform_array_operation_on_document,
/// A document operation was performed while building an array.
k_cannot_perform_document_operation_on_array,
#define BSONCXX_ENUM(name, value) k_need_element_type_k_##name,
#include <bsoncxx/enums/type.hpp>
#undef BSONCXX_ENUM
/// No key was provided when one was needed.
k_need_key,
/// An array was closed while no array was open.
k_no_array_to_close,
/// A document was closed while no document was open.
k_no_document_to_close,
// Attempted to view or extract a document when a key was still awaiting a matching value.
k_unmatched_key_in_builder,
/// An empty element was accessed.
k_unset_element,
/// A JSON document failed to parse.
k_json_parse_failure,
/// An Object ID string failed to parse.
k_invalid_oid,
// This type is unused and deprecated.
k_failed_converting_bson_to_json,
/// A Decimal128 string failed to parse.
k_invalid_decimal128,
/// BSON data could not be processed, but no specific reason was available.
k_internal_error,
/// Failed to begin appending an array to a BSON document or array.
k_cannot_begin_appending_array,
/// Failed to begin appending a BSON document to a BSON document or array.
k_cannot_begin_appending_document,
/// Failed to complete appending an array to a BSON document or array.
k_cannot_end_appending_array,
/// Failed to complete appending a BSON document to a BSON document or array.
k_cannot_end_appending_document,
/// Invalid binary subtype.
k_invalid_binary_subtype,
/// Invalid type.
k_invalid_bson_type_id,
/// A value failed to append.
#define BSONCXX_ENUM(name, value) k_cannot_append_##name,
#include <bsoncxx/enums/type.hpp>
#undef BSONCXX_ENUM
k_cannot_append_utf8 = k_cannot_append_string,
k_need_element_type_k_utf8 = k_need_element_type_k_string,
// Add new constant string message to error_code.cpp as well!
};
///
/// Get the error_category for exceptions originating from the bsoncxx library.
///
/// @return The bsoncxx error_category
///
BSONCXX_API const std::error_category& BSONCXX_CALL error_category();
///
/// Translate a bsoncxx::error_code into a std::error_code.
///
/// @param error An error from bsoncxx
/// @return An error_code
///
BSONCXX_INLINE std::error_code make_error_code(error_code error) {
return {static_cast<int>(error), error_category()};
}
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>
namespace std {
// Specialize is_error_code_enum so we get simpler std::error_code construction
template <>
struct is_error_code_enum<bsoncxx::error_code> : public true_type {};
} // namespace std

View File

@@ -0,0 +1,35 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <system_error>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
///
/// Class representing any exceptions emitted from the bsoncxx library or
/// its underlying implementation.
///
class BSONCXX_API exception : public std::system_error {
using std::system_error::system_error;
};
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,90 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <string>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <bsoncxx/config/prelude.hpp>
///
/// Top level namespace for MongoDB C++ BSON functionality.
///
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
// Placing this variable between the `BSONCXX_INLINE_NAMESPACE_BEGIN` and the Doxygen documentation
// for `to_json` suppressed the macro name from being shown as part of the return type in the
// generated documentation pages.
extern const bool k_silence_doxygen;
///
/// An enumeration of the types of Extended JSON that the to_json function accepts
enum class ExtendedJsonMode : std::uint8_t {
k_legacy, ///< to produce Legacy Extended JSON
k_canonical, ///< to produce Canonical Extended JSON
k_relaxed, ///< to produce Relaxed Extended JSON
};
///
/// Converts a BSON document to a JSON string, in extended format.
///
/// @param view
/// A valid BSON document.
/// @param mode
/// An optional JSON representation mode.
///
/// @throws bsoncxx::exception with error details if the conversion failed.
///
/// @returns An extended JSON string.
///
BSONCXX_API std::string BSONCXX_CALL to_json(document::view view,
ExtendedJsonMode mode = ExtendedJsonMode::k_legacy);
///
/// Constructs a new document::value from the provided JSON text.
///
/// @param 'json'
/// A string_view into a JSON document.
///
/// @returns A document::value if conversion worked.
///
/// @throws bsoncxx::exception with error details if the conversion failed.
///
BSONCXX_API document::value BSONCXX_CALL from_json(stdx::string_view json);
///
/// Constructs a new document::value from the provided JSON text. This is the UDL version of
/// from_json().
///
/// @param 'json'
/// A string into a JSON document.
///
/// @param 'len'
/// The length of the JSON string. This is calculated automatically upon use of the UDL.
///
/// @returns A document::value if conversion worked.
///
/// @throws bsoncxx::exception with error details if the conversion failed.
///
BSONCXX_API document::value BSONCXX_CALL operator"" _bson(const char* json, size_t len);
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,126 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <array>
#include <ctime>
#include <string>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
///
/// Represents a MongoDB ObjectId. As this BSON type is used within the MongoDB server
/// as a primary key for each document, it is useful for representing a 'pointer'
/// to another document.
///
/// @note we use 'oid' to refer to this concrete class. We use 'ObjectId' to refer
/// to the BSON type.
///
/// @see https://docs.mongodb.com/manual/reference/object-id/
///
class BSONCXX_API oid {
public:
static constexpr std::size_t k_oid_length = 12;
///
/// Constructs an oid and initializes it to a newly generated ObjectId.
///
oid();
///
/// Constructs an oid initializes it to the contents of the provided buffer.
///
/// @param bytes
/// A pointer a buffer containing a valid ObjectId.
/// @param len
/// The length of the buffer. Should be equal to oid::size().
///
/// @throws bsoncxx::exception if the length is not equal to oid::size().
///
explicit oid(const char* bytes, std::size_t len);
///
/// Constructs an oid and initializes it from the provided hex string.
///
/// @param str
/// A string of a hexadecimal representation of a valid ObjectId.
///
/// @throws bsoncxx::exception if the string isn't an OID-sized hex
/// string.
///
explicit oid(const bsoncxx::stdx::string_view& str);
///
/// Converts this oid to a hexadecimal string.
///
/// @return A hexadecimal string representation of this ObjectId.
///
std::string to_string() const;
///
/// Returns the number of bytes in this ObjectId.
///
/// @return The length of this oid's buffer.
///
static std::size_t size() {
return k_oid_length;
}
///
/// @{
///
/// Relational operators for OIDs
///
/// @relates oid
///
friend BSONCXX_API bool BSONCXX_CALL operator<(const oid& lhs, const oid& rhs);
friend BSONCXX_API bool BSONCXX_CALL operator>(const oid& lhs, const oid& rhs);
friend BSONCXX_API bool BSONCXX_CALL operator<=(const oid& lhs, const oid& rhs);
friend BSONCXX_API bool BSONCXX_CALL operator>=(const oid& lhs, const oid& rhs);
friend BSONCXX_API bool BSONCXX_CALL operator==(const oid& lhs, const oid& rhs);
friend BSONCXX_API bool BSONCXX_CALL operator!=(const oid& lhs, const oid& rhs);
///
/// @}
///
///
/// Extracts the timestamp portion of the underlying ObjectId.
///
/// @return A std::time_t initialized to the timestamp.
///
std::time_t get_time_t() const;
///
/// An accessor for the internal data buffer in the oid.
///
/// @return A pointer to the internal buffer holding the oid bytes.
///
const char* bytes() const;
private:
friend BSONCXX_PRIVATE int oid_compare(const oid& lhs, const oid& rhs);
std::array<char, k_oid_length> _bytes;
};
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,69 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/config/prelude.hpp>
#if defined(BSONCXX_POLY_USE_MNMLSTC)
#if defined(MONGO_CXX_DRIVER_COMPILING) || defined(BSONCXX_POLY_USE_SYSTEM_MNMLSTC)
#include <core/memory.hpp>
#else
#include <bsoncxx/third_party/mnmlstc/core/memory.hpp>
#endif
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::core::make_unique;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif defined(BSONCXX_POLY_USE_BOOST)
#include <boost/smart_ptr/make_unique.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::boost::make_unique;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif __cplusplus >= 201402L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201402L)
#include <memory>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::std::make_unique;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#else
#error "Cannot find a valid polyfill for make_unique"
#endif
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,99 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/config/prelude.hpp>
#if defined(BSONCXX_POLY_USE_MNMLSTC)
#if defined(MONGO_CXX_DRIVER_COMPILING) || defined(BSONCXX_POLY_USE_SYSTEM_MNMLSTC)
#include <core/optional.hpp>
#else
#include <bsoncxx/third_party/mnmlstc/core/optional.hpp>
#endif
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::core::make_optional;
using ::core::nullopt;
using ::core::nullopt_t;
using ::core::optional;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif defined(BSONCXX_POLY_USE_BOOST)
#include <boost/none.hpp>
#include <boost/optional/optional.hpp>
#include <boost/optional/optional_io.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::boost::optional;
using nullopt_t = ::boost::none_t;
// TODO(MSVC): This would be better expressed as constexpr, but VS2015U1 can't do it.
const nullopt_t nullopt{::boost::none};
using ::boost::make_optional;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif defined(BSONCXX_POLY_USE_STD_EXPERIMENTAL)
#include <experimental/optional>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::std::experimental::make_optional;
using ::std::experimental::nullopt;
using ::std::experimental::nullopt_t;
using ::std::experimental::optional;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif defined(BSONCXX_POLY_USE_STD)
#include <optional>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::std::make_optional;
using ::std::nullopt;
using ::std::nullopt_t;
using ::std::optional;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#else
#error "Cannot find a valid polyfill for optional"
#endif
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,109 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/config/prelude.hpp>
#if defined(BSONCXX_POLY_USE_MNMLSTC)
#if defined(MONGO_CXX_DRIVER_COMPILING) || defined(BSONCXX_POLY_USE_SYSTEM_MNMLSTC)
#include <core/string.hpp>
#else
#include <bsoncxx/third_party/mnmlstc/core/string.hpp>
#endif
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::core::basic_string_view;
using ::core::string_view;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif defined(BSONCXX_POLY_USE_BOOST)
#include <boost/version.hpp>
#if BOOST_VERSION >= 106100
#include <boost/utility/string_view.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::boost::basic_string_view;
using ::boost::string_view;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#else
#include <boost/utility/string_ref.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
template <typename charT, typename traits = std::char_traits<charT>>
using basic_string_view = ::boost::basic_string_ref<charT, traits>;
using string_view = ::boost::string_ref;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#endif
#elif defined(BSONCXX_POLY_USE_STD_EXPERIMENTAL)
#include <experimental/string_view>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::std::experimental::basic_string_view;
using ::std::experimental::string_view;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#elif defined(BSONCXX_POLY_USE_STD)
#include <string_view>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace stdx {
using ::std::basic_string_view;
using ::std::string_view;
} // namespace stdx
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#else
#error "Cannot find a valid polyfill for string_view"
#endif
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,40 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <string>
#include <utility>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace string {
template <class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>>
BSONCXX_INLINE std::basic_string<CharT, Traits, Allocator> to_string(
stdx::basic_string_view<CharT, Traits> value, const Allocator& alloc = Allocator()) {
return std::basic_string<CharT, Traits, Allocator>{value.data(), value.length(), alloc};
}
} // namespace string
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,123 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <string>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/view_or_value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace string {
///
/// Class representing a view-or-value variant type for strings.
///
/// This class adds several string-specific methods to the bsoncxx::view_or_value template:
/// - a constructor overload for const char*
/// - a constructor overload for std::string by l-value reference
/// - a safe c_str() operation to return null-terminated c-style strings.
///
class BSONCXX_API view_or_value : public bsoncxx::view_or_value<stdx::string_view, std::string> {
public:
///
/// Forward all bsoncxx::view_or_value constructors.
///
using bsoncxx::view_or_value<stdx::string_view, std::string>::view_or_value;
///
/// Default constructor, equivalent to using an empty string.
///
BSONCXX_INLINE view_or_value() = default;
///
/// Construct a string::view_or_value using a null-terminated const char *.
/// The resulting view_or_value will keep a string_view of 'str', so it is
/// important that the passed-in string outlive this object.
///
/// @param str A null-terminated string
///
BSONCXX_INLINE view_or_value(const char* str)
: bsoncxx::view_or_value<stdx::string_view, std::string>(stdx::string_view(str)) {}
///
/// Allow construction with an l-value reference to a std::string. The resulting
/// view_or_value will keep a string_view of 'str', so it is important that the
/// passed-in string outlive this object.
///
/// Construction calls passing a std::string by r-value reference will use the
/// constructor defined in the parent view_or_value class.
///
/// @param str A std::string l-value reference.
///
BSONCXX_INLINE view_or_value(const std::string& str)
: bsoncxx::view_or_value<stdx::string_view, std::string>(stdx::string_view(str)) {}
///
/// Return a string_view_or_value that is guaranteed to hold a null-terminated
/// string. The lifetime of the returned object must be a subset of this object's
/// lifetime, because the new view_or_value might hold a view into this one.
///
/// It is recommended that this method be used before calling .data() on a
/// view_or_value, as that method may return a non-null-terminated string.
///
/// @return A new view_or_value object.
///
view_or_value terminated() const;
///
/// Call data() on this view_or_value's string_view. This method is not
/// guaranteed to return a null-terminated string unless it is used in
/// combination with terminated().
///
/// @return A const char* of this string.
///
const char* data() const;
};
///
/// @{
///
/// Comparison operators for comparing string::view_or_value directly with const char *.
///
/// @relates view_or_value
///
BSONCXX_INLINE bool operator==(const view_or_value& lhs, const char* rhs) {
return lhs.view() == stdx::string_view(rhs);
}
BSONCXX_INLINE bool operator!=(const view_or_value& lhs, const char* rhs) {
return !(lhs == rhs);
}
BSONCXX_INLINE bool operator==(const char* lhs, const view_or_value& rhs) {
return rhs == lhs;
}
BSONCXX_INLINE bool operator!=(const char* lhs, const view_or_value& rhs) {
return !(rhs == lhs);
}
///
/// @}
///
} // namespace string
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,293 @@
#ifndef CORE_ANY_HPP
#define CORE_ANY_HPP
#include <stdexcept>
#include <typeinfo>
#include <memory>
#include <bsoncxx/third_party/mnmlstc/core/type_traits.hpp>
#include <bsoncxx/third_party/mnmlstc/core/utility.hpp>
namespace core {
inline namespace v1 {
namespace impl {
using data_type = add_pointer_t<void>;
template <class Type>
using is_small = ::std::integral_constant<
bool,
sizeof(decay_t<Type>) <= sizeof(void*)
>;
struct any_dispatch {
using destroy_function = void (*)(data_type&);
using clone_function = void(*)(data_type const&, data_type&);
using type_function = ::std::type_info const& (*)();
destroy_function const destroy;
clone_function const clone;
type_function const type;
};
template <class Type, bool=is_small<Type>::value>
struct any_dispatch_select;
template <class Type>
struct any_dispatch_select<Type, true> {
using allocator_type = ::std::allocator<Type>;
using allocator_traits = ::std::allocator_traits<allocator_type>;
static void clone (data_type const& source, data_type& data) {
allocator_type alloc { };
auto const& value = reinterpret_cast<Type const&>(source);
auto& ref = reinterpret_cast<Type&>(data);
allocator_traits::construct(alloc, ::std::addressof(ref), value);
}
static void destroy (data_type& data) {
allocator_type alloc { };
auto& ref = reinterpret_cast<Type&>(data);
allocator_traits::destroy(alloc, ::std::addressof(ref));
}
};
template <class Type>
struct any_dispatch_select<Type, false> {
using allocator_type = ::std::allocator<Type>;
using allocator_traits = ::std::allocator_traits<allocator_type>;
static void clone (data_type const& source, data_type& data) {
allocator_type alloc { };
auto const& value = *static_cast<Type* const>(source);
auto pointer = allocator_traits::allocate(alloc, 1);
auto scope = make_scope_guard([&alloc, pointer] {
allocator_traits::deallocate(alloc, pointer, 1);
});
allocator_traits::construct(alloc, pointer, value);
scope.dismiss();
data = pointer;
}
static void destroy (data_type& data) {
allocator_type alloc { };
auto value = static_cast<Type*>(data);
allocator_traits::destroy(alloc, value);
allocator_traits::deallocate(alloc, value, 1);
}
};
template <class Type>
any_dispatch const* get_any_dispatch () {
static any_dispatch const instance = {
any_dispatch_select<Type>::destroy,
any_dispatch_select<Type>::clone,
[] () -> ::std::type_info const& { return typeid(Type); }
};
return ::std::addressof(instance);
}
template <>
inline any_dispatch const* get_any_dispatch<void> () {
static any_dispatch const instance = {
[] (data_type&) { },
[] (data_type const&, data_type&) { },
[] () -> ::std::type_info const& { return typeid(void); }
};
return ::std::addressof(instance);
}
} /* namespace impl */
class bad_any_cast final : public ::std::bad_cast {
public:
virtual char const* what () const noexcept override {
return "bad any cast";
}
};
class any final {
template <class ValueType>
friend ValueType const* any_cast (any const*) noexcept;
template <class ValueType> friend ValueType* any_cast (any*) noexcept;
impl::any_dispatch const* table;
impl::data_type data;
template <class ValueType>
any (ValueType&& value, ::std::true_type&&) :
table { impl::get_any_dispatch<decay_t<ValueType>>() },
data { nullptr }
{
using value_type = decay_t<ValueType>;
using allocator_type = ::std::allocator<value_type>;
allocator_type alloc { };
auto pointer = reinterpret_cast<value_type*>(::std::addressof(this->data));
::std::allocator_traits<allocator_type>::construct(
alloc, pointer, ::std::forward<ValueType>(value)
);
}
template <class ValueType>
any (ValueType&& value, ::std::false_type&&) :
table { impl::get_any_dispatch<decay_t<ValueType>>() },
data { nullptr }
{
using value_type = decay_t<ValueType>;
using allocator_type = ::std::allocator<value_type>;
allocator_type alloc { };
auto pointer = ::std::allocator_traits<allocator_type>::allocate(alloc, 1);
::std::allocator_traits<allocator_type>::construct(
alloc, pointer, ::std::forward<ValueType>(value)
);
this->data = pointer;
}
template <class ValueType>
ValueType const* cast (::std::true_type&&) const {
return reinterpret_cast<ValueType const*>(::std::addressof(this->data));
}
template <class ValueType>
ValueType* cast (::std::true_type&&) {
return reinterpret_cast<ValueType*>(::std::addressof(this->data));
}
template <class ValueType>
ValueType const* cast (::std::false_type&&) const {
return static_cast<ValueType const*>(this->data);
}
template <class ValueType>
ValueType* cast (::std::false_type&&) {
return static_cast<ValueType*>(this->data);
}
public:
any (any const& that) :
table { that.table },
data { nullptr }
{ this->table->clone(that.data, this->data); }
any (any&& that) noexcept :
table { that.table },
data { that.data }
{
that.table = impl::get_any_dispatch<void>();
that.data = nullptr;
}
any () noexcept :
table { impl::get_any_dispatch<void>() },
data { nullptr }
{ }
template <
class ValueType,
class=enable_if_t<not ::std::is_same<any, decay_t<ValueType>>::value>
> any (ValueType&& value) :
any { ::std::forward<ValueType>(value), impl::is_small<ValueType> { } }
{ }
~any () noexcept { this->clear(); }
any& operator = (any const& that) {
any { that }.swap(*this);
return *this;
}
any& operator = (any&& that) noexcept {
any { ::std::move(that) }.swap(*this);
return *this;
}
template <
class ValueType,
class=enable_if_t<not ::std::is_same<any, decay_t<ValueType>>::value>
> any& operator = (ValueType&& value) {
any {
::std::forward<ValueType>(value),
impl::is_small<ValueType> { }
}.swap(*this);
return *this;
}
void swap (any& that) noexcept {
using ::std::swap;
swap(this->table, that.table);
swap(this->data, that.data);
}
void clear () noexcept {
this->table->destroy(this->data);
this->table = impl::get_any_dispatch<void>();
}
::std::type_info const& type () const noexcept {
return this->table->type();
}
bool empty () const noexcept {
return this->table == impl::get_any_dispatch<void>();
}
};
template <class ValueType>
ValueType const* any_cast (any const* operand) noexcept {
return operand and operand->type() == typeid(ValueType)
? operand->cast<ValueType>(impl::is_small<ValueType> { })
: nullptr;
}
template <class ValueType>
ValueType* any_cast (any* operand) noexcept {
return operand and operand->type() == typeid(ValueType)
? operand->cast<ValueType>(impl::is_small<ValueType> { })
: nullptr;
}
template <
class ValueType,
class=enable_if_t<
::std::is_reference<ValueType>::value or
::std::is_copy_constructible<ValueType>::value
>
> ValueType any_cast (any const& operand) {
using type = remove_reference_t<ValueType>;
auto pointer = any_cast<add_const_t<type>>(::std::addressof(operand));
if (not pointer) { throw bad_any_cast { }; }
return *pointer;
}
template <
class ValueType,
class=enable_if_t<
::std::is_reference<ValueType>::value or
::std::is_copy_constructible<ValueType>::value
>
> ValueType any_cast (any&& operand) {
using type = remove_reference_t<ValueType>;
auto pointer = any_cast<type>(::std::addressof(operand));
if (not pointer) { throw bad_any_cast { }; }
return *pointer;
}
template <
class ValueType,
class=enable_if_t<
::std::is_reference<ValueType>::value or
::std::is_copy_constructible<ValueType>::value
>
> ValueType any_cast (any& operand) {
using type = remove_reference_t<ValueType>;
auto pointer = any_cast<type>(::std::addressof(operand));
if (not pointer) { throw bad_any_cast { }; }
return *pointer;
}
inline void swap (any& lhs, any& rhs) noexcept { lhs.swap(rhs); }
}} /* namespace core::v1 */
#endif /* CORE_ANY_HPP */

View File

@@ -0,0 +1,201 @@
#ifndef CORE_FUNCTIONAL_HPP
#define CORE_FUNCTIONAL_HPP
#include <bsoncxx/third_party/mnmlstc/core/type_traits.hpp>
#include <bsoncxx/third_party/mnmlstc/core/utility.hpp>
#include <functional>
#include <tuple>
#include <array>
namespace core {
inline namespace v1 {
template <class F> struct function_traits;
template <class R, class... Args>
struct function_traits<R(*)(Args...)> : function_traits<R(Args...)> { };
template <class C, class R>
struct function_traits<R(C::*)> : function_traits<R(C&)> { };
template <class C, class R, class... Args>
struct function_traits<R(C::*)(Args...)> : function_traits<R(C&, Args...)> { };
template <class C, class R, class... Args>
struct function_traits<R(C::*)(Args...) const volatile> :
function_traits<R(C volatile const&, Args...)>
{ };
template <class C, class R, class... Args>
struct function_traits<R(C::*)(Args...) volatile> :
function_traits<R(C volatile&, Args...)>
{ };
template <class C, class R, class... Args>
struct function_traits<R(C::*)(Args...) const> :
function_traits<R(C const&, Args...)>
{ };
template <class R, class... Args>
struct function_traits<R(Args...)> {
using return_type = R;
using pointer = return_type(*)(Args...);
static constexpr ::std::size_t arity = sizeof...(Args);
template < ::std::size_t N>
using argument = typename ::std::tuple_element<
N,
::std::tuple<Args...>
>::type;
};
template <class F> struct function_traits {
using functor_type = function_traits<decltype(&decay_t<F>::operator())>;
using return_type = typename functor_type::return_type;
using pointer = typename functor_type::pointer;
static constexpr ::std::size_t arity = functor_type::arity - 1;
template < ::std::size_t N>
using argument = typename functor_type::template argument<N>;
};
/* N3727 */
template <class Functor, class Object, class... Args>
auto invoke (Functor&& functor, Object&& object, Args&&... args) -> enable_if_t<
invokable<Functor, Object, Args...>::value,
decltype((object.*functor)(::core::forward<Args>(args)...))
> { return (object.*functor)(::core::forward<Args>(args)...); }
template <class Functor, class Object, class... Args>
auto invoke (Functor&& functor, Object&& object, Args&&... args) -> enable_if_t<
invokable<Functor, Object, Args...>::value,
decltype(
((*::core::forward<Object>(object)).*functor)(::core::forward<Args>(args)...)
)
> {
return (
(*::core::forward<Object>(object)).*functor
)(::core::forward<Args>(args)...);
}
template <class Functor, class Object>
auto invoke (Functor&& functor, Object&& object) -> enable_if_t<
invokable<Functor, Object>::value,
decltype(object.*functor)
> { return object.*functor; }
template <class Functor, class Object>
auto invoke (Functor&& functor, Object&& object) -> enable_if_t<
invokable<Functor, Object>::value,
decltype((*::core::forward<Object>(object)).*functor)
> { return (*::core::forward<Object>(object)).*functor; }
template <class Functor, class... Args>
constexpr auto invoke (Functor&& functor, Args&&... args) -> enable_if_t<
invokable<Functor, Args...>::value,
decltype(::core::forward<Functor>(functor)(::core::forward<Args>(args)...))
> { return ::core::forward<Functor>(functor)(::core::forward<Args>(args)...); }
namespace impl {
template <class Functor, class U, ::std::size_t... I>
auto unpack (
Functor&& functor,
U&& unpackable,
index_sequence<I...>&&
) -> invoke_of_t<
Functor,
decltype(::std::get<I>(::std::forward<U>(unpackable)))...
> {
return ::core::v1::invoke(::std::forward<Functor>(functor),
::std::get<I>(::std::forward<U>(unpackable))...
);
}
template <class U, ::std::size_t... I>
auto unpack (U&& unpackable, index_sequence<I...>&&) -> invoke_of_t<
decltype(::std::get<I>(::std::forward<U>(unpackable)))...
> {
return ::core::v1::invoke(::std::get<I>(::std::forward<U>(unpackable))...);
}
template <class Functor, class U, ::std::size_t... I>
auto runpack (
Functor&& functor,
U&& runpackable,
index_sequence<I...>&&
) -> invoke_of_t<Functor, decltype(::std::forward<U>(runpackable).at(I))...> {
return ::core::v1::invoke(
::std::forward<Functor>(functor),
::std::forward<U>(runpackable).at(I)...);
}
} /* namespace impl */
struct unpack_t final { };
constexpr unpack_t unpack { };
struct runpack_t final { };
constexpr runpack_t runpack { };
template <class Functor, class Unpackable>
auto invoke (unpack_t, Functor&& functor, Unpackable&& unpackable) ->
enable_if_t<
is_unpackable<decay_t<Unpackable>>::value,
decltype(
impl::unpack(
::std::forward<Functor>(functor),
::std::forward<Unpackable>(unpackable),
make_index_sequence<::std::tuple_size<decay_t<Unpackable>>::value> { }
)
)
> {
return impl::unpack(
::std::forward<Functor>(functor),
::std::forward<Unpackable>(unpackable),
make_index_sequence<::std::tuple_size<decay_t<Unpackable>>::value> { }
);
}
template <class Unpackable>
auto invoke (unpack_t, Unpackable&& unpackable) ->
enable_if_t<
is_unpackable<decay_t<Unpackable>>::value,
decltype(
impl::unpack(
::std::forward<Unpackable>(unpackable),
make_index_sequence<::std::tuple_size<decay_t<Unpackable>>::value> { }
)
)
> {
return impl::unpack(
::std::forward<Unpackable>(unpackable),
make_index_sequence<::std::tuple_size<decay_t<Unpackable>>::value> { }
);
}
template <class Functor, class Runpackable>
auto invoke (
runpack_t,
Functor&& functor,
Runpackable&& unpackable
) -> enable_if_t<
is_runpackable<decay_t<Runpackable>>::value,
decltype(
impl::runpack(
::std::forward<Functor>(functor),
::std::forward<Runpackable>(unpackable),
make_index_sequence<function_traits<Functor>::arity> { }
)
)
> {
return impl::runpack(
::std::forward<Functor>(functor),
::std::forward<Runpackable>(unpackable),
make_index_sequence<function_traits<Functor>::arity> { }
);
}
}} /* namespace core::v1 */
#endif /* CORE_FUNCTIONAL_HPP */

View File

@@ -0,0 +1,164 @@
#ifndef CORE_ITERATOR_HPP
#define CORE_ITERATOR_HPP
#include <functional>
#include <iterator>
#include <ostream>
namespace core {
inline namespace v1 {
/* capacity */
template <class Container>
constexpr auto size (Container const& container) noexcept -> decltype(
container.size()
) { return container.size(); }
template <class T, ::std::size_t N>
constexpr ::std::size_t size (T const (&)[N]) noexcept { return N; }
template <class Container>
constexpr bool empty (Container const& container) noexcept {
return container.empty();
}
template <class T, std::size_t N>
constexpr bool empty (T const (&)[N]) noexcept { return false; }
/* element access */
template <class Container>
constexpr auto front (Container const& container) -> decltype(
container.front()
) { return container.front(); }
template <class Container>
constexpr auto front (Container& container) -> decltype(container.front()) {
return container.front();
}
template <class T, ::std::size_t N>
constexpr T const& front (T const (&array)[N]) noexcept { return array[0]; }
template <class T, ::std::size_t N>
constexpr T& front (T (&array)[N]) noexcept { return array[0]; }
template <class Container>
constexpr auto back (Container const& container) -> decltype(
container.back()
) { return container.back(); }
template <class Container>
constexpr auto back (Container& container) -> decltype(container.back()) {
return container.back();
}
template <class T, ::std::size_t N>
constexpr T const& back (T const (&array)[N]) noexcept { return array[N - 1]; }
template <class T, ::std::size_t N>
constexpr T& back (T (&array)[N]) noexcept { return array[N - 1]; }
/* data access */
template <class Container>
constexpr auto data (Container const& container) noexcept -> decltype(
container.data()
) { return container.data(); }
template <class Container>
constexpr auto data (Container& container) noexcept -> decltype(
container.data()
) { return container.data(); }
template <class T, ::std::size_t N>
constexpr T const* data (T const (&array)[N]) noexcept { return array; }
template <class T, ::std::size_t N>
constexpr T* data (T (&array)[N]) noexcept { return array; }
/* iteration */
template <class Container>
auto cbegin (Container const& container) -> decltype(::std::begin(container)) {
return ::std::begin(container);
}
template <class Container>
auto cend (Container const& container) -> decltype(::std::end(container)) {
return ::std::end(container);
}
template <class Container>
auto rbegin (Container const& container) -> decltype(container.rbegin()) {
return container.rbegin();
}
template <class Container>
auto rbegin (Container& container) -> decltype(container.rbegin()) {
return container.rbegin();
}
template <class Container>
auto crbegin (Container const& container) -> decltype(rbegin(container)) {
return rbegin(container);
}
template <class Container>
auto rend (Container const& container) -> decltype(container.rend()) {
return container.rend();
}
template <class Container>
auto rend (Container& container) -> decltype(container.rend()) {
return container.rend();
}
template <class Container>
auto crend (Container const& container) -> decltype(rend(container)) {
return rend(container);
}
template <
class T,
class CharT=char,
class Traits=::std::char_traits<CharT>
> struct infix_ostream_iterator final : ::std::iterator<
::std::output_iterator_tag,
void,
void,
void,
void
> {
using ostream_type = ::std::basic_ostream<CharT, Traits>;
using traits_type = Traits;
using char_type = CharT;
infix_ostream_iterator (ostream_type& os) :
infix_ostream_iterator { os, nullptr }
{ }
infix_ostream_iterator (ostream_type& os, char_type const* delimiter) :
os { os },
delimiter { delimiter },
first { true }
{ }
infix_ostream_iterator& operator = (T const& item) {
if (not first and delimiter) { this->os.get() << delimiter; }
os.get() << item;
this->first = false;
return *this;
}
infix_ostream_iterator& operator ++ (int) { return *this; }
infix_ostream_iterator& operator ++ () { return *this; }
infix_ostream_iterator& operator * () { return *this; }
private:
::std::reference_wrapper<ostream_type> os;
char_type const* delimiter;
bool first;
};
}} /* namespace core::v1 */
#endif /* CORE_ITERATOR_HPP */

View File

@@ -0,0 +1,804 @@
#ifndef CORE_MEMORY_HPP
#define CORE_MEMORY_HPP
#include <stdexcept>
#include <typeinfo>
#include <memory>
#include <tuple>
#include <cstddef>
#include <bsoncxx/third_party/mnmlstc/core/type_traits.hpp>
namespace core {
inline namespace v1 {
namespace impl {
template <class T>
using deep_lvalue = conditional_t<
::std::is_reference<T>::value, T, T const&
>;
template <class T, class D>
class pointer {
template <class U>
static auto check (typename U::pointer*) noexcept -> typename U::pointer;
template <class> static auto check (...) noexcept(false) -> T*;
using deleter_type = remove_reference_t<D>;
public:
static constexpr bool value = noexcept(check<deleter_type>(nullptr));
using type = decltype(check<deleter_type>(nullptr));
};
} /* namespace impl */
/* poly_ptr copier */
template <class T, class D, class U>
::std::unique_ptr<T, D> default_poly_copy (
::std::unique_ptr<T, D> const& ptr
) {
auto value = *dynamic_cast<U*>(ptr.get());
auto const& deleter = ptr.get_deleter();
return ::std::unique_ptr<T, D> { new U { ::std::move(value) }, deleter };
}
/* null-state poly_ptr copier (don't copy that poly!) */
template <class T, class D>
::std::unique_ptr<T, D> null_poly_copy (
::std::unique_ptr<T, D> const&
) noexcept { return ::std::unique_ptr<T, D> { }; }
/* deep_ptr copier */
template <class T>
struct default_copy {
using pointer = T*;
constexpr default_copy () = default;
template <class U> default_copy (default_copy<U> const&) noexcept { }
pointer operator ()(pointer const ptr) const { return new T { *ptr }; }
};
struct bad_polymorphic_reset : ::std::logic_error {
using ::std::logic_error::logic_error;
};
template <class T, class Deleter=::std::default_delete<T>>
struct poly_ptr final {
using unique_type = ::std::unique_ptr<T, Deleter>;
using element_type = typename unique_type::element_type;
using deleter_type = typename unique_type::deleter_type;
using copier_type = unique_type (*)(unique_type const&);
using pointer = typename unique_type::pointer;
template <class U>
explicit poly_ptr (U* ptr) noexcept :
poly_ptr { ptr, deleter_type { } }
{ }
template <class U, class E>
explicit poly_ptr (
::std::unique_ptr<U, E>&& ptr,
copier_type copier=::std::addressof(
default_poly_copy<element_type, deleter_type, U>
)
) noexcept :
copier { copier },
ptr { ::std::move(ptr) }
{
constexpr bool abstract = ::std::is_abstract<U>::value;
constexpr bool base = ::std::is_base_of<element_type, U>::value;
static_assert(not abstract, "cannot create poly_ptr with abstract ptr");
static_assert(base, "cannot create poly_ptr with non-derived type");
}
template <class U, class E>
poly_ptr (
U* ptr, E&& deleter,
copier_type copier=::std::addressof(
default_poly_copy<element_type, deleter_type, U>
)
) noexcept :
poly_ptr {
unique_type { ::std::move(ptr), ::std::forward<E>(deleter) }, copier
}
{ }
poly_ptr (poly_ptr const& that) :
copier { that.copier },
ptr { that.copier(that.ptr) }
{ }
poly_ptr (poly_ptr&& that) noexcept :
copier { ::std::move(that.copier) },
ptr { ::std::move(that.ptr) }
{ that.copier = null_poly_copy<element_type, deleter_type>; }
constexpr poly_ptr () noexcept { }
~poly_ptr () noexcept { }
template <class U, class E>
poly_ptr& operator = (::std::unique_ptr<U, E>&& ptr) {
poly_ptr { ::std::move(ptr) }.swap(*this);
return *this;
}
template <class U>
poly_ptr& operator = (U* ptr) {
poly_ptr { ptr }.swap(*this);
return *this;
}
poly_ptr& operator = (::std::nullptr_t) noexcept {
this->reset();
return *this;
}
poly_ptr& operator = (poly_ptr const& that) {
return *this = poly_ptr { that };
}
poly_ptr& operator = (poly_ptr&& that) noexcept {
poly_ptr { ::std::move(that) }.swap(*this);
return *this;
}
explicit operator bool () const noexcept { return bool(this->ptr); }
add_lvalue_reference_t<element_type> operator * () const noexcept {
return *this->ptr;
}
pointer operator -> () const noexcept { return this->ptr.get(); }
pointer get () const noexcept { return this->ptr.get(); }
deleter_type const& get_deleter () const noexcept {
return this->ptr.get_deleter();
}
deleter_type& get_deleter () noexcept { return this->ptr.get_deleter(); }
copier_type const& get_copier () const noexcept { return this->copier; }
copier_type& get_copier () noexcept { return this->copier; }
pointer release () noexcept {
this->copier = null_poly_copy<element_type, deleter_type>;
return this->ptr.release();
}
void reset (pointer ptr = pointer { }) {
constexpr auto invalid = "cannot reset null poly_ptr with valid pointer";
constexpr auto type = "cannot reset poly_ptr with different type";
if (ptr and not this->ptr) { throw bad_polymorphic_reset { invalid }; }
if (ptr and typeid(*this->ptr) != typeid(*ptr)) {
throw bad_polymorphic_reset { type };
}
this->ptr.reset(ptr);
if (not ptr) { this->copier = null_poly_copy<element_type, deleter_type>; }
}
void swap (poly_ptr& that) noexcept {
using ::std::swap;
swap(this->get_copier(), that.get_copier());
swap(this->ptr, that.ptr);
}
private:
static_assert(
::std::is_polymorphic<element_type>::value,
"cannot create a poly_ptr with a non-polymorphic type"
);
copier_type copier { null_poly_copy<element_type, deleter_type> };
unique_type ptr;
};
template <
class T,
class Deleter=::std::default_delete<T>,
class Copier=default_copy<T>
> struct deep_ptr final {
using element_type = T;
using deleter_type = Deleter;
using copier_type = Copier;
using pointer = typename impl::pointer<element_type, deleter_type>::type;
static_assert(
::std::is_same<result_of_t<copier_type(pointer)>, pointer>::value,
"deleter_type and copier_type have differing pointer types"
);
using data_type = ::std::tuple<pointer, deleter_type, copier_type>;
deep_ptr (
pointer ptr,
impl::deep_lvalue<deleter_type> deleter,
impl::deep_lvalue<copier_type> copier
) noexcept :
data { ptr, deleter, copier }
{ }
deep_ptr (
pointer ptr,
remove_reference_t<deleter_type>&& deleter,
remove_reference_t<copier_type>&& copier
) noexcept :
data { ::std::move(ptr), ::std::move(deleter), ::std::move(copier) }
{ }
template <class U, class E>
deep_ptr (::std::unique_ptr<U, E>&& that) noexcept :
deep_ptr {
that.release(),
::std::move(that.get_deleter()),
copier_type { }
}
{ }
explicit deep_ptr (pointer ptr) noexcept :
deep_ptr { ptr, deleter_type { }, copier_type { } }
{ }
constexpr deep_ptr (::std::nullptr_t) noexcept : deep_ptr { } { }
deep_ptr (deep_ptr const& that) :
deep_ptr {
that.get() ? that.get_copier()(that.get()) : that.get(),
that.get_deleter(),
that.get_copier()
}
{ }
deep_ptr (deep_ptr&& that) noexcept :
data {
that.release(),
::std::move(that.get_deleter()),
::std::move(that.get_copier())
}
{ }
constexpr deep_ptr () noexcept : data { } { }
~deep_ptr () noexcept {
auto& ptr = ::std::get<0>(this->data);
if (not ptr) { return; }
this->get_deleter()(ptr);
ptr = nullptr;
}
deep_ptr& operator = (::std::nullptr_t) noexcept {
this->reset();
return *this;
}
deep_ptr& operator = (deep_ptr const& that) {
return *this = deep_ptr { that };
}
deep_ptr& operator = (deep_ptr&& that) noexcept {
deep_ptr { ::std::move(that) }.swap(*this);
return *this;
}
explicit operator bool () const noexcept { return this->get(); }
add_lvalue_reference_t<element_type> operator * () const noexcept {
return *this->get();
}
pointer operator -> () const noexcept { return this->get(); }
pointer get () const noexcept { return ::std::get<0>(this->data); }
deleter_type const& get_deleter () const noexcept {
return ::std::get<1>(this->data);
}
deleter_type& get_deleter () noexcept { return ::std::get<1>(this->data); }
copier_type const& get_copier () const noexcept {
return ::std::get<2>(this->data);
}
copier_type& get_copier () noexcept { return ::std::get<2>(this->data); }
pointer release () noexcept {
auto ptr = this->get();
::std::get<0>(this->data) = nullptr;
return ptr;
}
void reset (pointer ptr = pointer { }) noexcept {
using ::std::swap;
swap(::std::get<0>(this->data), ptr);
if (not ptr) { return; }
this->get_deleter()(ptr);
}
void swap (deep_ptr& that) noexcept(is_nothrow_swappable<data_type>::value) {
using ::std::swap;
swap(this->data, that.data);
}
private:
data_type data;
};
template <class W>
struct observer_ptr final {
using element_type = W;
using const_pointer = add_pointer_t<add_const_t<element_type>>;
using pointer = add_pointer_t<element_type>;
using const_reference = add_lvalue_reference_t<add_const_t<element_type>>;
using reference = add_lvalue_reference_t<element_type>;
constexpr observer_ptr (::std::nullptr_t) noexcept : ptr { nullptr } { }
explicit observer_ptr (pointer ptr) noexcept : ptr { ptr } { }
template <
class T,
class=enable_if_t< ::std::is_convertible<pointer, add_pointer_t<T>>::value>
> explicit observer_ptr (add_pointer_t<T> ptr) noexcept :
ptr { dynamic_cast<pointer>(ptr) }
{ }
template <
class T,
class=enable_if_t< ::std::is_convertible<pointer, add_pointer_t<T>>::value>
> observer_ptr (observer_ptr<T> const& that) noexcept :
observer_ptr { that.get() }
{ }
constexpr observer_ptr () noexcept : observer_ptr { nullptr } { }
~observer_ptr () noexcept { this->ptr = nullptr; }
template <
class T,
class=enable_if_t< ::std::is_convertible<pointer, add_pointer_t<T>>::value>
> observer_ptr& operator = (add_pointer_t<T> ptr) noexcept {
observer_ptr { ptr }.swap(*this);
return *this;
}
template <
class T,
class=enable_if_t< ::std::is_convertible<pointer, add_pointer_t<T>>::value>
> observer_ptr& operator = (observer_ptr<T> const& that) noexcept {
observer_ptr { that }.swap(*this);
return *this;
}
observer_ptr& operator = (::std::nullptr_t) noexcept {
this->reset();
return *this;
}
void swap (observer_ptr& that) noexcept {
using ::std::swap;
swap(this->ptr, that.ptr);
}
explicit operator const_pointer () const noexcept { return this->get(); }
explicit operator pointer () noexcept { return this->get(); }
explicit operator bool () noexcept { return this->get(); }
reference operator * () const noexcept { return *this->get(); }
pointer operator -> () const noexcept { return this->get(); }
pointer get () const noexcept { return this->ptr; }
pointer release () noexcept {
auto result = this->get();
this->reset();
return result;
}
void reset (pointer ptr = nullptr) noexcept { this->ptr = ptr; }
private:
pointer ptr;
};
/* poly_ptr convention for type and deleter is:
* T, D : U, E
*/
template <class T, class D, class U, class E>
bool operator == (
poly_ptr<T, D> const& lhs,
poly_ptr<U, E> const& rhs
) noexcept { return lhs.get() == rhs.get(); }
template <class T, class D, class U, class E>
bool operator != (
poly_ptr<T, D> const& lhs,
poly_ptr<U, E> const& rhs
) noexcept { return lhs.get() != rhs.get(); }
template <class T, class D, class U, class E>
bool operator >= (
poly_ptr<T, D> const& lhs,
poly_ptr<U, E> const& rhs
) noexcept { return not (lhs < rhs); }
template <class T, class D, class U, class E>
bool operator <= (
poly_ptr<T, D> const& lhs,
poly_ptr<U, E> const& rhs
) noexcept { return not (rhs < lhs); }
template <class T, class D, class U, class E>
bool operator > (
poly_ptr<T, D> const& lhs,
poly_ptr<U, E> const& rhs
) noexcept { return rhs < lhs; }
template <class T, class D, class U, class E>
bool operator < (
poly_ptr<T, D> const& lhs,
poly_ptr<U, E> const& rhs
) noexcept {
using common_type = typename ::std::common_type<
typename poly_ptr<T, D>::pointer,
typename poly_ptr<U, E>::pointer
>::type;
return ::std::less<common_type> { }(lhs.get(), rhs.get());
}
/* deep_ptr convention for type, deleter, copier is
* T, D, C : U, E, K
*/
template <class T, class D, class C, class U, class E, class K>
bool operator == (
deep_ptr<T, D, C> const& lhs,
deep_ptr<U, E, K> const& rhs
) noexcept { return lhs.get() == rhs.get(); }
template <class T, class D, class C, class U, class E, class K>
bool operator != (
deep_ptr<T, D, C> const& lhs,
deep_ptr<U, E, K> const& rhs
) noexcept { return lhs.get() != rhs.get(); }
template <class T, class D, class C, class U, class E, class K>
bool operator >= (
deep_ptr<T, D, C> const& lhs,
deep_ptr<U, E, K> const& rhs
) noexcept { return not (lhs < rhs); }
template <class T, class D, class C, class U, class E, class K>
bool operator <= (
deep_ptr<T, D, C> const& lhs,
deep_ptr<U, E, K> const& rhs
) noexcept { return not (rhs < lhs); }
template <class T, class D, class C, class U, class E, class K>
bool operator > (
deep_ptr<T, D, C> const& lhs,
deep_ptr<U, E, K> const& rhs
) noexcept { return rhs < lhs; }
template <class T, class D, class C, class U, class E, class K>
bool operator < (
deep_ptr<T, D, C> const& lhs,
deep_ptr<U, E, K> const& rhs
) noexcept {
using common_type = common_type_t<
typename deep_ptr<T, D, C>::pointer,
typename deep_ptr<U, E, K>::pointer
>;
return ::std::less<common_type> { }(lhs.get(), rhs.get());
}
/* poly_ptr nullptr operator overloads */
template <class T, class D>
bool operator == (poly_ptr<T, D> const& lhs, ::std::nullptr_t) noexcept {
return not lhs;
}
template <class T, class D>
bool operator == (::std::nullptr_t, poly_ptr<T, D> const& rhs) noexcept {
return not rhs;
}
template <class T, class D>
bool operator != (poly_ptr<T, D> const& lhs, ::std::nullptr_t) noexcept {
return bool(lhs);
}
template <class T, class D>
bool operator != (::std::nullptr_t, poly_ptr<T, D> const& rhs) noexcept {
return bool(rhs);
}
template <class T, class D>
bool operator >= (poly_ptr<T, D> const& lhs, ::std::nullptr_t) noexcept {
return not (lhs < nullptr);
}
template <class T, class D>
bool operator >= (::std::nullptr_t, poly_ptr<T, D> const& rhs) noexcept {
return not (nullptr < rhs);
}
template <class T, class D>
bool operator <= (poly_ptr<T, D> const& lhs, ::std::nullptr_t) noexcept {
return not (nullptr < lhs);
}
template <class T, class D>
bool operator <= (::std::nullptr_t, poly_ptr<T, D> const& rhs) noexcept {
return not (rhs < nullptr);
}
template <class T, class D>
bool operator > (poly_ptr<T, D> const& lhs, ::std::nullptr_t) noexcept {
return nullptr < lhs;
}
template <class T, class D>
bool operator > (::std::nullptr_t, poly_ptr<T, D> const& rhs) noexcept {
return rhs < nullptr;
}
template <class T, class D>
bool operator < (poly_ptr<T, D> const& lhs, ::std::nullptr_t) noexcept {
using pointer = typename poly_ptr<T, D>::pointer;
return ::std::less<pointer> { }(lhs.get(), nullptr);
}
template <class T, class D>
bool operator < (::std::nullptr_t, poly_ptr<T, D> const& rhs) noexcept {
using pointer = typename poly_ptr<T, D>::pointer;
return ::std::less<pointer> { }(nullptr, rhs.get());
}
/* deep_ptr nullptr operator overloads */
template <class T, class D, class C>
bool operator == (deep_ptr<T, D, C> const& lhs, ::std::nullptr_t) noexcept {
return not lhs;
}
template <class T, class D, class C>
bool operator == (::std::nullptr_t, deep_ptr<T, D, C> const& rhs) noexcept {
return not rhs;
}
template <class T, class D, class C>
bool operator != (deep_ptr<T, D, C> const& lhs, ::std::nullptr_t) noexcept {
return bool(lhs);
}
template <class T, class D, class C>
bool operator != (::std::nullptr_t, deep_ptr<T, D, C> const& rhs) noexcept {
return bool(rhs);
}
template <class T, class D, class C>
bool operator >= (deep_ptr<T, D, C> const& lhs, ::std::nullptr_t) noexcept {
return not (lhs < nullptr);
}
template <class T, class D, class C>
bool operator >= (::std::nullptr_t, deep_ptr<T, D, C> const& rhs) noexcept {
return not (nullptr < rhs);
}
template <class T, class D, class C>
bool operator <= (deep_ptr<T, D, C> const& lhs, ::std::nullptr_t) noexcept {
return not (nullptr < lhs);
}
template <class T, class D, class C>
bool operator <= (::std::nullptr_t, deep_ptr<T, D, C> const& rhs) noexcept {
return not (rhs < nullptr);
}
template <class T, class D, class C>
bool operator > (deep_ptr<T, D, C> const& lhs, ::std::nullptr_t) noexcept {
return nullptr < lhs;
}
template <class T, class D, class C>
bool operator > (::std::nullptr_t, deep_ptr<T, D, C> const& rhs) noexcept {
return rhs < nullptr;
}
template <class T, class D, class C>
bool operator < (deep_ptr<T, D, C> const& lhs, ::std::nullptr_t) noexcept {
using pointer = typename deep_ptr<T, D, C>::pointer;
return ::std::less<pointer> { }(lhs.get(), nullptr);
}
template <class T, class D, class C>
bool operator < (::std::nullptr_t, deep_ptr<T, D, C> const& rhs) noexcept {
using pointer = typename deep_ptr<T, D, C>::pointer;
return ::std::less<pointer> { }(nullptr, rhs.get());
}
/* observer_ptr and nullptr overloads */
template <class T, class U>
bool operator == (
observer_ptr<T> const& lhs,
observer_ptr<U> const& rhs
) noexcept { return lhs.get() == rhs.get(); }
template <class T, class U>
bool operator != (
observer_ptr<T> const& lhs,
observer_ptr<U> const& rhs
) noexcept { return lhs.get() != rhs.get(); }
template <class T>
bool operator == (observer_ptr<T> const& lhs, ::std::nullptr_t) noexcept {
return lhs.get() == nullptr;
}
template <class T>
bool operator != (observer_ptr<T> const& lhs, ::std::nullptr_t) noexcept {
return lhs.get() != nullptr;
}
template <class T>
bool operator == (::std::nullptr_t, observer_ptr<T> const& rhs) noexcept {
return nullptr == rhs.get();
}
template <class T>
bool operator != (::std::nullptr_t, observer_ptr<T> const& rhs) noexcept {
return nullptr != rhs.get();
}
template <class T, class U>
bool operator >= (
observer_ptr<T> const& lhs,
observer_ptr<U> const& rhs
) noexcept { return lhs.get() >= rhs.get(); }
template <class T, class U>
bool operator <= (
observer_ptr<T> const& lhs,
observer_ptr<U> const& rhs
) noexcept { return lhs.get() <= rhs.get(); }
template <class T, class U>
bool operator > (
observer_ptr<T> const& lhs,
observer_ptr<U> const& rhs
) noexcept { return lhs.get() > rhs.get(); }
template <class T, class U>
bool operator < (
observer_ptr<T> const& lhs,
observer_ptr<U> const& rhs
) noexcept { return lhs.get() < rhs.get(); }
/* make_observer */
template <class W>
observer_ptr<W> make_observer (W* ptr) noexcept {
return observer_ptr<W> { ptr };
}
template <class W, class D>
observer_ptr<W> make_observer (::std::unique_ptr<W, D> const& ptr) noexcept {
return observer_ptr<W> { ptr.get() };
}
template <class W>
observer_ptr<W> make_observer (::std::shared_ptr<W> const& ptr) noexcept {
return observer_ptr<W> { ptr.get() };
}
template <class W>
observer_ptr<W> make_observer (::std::weak_ptr<W> const& ptr) noexcept {
return make_observer(ptr.lock());
}
template <class W, class C, class D>
observer_ptr<W> make_observer (deep_ptr<W, C, D> const& ptr) noexcept {
return observer_ptr<W> { ptr.get() };
}
template <class W, class D>
observer_ptr<W> make_observer (poly_ptr<W, D> const& ptr) noexcept {
return observer_ptr<W> { ptr.get() };
}
/* make_poly */
template <
class T,
class U,
class=enable_if_t<
::std::is_polymorphic<T>::value and ::std::is_base_of<T, U>::value
>
> auto make_poly (U&& value) -> poly_ptr<T> {
return poly_ptr<T> { new U { ::std::forward<U>(value) } };
}
/* make_deep */
template <
class T,
class=enable_if_t<not ::std::is_array<T>::value>,
class... Args
> auto make_deep (Args&&... args) -> deep_ptr<T> {
return deep_ptr<T> { new T { ::std::forward<Args>(args)... } };
}
/* make_unique */
template <
class Type,
class=enable_if_t<not ::std::is_array<Type>::value>,
class... Args
> auto make_unique(Args&&... args) -> ::std::unique_ptr<Type> {
return ::std::unique_ptr<Type> {
new Type { ::std::forward<Args>(args)... }
};
}
template <
class Type,
class=enable_if_t< ::std::is_array<Type>::value>,
class=enable_if_t<not ::std::extent<Type>::value>
> auto make_unique(::std::size_t size) -> ::std::unique_ptr<Type> {
return ::std::unique_ptr<Type> { new remove_extent_t<Type>[size] { } };
}
template <
class Type,
class=enable_if_t< ::std::is_array<Type>::value>,
class=enable_if_t< ::std::extent<Type>::value>,
class... Args
> auto make_unique(Args&&...) -> void = delete;
template <class T, class D>
void swap (poly_ptr<T, D>& lhs, poly_ptr<T, D>& rhs) noexcept(
noexcept(lhs.swap(rhs))
) { lhs.swap(rhs); }
template <class T, class D, class C>
void swap (deep_ptr<T, D, C>& lhs, deep_ptr<T, D, C>& rhs) noexcept(
noexcept(lhs.swap(rhs))
) { lhs.swap(rhs); }
template <class W>
void swap (observer_ptr<W>& lhs, observer_ptr<W>& rhs) noexcept(
noexcept(lhs.swap(rhs))
) { lhs.swap(rhs); }
}} /* namespace core::v1 */
namespace std {
template <class T, class D>
struct hash<core::v1::poly_ptr<T, D>> {
using value_type = core::v1::poly_ptr<T, D>;
size_t operator ()(value_type const& value) const noexcept {
return hash<typename value_type::pointer>{ }(value.get());
}
};
template <class T, class Deleter, class Copier>
struct hash<core::v1::deep_ptr<T, Deleter, Copier>> {
using value_type = core::v1::deep_ptr<T, Deleter, Copier>;
size_t operator ()(value_type const& value) const noexcept {
return hash<typename value_type::pointer> { }(value.get());
}
};
template <class W>
struct hash<core::v1::observer_ptr<W>> {
using value_type = core::v1::observer_ptr<W>;
size_t operator ()(value_type const& value) const noexcept {
return hash<typename value_type::pointer> { }(value.get());
}
};
} /* namespace std */
#endif /* CORE_MEMORY_HPP */

View File

@@ -0,0 +1,156 @@
#ifndef CORE_NUMERIC_HPP
#define CORE_NUMERIC_HPP
#include <numeric>
#include <bsoncxx/third_party/mnmlstc/core/range.hpp>
namespace core {
inline namespace v1 {
template <class Range, class T>
auto iota (Range&& rng, T&& value) -> enable_if_t<is_range<Range>::value> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_forward = decltype(range)::is_forward;
static_assert(is_forward, "iota requires ForwardIterators");
return ::std::iota(
::std::begin(range),
::std::end(range),
::std::forward<T>(value)
);
}
template <class Range, class T>
auto accumulate (Range&& rng, T&& init) -> enable_if_t<
is_range<Range>::value,
decay_t<T>
> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "accumulate requires InputIterators");
return ::std::accumulate(
::std::begin(range),
::std::end(range),
::std::forward<T>(init)
);
}
template <class Range, class T, class BinaryOp>
auto accumulate (Range&& rng, T&& init, BinaryOp&& op) -> enable_if_t<
is_range<Range>::value,
decay_t<T>
> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "accumulate requires InputIterators");
return ::std::accumulate(
::std::begin(range),
::std::end(range),
::std::forward<T>(init),
::std::forward<BinaryOp>(op)
);
}
template <class Range, class InputIt, class T>
auto inner_product (Range&& rng, InputIt&& it, T&& value) -> enable_if_t<
is_range<Range>::value,
decay_t<T>
> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "inner_product requires InputIterators");
return ::std::inner_product(
::std::begin(range),
::std::end(range),
::std::forward<InputIt>(it),
::std::forward<T>(value)
);
}
template <class Range, class InputIt, class T, class BinaryOp, class BinaryOp2>
auto inner_product (
Range&& rng,
InputIt&& it,
T&& value,
BinaryOp&& op,
BinaryOp2&& op2
) -> enable_if_t<is_range<Range>::value, decay_t<T>> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "inner_product requires InputIterators");
return ::std::inner_product(
::std::begin(range),
::std::end(range),
::std::forward<InputIt>(it),
::std::forward<T>(value),
::std::forward<BinaryOp>(op),
::std::forward<BinaryOp2>(op2)
);
}
template <class Range, class OutputIt>
auto adjacent_difference (Range&& rng, OutputIt&& it) -> enable_if_t<
is_range<Range>::value,
decay_t<OutputIt>
> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "adjacent_difference requires InputIterators");
return ::std::adjacent_difference(
::std::begin(range),
::std::end(range),
::std::forward<OutputIt>(it)
);
}
template <class Range, class OutputIt, class BinaryOp>
auto adjacent_difference (
Range&& rng,
OutputIt&& it,
BinaryOp&& op
) -> enable_if_t<is_range<Range>::value, decay_t<OutputIt>> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "adjacent_difference requires InputIterators");
return ::std::adjacent_difference(
::std::begin(range),
::std::end(range),
::std::forward<OutputIt>(it),
::std::forward<BinaryOp>(op)
);
}
template <class Range, class OutputIt>
auto partial_sum (Range&& rng, OutputIt&& it) -> enable_if_t<
is_range<Range>::value,
decay_t<OutputIt>
> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "partial_sum requires InputIterators");
return ::std::partial_sum(
::std::begin(range),
::std::end(range),
::std::forward<OutputIt>(it)
);
}
template <class Range, class OutputIt, class BinaryOp>
auto partial_sum (Range&& rng, OutputIt&& it, BinaryOp&& op) -> enable_if_t<
is_range<Range>::value,
decay_t<OutputIt>
> {
auto range = make_range(::std::forward<Range>(rng));
constexpr auto is_input = decltype(range)::is_input;
static_assert(is_input, "partial_sum requires InputIterators");
return ::std::partial_sum(
::std::begin(range),
::std::end(range),
::std::forward<OutputIt>(it),
::std::forward<BinaryOp>(op)
);
}
}} /* namespace core::v1 */
#endif /* CORE_NUMERIC_HPP */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,313 @@
#ifndef CORE_RANGE_HPP
#define CORE_RANGE_HPP
#include <iterator>
#include <istream>
#include <utility>
#include <memory>
#include <cstdlib>
#include <bsoncxx/third_party/mnmlstc/core/type_traits.hpp>
namespace core {
inline namespace v1 {
namespace impl {
template <class T>
class begin {
template <class U>
static auto check (U&& u) noexcept -> decltype(::std::begin(u));
static void check (...) noexcept(false);
public:
using type = decltype(check(::std::declval<T>()));
static constexpr bool value = noexcept(check(::std::declval<T>()));
};
template <class T>
class end {
template <class U>
static auto check (U&& u) noexcept -> decltype(::std::end(u));
static void check (...) noexcept(false);
public:
using type = decltype(check(::std::declval<T>()));
static constexpr bool value = noexcept(check(::std::declval<T>()));
};
} /* namespace impl */
template <class R>
struct is_range : ::std::integral_constant<bool,
impl::begin<R>::value and impl::end<R>::value
> { };
template <class Iterator>
struct range {
using traits = ::std::iterator_traits<Iterator>;
using iterator_category = typename traits::iterator_category;
using difference_type = typename traits::difference_type;
using value_type = typename traits::value_type;
using reference = typename traits::reference;
using pointer = typename traits::pointer;
using iterator = Iterator;
static constexpr bool is_input = ::std::is_convertible<
iterator_category,
::std::input_iterator_tag
>::value;
static constexpr bool is_output = ::std::is_convertible<
iterator_category,
::std::output_iterator_tag
>::value;
static constexpr bool is_forward = ::std::is_convertible<
iterator_category,
::std::forward_iterator_tag
>::value;
static constexpr bool is_bidirectional = ::std::is_convertible<
iterator_category,
::std::bidirectional_iterator_tag
>::value;
static constexpr bool is_random_access = ::std::is_convertible<
iterator_category,
::std::random_access_iterator_tag
>::value;
template <
typename Range,
typename=enable_if_t<
not ::std::is_pointer<iterator>::value and
is_range<Range>::value and
::std::is_convertible<typename impl::begin<Range>::type, iterator>::value
>
> explicit range (Range&& r) noexcept :
range { ::std::begin(r), ::std::end(r) }
{ }
range (::std::pair<iterator, iterator> pair) noexcept :
range { ::std::get<0>(pair), ::std::get<1>(pair) }
{ }
range (iterator begin_, iterator end_) noexcept :
begin_ { begin_ },
end_ { end_ }
{ }
range (range const& that) :
range { that.begin_, that.end_ }
{ }
range (range&& that) noexcept :
range { ::std::move(that.begin_), ::std::move(that.end_) }
{ that.begin_ = that.end_; }
range () = default;
~range () = default;
range& operator = (range const& that) {
return *this = range { that };
}
range& operator = (range&& that) {
range { ::std::move(that) }.swap(*this);
return *this;
}
reference operator [](difference_type idx) const {
static_assert(is_random_access, "can only subscript into random-access");
return idx < 0 ? this->end()[idx] : this->begin()[idx];
}
iterator begin () const { return this->begin_; }
iterator end () const { return this->end_; }
reference front () const { return *this->begin(); }
reference back () const {
static_assert(is_bidirectional, "can only get back of bidirectional");
return *::std::prev(this->end());
}
bool empty () const { return this->begin() == this->end(); }
difference_type size () const {
static_assert(is_forward, "can only get size of forward-range");
return ::std::distance(this->begin(), this->end());
}
/* Creates an open-ended range of [start, stop) */
range slice (difference_type start, difference_type stop) const {
static_assert(is_forward, "can only slice forward-range");
/* Behavior is:
* if start is negative, the begin marker is this->end() - start
* if stop is negative, the end marker is this->end() - stop
* if start is positive, the begin marker is this->begin() + start
* if stop is positive, the end marker is this->begin() + stop
*
* if start and stop are positive, and stop is less than or equal to start,
* an empty range is returned.
*
* if start and stop are negative and stop is less than or equal to start,
* an empty range is returned.
*
* if start is positive and stop is negative and abs(stop) + start is
* greater than or equal to this->size(), an empty range is returned.
*
* if start is negative and stop is positive and this->size() + start is
* greater or equal to stop, an empty range is returned.
*
* The first two conditions can be computed cheaply, while the third and
* fourth are a bit more expensive, but WILL be required no matter what
* iterator type we are. However we don't compute the size until after
* we've checked the first two conditions
*
* An example with python style slicing for each would be:
* [4:3] -> empty range
* [-4:-4] -> empty range
* [7:-4] -> empty range for string of size 11 or more
* [-4:15] -> empty range for a string of size 19 or less.
*/
bool const start_positive = start > 0;
bool const stop_positive = stop > 0;
bool const stop_less = stop < start;
bool const first_return_empty =
(start_positive and stop_positive and stop_less) or
(not start_positive and not stop_positive and stop_less);
if (first_return_empty) { return range { }; }
/* now safe to compute size */
auto const size = this->size();
auto third_empty = ::std::abs(stop) + start;
bool const second_return_empty =
(start_positive and not stop_positive and third_empty >= size) or
(not start_positive and stop_positive and size + start >= stop);
if (second_return_empty) { return range { }; }
/* While the code below technically works for all iterators it is
* ineffecient in some cases for bidirectional ranges, where either of
* start or stop are negative.
* TODO: Specialize for bidirectional operators
*/
if (not start_positive) { start = size + start; }
if (not stop_positive) { stop = size + stop; }
auto begin = this->begin();
::std::advance(begin, start);
auto end = begin;
::std::advance(end, stop - start);
return range { begin, end };
}
/* Creates an open-ended range of [start, end()) */
range slice (difference_type start) const {
static_assert(is_forward, "can only slice forward-range");
return range { split(start).second };
}
::std::pair<range, range> split (difference_type idx) const {
static_assert(is_forward,"can only split a forward-range");
if (idx >= 0) {
range second { *this };
second.pop_front_upto(idx);
return ::std::make_pair(range { this->begin(), second.begin() }, second);
}
range first { *this };
first.pop_back_upto(-idx);
return ::std::make_pair(first, range { first.end(), this->end() });
}
/* mutates range */
void pop_front (difference_type n) { ::std::advance(this->begin_, n); }
void pop_front () { ++this->begin_; }
void pop_back (difference_type n) {
static_assert(is_bidirectional, "can only pop-back bidirectional-range");
::std::advance(this->end_, -n);
}
void pop_back () {
static_assert(is_bidirectional, "can only pop-back bidirectional-range");
--this->end_;
}
/* Negative argument causes no change */
void pop_front_upto (difference_type n) {
::std::advance(
this->begin_,
::std::min(::std::max<difference_type>(0, n), this->size())
);
}
/* Negative argument causes no change */
void pop_back_upto (difference_type n) {
static_assert(is_bidirectional, "can only pop-back-upto bidirectional");
::std::advance(
this->end_,
-::std::min(::std::max<difference_type>(0, n), this->size())
);
}
void swap (range& that) noexcept(is_nothrow_swappable<iterator>::value) {
using ::std::swap;
swap(this->begin_, that.begin_);
swap(this->end_, that.end_);
}
private:
iterator begin_;
iterator end_;
};
template <class Iterator>
auto make_range (Iterator begin, Iterator end) -> range<Iterator> {
return range<Iterator> { begin, end };
}
template <class Range>
auto make_range (Range&& value) -> range<decltype(::std::begin(value))> {
return make_range(::std::begin(value), ::std::end(value));
}
template <class Range>
auto make_ptr_range (Range&& value) -> range<
decltype(::std::addressof(*::std::begin(value)))
>;
/* Used like: core::make_range<char>(::std::cin) */
template <
class T,
class CharT,
class Traits=::std::char_traits<CharT>
> auto make_range (::std::basic_istream<CharT, Traits>& stream) -> range<
::std::istream_iterator<T, CharT, Traits>
> {
using iterator = ::std::istream_iterator<T, CharT, Traits>;
return make_range(iterator { stream }, iterator { });
}
template <class CharT, class Traits=::std::char_traits<CharT>>
auto make_range (::std::basic_streambuf<CharT, Traits>* buffer) -> range<
::std::istreambuf_iterator<CharT, Traits>
> {
using iterator = ::std::istreambuf_iterator<CharT, Traits>;
return make_range(iterator { buffer }, iterator { });
}
template <class Iterator>
void swap (range<Iterator>& lhs, range<Iterator>& rhs) noexcept(
noexcept(lhs.swap(rhs))
) { lhs.swap(rhs); }
}} /* namespace core::v1 */
#endif /* CORE_RANGE_HPP */

View File

@@ -0,0 +1,369 @@
#ifndef CORE_STRING_HPP
#define CORE_STRING_HPP
#include <initializer_list>
#include <functional>
#include <stdexcept>
#include <algorithm>
#include <iterator>
#include <string>
#include <limits>
namespace core {
inline namespace v1 {
template <class CharT, class Traits=::std::char_traits<CharT>>
struct basic_string_view {
using difference_type = ::std::ptrdiff_t;
using value_type = CharT;
using size_type = ::std::size_t;
using reference = value_type const&;
using pointer = value_type const*;
using const_reference = reference;
using const_pointer = pointer;
using const_iterator = pointer;
using iterator = const_iterator;
using const_reverse_iterator = ::std::reverse_iterator<const_iterator>;
using reverse_iterator = const_reverse_iterator;
using traits = Traits;
static constexpr size_type npos = ::std::numeric_limits<size_type>::max();
template <class Allocator>
basic_string_view (
::std::basic_string<CharT, Traits, Allocator> const& that
) : str { that.data() }, len { that.size() } { }
constexpr basic_string_view (pointer str, size_type len) noexcept :
str { str },
len { len }
{ }
basic_string_view (pointer str) noexcept :
basic_string_view { str, traits::length(str) }
{ }
constexpr basic_string_view (basic_string_view const& that) noexcept :
str { that.str },
len { that.len }
{ }
constexpr basic_string_view () noexcept :
str { nullptr },
len { 0 }
{ }
basic_string_view& operator = (basic_string_view const& that) noexcept {
basic_string_view { that }.swap(*this);
return *this;
}
template <class Allocator>
explicit operator ::std::basic_string<CharT, Traits, Allocator> () const {
return ::std::basic_string<CharT, Traits, Allocator> {
this->data(),
this->size()
};
}
template <class Allocator=std::allocator<CharT>>
::std::basic_string<CharT, Traits, Allocator> to_string (
Allocator const& allocator = Allocator()
) const {
return ::std::basic_string<CharT, Traits, Allocator> {
this->data(),
this->size(),
allocator
};
}
constexpr const_iterator begin () const noexcept { return this->data(); }
constexpr const_iterator end () const noexcept {
return this->data() + this->size();
}
constexpr const_iterator cbegin () const noexcept { return this->begin(); }
constexpr const_iterator cend () const noexcept { return this->end(); }
const_reverse_iterator rbegin () const noexcept {
return const_reverse_iterator { this->end()};
}
const_reverse_iterator rend () const noexcept {
return const_reverse_iterator { this->begin() };
}
const_reverse_iterator crbegin () const noexcept { return this->rbegin(); }
const_reverse_iterator crend () const noexcept { return this->rend(); }
constexpr size_type max_size () const noexcept { return this->size(); }
constexpr size_type length () const noexcept { return this->size(); }
constexpr size_type size () const noexcept { return this->len; }
constexpr bool empty () const noexcept { return this->size() == 0; }
constexpr reference operator [] (size_type idx) const {
return this->str[idx];
}
constexpr reference front () const { return this->str[0]; }
constexpr reference back () const { return this->str[this->size() - 1]; }
constexpr pointer data () const { return this->str; }
void remove_prefix (size_type n) {
if (n > this->size()) { n = this->size(); }
this->str += n;
this->len -= n;
}
void remove_suffix (size_type n) {
if (n > this->size()) { n = this->size(); }
this->len -= n;
}
void clear () noexcept {
this->str = nullptr;
this->len = 0;
}
constexpr basic_string_view substr (size_type pos, size_type n=npos) const {
return pos > this->size()
? throw ::std::out_of_range { "start position out of range" }
: basic_string_view {
this->data() + pos,
n == npos or pos + n > this->size()
? (this->size() - pos)
: n
};
}
bool starts_with (value_type value) const noexcept {
return not this->empty() and traits::eq(value, this->front());
}
bool ends_with (value_type value) const noexcept {
return not this->empty() and traits::eq(value, this->back());
}
bool starts_with (basic_string_view that) const noexcept {
return this->size() >= that.size() and
traits::compare(this->data(), that.data(), that.size()) == 0;
}
bool ends_with (basic_string_view that) const noexcept {
return this->size() >= that.size() and
traits::compare(
this->data() + this->size() - that.size(),
that.data(),
that.size()
) == 0;
}
difference_type compare (basic_string_view that) const {
auto cmp = traits::compare(
this->data(),
that.data(),
::std::min(this->size(), that.size())
);
if (cmp != 0) { return cmp; }
if (this->size() == that.size()) { return 0; }
if (this->size() < that.size()) { return -1; }
return 1;
}
reference at (size_type idx) const {
if (idx >= this->size()) {
throw ::std::out_of_range { "requested index out of range" };
}
return this->str[idx];
}
/* functions that take a string-ref */
size_type find_first_not_of (basic_string_view that) const {
for (auto iter = this->begin(); iter != this->end(); ++iter) {
if (traits::find(that.data(), that.size(), *iter)) { continue; }
return ::std::distance(this->begin(), iter);
}
return npos;
}
size_type find_last_not_of (basic_string_view that) const {
for (auto iter = this->rbegin(); iter != this->rend(); ++iter) {
if (traits::find(that.data(), that.size(), *iter)) { continue; }
return this->size() - ::std::distance(this->rbegin(), iter) - 1;
}
return npos;
}
size_type find_first_of (basic_string_view that) const {
auto iter = ::std::find_first_of(
this->begin(), this->end(),
that.begin(), that.end(),
traits::eq
);
if (iter == this->end()) { return npos; }
return ::std::distance(this->begin(), iter);
}
size_type find_last_of (basic_string_view that) const {
auto iter = ::std::find_first_of(
this->rbegin(), this->rend(),
that.rbegin(), that.rend(),
traits::eq
);
if (iter == this->rend()) { return npos; }
return this->size() - ::std::distance(this->rbegin(), iter) - 1;
}
size_type rfind (basic_string_view that) const {
auto iter = ::std::search(
this->rbegin(), this->rend(),
that.rbegin(), that.rend(),
traits::eq
);
if (iter == this->rend()) { return npos; }
return this->size() - ::std::distance(this->rbegin(), iter) - 1;
}
size_type find (basic_string_view that) const {
auto iter = ::std::search(
this->begin(), this->end(),
that.begin(), that.end(),
traits::eq
);
if (iter == this->end()) { return npos; }
return ::std::distance(this->begin(), iter);
}
/* functions that take a single CharT */
size_type find_first_not_of (value_type value) const {
auto end = this->end();
auto iter = ::std::find_if_not(
this->begin(),
end,
[value](value_type val) { return traits::eq(val, value); }
);
if (iter == end) { return npos; }
return ::std::distance(this->begin(), iter);
}
size_type find_last_not_of (value_type value) const {
auto end = this->rend();
auto iter = ::std::find_if_not(
this->rbegin(),
end,
[value](value_type val) { return traits::eq(val, value); }
);
if (iter == end) { return npos; }
return this->size() - ::std::distance(this->rbegin(), iter) - 1;
}
size_type find_first_of (value_type value) const {
return this->find(value);
}
size_type find_last_of (value_type value) const {
return this->rfind(value);
}
size_type rfind (value_type value) const {
auto end = this->rend();
auto iter = ::std::find(this->rbegin(), end, value);
if (iter == end) { return npos; }
return this->size() - ::std::distance(this->rbegin(), iter) -1;
}
size_type find (value_type value) const {
auto end = this->end();
auto iter = ::std::find(this->begin(), end, value);
if (iter == end) { return npos; }
return ::std::distance(this->begin(), iter);
}
void swap (basic_string_view& that) noexcept {
using ::std::swap;
swap(this->str, that.str);
swap(this->len, that.len);
}
private:
pointer str;
size_type len;
};
using u32string_view = basic_string_view<char32_t>;
using u16string_view = basic_string_view<char16_t>;
using wstring_view = basic_string_view<wchar_t>;
using string_view = basic_string_view<char>;
template <class CharT, typename Traits>
bool operator == (
basic_string_view<CharT, Traits> lhs,
basic_string_view<CharT, Traits> rhs
) noexcept { return lhs.size() == rhs.size() and lhs.compare(rhs) == 0; }
template <class CharT, typename Traits>
bool operator != (
basic_string_view<CharT, Traits> lhs,
basic_string_view<CharT, Traits> rhs
) noexcept { return lhs.size() != rhs.size() or lhs.compare(rhs) != 0; }
template <class CharT, typename Traits>
bool operator >= (
basic_string_view<CharT, Traits> lhs,
basic_string_view<CharT, Traits> rhs
) noexcept { return lhs.compare(rhs) >= 0; }
template <class CharT, typename Traits>
bool operator <= (
basic_string_view<CharT, Traits> lhs,
basic_string_view<CharT, Traits> rhs
) noexcept { return lhs.compare(rhs) <= 0; }
template <class CharT, typename Traits>
bool operator > (
basic_string_view<CharT, Traits> lhs,
basic_string_view<CharT, Traits> rhs
) noexcept { return lhs.compare(rhs) > 0; }
template <class CharT, typename Traits>
bool operator < (
basic_string_view<CharT, Traits> lhs,
basic_string_view<CharT, Traits> rhs
) noexcept { return lhs.compare(rhs) < 0; }
template <class CharT, class Traits>
::std::basic_ostream<CharT, Traits>& operator << (
::std::basic_ostream<CharT, Traits>& os,
basic_string_view<CharT, Traits> const& str
) { return os << str.to_string(); }
template <class CharT, class Traits>
void swap (
basic_string_view<CharT, Traits>& lhs,
basic_string_view<CharT, Traits>& rhs
) noexcept { return lhs.swap(rhs); }
}} /* namespace core::v1 */
namespace std {
template <typename CharT, typename Traits>
struct hash<core::v1::basic_string_view<CharT, Traits>> {
using argument_type = core::v1::basic_string_view<CharT, Traits>;
using result_type = size_t;
result_type operator ()(argument_type const& ref) const noexcept {
return hash<typename argument_type::pointer> { }(ref.data());
}
};
} /* namespace std */
#endif /* CORE_STRING_HPP */

View File

@@ -0,0 +1,267 @@
#ifndef CORE_TYPE_TRAITS_HPP
#define CORE_TYPE_TRAITS_HPP
#include <type_traits>
#include <utility>
namespace core {
inline namespace v1 {
/* custom type traits */
/* tuple_size is used by unpack, so we expect it to be available.
* We also expect ::std::get<N> to be available for the give type T
*/
template <class T>
class is_unpackable {
template <class U> using tuple_size_t = typename ::std::tuple_size<U>::type;
template <class U> static void check (tuple_size_t<U>*) noexcept;
template <class> static void check (...) noexcept(false);
public:
static constexpr bool value = noexcept(check<T>(nullptr));
};
/* Used for types that have a .at(size_type) member function */
template <class T>
class is_runpackable {
template <class U>
static auto check (U* u) noexcept -> decltype(u->at(0ul), void());
template <class> static void check (...) noexcept(false);
public:
static constexpr bool value = noexcept(check<T>(nullptr));
};
/* extracts the class of a member function ponter */
template <class T> struct class_of { using type = T; };
template <class Signature, class Type>
struct class_of<Signature Type::*> { using type = Type; };
/* forward declaration */
template <class... Args> struct invokable;
template <class... Args> struct invoke_of;
template <class T> struct result_of; /* SFINAE result_of */
/* C++14 style aliases for standard traits */
template <class T>
using remove_volatile_t = typename ::std::remove_volatile<T>::type;
template <class T>
using remove_const_t = typename ::std::remove_const<T>::type;
template <class T> using remove_cv_t = typename ::std::remove_cv<T>::type;
template <class T>
using add_volatile_t = typename ::std::add_volatile<T>::type;
template <class T> using add_const_t = typename ::std::add_const<T>::type;
template <class T> using add_cv_t = typename ::std::add_cv<T>::type;
template <class T>
using add_lvalue_reference_t = typename ::std::add_lvalue_reference<T>::type;
template <class T>
using add_rvalue_reference_t = typename ::std::add_rvalue_reference<T>::type;
template <class T>
using remove_reference_t = typename ::std::remove_reference<T>::type;
template <class T>
using remove_pointer_t = typename ::std::remove_pointer<T>::type;
template <class T> using add_pointer_t = typename ::std::add_pointer<T>::type;
template <class T>
using make_unsigned_t = typename ::std::make_unsigned<T>::type;
template <class T> using make_signed_t = typename ::std::make_signed<T>::type;
template <class T>
using remove_extent_t = typename ::std::remove_extent<T>::type;
template <class T>
using remove_all_extents_t = typename ::std::remove_all_extents<T>::type;
template < ::std::size_t Len, ::std::size_t Align>
using aligned_storage_t = typename ::std::aligned_storage<Len, Align>::type;
template <class T> using decay_t = typename ::std::decay<T>::type;
template <bool B, class T = void>
using enable_if_t = typename ::std::enable_if<B, T>::type;
template <bool B, class T, class F>
using conditional_t = typename ::std::conditional<B, T, F>::type;
template <class T>
using underlying_type_t = typename ::std::underlying_type<T>::type;
/* custom type trait specializations */
template <class... Args> using invoke_of_t = typename invoke_of<Args...>::type;
template <class T> using class_of_t = typename class_of<T>::type;
namespace impl {
struct undefined { undefined (...); };
/* Get the result of an attempt at the INVOKE expression */
/* fallback */
template <class... Args> auto invoke_expr (undefined, Args&&...) -> undefined;
template <class Functor, class Object, class... Args>
auto invoke_expr (Functor&& fun, Object&& obj, Args&&... args) -> enable_if_t<
::std::is_member_function_pointer<remove_reference_t<Functor>>::value and
::std::is_base_of<
class_of_t<remove_reference_t<Functor>>,
remove_reference_t<Object>
>::value,
decltype((::std::forward<Object>(obj).*fun)(::std::forward<Args>(args)...))
>;
template <class Functor, class Object, class... Args>
auto invoke_expr (Functor&& fun, Object&& obj, Args&&... args) -> enable_if_t<
::std::is_member_function_pointer<remove_reference_t<Functor>>::value and
not ::std::is_base_of<
class_of_t<remove_reference_t<Functor>>,
remove_reference_t<Object>
>::value,
decltype(
((*::std::forward<Object>(obj)).*fun)(::std::forward<Args>(args)...)
)
>;
template <class Functor, class Object>
auto invoke_expr (Functor&& functor, Object&& object) -> enable_if_t<
::std::is_member_object_pointer<remove_reference_t<Functor>>::value and
::std::is_base_of<
class_of_t<remove_reference_t<Functor>>,
remove_reference_t<Object>
>::value,
decltype(::std::forward<Object>(object).*functor)
>;
template <class Functor, class Object>
auto invoke_expr (Functor&& functor, Object&& object) -> enable_if_t<
::std::is_member_object_pointer<remove_reference_t<Functor>>::value and
not ::std::is_base_of<
class_of_t<remove_reference_t<Functor>>,
remove_reference_t<Object>
>::value,
decltype((*::std::forward<Object>(object)).*functor)
>;
template <class Functor, class... Args>
auto invoke_expr (Functor&& functor, Args&&... args) -> decltype(
::std::forward<Functor>(functor)(::std::forward<Args>(args)...)
);
template <bool, class... Args> struct invoke_of { };
template <class... Args>
struct invoke_of<true, Args...> {
using type = decltype(invoke_expr(::std::declval<Args>()...));
};
/* swappable implementation details */
using ::std::declval;
using ::std::swap;
template <class T, class U>
class is_swappable {
template <class X, class Y>
static auto check (int) noexcept -> decltype(
swap(declval<X&>(), declval<Y&>()),
void()
);
template <class X, class Y> static void check (...) noexcept(false);
public:
static constexpr bool value =
noexcept(check<T, U>(0)) and noexcept(check<U, T>(0));
};
template <class T, class U>
struct is_nothrow_swappable : ::std::integral_constant<
bool,
is_swappable<T, U>::value and noexcept(swap(declval<T&>(), declval<U&>()))
> { };
} /* namespace impl */
template <class... Args> struct invokable : ::std::integral_constant<
bool,
not ::std::is_same<
decltype(impl::invoke_expr(::std::declval<Args>()...)),
impl::undefined
>::value
> { };
template <class... Args> struct invoke_of :
impl::invoke_of<invokable<Args...>::value, Args...>
{ };
template <class F, class... Args>
struct result_of<F(Args...)> : invoke_of<F, Args...> { };
template <class T> using result_of_t = typename result_of<T>::type;
template <class... Ts> struct common_type;
template <class T> struct common_type<T> { using type = decay_t<T>; };
template <class T, class U>
struct common_type<T, U> {
using type = decay_t<
decltype(true ? ::std::declval<T>() : ::std::declval<U>())
>;
};
template <class T, class U, class... Ts>
struct common_type<T, U, Ts...> {
using type = typename common_type<
typename common_type<T, U>::type,
Ts...
>::type;
};
template <class... T> using common_type_t = typename common_type<T...>::type;
/* is_null_pointer */
template <class T> struct is_null_pointer : ::std::false_type { };
template <>
struct is_null_pointer<add_cv_t< ::std::nullptr_t>> : ::std::true_type { };
template <>
struct is_null_pointer< ::std::nullptr_t volatile> : ::std::true_type { };
template <>
struct is_null_pointer< ::std::nullptr_t const> : ::std::true_type { };
template <>
struct is_null_pointer< ::std::nullptr_t> : ::std::true_type { };
/* is_swappable */
template <class T, class U=T>
using is_swappable = ::std::integral_constant<
bool,
impl::is_swappable<T, U>::value
>;
/* is_nothrow_swappable */
template <class T, class U=T>
using is_nothrow_swappable = impl::is_nothrow_swappable<T, U>;
/* all-traits */
template <class...> struct all_traits;
template <class T, class... Args>
struct all_traits<T, Args...> : ::std::integral_constant<bool,
T::value and all_traits<Args...>::value
> { };
template <> struct all_traits<> : ::std::true_type { };
/* any-traits */
template <class...> struct any_traits;
template <class T, class... Args>
struct any_traits<T, Args...> : ::std::integral_constant<bool,
T::value or any_traits<Args...>::value
> { };
template <> struct any_traits<> : ::std::false_type { };
/* no-traits */
template <class... Args> struct no_traits : ::std::integral_constant<bool,
not all_traits<Args...>::value
> { };
}} /* namespace core::v1 */
#endif /* CORE_TYPE_TRAITS_HPP */

View File

@@ -0,0 +1,142 @@
#ifndef CORE_UTILITY_HPP
#define CORE_UTILITY_HPP
#include <functional>
#include <cstddef>
#include <bsoncxx/third_party/mnmlstc/core/type_traits.hpp>
namespace core {
inline namespace v1 {
namespace impl {
template <class T, T... I> struct integer_sequence {
static_assert(
::std::is_integral<T>::value,
"integer_sequence must use an integral type"
);
template <T N> using append = integer_sequence<T, I..., N>;
static constexpr ::std::size_t size () noexcept { return sizeof...(I); }
using next = append<size()>;
using type = T;
};
template <class T, T Index, ::std::size_t N>
struct sequence_generator {
static_assert(Index >= 0, "Index cannot be negative");
using type = typename sequence_generator<T, Index - 1, N - 1>::type::next;
};
template <class T, T Index>
struct sequence_generator<T, Index, 0ul> { using type = integer_sequence<T>; };
template < ::std::size_t Index, class T, class U, class... Types>
struct typelist_index {
using type = typename typelist_index<Index + 1, T, Types...>::type;
static constexpr ::std::size_t value = Index;
};
template < ::std::size_t Index, class T, class... Types>
struct typelist_index<Index, T, T, Types...> {
using type = typelist_index;
static constexpr ::std::size_t value = Index;
};
} /* namespace impl */
template <class T>
constexpr T&& forward (remove_reference_t<T>& t) noexcept {
return static_cast<T&&>(t);
}
template <class T>
constexpr T&& forward (remove_reference_t<T>&& t) noexcept {
return static_cast<T&&>(t);
}
template <class T>
constexpr auto move (T&& t) noexcept -> decltype(
static_cast<remove_reference_t<T>&&>(t)
) { return static_cast<remove_reference_t<T>&&>(t); }
template <class T, T... I>
using integer_sequence = impl::integer_sequence<T, I...>;
template < ::std::size_t... I>
using index_sequence = integer_sequence< ::std::size_t, I...>;
template <class T, T N>
using make_integer_sequence = typename impl::sequence_generator<T, N, N>::type;
template < ::std::size_t N>
using make_index_sequence = make_integer_sequence< ::std::size_t, N>;
template <class T, class... Ts>
using typelist_index = ::std::integral_constant<
::std::size_t,
impl::typelist_index<0ul, T, Ts...>::type::value
>;
/* N3761 (with some additions) */
template < ::std::size_t N, class T, class... Ts>
struct type_at { using type = typename type_at<N - 1, Ts...>::type; };
template <class T, class... Ts>
struct type_at<0ul, T, Ts...> { using type = T; };
template < ::std::size_t N, class... Ts>
using type_at_t = typename type_at<N, Ts...>::type;
template < ::std::size_t N, class T, class... Ts>
constexpr auto value_at (T&& value, Ts&&...) -> enable_if_t<
N == 0 and N < (sizeof...(Ts) + 1),
decltype(::core::forward<T>(value))
> { return ::core::forward<T>(value); }
template < ::std::size_t N, class T, class... Ts>
constexpr auto value_at (T&&, Ts&&... values) -> enable_if_t<
N != 0 and N < (sizeof...(Ts) + 1),
type_at_t<N, T, Ts...>
> { return value_at<N - 1, Ts...>(::core::forward<Ts>(values)...); }
template <class Callable>
struct scope_guard final {
static_assert(
::std::is_nothrow_move_constructible<Callable>::value,
"Given type must be nothrow move constructible"
);
explicit scope_guard (Callable callable) noexcept :
callable { ::core::move(callable) },
dismissed { false }
{ }
scope_guard (scope_guard const&) = delete;
scope_guard (scope_guard&&) = default;
scope_guard () = delete;
~scope_guard () noexcept { if (not this->dismissed) { callable(); } }
scope_guard& operator = (scope_guard const&) = delete;
scope_guard& operator = (scope_guard&&) = default;
void dismiss () noexcept { this->dismissed = true; }
private:
Callable callable;
bool dismissed;
};
template <class Callable>
auto make_scope_guard(Callable&& callable) -> scope_guard<decay_t<Callable>> {
return scope_guard<decay_t<Callable>> {
::core::forward<Callable>(callable)
};
}
}} /* namespace core::v1 */
#endif /* CORE_UTILITY_HPP */

View File

@@ -0,0 +1,400 @@
#ifndef CORE_VARIANT_HPP
#define CORE_VARIANT_HPP
#include <bsoncxx/third_party/mnmlstc/core/type_traits.hpp>
#include <bsoncxx/third_party/mnmlstc/core/functional.hpp>
#include <bsoncxx/third_party/mnmlstc/core/utility.hpp>
#include <stdexcept>
#include <typeinfo>
#include <limits>
#include <cstdint>
namespace core {
inline namespace v1 {
namespace impl {
template <class... Ts> union discriminate;
template <> union discriminate<> { };
template <class T, class... Ts>
union discriminate<T, Ts...> {
T value;
discriminate<Ts...> rest;
};
/* Used to provide lambda based pattern matching for the variant
* Based off of Dave Abrahams C++11 'generic lambda' example.
*/
template <class... Lambdas> struct overload;
template <class Lambda> struct overload<Lambda> : Lambda {
using call_type = Lambda;
using call_type::operator ();
};
template <class Lambda, class... Lambdas>
struct overload<Lambda, Lambdas...> :
private Lambda,
private overload<Lambdas...>::call_type
{
using base_type = typename overload<Lambdas...>::call_type;
using lambda_type = Lambda;
using call_type = overload;
overload (Lambda&& lambda, Lambdas&&... lambdas) :
lambda_type(::core::forward<Lambda>(lambda)),
base_type(::core::forward<Lambdas>(lambdas)...)
{ }
using lambda_type::operator ();
using base_type::operator ();
};
template <class... Lambdas>
auto make_overload(Lambdas&&... lambdas) -> overload<Lambdas...> {
return overload<Lambdas...> { ::core::forward<Lambdas>(lambdas)... };
}
template <class Visitor, class Type, class Data, class Result, class... Args>
auto visitor_gen () -> Result {
return [](Visitor&& visitor, Data& data, Args&&... args) {
return invoke(
::core::forward<Visitor>(visitor),
reinterpret_cast<Type&>(data),
::core::forward<Args>(args)...
);
};
}
} /* namespace impl */
struct bad_variant_get final : ::std::logic_error {
using ::std::logic_error::logic_error;
};
/* visitation semantics require that, given a callable type C, and variadic
* arguments Args... that the return type of the visit will be SFINAE-ified
* as common_type_t<invoke_of_t<C, Args>...> (this assumes a variadic
* approach can be taken with common_type, which it cannot at this time. A
* custom SFINAE-capable version has been written within the type traits
* component.
*
* Obviously if a common type cannot be found, then the visitation function
* cannot be generated.
*
* These same semantics are required for variant<Ts...>::match which simply
* calls visit with a generate overload<Lambdas...> type.
*/
template <class... Ts>
class variant final {
static_assert(
sizeof...(Ts) < ::std::numeric_limits<uint8_t>::max(),
"Cannot have more elements than variant can contain"
);
using tuple_type = ::std::tuple<Ts...>;
using storage_type = aligned_storage_t<
sizeof(impl::discriminate<Ts...>),
::std::alignment_of<impl::discriminate<Ts...>>::value
>;
template < ::std::size_t N>
using element = typename ::std::tuple_element<N, tuple_type>::type;
template < ::std::size_t N>
using index = ::std::integral_constant< ::std::size_t, N>;
struct copier final {
using data_type = ::std::reference_wrapper<storage_type>;
data_type data;
template <class T>
void operator ()(T const& value) const {
new (::std::addressof(this->data.get())) T { value };
}
};
struct mover final {
using data_type = ::std::reference_wrapper<storage_type>;
data_type data;
template <class T>
void operator () (T&& value) {
new (::std::addressof(this->data.get())) decay_t<T> { ::std::move(value) };
}
};
struct destroyer final {
template <class T> void operator ()(T const& value) const { value.~T(); }
};
struct swapper final {
using data_type = ::std::reference_wrapper<storage_type>;
data_type data;
template <class T>
void operator ()(T&& value) noexcept(is_nothrow_swappable<T>::value) {
using ::std::swap;
swap(reinterpret_cast<decay_t<T>&>(this->data.get()), value);
}
};
struct equality final {
using data_type = ::std::reference_wrapper<storage_type const>;
data_type data;
template <class T>
bool operator ()(T const& value) {
return ::std::equal_to<T> { }(
reinterpret_cast<T const&>(this->data.get()),
value
);
}
};
struct less_than final {
using data_type = ::std::reference_wrapper<storage_type const>;
data_type data;
template <class T>
bool operator ()(T const& value) noexcept {
return ::std::less<T> { }(
reinterpret_cast<T const&>(this->data.get()),
value
);
}
};
struct type_info final {
template <class T>
::std::type_info const* operator ()(T&&) const noexcept {
return ::std::addressof(typeid(decay_t<T>));
}
};
template <
::std::size_t N,
class=enable_if_t<N < sizeof...(Ts)>,
class T
> explicit variant (index<N>&&, ::std::false_type&&, T&& value) :
variant {
index<N + 1> { },
::std::is_constructible<type_at_t<N + 1, Ts...>, T> { },
::core::forward<T>(value)
}
{ }
template <
::std::size_t N,
class=enable_if_t<N < sizeof...(Ts)>,
class T
> explicit variant (index<N>&&, ::std::true_type&&, T&& value) :
data { }, tag { N }
{
new (::std::addressof(this->data)) type_at_t<N, Ts...> (
::core::forward<T>(value)
);
}
public:
template <
class T,
class=enable_if_t<not ::std::is_same<decay_t<T>, variant>::value>
> variant (T&& value) :
variant {
index<0> { },
::std::is_constructible<type_at_t<0, Ts...>, T> { },
::core::forward<T>(value)
}
{ }
variant (variant const& that) :
data { }, tag { that.tag }
{ that.visit(copier { ::std::ref(this->data) }); }
variant (variant&& that) noexcept :
data { }, tag { that.tag }
{ that.visit(mover { ::std::ref(this->data) }); }
template <
class=enable_if_t<
::std::is_default_constructible<type_at_t<0, Ts...>>::value
>
> variant () : variant { type_at_t<0, Ts...> { } } { }
~variant () { this->visit(destroyer { }); }
template <
class T,
class=enable_if_t<not ::std::is_same<decay_t<T>, variant>::value>
> variant& operator = (T&& value) {
variant { ::core::forward<T>(value) }.swap(*this);
return *this;
}
variant& operator = (variant const& that) {
variant { that }.swap(*this);
return *this;
}
variant& operator = (variant&& that) noexcept {
this->visit(destroyer { });
this->tag = that.tag;
that.visit(mover { ::std::ref(this->data) });
return *this;
}
/* Placing these inside of the variant results in no implicit conversions
* occuring
*/
bool operator == (variant const& that) const noexcept {
if (this->tag != that.tag) { return false; }
return that.visit(equality { ::std::cref(this->data) });
}
bool operator < (variant const& that) const noexcept {
if (this->tag != that.tag) { return this->tag < that.tag; }
return that.visit(less_than { ::std::cref(this->data) });
}
void swap (variant& that) noexcept(
all_traits<is_nothrow_swappable<Ts>...>::value
) {
if (this->which() == that.which()) {
that.visit(swapper { ::std::ref(this->data) });
return;
}
variant temp { ::core::move(*this) };
*this = ::core::move(that);
that = ::core::move(temp);
}
template <class Visitor, class... Args>
auto visit (Visitor&& visitor, Args&&... args) -> common_type_t<
invoke_of_t<Visitor, Ts, Args...>...
> {
using return_type = common_type_t<invoke_of_t<Visitor, Ts, Args...>...>;
using function = return_type(*)(Visitor&&, storage_type&, Args&&...);
constexpr ::std::size_t size = ::std::tuple_size<tuple_type>::value;
static function const callers[size] {
impl::visitor_gen<Visitor, Ts, storage_type, function, Args...>()...
};
return callers[this->tag](
::std::forward<Visitor>(visitor),
this->data,
::std::forward<Args>(args)...
);
}
template <class Visitor, class... Args>
auto visit (Visitor&& visitor, Args&&... args) const -> common_type_t<
invoke_of_t<Visitor, Ts, Args...>...
> {
using return_type = common_type_t<invoke_of_t<Visitor, Ts, Args...>...>;
using function = return_type(*)(Visitor&&, storage_type const&, Args&&...);
constexpr ::std::size_t size = ::std::tuple_size<tuple_type>::value;
static function const callers[size] = {
impl::visitor_gen<
Visitor,
Ts const,
storage_type const,
function,
Args...
>()...
};
return callers[this->tag](
::core::forward<Visitor>(visitor),
this->data,
::core::forward<Args>(args)...
);
}
template <class... Visitors>
auto match (Visitors&&... visitors) -> decltype(
this->visit(impl::make_overload(::core::forward<Visitors>(visitors)...))
) {
return this->visit(
impl::make_overload(::core::forward<Visitors>(visitors)...)
);
}
template <class... Visitors>
auto match (Visitors&&... visitors) const -> decltype(
this->visit(impl::make_overload(::core::forward<Visitors>(visitors)...))
) {
return this->visit(
impl::make_overload(::core::forward<Visitors>(visitors)...)
);
}
template < ::std::size_t N>
auto get () const& noexcept(false) -> element<N> const& {
if (this->tag != N) { throw bad_variant_get { "incorrect type" }; }
return reinterpret_cast<element<N> const&>(this->data);
}
template < ::std::size_t N>
auto get () && noexcept(false) -> element<N>&& {
if (this->tag != N) { throw bad_variant_get { "incorrect type" }; }
return ::std::move(reinterpret_cast<element<N>&>(this->data));
}
template < ::std::size_t N>
auto get () & noexcept(false) -> element<N>& {
if (this->tag != N) { throw bad_variant_get { "incorrect type" }; }
return reinterpret_cast<element<N>&>(this->data);
}
::std::type_info const& type () const noexcept {
return *this->visit(type_info { });
}
::std::uint32_t which () const noexcept { return this->tag; }
bool empty () const noexcept { return false; }
private:
storage_type data;
::std::uint8_t tag;
};
template <class... Ts>
void swap (variant<Ts...>& lhs, variant<Ts...>& rhs) noexcept(
noexcept(lhs.swap(rhs))
) { lhs.swap(rhs); }
}} /* namespace core::v1 */
namespace std {
template <class... Ts>
struct hash<core::v1::variant<Ts...>> {
using argument_type = core::v1::variant<Ts...>;
using result_type = size_t;
result_type operator () (argument_type const& value) const {
return value.match(hash<Ts> { }...);
};
};
template <size_t I, class... Ts>
auto get (core::v1::variant<Ts...> const& variant) noexcept(false) -> decltype(
variant.template get<I>()
) { return variant.template get<I>(); }
template <size_t I, class... Ts>
auto get (core::v1::variant<Ts...>&& variant) noexcept(false) -> decltype(
variant.template get<I>()
) { return variant.template get<I>(); }
template <size_t I, class... Ts>
auto get (core::v1::variant<Ts...>& variant) noexcept (false) -> decltype(
variant.template get<I>()
) { return variant.template get<I>(); }
} /* namespace std */
#endif /* CORE_VARIANT_HPP */

View File

@@ -0,0 +1,70 @@
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
# but only if the requested major version is the same as the current one.
# The variable CVF_VERSION must be set before calling configure_file().
set(PACKAGE_VERSION "1.1.0")
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
if("1.1.0" MATCHES "^([0-9]+)\\.")
set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
endif()
else()
set(CVF_VERSION_MAJOR "1.1.0")
endif()
if(PACKAGE_FIND_VERSION_RANGE)
# both endpoints of the range must have the expected major version
math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1")
if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR)
OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT)))
set(PACKAGE_VERSION_COMPATIBLE FALSE)
elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX)
OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX)))
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
else()
if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
endif()
# if the installed project requested no architecture check, don't perform the check
if("FALSE")
return()
endif()
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "8" STREQUAL "")
return()
endif()
# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "8")
math(EXPR installedBits "8 * 8")
set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

View File

@@ -0,0 +1,32 @@
set(CORE_VERSION 1.1.0)
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was core-config.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
set_and_check(CORE_INCLUDE_DIR "${PACKAGE_PREFIX_DIR}/.")
set_and_check(CORE_CMAKE_DIR "${PACKAGE_PREFIX_DIR}/share/cmake/core")
check_required_components(core)

View File

@@ -0,0 +1,697 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
#include <chrono>
#include <cstring>
#include <bsoncxx/array/view.hpp>
#include <bsoncxx/decimal128.hpp>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/oid.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
///
/// An enumeration of each BSON type.
/// These x-macros will expand to be of the form:
/// k_double = 0x01,
/// k_string = 0x02,
/// k_document = 0x03,
/// k_array = 0x04 ...
///
enum class type : std::uint8_t {
#define BSONCXX_ENUM(name, val) k_##name = val,
#include <bsoncxx/enums/type.hpp>
#undef BSONCXX_ENUM
k_utf8 = 0x02,
};
///
/// An enumeration of each BSON binary sub type.
/// These x-macros will expand to be of the form:
/// k_binary = 0x00,
/// k_function = 0x01,
/// k_binary_deprecated = 0x02,
/// k_uuid_deprecated = 0x03,
/// k_uuid = 0x04,
/// k_md5 = 0x05,
/// k_encrypted = 0x06,
/// k_column = 0x07,
/// k_user = 0x80
///
enum class binary_sub_type : std::uint8_t {
#define BSONCXX_ENUM(name, val) k_##name = val,
#include <bsoncxx/enums/binary_sub_type.hpp>
#undef BSONCXX_ENUM
};
///
/// Returns a stringification of the given type.
///
/// @param rhs
/// The type to stringify.
///
/// @return a std::string representation of the type.
///
BSONCXX_API std::string BSONCXX_CALL to_string(type rhs);
///
/// Returns a stringification of the given binary sub type.
///
/// @param rhs
/// The type to stringify.
///
/// @return a std::string representation of the type.
///
BSONCXX_API std::string BSONCXX_CALL to_string(binary_sub_type rhs);
namespace types {
///
/// A BSON double value.
///
struct BSONCXX_API b_double {
static constexpr auto type_id = type::k_double;
double value;
///
/// Conversion operator unwrapping a double
///
BSONCXX_INLINE operator double() const {
return value;
}
};
///
/// free function comparator for b_double
///
/// @relatesalso b_double
///
BSONCXX_INLINE bool operator==(const b_double& lhs, const b_double& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON UTF-8 encoded string value.
///
struct BSONCXX_API b_string {
static constexpr auto type_id = type::k_string;
///
/// Constructor for b_string.
///
/// @param t
/// The value to wrap.
///
template <typename T,
typename std::enable_if<!std::is_same<b_string, typename std::decay<T>::type>::value,
int>::type = 0>
BSONCXX_INLINE explicit b_string(T&& t) : value(std::forward<T>(t)) {}
stdx::string_view value;
///
/// Conversion operator unwrapping a string_view
///
BSONCXX_INLINE operator stdx::string_view() const {
return value;
}
};
///
/// free function comparator for b_string
///
/// @relatesalso b_string
///
BSONCXX_INLINE bool operator==(const b_string& lhs, const b_string& rhs) {
return lhs.value == rhs.value;
}
///
/// This class has been renamed to b_string
///
/// @deprecated use b_string instead.
///
BSONCXX_DEPRECATED typedef b_string b_utf8;
///
/// A BSON document value.
///
struct BSONCXX_API b_document {
static constexpr auto type_id = type::k_document;
document::view value;
///
/// Conversion operator unwrapping a document::view
///
BSONCXX_INLINE operator document::view() const {
return value;
}
///
/// Returns an unwrapped document::view
///
BSONCXX_INLINE document::view view() {
return value;
}
};
///
/// free function comparator for b_document
///
/// @relatesalso b_document
///
BSONCXX_INLINE bool operator==(const b_document& lhs, const b_document& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON array value.
///
struct BSONCXX_API b_array {
static constexpr auto type_id = type::k_array;
array::view value;
///
/// Conversion operator unwrapping an array::view
///
BSONCXX_INLINE operator array::view() const {
return value;
}
};
///
/// free function comparator for b_array
///
/// @relatesalso b_array
///
BSONCXX_INLINE bool operator==(const b_array& lhs, const b_array& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON binary data value.
///
struct BSONCXX_API b_binary {
static constexpr auto type_id = type::k_binary;
binary_sub_type sub_type;
uint32_t size;
const uint8_t* bytes;
};
///
/// free function comparator for b_binary
///
/// @relatesalso b_binary
///
BSONCXX_INLINE bool operator==(const b_binary& lhs, const b_binary& rhs) {
return lhs.sub_type == rhs.sub_type && lhs.size == rhs.size &&
(!lhs.size || (std::memcmp(lhs.bytes, rhs.bytes, lhs.size) == 0));
}
///
/// A BSON undefined value.
///
/// @deprecated
/// This BSON type is deprecated and use by clients is discouraged.
///
struct BSONCXX_API b_undefined {
static constexpr auto type_id = type::k_undefined;
};
///
/// free function comparator for b_undefined
///
/// @relatesalso b_undefined
///
BSONCXX_INLINE bool operator==(const b_undefined&, const b_undefined&) {
return true;
}
///
/// A BSON ObjectId value.
///
struct BSONCXX_API b_oid {
static constexpr auto type_id = type::k_oid;
oid value;
};
///
/// free function comparator for b_oid
///
/// @relatesalso b_oid
///
BSONCXX_INLINE bool operator==(const b_oid& lhs, const b_oid& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON boolean value.
///
struct BSONCXX_API b_bool {
static constexpr auto type_id = type::k_bool;
bool value;
///
/// Conversion operator unwrapping a bool
///
BSONCXX_INLINE operator bool() const {
return value;
}
};
///
/// free function comparator for b_bool
///
/// @relatesalso b_bool
///
BSONCXX_INLINE bool operator==(const b_bool& lhs, const b_bool& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON date value.
///
struct BSONCXX_API b_date {
static constexpr auto type_id = type::k_date;
///
/// Constructor for b_date
///
/// @param value
/// Milliseconds since the system_clock epoch.
///
BSONCXX_INLINE
explicit b_date(std::chrono::milliseconds value) : value(value) {}
///
/// Constructor for b_date
///
/// @param tp
/// A system_clock time_point.
///
BSONCXX_INLINE
explicit b_date(const std::chrono::system_clock::time_point& tp)
: value(std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch())) {}
std::chrono::milliseconds value;
///
/// Conversion operator unwrapping a int64_t
///
BSONCXX_INLINE operator int64_t() const {
return value.count();
}
///
/// Manually convert this b_date to an int64_t
///
BSONCXX_INLINE int64_t to_int64() const {
return value.count();
}
///
/// Conversion operator unwrapping a time_point
///
BSONCXX_INLINE operator std::chrono::system_clock::time_point() const {
return std::chrono::system_clock::time_point(
std::chrono::duration_cast<std::chrono::system_clock::duration>(value));
}
};
///
/// free function comparator for b_date
///
/// @relatesalso b_date
///
BSONCXX_INLINE bool operator==(const b_date& lhs, const b_date& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON null value.
///
struct BSONCXX_API b_null {
static constexpr auto type_id = type::k_null;
};
///
/// free function comparator for b_null
///
/// @relatesalso b_null
///
BSONCXX_INLINE bool operator==(const b_null&, const b_null&) {
return true;
}
///
/// A BSON regex value.
///
struct BSONCXX_API b_regex {
static constexpr auto type_id = type::k_regex;
///
/// Constructor for b_regex
///
/// @param regex
/// The regex pattern
///
/// @param options
/// The regex options
///
template <typename T,
typename U = stdx::string_view,
typename std::enable_if<!std::is_same<b_regex, typename std::decay<T>::type>::value,
int>::type = 0>
BSONCXX_INLINE explicit b_regex(T&& regex, U&& options = U{})
: regex(std::forward<T>(regex)), options(std::forward<U>(options)) {}
stdx::string_view regex;
stdx::string_view options;
};
///
/// free function comparator for b_regex
///
/// @relatesalso b_regex
///
BSONCXX_INLINE bool operator==(const b_regex& lhs, const b_regex& rhs) {
return lhs.regex == rhs.regex && lhs.options == rhs.options;
}
///
/// A BSON DBPointer value.
///
/// @deprecated
/// A BSON DBPointer (aka DBRef) is still supported but deprecated.
///
struct BSONCXX_API b_dbpointer {
static constexpr auto type_id = type::k_dbpointer;
stdx::string_view collection;
oid value;
};
///
/// free function comparator for b_dbpointer
///
/// @relatesalso b_dbpointer
///
BSONCXX_INLINE bool operator==(const b_dbpointer& lhs, const b_dbpointer& rhs) {
return lhs.collection == rhs.collection && lhs.value == rhs.value;
}
///
/// A BSON JavaScript code value.
///
struct BSONCXX_API b_code {
static constexpr auto type_id = type::k_code;
///
/// Constructor for b_code.
///
/// @param t
/// The js code
///
template <typename T,
typename std::enable_if<!std::is_same<b_code, typename std::decay<T>::type>::value,
int>::type = 0>
BSONCXX_INLINE explicit b_code(T&& t) : code(std::forward<T>(t)) {}
stdx::string_view code;
///
/// Conversion operator unwrapping a string_view
///
BSONCXX_INLINE operator stdx::string_view() const {
return code;
}
};
///
/// free function comparator for b_code
///
/// @relatesalso b_code
///
BSONCXX_INLINE bool operator==(const b_code& lhs, const b_code& rhs) {
return lhs.code == rhs.code;
}
///
/// A BSON Symbol value.
///
/// @deprecated
/// This BSON type is deprecated and use by clients is discouraged.
///
struct BSONCXX_API b_symbol {
static constexpr auto type_id = type::k_symbol;
///
/// Constructor for b_symbol.
///
/// @param t
/// The symbol.
///
template <typename T,
typename std::enable_if<!std::is_same<b_symbol, typename std::decay<T>::type>::value,
int>::type = 0>
BSONCXX_INLINE explicit b_symbol(T&& t) : symbol(std::forward<T>(t)) {}
stdx::string_view symbol;
///
/// Conversion operator unwrapping a string_view
///
BSONCXX_INLINE operator stdx::string_view() const {
return symbol;
}
};
///
/// free function comparator for b_symbol
///
/// @relatesalso b_symbol
///
BSONCXX_INLINE bool operator==(const b_symbol& lhs, const b_symbol& rhs) {
return lhs.symbol == rhs.symbol;
}
///
/// A BSON JavaScript code with scope value.
///
struct BSONCXX_API b_codewscope {
static constexpr auto type_id = type::k_codewscope;
///
/// Constructor for b_codewscope.
///
/// @param code
/// The js code
///
/// @param scope
/// A bson document view holding the scope environment.
///
template <
typename T,
typename U,
typename std::enable_if<!std::is_same<b_codewscope, typename std::decay<T>::type>::value,
int>::type = 0>
BSONCXX_INLINE explicit b_codewscope(T&& code, U&& scope)
: code(std::forward<T>(code)), scope(std::forward<U>(scope)) {}
stdx::string_view code;
document::view scope;
};
///
/// free function comparator for b_codewscope
///
/// @relatesalso b_codewscope
///
BSONCXX_INLINE bool operator==(const b_codewscope& lhs, const b_codewscope& rhs) {
return lhs.code == rhs.code && lhs.scope == rhs.scope;
}
///
/// A BSON signed 32-bit integer value.
///
struct BSONCXX_API b_int32 {
static constexpr auto type_id = type::k_int32;
int32_t value;
///
/// Conversion operator unwrapping a int32_t
///
BSONCXX_INLINE operator int32_t() const {
return value;
}
};
///
/// free function comparator for b_int32
///
/// @relatesalso b_int32
///
BSONCXX_INLINE bool operator==(const b_int32& lhs, const b_int32& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON replication timestamp value.
///
/// @warning
/// This BSON type is used internally by the MongoDB server - use by clients
/// is discouraged.
///
struct BSONCXX_API b_timestamp {
static constexpr auto type_id = type::k_timestamp;
uint32_t increment;
uint32_t timestamp;
};
///
/// free function comparator for b_timestamp
///
/// @relatesalso b_timestamp
///
BSONCXX_INLINE bool operator==(const b_timestamp& lhs, const b_timestamp& rhs) {
return lhs.increment == rhs.increment && lhs.timestamp == rhs.timestamp;
}
///
/// A BSON 64-bit signed integer value.
///
struct BSONCXX_API b_int64 {
static constexpr auto type_id = type::k_int64;
int64_t value;
///
/// Conversion operator unwrapping a int64_t
///
BSONCXX_INLINE operator int64_t() const {
return value;
}
};
///
/// free function comparator for b_int64
///
/// @relatesalso b_int64
///
BSONCXX_INLINE bool operator==(const b_int64& lhs, const b_int64& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON Decimal128 value.
///
struct BSONCXX_API b_decimal128 {
static constexpr auto type_id = type::k_decimal128;
decimal128 value;
///
/// Constructor for b_decimal128.
///
/// @param t
/// The value to wrap.
///
template <
typename T,
typename std::enable_if<!std::is_same<b_decimal128, typename std::decay<T>::type>::value,
int>::type = 0>
BSONCXX_INLINE explicit b_decimal128(T&& t) : value(std::forward<T>(t)) {}
};
///
/// free function comparator for b_decimal128
///
/// @relatesalso b_decimal128
///
BSONCXX_INLINE bool operator==(const b_decimal128& lhs, const b_decimal128& rhs) {
return lhs.value == rhs.value;
}
///
/// A BSON min-key value.
///
struct BSONCXX_API b_minkey {
static constexpr auto type_id = type::k_minkey;
};
///
/// free function comparator for b_minkey
///
/// @relatesalso b_minkey
///
BSONCXX_INLINE bool operator==(const b_minkey&, const b_minkey&) {
return true;
}
///
/// A BSON max-key value.
///
struct BSONCXX_API b_maxkey {
static constexpr auto type_id = type::k_maxkey;
};
///
/// free function comparator for b_maxkey
///
/// @relatesalso b_maxkey
///
BSONCXX_INLINE bool operator==(const b_maxkey&, const b_maxkey&) {
return true;
}
#define BSONCXX_ENUM(name, val) \
BSONCXX_INLINE bool operator!=(const b_##name& lhs, const b_##name& rhs) { \
return !(lhs == rhs); \
}
#include <bsoncxx/enums/type.hpp>
#undef BSONCXX_ENUM
} // namespace types
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

View File

@@ -0,0 +1,43 @@
// Copyright 2020 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/types/bson_value/value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace types {
namespace bson_value {
///
/// Helper to construct a bson_value::value from a component bson type. The type
/// of the passed-in t can be anything that builder::basic::sub_document::append accepts.
///
template <typename T>
BSONCXX_INLINE bson_value::value make_value(T&& t) {
auto doc = builder::basic::make_document(builder::basic::kvp("v", std::forward<T>(t)));
return doc.view()["v"].get_owning_value();
}
} // namespace bson_value
} // namespace types
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,327 @@
// Copyright 2020 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <iostream>
#include <memory>
#include <vector>
#include <bsoncxx/array/view_or_value.hpp>
#include <bsoncxx/document/view_or_value.hpp>
#include <bsoncxx/stdx/make_unique.hpp>
#include <bsoncxx/types/bson_value/view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace types {
namespace bson_value {
///
/// A variant owning type that represents any BSON type. Owns its underlying
/// buffer. When a bson_value::value goes out of scope, its underlying
/// buffer is freed.
///
/// For accessors into this type and to extract the various BSON types out,
/// please use bson_value::view.
///
/// @relatesalso bson_value::view
///
class BSONCXX_API value {
public:
///
/// Constructor for each BSON type.
///
/// These x-macros will expand to:
/// value(b_double v);
/// value(b_string v);
/// value(b_document v);
/// value(b_array v); ...
///
#define BSONCXX_ENUM(name, val) value(b_##name v);
#include <bsoncxx/enums/type.hpp>
#undef BSONCXX_ENUM
///
/// Constructs a BSON UTF-8 string value.
///
value(const char* v);
///
/// Constructs a BSON UTF-8 string value.
///
value(std::string v);
///
/// Constructs a BSON UTF-8 string value.
///
value(stdx::string_view v);
///
/// Constructs a BSON 32-bit signed integer value.
///
value(int32_t v);
///
/// Constructs a BSON 64-bit signed integer value.
///
value(int64_t v);
///
/// Constructs a BSON double value.
///
value(double v);
///
/// Constructs a BSON boolean value.
///
value(bool v);
///
/// Constructs a BSON ObjectId value.
///
value(oid v);
///
/// Constructs a BSON Decimal128 value.
///
value(decimal128 v);
///
/// Constructs a BSON date value.
///
value(std::chrono::milliseconds v);
///
/// Constructs a BSON null value.
///
value(std::nullptr_t);
///
/// Constructs a BSON document value.
///
value(bsoncxx::document::view v);
///
/// Constructs a BSON array value.
///
value(bsoncxx::array::view v);
///
/// Constructs a BSON binary data value.
///
/// @param v
/// a stream of bytes
/// @param sub_type
/// an optional binary sub type. Defaults to type::k_binary
///
value(std::vector<unsigned char> v, const binary_sub_type sub_type = {});
///
/// Constructs a BSON binary data value.
///
/// @param data
/// pointer to a stream of bytes
/// @param size
/// the size of the stream of bytes
/// @param sub_type
/// an optional binary sub type. Defaults to type::k_binary
///
value(const uint8_t* data, size_t size, const binary_sub_type sub_type = {});
///
/// Constructs a BSON DBPointer value.
///
/// @param collection
/// the collection name
/// @param value
/// the object id
///
/// @deprecated
/// A BSON DBPointer (aka DBRef) is still supported but deprecated.
///
value(stdx::string_view collection, oid value);
///
/// Constructs a BSON JavaScript code with scope value.
///
/// @param code
/// the JavaScript code
/// @param scope
/// a bson document view holding the scope environment
///
value(stdx::string_view code, bsoncxx::document::view_or_value scope);
///
/// Constructs a BSON regex value with options.
///
/// @param regex
/// The regex pattern
/// @param options
/// The regex options
///
value(stdx::string_view regex, stdx::string_view options);
///
/// Constructs one of the following BSON values (each specified by the parenthesized type):
/// - BSON code value (type::k_code)
/// - BSON regex value (type::k_regex)
/// - BSON symbol value (type::k_symbol)
///
/// @param id
/// the type of BSON value to construct.
/// @param v
/// the symbol, JavaScript code, or regex pattern for the BSON symbol, code, or regex value
/// respectively.
///
/// @throws bsoncxx::exception if the type's value is not k_code, k_regex, or k_symbol.
///
/// @deprecated
/// The BSON symbol type is deprecated and use by clients is discouraged.
/// @deprecated
/// The BSON undefined type is deprecated and use by clients is discouraged.
///
value(const type id, stdx::string_view v);
///
/// Constructs one of the following BSON values (each specified by the parenthesized type):
/// - BSON maxkey value (type::k_maxkey)
/// - BSON minkey value (type::k_minkey)
/// - BSON undefined value (type::k_undefined)
///
/// @param id
/// the type of BSON value to construct.
///
/// @throws bsoncxx::exception if the type's value is not k_maxkey, k_minkey, or k_undefined.
///
value(const type id);
///
/// Constructs one of the following BSON values (each specified by the parenthesized type):
/// - BSON decimal128 value (type::k_decimal128)
/// - BSON timestamp value (type::k_timestamp)
///
/// @param id
/// the type of the BSON value to construct.
/// @param a
/// If a BSON decimal128 value is to be constructed, this is the high value.
/// If a BSON timestamp value is to be constructed, this is the increment.
/// @param b
/// If a BSON decimal128 value is to be constructed, this is the low value.
/// If a BSON timestamp value is to be constructed, this is the timestamp.
///
/// @throws bsoncxx::exception if the specified type is missing its required arguments.
///
/// @warning
/// The BSON timestamp type is used internally by the MongoDB server - use by clients
/// is discouraged.
///
value(const type id, uint64_t a, uint64_t b);
~value();
value(const value&);
value& operator=(const value&);
value(value&&) noexcept;
value& operator=(value&&) noexcept;
///
/// Create an owning copy of a bson_value::view.
///
explicit value(const view&);
///
/// Get a view over the bson_value owned by this object.
///
bson_value::view view() const noexcept;
///
/// Conversion operator that provides a bson_value::view given a bson_value::value.
///
operator bson_value::view() const noexcept;
private:
friend class bsoncxx::document::element;
value(const std::uint8_t* raw,
std::uint32_t length,
std::uint32_t offset,
std::uint32_t keylen);
// Makes a copy of 'internal_value' and owns the copy.
value(void* internal_value);
friend value make_owning_bson(void* internal_value);
class BSONCXX_PRIVATE impl;
std::unique_ptr<impl> _impl;
};
///
/// @{
///
/// Compares values for (in)-equality.
///
/// @relates bson_value::value
///
BSONCXX_INLINE bool operator==(const value& lhs, const value& rhs) {
return (lhs.view() == rhs.view());
}
BSONCXX_INLINE bool operator!=(const value& lhs, const value& rhs) {
return !(lhs == rhs);
}
///
/// @}
///
///
/// @{
///
/// Compares a value with a view for (in)-equality.
///
/// @relates bson_value::value
///
BSONCXX_INLINE bool operator==(const value& lhs, const view& rhs) {
return (lhs.view() == rhs);
}
BSONCXX_INLINE bool operator==(const view& lhs, const value& rhs) {
return (rhs == lhs);
}
BSONCXX_INLINE bool operator!=(const value& lhs, const view& rhs) {
return !(lhs == rhs);
}
BSONCXX_INLINE bool operator!=(const view& lhs, const value& rhs) {
return !(lhs == rhs);
}
///
/// @}
///
} // namespace bson_value
} // namespace types
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,345 @@
// Copyright 2020 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstddef>
#include <cstdint>
#include <type_traits>
#include <bsoncxx/types.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace document {
class element;
} // namespace document
namespace types {
namespace bson_value {
class value;
///
/// A view-only variant that can contain any BSON type.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception
/// to be thrown.
///
class BSONCXX_API view {
public:
///
/// Construct a bson_value::view from any of the various BSON types. Defines
/// constructors of the following form for each type:
///
/// explicit view(type) noexcept;
///
/// Like this:
///
/// explicit view(b_double) noexcept;
/// explicit view(b_string) noexcept;
/// explicit view(b_bool) noexcept;
///
/// etc.
///
#define BSONCXX_ENUM(type, val) explicit view(b_##type) noexcept;
#include <bsoncxx/enums/type.hpp>
#undef BSONCXX_ENUM
///
/// Default constructs a bson_value::view. The resulting view will be initialized
/// to point at a bson_value of type k_null.
///
view() noexcept;
view(const view&) noexcept;
view& operator=(const view&) noexcept;
~view();
///
/// @{
///
/// Compare two bson_value::views for equality
///
/// @relates bson_value::view
///
friend BSONCXX_API bool BSONCXX_CALL operator==(const bson_value::view&,
const bson_value::view&);
friend BSONCXX_API bool BSONCXX_CALL operator!=(const bson_value::view&,
const bson_value::view&);
///
/// @}
///
///
/// @return The type of the underlying BSON value stored in this object.
///
bsoncxx::type type() const;
///
/// @return The underlying BSON double value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_double& get_double() const;
///
/// @return The underlying BSON UTF-8 string value.
///
/// @deprecated use get_string instead.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
BSONCXX_DEPRECATED const b_string& get_utf8() const;
///
/// @return The underlying BSON UTF-8 string value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_string& get_string() const;
///
/// @return The underlying BSON document value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_document& get_document() const;
///
/// @return The underlying BSON array value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_array& get_array() const;
///
/// @return The underlying BSON binary data value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_binary& get_binary() const;
///
/// @return The underlying BSON undefined value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_undefined& get_undefined() const;
///
/// @return The underlying BSON ObjectId value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_oid& get_oid() const;
///
/// @return The underlying BSON boolean value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_bool& get_bool() const;
///
/// @return The underlying BSON date value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_date& get_date() const;
///
/// @return The underlying BSON null value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_null& get_null() const;
///
/// @return The underlying BSON regex value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_regex& get_regex() const;
///
/// @return The underlying BSON DBPointer value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_dbpointer& get_dbpointer() const;
///
/// @return The underlying BSON JavaScript code value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_code& get_code() const;
///
/// @return The underlying BSON symbol value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_symbol& get_symbol() const;
///
/// @return The underlying BSON JavaScript code with scope value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_codewscope& get_codewscope() const;
///
/// @return The underlying BSON 32-bit signed integer value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_int32& get_int32() const;
///
/// @return The underlying BSON replication timestamp value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_timestamp& get_timestamp() const;
///
/// @return The underlying BSON 64-bit signed integer value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_int64& get_int64() const;
///
/// @return The underlying BSON Decimal128 value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_decimal128& get_decimal128() const;
///
/// @return The underlying BSON min-key value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_minkey& get_minkey() const;
///
/// @return The underlying BSON max-key value.
///
/// @warning
/// Calling the wrong get_<type> method will cause an exception to be thrown.
///
const b_maxkey& get_maxkey() const;
private:
friend class document::element;
friend class bson_value::value;
view(const std::uint8_t* raw, std::uint32_t length, std::uint32_t offset, std::uint32_t keylen);
view(void* internal_value) noexcept;
void _init(void* internal_value) noexcept;
void BSONCXX_PRIVATE destroy() noexcept;
bsoncxx::type _type;
union {
struct b_double _b_double;
struct b_string _b_string;
struct b_document _b_document;
struct b_array _b_array;
struct b_binary _b_binary;
struct b_undefined _b_undefined;
struct b_oid _b_oid;
struct b_bool _b_bool;
struct b_date _b_date;
struct b_null _b_null;
struct b_regex _b_regex;
struct b_dbpointer _b_dbpointer;
struct b_code _b_code;
struct b_symbol _b_symbol;
struct b_codewscope _b_codewscope;
struct b_int32 _b_int32;
struct b_timestamp _b_timestamp;
struct b_int64 _b_int64;
struct b_decimal128 _b_decimal128;
struct b_minkey _b_minkey;
struct b_maxkey _b_maxkey;
};
};
// sfinae in the bool return to avoid competing with the value == value
// operators.
template <typename T>
using not_view = typename std::enable_if<
std::is_constructible<bson_value::view, T>::value &&
!std::is_same<typename std::decay<T>::type, bson_value::view>::value &&
!std::is_same<typename std::decay<T>::type, bson_value::value>::value,
bool>::type;
template <typename T>
BSONCXX_INLINE not_view<T> operator==(const bson_value::view& lhs, T&& rhs) {
return lhs == bson_value::view{std::forward<T>(rhs)};
}
template <typename T>
BSONCXX_INLINE not_view<T> operator==(T&& lhs, const bson_value::view& rhs) {
return bson_value::view{std::forward<T>(lhs)} == rhs;
}
template <typename T>
BSONCXX_INLINE not_view<T> operator!=(const bson_value::view& lhs, T&& rhs) {
return lhs != bson_value::view{std::forward<T>(rhs)};
}
template <typename T>
BSONCXX_INLINE not_view<T> operator!=(T&& lhs, const bson_value::view& rhs) {
return bson_value::view{std::forward<T>(lhs)} != rhs;
}
} // namespace bson_value
} // namespace types
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,35 @@
// Copyright 2020 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/types/bson_value/value.hpp>
#include <bsoncxx/types/bson_value/view.hpp>
#include <bsoncxx/view_or_value.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace types {
namespace bson_value {
using view_or_value = bsoncxx::view_or_value<bson_value::view, bson_value::value>;
} // namespace bson_value
} // namespace types
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,39 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/types/bson_value/view.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace types {
///
/// The bsoncxx::types::bson_value::view class has been renamed to
/// bsoncxx::types::bson_value::view.
///
/// @deprecated use bsoncxx::types::bson_value::view instead.
///
BSONCXX_DEPRECATED typedef types::bson_value::view value;
} // namespace types
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,114 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <functional>
#include <type_traits>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
namespace util {
// TODO(MSVC): VS2015U1 Completely falls apart trying to honor the
// simple definition of is_functor since is_convertible returns the
// wrong results for std::function, so we fall back to a bunch of
// other template metaprogramming there.
#if !defined(_MSC_VER)
template <typename FunctionLike, typename Signature>
using is_functor = std::is_convertible<FunctionLike, std::function<Signature>>;
#else
namespace functor {
template <typename, typename>
struct build_free_function;
template <typename F, typename R, typename... Args>
struct build_free_function<F, R(Args...)> {
typedef R (*type)(Args...);
};
template <typename, typename>
struct build_class_function;
template <typename C, typename R, typename... Args>
struct build_class_function<C, R(Args...)> {
typedef R (C::*type)(Args...);
};
template <typename>
struct strip_cv_from_class_function;
template <typename C, typename R, typename... Args>
struct strip_cv_from_class_function<R (C::*)(Args...)> {
typedef R (C::*type)(Args...);
};
template <typename C, typename R, typename... Args>
struct strip_cv_from_class_function<R (C::*)(Args...) const> {
typedef R (C::*type)(Args...);
};
template <typename C, typename R, typename... Args>
struct strip_cv_from_class_function<R (C::*)(Args...) volatile> {
typedef R (C::*type)(Args...);
};
template <typename C, typename S>
struct is_class_method_with_signature {
typedef int yes;
typedef char no;
// T stands for SFINAE
template <typename T>
static typename std::enable_if<std::is_convertible<typename build_class_function<C, S>::type,
typename strip_cv_from_class_function<
decltype(&T::operator())>::type>::value,
yes>::type
sfinae(void*);
template <typename>
static no sfinae(...);
static bool constexpr value = sizeof(sfinae<C>(nullptr)) == sizeof(yes);
};
template <typename F, typename S>
struct is_function_with_signature
: std::is_convertible<F, typename build_free_function<F, S>::type> {};
template <typename C, typename S, bool>
struct is_functor_impl : is_class_method_with_signature<C, S> {};
template <typename F, typename S>
struct is_functor_impl<F, S, false> : is_function_with_signature<F, S> {};
} // namespace functor
template <typename C, typename S>
struct is_functor : functor::is_functor_impl<C, S, std::is_class<C>::value> {};
#endif
} // namespace util
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,162 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <cstdint>
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
class validator;
///
/// Validates a BSON document. This is a simplified overload that will
/// only do the bare minimum validation of document structure, and does
/// not provide any further information if the document is found to be invalid.
///
/// @param data
/// A buffer containing a BSON document to validate.
/// @param length
/// The size of the buffer.
///
/// @returns
/// An engaged optional containing a view if the document is valid, or
/// an unengaged optional if the document is invalid.
///
BSONCXX_API stdx::optional<document::view> BSONCXX_CALL validate(const std::uint8_t* data,
std::size_t length);
///
/// Validates a BSON document. This overload provides additional control over the
/// precise validation that is performed, and will give the caller access to the
/// offset at which the document was found to be invalid.
///
/// @param data
/// A buffer containing a BSON document to validate.
/// @param length
/// The size of the buffer.
/// @param validator
/// A validator used to configure what checks are done. If validation fails, it
/// will contain the offset at which the document was found to be invalid.
/// @param invalid_offset
/// If validation fails, the offset at which the document was found to be invalid
/// will be stored here (if non-null).
///
/// @returns
/// An engaged optional containing a view if the document is valid, or
/// an unengaged optional if the document is invalid.
///
BSONCXX_API stdx::optional<document::view> BSONCXX_CALL
validate(const std::uint8_t* data,
std::size_t length,
const validator& validator,
std::size_t* invalid_offset = nullptr);
///
/// A validator is used to enable or disable specific checks that can be
/// performed during BSON validation.
///
class BSONCXX_API validator {
public:
///
/// Constructs a validator.
///
validator();
///
/// Destructs a validator.
///
~validator();
///
/// Verify that all keys and string values are valid UTF-8.
///
/// @param check_utf8
/// If true, UTF-8 validation is performed.
///
void check_utf8(bool check_utf8);
///
/// Getter for the current check_utf8 value of the underlying validator.
///
/// @return True if UTF-8 validation is performed.
///
bool check_utf8() const;
///
/// Verify that all keys and string values are valid UTF-8, but allow
/// null bytes. This is generally bad practice, but some languages such
/// as Python, can sennd UTF-8 encoded strings with null bytes.
///
/// @param check_utf8_allow_null
/// If true, UTF-8 validation (with null bytes allowed) is performed.
///
void check_utf8_allow_null(bool check_utf8_allow_null);
///
/// Getter for the current check_utf8_allow_null value of the underlying
/// validator.
///
/// @return True if UTF-8 validation (with null bytes allowed) is
/// performed.
///
bool check_utf8_allow_null() const;
///
/// Verifies that document keys are not preceeded with '$'.
///
/// @param check_dollar_keys
/// If true, keys starting with '$' will be treated as invalid.
///
void check_dollar_keys(bool check_dollar_keys);
///
/// Getter for the current check_dollar_keys value of the underlying
/// validator.
///
/// @return True if keys starting with '$' will be treated as invalid.
///
bool check_dollar_keys() const;
///
/// Verifies that document keys do not contain any '.' characters.
///
/// @param check_dot_keys
/// If true, keys containing '.' will be treated as invalid.
///
void check_dot_keys(bool check_dot_keys);
///
/// Getter for the current check_dot_keys value of the underlying
/// validator.
///
/// @return True if keys containing '.' will be treated as invalid.
///
bool check_dot_keys() const;
private:
struct BSONCXX_PRIVATE impl;
std::unique_ptr<impl> _impl;
};
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

View File

@@ -0,0 +1,215 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <type_traits>
#include <bsoncxx/stdx/optional.hpp>
#include <bsoncxx/config/prelude.hpp>
namespace bsoncxx {
BSONCXX_INLINE_NAMESPACE_BEGIN
///
/// Class representing a view-or-value variant type.
///
template <typename View, typename Value>
class view_or_value {
public:
using view_type = View;
using value_type = Value;
///
/// Class View must be constructible from an instance of class Value.
///
static_assert(std::is_constructible<View, Value>::value,
"View type must be constructible from a Value");
///
/// Class View must be default constructible.
///
static_assert(std::is_default_constructible<View>::value,
"View type must be default constructible");
///
/// Default-constructs a view_or_value. This is equivalent to constructing a
/// view_or_value with a default-constructed View.
///
BSONCXX_INLINE view_or_value() = default;
///
/// Construct a view_or_value from a View. When constructed with a View,
/// this object is non-owning. The Value underneath the given View must outlive this object.
///
/// @param view
/// A non-owning View.
///
BSONCXX_INLINE view_or_value(View view) : _view{view} {}
///
/// Constructs a view_or_value from a Value type. This object owns the passed-in Value.
///
/// @param value
/// A Value type.
///
BSONCXX_INLINE view_or_value(Value&& value) : _value(std::move(value)), _view(*_value) {}
///
/// Construct a view_or_value from a copied view_or_value.
///
BSONCXX_INLINE view_or_value(const view_or_value& other)
: _value(other._value), _view(_value ? *_value : other._view) {}
///
/// Assign to this view_or_value from a copied view_or_value.
///
BSONCXX_INLINE view_or_value& operator=(const view_or_value& other) {
_value = other._value;
_view = _value ? *_value : other._view;
return *this;
}
///
/// Construct a view_or_value from a moved-in view_or_value.
///
/// TODO CXX-800: Create a noexcept expression to check the conditions that must be met.
BSONCXX_INLINE view_or_value(view_or_value&& other) noexcept
: _value{std::move(other._value)}, _view(_value ? *_value : std::move(other._view)) {
other._view = View();
other._value = stdx::nullopt;
}
///
/// Assign to this view_or_value from a moved-in view_or_value.
///
/// TODO CXX-800: Create a noexcept expression to check the conditions that must be met.
BSONCXX_INLINE view_or_value& operator=(view_or_value&& other) noexcept {
_value = std::move(other._value);
_view = _value ? *_value : std::move(other._view);
other._view = View();
other._value = stdx::nullopt;
return *this;
}
///
/// Return whether or not this view_or_value owns an underlying Value.
///
/// @return bool Whether we are owning.
///
BSONCXX_INLINE bool is_owning() const noexcept {
return static_cast<bool>(_value);
}
///
/// This type may be used as a View.
///
/// @return a View into this view_or_value.
///
BSONCXX_INLINE operator View() const {
return _view;
}
///
/// Get a View for the type.
///
/// @return a View into this view_or_value.
///
BSONCXX_INLINE const View& view() const {
return _view;
}
private:
stdx::optional<Value> _value;
View _view;
};
///
/// @{
///
/// Compare view_or_value objects for (in)-equality
///
/// @relates: view_or_value
///
template <typename View, typename Value>
BSONCXX_INLINE bool operator==(const view_or_value<View, Value>& lhs,
const view_or_value<View, Value>& rhs) {
return lhs.view() == rhs.view();
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(const view_or_value<View, Value>& lhs,
const view_or_value<View, Value>& rhs) {
return !(lhs == rhs);
}
///
/// @}
///
///
/// @{
///
/// Mixed (in)-equality operators for view_or_value against View or Value types
///
/// @relates view_or_value
///
template <typename View, typename Value>
BSONCXX_INLINE bool operator==(const view_or_value<View, Value>& lhs, View rhs) {
return lhs.view() == rhs;
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator==(View lhs, const view_or_value<View, Value>& rhs) {
return rhs == lhs;
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(const view_or_value<View, Value>& lhs, View rhs) {
return !(lhs == rhs);
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(View lhs, const view_or_value<View, Value>& rhs) {
return !(rhs == lhs);
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator==(const view_or_value<View, Value>& lhs, const Value& rhs) {
return lhs.view() == View(rhs);
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator==(const Value& lhs, const view_or_value<View, Value>& rhs) {
return rhs == lhs;
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(const view_or_value<View, Value>& lhs, const Value& rhs) {
return !(lhs == rhs);
}
template <typename View, typename Value>
BSONCXX_INLINE bool operator!=(const Value& lhs, const view_or_value<View, Value>& rhs) {
return !(rhs == lhs);
}
///
/// @}
///
BSONCXX_INLINE_NAMESPACE_END
} // namespace bsoncxx
#include <bsoncxx/config/postlude.hpp>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,111 @@
// Copyright 2014-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <mongocxx/client_session.hpp>
#include <mongocxx/model/write.hpp>
#include <mongocxx/options/bulk_write.hpp>
#include <mongocxx/result/bulk_write.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
class collection;
///
/// Class representing a batch of write operations that can be sent to the server as a group.
///
/// If you have a lot of write operations to execute, it can be more efficient to send them as
/// part of a bulk_write in order to avoid unnecessary network-level round trips between the driver
/// and the server.
///
/// Bulk writes affect a single collection only and are executed via the bulk_write::execute()
/// method. Options that you would typically specify for individual write operations (such as write
/// concern) are instead specified for the aggregate operation.
///
/// @see https://docs.mongodb.com/manual/core/crud/
/// @see https://docs.mongodb.com/manual/core/bulk-write-operations/
///
class MONGOCXX_API bulk_write {
public:
///
/// Move constructs a bulk write operation.
///
bulk_write(bulk_write&&) noexcept;
///
/// Move assigns a bulk write operation.
///
bulk_write& operator=(bulk_write&&) noexcept;
///
/// Destroys a bulk write operation.
///
~bulk_write();
///
/// Appends a single write to the bulk write operation. The write operation's contents are
/// copied into the bulk operation completely, so there is no dependency between the life of an
/// appended write operation and the bulk operation itself.
///
/// @param operation
/// The write operation to append (an instance of model::write)
///
/// A model::write can be implicitly constructed from any of the following MongoDB models:
///
/// - model::insert_one
/// - model::delete_one
/// - model::replace_one
/// - model::update_many
/// - model::update_one
///
/// @return
/// A reference to the object on which this member function is being called. This facilitates
/// method chaining.
///
/// @throws mongocxx::logic_error if the given operation is invalid.
///
bulk_write& append(const model::write& operation);
///
/// Executes a bulk write.
///
/// @throws mongocxx::bulk_write_exception when there are errors processing the writes.
///
/// @return The optional result of the bulk operation execution, a result::bulk_write.
///
/// @see https://docs.mongodb.com/manual/core/bulk-write-operations/
///
stdx::optional<result::bulk_write> execute() const;
private:
friend class collection;
class MONGOCXX_PRIVATE impl;
MONGOCXX_PRIVATE bulk_write(const collection& coll,
const options::bulk_write& options,
const client_session* session = nullptr);
bool _created_from_collection;
std::unique_ptr<impl> _impl;
};
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,208 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
class client;
class collection;
class database;
///
/// Class representing a MongoDB change stream.
///
class MONGOCXX_API change_stream {
public:
/// A change stream iterator.
class MONGOCXX_API iterator;
///
/// Move constructs a change_stream.
///
change_stream(change_stream&& other) noexcept;
///
/// Move assigns a change_stream.
///
change_stream& operator=(change_stream&& other) noexcept;
///
/// Destroys a change_stream.
///
~change_stream();
///
/// A change_stream::iterator points to the beginning of any
/// available notifications. Each call to begin() advances to the next
/// available notification. The state of all iterators is tracked by the
/// change_stream itself, so advancing one iterator advances all iterators.
///
/// change_stream::begin() and the increment operators are blocking operations.
/// They will not return until a notification is available, the max_await_time (from
/// the options::change_stream) milliseconds have elapsed, or a server
/// error is encountered.
///
/// When change_stream.begin() == change_stream.end(), no notifications
/// are available. Each call to change_stream.begin() checks again for
/// newly-available notifications.
///
/// @return
/// The change_stream::iterator
/// @exception
/// Throws mongocxx::query_exception if the query failed.
///
iterator begin() const;
///
/// A change_stream::iterator indicating stream exhaustion, meaning that
/// no notifications are available from the stream.
///
/// @return
/// The change_stream::iterator indicating exhaustion
///
iterator end() const;
///
/// Returns a resume token for this change stream.
///
/// If the change stream has not been iterated, and either resume_after or
/// start_after was specified in the options to this change stream, the
/// specified value will be returned by this method. If neither resume_after or
/// start_after was set on the options for this change stream, and it has
/// not been iterated, this method will return no token.
///
/// Once this change stream has been iterated, this method will return the
/// resume token of the most recently returned document in the stream, or a
/// postBatchResumeToken if the current batch of documents has been exhausted.
///
/// @see https://docs.mongodb.com/manual/changeStreams/#change-stream-resume-token
///
/// The returned document::view is valid for the lifetime of the stream and
/// its data may be updated if the change stream is iterated after this function.
/// The value may be copied to extend its lifetime or preserve the
/// current resume token.
///
/// @return
/// The token.
///
bsoncxx::stdx::optional<bsoncxx::document::view> get_resume_token() const;
private:
friend class client;
friend class collection;
friend class database;
friend class change_stream::iterator;
MONGOCXX_PRIVATE change_stream(void* change_stream_ptr);
class MONGOCXX_PRIVATE impl;
std::unique_ptr<impl> _impl;
};
///
/// Class representing a MongoDB change stream iterator.
///
class MONGOCXX_API change_stream::iterator {
public:
// Support input-iterator (caveat of post-increment returning void)
using difference_type = std::int64_t;
using value_type = const bsoncxx::document::view;
using pointer = std::add_pointer<value_type>::type;
using reference = std::add_lvalue_reference<value_type>::type;
using iterator_category = std::input_iterator_tag;
///
/// Default-construct an iterator.
/// Default-constucted iterators can be compared (all default-constructed
/// iterators are ==), assigned, and copied.
///
iterator();
///
/// Dereferences the view for the document currently being pointed to.
///
const bsoncxx::document::view& operator*() const;
///
/// Accesses a member of the dereferenced document currently being pointed to.
///
const bsoncxx::document::view* operator->() const;
///
/// Pre-increments the iterator to move to the next document.
///
/// change_stream::begin() and increment operators are blocking operations.
/// They will not return until a notification is available, the max_await_time (from
/// the options::change_stream) miliseconds have elapsed, or a server
/// error is encountered.
///
/// @throws mongocxx::query_exception if the query failed
///
iterator& operator++();
///
/// Post-increments the iterator to move to the next document.
///
/// change_stream::begin() and increment operators are blocking operations.
/// They will not return until a notification is available, the max_await_time (from
/// the options::change_stream) miliseconds have elapsed, or a server
/// error is encountered.
///
/// @throws mongocxx::query_exception if the query failed
///
void operator++(int);
private:
friend class change_stream;
enum class iter_type { k_tracking, k_default_constructed, k_end };
MONGOCXX_PRIVATE explicit iterator(iter_type type, const change_stream* change_stream);
///
/// @{
///
/// Compare two iterators for (in)-equality. Iterators compare equal if
/// they point to the same underlying change_stream or if both are exhausted.
///
/// @relates iterator
///
friend MONGOCXX_API bool MONGOCXX_CALL operator==(const change_stream::iterator&,
const change_stream::iterator&) noexcept;
friend MONGOCXX_API bool MONGOCXX_CALL operator!=(const change_stream::iterator&,
const change_stream::iterator&) noexcept;
///
/// @}
///
MONGOCXX_PRIVATE bool is_exhausted() const;
// iter_type==k_default_constructed is equivalent to _change_stream==nullptr
iter_type _type;
const change_stream* _change_stream;
};
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,412 @@
// Copyright 2014-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <mongocxx/client_session.hpp>
#include <mongocxx/database.hpp>
#include <mongocxx/options/client.hpp>
#include <mongocxx/options/client_encryption.hpp>
#include <mongocxx/options/client_session.hpp>
#include <mongocxx/read_concern.hpp>
#include <mongocxx/read_preference.hpp>
#include <mongocxx/stdx.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/write_concern.hpp>
#include <mongocxx/config/prelude.hpp>
///
/// Top level namespace for the MongoDB C++ driver.
///
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
class client_session;
///
/// Class representing a client connection to MongoDB.
///
/// Acts as a logical gateway for working with databases contained within a MongoDB server.
///
/// Databases that are created via this client inherit the @c read_concern, @c read_preference, and
/// @c write_concern settings of this client when they are created. The lifetimes of objects created
/// via a client object (databases, collections, cursors, etc...) @b must be a subset of the
/// lifetime of the client that created them.
///
/// Example:
/// @code
/// mongocxx::client mongo_client{mongocxx::uri{}};
/// mongocxx::client mongo_client{mongocxx::uri{"mongodb://localhost:27017"}};
/// @endcode
///
/// Note that client is not thread-safe. See
/// https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/thread-safety/ for more details.
class MONGOCXX_API client {
public:
///
/// Default constructs a new client. The client is not connected and is equivalent to the
/// state of a moved-from client. The only valid actions to take with a default constructed
/// 'client' are to assign to it, or destroy it.
///
client() noexcept;
///
/// Creates a new client connection to MongoDB.
///
/// @param mongodb_uri
/// A MongoDB URI representing the connection parameters
/// @param options
/// Additional options that cannot be specified via the mongodb_uri
///
/// @throws mongocxx::exception if invalid options are provided
/// (whether from the URI or provided client options).
///
client(const class uri& mongodb_uri, const options::client& options = options::client());
///
/// Move constructs a client.
///
client(client&&) noexcept;
///
/// Move assigns a client.
///
client& operator=(client&&) noexcept;
///
/// Destroys a client.
///
~client();
///
/// Returns true if the client is valid, meaning it was not default constructed
/// or moved from.
///
explicit operator bool() const noexcept;
///
/// Sets the read concern for this client.
///
/// Modifications at this level do not affect existing database instances that have been
/// created by this client but do affect new ones as databases inherit the @c read_concern
/// settings of their parent upon instantiation.
///
/// @deprecated
/// This method is deprecated. Read concerns should be set either in the URI or directly on
/// database or collection objects.
///
/// @param rc
/// The new @c read_concern
///
/// @see https://docs.mongodb.com/manual/reference/read-concern/
///
MONGOCXX_DEPRECATED void read_concern(class read_concern rc);
void read_concern_deprecated(class read_concern rc);
///
/// Returns the current read concern for this client.
///
/// @return The current @c read_concern
///
class read_concern read_concern() const;
///
/// Sets the read preference for this client.
///
/// Modifications at this level do not affect existing database instances that have been
/// created by this client but do affect new ones as databases inherit the @c read_preference
/// settings of their parent upon instantiation.
///
/// @deprecated
/// This method is deprecated. Read preferences should be set either in the URI or directly on
/// database or collection objects.
///
/// @param rp
/// The new @c read_preference
///
/// @see https://docs.mongodb.com/manual/core/read-preference/
///
MONGOCXX_DEPRECATED void read_preference(class read_preference rp);
void read_preference_deprecated(class read_preference rp);
///
/// Returns the current read preference for this client.
///
/// @return The current @c read_preference
///
/// @see https://docs.mongodb.com/manual/core/read-preference/
///
class read_preference read_preference() const;
///
/// Returns the current uri for this client.
///
/// @return The @c uri that this client was created with.
///
class uri uri() const;
///
/// Sets the write concern for this client.
///
/// @note Modifications at this level do not affect existing databases or collection instances
/// that have come from this client but do affect new ones as databases will receive a copy of
/// this client's @c write_concern upon instantiation.
///
/// @deprecated
/// This method is deprecated. Write concerns should be set either in the URI or directly on
/// database or collection objects.
///
/// @param wc
/// The new write concern
///
MONGOCXX_DEPRECATED void write_concern(class write_concern wc);
void write_concern_deprecated(class write_concern wc);
///
/// Returns the current write concern for this client.
///
/// @return the current @c write_concern
class write_concern write_concern() const;
///
/// Obtains a database that represents a logical grouping of collections on a MongoDB server.
///
/// @note A database cannot be obtained from a temporary client object.
///
/// @param name
/// The name of the database to get
///
/// @return The database
///
class database database(bsoncxx::string::view_or_value name) const&;
class database database(bsoncxx::string::view_or_value name) const&& = delete;
///
/// Allows the syntax @c client["db_name"] as a convenient shorthand for the client::database()
/// method by implementing the array subscript operator.
///
/// @note A database cannot be obtained from a temporary client object.
///
/// @param name
/// The name of the database.
///
/// @return Client side representation of a server side database
///
MONGOCXX_INLINE class database operator[](bsoncxx::string::view_or_value name) const&;
MONGOCXX_INLINE class database operator[](bsoncxx::string::view_or_value name) const&& = delete;
///
/// @{
///
/// Enumerates the databases in the client.
///
/// @return A mongocxx::cursor containing a BSON document for each
/// database. Each document contains a name field with the database
/// name, a sizeOnDisk field with the total size of the database file on
/// disk in bytes, and an empty field specifying whether the database
/// has any data.
///
/// @throws mongocxx::operation_exception if the underlying 'listDatabases' command fails.
///
/// @see https://docs.mongodb.com/manual/reference/command/listDatabases
///
cursor list_databases() const;
///
/// Enumerates the databases in the client.
///
/// @param session
/// The mongocxx::client_session with which to perform the aggregation.
///
/// @return A mongocxx::cursor containing a BSON document for each
/// database. Each document contains a name field with the database
/// name, a sizeOnDisk field with the total size of the database file on
/// disk in bytes, and an empty field specifying whether the database
/// has any data.
///
/// @throws mongocxx::operation_exception if the underlying 'listDatabases' command fails.
///
/// @see https://docs.mongodb.com/manual/reference/command/listDatabases
///
cursor list_databases(const client_session& session) const;
///
/// Enumerates the databases in the client.
///
/// @param opts
/// Options passed directly to the 'listDatabases' command.
///
/// @return A mongocxx::cursor containing a BSON document for each
/// database. Each document contains a name field with the database
/// name, a sizeOnDisk field with the total size of the database file on
/// disk in bytes, and an empty field specifying whether the database
/// has any data.
///
/// @throws mongocxx::operation_exception if the underlying 'listDatabases' command fails.
///
/// @see https://docs.mongodb.com/manual/reference/command/listDatabases
///
cursor list_databases(const bsoncxx::document::view_or_value opts) const;
///
/// Queries the MongoDB server for a list of known databases.
///
/// @param filter
/// An optional query expression to filter the returned database names.
///
/// @return std::vector<std::string> containing the database names.
///
/// @throws mongocxx::operation_exception if the underlying 'listDatabases'
/// command fails.
///
/// @see https://docs.mongodb.com/manual/reference/command/listDatabases
///
std::vector<std::string> list_database_names(
const bsoncxx::document::view_or_value filter = {}) const;
///
/// @}
///
///
/// Create a client session for a sequence of operations.
///
/// @return A client_session object. See `mongocxx::client_session` for more information.
///
/// @throws mongocxx::operation_exception if the driver is not built with crypto support, if
/// options is misconfigured, or if the session is configured with options that the server does
/// not support.
///
client_session start_session(const options::client_session& options = {});
///
/// @{
///
/// Gets a change stream on this client with an empty pipeline.
/// Change streams are only supported with a "majority" read concern or no read concern.
///
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this client.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const options::change_stream& options = {});
///
/// @param session
/// The mongocxx::client_session with which to perform the watch operation.
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this client.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const client_session& session, const options::change_stream& options = {});
///
/// Gets a change stream on this client.
/// Change streams are only supported with a "majority" read concern or no read concern.
///
/// @param pipe
/// The aggregation pipeline to be used on the change notifications.
/// Only a subset of pipeline operations are supported for change streams. For more
/// information see the change streams documentation.
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this client.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const pipeline& pipe, const options::change_stream& options = {});
///
/// Gets a change stream on this client.
///
/// @param session
/// The mongocxx::client_session with which to perform the watch operation.
/// @param pipe
/// The aggregation pipeline to be used on the change notifications.
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this client.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const client_session& session,
const pipeline& pipe,
const options::change_stream& options = {});
///
/// @}
///
///
/// Prevents resource cleanup in the child process from interfering
/// with the parent process after forking.
///
/// Clients should not be reused after forking. Call this method in the
/// child after forking to safely destroy the client. This method should
/// not be used with multi-threaded clients.
///
/// This method causes the client to clear its session pool without sending
/// endSessions. It also increments an internal generation counter on the
/// given client. After this method is called, cursors from
/// previous generations will not issue a killCursors command when
/// they are destroyed. Client sessions from previous generations
/// cannot be used and should be destroyed.
///
void reset();
private:
friend class collection;
friend class database;
friend class pool;
friend class client_session;
friend class options::auto_encryption;
friend class options::client_encryption;
MONGOCXX_PRIVATE explicit client(void* implementation);
MONGOCXX_PRIVATE change_stream _watch(const client_session* session,
const pipeline& pipe,
const options::change_stream& options);
class MONGOCXX_PRIVATE impl;
MONGOCXX_PRIVATE impl& _get_impl();
MONGOCXX_PRIVATE const impl& _get_impl() const;
std::unique_ptr<impl> _impl;
};
MONGOCXX_INLINE database client::operator[](bsoncxx::string::view_or_value name) const& {
return database(name);
}
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,124 @@
// Copyright 2020 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/types/bson_value/value.hpp>
#include <bsoncxx/types/bson_value/view.hpp>
#include <mongocxx/options/client_encryption.hpp>
#include <mongocxx/options/data_key.hpp>
#include <mongocxx/options/encrypt.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
///
/// Class supporting operations for MongoDB Client-Side Field Level Encryption.
///
class MONGOCXX_API client_encryption {
public:
///
/// Creates a client_encryption object.
///
/// @param opts
/// An object representing encryption options.
///
/// @see https://docs.mongodb.com/ecosystem/use-cases/client-side-field-level-encryption-guide
///
client_encryption(options::client_encryption opts);
///
/// Destroys a client_encryption.
///
~client_encryption() noexcept;
///
/// Move-constructs a client_encryption object.
///
client_encryption(client_encryption&&);
///
/// Move-assigns a client_encryption object.
///
client_encryption& operator=(client_encryption&&);
client_encryption(const client_encryption&) = delete;
client_encryption& operator=(const client_encryption&) = delete;
///
/// Creates a new key document and inserts into the key vault collection.
///
/// @param kms_provider
/// A string identifying the KMS service to use to encrypt the datakey.
/// Must be one of "aws", "azure", "gcp", "kmip", or "local".
/// @param opts
/// Optional arguments, see options::data_key.
///
/// @return The id of the created document as a bson_value::value containing
/// a UUID (BSON binary subtype 4).
///
/// @throws mongocxx::exception if there is an error creating the key.
///
/// @see
/// https://docs.mongodb.com/ecosystem/use-cases/client-side-field-level-encryption-guide/#b-create-a-data-encryption-key
///
bsoncxx::types::bson_value::value create_data_key(std::string kms_provider,
const options::data_key& opts = {});
///
/// Encrypts a BSON value with a given key and algorithm.
///
/// @param value
/// The BSON value to encrypt.
/// @param opts
/// Options must be given in order to specify an encryption algorithm
/// and a key_id or key_alt_name. See options::encrypt.
///
/// @return The encrypted value (BSON binary subtype 6).
///
/// @throws mongocxx::exception if there is an error encrypting the value.
///
/// @see
/// https://docs.mongodb.com/manual/reference/method/ClientEncryption.encrypt/#ClientEncryption.encrypt
///
bsoncxx::types::bson_value::value encrypt(bsoncxx::types::bson_value::view value,
const options::encrypt& opts);
///
/// Decrypts an encrypted value (BSON binary of subtype 6).
///
/// @param value
/// The encrypted value.
///
/// @return The original BSON value.
///
/// @throws mongocxx::exception if there is an error decrypting the value.
///
/// @see
/// https://docs.mongodb.com/manual/reference/method/ClientEncryption.decrypt/#ClientEncryption.decrypt
///
bsoncxx::types::bson_value::value decrypt(bsoncxx::types::bson_value::view value);
private:
class MONGOCXX_PRIVATE impl;
std::unique_ptr<impl> _impl;
};
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,215 @@
// Copyright 2017-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <functional>
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/options/client_session.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
class client;
///
/// Use a session for a sequence of operations, optionally with either causal consistency
/// or snapshots.
///
/// Note that client_session is not thread-safe. See
/// https://mongodb.github.io/mongo-cxx-driver/mongocxx-v3/thread-safety/ for more details.
///
/// @see http://dochub.mongodb.org/core/causal-consistency
///
class MONGOCXX_API client_session {
public:
enum class transaction_state {
k_transaction_none,
k_transaction_starting,
k_transaction_in_progress,
k_transaction_committed,
k_transaction_aborted,
};
///
/// Move constructs a session.
///
client_session(client_session&&) noexcept;
///
/// Move assigns a session.
///
client_session& operator=(client_session&&) noexcept;
client_session(const client_session&) = delete;
client_session& operator=(const client_session&) = delete;
///
/// Ends and destroys the session.
///
~client_session() noexcept;
///
/// Gets the client that started this session.
///
const class client& client() const noexcept;
///
/// Gets the options this session was created with.
///
const options::client_session& options() const noexcept;
///
/// Get the server-side "logical session ID" associated with this session, as a BSON document.
/// This view is invalid after the session is destroyed.
///
bsoncxx::document::view id() const noexcept;
///
/// Get the session's clusterTime, as a BSON document. This is an opaque value suitable for
/// passing to advance_cluster_time(). The document is empty if the session has
/// not been used for any operation and you have not called advance_cluster_time().
/// This view is invalid after the session is destroyed.
///
bsoncxx::document::view cluster_time() const noexcept;
///
/// Get the session's operationTime, as a BSON timestamp. This is an opaque value suitable for
/// passing to advance_operation_time(). The timestamp is zero if the session has not been used
/// for any operation and you have not called advance_operation_time().
///
bsoncxx::types::b_timestamp operation_time() const noexcept;
///
/// Get the server_id the session is pinned to. The server_id is zero if the session is not
/// pinned to a server.
///
std::uint32_t server_id() const noexcept;
///
/// Returns the current transaction state for this session.
///
transaction_state get_transaction_state() const noexcept;
///
/// Returns whether or not this session is dirty.
///
bool get_dirty() const noexcept;
///
/// Advance the cluster time for a session. Has an effect only if the new cluster time is
/// greater than the session's current cluster time.
///
/// Use advance_operation_time() and advance_cluster_time() to copy the operationTime and
/// clusterTime from another session, ensuring subsequent operations in this session are
/// causally consistent with the last operation in the other session.
///
void advance_cluster_time(const bsoncxx::document::view& cluster_time);
///
/// Advance the session's operation time, expressed as a BSON timestamp. Has an effect only if
/// the new operation time is greater than the session's current operation time.
///
/// Use advance_operation_time() and advance_cluster_time() to copy the operationTime and
/// clusterTime from another session, ensuring subsequent operations in this session are
/// causally consistent with the last operation in the other session.
///
void advance_operation_time(const bsoncxx::types::b_timestamp& operation_time);
///
/// Starts a transaction on the current client session.
///
/// @param transaction_opts (optional)
/// The options to use in the transaction.
///
/// @throws mongocxx::operation_exception if the options are misconfigured, if there are network
/// or other transient failures, or if there are other errors such as a session with a
/// transaction already in progress.
///
void start_transaction(const stdx::optional<options::transaction>& transaction_opts = {});
///
/// Commits a transaction on the current client session.
///
/// @throws mongocxx::operation_exception if the options are misconfigured, if there are network
/// or other transient failures, or if there are other errors such as a session with no
/// transaction in progress.
///
void commit_transaction();
///
/// Aborts a transaction on the current client session.
///
/// @throws mongocxx::operation_exception if the options are misconfigured or if there are
/// other errors such as a session with no transaction in progress.
///
void abort_transaction();
///
/// Helper to run a user-provided callback within a transaction.
///
/// This method will start a new transaction on this client session,
/// run the callback, then commit the transaction. If it cannot commit
/// the transaction, the entire sequence may be retried, and the callback
/// may be run multiple times.
///
/// If the user callback calls driver methods that run operations against the
/// server that can throw an operation_exception (ex: collection::insert_one),
/// the user callback should allow those exceptions to propagate up the stack
/// so they can be caught and processed by the with_transaction helper.
///
/// @param cb
/// The callback to run inside of a transaction.
/// @param opts (optional)
/// The options to use to run the transaction.
///
/// @throws mongocxx::operation_exception if there are errors completing the
/// transaction.
///
using with_transaction_cb = std::function<void MONGOCXX_CALL(client_session*)>;
void with_transaction(with_transaction_cb cb, options::transaction opts = {});
private:
friend class bulk_write;
friend class client;
friend class collection;
friend class database;
friend class index_view;
class MONGOCXX_PRIVATE impl;
// "class client" distinguishes from client() method above.
MONGOCXX_PRIVATE client_session(const class client* client,
const options::client_session& options);
MONGOCXX_PRIVATE impl& _get_impl();
MONGOCXX_PRIVATE const impl& _get_impl() const;
std::unique_ptr<impl> _impl;
};
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>
///
/// @example examples/mongocxx/client_session.cpp
/// Use a mongocxx::client_session for a sequence of operations with causal consistency.
///

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
// Copyright 2015 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// TODO: DRY this definition with the one from bsoncxx/config/compiler.hpp per discussion
// here - https://github.com/mongodb/mongo-cxx-driver/pull/374#issuecomment-158179295
#if defined(_MSC_VER)
// Disable MSVC warnings that cause a lot of noise related to DLL visibility
// for types that we don't control (like std::unique_ptr).
#pragma warning(push)
#pragma warning(disable : 4251 4275)
#define MONGOCXX_INLINE inline MONGOCXX_PRIVATE
#define MONGOCXX_CALL __cdecl
#else
#define MONGOCXX_INLINE inline MONGOCXX_PRIVATE
#define MONGOCXX_CALL
#endif

View File

@@ -0,0 +1,17 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#define MONGOCXX_INLINE_NAMESPACE_BEGIN inline namespace v_noabi {
#define MONGOCXX_INLINE_NAMESPACE_END } // namespace v_noabi

View File

@@ -0,0 +1,42 @@
#ifndef MONGOCXX_API_H
#define MONGOCXX_API_H
#ifdef MONGOCXX_STATIC
# define MONGOCXX_API
# define MONGOCXX_PRIVATE
#else
# ifndef MONGOCXX_API
# ifdef MONGOCXX_EXPORTS
/* We are building this library */
# define MONGOCXX_API __attribute__((visibility("default")))
# else
/* We are using this library */
# define MONGOCXX_API __attribute__((visibility("default")))
# endif
# endif
# ifndef MONGOCXX_PRIVATE
# define MONGOCXX_PRIVATE __attribute__((visibility("hidden")))
# endif
#endif
#ifndef MONGOCXX_DEPRECATED
# define MONGOCXX_DEPRECATED __attribute__ ((__deprecated__))
#endif
#ifndef MONGOCXX_DEPRECATED_EXPORT
# define MONGOCXX_DEPRECATED_EXPORT MONGOCXX_API MONGOCXX_DEPRECATED
#endif
#ifndef MONGOCXX_DEPRECATED_NO_EXPORT
# define MONGOCXX_DEPRECATED_NO_EXPORT MONGOCXX_PRIVATE MONGOCXX_DEPRECATED
#endif
#if 0 /* DEFINE_NO_DEPRECATED */
# ifndef MONGOCXX_NO_DEPRECATED
# define MONGOCXX_NO_DEPRECATED
# endif
#endif
#endif /* MONGOCXX_API_H */

View File

@@ -0,0 +1,62 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// src/mongocxx/config/compiler.hpp
#undef MONGOCXX_INLINE
#pragma pop_macro("MONGOCXX_INLINE")
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
#undef MONGOCXX_CALL
#pragma pop_macro("MONGOCXX_CALL")
// src/mongocxx/config/config.hpp.in
#undef MONGOCXX_INLINE_NAMESPACE_BEGIN
#pragma pop_macro("MONGOCXX_INLINE_NAMESPACE_BEGIN")
#undef MONGOCXX_INLINE_NAMESPACE_END
#pragma pop_macro("MONGOCXX_INLINE_NAMESPACE_END")
// src/mongocxx/config/version.hpp.in
#undef MONGOCXX_VERSION_STRING
#pragma pop_macro("MONGOCXX_VERSION_STRING")
#undef MONGOCXX_VERSION_EXTRA
#pragma pop_macro("MONGOCXX_VERSION_EXTRA")
#undef MONGOCXX_VERSION_MAJOR
#pragma pop_macro("MONGOCXX_VERSION_MAJOR")
#undef MONGOCXX_VERSION_MINOR
#pragma pop_macro("MONGOCXX_VERSION_MINOR")
#undef MONGOCXX_VERSION_PATCH
#pragma pop_macro("MONGOCXX_VERSION_PATCH")
// export.hpp (generated by cmake)
#undef MONGOCXX_API_H
#pragma pop_macro("MONGOCXX_API_H")
#undef MONGOCXX_API
#pragma pop_macro("MONGOCXX_API")
#undef MONGOCXX_PRIVATE
#pragma pop_macro("MONGOCXX_PRIVATE")
#undef MONGOCXX_DEPRECATED
#pragma pop_macro("MONGOCXX_DEPRECATED")
#undef MONGOCXX_DEPRECATED_EXPORT
#pragma pop_macro("MONGOCXX_DEPRECATED_EXPORT")
#undef MONGOCXX_DEPRECATED_NO_EXPORT
#pragma pop_macro("MONGOCXX_DEPRECATED_NO_EXPORT")
#undef DEFINE_NO_DEPRECATED
#pragma pop_macro("DEFINE_NO_DEPRECATED")
#undef MONGOCXX_NO_DEPRECATED
#pragma pop_macro("MONGOCXX_NO_DEPRECATED")
// prelude.hpp
#undef MONGOCXX_UNREACHABLE
#pragma pop_macro("MONGOCXX_UNREACHABLE")

View File

@@ -0,0 +1,65 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// src/mongocxx/config/compiler.hpp
#pragma push_macro("MONGOCXX_INLINE")
#undef MONGOCXX_INLINE
#pragma push_macro("MONGOCXX_CALL")
#undef MONGOCXX_CALL
// src/mongocxx/config/config.hpp.in
#pragma push_macro("MONGOCXX_INLINE_NAMESPACE_BEGIN")
#undef MONGOCXX_INLINE_NAMESPACE_BEGIN
#pragma push_macro("MONGOCXX_INLINE_NAMESPACE_END")
#undef MONGOCXX_INLINE_NAMESPACE_END
// src/mongocxx/config/version.hpp.in
#pragma push_macro("MONGOCXX_VERSION_STRING")
#undef MONGOCXX_VERSION_STRING
#pragma push_macro("MONGOCXX_VERSION_EXTRA")
#undef MONGOCXX_VERSION_EXTRA
#pragma push_macro("MONGOCXX_VERSION_MAJOR")
#undef MONGOCXX_VERSION_MAJOR
#pragma push_macro("MONGOCXX_VERSION_MINOR")
#undef MONGOCXX_VERSION_MINOR
#pragma push_macro("MONGOCXX_VERSION_PATCH")
#undef MONGOCXX_VERSION_PATCH
// export.hpp (generated by cmake)
#pragma push_macro("MONGOCXX_API_H")
#undef MONGOCXX_API_H
#pragma push_macro("MONGOCXX_API")
#undef MONGOCXX_API
#pragma push_macro("MONGOCXX_PRIVATE")
#undef MONGOCXX_PRIVATE
#pragma push_macro("MONGOCXX_DEPRECATED")
#undef MONGOCXX_DEPRECATED
#pragma push_macro("MONGOCXX_DEPRECATED_EXPORT")
#undef MONGOCXX_DEPRECATED_EXPORT
#pragma push_macro("MONGOCXX_DEPRECATED_NO_EXPORT")
#undef MONGOCXX_DEPRECATED_NO_EXPORT
#pragma push_macro("DEFINE_NO_DEPRECATED")
#undef DEFINE_NO_DEPRECATED
#pragma push_macro("MONGOCXX_NO_DEPRECATED")
#undef MONGOCXX_NO_DEPRECATED
#include <mongocxx/config/compiler.hpp>
#include <mongocxx/config/config.hpp>
#include <mongocxx/config/export.hpp>
#include <mongocxx/config/version.hpp>
// TODO: Find a way to DRY this with BSONCXX_UNREACHABLE
#pragma push_macro("MONGOCXX_UNREACHABLE")
#undef MONGOCXX_UNREACHABLE
#define MONGOCXX_UNREACHABLE std::abort()

View File

@@ -0,0 +1,19 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#define MONGOCXX_VERSION_STRING "3.7.1"
#define MONGOCXX_VERSION_MAJOR 3
#define MONGOCXX_VERSION_MINOR 7
#define MONGOCXX_VERSION_PATCH 1
#define MONGOCXX_VERSION_EXTRA

View File

@@ -0,0 +1,176 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
class collection;
///
/// Class representing a pointer to the result set of a query on a MongoDB server.
///
/// Clients can iterate through a cursor::iterator to retrieve results.
///
/// @note By default, cursors timeout after 10 minutes of inactivity.
///
class MONGOCXX_API cursor {
public:
enum class type { k_non_tailable, k_tailable, k_tailable_await };
class MONGOCXX_API iterator;
///
/// Move constructs a cursor.
///
cursor(cursor&&) noexcept;
///
/// Move assigns a cursor.
///
cursor& operator=(cursor&&) noexcept;
///
/// Destroys a cursor.
///
~cursor();
///
/// A cursor::iterator that points to the beginning of any available
/// results. If begin() is called more than once, the cursor::iterator
/// returned points to the next remaining result, not the result of
/// the original call to begin().
///
/// For a tailable cursor, when cursor.begin() == cursor.end(), no
/// documents are available. Each call to cursor.begin() checks again
/// for newly-available documents.
///
/// @return the cursor::iterator
///
/// @throws mongocxx::query_exception if the query failed
///
iterator begin();
///
/// A cursor::iterator indicating cursor exhaustion, meaning that
/// no documents are available from the cursor.
///
/// @return the cursor::iterator
///
iterator end();
private:
friend class collection;
friend class client;
friend class database;
friend class index_view;
friend class cursor::iterator;
MONGOCXX_PRIVATE cursor(void* cursor_ptr,
bsoncxx::stdx::optional<type> cursor_type = bsoncxx::stdx::nullopt);
class MONGOCXX_PRIVATE impl;
std::unique_ptr<impl> _impl;
};
///
/// Class representing an input iterator of documents in a MongoDB cursor
/// result set.
///
/// All non-end iterators derived from the same mongocxx::cursor move in
/// lock-step. Dereferencing any non-end() iterator always gives the first
/// remaining document in the cursor. Incrementing one non-end iterator is
/// equivalent to incrementing them all.
///
/// An iterator is 'exhausted' when no documents are available. An
/// end-iterator is always exhausted. A non-end iterator is exhausted when the
/// originating mongocxx::cursor has no more documents. When an iterator is
/// exhausted, it must not be dereferenced or incremented.
///
/// For iterators of a tailable cursor, calling cursor.begin() may revive an
/// exhausted iterator so that it no longer compares equal to the
/// end-iterator.
///
class MONGOCXX_API cursor::iterator {
public:
///
/// std::iterator_traits
///
using value_type = bsoncxx::document::view;
using reference = bsoncxx::document::view&;
using pointer = bsoncxx::document::view*;
using iterator_category = std::input_iterator_tag;
using difference_type = std::ptrdiff_t;
///
/// Dereferences the view for the document currently being pointed to.
///
const bsoncxx::document::view& operator*() const;
///
/// Accesses a member of the dereferenced document currently being pointed to.
///
const bsoncxx::document::view* operator->() const;
///
/// Pre-increments the iterator to move to the next document.
///
/// @throws mongocxx::query_exception if the query failed
///
iterator& operator++();
///
/// Post-increments the iterator to move to the next document.
///
/// @throws mongocxx::query_exception if the query failed
///
void operator++(int);
private:
friend class cursor;
///
/// @{
///
/// Compare two iterators for (in)-equality. Iterators compare equal if
/// they point to the same underlying cursor or if both are exhausted.
///
/// @relates iterator
///
friend MONGOCXX_API bool MONGOCXX_CALL operator==(const iterator&, const iterator&);
friend MONGOCXX_API bool MONGOCXX_CALL operator!=(const iterator&, const iterator&);
///
/// @}
///
MONGOCXX_PRIVATE bool is_exhausted() const;
MONGOCXX_PRIVATE explicit iterator(cursor* cursor);
// If this pointer is null, the iterator is considered "past-the-end".
cursor* _cursor;
};
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,679 @@
// Copyright 2014 MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <string>
#include <bsoncxx/document/view_or_value.hpp>
#include <bsoncxx/string/view_or_value.hpp>
#include <mongocxx/client_session.hpp>
#include <mongocxx/collection.hpp>
#include <mongocxx/gridfs/bucket.hpp>
#include <mongocxx/options/create_collection.hpp>
#include <mongocxx/options/gridfs/bucket.hpp>
#include <mongocxx/read_preference.hpp>
#include <mongocxx/write_concern.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
class client;
///
/// Class representing a MongoDB database.
///
/// Acts as a gateway for accessing collections that are contained within a database. It inherits
/// all of its default settings from the client that creates it.
///
class MONGOCXX_API database {
public:
///
/// Default constructs a new database. The database is not valid for use and is equivalent
/// to the state of a moved-from database. The only valid actions to take with a default
/// constructed database are to assign to it, or destroy it.
///
database() noexcept;
///
/// Move constructs a database.
///
database(database&&) noexcept;
///
/// Move assigns a database.
///
database& operator=(database&&) noexcept;
///
/// Copy constructs a database.
///
database(const database&);
///
/// Copy assigns a database.
///
database& operator=(const database&);
///
/// Destroys a database.
///
~database();
///
/// Returns true if the client is valid, meaning it was not default constructed
/// or moved from.
///
explicit operator bool() const noexcept;
///
/// @{
///
/// Runs an aggregation framework pipeline against this database for
/// pipeline stages that do not require an underlying collection,
/// such as $currentOp and $listLocalSessions.
///
/// @param pipeline
/// The pipeline of aggregation operations to perform.
/// @param options
/// Optional arguments, see mongocxx::options::aggregate.
///
/// @return A mongocxx::cursor with the results. If the query fails,
/// the cursor throws mongocxx::query_exception when the returned cursor
/// is iterated.
///
/// @see https://docs.mongodb.com/manual/reference/command/aggregate/#dbcmd.aggregate
///
/// @note
/// In order to pass a read concern to this, you must use the
/// database level set read concern - database::read_concern(rc).
/// (Write concern supported only for MongoDB 3.4+).
///
cursor aggregate(const pipeline& pipeline,
const options::aggregate& options = options::aggregate());
///
/// Runs an aggregation framework pipeline against this database for
/// pipeline stages that do not require an underlying collection,
/// such as $currentOp and $listLocalSessions.
///
/// @param session
/// The mongocxx::client_session with which to perform the aggregation.
/// @param pipeline
/// The pipeline of aggregation operations to perform.
/// @param options
/// Optional arguments, see mongocxx::options::aggregate.
///
/// @return A mongocxx::cursor with the results. If the query fails,
/// the cursor throws mongocxx::query_exception when the returned cursor
/// is iterated.
///
/// @see https://docs.mongodb.com/manual/reference/command/aggregate/#dbcmd.aggregate
///
/// @note
/// In order to pass a read concern to this, you must use the
/// database level set read concern - database::read_concern(rc).
/// (Write concern supported only for MongoDB 3.4+).
///
cursor aggregate(const client_session& session,
const pipeline& pipeline,
const options::aggregate& options = options::aggregate());
///
/// @}
///
///
/// @{
///
/// Runs a command against this database.
///
/// @see https://docs.mongodb.com/manual/reference/method/db.runCommand/
///
/// @param command document representing the command to be run.
/// @return the result of executing the command.
///
/// @throws mongocxx::operation_exception if the operation fails.
///
bsoncxx::document::value run_command(bsoncxx::document::view_or_value command);
///
/// Runs a command against this database.
///
/// @see https://docs.mongodb.com/manual/reference/method/db.runCommand/
///
/// @param session The mongocxx::client_session with which to run the command.
/// @param command document representing the command to be run.
/// @return the result of executing the command.
///
/// @throws mongocxx::operation_exception if the operation fails.
///
bsoncxx::document::value run_command(const client_session& session,
bsoncxx::document::view_or_value command);
///
/// Executes a command on a specific server using this database.
///
/// @see https://docs.mongodb.com/manual/reference/method/db.runCommand/
///
/// @param command document representing the command to be run.
/// @param server_id specifying which server to use.
/// @return the result of executing the command.
///
/// @throws mongocxx::operation_exception if the operation fails.
///
bsoncxx::document::value run_command(bsoncxx::document::view_or_value command,
uint32_t server_id);
///
/// @}
///
///
/// @{
///
/// Explicitly creates a collection in this database with the specified options.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/create/
///
/// @note This function can also be used to create a Time Series Collection. See:
/// https://docs.mongodb.com/manual/core/timeseries-collections/
///
/// @param name
/// the new collection's name.
/// @param collection_options
/// the options for the new collection.
/// @param write_concern
/// the write concern to use for this operation. Will default to database
/// set write concern if none passed here.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
class collection create_collection(stdx::string_view name,
bsoncxx::document::view_or_value collection_options = {},
const stdx::optional<write_concern>& write_concern = {});
///
/// Explicitly creates a collection in this database with the specified options.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/create/
///
/// @note This function can also be used to create a Time Series Collection. See:
/// https://docs.mongodb.com/manual/core/timeseries-collections/
///
/// @param session
/// The mongocxx::client_session with which to perform the create operation.
/// @param name
/// the new collection's name.
/// @param collection_options
/// the options for the new collection.
/// @param write_concern
/// the write concern to use for this operation. Will default to database
/// set write concern if none passed here.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
class collection create_collection(const client_session& session,
stdx::string_view name,
bsoncxx::document::view_or_value collection_options = {},
const stdx::optional<write_concern>& write_concern = {});
///
/// Explicitly creates a collection in this database with the specified options.
///
/// @deprecated
/// This overload is deprecated. Call database::create_collection with a
/// bsoncxx::document::view_or_value collection_options instead.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/create/
///
/// @param name
/// the new collection's name.
/// @param collection_options
/// the options for the new collection.
/// @param write_concern
/// the write concern to use for this operation. Will default to database
/// set write concern if none passed here.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
MONGOCXX_DEPRECATED class collection create_collection(
bsoncxx::string::view_or_value name,
const options::create_collection_deprecated& collection_options,
const stdx::optional<write_concern>& write_concern = {}) {
return create_collection_deprecated(name, collection_options, write_concern);
}
class collection create_collection_deprecated(
bsoncxx::string::view_or_value name,
const options::create_collection_deprecated& collection_options,
const stdx::optional<write_concern>& write_concern = {});
///
/// Explicitly creates a collection in this database with the specified options.
///
/// @deprecated
/// This overload is deprecated. Call database::create_collection with a
/// bsoncxx::document::view_or_value collection_options instead.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/create/
///
/// @param session
/// The mongocxx::client_session with which to perform the create operation.
/// @param name
/// the new collection's name.
/// @param collection_options
/// the options for the new collection.
/// @param write_concern
/// the write concern to use for this operation. Will default to database
/// set write concern if none passed here.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
MONGOCXX_DEPRECATED class collection create_collection(
const client_session& session,
bsoncxx::string::view_or_value name,
const options::create_collection_deprecated& collection_options,
const stdx::optional<write_concern>& write_concern = {}) {
return create_collection_deprecated(session, name, collection_options, write_concern);
}
///
/// Explicitly creates a collection in this database with the specified options.
///
/// @deprecated
/// This overload is deprecated. Call database::create_collection with a
/// bsoncxx::document::view_or_value collection_options instead.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/create/
///
/// @param session
/// The mongocxx::client_session with which to perform the create operation.
/// @param name
/// the new collection's name.
/// @param collection_options
/// the options for the new collection.
/// @param write_concern
/// the write concern to use for this operation. Will default to database
/// set write concern if none passed here.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
class collection create_collection_deprecated(
const client_session& session,
bsoncxx::string::view_or_value name,
const options::create_collection_deprecated& collection_options,
const stdx::optional<write_concern>& write_concern = {});
///
/// @}
///
///
/// @{
///
/// Drops the database and all its collections.
///
/// @param write_concern (optional)
/// The write concern to be used for this operation. If not passed here, the write concern
/// set on the database will be used.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/dropDatabase/
///
void drop(const bsoncxx::stdx::optional<mongocxx::write_concern>& write_concern = {});
///
/// Drops the database and all its collections.
///
/// @param session
/// The mongocxx::client_session with which to perform the aggregation.
/// @param write_concern (optional)
/// The write concern to be used for this operation. If not passed here, the write concern
/// set on the database will be used.
///
/// @exception
/// mongocxx::operation_exception if the operation fails.
///
/// @see
/// https://docs.mongodb.com/manual/reference/command/dropDatabase/
///
void drop(const client_session& session,
const bsoncxx::stdx::optional<mongocxx::write_concern>& write_concern = {});
///
/// @}
///
///
/// Checks whether this database contains a collection having the given name.
///
/// @param name the name of the collection.
///
/// @return bool whether the collection exists in this database.
///
/// @throws mongocxx::operation_exception if the underlying 'listCollections'
/// command fails.
///
bool has_collection(bsoncxx::string::view_or_value name) const;
///
/// @{
///
/// Enumerates the collections in this database.
///
/// @param filter
/// An optional query expression to filter the returned collections.
///
/// @return mongocxx::cursor containing the collection information.
///
/// @see https://docs.mongodb.com/manual/reference/command/listCollections/
///
cursor list_collections(bsoncxx::document::view_or_value filter = {});
///
/// Enumerates the collections in this database.
///
/// @param session
/// The mongocxx::client_session with which to perform the aggregation.
/// @param filter
/// An optional query expression to filter the returned collections.
///
/// @return mongocxx::cursor containing the collection information.
///
/// @see https://docs.mongodb.com/manual/reference/command/listCollections/
///
cursor list_collections(const client_session& session,
bsoncxx::document::view_or_value filter = {});
///
/// Enumerates the collection names in this database.
///
/// @param filter
/// An optional query expression to filter the returned collection names.
///
/// @return std::vector<std::string> containing the collection names.
///
/// @throws mongocxx::operation_exception if the underlying 'listCollections'
/// command fails.
///
/// @see https://docs.mongodb.com/manual/reference/command/listCollections/
///
std::vector<std::string> list_collection_names(bsoncxx::document::view_or_value filter = {});
///
/// Enumerates the collection names in this database.
///
/// @param session
/// The mongocxx::client_session with which to perform the aggregation.
/// @param filter
/// An optional query expression to filter the returned collection names.
///
/// @return std::vector<std::string> containing the collection names.
///
/// @throws mongocxx::operation_exception if the underlying 'listCollections'
/// command fails.
///
/// @see https://docs.mongodb.com/manual/reference/command/listCollections/
///
std::vector<std::string> list_collection_names(const client_session& session,
bsoncxx::document::view_or_value filter = {});
///
/// @}
///
///
/// Get the name of this database.
///
/// @return the name of this database.
///
stdx::string_view name() const;
///
/// Sets the read_concern for this database.
///
/// @note Modifications at this level do not affect existing collection instances that have come
/// from this database, but do affect new ones. New collections will receive a copy of the
/// new read_concern for this database upon instantiation.
///
/// @param rc
/// The new @c read_concern
///
/// @see https://docs.mongodb.com/manual/reference/read-concern/
///
void read_concern(class read_concern rc);
///
/// The current read concern for this database.
///
/// If the read_concern is not explicitly set on this database object, it inherits the
/// read_concern from its parent client object.
///
/// @return the current read_concern
///
class read_concern read_concern() const;
///
/// Sets the read_preference for this database.
///
/// @note Modifications at this level do not affect existing collection instances that have come
/// from this database, but do affect new ones. New collections will receive a copy of the
/// new read_preference for this database upon instantiation.
///
/// @see https://docs.mongodb.com/manual/core/read-preference/
///
/// @param rp the new read_preference.
///
void read_preference(class read_preference rp);
///
/// The current read preference for this database.
///
/// @see https://docs.mongodb.com/manual/core/read-preference/
///
/// @return the current read_preference
///
class read_preference read_preference() const;
///
/// Sets the write_concern for this database.
///
/// @note Modifications at this level do not affect existing collection instances that have come
/// from this database, but do affect new ones as new collections will receive a copy of the
/// write_concern of this database upon instantiation.
///
void write_concern(class write_concern wc);
///
/// The current write_concern for this database.
///
/// @return the current write_concern
///
class write_concern write_concern() const;
///
/// Access a collection (logical grouping of documents) within this database.
///
/// @param name the name of the collection to get.
///
/// @return the collection.
///
class collection collection(bsoncxx::string::view_or_value name) const;
///
/// Allows the db["collection_name"] syntax to be used to access a collection within this
/// database.
///
/// @param name the name of the collection to get.
///
/// @return the collection.
///
MONGOCXX_INLINE class collection operator[](bsoncxx::string::view_or_value name) const;
///
/// Access a GridFS bucket within this database.
///
/// @param options
/// The options for the bucket.
///
/// @return
/// The GridFS bucket.
///
/// @note
/// See the class comment for `gridfs::bucket` for more information about GridFS.
///
/// @throws mongocxx::logic_error if `options` are invalid.
///
class gridfs::bucket gridfs_bucket(
const options::gridfs::bucket& options = options::gridfs::bucket()) const;
///
/// @{
///
/// Gets a change stream on this database with an empty pipeline.
/// Change streams are only supported with a "majority" read concern or no read concern.
///
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this database.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const options::change_stream& options = {});
///
/// @param session
/// The mongocxx::client_session with which to perform the watch operation.
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this database.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const client_session& session, const options::change_stream& options = {});
///
/// Gets a change stream on this database.
/// Change streams are only supported with a "majority" read concern or no read concern.
///
/// @param pipe
/// The aggregation pipeline to be used on the change notifications.
/// Only a subset of pipeline operations are supported for change streams. For more
/// information see the change streams documentation.
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this database.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const pipeline& pipe, const options::change_stream& options = {});
///
/// Gets a change stream on this database.
///
/// @param session
/// The mongocxx::client_session with which to perform the watch operation.
/// @param pipe
/// The aggregation pipeline to be used on the change notifications.
/// @param options
/// The options to use when creating the change stream.
///
/// @return
/// A change stream on this database.
///
/// @see https://docs.mongodb.com/manual/changeStreams/
///
change_stream watch(const client_session& session,
const pipeline& pipe,
const options::change_stream& options = {});
///
/// @}
///
private:
friend class client;
friend class collection;
MONGOCXX_PRIVATE database(const class client& client, bsoncxx::string::view_or_value name);
MONGOCXX_PRIVATE cursor _aggregate(const client_session* session,
const pipeline& pipeline,
const options::aggregate& options);
MONGOCXX_PRIVATE bsoncxx::document::value _run_command(
const client_session* session, bsoncxx::document::view_or_value command);
MONGOCXX_PRIVATE class collection _create_collection(
const client_session* session,
stdx::string_view name,
bsoncxx::document::view_or_value collection_options,
const stdx::optional<class write_concern>& write_concern);
MONGOCXX_PRIVATE class collection _create_collection_deprecated(
const client_session* session,
bsoncxx::string::view_or_value name,
const options::create_collection_deprecated& collection_options,
const stdx::optional<class write_concern>& write_concern);
MONGOCXX_PRIVATE cursor _list_collections(const client_session* session,
bsoncxx::document::view_or_value filter);
MONGOCXX_PRIVATE std::vector<std::string> _list_collection_names(
const client_session* session, bsoncxx::document::view_or_value filter);
MONGOCXX_PRIVATE void _drop(
const client_session* session,
const bsoncxx::stdx::optional<mongocxx::write_concern>& write_concern);
MONGOCXX_PRIVATE change_stream _watch(const client_session* session,
const pipeline& pipe,
const options::change_stream& options);
class MONGOCXX_PRIVATE impl;
MONGOCXX_PRIVATE impl& _get_impl();
MONGOCXX_PRIVATE const impl& _get_impl() const;
std::unique_ptr<impl> _impl;
};
MONGOCXX_INLINE collection database::operator[](bsoncxx::string::view_or_value name) const {
return collection(name);
}
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,109 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/oid.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver fails to execute a MongoDB command.
///
/// @see "CommandFailedEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst
///
class MONGOCXX_API command_failed_event {
public:
MONGOCXX_PRIVATE explicit command_failed_event(const void* event);
///
/// Destroys a command_failed_event.
///
~command_failed_event();
///
/// Returns the servers reply to the failed operation.
///
/// @return The failure.
///
bsoncxx::document::view failure() const;
///
/// Returns the name of the command.
///
/// @return The command name.
///
bsoncxx::stdx::string_view command_name() const;
///
/// Returns the duration of the failed operation.
///
/// @return The duration in microseconds.
///
std::int64_t duration() const;
///
/// Returns the request id.
///
/// @return The request id.
///
std::int64_t request_id() const;
///
/// Returns the operation id.
///
/// @return The operation id.
///
std::int64_t operation_id() const;
///
/// Optionally returns the service id.
///
/// @return No contained value, or contains the service id if load balancing is enabled.
///
bsoncxx::stdx::optional<bsoncxx::oid> service_id() const;
///
/// Returns the host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the port.
///
/// @return The port.
///
std::uint16_t port() const;
private:
const void* _failed_event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,109 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/oid.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver begins executing a MongoDB command.
///
/// @see "CommandStartedEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst
///
class MONGOCXX_API command_started_event {
public:
MONGOCXX_PRIVATE explicit command_started_event(const void* event);
///
/// Destroys a command_started_event.
///
~command_started_event();
///
/// Returns the command that has been started.
///
/// @return The command.
///
bsoncxx::document::view command() const;
///
/// Returns the name of the database.
///
/// @return The database name.
///
bsoncxx::stdx::string_view database_name() const;
///
/// Returns the name of the command.
///
/// @return The command name.
///
bsoncxx::stdx::string_view command_name() const;
///
/// Returns the request id.
///
/// @return The request id.
///
std::int64_t request_id() const;
///
/// Returns the operation id.
///
/// @return The operation id.
///
std::int64_t operation_id() const;
///
/// Optionally returns the service id.
///
/// @return No contained value, or contains the service id if load balancing is enabled.
///
bsoncxx::stdx::optional<bsoncxx::oid> service_id() const;
///
/// Returns the host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the port.
///
/// @return The port.
///
std::uint16_t port() const;
private:
const void* _started_event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,109 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <memory>
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/oid.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver successfully executes a MongoDB command.
///
/// @see "CommandSucceededEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/command-monitoring/command-monitoring.rst
///
class MONGOCXX_API command_succeeded_event {
public:
MONGOCXX_PRIVATE explicit command_succeeded_event(const void* event);
///
/// Destroys a command_succeeded_event.
///
~command_succeeded_event();
///
/// Returns the server reply for the succeeded operation.
///
/// @return The reply.
///
bsoncxx::document::view reply() const;
///
/// Returns the name of the command.
///
/// @return The command name.
///
bsoncxx::stdx::string_view command_name() const;
///
/// Returns the duration of the successful operation.
///
/// @return The duration in microseconds.
///
std::int64_t duration() const;
///
/// Returns the request id.
///
/// @return The request id.
///
std::int64_t request_id() const;
///
/// Returns the operation id.
///
/// @return The operation id.
///
std::int64_t operation_id() const;
///
/// Optionally returns the service id.
///
/// @return No contained value, or contains the service id if load balancing is enabled.
///
bsoncxx::stdx::optional<bsoncxx::oid> service_id() const;
///
/// Returns the host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the port.
///
/// @return The port.
///
std::uint16_t port() const;
private:
const void* _succeeded_event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,85 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver failed to send an "hello" command to check the
/// status of a server.
///
/// @see "ServerHeartbeatFailedEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst
///
class MONGOCXX_API heartbeat_failed_event {
public:
MONGOCXX_PRIVATE explicit heartbeat_failed_event(const void* event);
///
/// Destroys a heartbeat_failed_event.
///
~heartbeat_failed_event();
///
/// Returns the failed operation's error message.
///
/// @return The message.
///
std::string message() const;
///
/// Returns the duration of the failed operation.
///
/// @return The duration in microseconds.
///
std::int64_t duration() const;
///
/// Returns the host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the port.
///
/// @return The port.
///
std::uint16_t port() const;
///
/// Returns a boolean indicating whether this heartbeat event is from an awaitable hello.
///
/// @return A boolean.
///
bool awaited() const;
private:
const void* _failed_event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,71 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver begins executing a "hello" command to check the
/// status of a server.
///
/// @see "ServerHeartbeatStartedEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst
///
class MONGOCXX_API heartbeat_started_event {
public:
MONGOCXX_PRIVATE explicit heartbeat_started_event(const void* event);
///
/// Destroys a heartbeat_started_event.
///
~heartbeat_started_event();
///
/// Returns the host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the port.
///
/// @return The port.
///
std::uint16_t port() const;
///
/// Returns a boolean indicating whether this heartbeat event is from an awaitable hello.
///
/// @return A boolean.
///
bool awaited() const;
private:
const void* _started_event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,86 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/document/view.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver completes a "hello" command to check the status
/// of a server.
///
/// @see "ServerHeartbeatSucceededEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst
///
class MONGOCXX_API heartbeat_succeeded_event {
public:
MONGOCXX_PRIVATE explicit heartbeat_succeeded_event(const void* event);
///
/// Destroys a heartbeat_succeeded_event.
///
~heartbeat_succeeded_event();
///
/// Returns the server reply for the succeeded operation.
///
/// @return The reply.
///
bsoncxx::document::view reply() const;
///
/// Returns the duration of the successful operation.
///
/// @return The duration in microseconds.
///
std::int64_t duration() const;
///
/// Returns the host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the port.
///
/// @return The port.
///
std::uint16_t port() const;
///
/// Returns a boolean indicating whether this heartbeat event is from an awaitable hello.
///
/// @return A boolean.
///
bool awaited() const;
private:
const void* _succeeded_event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,87 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/oid.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/events/server_description.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver observes a change in the status of a server it is
/// connected to.
///
/// @see "ServerDescriptionChangedEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst
///
class MONGOCXX_API server_changed_event {
public:
MONGOCXX_PRIVATE explicit server_changed_event(const void* event);
///
/// Destroys a server_changed_event.
///
~server_changed_event();
///
/// Returns the server host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the server port.
///
/// @return The port.
///
std::uint16_t port() const;
///
/// An opaque id, unique to this topology for this mongocxx::client or mongocxx::pool.
///
/// @return The id.
///
const bsoncxx::oid topology_id() const;
///
/// The server's description before it changed.
///
/// @return The server_description.
///
const server_description previous_description() const;
///
/// The server's description after it changed.
///
/// @return The server_description.
///
const server_description new_description() const;
private:
const void* _event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

View File

@@ -0,0 +1,72 @@
// Copyright 2018-present MongoDB Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include <bsoncxx/oid.hpp>
#include <bsoncxx/stdx/string_view.hpp>
#include <mongocxx/config/prelude.hpp>
namespace mongocxx {
MONGOCXX_INLINE_NAMESPACE_BEGIN
namespace events {
///
/// An event notification sent when the driver stops monitoring a MongoDB server and removes it
/// from the topology description.
///
/// @see "ServerClosedEvent" in
/// https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring-monitoring.rst
///
class MONGOCXX_API server_closed_event {
public:
MONGOCXX_PRIVATE explicit server_closed_event(const void* event);
///
/// Destroys a server_closed_event.
///
~server_closed_event();
///
/// Returns the server host name.
///
/// @return The host name.
///
bsoncxx::stdx::string_view host() const;
///
/// Returns the server port.
///
/// @return The port.
///
std::uint16_t port() const;
///
/// An opaque id, unique to this topology for this mongocxx::client or mongocxx::pool.
///
/// @return The id.
///
const bsoncxx::oid topology_id() const;
private:
const void* _event;
};
} // namespace events
MONGOCXX_INLINE_NAMESPACE_END
} // namespace mongocxx
#include <mongocxx/config/postlude.hpp>

Some files were not shown because too many files have changed in this diff Show More