// 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 #include #include 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 using is_functor = std::is_convertible>; #else namespace functor { template struct build_free_function; template struct build_free_function { typedef R (*type)(Args...); }; template struct build_class_function; template struct build_class_function { typedef R (C::*type)(Args...); }; template struct strip_cv_from_class_function; template struct strip_cv_from_class_function { typedef R (C::*type)(Args...); }; template struct strip_cv_from_class_function { typedef R (C::*type)(Args...); }; template struct strip_cv_from_class_function { typedef R (C::*type)(Args...); }; template struct is_class_method_with_signature { typedef int yes; typedef char no; // T stands for SFINAE template static typename std::enable_if::type, typename strip_cv_from_class_function< decltype(&T::operator())>::type>::value, yes>::type sfinae(void*); template static no sfinae(...); static bool constexpr value = sizeof(sfinae(nullptr)) == sizeof(yes); }; template struct is_function_with_signature : std::is_convertible::type> {}; template struct is_functor_impl : is_class_method_with_signature {}; template struct is_functor_impl : is_function_with_signature {}; } // namespace functor template struct is_functor : functor::is_functor_impl::value> {}; #endif } // namespace util BSONCXX_INLINE_NAMESPACE_END } // namespace bsoncxx #include