/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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
 *
 *   http://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.
 **/

#ifndef QUICKSTEP_TYPES_TYPED_VALUE_HPP_
#define QUICKSTEP_TYPES_TYPED_VALUE_HPP_

#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <functional>

#include "types/DatetimeLit.hpp"
#include "types/IntervalLit.hpp"
#include "types/TypeID.hpp"
#include "types/TypedValue.pb.h"
#include "types/port/strnlen.hpp"
#include "utility/HashPair.hpp"
#include "utility/Macros.hpp"

#include "farmhash/farmhash.h"

#include "glog/logging.h"

namespace quickstep {

/** \addtogroup Types
 *  @{
 */

/**
 * @brief A value with Type information attached. May be a literal which owns
 *        its own data, or a reference to data which is "owned" elsewhere (e.g.
 *        in a StorageBlock).
 *
 * @note std::memset may be used to zero-out memory that will hold one or more
 *       TypedValues. It will be as if those TypedValues were constructed with
 *       the default zero-argument constructor. HOWEVER, it is only safe to
 *       overwrite a TypedValue with memset/memcpy/memmove if
 *       ownsOutOfLineData() is false (otherwise memory leaks WILL occur).
 * @note std::memcpy and std::memmove are only safe to use with a TypedValue if
 *       ownsOutOfLineData() is false. Otherwise, double-frees may occur.
 **/
class TypedValue {
 public:
  /**
   * @brief Default constructor. Creates an int 0.
   **/
  TypedValue()
      : value_info_(0) {
    value_union_.hash64 = 0;
  }

  /**
   * @brief Copy constructor. If copying from a literal, copies underlying
   *        data.
   **/
  TypedValue(const TypedValue &orig)
      : value_union_(orig.value_union_),
        value_info_(orig.value_info_) {
    if (ownsOutOfLineData()) {
      convertToLiteral();
    }
  }

  /**
   * @brief Move constructor. If moving from a literal that owns out-of-line
   *        data, the new TypedValue takes ownership of that data.
   **/
  TypedValue(TypedValue &&orig) noexcept
      : value_union_(orig.value_union_),
        value_info_(orig.value_info_) {
    orig.value_info_ = 0;
  }

  /**
   * @brief Constructor for a literal value of IntType.
   **/
  explicit TypedValue(const int literal_int)
      : value_info_(static_cast<std::uint64_t>(kInt)) {
    // Zero-out all bytes in the union for getHash() and fastEqualCheck().
    value_union_.hash64 = 0;
    value_union_.int_value = literal_int;
  }

  /**
   * @brief Constructor for a literal value of LongType.
   **/
  explicit TypedValue(const std::int64_t literal_long)
      : value_info_(static_cast<std::uint64_t>(kLong)) {
    value_union_.long_value = literal_long;
  }

  /**
   * @brief Constructor for a literal value of FloatType.
   **/
  explicit TypedValue(const float literal_float)
      : value_info_(static_cast<std::uint64_t>(kFloat)) {
    // Zero-out all bytes in the union for getHash() and fastEqualCheck().
    value_union_.hash64 = 0;

    // Canonicalize negative zero.
    value_union_.float_value = literal_float == 0 ? 0 : literal_float;
  }

  /**
   * @brief Constructor for a literal value of DoubleType.
   **/
  explicit TypedValue(const double literal_double)
      : value_info_(static_cast<std::uint64_t>(kDouble)) {
    // Canonicalize negative zero.
    value_union_.double_value = literal_double == 0 ? 0 : literal_double;
  }

  /**
   * @brief Constructor for a literal value of DateType.
   **/
  explicit TypedValue(const DateLit literal_date)
      : value_info_(static_cast<std::uint64_t>(kDate)) {
    value_union_.date_value = literal_date;
  }

  /**
   * @brief Constructor for a literal value of DatetimeType.
   **/
  explicit TypedValue(const DatetimeLit literal_datetime)
      : value_info_(static_cast<std::uint64_t>(kDatetime)) {
    value_union_.datetime_value = literal_datetime;
  }

  /**
   * @brief Constructor for a literal value of DatetimeIntervalType.
   **/
  explicit TypedValue(const DatetimeIntervalLit literal_datetime_interval)
      : value_info_(static_cast<std::uint64_t>(kDatetimeInterval)) {
    value_union_.datetime_interval_value = literal_datetime_interval;
  }

  /**
   * @brief Constructor for a literal value of YearMonthIntervalType.
   **/
  explicit TypedValue(const YearMonthIntervalLit literal_year_month_interval)
      : value_info_(static_cast<std::uint64_t>(kYearMonthInterval)) {
    value_union_.year_month_interval_value = literal_year_month_interval;
  }

  /**
   * @brief Constructor for a reference to non-numeric data.
   *
   * @param type_id The ID of the value's Type.
   * @param value_ptr A pointer to the underlying data to represent.
   * @param value_size The number of bytes of data at value_ptr.
   *
   * @note To make a literal value, call ensureNotReference() on the TypedValue
   *       created by this constructor.
   **/
  TypedValue(const TypeID type_id,
             const void* value_ptr,
             const std::size_t value_size)
      : value_info_(static_cast<std::uint64_t>(type_id) | (value_size << kSizeShift)) {
    DCHECK(value_ptr != nullptr);
    DCHECK_EQ(value_size, getDataSize());
    value_union_.out_of_line_data = value_ptr;
  }

  /**
   * @brief Constructor for a NULL value of the specified Type.
   *
   * @param type_id The ID of the value's Type.
   **/
  explicit TypedValue(const TypeID type_id)
      : value_info_(static_cast<std::uint64_t>(type_id) | kNullIndicatorMask) {
    // Although 'value_union_' should never be accessed when the null bit is
    // set, we zero it out anyway to prevent a false positive warning when the
    // compiler may complain about 'value_union_' being read without being
    // initialized.
    value_union_.long_value = 0;
  }

  /**
   * @brief Constructor for reversing a hash function, recovering the original
   *        value.
   *
   * @warning This is only usable for Types that have a reversible hash
   *          function. Check HashIsReversible() if unsure.
   *
   * @param type_id The ID of the value's Type.
   * @param hash The value's hash.
   **/
  inline TypedValue(const TypeID type_id, const std::size_t hash);

  /**
   * @brief Destructor.
   **/
  ~TypedValue() {
    if (ownsOutOfLineData()) {
      std::free(const_cast<void*>(value_union_.out_of_line_data));
    }
  }

  /**
   * @brief Assignment operator. If assigning from a literal, copies underlying
   *        data.
   **/
  TypedValue& operator=(const TypedValue &rhs) {
    if (this != &rhs) {
      if (ownsOutOfLineData()) {
        std::free(const_cast<void*>(value_union_.out_of_line_data));
      }

      value_union_ = rhs.value_union_;
      value_info_ = rhs.value_info_;
      if (ownsOutOfLineData()) {
        convertToLiteral();
      }
    }

    return *this;
  }

  /**
   * @brief Move assignment operator. If moving from a literal that owns
   *        out-of-line data, this TypedValue takes ownership of that data.
   **/
  TypedValue& operator=(TypedValue &&rhs) {
    if (this != &rhs) {
      if (ownsOutOfLineData()) {
        std::free(const_cast<void*>(value_union_.out_of_line_data));
      }

      value_union_ = rhs.value_union_;
      value_info_ = rhs.value_info_;
      rhs.value_info_ = 0;
    }

    return *this;
  }

  /**
   * @brief Create a new literal TypedValue with pre-allocated out-of-line
   *        data.
   * @warning The memory at value_ptr must be allocated with malloc() or
   *          similar (e.g. malloc_with_alignment()), NOT with the new operator
   *          or mmap().
   *
   * @param type_id The ID of the value's Type.
   * @param value_ptr A pointer to the underlying data to represent. The new
   *        TypedValue will take ownership of this memory.
   * @param value_size The number of bytes of data at value_ptr.
   **/
  static TypedValue CreateWithOwnedData(const TypeID type_id,
                                        void *value_ptr,
                                        const std::size_t value_size) {
    TypedValue val(type_id, value_ptr, value_size);
    val.value_info_ |= kOwnershipMask;
    return val;
  }

  /**
   * @brief Determine if TypedValue will use an in-line data representation
   *        for instances of a given type.
   *
   * @param type_id The ID of the type to check.
   * @return Whether TypedValue represents instances of the type denoted by
   *         type_id in-line.
   **/
  static bool RepresentedInline(const TypeID type_id) {
    switch (type_id) {
      case kInt:
      case kLong:
      case kFloat:
      case kDouble:
      case kDate:
      case kDatetime:
      case kDatetimeInterval:
      case kYearMonthInterval:
      case kNullType:
        return true;
      default:
        return false;
    }
  }

  /**
   * @brief Determine if the hash function getHash() is reversible for
   *        instances of a given type.
   *
   * @note If getHash() is reversible, then it is possible to use the
   *       hash-reversing constructor above to perfectly recreate a value from
   *       its hash code. This is exploited by some code (e.g.
   *       SimpleScalarSeparateChainingHashTable) to avoid copying and storing
   *       values when just their hashes can be stored instead.
   *
   * @param type_id The ID of the type to check.
   * @return Whether the hash function getHash() is reversible for instances of
   *         the type denoted by type_id.
   **/
  static bool HashIsReversible(const TypeID type_id) {
    switch (type_id) {
      case kInt:
      case kFloat:
        return sizeof(value_union_.int_value) <= sizeof(std::size_t);
      case kLong:
      case kDouble:
      case kDate:
      case kDatetime:
      case kDatetimeInterval:
      case kYearMonthInterval:
        return sizeof(value_union_) <= sizeof(std::size_t);
      default:
        return false;
    }
  }

  /**
   * @brief Clears this value, making it equivalent to a default-constructed
   *        TypedValue (int 0). Frees any owned out-of-line data.
   **/
  inline void clear() {
    if (ownsOutOfLineData()) {
      std::free(const_cast<void*>(value_union_.out_of_line_data));
    }

    value_info_ = 0;
    value_union_.hash64 = 0;
  }

  /**
   * @brief Determine if this value is NULL.
   *
   * @return Whether this is a NULL value.
   **/
  inline bool isNull() const {
    return value_info_ & kNullIndicatorMask;
  }

  /**
   * @brief Determine if this value is a reference (i.e. it points to
   *        out-of-line data which it does not own).
   *
   * @return Whether this is a reference.
   **/
  inline bool isReference() const {
    return ((value_info_ & kSizeBitsMask) && !(value_info_ & kOwnershipMask));
  }

  /**
   * @brief Determine if this value points to out-of-line data which it owns.
   * @note This is not simply the opposite of isReference(), because a value
   *       may be a literal (i.e. not a reference), but still not have any
   *       out-of-line data which it owns. This is the case for all NULL
   *       values and all numeric values.
   *
   * @returns Whether this value owns out-of-line data.
   **/
  inline bool ownsOutOfLineData() const {
    return ((value_info_ & kOwnershipMask) && (value_info_ & kSizeBitsMask));
  }

  /**
   * @brief Get the TypeID of this value.
   *
   * @return This value's TypeID.
   **/
  inline TypeID getTypeID() const {
    return static_cast<TypeID>(value_info_ & kTypeIDMask);
  }

  /**
   * @brief Get the size of this value's data.
   * @warning Only usable with non-NULL values.
   *
   * @return The size, in bytes, of this value's data.
   **/
  inline std::size_t getDataSize() const {
    DCHECK(!isNull());
    switch (getTypeID()) {
      case kInt:
      case kFloat:
        return sizeof(int);
      case kLong:
      case kDouble:
      case kDate:
      case kDatetime:
      case kDatetimeInterval:
      case kYearMonthInterval:
        return sizeof(value_union_);
      default:
        return value_info_ >> kSizeShift;
    }
  }

  /**
   * @brief Determine if this value is plausibly a valid instance of a given
   *        Type.
   * @warning This is NOT authoritative and in some circumstances can give
   *          false positives. It only checks TypeID, nullability, and length,
   *          but does not know about additional properties of Types that are
   *          not available to a TypedValue (e.g. the precision of a DECIMAL
   *          type). This is intended mainly as a sanity check for debugging
   *          assertions.
   * @note For variable-length types, this assumes that a TypedValue is a valid
   *       instance of the type if it has the same TypeID and its size is
   *       between type.minimumByteLength() and type.maximumByteLength(),
   *       inclusive. This is true for VarChar, but may need to be modified if
   *       other variable-length types are added for which this is not true.
   *
   * @param type The signature of the Type to check.
   * @return Whether this value is a valid instance of type.
   **/
  bool isPlausibleInstanceOf(const TypeSignature type) const;

  /**
   * @brief Ensure that this TypedValue is not a reference (i.e. force it to
   *        be a literal), copying out-of-line data if necessary.
   *
   * @return A reference to this TypedValue (this a fluent modifier).
   **/
  inline TypedValue& ensureNotReference() {
    if (isReference()) {
      convertToLiteral();
    }
    return *this;
  }

  /**
   * @brief Make a reference pointing to the data represented by this
   *        TypedValue.
   * @note If this is a literal which is represented in-line, then a literal
   *       TypedValue will actually be returned, which is just as efficient as
   *       a reference and requires less indirection.
   *
   * @return A reference to this TypedValue's data.
   **/
  inline TypedValue makeReferenceToThis() const {
    if (ownsOutOfLineData()) {
      return TypedValue(getTypeID(), value_union_.out_of_line_data, getDataSize());
    } else {
      return *this;
    }
  }

  /**
   * @brief Get the literal value represented by this TypedValue,
   *        including four numeric types (int, std::int64_t, float, and double) and
   *        three date types (DatetimeLit, DatetimeIntervalLit, and YearMonthIntervalLit).
   * @warning This must only be used with the exactly correct underlying
   *          C++ type of a literal value. For numeric types,
   *          see also getNumericCoerced().
   *
   * @return The underlying literal value represented by this TypedValue.
   **/
  template <typename LiteralType>
  LiteralType getLiteral() const;

  /**
   * @brief Get the out-of-line data which this TypedValue points to.
   * @warning This must only be used with a TypedValue which has out-of-line
   *          data (i.e. not NULL, and not a numeric nor a date type
   *          which is represented in-line).
   *
   * @return The out-of-line data this TypedValue points to.
   **/
  inline const void* getOutOfLineData() const {
    DCHECK(!(getTypeID() == kInt
                   || getTypeID() == kLong
                   || getTypeID() == kFloat
                   || getTypeID() == kDouble
                   || getTypeID() == kDate
                   || getTypeID() == kDatetime
                   || getTypeID() == kDatetimeInterval
                   || getTypeID() == kYearMonthInterval));
    DCHECK(!isNull());
    return value_union_.out_of_line_data;
  }

  /**
   * @brief Get the length of the ASCII string this TypedValue represents,
   *        not counting a null terminator character, if any (same behavior
   *        as strlen).
   * @warning This must only be used with string types (i.e. Char and VarChar).
   *
   * @return The length of the string represented by this TypedValue.
   **/
  inline std::size_t getAsciiStringLength() const {
    DCHECK(getTypeID() == kChar || getTypeID() == kVarChar);
    DCHECK(!isNull());
    if (getTypeID() == kChar) {
      return strnlen(static_cast<const char*>(value_union_.out_of_line_data),
                     getDataSize());
    } else {
      return getDataSize() - 1;
    }
  }

  /**
   * @brief Get a pointer to the underlying data represented by this TypedValue.
   * @warning This must not be used with null values.
   *
   * @return A raw pointer to this TypedValue's data.
   **/
  inline const void* getDataPtr() const {
    DCHECK(!isNull());
    if (value_info_ & kSizeBitsMask) {
      // Data is out-of-line.
      DCHECK(!RepresentedInline(getTypeID()));
      return value_union_.out_of_line_data;
    } else {
       // According to the C standard, a pointer to a union points to each of
       // its members and vice versa (i.e. every non-bitfield member of a union
       // is always aligned at the front of the union itself).
      DCHECK(RepresentedInline(getTypeID()));
      return &value_union_;
    }
  }

  /**
   * @brief Copy this value's underlying data to the specified memory location.
   * @warning This must not be used with null values.
   *
   * @param destination The memory location where this value's underlying data
   *        should be copied. At least getDataSize() bytes of data must be
   *        available to write at destination.
   **/
  inline void copyInto(void *destination) const {
    DCHECK(!isNull());
    const std::size_t out_of_line_size = value_info_ >> kSizeShift;
    if (out_of_line_size != 0) {
      std::memcpy(destination,
                  value_union_.out_of_line_data,
                  value_info_ >> kSizeShift);
    } else {
      switch (getTypeID()) {
        case kInt:
        case kFloat:
          // 4 bytes byte-for-byte copy.
          *static_cast<int*>(destination) = value_union_.int_value;
          break;
        default:
          // 8 bytes byte-for-byte copy.
          *static_cast<ValueUnion*>(destination) = value_union_;
      }
    }
  }

  /**
   * @brief Get a hash of this TypedValue.
   * @note A trivial bit-for-bit identity hash is used for inline literal
   *       values (although on 32-bit systems bits from 64-bit wide scalars
   *       will be mixed by CombineHashes()), and FarmHash is used for all
   *       other values.
   * @note String values which are the same will hash to the same value, even
   *       if they are different types (i.e. Char or VarChar with different
   *       width parameters). This is intentional.
   * @warning This must not be used with null values.
   *
   * @return A hash of this TypedValue.
   **/
  inline std::size_t getHash() const {
    switch (getTypeID()) {
      case kInt:
      case kLong:
      case kFloat:
      case kDouble:
      case kDate:
      case kDatetime:
      case kDatetimeInterval:
      case kYearMonthInterval:
        return getHashScalarLiteral();
      case kChar:
      case kVarChar:
        return getHashAsciiString();
      default:
        return getHashOutOfLineNonString();
    }
  }

  /**
   * @brief Simplified version of getHash() that is only for scalar literals
   *        that are represented inline.
   *
   * @note A trivial bit-for-bit identity hash is used for inline scalar
   *       literals (although on 32-bit systems bits from 64-bit wide scalars
   *       will be mixed by CombineHashes()).
   * @warning It is an error to call this for a TypedValue where
   *          RepresentedInline() is false. If in doubt, use the generic
   *          getHash() method instead.
   * @warning This must not be used with null values.
   *
   * @return A hash of this TypedValue.
   **/
  inline std::size_t getHashScalarLiteral() const;

  /**
   * @brief Simplified version of getHash() that is only for ASCII string types
   *        (i.e. instances of CharType or VarCharType).
   *
   * @note FarmHash is the hash function used for strings.
   * @note Strings which are the same according to lexicographical comparison
   *       will hash to the same value, even if they are different types (e.g.
   *       CharType vs. VarCharType and/or string types with different width
   *       parameters). This is intentional.
   * @warning It is an error to call this for a TypedValue where getTypeID() is
   *          not kChar or kVarChar. If in doubt, use the generic getHash()
   *          method instead.
   * @warning This must not be used with null values.
   *
   * @return A hash of this TypedValue.
   **/
  inline std::size_t getHashAsciiString() const {
    DCHECK(!isNull());
    DCHECK(getTypeID() == kChar || getTypeID() == kVarChar);

    // Don't hash a null-terminator or any bytes that follow it.
    return util::Hash(static_cast<const char*>(value_union_.out_of_line_data),
                      getAsciiStringLength());
  }

  /**
   * @brief Simplified version of getHash() that is only for types that are
   *        represented out-of-line but are NOT ASCII strings.
   *
   * @note FarmHash is the hash function used for types represented
   *       out-of-line.
   * @warning It is an error to call this for a TypedValue where
   *          RepresentedInline() is true, or if getTypeID() is kChar or
   *          kVarChar. If in doubt, use the generic getHash() instead.
   * @warning This must not be used with null values.
   *
   * @return A hash of this TypedValue.
   **/
  inline std::size_t getHashOutOfLineNonString() const {
    DCHECK(!isNull());
    DCHECK(!RepresentedInline(getTypeID())
           && !(getTypeID() == kChar || getTypeID() == kVarChar));
    return util::Hash(static_cast<const char*>(value_union_.out_of_line_data),
                      getDataSize());
  }

  /**
   * @brief Quickly check if two TypedValues of the same Type are equal.
   * @note This is intended mainly for use in hash tables to quickly check if
   *       two TypedValues that return equal values for getHash() are actually
   *       equal to each other. EqualComparison should be used instead for
   *       general use.
   * @warning This must not be used with null values.
   * @warning Must only be used with two TypedValues of the same Type.
   *
   * @param other Another TypedValue to check for equality with this one.
   * @return Whether this TypedValue is equal to other.
   **/
  inline bool fastEqualCheck(const TypedValue &other) const {
    DCHECK(!isNull());
    DCHECK(!other.isNull());
    DCHECK_EQ(getTypeID(), other.getTypeID());
    switch (getTypeID()) {
      case kInt:
      case kLong:
      case kFloat:
      case kDouble:
      case kDate:
      case kDatetime:
      case kDatetimeInterval:
      case kYearMonthInterval:
        // NOTE(chasseur): We simply do a byte-for-byte equality check of
        // 'value_union_' for types that are represented inline. For types that
        // are effectively 64-bit integers (LONG, DATETIME, and both INTERVAL
        // types) this is exactly the same as normal integer equality. For
        // types shorter than 64 bits (INT and FLOAT) we zero-out the union
        // when constructing the TypedValue, so the non-value bytes of the
        // union will always compare the same. Finally, for floating-point
        // types (FLOAT and DOUBLE), we always convert negative zero to
        // ordinary zero so that bitwise comparison will give correct results
        // for exact equality (although the usual caveats about rounding errors
        // for floating-point arithmetic still apply).
        return value_union_.hash64 == other.value_union_.hash64;
      case kChar:
      case kVarChar: {
        const std::size_t len = getAsciiStringLength();
        const std::size_t other_len = other.getAsciiStringLength();
        return ((len == other_len)
                && (std::memcmp(static_cast<const char*>(value_union_.out_of_line_data),
                                static_cast<const char*>(other.value_union_.out_of_line_data),
                                len) == 0));
      }
      default: {
        const std::size_t len = getDataSize();
        const std::size_t other_len = other.getDataSize();
        return ((len == other_len)
                && (std::memcmp(value_union_.out_of_line_data,
                                other.value_union_.out_of_line_data,
                                len) == 0));
      }
    }
  }

  /**
   * @brief Generate a serialized Protocol Buffer representation
   *        of this TypedValue.
   *
   * @return The serialized Protocol Buffer representation of this TypedValue.
   **/
  serialization::TypedValue getProto() const;

  /**
   * @brief Generate a TypedValue from that TypedValue's serialized
   *        Protocol Buffer representation.
   *
   * @param proto A serialized Protocol Buffer representation of a TypedValue,
   *        originally generated by getProto().
   * @return The TypedValue described by proto.
   **/
  static TypedValue ReconstructFromProto(const serialization::TypedValue &proto);

  /**
   * @brief Check whether a serialization::TypedValue is fully-formed and
   *        all parts are valid.
   *
   * @param proto A serialized Protocol Buffer representation of a TypedValue,
   *        originally generated by getProto().
   * @return Whether proto is fully-formed and valid.
   **/
  static bool ProtoIsValid(const serialization::TypedValue &proto);

 private:
  friend class CharType;
  friend class VarCharType;

  static const std::uint64_t kTypeIDMask = static_cast<std::uint64_t>(0x3F);
  static const std::uint64_t kNullIndicatorMask = static_cast<std::uint64_t>(0x40);
  static const std::uint64_t kOwnershipMask = static_cast<std::uint64_t>(0x80);
  static const std::uint64_t kNonSizeBitsMask = static_cast<std::uint64_t>(0xFF);
  static const std::uint64_t kSizeBitsMask = ~kNonSizeBitsMask;
  static const unsigned kSizeShift = 8;

  TypedValue(const TypeID type_id,
             void* value_ptr,
             const std::size_t value_size,
             bool owned)
      : value_info_(static_cast<std::uint64_t>(type_id)
                    | (owned ? kOwnershipMask : 0)
                    | (value_size << kSizeShift)) {
    DCHECK(value_ptr != nullptr);
    DCHECK_EQ(value_size, getDataSize());
    value_union_.out_of_line_data = value_ptr;
  }

  inline void markType(const TypeID type_id) {
    DCHECK_EQ(static_cast<std::uint64_t>(type_id),
              static_cast<std::uint64_t>(type_id) & kTypeIDMask);
    value_info_ = (value_info_ & ~kTypeIDMask) | static_cast<std::uint64_t>(type_id);
  }

  inline void convertToLiteral() {
    const std::size_t data_size = getDataSize();
    void* data_copy = std::malloc(data_size);
    std::memcpy(data_copy, value_union_.out_of_line_data, data_size);
    value_union_.out_of_line_data = data_copy;

    value_info_ |= kOwnershipMask;
  }

  // Templated helper method for getHashScalarLiteral(). Has implementations
  // for 64-bit systems (always the trivial identity hash) and 32-bit systems
  // (the trivial identity hash for scalars that are themselves 32 bits like
  // INT and FLOAT, otherwise CombineHashes() applied to the lower and upper
  // 4 bytes of 'value_union_').
  template <bool size_t_64bit>
  inline std::size_t getHashScalarLiteralImpl() const;

  // Helper method for hash-reversing constructor.
  template <bool size_t_64bit>
  inline void reverseHash(const std::size_t hash);

  union ValueUnion {
    int int_value;
    std::int64_t long_value;
    float float_value;
    double double_value;
    const void* out_of_line_data;
    DateLit date_value;
    DatetimeLit datetime_value;
    DatetimeIntervalLit datetime_interval_value;
    YearMonthIntervalLit year_month_interval_value;

    // Used to interpret the bytes of any of the inline fields above as a
    // 64-bit integer, providing a trivial reversible hash function.
    std::uint64_t hash64;

    // For 32-bit systems, this struct splits the 8 bytes of the ValueUnion
    // into 2 4-byte fields that we can use CombineHashes() on.
    struct Hash32 {
      std::uint32_t a;
      std::uint32_t b;
    } hash32;
  } value_union_;

  // Some static asserts that guarantee certain assumptions about ValueUnion
  // hold.
  static_assert(sizeof(ValueUnion) == sizeof(std::uint64_t),
                "TypedValue::ValueUnion must fit in 64 bits.");

  static_assert(sizeof(ValueUnion) == sizeof(ValueUnion::Hash32),
                "TypedValue::ValueUnion::Hash32 must cover all of ValueUnion.");

  static_assert(sizeof(ValueUnion) == sizeof(std::int64_t)
                    && sizeof(ValueUnion) == sizeof(double)
                    && sizeof(ValueUnion) == sizeof(DatetimeLit)
                    && sizeof(ValueUnion) == sizeof(DatetimeIntervalLit)
                    && sizeof(ValueUnion) == sizeof(YearMonthIntervalLit),
                "All inline fields of TypedValue::ValueUnion except for "
                "int_value and float_value should be 64 bits.");

  static_assert(sizeof(int) == 4 && sizeof(float) == 4,
                "TypedValue::ValueUnion::int_value and "
                "TypedValue::ValueUnion::float_value should both be 32 bits.");

  // Lowest-order 6 bits are the TypeID, the 7th-lowest bit is the NULL
  // indicator, and the 8th-lowest bit indicates whether
  // '*value_union_.out_of_line_data' is owned by this TypedValue. The
  // higher-order 7 bytes (shifted right) are the size of out-of-line data.
  std::uint64_t value_info_;
};

/** @} */

// Explicit specializations of getLiteral().
template <>
inline int TypedValue::getLiteral<int>() const {
  DCHECK_EQ(kInt, getTypeID());
  DCHECK(!isNull());
  return value_union_.int_value;
}

template <>
inline std::int64_t TypedValue::getLiteral<std::int64_t>() const {
  DCHECK_EQ(kLong, getTypeID());
  DCHECK(!isNull());
  return value_union_.long_value;
}

template <>
inline float TypedValue::getLiteral<float>() const {
  DCHECK_EQ(kFloat, getTypeID());
  DCHECK(!isNull());
  return value_union_.float_value;
}

template <>
inline double TypedValue::getLiteral<double>() const {
  DCHECK_EQ(kDouble, getTypeID());
  DCHECK(!isNull());
  return value_union_.double_value;
}

template <>
inline DateLit TypedValue::getLiteral<DateLit>() const {
  DCHECK_EQ(kDate, getTypeID());
  DCHECK(!isNull());
  return value_union_.date_value;
}

template <>
inline DatetimeLit TypedValue::getLiteral<DatetimeLit>() const {
  DCHECK_EQ(kDatetime, getTypeID());
  DCHECK(!isNull());
  return value_union_.datetime_value;
}

template <>
inline DatetimeIntervalLit TypedValue::getLiteral<DatetimeIntervalLit>() const {
  DCHECK_EQ(kDatetimeInterval, getTypeID());
  DCHECK(!isNull());
  return value_union_.datetime_interval_value;
}

template <>
inline YearMonthIntervalLit TypedValue::getLiteral<YearMonthIntervalLit>() const {
  DCHECK_EQ(kYearMonthInterval, getTypeID());
  DCHECK(!isNull());
  return value_union_.year_month_interval_value;
}

// Explicit specializations of getHashScalarLiteralImpl().

// 32-bit size_t.
template <>
inline std::size_t TypedValue::getHashScalarLiteralImpl<false>() const {
  switch (getTypeID()) {
    case kInt:
    case kFloat:
      return value_union_.hash32.a;
    default:
      return CombineHashes(value_union_.hash32.a, value_union_.hash32.b);
  }
}

// 64-bit size_t.
template <>
inline std::size_t TypedValue::getHashScalarLiteralImpl<true>() const {
  return value_union_.hash64;
}

// Implementation of TypedValue::getHashScalarLiteral() is written out-of-line
// here because instantiations of TypedValue::getHashScalarLiteralImpl() must
// come after the explicit specializations above.
inline std::size_t TypedValue::getHashScalarLiteral() const {
  DCHECK(!isNull());
  DCHECK(RepresentedInline(getTypeID()));
  return getHashScalarLiteralImpl<sizeof(std::size_t) == sizeof(std::uint64_t)>();
}

// Explicit specializations of reverseHash().

// 32-bit size_t.
template <>
inline void TypedValue::reverseHash<false>(const std::size_t hash) {
  value_union_.hash32.a = hash;
  value_union_.hash32.b = 0;
}

// 64-bit size_t.
template <>
inline void TypedValue::reverseHash<true>(const std::size_t hash) {
  value_union_.hash64 = hash;
}

// Implementation of hash-reversing constructor is written out-of-line here
// because instantiations of TypedValue::reverseHash() must come after the
// explicit specializations above.
inline TypedValue::TypedValue(const TypeID type_id,
                              const std::size_t hash)
    : value_info_(static_cast<std::uint64_t>(type_id)) {
  DCHECK(HashIsReversible(type_id));
  reverseHash<sizeof(std::size_t) == sizeof(std::uint64_t)>(hash);
}

}  // namespace quickstep

#endif  // QUICKSTEP_TYPES_TYPED_VALUE_HPP_
