// 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"

// 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 {
    ::std::string token;
    if (!::emboss::support::ReadToken(stream, &token)) return false;
    if (token == "true") {
      return TryToWrite(true);
    } else if (token == "false") {
      return TryToWrite(false);
    }
    // TODO(bolms): Provide a way to get an error message on parse failure.
    return false;
  }

  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_
