/**
 * 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 "third_party/src/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_
