endian: be less clever with value operators

This commit is contained in:
Danny Robson 2019-02-03 16:37:08 +11:00
parent 5218fa8165
commit f41ffe339c

View File

@ -3,14 +3,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
* *
* Copyright 2010-2014 Danny Robson <danny@nerdcruft.net> * Copyright 2010-2019 Danny Robson <danny@nerdcruft.net>
*/ */
#ifndef __UTIL_ENDIAN_HPP #pragma once
#define __UTIL_ENDIAN_HPP
#include "std.hpp" #include "std.hpp"
#include "types/bits.hpp" #include "types/bits.hpp"
#include "cast.hpp"
#include <cstring> #include <cstring>
#include <cstdint> #include <cstdint>
@ -206,25 +206,53 @@ namespace cruft {
namespace endian { namespace endian {
template <scheme StorageV, typename ValueT> template <scheme StorageV, typename RawT>
struct value { struct value {
constexpr RawT native (void) const { return convert<StorageV,scheme::native> (raw); }
operator ValueT () const operator RawT () const
{ {
return convert<StorageV,scheme::native> (raw); return native ();
} }
ValueT native (void) const { return *this; } decltype(auto) operator+ () const { return +native (); }
decltype(auto) operator+ () const { return +this->operator ValueT (); } constexpr value operator>> (std::size_t s) const {
RawT const val = native () >> s;
return { .raw = convert<scheme::native,StorageV> (val) };
}
constexpr value operator<< (std::size_t s) const {
RawT const val = native () << s;
return { .raw = convert<scheme::native,StorageV> (val) };
}
ValueT operator<< (size_t s) const { return convert<StorageV,scheme::native> (raw) << s; } value operator& (value rhs) const { return value { .raw = raw & rhs.raw }; }
auto& operator= (ValueT const &val) { raw = convert<scheme::native,StorageV> (val); return *this; } template <typename OperandT>
value operator& (OperandT rhs) const {
RawT const val = native () & rhs;
return { .raw = convert<scheme::native,StorageV> (val) };
}
ValueT raw; auto& operator= (RawT const &val) { raw = convert<scheme::native,StorageV> (val); return *this; }
bool operator== (value const &rhs) const { return raw == rhs.raw; }
RawT raw;
}; };
template <scheme StorageV, typename RawT, typename OperandT>
constexpr decltype(auto) operator== (value<StorageV,RawT> const &a, OperandT const &b)
{
return a.native () == b;
}
template <scheme StorageV, typename RawT, typename OperandT>
constexpr decltype(auto) operator== (OperandT const &a, value<StorageV,RawT> const &b)
{
return a == b.native ();
}
template <typename ValueT> using little = value<scheme::little,ValueT>; template <typename ValueT> using little = value<scheme::little,ValueT>;
template <typename ValueT> using big = value<scheme::big ,ValueT>; template <typename ValueT> using big = value<scheme::big ,ValueT>;
@ -246,6 +274,3 @@ namespace cruft {
using bi32 = endian::big<i32>; using bi32 = endian::big<i32>;
using bi64 = endian::big<i64>; using bi64 = endian::big<i64>;
} }
#endif