def _cpp_integer_type_for_range(min_val, max_val):
  """Returns the appropriate C++ integer type to hold min_val up to max_val."""
  # The choice of int32_t, uint32_t, int64_t, then uint64_t is somewhat
  # arbitrary here, and might not be perfectly ideal.  I (bolms@) have chosen
  # this set of types to a) minimize the number of casts that occur in
  # arithmetic expressions, and b) favor 32-bit arithmetic, which is mostly
  # "cheapest" on current (2018) systems.  Signed integers are also preferred
  # over unsigned so that the C++ compiler can take advantage of undefined
  # overflow.
  for size in (32, 64):
    if min_val >= -(2**(size - 1)) and max_val <= 2**(size - 1) - 1:
      return "::std::int{}_t".format(size)
    elif min_val >= 0 and max_val <= 2**size - 1:
      return "::std::uint{}_t".format(size)
  return None