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
* 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
#define __UTIL_ENDIAN_HPP
#pragma once
#include "std.hpp"
#include "types/bits.hpp"
#include "cast.hpp"
#include <cstring>
#include <cstdint>
@ -206,25 +206,53 @@ namespace cruft {
namespace endian {
template <scheme StorageV, typename ValueT>
template <scheme StorageV, typename RawT>
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 big = value<scheme::big ,ValueT>;
@ -246,6 +274,3 @@ namespace cruft {
using bi32 = endian::big<i32>;
using bi64 = endian::big<i64>;
}
#endif