<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title>endian</title>

	<style>
	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;
	}
	ins {color:#00A000}
	del {color:#A00000}
	code {white-space:pre;}
	</style>
</head>
<body>

<address align=right>
Document number: P0463R1<br>
<br/>
<br/>
<a href="mailto:howard.hinnant@gmail.com">Howard E. Hinnant</a><br/>
2017-07-13<br/>
</address>
<hr/>
<h1 align=center><code>endian</code>, Just <code>endian</code></h1>

<h2>Contents</h2>

<ul>
<li><a href="#Introduction">Introduction</a></li>
<li><a href="#Proposal">Proposal</a></li>
<li><a href="#Implementation">Implementation</a></li>
<li><a href="#Wording">Wording</a></li>
</ul>

<a name="Revision"></a><h2>Changes from R0</h2>

<ul>
<li>Tweak wording per LWG guidance.</li>
</ul>

<a name="Introduction"></a><h2>Introduction</h2>

<p>
A ancient, time-honored tradition among C++ programmers is detecting the
endian of their execution environment:
</p>

<blockquote><p>
<a href="http://stackoverflow.com/q/1001307/576911">Detecting endianness programmatically in a C++ program</a>
</p></blockquote>

<p>
There are many hacks that work <i>most</i> of the time.  None of them seem bullet proof.
Few give the answer as a compile-time constant.  And in every single case:
</p>

<blockquote><p><b>
The compiler knows the answer!
</b></p></blockquote>

<p>
It is a no-brainer for the committee to provide an API so that the programmer can query
the implementation for an answer to this common question.
</p>

<a name="Proposal"></a><h2>Proposal</h2>

<p>
Put into <code>&lt;type_traits&gt;</code>:
</p>

<blockquote><pre>
enum class endian
{
    little = __ORDER_LITTLE_ENDIAN__,
    big    = __ORDER_BIG_ENDIAN__,
    native = __BYTE_ORDER__
};
</pre></blockquote>

<p>
with appropriate constants for platforms that don't define <code>__BYTE_ORDER__</code>
et al.  That's it.  That's the entire proposal.
</p>

<p>
<u>Objection #1:</u> Some modern processors can switch endian at run time.  How can this
be a compile-time constant?
</p>

<blockquote><p>
No operating system tolerates switching endian at run time once an application has
launched.  Every compiler knows what endian it has to target.
</p></blockquote>

<p>
<u>Objection #2:</u> Where are the functions to translate scalars between native endian
and big or little endian?
</p>

<blockquote><p>
Those are good features to have.  But they do not represent everything that is needed.
And they can more easily be built on top of <code>class endian</code> once it exists.
At a minimum we need <code>class endian</code> as soon as possible (1998 would be nice).
This proposal aims to get the minimum required functionality in as quickly as possible.
</p></blockquote>

<p>
<u>Objection #3:</u> I am quite sure that PDP endian is on the way back in.  PDP is
neither big nor little endian.  This proposal doesn't handle that!
</p>

<blockquote><p>
<ol>
<li>This proposal handles "mixed endian" today by ensuring that
<code>endian::native</code> equals neither <code>endian::big</code> nor
<code>endian::little</code>.</li>
<li>Today, no C++14 compiler targets a machine that is not big endian or little
endian.</li>
<li>If tomorrow we need another flavor of endian, a new member could easily be
added to <code>class endian</code> with no backwards compatibility problems
(e.g. <code>endian::pdp</code>).</li>
</ol>
</p></blockquote>

<p>
<u>How do I use this?</u>
</p>

<blockquote><p>
You can either build compile-time traits with this, or use it at run time.  For example:
</p>

<pre>
if (endian::native == endian::big)
    // handle big endian
else if (endian::native == endian::little)
    // handle big endian
else
    // handle mixed endian
</pre>
</blockquote>

<p>
<u>Why not just a macro?</u>
</p>

<blockquote><p>
This API was chosen because there are a few times when a program needs to do
<i>more</i> than just query endianness.  Sometimes a program needs to either
<i>declare</i> or <i>request</i> endianness.  This API provides a universal way
of doing so.  For example a fingerprinting hash object such as
<a href="https://en.wikipedia.org/wiki/SHA-2">SHA-2</a> traffics in big endian.
This might be advertised like:
</p>

<blockquote><pre>
class sha256
{
public: 
    static constexpr std::endian endian = std::endian::big;
    // ...
</pre></blockquote>

<p>
The type <code>sha256</code> may need to meet a type concept that requires a public
nested value of type <code>std::endian</code> that specifies how input should be 
preprocessed, or that specifies how some of the output is encoded.  Details like this
are crucial for inter-machine communication.
</p></blockquote>

<a name="Implementation"></a><h2>Implementation</h2>

<blockquote><pre>
enum class endian
{
#ifdef _WIN32
    little = 0,
    big    = 1,
    native = little
#else
    little = __ORDER_LITTLE_ENDIAN__,
    big    = __ORDER_BIG_ENDIAN__
    native = __BYTE_ORDER__,
#endif
};
</pre></blockquote>

<p>
On the platform on which I'm writing this, this preprocesses to:
</p>

<blockquote><pre>
enum class endian
{
    little = 1234,
    big    = 4321,
    native = 1234
};
</pre></blockquote>


<a name="Wording"></a><h2>Wording</h2>

<ol>
<li>
<p>
Add to [meta.type.synop].
</p>
<blockquote><pre>
enum class endian
{
    little = <i>see below</i>,
    big    = <i>see below</i>,
    native = <i>see below</i>
};
</pre></blockquote>

</li>

<li>
<p>
Add a new section after [meta.logical]:
</p>
<blockquote>
<p>
<b>23.15.9 Endian [meta.endian]</b>
</p>
<p> 
Two common methods of byte ordering in multibyte scalar types are
big-endian and little-endian in the execution environment. Big-endian
is a format for storage of binary data in which the most significant
byte is placed first, with the rest in descending order. Little-endian
is a format for storage of binary data in which the least significant
byte is placed first, with the rest in ascending order. This subclause
describes the endianness of the scalar types of the execution
environment.
</p>
<pre>
enum class endian
{
    little = <i>see below</i>,
    big    = <i>see below</i>,
    native = <i>see below</i>
};
</pre>
<p>
If all scalar types have size 1, then all of
<code>endian::little</code>, <code>endian::big</code>, and
<code>endian::native</code> have the same value. Otherwise
<code>endian::little</code> shall not be equal to
<code>endian::big</code>. If all scalar types are big-endian,
<code>endian::native</code> shall be equal to
<code>endian::big</code>. If all scalar types are little-endian,
<code>endian::native</code> shall be equal to
<code>endian::little</code>. Otherwise <code>endian::native</code>
shall have a value that is not equal to either of
<code>endian::big</code> nor <code>endian::little</code>.
</p>

</blockquote>
</li>

</ol>

</body>
</html>
