numeric/endian: Add generic endian conversion function

This enables us to convert to big or little endian based on a template
sepcifier, giving us more flexibility than network endian.

Change-Id: I0d4ef177e907163699ac1e458294756f5208651e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/numeric/endian.hpp b/include/stdplus/numeric/endian.hpp
index bd3199b..39487ac 100644
--- a/include/stdplus/numeric/endian.hpp
+++ b/include/stdplus/numeric/endian.hpp
@@ -86,16 +86,38 @@
     return n;
 }
 
-template <typename T>
-constexpr T hton(T n) noexcept
+template <std::endian E, typename T>
+constexpr T htoe(T t) noexcept
 {
     if constexpr (std::endian::native == std::endian::big)
     {
-        return n;
+        if constexpr (E == std::endian::big)
+        {
+            return t;
+        }
+        else if constexpr (E == std::endian::little)
+        {
+            return bswap(t);
+        }
+        else
+        {
+            static_assert(std::is_same_v<T, void>);
+        }
     }
     else if constexpr (std::endian::native == std::endian::little)
     {
-        return bswap(n);
+        if constexpr (E == std::endian::big)
+        {
+            return bswap(t);
+        }
+        else if constexpr (E == std::endian::little)
+        {
+            return t;
+        }
+        else
+        {
+            static_assert(std::is_same_v<T, void>);
+        }
     }
     else
     {
@@ -103,10 +125,46 @@
     }
 }
 
-template <typename T>
-constexpr T ntoh(T n) noexcept
+template <std::endian E, typename T>
+constexpr T etoh(T t) noexcept
 {
-    return hton(n);
+    return htoe<E>(t);
+}
+
+template <typename T>
+constexpr T htob(T t) noexcept
+{
+    return htoe<std::endian::big>(t);
+}
+
+template <typename T>
+constexpr T btoh(T t) noexcept
+{
+    return etoh<std::endian::big>(t);
+}
+
+template <typename T>
+constexpr T htol(T t) noexcept
+{
+    return htoe<std::endian::little>(t);
+}
+
+template <typename T>
+constexpr T ltoh(T t) noexcept
+{
+    return etoh<std::endian::little>(t);
+}
+
+template <typename T>
+constexpr T hton(T t) noexcept
+{
+    return htoe<std::endian::big>(t);
+}
+
+template <typename T>
+constexpr T ntoh(T t) noexcept
+{
+    return etoh<std::endian::big>(t);
 }
 
 } // namespace stdplus