<html>

<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF8">

  <meta name="description" content="Proposal for C++ Standard">
  <meta name="keywords" content="C++,cplusplus,wg21">
  <meta name="author" content="Alisdair Meredith">

  <title>Nested Inline Namespaces</title>

  <style type="text/css">
    ins {background-color:#A0FFA0}
    del {background-color:#FFA0A0}
    p {text-align:justify}
    li {text-align:justify}
    blockquote.note
    {
      background-color:#E0E0E0;
      padding-left: 15px;
      padding-right: 15px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
    blockquote.recommend
    {
      background-color:#ffffb0;
      padding-left: 10px;
      padding-right: 10px;
      padding-top: 1px;
      padding-bottom: 1px;
    }
  </style>
</head>

<body>
<table>
<tr>
  <td align="left">Doc. no.</td>
  <td align="left">P1094R0</td>
</tr>
<tr>
  <td align="left">Date:</td>
  <td align="left">2018-05-07</td>
</tr>
<tr>
  <td align="left">Project:</td>
  <td align="left">Programming Language C++</td>
</tr>
<tr>
  <td align="left">Audience:</td>
  <td align="left">Evolution Working Group</td>
</tr>
<tr>
  <td align="left">Reply to:</td>
  <td align="left">Alisdair Meredith &lt;<a href="mailto:ameredith1@bloomberg.net">ameredith1@bloomberg.net</a>&gt;</td>
</tr>
</table>

<h1>Nested Inline Namespaces</h1>

<h2>Table of Contents</h2>
<ol start="0">
<li><a href="#rev.hist">Revision History</a></li>
  <ul>
  <li><a href="#rev.0">Revision 0</a></li>
  </ul>
<li><a href="#1.0">Introduction</a></li>
<li><a href="#2.0">Stating the problem</a></li>
<li><a href="#3.0">Propose Solution</a></li>
  <ul>
  <li><a href="#3.1">Compatibilty Concerns</a></li>
  </ul>
<li><a href="#4.0">Other Directions</a></li>
<li><a href="#5.0">Formal Wording</a></li>
<li><a href="#6.0">Acknowledgements</a></li>
<li><a href="#7.0">References</a></li>
</ol>


<h2><a name="rev.hist">Revision History</a></h2>

<h3><a name="rev.0">Revision 0</a></h3>
<p>
Original version of the paper for the 2017 post-Albuquerque mailing.
</p>

<h2><a name="1.0">1 Introduction</a></h2>
<p>
Inline namespaces are not supported in nested namespace definitiond,
and it is surprising that the "obvious" syntax is not supported.
</p>


<h2><a name="2.0">2 Stating the problem</a></h2>
<p>
While working on the header synopses for several TSes, it is apparent
how convenient the nested namespace feature is.  However, it is equally
surprising that the inline versioning namespace cannot be similarly
decalared.  For example, in the Concurrency TS v2 it would be nice to
specify the <tt>&lt;experimental/execution&gt;</tt> synopsis as:
</p>
<blockquote><pre>
namespace std::experimental::inline parallism_v2::execution {
  // 5.7, Unsequenced execution policy
  class unsequenced_policy;

  // 5.8, Vector execution policy
  class vector_policy;

  // 5.10, execution policy objects
  inline constexpr sequenced_policy seq{ unspecified };
  inline constexpr parallel_policy par{ unspecified };
}
</pre></blockquote>

<p>
Instead, must must open and close namespaces three separate times,
essentially rendering the nested namespace feature useless:
</p>

<blockquote><pre>
namespace std::experimental {
inline namespace parallism_v2 {
namespace execution {
  // 5.7, Unsequenced execution policy
  class unsequenced_policy;

  // 5.8, Vector execution policy
  class vector_policy;

  // 5.10, execution policy objects
  inline constexpr sequenced_policy seq{ unspecified };
  inline constexpr parallel_policy par{ unspecified };
}
}
}
</pre></blockquote>

<h3><a name="3.1">2.1 Impact on the Language</a></h3>
<p>
The concern raised is an inconvenient embarrassment, rather than a fundamental
flaw.  It would be nice to see this fixed, and hopefully should be possible
with a minimal investment of time by the committee.  If it is not seen as
immediately useful, it is probably not worth further committee time to discuss
alternative designs.
</p>


<h2><a name="3.0">3 Propose Solution</a></h2>
<p>
The proposed solution is fairly simple: allow the <tt>inline</tt> keyword
to optionally precede the identifier naming a namespace at each step of a
nested namespace declaration.  It is believed that editing the grammar is
a sufficient change, as the existing text can be interpreted to have the
right meaning after this change too.
</p>

<h3><a name="3.1">3.1 Compatibilty Concerns</a></h3>
<p>
The proposed solution is a pure extension where the new syntax was not
valid before, and could not show up even in a SFINAE context.  There are
not expected to be any backwards compatibility concerns.
</p>

<p>
A fine-grained feature macro is not warranted in this case, as use of
the macro to enable the convenience feature would be more work than the
convenience returned.  The regular <tt>__cplusplus</tt> macro should
suffice for those keep to create a codebase anticipating a future cleanup
that can assume this feature once support for older dialects (by that
user) is dropped.
</p>

<h2><a name="4.0">4 Other Directions</a></h2>
<p>
Given the existing syntax does not support an <tt>inline</tt> <i>before</i>
the <tt>namespace</tt> keyword for a nested namespace declaration, which is
the position required in the grammar for a non-nested namespace declaration,
careful consideration was given to supporting this as an option too, if for
no other reason than the notion of consistency.
</p>

<p>
This idea was rejected as potentially confusing.  Which namespace is intended
to be inline in such cases?  The trailing namespace?  The leading namespace?
All of the namespaces?  Requiring the <tt>inline</tt> keyword to precede the
namespace that it inlines cleanly resolves such concerns, so there should be
no other syntax supported to introduce such confusion, along with endless
style-guide debates.
</p>

<p>
It was also observed, while drafting this paper, that nested namespaces do
not support attributes.  That was deemed a separate issue beyond the scope
of this paper, and is not a topic the author is motivated to solve himself.
</p>


<h2><a name="5.0">5 Formal Wording</a></h2>
<p>
Make the following changes to the specified working paper:
</p>

<blockquote>

<h4>10.3.1 Namespace definition [namespace.def]</h4>
<blockquote><pre>
<i>namespace-name:</i>
    <i>identifier</i>
    <i>namespace-alias</i>

<i>namespace-definition:</i>
    <i>named-namespace-definition</i>
    <i>unnamed-namespace-definition</i>
    <i>nested-namespace-definition</i>

<i>named-namespace-definition:</i>
    <tt><b>inline</b></tt><sub><i>opt</i></sub> <tt><b>namespace</b></tt> <i>attribute-specifier-seq<sub>opt</sub> identifier </i><tt>{</tt><i> namespace-body </i><tt>}</tt>

<i>unnamed-namespace-definition:</i>
    <tt><b>inline</b></tt><sub><i>opt</i></sub> <tt><b>namespace</b></tt> <i>attribute-specifier-seq<sub>opt</sub> </i><tt>{</tt><i> namespace-body </i><tt>}</tt>

<i>nested-namespace-definition:</i>
    <tt><b>namespace</b></tt> <i>enclosing-namespace-specifier :: <ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins> identifier  </i><tt>{</tt><i> namespace-body </i><tt>}</tt>
    
<i>enclosing-namespace-specifier:</i>
    <ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins> <i>identifier</i>
    <i>enclosing-namespace-specifier :: <ins><tt><b>inline</b></tt><sub><i>opt</i></sub></ins> identifier</i>

<i>namespace-body :</i>
    <i>declaration-seq<sub>opt</sub></i>
</pre></blockquote>

</blockquote>

</body>
</html>
