MongoDB C++ Driver mongocxx-3.10.1
Loading...
Searching...
No Matches
functor.hpp
1// Copyright 2014 MongoDB Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <functional>
18#include <type_traits>
19
20#include <bsoncxx/config/prelude.hpp>
21
22namespace bsoncxx {
23namespace v_noabi {
24namespace util {
25
26// TODO(MSVC): VS2015U1 Completely falls apart trying to honor the
27// simple definition of is_functor since is_convertible returns the
28// wrong results for std::function, so we fall back to a bunch of
29// other template metaprogramming there.
30
31#if !defined(_MSC_VER)
32
33template <typename FunctionLike, typename Signature>
34using is_functor = std::is_convertible<FunctionLike, std::function<Signature>>;
35
36#else
37
38namespace functor {
39
40template <typename, typename>
41struct build_free_function;
42
43template <typename F, typename R, typename... Args>
44struct build_free_function<F, R(Args...)> {
45 typedef R (*type)(Args...);
46};
47
48template <typename, typename>
49struct build_class_function;
50
51template <typename C, typename R, typename... Args>
52struct build_class_function<C, R(Args...)> {
53 typedef R (C::*type)(Args...);
54};
55
56template <typename>
57struct strip_cv_from_class_function;
58
59template <typename C, typename R, typename... Args>
60struct strip_cv_from_class_function<R (C::*)(Args...)> {
61 typedef R (C::*type)(Args...);
62};
63
64template <typename C, typename R, typename... Args>
65struct strip_cv_from_class_function<R (C::*)(Args...) const> {
66 typedef R (C::*type)(Args...);
67};
68
69template <typename C, typename R, typename... Args>
70struct strip_cv_from_class_function<R (C::*)(Args...) volatile> {
71 typedef R (C::*type)(Args...);
72};
73
74template <typename C, typename S>
75struct is_class_method_with_signature {
76 typedef int yes;
77 typedef char no;
78
79 // T stands for SFINAE
80 template <typename T>
81 static typename std::enable_if<std::is_convertible<typename build_class_function<C, S>::type,
82 typename strip_cv_from_class_function<
83 decltype(&T::operator())>::type>::value,
84 yes>::type
85 sfinae(void*);
86
87 template <typename>
88 static no sfinae(...);
89
90 static bool constexpr value = sizeof(sfinae<C>(nullptr)) == sizeof(yes);
91};
92
93template <typename F, typename S>
94struct is_function_with_signature
95 : std::is_convertible<F, typename build_free_function<F, S>::type> {};
96
97template <typename C, typename S, bool>
98struct is_functor_impl : is_class_method_with_signature<C, S> {};
99
100template <typename F, typename S>
101struct is_functor_impl<F, S, false> : is_function_with_signature<F, S> {};
102
103} // namespace functor
104
105template <typename C, typename S>
106struct is_functor : functor::is_functor_impl<C, S, std::is_class<C>::value> {};
107
108#endif
109
110} // namespace util
111} // namespace v_noabi
112} // namespace bsoncxx
113
114#include <bsoncxx/config/postlude.hpp>
type
An enumeration of each BSON type.
Definition types.hpp:48
The top-level namespace for bsoncxx library entities.
Definition element-fwd.hpp:19