Squashed 'third_party/boostorg/type_traits/' content from commit 059ed88

Change-Id: I222c604dfa1db194bf53bc6aa1152fb16e83ce06
git-subtree-dir: third_party/boostorg/type_traits
git-subtree-split: 059ed8839da3fecd1e8b62cdc11be006f6346b5e
diff --git a/doc/has_complement.qbk b/doc/has_complement.qbk
new file mode 100644
index 0000000..f6b567b
--- /dev/null
+++ b/doc/has_complement.qbk
@@ -0,0 +1,109 @@
+[/
+  (C) Copyright 2009-2011  Frederic Bron.
+  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).
+]
+
+[section:has_complement has_complement]
+   template <class Rhs, class Ret=dont_care>
+   struct has_complement : public __tof {};
+
+__inherit
+If (i) `rhs` of type `Rhs` can be used in expression `~rhs`,
+and (ii) `Ret=dont_care` or the result of expression `~rhs` is convertible to `Ret`
+then inherits from __true_type,
+otherwise inherits from __false_type.
+
+The default behaviour (`Ret=dont_care`) is to not check for the return value of prefix `operator~`.
+If `Ret` is different from the default `dont_care` type, the return value is checked to be convertible to `Ret`.
+Convertible to `Ret` means that the return value of the operator can be used as argument to a function expecting `Ret`:
+``
+void f(Ret);
+Rhs rhs;
+f(~rhs); // is valid if has_complement<Rhs, Ret>::value==true
+``
+If `Ret=void`, the return type is checked to be exactly `void`.
+
+__header `#include <boost/type_traits/has_complement.hpp>` or `#include <boost/type_traits/has_operator.hpp>` or `#include <boost/type_traits.hpp>`
+
+[has_binary_operator_compat]
+
+__examples
+
+[:`has_complement<Rhs, Ret>::value_type` is the type `bool`.]
+[:`has_complement<Rhs, Ret>::value` is a `bool` integral constant expression.]
+[:`has_complement<int>::value` is a `bool` integral constant expression that evaluates to `true`.]
+[:`has_complement<long>` inherits from `__true_type`.]
+
+[:`has_complement<int, int>` inherits from `__true_type`.]
+[:`has_complement<int, long>` inherits from `__true_type`.]
+[:`has_complement<const int>` inherits from `__true_type`.]
+
+[:`has_complement<int*>` inherits from `__false_type`.]
+[:`has_complement<double, double>` inherits from `__false_type`.]
+[:`has_complement<double, int>` inherits from `__false_type`.]
+[:`has_complement<int, std::string>` inherits from `__false_type`.]
+
+
+[*See also:] [link boost_typetraits.category.value_traits.operators Operator Type Traits]
+
+[*Known issues:]
+
+* This trait cannot detect whether prefix `operator~` is public or not:
+if `operator~` is defined as a private member of `Rhs` then
+instantiating `has_complement<Rhs>` will produce a compiler error.
+For this reason `has_complement` cannot be used to determine whether a type has a public `operator~` or not.
+``
+struct A { private: void operator~(); };
+boost::has_complement<A>::value; // error: A::operator~() is private
+``
+
+* There is an issue if the operator exists only for type `A` and `B` is
+convertible to `A`. In this case, the compiler will report an ambiguous overload.
+``
+struct A { };
+void operator~(const A&);
+struct B { operator A(); };
+boost::has_complement<A>::value; // this is fine
+boost::has_complement<B>::value; // error: ambiguous overload
+``
+
+* There is an issue when applying this trait to template classes.
+If `operator~` is defined but does not bind for a given template type,
+it is still detected by the trait which returns `true` instead of `false`.
+Example:
+``
+#include <boost/type_traits/has_complement.hpp>
+#include <iostream>
+
+template <class T>
+struct contains { T data; };
+
+template <class T>
+bool operator~(const contains<T> &rhs) {
+	return f(rhs.data);
+}
+
+class bad { };
+class good { };
+bool f(const good&) { }
+
+int main() {
+	std::cout<<std::boolalpha;
+	// works fine for contains<good>
+	std::cout<<boost::has_complement< contains< good > >::value<<'\n'; // true
+	contains<good> g;
+	~g; // ok
+	// does not work for contains<bad>
+	std::cout<<boost::has_complement< contains< bad > >::value<<'\n'; // true, should be false
+	contains<bad> b;
+	~b; // compile time error
+	return 0;
+}
+``
+
+* `volatile` qualifier is not properly handled and would lead to undefined behavior
+
+[endsect]
+