﻿<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Feature-testing preprocessor predicates for C++17</title>
    <style type="text/css">
        del {
            background-color: #FCC;
        }

        ins {
            background-color: #CFC;
        }
    </style>
</head>
<body>
    <table border="1">
	<tbody>
	    <tr>
		<th>Doc. No.:</th>
		<td>P0061R1</td>
	    </tr>
	    <tr>
		<th>Date:</th>
		<td>2015-10-23</td>
	    </tr>
	    <tr>
		<th rowspan="2">Reply to:</th>
		<td>Clark Nelson</td>
	    </tr>
	    <tr>
		<td>Richard Smith</td>
	    </tr>
	</tbody>
    </table>
    <h1><code>__has_include</code> for C++17</h1>
    <!--    <h2>Introduction</h2>
    <p>SD-6 recommends, in addition to defining feature-test macros,
	that implementations support
	two new predicates for use in preprocessor conditional inclusion
	(like the existing <code>defined</code> predicate).</p>
    <p>The first of these, <code>__has_include</code>,
	is actually a general-purpose extension to the preprocessor,
	and would be useful to improve portability
	between a very wide range of implementations.
	The other, <code>__has_cpp_attribute</code>, has somewhat narrower utility.
    </p>
    <p>SG10 would like EWG and WG21 to consider
	whether these predicates would be worth adding to the C++17 standard.</p>
    <h2>Descriptions (verbatim from SD-6)</h2>
    <h3 id="recs.hasinc">Testing for the presence of a header: <code>__has_include</code></h3>
    <p>It is impossible for a C++ program to directly, reliably and portably determine whether
		or not a library header is available for inclusion. Conditionally including a header
		requires the use of a configuration macro, whose setting can be determined by a
		configuration-test process at build time (reliable, but less portable), or by some
		other means (often not reliable or portable).</p>
    <p>To solve this general problem, WG21 recommends that implementers provide, and programmers
		use, the <code>__has_include</code> feature.</p>
    <h4>Syntax</h4>
    -->
    <p>Replace paragraph 1 of 16.1 with several paragraphs, as follows:</p>
    <blockquote>
	<dl>
	    <dt><ins><dfn>defined-macro-expression</dfn>:</ins></dt>
	    <dd><ins><code>defined</code> <var>identifier</var></ins></dd>
	    <dd><ins><code>defined (</code> <var>identifier</var> <code>)</code></ins></dd>
	</dl>
	<dl>
	    <dt><ins><dfn>h-preprocessing-token</dfn>:</ins></dt>
	    <dd><ins>any <var>preprocessing-token</var> other than <code>&gt;</code></ins></dd>
	</dl>
	<dl>
	    <dt><ins><dfn>h-pp-tokens</dfn>:</ins></dt>
	    <dd><ins><var>h-preprocessing-token</var></ins></dd>
	    <dd><ins><var>h-pp-tokens h-preprocessing-token</var></ins></dd>
	</dl>
	<dl>
	    <dt><ins><dfn>has-include-expression</dfn>:</ins></dt>
	    <dd><ins><code>__has_include ( &lt;</code><var>h-char-sequence</var><code>&gt; )</code></ins></dd>
	    <dd><ins><code>__has_include ( "</code><var>q-char-sequence</var><code>" )</code></ins></dd>
	    <dd><ins><code>__has_include (</code> <var>string-literal</var> <code>)</code></ins></dd>
	    <dd><ins><code>__has_include ( &lt;</code> <var>h-pp-tokens</var> <code>&gt; )</code></ins></dd>
	</dl>
	<p>The expression that controls conditional inclusion
	shall be an integral constant expression
	except that identifiers
	(including those lexically identical to keywords)
	are interpreted as described below<sup>146</sup>
	    and it may contain <ins>zero or more <var>defined-macro-expressions</var>
		and/or <var>has-include-expressions</var> as</ins> unary operator expressions<ins>.</ins>
	    <del>of the form</del>
	</p>
	<p><del><code>defined</code> <var>identifier</var></del></p>
	<p><del>or</del></p>
	<p><del><code>defined (</code> <var>identifier</var> <code>)</code></del></p>
	<p><del>which evaluate</del> <ins>A <var>defined-macro-expression</var> evaluates</ins> to <code>1</code> if the identifier is currently defined as a macro name
	(that is, if it is predefined
	or if it has been the subject of a <code>#define</code> preprocessing directive
	without an intervening <code>#undef</code> directive with the same subject identifier),
	<code>0</code> if it is not.</p>
	<!-- Needs some work. -->
	<p><ins><!-- In the first and second forms of the <var>has-include-expression</var>,
	    the parenthesized <var>header-name</var> token is not subject to macro expansion. -->
	    The third and fourth forms of <var>has-include-expression</var> are considered
	    only if neither of the first or second forms matches,
	    in which case the preprocessing tokens are processed just as in normal text.</ins></p>
	<p>
	    <!--A <var>has-include-expression</var> shall appear only in the controlling constant
		expression of a <code>#if</code> or <code>#elif</code> directive ([cpp.cond] 16.1).
		Prior to the evaluation of such an expression,
	-->
	    <ins>The header or source file identified by the
		parenthesized preprocessing token sequence in each contained <var>has-include-expression</var>
		is searched for as if that preprocessing token sequence were the <var>pp-tokens</var>
		in a <code>#include</code> directive, except that no further macro expansion is
		performed. If such a directive would not satisfy the syntactic requirements of a
		<code>#include</code> directive, the program is ill-formed. The <var>has-include-expression</var>
		evaluates to <code>1</code> if the search for the source
		file succeeds, and to <code>0</code> if the search fails.</ins></p>
	<p><ins>The <code>#ifdef</code> and <code>#ifndef</code> directives, and the <code>defined</code>
	    conditional inclusion operator, shall treat <code>__has_include</code> as if it
		were the name of a defined macro. The identifier <code>__has_include</code> shall
		not appear in any context not mentioned in this section.</ins></p>
    </blockquote>
    <p>Change 16.1p4:</p>
    <blockquote>... After all replacements due to macro expansion and
	<del>the <code>defined</code> unary operator</del>
	<ins>evaluations of <var>defined-macro-expressions</var> and <var>has-include-expressions</var></ins> have been performed,
	all remaining identifiers and keywords<sup>147</sup>,
	except for <code>true</code> and <code>false</code>,
	are replaced with the pp-number <code>0</code>,
	and then each preprocessing token is converted into a token. ...</blockquote>
    <p>Add the following example after 16.1p6:</p>
    <blockquote>
	<p><ins>[ <em>Example:</em> This demonstrates a way to include a library <code>optional</code> facility only if it is available.</ins></p>
	<pre>#if __has_include(&lt;optional&gt;)
#  include &lt;optional&gt;
#  define have_optional 1
#elif __has_include(&lt;experimental/optional&gt;)
#  include &lt;experimental/optional&gt;
#  define have_optional 1
#  define experimental_optional 1
#else
#  define have_optional 0
#endif</pre>
	<p><ins>&mdash; <em>end example</em> ]</ins></p>
    </blockquote>
    <!--
    <h3 id="recs.hasattr">Testing for the presence of an attribute: <code>__has_cpp_attribute</code></h3>
    <p>A C++ program cannot directly, reliably, and portably determine whether or not
		a standard or vendor-specific attribute is available for use. Testing for attribute
		support generally requires complex macro logic, as illustrated above for language
		features in general.</p>
    <p>To solve this general problem, WG21 recommends that implementers provide, and
		programmers use, the <code>__has_cpp_attribute</code> feature.</p>
    <h4>Syntax</h4>
    <dl>
	<dt><dfn>has-attribute-expression</dfn>:</dt>
	<dd><code>__has_cpp_attribute (</code> <var>attribute-token</var> <code>)</code></dd>
    </dl>
    <h4>Semantics</h4>
    <p>A <var>has-attribute-expression</var> shall appear only in the controlling constant
		expression of a <code>#if</code> or <code>#elif</code> directive ([cpp.cond] 16.1).
		The <var>has-attribute-expression</var> is replaced by a non-zero pp-number if the
		implementation supports an attribute with the specified name, and by the pp-number
		0 otherwise.</p>
    <p>For a standard attribute, the value of the <code>__has_cpp_attribute</code>
	macro is based on the year and month in which the attribute was voted into the working
		draft. In the case where the attribute is vendor-specific, the value is implementation-defined.
		However, in most cases it is expected that the availability of an attribute can
		be detected by any non-zero result.</p>
    <p>The <code>#ifdef</code> and <code>#ifndef</code> directives, and the <code>defined</code>
	conditional inclusion operator, shall treat <code>__has_cpp_attribute</code> as
		if it were the name of a defined macro. The identifier <code>__has_cpp_attribute</code>
	shall not appear in any context not mentioned in this section.</p>
    <h4>Example</h4>
    <p>This demonstrates a way to use the attribute <code>[[deprecated]]</code> only
		if it is available.</p>
    <pre>#ifdef __has_cpp_attribute
#  if __has_cpp_attribute(deprecated)
#    define ATTR_DEPRECATED(msg) [[deprecated(msg)]]
#  else
#    define ATTR_DEPRECATED(msg)
#  endif
#endif</pre></blockquote>
-->
</body>
</html>
