/**
  * @brief Find the first code which is greater than the specified typed
  *        value, similar to std::upper_bound().
  * @warning value must not be NULL.
  *
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The first code whose corresponding uncompressed value is greater
  *         than value. May return numberOfCodes() if every value in the
  *         dictionary is less than or equal to value.
  **/
 std::uint32_t getUpperBoundCodeForTypedValue(const TypedValue &value,
                                              const Type &value_type) const {
   DCHECK(!value.isNull());
   if (value_type.isSubsumedBy(type_)) {
     return getUpperBoundCodeForUntypedValue(value.getDataPtr());
   } else {
     return getUpperBoundCodeForDifferentTypedValue(value, value_type);
   }
 }
 /**
  * @brief Find the first code which is not less than the specified typed
  *        value, similar to std::lower_bound().
  * @warning value must not be NULL.
  *
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The first code whose corresponding uncompressed value is not less
  *         than value. May return numberOfCodes() if every value in the
  *         dictionary is less than value.
  **/
 std::uint32_t getLowerBoundCodeForTypedValue(const TypedValue &value,
                                              const Type &value_type,
                                              const bool ignore_null_code = false) const {
   DCHECK(!value.isNull());
   if (value_type.isSubsumedBy(type_)) {
     return getLowerBoundCodeForUntypedValue(value.getDataPtr(), ignore_null_code);
   } else {
     return getLowerBoundCodeForDifferentTypedValue(value, value_type, ignore_null_code);
   }
 }
 /**
  * @brief Determine the range of codes that match a specified comparison with
  *        a specified typed value.
  *
  * @param comp The comparison to evaluate.
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The limits of the range of codes which match the predicate
  *         "coded-value comp value". The range is [first, second) (i.e. it
  *         is inclusive of first but not second).
  **/
 std::pair<std::uint32_t, std::uint32_t> getLimitCodesForComparisonTyped(
     const ComparisonID comp,
     const TypedValue &value,
     const Type &value_type) const {
   if (value_type.isSubsumedBy(type_)) {
     return getLimitCodesForComparisonUntyped(comp,
                                              value.isNull() ? nullptr : value.getDataPtr());
   } else {
     return getLimitCodesForComparisonDifferentTyped(comp, value, value_type);
   }
 }
 /**
  * @brief Get the compressed code that represents the specified typed value.
  * @note This uses a binary search to find the appropriate code. It runs in
  *       O(log(n)) time.
  *
  * @param value A typed value, which can be either the exact same Type as
  *        the values in this dictionary, or another Type which is comparable
  *        according to LessComparison.
  * @param value_type The Type that value belongs to.
  * @return The code for value in this dictionary, or the value of
  *         numberOfCodes() (the maximum code plus one) if value is not
  *         contained in this dictionary.
  **/
 std::uint32_t getCodeForTypedValue(const TypedValue &value,
                                    const Type &value_type) const {
   if (value.isNull()) {
     return getNullCode() == std::numeric_limits<std::uint32_t>::max() ? number_of_codes_including_null_
                                                                       : getNullCode();
   } else if (value_type.isSubsumedBy(type_)) {
     return getCodeForUntypedValue(value.getDataPtr());
   } else {
     return getCodeForDifferentTypedValue(value, value_type);
   }
 }