未验证 提交 9be41447 编写于 作者: C chentianyu03 提交者: GitHub

Copy boost optional to Paddle (#34780)

* copy boost optional.hpp to paddle

* copy boost optional.hpp to paddle

* move directions

* del fluid/utils

* modify .hpp to .h

* move directions

* modify to paddle::optional

* add modification description

* format code stype for the files in paddle/utils

* format code stype
上级 f1c1d9e0
...@@ -36,8 +36,8 @@ static inline bool SeqOnlyAllReduceOps(const BuildStrategy &strategy) { ...@@ -36,8 +36,8 @@ static inline bool SeqOnlyAllReduceOps(const BuildStrategy &strategy) {
!strategy.enable_parallel_graph_; !strategy.enable_parallel_graph_;
} }
static inline void ConvertDefaultValue(boost::optional<bool> *default_value) { static inline void ConvertDefaultValue(paddle::optional<bool> *default_value) {
if (*default_value == boost::none) { if (*default_value == paddle::none) {
*default_value = true; *default_value = true;
} }
} }
...@@ -247,7 +247,7 @@ class ParallelExecutorPassBuilder : public ir::PassBuilder { ...@@ -247,7 +247,7 @@ class ParallelExecutorPassBuilder : public ir::PassBuilder {
} }
} }
void AppendPassWithCheck(const boost::optional<bool> &append_pass, void AppendPassWithCheck(const paddle::optional<bool> &append_pass,
const std::string &pass_name) { const std::string &pass_name) {
AppendPassWithCheck(append_pass == true, pass_name); AppendPassWithCheck(append_pass == true, pass_name);
} }
......
...@@ -112,8 +112,8 @@ struct BuildStrategy { ...@@ -112,8 +112,8 @@ struct BuildStrategy {
bool enable_auto_fusion_{false}; bool enable_auto_fusion_{false};
// Fuse_all_optimizer_ops and fuse_all_reduce_ops require that gradients // Fuse_all_optimizer_ops and fuse_all_reduce_ops require that gradients
// should not be sparse types // should not be sparse types
boost::optional<bool> fuse_all_optimizer_ops_{false}; paddle::optional<bool> fuse_all_optimizer_ops_{false};
boost::optional<bool> fuse_all_reduce_ops_{boost::none}; paddle::optional<bool> fuse_all_reduce_ops_{boost::none};
// fuse_relu_depthwise_conv can fuse the `relu -> // fuse_relu_depthwise_conv can fuse the `relu ->
// depthwise_conv` // depthwise_conv`
bool fuse_relu_depthwise_conv_{false}; bool fuse_relu_depthwise_conv_{false};
...@@ -121,7 +121,7 @@ struct BuildStrategy { ...@@ -121,7 +121,7 @@ struct BuildStrategy {
// faster. Because fusing broadcast OP equals delaying the execution of all // faster. Because fusing broadcast OP equals delaying the execution of all
// broadcast Ops, in this case, all nccl streams are used only for reduce // broadcast Ops, in this case, all nccl streams are used only for reduce
// operations for a period of time. // operations for a period of time.
boost::optional<bool> fuse_broadcast_ops_{boost::none}; paddle::optional<bool> fuse_broadcast_ops_{boost::none};
// replace batch_norm with sync_batch_norm. // replace batch_norm with sync_batch_norm.
bool sync_batch_norm_{false}; bool sync_batch_norm_{false};
...@@ -135,7 +135,7 @@ struct BuildStrategy { ...@@ -135,7 +135,7 @@ struct BuildStrategy {
// By default, memory_optimize would be opened if gc is disabled, and // By default, memory_optimize would be opened if gc is disabled, and
// be closed if gc is enabled. // be closed if gc is enabled.
// Users can forcely enable/disable memory_optimize by setting True/False. // Users can forcely enable/disable memory_optimize by setting True/False.
boost::optional<bool> memory_optimize_{boost::none}; paddle::optional<bool> memory_optimize_{boost::none};
// Turn on inplace by default. // Turn on inplace by default.
bool enable_inplace_{true}; bool enable_inplace_{true};
......
...@@ -74,11 +74,11 @@ bool IsReachable(ir::Graph* graph, Node* from, Node* to) { ...@@ -74,11 +74,11 @@ bool IsReachable(ir::Graph* graph, Node* from, Node* to) {
} }
template <typename T> template <typename T>
boost::optional<T> HasAttribute(const Node& op, const std::string& attr) { paddle::optional<T> HasAttribute(const Node& op, const std::string& attr) {
if (op.Op()->HasAttr(attr)) if (op.Op()->HasAttr(attr))
return BOOST_GET_CONST(T, op.Op()->GetAttr(attr)); return BOOST_GET_CONST(T, op.Op()->GetAttr(attr));
else else
return boost::none; return paddle::none;
} }
ResidualConnectionMKLDNNFusePass::ResidualConnectionMKLDNNFusePass() { ResidualConnectionMKLDNNFusePass::ResidualConnectionMKLDNNFusePass() {
......
...@@ -40,7 +40,7 @@ using GraphWithStats = std::pair<ir::Graph*, int>; ...@@ -40,7 +40,7 @@ using GraphWithStats = std::pair<ir::Graph*, int>;
void CorrectGraphEdges(Graph* graph, Node* from, Node* to); void CorrectGraphEdges(Graph* graph, Node* from, Node* to);
bool IsReachable(ir::Graph* graph, Node* from, Node* to); bool IsReachable(ir::Graph* graph, Node* from, Node* to);
boost::optional<Node*> HasBias(const Node& op, const std::string& bias_name); paddle::optional<Node*> HasBias(const Node& op, const std::string& bias_name);
class ResidualConnectionMKLDNNFusePass : public FusePassBase { class ResidualConnectionMKLDNNFusePass : public FusePassBase {
private: private:
......
...@@ -27,6 +27,8 @@ limitations under the License. */ ...@@ -27,6 +27,8 @@ limitations under the License. */
#include "paddle/fluid/framework/tensor_util.h" #include "paddle/fluid/framework/tensor_util.h"
#include "paddle/fluid/memory/malloc.h" #include "paddle/fluid/memory/malloc.h"
#include "paddle/fluid/memory/memcpy.h" #include "paddle/fluid/memory/memcpy.h"
#include "paddle/utils/none.h"
#include "paddle/utils/optional.h"
namespace paddle { namespace paddle {
namespace framework { namespace framework {
...@@ -195,10 +197,10 @@ class Vector { ...@@ -195,10 +197,10 @@ class Vector {
std::mutex &Mutex() const { return mtx_; } std::mutex &Mutex() const { return mtx_; }
boost::optional<platform::CUDAPlace> CUDAPlace() const { paddle::optional<platform::CUDAPlace> CUDAPlace() const {
return gpu_ == nullptr return gpu_ == nullptr
? boost::none ? paddle::none
: boost::optional<platform::CUDAPlace>( : paddle::optional<platform::CUDAPlace>(
BOOST_GET_CONST(platform::CUDAPlace, gpu_->place())); BOOST_GET_CONST(platform::CUDAPlace, gpu_->place()));
} }
...@@ -389,7 +391,7 @@ class Vector { ...@@ -389,7 +391,7 @@ class Vector {
auto &mtx = m_.Data().Mutex(); auto &mtx = m_.Data().Mutex();
std::lock_guard<std::mutex> guard(mtx); std::lock_guard<std::mutex> guard(mtx);
auto cuda_place = m_.Data().CUDAPlace(); auto cuda_place = m_.Data().CUDAPlace();
if (cuda_place == boost::none || if (cuda_place == paddle::none ||
cuda_place == BOOST_GET(platform::CUDAPlace, place)) { cuda_place == BOOST_GET(platform::CUDAPlace, place)) {
return m_.Data().CUDAData(place); return m_.Data().CUDAData(place);
} }
...@@ -405,7 +407,7 @@ class Vector { ...@@ -405,7 +407,7 @@ class Vector {
auto &mtx = m_.Data().Mutex(); auto &mtx = m_.Data().Mutex();
std::lock_guard<std::mutex> guard(mtx); std::lock_guard<std::mutex> guard(mtx);
auto cuda_place = m_.Data().CUDAPlace(); auto cuda_place = m_.Data().CUDAPlace();
if (cuda_place == boost::none || if (cuda_place == paddle::none ||
cuda_place == BOOST_GET(platform::CUDAPlace, place)) { cuda_place == BOOST_GET(platform::CUDAPlace, place)) {
return m_.MutableData()->CUDAMutableData(place); return m_.MutableData()->CUDAMutableData(place);
} }
......
...@@ -22,6 +22,7 @@ limitations under the License. */ ...@@ -22,6 +22,7 @@ limitations under the License. */
#include "paddle/fluid/framework/op_version_proto.h" #include "paddle/fluid/framework/op_version_proto.h"
#include "paddle/fluid/platform/enforce.h" #include "paddle/fluid/platform/enforce.h"
#include "paddle/utils/none.h"
namespace paddle { namespace paddle {
namespace framework { namespace framework {
...@@ -42,7 +43,7 @@ using OpAttrVariantT = ...@@ -42,7 +43,7 @@ using OpAttrVariantT =
std::vector<int32_t>, /* AttrType::INTS */ std::vector<int32_t>, /* AttrType::INTS */
std::vector<int64_t>, /* AttrType::LONGS */ std::vector<int64_t>, /* AttrType::LONGS */
std::vector<std::string>, /* AttrType::STRINGS */ std::vector<std::string>, /* AttrType::STRINGS */
boost::none_t /* None */ paddle::none_t /* None */
>; >;
struct OpUpdateInfo { struct OpUpdateInfo {
...@@ -51,7 +52,7 @@ struct OpUpdateInfo { ...@@ -51,7 +52,7 @@ struct OpUpdateInfo {
struct OpAttrInfo : OpUpdateInfo { struct OpAttrInfo : OpUpdateInfo {
OpAttrInfo(const std::string& name, const std::string& remark, OpAttrInfo(const std::string& name, const std::string& remark,
const OpAttrVariantT& default_value = boost::none) const OpAttrVariantT& default_value = paddle::none)
: name_{name}, default_value_{default_value}, remark_{remark} {} : name_{name}, default_value_{default_value}, remark_{remark} {}
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
......
...@@ -161,5 +161,5 @@ REGISTER_OP_VERSION(flip) ...@@ -161,5 +161,5 @@ REGISTER_OP_VERSION(flip)
R"ROC(Upgrade flip, add new attr [axis] and delete attr [dims].)ROC", R"ROC(Upgrade flip, add new attr [axis] and delete attr [dims].)ROC",
paddle::framework::compatible::OpVersionDesc() paddle::framework::compatible::OpVersionDesc()
.NewAttr("axis", "The added attr 'axis' doesn't set default value.", .NewAttr("axis", "The added attr 'axis' doesn't set default value.",
boost::none) paddle::none)
.DeleteAttr("dims", "The attr 'dims' is deleted.")); .DeleteAttr("dims", "The attr 'dims' is deleted."));
...@@ -137,7 +137,7 @@ class ConcatPrimitiveFactory { ...@@ -137,7 +137,7 @@ class ConcatPrimitiveFactory {
private: private:
std::vector<memory::desc> srcs_d; std::vector<memory::desc> srcs_d;
std::vector<mkldnn::memory> srcs; std::vector<mkldnn::memory> srcs;
boost::optional<mkldnn::memory> dst_mem; paddle::optional<mkldnn::memory> dst_mem;
}; };
template <typename T> template <typename T>
......
...@@ -893,7 +893,7 @@ class ConvMKLDNNOpKernel : public paddle::framework::OpKernel<T> { ...@@ -893,7 +893,7 @@ class ConvMKLDNNOpKernel : public paddle::framework::OpKernel<T> {
fuse_residual_conn, propagation, output_shift_scale, sum_scale); fuse_residual_conn, propagation, output_shift_scale, sum_scale);
} else { } else {
conv_pd = handler->AcquireConvolutionPrimitiveDescriptor( conv_pd = handler->AcquireConvolutionPrimitiveDescriptor(
src_md, weights_md, boost::none, dst_md, strides, dilations, src_md, weights_md, paddle::none, dst_md, strides, dilations,
paddings, mkldnn_engine, fuse_activation, fuse_alpha, fuse_beta, paddings, mkldnn_engine, fuse_activation, fuse_alpha, fuse_beta,
fuse_residual_conn, propagation, output_shift_scale, sum_scale); fuse_residual_conn, propagation, output_shift_scale, sum_scale);
} }
......
...@@ -89,7 +89,8 @@ class FCPrimitiveFactory { ...@@ -89,7 +89,8 @@ class FCPrimitiveFactory {
// descriptor has been divided into separate cases, based on the number // descriptor has been divided into separate cases, based on the number
// of input dimensions. // of input dimensions.
size_t input_dim_num = input->dims().size(); size_t input_dim_num = input->dims().size();
boost::optional<mkldnn::inner_product_forward::primitive_desc> fc_prim_desc; paddle::optional<mkldnn::inner_product_forward::primitive_desc>
fc_prim_desc;
memory::desc usr_weights_desc = {}; memory::desc usr_weights_desc = {};
switch (input_dim_num) { switch (input_dim_num) {
case 2: case 2:
...@@ -545,11 +546,11 @@ class FCPrimitiveFactory { ...@@ -545,11 +546,11 @@ class FCPrimitiveFactory {
private: private:
const mkldnn::engine& engine_; const mkldnn::engine& engine_;
boost::optional<memory> input_; paddle::optional<memory> input_;
boost::optional<memory> output_; paddle::optional<memory> output_;
std::shared_ptr<memory> bias_; std::shared_ptr<memory> bias_;
std::shared_ptr<memory> weights_; std::shared_ptr<memory> weights_;
boost::optional<inner_product_forward> fc_; paddle::optional<inner_product_forward> fc_;
}; };
// Attempt to fetch cached primitive factory based on provided parameters // Attempt to fetch cached primitive factory based on provided parameters
......
...@@ -290,10 +290,10 @@ class MulPrimitiveFactory { ...@@ -290,10 +290,10 @@ class MulPrimitiveFactory {
} }
const mkldnn::engine &engine_; const mkldnn::engine &engine_;
boost::optional<memory> x_input_; paddle::optional<memory> x_input_;
boost::optional<memory> y_input_; paddle::optional<memory> y_input_;
boost::optional<memory> output_; paddle::optional<memory> output_;
boost::optional<inner_product_forward> mul_; paddle::optional<inner_product_forward> mul_;
static constexpr bool is_int8_ = static constexpr bool is_int8_ =
std::is_same<XT, int8_t>::value || std::is_same<XT, uint8_t>::value; std::is_same<XT, int8_t>::value || std::is_same<XT, uint8_t>::value;
}; };
......
...@@ -123,7 +123,7 @@ class SeqConcatGradKernel : public framework::OpKernel<T> { ...@@ -123,7 +123,7 @@ class SeqConcatGradKernel : public framework::OpKernel<T> {
} }
std::vector<framework::Tensor> sliced_x; std::vector<framework::Tensor> sliced_x;
std::vector<boost::optional<framework::Tensor>> sliced_dx; std::vector<paddle::optional<framework::Tensor>> sliced_dx;
for (size_t i = 1; i < xs[0]->lod()[0].size(); ++i) { for (size_t i = 1; i < xs[0]->lod()[0].size(); ++i) {
for (size_t j = 0; j < xs.size(); ++j) { for (size_t j = 0; j < xs.size(); ++j) {
...@@ -145,7 +145,7 @@ class SeqConcatGradKernel : public framework::OpKernel<T> { ...@@ -145,7 +145,7 @@ class SeqConcatGradKernel : public framework::OpKernel<T> {
if (dx) { if (dx) {
sliced_dx.emplace_back(dx->Slice(prev_lod, next_lod)); sliced_dx.emplace_back(dx->Slice(prev_lod, next_lod));
} else { } else {
sliced_dx.emplace_back(boost::none); sliced_dx.emplace_back(paddle::none);
} }
} }
} }
......
...@@ -1426,7 +1426,7 @@ class ConvMKLDNNTemplateHandler : public MKLDNNHandler { ...@@ -1426,7 +1426,7 @@ class ConvMKLDNNTemplateHandler : public MKLDNNHandler {
std::shared_ptr<typename forward_t::primitive_desc> std::shared_ptr<typename forward_t::primitive_desc>
AcquireConvolutionPrimitiveDescriptor( AcquireConvolutionPrimitiveDescriptor(
const mkldnn::memory::desc& src, const mkldnn::memory::desc& weights, const mkldnn::memory::desc& src, const mkldnn::memory::desc& weights,
boost::optional<const mkldnn::memory::desc&> bias, paddle::optional<const mkldnn::memory::desc&> bias,
const mkldnn::memory::desc& dst, const std::vector<int64_t>& strides, const mkldnn::memory::desc& dst, const std::vector<int64_t>& strides,
const std::vector<int64_t>& dilations, const std::vector<int64_t>& dilations,
const std::vector<int64_t>& paddings, const mkldnn::engine& engine, const std::vector<int64_t>& paddings, const mkldnn::engine& engine,
......
...@@ -73,6 +73,7 @@ limitations under the License. */ ...@@ -73,6 +73,7 @@ limitations under the License. */
#include "paddle/fluid/platform/profiler.h" #include "paddle/fluid/platform/profiler.h"
#include "paddle/fluid/pybind/cuda_streams_py.h" #include "paddle/fluid/pybind/cuda_streams_py.h"
#include "paddle/fluid/pybind/io.h" #include "paddle/fluid/pybind/io.h"
#include "paddle/utils/none.h"
#ifdef PADDLE_WITH_ASCEND #ifdef PADDLE_WITH_ASCEND
#include "paddle/fluid/pybind/ascend_wrapper_py.h" #include "paddle/fluid/pybind/ascend_wrapper_py.h"
#endif #endif
...@@ -2910,7 +2911,7 @@ All parameter, weight, gradient are variables in Paddle. ...@@ -2910,7 +2911,7 @@ All parameter, weight, gradient are variables in Paddle.
.def_property("fuse_broadcast_ops", .def_property("fuse_broadcast_ops",
[](const BuildStrategy &self) { [](const BuildStrategy &self) {
return self.fuse_broadcast_ops_ == true || return self.fuse_broadcast_ops_ == true ||
self.fuse_broadcast_ops_ == boost::none; self.fuse_broadcast_ops_ == paddle::none;
}, },
[](BuildStrategy &self, bool b) { [](BuildStrategy &self, bool b) {
PADDLE_ENFORCE_NE(self.IsFinalized(), true, PADDLE_ENFORCE_NE(self.IsFinalized(), true,
...@@ -2940,7 +2941,7 @@ All parameter, weight, gradient are variables in Paddle. ...@@ -2940,7 +2941,7 @@ All parameter, weight, gradient are variables in Paddle.
.def_property("fuse_all_optimizer_ops", .def_property("fuse_all_optimizer_ops",
[](const BuildStrategy &self) { [](const BuildStrategy &self) {
return self.fuse_all_optimizer_ops_ == true || return self.fuse_all_optimizer_ops_ == true ||
self.fuse_all_optimizer_ops_ == boost::none; self.fuse_all_optimizer_ops_ == paddle::none;
}, },
[](BuildStrategy &self, bool b) { [](BuildStrategy &self, bool b) {
PADDLE_ENFORCE_NE(self.IsFinalized(), true, PADDLE_ENFORCE_NE(self.IsFinalized(), true,
...@@ -2989,7 +2990,7 @@ All parameter, weight, gradient are variables in Paddle. ...@@ -2989,7 +2990,7 @@ All parameter, weight, gradient are variables in Paddle.
[](BuildStrategy &self, const py::handle &value) { [](BuildStrategy &self, const py::handle &value) {
auto *py_obj = value.ptr(); auto *py_obj = value.ptr();
if (py_obj == nullptr || py_obj == Py_None) { if (py_obj == nullptr || py_obj == Py_None) {
self.memory_optimize_ = boost::none; self.memory_optimize_ = paddle::none;
} else if (PyBool_Check(py_obj)) { } else if (PyBool_Check(py_obj)) {
self.memory_optimize_ = (py_obj == Py_True); self.memory_optimize_ = (py_obj == Py_True);
} else { } else {
...@@ -3046,7 +3047,7 @@ All parameter, weight, gradient are variables in Paddle. ...@@ -3046,7 +3047,7 @@ All parameter, weight, gradient are variables in Paddle.
"fuse_all_reduce_ops", "fuse_all_reduce_ops",
[](const BuildStrategy &self) { [](const BuildStrategy &self) {
return self.fuse_all_reduce_ops_ == true || return self.fuse_all_reduce_ops_ == true ||
self.fuse_all_reduce_ops_ == boost::none; self.fuse_all_reduce_ops_ == paddle::none;
}, },
[](BuildStrategy &self, bool b) { self.fuse_all_reduce_ops_ = b; }) [](BuildStrategy &self, bool b) { self.fuse_all_reduce_ops_ = b; })
.def_property("enable_backward_optimizer_op_deps", .def_property("enable_backward_optimizer_op_deps",
......
...@@ -44,7 +44,7 @@ namespace reader = operators::reader; ...@@ -44,7 +44,7 @@ namespace reader = operators::reader;
// Check whether the tensor shape matches the VarDesc shape // Check whether the tensor shape matches the VarDesc shape
// Return the different shape if exists // Return the different shape if exists
static boost::optional<std::vector<int64_t>> DiffTensorShapeWithVarDesc( static paddle::optional<std::vector<int64_t>> DiffTensorShapeWithVarDesc(
const framework::LoDTensor &tensor, const framework::VarDesc &var_desc, const framework::LoDTensor &tensor, const framework::VarDesc &var_desc,
size_t num_places) { size_t num_places) {
auto tensor_shape = tensor.dims(); auto tensor_shape = tensor.dims();
...@@ -56,7 +56,7 @@ static boost::optional<std::vector<int64_t>> DiffTensorShapeWithVarDesc( ...@@ -56,7 +56,7 @@ static boost::optional<std::vector<int64_t>> DiffTensorShapeWithVarDesc(
if (desc_shape.size() != 0) { // Tensor rank = 0 but desc does not match if (desc_shape.size() != 0) { // Tensor rank = 0 but desc does not match
return framework::vectorize<int64_t>(tensor_shape); return framework::vectorize<int64_t>(tensor_shape);
} else { } else {
return boost::none; return paddle::none;
} }
} }
...@@ -92,7 +92,7 @@ static boost::optional<std::vector<int64_t>> DiffTensorShapeWithVarDesc( ...@@ -92,7 +92,7 @@ static boost::optional<std::vector<int64_t>> DiffTensorShapeWithVarDesc(
} }
} }
return boost::none; return paddle::none;
} }
static const std::shared_ptr<reader::LoDTensorBlockingQueue> &GetQueue( static const std::shared_ptr<reader::LoDTensorBlockingQueue> &GetQueue(
......
//This file copy from boost/any.hpp and boost version: 1.41.0 // This file copy from boost/any.hpp and boost version: 1.41.0
//Modified the following points: // Modified the following points:
//1. modify namespace from boost::any to paddle::any // 1. modify namespace from boost::any to paddle::any
//2. remove the depending boost header files // 2. remove the depending boost header files
//3. remove/modify some macro // 3. remove/modify some macro
// See http://www.boost.org/libs/any for Documentation. // See http://www.boost.org/libs/any for Documentation.
...@@ -17,210 +17,157 @@ ...@@ -17,210 +17,157 @@
// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 // where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95
#include <algorithm> #include <algorithm>
#include <typeinfo>
#include <type_traits> #include <type_traits>
#include <typeinfo>
// See boost/python/type_id.hpp // See boost/python/type_id.hpp
// TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp // TODO: add BOOST_TYPEID_COMPARE_BY_NAME to config.hpp
# if (defined(__GNUC__) && __GNUC__ >= 3) \ #if (defined(__GNUC__) && __GNUC__ >= 3) || defined(_AIX) || \
|| defined(_AIX) \ (defined(__sgi) && defined(__host_mips)) || \
|| ( defined(__sgi) && defined(__host_mips)) \ (defined(__hpux) && defined(__HP_aCC)) || \
|| (defined(__hpux) && defined(__HP_aCC)) \ (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC))
|| (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) #define BOOST_AUX_ANY_TYPE_ID_NAME
# define BOOST_AUX_ANY_TYPE_ID_NAME
#include <cstring> #include <cstring>
# endif #endif
namespace paddle
{
class any
{
public: // structors
any()
: content(0)
{
}
template<typename ValueType> namespace paddle {
any(const ValueType & value) class any {
: content(new holder<ValueType>(value)) public: // structors
{ any() : content(0) {}
}
any(const any & other) template <typename ValueType>
: content(other.content ? other.content->clone() : 0) any(const ValueType &value) : content(new holder<ValueType>(value)) {}
{
}
~any() any(const any &other) : content(other.content ? other.content->clone() : 0) {}
{
delete content;
}
public: // modifiers ~any() { delete content; }
any & swap(any & rhs) public: // modifiers
{ any &swap(any &rhs) {
std::swap(content, rhs.content); std::swap(content, rhs.content);
return *this; return *this;
} }
template<typename ValueType> template <typename ValueType>
any & operator=(const ValueType & rhs) any &operator=(const ValueType &rhs) {
{ any(rhs).swap(*this);
any(rhs).swap(*this); return *this;
return *this; }
}
any & operator=(any rhs) any &operator=(any rhs) {
{ rhs.swap(*this);
rhs.swap(*this); return *this;
return *this; }
}
public: // queries public: // queries
bool empty() const { return !content; }
bool empty() const const std::type_info &type() const {
{ return content ? content->type() : typeid(void);
return !content; }
}
const std::type_info & type() const public: // types (public so any_cast can be non-friend)
{ class placeholder {
return content ? content->type() : typeid(void); public: // structors
} virtual ~placeholder() {}
public: // types (public so any_cast can be non-friend) public: // queries
virtual const std::type_info &type() const = 0;
class placeholder virtual placeholder *clone() const = 0;
{ };
public: // structors
virtual ~placeholder() template <typename ValueType>
{ class holder : public placeholder {
} public: // structors
holder(const ValueType &value) : held(value) {}
public: // queries public: // queries
virtual const std::type_info &type() const { return typeid(ValueType); }
virtual const std::type_info & type() const = 0; virtual placeholder *clone() const { return new holder(held); }
virtual placeholder * clone() const = 0; public: // representation
ValueType held;
}; private: // intentionally left unimplemented
holder &operator=(const holder &);
};
template<typename ValueType> public: // representation (public so any_cast can be non-friend)
class holder : public placeholder placeholder *content;
{ };
public: // structors
holder(const ValueType & value) class bad_any_cast : public std::bad_cast {
: held(value) public:
{ virtual const char *what() const throw() {
} return "paddle::bad_any_cast: "
"failed conversion using paddle::any_cast";
}
};
public: // queries template <typename ValueType>
ValueType *any_cast(any *operand) {
return operand &&
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
std::strcmp(operand->type().name(),
typeid(ValueType).name()) == 0
#else
operand->type() == typeid(ValueType)
#endif
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}
virtual const std::type_info & type() const template <typename ValueType>
{ inline const ValueType *any_cast(const any *operand) {
return typeid(ValueType); return any_cast<ValueType>(const_cast<any *>(operand));
} }
virtual placeholder * clone() const template <typename ValueType>
{ ValueType any_cast(any &operand) {
return new holder(held); typedef typename std::remove_reference<ValueType>::type nonref;
}
public: // representation // If 'nonref' is still reference type, it means the user has not
// specialized 'remove_reference'.
ValueType held; // Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
// to generate specialization of remove_reference for your class
// See type traits library documentation for details
static_assert(!std::is_reference<nonref>::value,
"!std::is_reference<nonref>::value");
private: // intentionally left unimplemented nonref *result = any_cast<nonref>(&operand);
holder & operator=(const holder &); if (!result) throw bad_any_cast();
}; return *result;
}
public: // representation (public so any_cast can be non-friend) template <typename ValueType>
inline ValueType any_cast(const any &operand) {
typedef typename std::remove_reference<ValueType>::type nonref;
placeholder * content; // The comment in the above version of 'any_cast' explains when this
// assert is fired and what to do.
static_assert(!std::is_reference<nonref>::value,
"!std::is_reference<nonref>::value");
}; return any_cast<const nonref &>(const_cast<any &>(operand));
}
class bad_any_cast : public std::bad_cast // Note: The "unsafe" versions of any_cast are not part of the
{ // public interface and may be removed at any time. They are
public: // required where we know what type is stored in the any and can't
virtual const char * what() const throw() // use typeid() comparison, e.g., when our types may travel across
{ // different shared libraries.
return "paddle::bad_any_cast: " template <typename ValueType>
"failed conversion using paddle::any_cast"; inline ValueType *unsafe_any_cast(any *operand) {
} return &static_cast<any::holder<ValueType> *>(operand->content)->held;
}; }
template<typename ValueType> template <typename ValueType>
ValueType * any_cast(any * operand) inline const ValueType *unsafe_any_cast(const any *operand) {
{ return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
return operand && }
#ifdef BOOST_AUX_ANY_TYPE_ID_NAME
std::strcmp(operand->type().name(), typeid(ValueType).name()) == 0
#else
operand->type() == typeid(ValueType)
#endif
? &static_cast<any::holder<ValueType> *>(operand->content)->held
: 0;
}
template<typename ValueType>
inline const ValueType * any_cast(const any * operand)
{
return any_cast<ValueType>(const_cast<any *>(operand));
}
template<typename ValueType>
ValueType any_cast(any & operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
// If 'nonref' is still reference type, it means the user has not
// specialized 'remove_reference'.
// Please use BOOST_BROKEN_COMPILER_TYPE_TRAITS_SPECIALIZATION macro
// to generate specialization of remove_reference for your class
// See type traits library documentation for details
static_assert(!std::is_reference<nonref>::value, "!std::is_reference<nonref>::value");
nonref * result = any_cast<nonref>(&operand);
if(!result)
throw bad_any_cast();
return *result;
}
template<typename ValueType>
inline ValueType any_cast(const any & operand)
{
typedef typename std::remove_reference<ValueType>::type nonref;
// The comment in the above version of 'any_cast' explains when this
// assert is fired and what to do.
static_assert(!std::is_reference<nonref>::value, "!std::is_reference<nonref>::value");
return any_cast<const nonref &>(const_cast<any &>(operand));
}
// Note: The "unsafe" versions of any_cast are not part of the
// public interface and may be removed at any time. They are
// required where we know what type is stored in the any and can't
// use typeid() comparison, e.g., when our types may travel across
// different shared libraries.
template<typename ValueType>
inline ValueType * unsafe_any_cast(any * operand)
{
return &static_cast<any::holder<ValueType> *>(operand->content)->held;
}
template<typename ValueType>
inline const ValueType * unsafe_any_cast(const any * operand)
{
return unsafe_any_cast<ValueType>(const_cast<any *>(operand));
}
} }
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved. // Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
......
// This file copy from boost/none_t.hpp and boost/none.hpp and boost version:
// 1.41.0
// Modified the following points:
// 1. modify namespace from boost::none to paddle::none
// 2. modify namespace from boost::none_t to paddle::none_t
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef PADDLE_NONE_17SEP2003_HPP
#define PADDLE_NONE_17SEP2003_HPP
namespace paddle {
namespace detail {
struct none_helper {};
}
typedef int detail::none_helper::*none_t;
} // namespace boost
// NOTE: Borland users have to include this header outside any precompiled
// headers
// (bcc<=5.64 cannot include instance data in a precompiled header)
// -- * To be verified, now that there's no unnamed namespace
namespace paddle {
none_t const none = ((none_t)0);
} // namespace boost
#endif
// This file copy from boost/optional/optional.hpp and boost version: 1.41.0
// Modified the following points:
// 1. modify namespace from boost::optional to paddle::optional
// 2. remove the depending boost header files
// 3. remove/modify some macro
// 4. copy some necessary data structures which are the depended by optional
// 5. replace type_with_alignment with std::aligned_storage
// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
//
// Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/lib/optional for documentation.
//
// You are welcome to contact the author at:
// fernando_cacciola@hotmail.com
//
#ifndef PADDLE_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
#define PADDLE_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
#include <algorithm>
#include <functional>
#include <new>
#include <type_traits>
#include "none.h"
// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
// member template of a factory as used in the optional<> implementation.
// He proposed this simple fix which is to move the call to apply<> outside
// namespace boost.
namespace paddle_optional_detail {
template <class T, class Factory>
void construct(Factory const& factory, void* address) {
factory.template apply<T>(address);
}
}
namespace paddle {
template <typename T>
class optional;
class in_place_factory_base {};
class typed_in_place_factory_base {};
// template<class OP> bool equal_pointees(OP const& x, OP const& y);
// template<class OP> struct equal_pointees_t;
//
// Being OP a model of OptionalPointee (either a pointer or an optional):
//
// If both x and y have valid pointees, returns the result of (*x == *y)
// If only one has a valid pointee, returns false.
// If none have valid pointees, returns true.
// No-throw
template <class OptionalPointee>
inline bool equal_pointees(OptionalPointee const& x, OptionalPointee const& y) {
return (!x) != (!y) ? false : (!x ? true : (*x) == (*y));
}
template <class OptionalPointee>
struct equal_pointees_t
: std::binary_function<OptionalPointee, OptionalPointee, bool> {
bool operator()(OptionalPointee const& x, OptionalPointee const& y) const {
return equal_pointees(x, y);
}
};
// template<class OP> bool less_pointees(OP const& x, OP const& y);
// template<class OP> struct less_pointees_t;
//
// Being OP a model of OptionalPointee (either a pointer or an optional):
//
// If y has not a valid pointee, returns false.
// ElseIf x has not a valid pointee, returns true.
// ElseIf both x and y have valid pointees, returns the result of (*x < *y)
// No-throw
template <class OptionalPointee>
inline bool less_pointees(OptionalPointee const& x, OptionalPointee const& y) {
return !y ? false : (!x ? true : (*x) < (*y));
}
template <class OptionalPointee>
struct less_pointees_t
: std::binary_function<OptionalPointee, OptionalPointee, bool> {
bool operator()(OptionalPointee const& x, OptionalPointee const& y) const {
return less_pointees(x, y);
}
};
namespace detail {
template <typename RefT>
class reference_content {
private: // representation
RefT content_;
public: // structors
~reference_content() {}
reference_content(RefT r) : content_(r) {}
reference_content(const reference_content& operand)
: content_(operand.content_) {}
private: // non-Assignable
reference_content& operator=(const reference_content&);
public: // queries
RefT get() const { return content_; }
};
template <typename T>
struct make_reference_content {
typedef T type;
};
template <typename T>
struct make_reference_content<T&> {
typedef reference_content<T&> type;
};
} // namespace detail
namespace optional_detail {
// This local class is used instead of that in "aligned_storage.hpp"
// because I've found the 'official' class to ICE BCB5.5
// when some types are used with optional<>
// (due to sizeof() passed down as a non-type template parameter)
template <class T>
class aligned_storage {
// Borland ICEs if unnamed unions are used for this!
union dummy_u {
char data[sizeof(T)];
typename std::aligned_storage<::std::alignment_of<T>::value>::type aligner_;
} dummy_;
public:
void const* address() const { return &dummy_.data[0]; }
void* address() { return &dummy_.data[0]; }
};
template <class T>
struct types_when_isnt_ref {
typedef T const& reference_const_type;
typedef T& reference_type;
typedef T const* pointer_const_type;
typedef T* pointer_type;
typedef T const& argument_type;
};
template <class T>
struct types_when_is_ref {
typedef typename std::remove_reference<T>::type raw_type;
typedef raw_type& reference_const_type;
typedef raw_type& reference_type;
typedef raw_type* pointer_const_type;
typedef raw_type* pointer_type;
typedef raw_type& argument_type;
};
struct optional_tag {};
template <class T>
class optional_base : public optional_tag {
private:
typedef
typename ::paddle::detail::make_reference_content<T>::type internal_type;
typedef aligned_storage<internal_type> storage_type;
typedef types_when_isnt_ref<T> types_when_not_ref;
typedef types_when_is_ref<T> types_when_ref;
typedef optional_base<T> this_type;
protected:
typedef T value_type;
typedef std::true_type is_reference_tag;
typedef std::false_type is_not_reference_tag;
typedef typename std::is_reference<T>::type is_reference_predicate;
typedef typename std::conditional<is_reference_predicate::value,
types_when_ref,
types_when_not_ref>::type types;
typedef bool (this_type::*unspecified_bool_type)() const;
typedef typename types::reference_type reference_type;
typedef typename types::reference_const_type reference_const_type;
typedef typename types::pointer_type pointer_type;
typedef typename types::pointer_const_type pointer_const_type;
typedef typename types::argument_type argument_type;
// Creates an optional<T> uninitialized.
// No-throw
optional_base() : m_initialized(false) {}
// Creates an optional<T> uninitialized.
// No-throw
optional_base(none_t) : m_initialized(false) {}
// Creates an optional<T> initialized with 'val'.
// Can throw if T::T(T const&) does
optional_base(argument_type val) : m_initialized(false) { construct(val); }
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise
// creates an uninitialzed optional<T>.
// Can throw if T::T(T const&) does
optional_base(bool cond, argument_type val) : m_initialized(false) {
if (cond) construct(val);
}
// Creates a deep copy of another optional<T>
// Can throw if T::T(T const&) does
optional_base(optional_base const& rhs) : m_initialized(false) {
if (rhs.is_initialized()) construct(rhs.get_impl());
}
// This is used for both converting and in-place constructions.
// Derived classes use the 'tag' to select the appropriate
// implementation (the correct 'construct()' overload)
template <class Expr>
explicit optional_base(Expr const& expr, Expr const* tag)
: m_initialized(false) {
construct(expr, tag);
}
// No-throw (assuming T::~T() doesn't)
~optional_base() { destroy(); }
// Assigns from another optional<T> (deep-copies the rhs value)
void assign(optional_base const& rhs) {
if (is_initialized()) {
if (rhs.is_initialized())
assign_value(rhs.get_impl(), is_reference_predicate());
else
destroy();
} else {
if (rhs.is_initialized()) construct(rhs.get_impl());
}
}
// Assigns from another _convertible_ optional<U> (deep-copies the rhs value)
template <class U>
void assign(optional<U> const& rhs) {
if (is_initialized()) {
if (rhs.is_initialized())
assign_value(static_cast<value_type>(rhs.get()),
is_reference_predicate());
else
destroy();
} else {
if (rhs.is_initialized()) construct(static_cast<value_type>(rhs.get()));
}
}
// Assigns from a T (deep-copies the rhs value)
void assign(argument_type val) {
if (is_initialized())
assign_value(val, is_reference_predicate());
else
construct(val);
}
// Assigns from "none", destroying the current value, if any, leaving this
// UNINITIALIZED
// No-throw (assuming T::~T() doesn't)
void assign(none_t) { destroy(); }
template <class Expr>
void assign_expr(Expr const& expr, Expr const* tag) {
if (is_initialized())
assign_expr_to_initialized(expr, tag);
else
construct(expr, tag);
}
public:
// Destroys the current value, if any, leaving this UNINITIALIZED
// No-throw (assuming T::~T() doesn't)
void reset() { destroy(); }
// Replaces the current value -if any- with 'val'
void reset(argument_type val) { assign(val); }
// Returns a pointer to the value if this is initialized, otherwise,
// returns NULL.
// No-throw
pointer_const_type get_ptr() const {
return m_initialized ? get_ptr_impl() : 0;
}
pointer_type get_ptr() { return m_initialized ? get_ptr_impl() : 0; }
bool is_initialized() const { return m_initialized; }
protected:
void construct(argument_type val) {
new (m_storage.address()) internal_type(val);
m_initialized = true;
}
// Constructs in-place using the given factory
template <class Expr>
void construct(Expr const& factory, in_place_factory_base const*) {
static_assert(!is_reference_predicate::value,
"!is_reference_predicate::value");
paddle_optional_detail::construct<value_type>(factory, m_storage.address());
m_initialized = true;
}
// Constructs in-place using the given typed factory
template <class Expr>
void construct(Expr const& factory, typed_in_place_factory_base const*) {
static_assert(!is_reference_predicate::value,
"!is_reference_predicate::value");
factory.apply(m_storage.address());
m_initialized = true;
}
template <class Expr>
void assign_expr_to_initialized(Expr const& factory,
in_place_factory_base const* tag) {
destroy();
construct(factory, tag);
}
// Constructs in-place using the given typed factory
template <class Expr>
void assign_expr_to_initialized(Expr const& factory,
typed_in_place_factory_base const* tag) {
destroy();
construct(factory, tag);
}
// Constructs using any expression implicitely convertible to the single
// argument
// of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function
// with
// 'Expr' being of type 'U' and relying on a converting constructor of T from
// U.
template <class Expr>
void construct(Expr const& expr, void const*) {
new (m_storage.address()) internal_type(expr);
m_initialized = true;
}
// Assigns using a form any expression implicitely convertible to the single
// argument
// of a T's assignment operator.
// Converting assignments of optional<T> from optional<U> uses this function
// with
// 'Expr' being of type 'U' and relying on a converting assignment of T from
// U.
template <class Expr>
void assign_expr_to_initialized(Expr const& expr, void const*) {
assign_value(expr, is_reference_predicate());
}
void assign_value(argument_type val, is_not_reference_tag) {
get_impl() = val;
}
void assign_value(argument_type val, is_reference_tag) { construct(val); }
void destroy() {
if (m_initialized) destroy_impl(is_reference_predicate());
}
unspecified_bool_type safe_bool() const {
return m_initialized ? &this_type::is_initialized : 0;
}
reference_const_type get_impl() const {
return dereference(get_object(), is_reference_predicate());
}
reference_type get_impl() {
return dereference(get_object(), is_reference_predicate());
}
pointer_const_type get_ptr_impl() const {
return cast_ptr(get_object(), is_reference_predicate());
}
pointer_type get_ptr_impl() {
return cast_ptr(get_object(), is_reference_predicate());
}
private:
// internal_type can be either T or reference_content<T>
internal_type const* get_object() const {
return static_cast<internal_type const*>(m_storage.address());
}
internal_type* get_object() {
return static_cast<internal_type*>(m_storage.address());
}
// reference_content<T> lacks an implicit conversion to T&, so the following
// is needed to obtain a proper reference.
reference_const_type dereference(internal_type const* p,
is_not_reference_tag) const {
return *p;
}
reference_type dereference(internal_type* p, is_not_reference_tag) {
return *p;
}
reference_const_type dereference(internal_type const* p,
is_reference_tag) const {
return p->get();
}
reference_type dereference(internal_type* p, is_reference_tag) {
return p->get();
}
void destroy_impl(is_not_reference_tag) {
get_ptr_impl()->T::~T();
m_initialized = false;
}
void destroy_impl(is_reference_tag) { m_initialized = false; }
// If T is of reference type, trying to get a pointer to the held value must
// result in a compile-time error.
// Decent compilers should disallow conversions from reference_content<T>* to
// T*, but just in case,
// the following olverloads are used to filter out the case and guarantee an
// error in case of T being a reference.
pointer_const_type cast_ptr(internal_type const* p,
is_not_reference_tag) const {
return p;
}
pointer_type cast_ptr(internal_type* p, is_not_reference_tag) { return p; }
pointer_const_type cast_ptr(internal_type const* p, is_reference_tag) const {
return &p->get();
}
pointer_type cast_ptr(internal_type* p, is_reference_tag) {
return &p->get();
}
bool m_initialized;
storage_type m_storage;
};
} // namespace optional_detail
template <class T>
class optional : public optional_detail::optional_base<T> {
typedef optional_detail::optional_base<T> base;
typedef typename base::unspecified_bool_type unspecified_bool_type;
public:
typedef optional<T> this_type;
typedef typename base::value_type value_type;
typedef typename base::reference_type reference_type;
typedef typename base::reference_const_type reference_const_type;
typedef typename base::pointer_type pointer_type;
typedef typename base::pointer_const_type pointer_const_type;
typedef typename base::argument_type argument_type;
// Creates an optional<T> uninitialized.
// No-throw
optional() : base() {}
// Creates an optional<T> uninitialized.
// No-throw
optional(none_t none_) : base(none_) {}
// Creates an optional<T> initialized with 'val'.
// Can throw if T::T(T const&) does
optional(argument_type val) : base(val) {}
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise
// creates an uninitialized optional.
// Can throw if T::T(T const&) does
optional(bool cond, argument_type val) : base(cond, val) {}
// Creates a deep copy of another convertible optional<U>
// Requires a valid conversion from U to T.
// Can throw if T::T(U const&) does
template <class U>
explicit optional(optional<U> const& rhs) : base() {
if (rhs.is_initialized()) this->construct(rhs.get());
}
// Creates an optional<T> with an expression which can be either
// (a) An instance of InPlaceFactory (i.e. in_place(a,b,...,n);
// (b) An instance of TypedInPlaceFactory ( i.e. in_place<T>(a,b,...,n);
// (c) Any expression implicitely convertible to the single type
// of a one-argument T's constructor.
// (d*) Weak compilers (BCB) might also resolved Expr as optional<T> and
// optional<U>
// even though explicit overloads are present for these.
// Depending on the above some T ctor is called.
// Can throw is the resolved T ctor throws.
template <class Expr>
explicit optional(Expr const& expr) : base(expr, &expr) {}
// Creates a deep copy of another optional<T>
// Can throw if T::T(T const&) does
optional(optional const& rhs) : base(rhs) {}
// No-throw (assuming T::~T() doesn't)
~optional() {}
// Assigns from an expression. See corresponding constructor.
// Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
template <class Expr>
optional& operator=(Expr expr) {
this->assign_expr(expr, &expr);
return *this;
}
// Assigns from another convertible optional<U> (converts && deep-copies the
// rhs value)
// Requires a valid conversion from U to T.
// Basic Guarantee: If T::T( U const& ) throws, this is left UNINITIALIZED
template <class U>
optional& operator=(optional<U> const& rhs) {
this->assign(rhs);
return *this;
}
// Assigns from another optional<T> (deep-copies the rhs value)
// Basic Guarantee: If T::T( T const& ) throws, this is left UNINITIALIZED
// (NOTE: On BCB, this operator is not actually called and left is left
// UNMODIFIED in case of a throw)
optional& operator=(optional const& rhs) {
this->assign(rhs);
return *this;
}
// Assigns from a T (deep-copies the rhs value)
// Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
optional& operator=(argument_type val) {
this->assign(val);
return *this;
}
// Assigns from a "none"
// Which destroys the current value, if any, leaving this UNINITIALIZED
// No-throw (assuming T::~T() doesn't)
optional& operator=(none_t none_) {
this->assign(none_);
return *this;
}
// Returns a reference to the value if this is initialized, otherwise,
// the behaviour is UNDEFINED
// No-throw
reference_const_type get() const {
assert(this->is_initialized());
return this->get_impl();
}
reference_type get() {
assert(this->is_initialized());
return this->get_impl();
}
// Returns a copy of the value if this is initialized, 'v' otherwise
reference_const_type get_value_or(reference_const_type v) const {
return this->is_initialized() ? get() : v;
}
reference_type get_value_or(reference_type v) {
return this->is_initialized() ? get() : v;
}
// Returns a pointer to the value if this is initialized, otherwise,
// the behaviour is UNDEFINED
// No-throw
pointer_const_type operator->() const {
assert(this->is_initialized());
return this->get_ptr_impl();
}
pointer_type operator->() {
assert(this->is_initialized());
return this->get_ptr_impl();
}
// Returns a reference to the value if this is initialized, otherwise,
// the behaviour is UNDEFINED
// No-throw
reference_const_type operator*() const { return this->get(); }
reference_type operator*() { return this->get(); }
// implicit conversion to "bool"
// No-throw
operator unspecified_bool_type() const { return this->safe_bool(); }
// This is provided for those compilers which don't like the conversion to
// bool
// on some contexts.
bool operator!() const { return !this->is_initialized(); }
};
// Returns optional<T>(v)
template <class T>
inline optional<T> make_optional(T const& v) {
return optional<T>(v);
}
// Returns optional<T>(cond,v)
template <class T>
inline optional<T> make_optional(bool cond, T const& v) {
return optional<T>(cond, v);
}
// Returns a reference to the value if this is initialized, otherwise, the
// behaviour is UNDEFINED.
// No-throw
template <class T>
inline typename optional<T>::reference_const_type get(optional<T> const& opt) {
return opt.get();
}
template <class T>
inline typename optional<T>::reference_type get(optional<T>& opt) {
return opt.get();
}
// Returns a pointer to the value if this is initialized, otherwise, returns
// NULL.
// No-throw
template <class T>
inline typename optional<T>::pointer_const_type get(optional<T> const* opt) {
return opt->get_ptr();
}
template <class T>
inline typename optional<T>::pointer_type get(optional<T>* opt) {
return opt->get_ptr();
}
// Returns a reference to the value if this is initialized, otherwise, the
// behaviour is UNDEFINED.
// No-throw
template <class T>
inline typename optional<T>::reference_const_type get_optional_value_or(
optional<T> const& opt, typename optional<T>::reference_const_type v) {
return opt.get_value_or(v);
}
template <class T>
inline typename optional<T>::reference_type get_optional_value_or(
optional<T>& opt, typename optional<T>::reference_type v) {
return opt.get_value_or(v);
}
// Returns a pointer to the value if this is initialized, otherwise, returns
// NULL.
// No-throw
template <class T>
inline typename optional<T>::pointer_const_type get_pointer(
optional<T> const& opt) {
return opt.get_ptr();
}
template <class T>
inline typename optional<T>::pointer_type get_pointer(optional<T>& opt) {
return opt.get_ptr();
}
// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics
// (compare values).
// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in
// generic code instead.
//
// optional<T> vs optional<T> cases
//
template <class T>
inline bool operator==(optional<T> const& x, optional<T> const& y) {
return equal_pointees(x, y);
}
template <class T>
inline bool operator<(optional<T> const& x, optional<T> const& y) {
return less_pointees(x, y);
}
template <class T>
inline bool operator!=(optional<T> const& x, optional<T> const& y) {
return !(x == y);
}
template <class T>
inline bool operator>(optional<T> const& x, optional<T> const& y) {
return y < x;
}
template <class T>
inline bool operator<=(optional<T> const& x, optional<T> const& y) {
return !(y < x);
}
template <class T>
inline bool operator>=(optional<T> const& x, optional<T> const& y) {
return !(x < y);
}
//
// optional<T> vs T cases
//
template <class T>
inline bool operator==(optional<T> const& x, T const& y) {
return equal_pointees(x, optional<T>(y));
}
template <class T>
inline bool operator<(optional<T> const& x, T const& y) {
return less_pointees(x, optional<T>(y));
}
template <class T>
inline bool operator!=(optional<T> const& x, T const& y) {
return !(x == y);
}
template <class T>
inline bool operator>(optional<T> const& x, T const& y) {
return y < x;
}
template <class T>
inline bool operator<=(optional<T> const& x, T const& y) {
return !(y < x);
}
template <class T>
inline bool operator>=(optional<T> const& x, T const& y) {
return !(x < y);
}
//
// T vs optional<T> cases
//
template <class T>
inline bool operator==(T const& x, optional<T> const& y) {
return equal_pointees(optional<T>(x), y);
}
template <class T>
inline bool operator<(T const& x, optional<T> const& y) {
return less_pointees(optional<T>(x), y);
}
template <class T>
inline bool operator!=(T const& x, optional<T> const& y) {
return !(x == y);
}
template <class T>
inline bool operator>(T const& x, optional<T> const& y) {
return y < x;
}
template <class T>
inline bool operator<=(T const& x, optional<T> const& y) {
return !(y < x);
}
template <class T>
inline bool operator>=(T const& x, optional<T> const& y) {
return !(x < y);
}
//
// optional<T> vs none cases
//
template <class T>
inline bool operator==(optional<T> const& x, none_t) {
return equal_pointees(x, optional<T>());
}
template <class T>
inline bool operator<(optional<T> const& x, none_t) {
return less_pointees(x, optional<T>());
}
template <class T>
inline bool operator!=(optional<T> const& x, none_t y) {
return !(x == y);
}
template <class T>
inline bool operator>(optional<T> const& x, none_t y) {
return y < x;
}
template <class T>
inline bool operator<=(optional<T> const& x, none_t y) {
return !(y < x);
}
template <class T>
inline bool operator>=(optional<T> const& x, none_t y) {
return !(x < y);
}
//
// none vs optional<T> cases
//
template <class T>
inline bool operator==(none_t x, optional<T> const& y) {
return equal_pointees(optional<T>(), y);
}
template <class T>
inline bool operator<(none_t x, optional<T> const& y) {
return less_pointees(optional<T>(), y);
}
template <class T>
inline bool operator!=(none_t x, optional<T> const& y) {
return !(x == y);
}
template <class T>
inline bool operator>(none_t x, optional<T> const& y) {
return y < x;
}
template <class T>
inline bool operator<=(none_t x, optional<T> const& y) {
return !(y < x);
}
template <class T>
inline bool operator>=(none_t x, optional<T> const& y) {
return !(x < y);
}
namespace optional_detail {
// optional's swap:
// If both are initialized, calls swap(T&, T&). If this swap throws, both will
// remain initialized but their values are now unspecified.
// If only one is initialized, calls U.reset(*I), THEN I.reset().
// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I
// is never reset)
// If both are uninitialized, do nothing (no-throw)
template <class T>
inline void optional_swap(optional<T>& x, optional<T>& y) {
if (!x && !!y) {
x.reset(*y);
y.reset();
} else if (!!x && !y) {
y.reset(*x);
x.reset();
} else if (!!x && !!y) {
// allow for Koenig lookup
using std::swap;
swap(*x, *y);
}
}
} // namespace optional_detail
} // namespace paddle
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册