// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// This header contains implementations of the types in the Emboss Prelude
// (UInt, Int, Flag, etc.)
#ifndef EMBOSS_RUNTIME_CPP_EMBOSS_PRELUDE_H_
#define EMBOSS_RUNTIME_CPP_EMBOSS_PRELUDE_H_

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include <limits>
#include <type_traits>
#include <utility>

#include "runtime/cpp/emboss_cpp_util.h"

// Forward declarations for optional text processing helpers.
namespace emboss {
class TextOutputOptions;
namespace support {
template <class Stream, class View>
bool ReadBooleanFromTextStream(View *view, Stream *stream);
template <class Stream, class View>
void WriteBooleanViewToTextStream(View *view, Stream *stream,
                                  const TextOutputOptions &);

template <class Stream, class View>
bool ReadIntegerFromTextStream(View *view, Stream *stream);
template <class Stream, class View>
void WriteIntegerViewToTextStream(View *view, Stream *stream,
                                  const TextOutputOptions &options);

template <class Stream, class View>
bool ReadFloatFromTextStream(View *view, Stream *stream);
template <class Stream, class Float>
void WriteFloatToTextStream(Float n, Stream *stream,
                            const TextOutputOptions &options);
}  // namespace support
}  // namespace emboss

// This namespace must match the [(cpp) namespace] in the Emboss prelude.
namespace emboss {
namespace prelude {

// FlagView is the C++ implementation of the Emboss "Flag" type, which is a
// 1-bit value.
template <class Parameters, class BitBlock>
class FlagView final {
 public:
  static_assert(Parameters::kBits == 1, "FlagView must be 1 bit.");

  explicit FlagView(BitBlock bits) : bit_block_{bits} {}
  FlagView() : bit_block_() {}
  FlagView(const FlagView &) = default;
  FlagView(FlagView &&) = default;
  FlagView &operator=(const FlagView &) = default;
  FlagView &operator=(FlagView &&) = default;
  ~FlagView() = default;

  bool Read() const {
    bool result = bit_block_.ReadUInt();
    EMBOSS_CHECK(Parameters::ValueIsOk(result));
    return result;
  }
  bool UncheckedRead() const { return bit_block_.UncheckedReadUInt(); }
  void Write(bool value) const {
    const bool result = TryToWrite(value);
    (void)result;
    EMBOSS_CHECK(result);
  }
  bool TryToWrite(bool value) const {
    if (!CouldWriteValue(value)) return false;
    if (!IsComplete()) return false;
    bit_block_.WriteUInt(value);
    return true;
  }
  static constexpr bool CouldWriteValue(bool value) {
    return Parameters::ValueIsOk(value);
  }
  void UncheckedWrite(bool value) const {
    bit_block_.UncheckedWriteUInt(value);
  }

  template <typename OtherView>
  void CopyFrom(const OtherView &other) const {
    Write(other.Read());
  }
  template <typename OtherView>
  void UncheckedCopyFrom(const OtherView &other) const {
    UncheckedWrite(other.UncheckedRead());
  }
  template <typename OtherView>
  bool TryToCopyFrom(const OtherView &other) const {
    return TryToWrite(other.Read());
  }

  bool Ok() const {
    return IsComplete() && Parameters::ValueIsOk(UncheckedRead());
  }
  template <class OtherBitBlock>
  bool Equals(const FlagView<Parameters, OtherBitBlock> &other) const {
    return Read() == other.Read();
  }
  template <class OtherBitBlock>
  bool UncheckedEquals(const FlagView<Parameters, OtherBitBlock> &other) const {
    return UncheckedRead() == other.UncheckedRead();
  }
  bool IsComplete() const {
    return bit_block_.Ok() && bit_block_.SizeInBits() > 0;
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    return ::emboss::support::ReadBooleanFromTextStream(this, stream);
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         const ::emboss::TextOutputOptions &options) const {
    ::emboss::support::WriteBooleanViewToTextStream(this, stream, options);
  }

  static constexpr bool IsAggregate() { return false; }

 private:
  BitBlock bit_block_;
};

// UIntView is a view for UInts inside of bitfields.
template <class Parameters, class BitViewType>
class UIntView final {
 public:
  using ValueType = typename ::emboss::support::LeastWidthInteger<
      Parameters::kBits>::Unsigned;

  static_assert(
      Parameters::kBits <= sizeof(ValueType) * 8,
      "UIntView requires sizeof(ValueType) * 8 >= Parameters::kBits.");

  template <typename... Args>
  explicit UIntView(Args &&...args) : buffer_{::std::forward<Args>(args)...} {}
  UIntView() : buffer_() {}
  UIntView(const UIntView &) = default;
  UIntView(UIntView &&) = default;
  UIntView &operator=(const UIntView &) = default;
  UIntView &operator=(UIntView &&) = default;
  ~UIntView() = default;

  ValueType Read() const {
    ValueType result = static_cast<ValueType>(buffer_.ReadUInt());
    EMBOSS_CHECK(Parameters::ValueIsOk(result));
    return result;
  }
  ValueType UncheckedRead() const { return buffer_.UncheckedReadUInt(); }

  // The Write, TryToWrite, and CouldWriteValue methods are templated in order
  // to avoid surprises due to implicit narrowing.
  //
  // In C++, you can pass (say) an `int` to a function expecting `uint8_t`, and
  // the compiler will silently cast the `int` to `uint8_t`, which can change
  // the value.  Even with fairly aggressive warnings, something like this will
  // silently compile, and print `256 is not >= 128!`:
  //
  //    bool is_big_uint8(uint8_t value) { return value >= 128; }
  //    bool is_big(uint32_t value) { return is_big_uint8(value); }
  //    int main() {
  //        assert(!is_big(256));  // big is truncated to 0.
  //        std::cout << 256 << " is not >= 128!\n";
  //        return 0;
  //    }
  //
  // (Most compilers will give a warning when directly passing a *constant* that
  // gets truncated; for example, GCC will throw -Woverflow on
  // `is_big_uint8(256U)`.)
  template <typename IntT,
            typename = typename ::std::enable_if<
                (::std::numeric_limits<typename ::std::remove_cv<
                     typename ::std::remove_reference<IntT>::type>::type>::
                     is_integer &&
                 !::std::is_same<bool, typename ::std::remove_cv<
                                           typename ::std::remove_reference<
                                               IntT>::type>::type>::value) ||
                ::std::is_enum<IntT>::value>::type>
  void Write(IntT value) const {
    const bool result = TryToWrite(value);
    (void)result;
    EMBOSS_CHECK(result);
  }

  template <typename IntT,
            typename = typename ::std::enable_if<
                (::std::numeric_limits<typename ::std::remove_cv<
                     typename ::std::remove_reference<IntT>::type>::type>::
                     is_integer &&
                 !::std::is_same<bool, typename ::std::remove_cv<
                                           typename ::std::remove_reference<
                                               IntT>::type>::type>::value) ||
                ::std::is_enum<IntT>::value>::type>
  bool TryToWrite(IntT value) const {
    if (!CouldWriteValue(value)) return false;
    if (!IsComplete()) return false;
    buffer_.WriteUInt(static_cast<ValueType>(value));
    return true;
  }

  template <typename IntT,
            typename = typename ::std::enable_if<
                (::std::numeric_limits<typename ::std::remove_cv<
                     typename ::std::remove_reference<IntT>::type>::type>::
                     is_integer &&
                 !::std::is_same<bool, typename ::std::remove_cv<
                                           typename ::std::remove_reference<
                                               IntT>::type>::type>::value) ||
                ::std::is_enum<IntT>::value>::type>
  static constexpr bool CouldWriteValue(IntT value) {
    // Implicit conversions are doing some work here, but the upshot is that the
    // value must be at least 0, and at most (2**kBits)-1.  The clause to
    // compute (2**kBits)-1 should not be "simplified" further.
    //
    // Because of C++ implicit integer promotions, the (2**kBits)-1 computation
    // works differently when `ValueType` is smaller than `unsigned int` than it
    // does when `ValueType` is at least as big as `unsigned int`.
    //
    // For example, when `ValueType` is `uint8_t` and `kBits` is 8:
    //
    // 1.   `static_cast<ValueType>(1)` becomes `uint8_t(1)`.
    // 2.   `uint8_t(1) << (kBits - 1)` is `uint8_t(1) << 7`.
    // 3.   The shift operator `<<` promotes its left operand to `unsigned`,
    //      giving `unsigned(1) << 7`.
    // 4.   `unsigned(1) << 7` becomes `unsigned(0x80)`.
    // 5.   `unsigned(0x80) << 1` becomes `unsigned(0x100)`.
    // 6.   Finally, `unsigned(0x100) - 1` is `unsigned(0xff)`.
    //
    // (Note that the cases where `kBits` is less than `sizeof(ValueType) * 8`
    // are very similar.)
    //
    // When `ValueType` is `uint32_t`, `unsigned` is 32 bits, and `kBits` is 32:
    //
    // 1.   `static_cast<ValueType>(1)` becomes `uint32_t(1)`.
    // 2.   `uint32_t(1) << (kBits - 1)` is `uint32_t(1) << 31`.
    // 3.   The shift operator `<<` does *not* further promote `uint32_t`.
    // 4.   `uint32_t(1) << 31` becomes `uint32_t(0x80000000)`.  Note that
    //      `uint32_t(1) << 32` would be undefined behavior (shift of >= the
    //      size of the left operand type), which is why the shift is broken
    //      into two parts.
    // 5.   `uint32_t(0x80000000) << 1` overflows, leaving `uint32_t(0)`.
    // 6.   `uint32_t(0) - 1` underflows, leaving `uint32_t(0xffffffff)`.
    //
    // Because unsigned overflow and underflow are defined to be modulo 2**N,
    // where N is the number of bits in the type, this is entirely
    // standards-compliant.
    return value >= 0 &&
           static_cast</**/ ::std::uint64_t>(value) <=
               ((static_cast<ValueType>(1) << (Parameters::kBits - 1)) << 1) -
                   1 &&
           Parameters::ValueIsOk(value);
  }
  void UncheckedWrite(ValueType value) const {
    buffer_.UncheckedWriteUInt(value);
  }

  template <typename OtherView>
  void CopyFrom(const OtherView &other) const {
    Write(other.Read());
  }
  template <typename OtherView>
  void UncheckedCopyFrom(const OtherView &other) const {
    UncheckedWrite(other.UncheckedRead());
  }
  template <typename OtherView>
  bool TryToCopyFrom(const OtherView &other) const {
    return other.Ok() && TryToWrite(other.Read());
  }

  // All bit patterns in the underlying buffer are valid, so Ok() is always
  // true if IsComplete() is true.
  bool Ok() const {
    return IsComplete() && Parameters::ValueIsOk(UncheckedRead());
  }
  template <class OtherBitViewType>
  bool Equals(const UIntView<Parameters, OtherBitViewType> &other) const {
    return Read() == other.Read();
  }
  template <class OtherBitViewType>
  bool UncheckedEquals(
      const UIntView<Parameters, OtherBitViewType> &other) const {
    return UncheckedRead() == other.UncheckedRead();
  }
  bool IsComplete() const {
    return buffer_.Ok() && buffer_.SizeInBits() >= Parameters::kBits;
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    return support::ReadIntegerFromTextStream(this, stream);
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         ::emboss::TextOutputOptions &options) const {
    support::WriteIntegerViewToTextStream(this, stream, options);
  }

  static constexpr bool IsAggregate() { return false; }

  static constexpr int SizeInBits() { return Parameters::kBits; }

 private:
  BitViewType buffer_;
};

// IntView is a view for Ints inside of bitfields.
template <class Parameters, class BitViewType>
class IntView final {
 public:
  using ValueType =
      typename ::emboss::support::LeastWidthInteger<Parameters::kBits>::Signed;

  static_assert(Parameters::kBits <= sizeof(ValueType) * 8,
                "IntView requires sizeof(ValueType) * 8 >= Parameters::kBits.");

  template <typename... Args>
  explicit IntView(Args &&...args) : buffer_{::std::forward<Args>(args)...} {}
  IntView() : buffer_() {}
  IntView(const IntView &) = default;
  IntView(IntView &&) = default;
  IntView &operator=(const IntView &) = default;
  IntView &operator=(IntView &&) = default;
  ~IntView() = default;

  ValueType Read() const {
    ValueType value = ConvertToSigned(buffer_.ReadUInt());
    EMBOSS_CHECK(Parameters::ValueIsOk(value));
    return value;
  }
  ValueType UncheckedRead() const {
    return ConvertToSigned(buffer_.UncheckedReadUInt());
  }
  // As with UIntView, above, Write, TryToWrite, and CouldWriteValue need to be
  // templated in order to avoid surprises due to implicit narrowing
  // conversions.
  template <typename IntT,
            typename = typename ::std::enable_if<
                (::std::numeric_limits<typename ::std::remove_cv<
                     typename ::std::remove_reference<IntT>::type>::type>::
                     is_integer &&
                 !::std::is_same<bool, typename ::std::remove_cv<
                                           typename ::std::remove_reference<
                                               IntT>::type>::type>::value) ||
                ::std::is_enum<IntT>::value>::type>
  void Write(IntT value) const {
    const bool result = TryToWrite(value);
    (void)result;
    EMBOSS_CHECK(result);
  }

  template <typename IntT,
            typename = typename ::std::enable_if<
                (::std::numeric_limits<typename ::std::remove_cv<
                     typename ::std::remove_reference<IntT>::type>::type>::
                     is_integer &&
                 !::std::is_same<bool, typename ::std::remove_cv<
                                           typename ::std::remove_reference<
                                               IntT>::type>::type>::value) ||
                ::std::is_enum<IntT>::value>::type>
  bool TryToWrite(IntT value) const {
    if (!CouldWriteValue(value)) return false;
    if (!IsComplete()) return false;
    buffer_.WriteUInt(::emboss::support::MaskToNBits(
        static_cast<typename BitViewType::ValueType>(value),
        Parameters::kBits));
    return true;
  }

  template <typename IntT,
            typename = typename ::std::enable_if<
                (::std::numeric_limits<typename ::std::remove_cv<
                     typename ::std::remove_reference<IntT>::type>::type>::
                     is_integer &&
                 !::std::is_same<bool, typename ::std::remove_cv<
                                           typename ::std::remove_reference<
                                               IntT>::type>::type>::value) ||
                ::std::is_enum<IntT>::value>::type>
  static constexpr bool CouldWriteValue(IntT value) {
    // This effectively checks that value >= -(2**(kBits-1) and value <=
    // (2**(kBits-1))-1.
    //
    // This has to be done somewhat piecemeal, in order to avoid various bits of
    // undefined and implementation-defined behavior.
    //
    // First, if IntT is an unsigned type, the check that value >=
    // -(2**(kBits-1)) is skipped, in order to avoid any signed <-> unsigned
    // conversions.
    //
    // Second, if kBits is 1, then the limits -1 and 0 are explicit, so that
    // there is never a shift by -1 (which is undefined behavior).
    //
    // Third, the shifts are by (kBits - 2), so that they do not alter sign
    // bits.  To get the final bounds, we use a bit of addition and
    // multiplication.  For example, for 8 bits, the lower bound is (1 << 6) *
    // -2, which is 64 * -2, which is -128.  The corresponding upper bound is
    // ((1 << 6) - 1) * 2 + 1, which is (64 - 1) * 2 + 1, which is 63 * 2 + 1,
    // which is 126 + 1, which is 127.  The upper bound must be computed in
    // multiple steps like this in order to avoid overflow.
    return (!::std::is_signed<typename ::std::remove_cv<
                typename ::std::remove_reference<IntT>::type>::type>::value ||
            static_cast</**/ ::std::int64_t>(value) >=
                (Parameters::kBits == 1
                     ? -1
                     : (static_cast<ValueType>(1) << (Parameters::kBits - 2)) *
                           -2)) &&
           value <=
               (Parameters::kBits == 1
                    ? 0
                    : ((static_cast<ValueType>(1) << (Parameters::kBits - 2)) -
                       1) * 2 +
                          1) &&
           Parameters::ValueIsOk(value);
  }

  void UncheckedWrite(ValueType value) const {
    buffer_.UncheckedWriteUInt(::emboss::support::MaskToNBits(
        static_cast<typename BitViewType::ValueType>(value),
        Parameters::kBits));
  }

  template <typename OtherView>
  void CopyFrom(const OtherView &other) const {
    Write(other.Read());
  }
  template <typename OtherView>
  void UncheckedCopyFrom(const IntView &other) const {
    UncheckedWrite(other.UncheckedRead());
  }
  template <typename OtherView>
  bool TryToCopyFrom(const OtherView &other) const {
    return other.Ok() && TryToWrite(other.Read());
  }

  // All bit patterns in the underlying buffer are valid, so Ok() is always
  // true if IsComplete() is true.
  bool Ok() const {
    return IsComplete() && Parameters::ValueIsOk(UncheckedRead());
  }
  template <class OtherBitViewType>
  bool Equals(const IntView<Parameters, OtherBitViewType> &other) const {
    return Read() == other.Read();
  }
  template <class OtherBitViewType>
  bool UncheckedEquals(
      const IntView<Parameters, OtherBitViewType> &other) const {
    return UncheckedRead() == other.UncheckedRead();
  }
  bool IsComplete() const {
    return buffer_.Ok() && buffer_.SizeInBits() >= Parameters::kBits;
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    return support::ReadIntegerFromTextStream(this, stream);
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         ::emboss::TextOutputOptions &options) const {
    support::WriteIntegerViewToTextStream(this, stream, options);
  }

  static constexpr bool IsAggregate() { return false; }

  static constexpr int SizeInBits() { return Parameters::kBits; }

 private:
  static ValueType ConvertToSigned(typename BitViewType::ValueType data) {
    static_assert(sizeof(ValueType) <= sizeof(typename BitViewType::ValueType),
                  "Integer types wider than BitViewType::ValueType are not "
                  "supported.");
#if EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT
    // static_cast from unsigned to signed is implementation-defined when the
    // value does not fit in the signed type (in this case, when the final value
    // should be negative).  Most implementations use a reasonable definition,
    // so on most systems we can just cast.
    //
    // If the integer does not take up the full width of ValueType, it needs to
    // be sign-extended until it does.  The easiest way to do this is to shift
    // until the sign bit is in the topmost position, then cast to signed, then
    // shift back.  The shift back will copy the sign bit.
    return static_cast<ValueType>(
               data << (sizeof(ValueType) * 8 - Parameters::kBits)) >>
           (sizeof(ValueType) * 8 - Parameters::kBits);
#else
    // Otherwise, in order to convert without running into
    // implementation-defined behavior, first mask out the sign bit.  This
    // results in (final result MOD 2 ** (width of int in bits - 1)).  That
    // value can be safely converted to the signed ValueType.
    //
    // Finally, if the sign bit was set, subtract (2 ** (width of int in bits -
    // 2)) twice.
    //
    // The 1-bit signed integer case must be handled separately, but it is
    // (fortunately) quite easy to enumerate both possible values.
    if (Parameters::kBits == 1) {
      if (data == 0) {
        return 0;
      } else if (data == 1) {
        return -1;
      } else {
        EMBOSS_CHECK(false);
        return -1;  // Return value if EMBOSS_CHECK is disabled.
      }
    } else {
      typename BitViewType::ValueType sign_bit =
          static_cast<typename BitViewType::ValueType>(1)
          << (Parameters::kBits - 1);
      typename BitViewType::ValueType mask = sign_bit - 1;
      typename BitViewType::ValueType data_mod2_to_n = mask & data;
      ValueType result_sign_bit =
          static_cast<ValueType>((data & sign_bit) >> 1);
      return data_mod2_to_n - result_sign_bit - result_sign_bit;
    }
#endif
  }

  BitViewType buffer_;
};

// The maximum Binary-Coded Decimal (BCD) value that fits in a particular number
// of bits.
template <typename ValueType>
constexpr inline ValueType MaxBcd(int bits) {
  return bits < 4 ? (1 << bits) - 1
                  : 10 * (MaxBcd<ValueType>(bits - 4) + 1) - 1;
}

template <typename ValueType>
inline bool IsBcd(ValueType x) {
  // Adapted from:
  // https://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord
  //
  // This determines if any nibble has a value greater than 9.  It does
  // this by treating operations on the n-bit value as parallel operations
  // on n/4 4-bit values.
  //
  // The result is computed in the high bit of each nibble: if any of those
  // bits is set in the end, then at least one nibble had a value in the
  // range 10-15.
  //
  // The first check is subtle: ~x is equivalent to (nibble = 15 - nibble).
  // Then, 6 is subtracted from each nibble.  This operation will underflow
  // if the original value was more than 9, leaving the high bit of the
  // nibble set.  It will also leave the high bit of the nibble set
  // (without underflow) if the original value was 0 or 1.
  //
  // The second check is just x: the high bit of each nibble in x is set if
  // that nibble's value is 8-15.
  //
  // Thus, the first check leaves the high bit set in any nibble with the
  // value 0, 1, or 10-15, and the second check leaves the high bit set in
  // any nibble with the value 8-15.  Bitwise-anding these results, high
  // bits are only set if the original value was 10-15.
  //
  // The underflow condition in the first check can screw up the condition
  // for nibbles in higher positions than the underflowing nibble.  This
  // cannot affect the overall boolean result, because the underflow
  // condition only happens if a nibble was greater than 9, and therefore
  // *that* nibble's final value will be nonzero, and therefore the whole
  // result will be nonzero, no matter what happens in the higher-order
  // nibbles.
  //
  // A couple of examples in 16 bit:
  //
  // x = 0x09a8
  // (~0x09a8 - 0x6666) & 0x09a8 & 0x8888
  // ( 0xf657 - 0x6666) & 0x09a8 & 0x8888
  //            0x8ff1  & 0x09a8 & 0x8888
  //                      0x09a0 & 0x8888
  //                               0x0880  Note the underflow into nibble 2
  //
  // x = 0x1289
  // (~0x1289 - 0x6666) & 0x1289 & 0x8888
  // ( 0xed76 - 0x6666) & 0x1289 & 0x8888
  //            0x8710  & 0x1289 & 0x8888
  //                      0x0200 & 0x8888
  //                               0x0000
  static_assert(!::std::is_signed<ValueType>::value,
                "IsBcd only works on unsigned values.");
  if (sizeof(ValueType) < sizeof(unsigned)) {
    // For types with lower integer conversion rank than unsigned int, integer
    // promotion rules cause many implicit conversions to signed int in the math
    // below, which makes the math go wrong.  Rather than add a dozen explicit
    // casts back to ValueType, just do the math as 'unsigned'.
    return IsBcd<unsigned>(x);
  } else {
    return ((~x - (~ValueType{0} / 0xf * 0x6 /* 0x6666...6666 */)) & x &
            (~ValueType{0} / 0xf * 0x8 /* 0x8888...8888 */)) == 0;
  }
}

// Base template for Binary-Coded Decimal (BCD) unsigned integer readers.
template <class Parameters, class BitViewType>
class BcdView final {
 public:
  using ValueType = typename ::emboss::support::LeastWidthInteger<
      Parameters::kBits>::Unsigned;

  static_assert(Parameters::kBits <= sizeof(ValueType) * 8,
                "BcdView requires sizeof(ValueType) * 8 >= Parameters::kBits.");

  template <typename... Args>
  explicit BcdView(Args &&...args) : buffer_{::std::forward<Args>(args)...} {}
  BcdView() : buffer_() {}
  BcdView(const BcdView &) = default;
  BcdView(BcdView &&) = default;
  BcdView &operator=(const BcdView &) = default;
  BcdView &operator=(BcdView &&) = default;
  ~BcdView() = default;

  ValueType Read() const {
    EMBOSS_CHECK(Ok());
    return ConvertToBinary(buffer_.ReadUInt());
  }
  ValueType UncheckedRead() const {
    return ConvertToBinary(buffer_.UncheckedReadUInt());
  }
  void Write(ValueType value) const {
    const bool result = TryToWrite(value);
    (void)result;
    EMBOSS_CHECK(result);
  }
  bool TryToWrite(ValueType value) const {
    if (!CouldWriteValue(value)) return false;
    if (!IsComplete()) return false;
    buffer_.WriteUInt(ConvertToBcd(value));
    return true;
  }
  static constexpr bool CouldWriteValue(ValueType value) {
    return value <= MaxValue() && Parameters::ValueIsOk(value);
  }
  void UncheckedWrite(ValueType value) const {
    buffer_.UncheckedWriteUInt(ConvertToBcd(value));
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    return support::ReadIntegerFromTextStream(this, stream);
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         ::emboss::TextOutputOptions &options) const {
    // TODO(bolms): This shares the numeric_base() option with IntView and
    // UIntView (and EnumView, for unknown enum values).  It seems like an end
    // user might prefer to see BCD values in decimal, even if they want to see
    // values of other numeric types in hex or binary.  It seems like there
    // could be some fancy C++ trickery to allow separate options for separate
    // view types.
    support::WriteIntegerViewToTextStream(this, stream, options);
  }

  static constexpr bool IsAggregate() { return false; }

  template <typename OtherView>
  void CopyFrom(const OtherView &other) const {
    Write(other.Read());
  }
  template <typename OtherView>
  void UncheckedCopyFrom(const OtherView &other) const {
    UncheckedWrite(other.UncheckedRead());
  }
  template <typename OtherView>
  bool TryToCopyFrom(const OtherView &other) const {
    return other.Ok() && TryToWrite(other.Read());
  }

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!IsBcd(buffer_.ReadUInt())) return false;
    if (!Parameters::ValueIsOk(UncheckedRead())) return false;
    return true;
  }
  template <class OtherBitViewType>
  bool Equals(const BcdView<Parameters, OtherBitViewType> &other) const {
    return Read() == other.Read();
  }
  template <class OtherBitViewType>
  bool UncheckedEquals(
      const BcdView<Parameters, OtherBitViewType> &other) const {
    return UncheckedRead() == other.UncheckedRead();
  }
  bool IsComplete() const {
    return buffer_.Ok() && buffer_.SizeInBits() >= Parameters::kBits;
  }

  static constexpr int SizeInBits() { return Parameters::kBits; }

 private:
  static ValueType ConvertToBinary(ValueType bcd_value) {
    ValueType result = 0;
    ValueType multiplier = 1;
    for (int shift = 0; shift < Parameters::kBits; shift += 4) {
      result += ((bcd_value >> shift) & 0xf) * multiplier;
      multiplier *= 10;
    }
    return result;
  }

  static ValueType ConvertToBcd(ValueType value) {
    ValueType bcd_value = 0;
    for (int shift = 0; shift < Parameters::kBits; shift += 4) {
      bcd_value |= (value % 10) << shift;
      value /= 10;
    }
    return bcd_value;
  }

  static constexpr ValueType MaxValue() {
    return MaxBcd<ValueType>(Parameters::kBits);
  }

  BitViewType buffer_;
};

// FloatView is the view for the Emboss Float type.
template <class Parameters, class BitViewType>
class FloatView final {
  static_assert(Parameters::kBits == 32 || Parameters::kBits == 64,
                "Only 32- and 64-bit floats are currently supported.");

 public:
  using ValueType = typename support::FloatType<Parameters::kBits>::Type;

  template <typename... Args>
  explicit FloatView(Args &&...args) : buffer_{::std::forward<Args>(args)...} {}
  FloatView() : buffer_() {}
  FloatView(const FloatView &) = default;
  FloatView(FloatView &&) = default;
  FloatView &operator=(const FloatView &) = default;
  FloatView &operator=(FloatView &&) = default;
  ~FloatView() = default;

  ValueType Read() const { return ConvertToFloat(buffer_.ReadUInt()); }
  ValueType UncheckedRead() const {
    return ConvertToFloat(buffer_.UncheckedReadUInt());
  }
  void Write(ValueType value) const {
    const bool result = TryToWrite(value);
    (void)result;
    EMBOSS_CHECK(result);
  }
  bool TryToWrite(ValueType value) const {
    if (!CouldWriteValue(value)) return false;
    if (!IsComplete()) return false;
    buffer_.WriteUInt(ConvertToUInt(value));
    return true;
  }
  static constexpr bool CouldWriteValue(ValueType value) {
    // Avoid unused parameters error:
    static_cast<void>(value);
    return true;
  }
  void UncheckedWrite(ValueType value) const {
    buffer_.UncheckedWriteUInt(ConvertToUInt(value));
  }

  template <typename OtherView>
  void CopyFrom(const OtherView &other) const {
    Write(other.Read());
  }
  template <typename OtherView>
  void UncheckedCopyFrom(const OtherView &other) const {
    UncheckedWrite(other.UncheckedRead());
  }
  template <typename OtherView>
  bool TryToCopyFrom(const OtherView &other) const {
    return other.Ok() && TryToWrite(other.Read());
  }

  // All bit patterns in the underlying buffer are valid, so Ok() is always
  // true if IsComplete() is true.
  bool Ok() const { return IsComplete(); }
  template <class OtherBitViewType>
  bool Equals(const FloatView<Parameters, OtherBitViewType> &other) const {
    return Read() == other.Read();
  }
  template <class OtherBitViewType>
  bool UncheckedEquals(
      const FloatView<Parameters, OtherBitViewType> &other) const {
    return UncheckedRead() == other.UncheckedRead();
  }
  bool IsComplete() const {
    return buffer_.Ok() && buffer_.SizeInBits() >= Parameters::kBits;
  }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    return support::ReadFloatFromTextStream(this, stream);
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         ::emboss::TextOutputOptions &options) const {
    support::WriteFloatToTextStream(Read(), stream, options);
  }

  static constexpr bool IsAggregate() { return false; }

  static constexpr int SizeInBits() { return Parameters::kBits; }

 private:
  using UIntType = typename support::FloatType<Parameters::kBits>::UIntType;
  static ValueType ConvertToFloat(UIntType bits) {
    // TODO(bolms): This method assumes a few things that are not always
    // strictly true; e.g., that uint32_t and float have the same endianness.
    ValueType result;
    memcpy(static_cast<void *>(&result), static_cast<void *>(&bits),
           sizeof result);
    return result;
  }

  static UIntType ConvertToUInt(ValueType value) {
    // TODO(bolms): This method assumes a few things that are not always
    // strictly true; e.g., that uint32_t and float have the same endianness.
    UIntType bits;
    memcpy(static_cast<void *>(&bits), static_cast<void *>(&value),
           sizeof bits);
    return bits;
  }

  BitViewType buffer_;
};

}  // namespace prelude
}  // namespace emboss

#endif  // EMBOSS_RUNTIME_CPP_EMBOSS_PRELUDE_H_
