raw: Make constexpr where possible

Change-Id: I6b2b60cd9cf73395a525e47074a83dafcf3a7136
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/include/stdplus/raw.hpp b/include/stdplus/raw.hpp
index 4f5b03f..5ac2a2f 100644
--- a/include/stdplus/raw.hpp
+++ b/include/stdplus/raw.hpp
@@ -1,4 +1,5 @@
 #pragma once
+#include <algorithm>
 #include <fmt/format.h>
 #include <span>
 #include <stdexcept>
@@ -53,12 +54,14 @@
  *  @return True if they are the same, false otherwise
  */
 template <typename A, typename B>
-bool equal(const A& a, const B& b) noexcept
+inline constexpr bool equal(const A& a, const B& b) noexcept
 {
     static_assert(std::is_trivially_copyable_v<A>);
     static_assert(std::is_trivially_copyable_v<B>);
     static_assert(sizeof(A) == sizeof(B));
-    return memcmp(&a, &b, sizeof(A)) == 0;
+    const auto a_byte = reinterpret_cast<const std::byte*>(&a);
+    const auto b_byte = reinterpret_cast<const std::byte*>(&b);
+    return std::equal(a_byte, a_byte + sizeof(A), b_byte);
 }
 
 /** @brief Copies data from a buffer into a copyable type
@@ -68,7 +71,7 @@
  */
 #define STDPLUS_COPY_FROM(func, comp)                                          \
     template <typename T, typename Container>                                  \
-    T func(const Container& c)                                                 \
+    inline constexpr T func(const Container& c)                                \
     {                                                                          \
         static_assert(std::is_trivially_copyable_v<T>);                        \
         static_assert(detail::trivialContainer<Container>);                    \
@@ -79,7 +82,9 @@
             throw std::runtime_error(                                          \
                 fmt::format(#func ": {} < {}", bytes, sizeof(ret)));           \
         }                                                                      \
-        std::memcpy(&ret, std::data(c), sizeof(ret));                          \
+        const auto c_bytes = reinterpret_cast<const std::byte*>(std::data(c)); \
+        const auto ret_bytes = reinterpret_cast<std::byte*>(&ret);             \
+        std::copy(c_bytes, c_bytes + sizeof(ret), ret_bytes);                  \
         return ret;                                                            \
     }
 STDPLUS_COPY_FROM(copyFrom, <)
@@ -94,7 +99,7 @@
 #define STDPLUS_REF_FROM(func, comp)                                           \
     template <typename T, typename Container,                                  \
               typename Tp = detail::copyConst<T, detail::dataType<Container>>> \
-    Tp& func(Container&& c)                                                    \
+    inline constexpr Tp& func(Container&& c)                                   \
     {                                                                          \
         static_assert(std::is_trivially_copyable_v<Tp>);                       \
         static_assert(detail::trivialContainer<Container>);                    \
@@ -118,7 +123,7 @@
  *  @return The copyable type with data populated
  */
 template <typename T, typename CharT>
-T extract(std::basic_string_view<CharT>& data)
+inline constexpr T extract(std::basic_string_view<CharT>& data)
 {
     T ret = copyFrom<T>(data);
     static_assert(sizeof(T) % sizeof(CharT) == 0);
@@ -127,7 +132,7 @@
 }
 template <typename T, typename IntT,
           typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>>
-T extract(std::span<IntT>& data)
+inline constexpr T extract(std::span<IntT>& data)
 {
     T ret = copyFrom<T>(data);
     static_assert(sizeof(T) % sizeof(IntT) == 0);
@@ -142,7 +147,7 @@
  *  @return A reference to the data
  */
 template <typename T, typename CharT>
-const T& extractRef(std::basic_string_view<CharT>& data)
+inline constexpr const T& extractRef(std::basic_string_view<CharT>& data)
 {
     const T& ret = refFrom<T>(data);
     static_assert(sizeof(T) % sizeof(CharT) == 0);
@@ -152,7 +157,7 @@
 template <typename T, typename IntT,
           typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>,
           typename Tp = detail::copyConst<T, IntT>>
-Tp& extractRef(std::span<IntT>& data)
+inline constexpr Tp& extractRef(std::span<IntT>& data)
 {
     Tp& ret = refFrom<Tp>(data);
     static_assert(sizeof(Tp) % sizeof(IntT) == 0);
@@ -167,7 +172,8 @@
  *  @return A view over the input with the given output integral type
  */
 template <typename CharT, typename T>
-std::enable_if_t<!detail::hasData<T>, std::basic_string_view<CharT>>
+inline constexpr std::enable_if_t<!detail::hasData<T>,
+                                  std::basic_string_view<CharT>>
     asView(const T& t) noexcept
 {
     static_assert(std::is_trivially_copyable_v<T>);
@@ -176,7 +182,8 @@
 }
 
 template <typename CharT, typename Container>
-std::enable_if_t<detail::hasData<Container>, std::basic_string_view<CharT>>
+inline constexpr std::enable_if_t<detail::hasData<Container>,
+                                  std::basic_string_view<CharT>>
     asView(const Container& c) noexcept
 {
     static_assert(detail::trivialContainer<Container>);
@@ -189,7 +196,7 @@
           typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>,
           typename = std::enable_if_t<!detail::hasData<T>>,
           typename IntTp = detail::copyConst<IntT, T>>
-std::span<IntTp> asSpan(T& t) noexcept
+inline constexpr std::span<IntTp> asSpan(T& t) noexcept
 {
     static_assert(std::is_trivially_copyable_v<T>);
     static_assert(sizeof(T) % sizeof(IntTp) == 0);
@@ -199,7 +206,7 @@
           typename = std::enable_if_t<std::is_trivially_copyable_v<IntT>>,
           typename = std::enable_if_t<detail::hasData<Container>>,
           typename IntTp = detail::copyConst<IntT, detail::dataType<Container>>>
-std::span<IntTp> asSpan(Container&& c) noexcept
+inline constexpr std::span<IntTp> asSpan(Container&& c) noexcept
 {
     static_assert(detail::trivialContainer<Container>);
     static_assert(sizeof(*std::data(c)) % sizeof(IntTp) == 0);