Is there a way to detect portable that the standard header is enabled using macros?

I want to make the equivalent of boost::swap , and in my environment standard headers may or may not be included. Depending on the licensing of the project and other things.
I would like to make parts of the code protected by security detectors:

Consider one compilation unit.
specific project, the aforementioned potential includes:

 #include <algorithm> // (or <utility> for C++11 projects) 

later in the project code included in my swap utility header:

 namespace MyCompany { template<class T1, class T2> void swap(T1& left, T2& right) { #ifdef _ALGORITHM_ // you get the idea. std::swap(left, right); #else // fallback impl #endif } } 

I am simplified because we are not talking about the details of the ADL trick here, but it will be included.
here for a reference to what I'm talking about, but this is not relevant to this question:
http://www.boost.org/doc/libs/1_57_0/boost/core/swap.hpp

So this question is about how can I define a standard header inclusion ? defender _ALGORITHM_ present in the header of the visual studio, but I have not read anywhere http://www.cplusplus.com/reference/algorithm/ that it should have any macro that I can check.

(last note: this question is a bit biased by XY. I really want to detect the presence of the std::swap function, not the header.)

+8
c ++ utility
source share
1 answer

One option that you have to make your overload β€œworse” than alternatives. Then, only if they do not exist yet, your version will be selected:

 #if 0 #include <algorithm> using std::swap; #endif template <typename T> struct ForceLessSpecialized { typedef T TYPE; }; template <typename T> void swap (T &, typename ForceLessSpecialized<T>::TYPE &) { } void bar () { int i; swap (i, i); } 

What's happening:

If there are two specialized function templates, the compiler performs "Partial ordering of function templates" ('03 14.5.5.2). This checks if the template parameters of the function of one template can be used to specialize another.

For each template, we will use dummy parameters T1 and T2 , and we create lists of dummy arguments using the following types:

 // std::swap argument list ( T1 & , T1 & ) // our swap argument list ( T2 &, typename ForceLessSpecialized<T2>::TYPE & ) 

Specializing in our swap using dummy arguments from std::swap , we get:

 Deduction from First parameter: T == T1 Deduction from Second parameter: Non Deduced Context 

The inferred T is equal to T1 , and the residue succeeded.

Specializing std::swap using dummy arguments for our swap, we get:

 Deduction from First parameter: T == T2 Deduction from Second parameter: T == ForceLessSpecialized<T2>::TYPE 

The deduced types for T do not match, and therefore this is considered a deduction failure.

Therefore, the synthesized arguments to std::swap can be used to specialize our template, but the synthesized arguments to our template cannot be used to specialize std::swap . std::swap considered as more specialized and therefore partial order wins.

+4
source share

All Articles