// Copyright 2017 The Abseil Authors.
//
// 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.

#ifndef ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
#define ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_

// This file contains some implementation details which are used by one or more
// of the absl random number distributions.

#include <cstdint>
#include <cstring>
#include <limits>
#include <type_traits>

#include "absl/base/internal/bits.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/traits.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {

// Tristate tag types controlling the output of GenerateRealFromBits.
struct GeneratePositiveTag {};
struct GenerateNegativeTag {};
struct GenerateSignedTag {};

// GenerateRealFromBits generates a single real value from a single 64-bit
// `bits` with template fields controlling the output.
//
// The `SignedTag` parameter controls whether positive, negative,
// or either signed/unsigned may be returned.
//   When SignedTag == GeneratePositiveTag, range is U(0, 1)
//   When SignedTag == GenerateNegativeTag, range is U(-1, 0)
//   When SignedTag == GenerateSignedTag, range is U(-1, 1)
//
// When the `IncludeZero` parameter is true, the function may return 0 for some
// inputs, otherwise it never returns 0.
//
// When a value in U(0,1) is required, use:
//   Uniform64ToReal<double, PositiveValueT, true>;
//
// When a value in U(-1,1) is required, use:
//   Uniform64ToReal<double, SignedValueT, false>;
//
//   This generates more distinct values than the mathematical equivalent
//   `U(0, 1) * 2.0 - 1.0`.
//
// Scaling the result by powers of 2 (and avoiding a multiply) is also possible:
//   GenerateRealFromBits<double>(..., -1);  => U(0, 0.5)
//   GenerateRealFromBits<double>(..., 1);   => U(0, 2)
//
template <typename RealType,  // Real type, either float or double.
          typename SignedTag = GeneratePositiveTag,  // Whether a positive,
                                                     // negative, or signed
                                                     // value is generated.
          bool IncludeZero = true>
inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
  using real_type = RealType;
  using uint_type = absl::conditional_t<std::is_same<real_type, float>::value,
                                        uint32_t, uint64_t>;

  static_assert(
      (std::is_same<double, real_type>::value ||
       std::is_same<float, real_type>::value),
      "GenerateRealFromBits must be parameterized by either float or double.");

  static_assert(sizeof(uint_type) == sizeof(real_type),
                "Mismatched unsinged and real types.");

  static_assert((std::numeric_limits<real_type>::is_iec559 &&
                 std::numeric_limits<real_type>::radix == 2),
                "RealType representation is not IEEE 754 binary.");

  static_assert((std::is_same<SignedTag, GeneratePositiveTag>::value ||
                 std::is_same<SignedTag, GenerateNegativeTag>::value ||
                 std::is_same<SignedTag, GenerateSignedTag>::value),
                "");

  static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
  static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
  static constexpr int kUintBits = sizeof(uint_type) * 8;

  int exp = exp_bias + int{std::numeric_limits<real_type>::max_exponent - 2};

  // Determine the sign bit.
  // Depending on the SignedTag, this may use the left-most bit
  // or it may be a constant value.
  uint_type sign = std::is_same<SignedTag, GenerateNegativeTag>::value
                       ? (static_cast<uint_type>(1) << (kUintBits - 1))
                       : 0;
  if (std::is_same<SignedTag, GenerateSignedTag>::value) {
    if (std::is_same<uint_type, uint64_t>::value) {
      sign = bits & uint64_t{0x8000000000000000};
    }
    if (std::is_same<uint_type, uint32_t>::value) {
      const uint64_t tmp = bits & uint64_t{0x8000000000000000};
      sign = static_cast<uint32_t>(tmp >> 32);
    }
    // adjust the bits and the exponent to account for removing
    // the leading bit.
    bits = bits & uint64_t{0x7FFFFFFFFFFFFFFF};
    exp++;
  }
  if (IncludeZero) {
    if (bits == 0u) return 0;
  }

  // Number of leading zeros is mapped to the exponent: 2^-clz
  // bits is 0..01xxxxxx. After shifting, we're left with 1xxx...0..0
  int clz = base_internal::CountLeadingZeros64(bits);
  bits <<= (IncludeZero ? clz : (clz & 63));  // remove 0-bits.
  exp -= clz;                                 // set the exponent.
  bits >>= (63 - kExp);

  // Construct the 32-bit or 64-bit IEEE 754 floating-point value from
  // the individual fields: sign, exp, mantissa(bits).
  uint_type val =
      (std::is_same<SignedTag, GeneratePositiveTag>::value ? 0u : sign) |
      (static_cast<uint_type>(exp) << kExp) |
      (static_cast<uint_type>(bits) & kMask);

  // bit_cast to the output-type
  real_type result;
  memcpy(static_cast<void*>(&result), static_cast<const void*>(&val),
         sizeof(result));
  return result;
}

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_RANDOM_INTERNAL_GENERATE_REAL_H_
