brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 53367c7 Raw
110 lines · c
1#ifndef BENCHMARK_REGISTER_H2#define BENCHMARK_REGISTER_H3 4#include <algorithm>5#include <limits>6#include <vector>7 8#include "check.h"9 10namespace benchmark {11namespace internal {12 13// Append the powers of 'mult' in the closed interval [lo, hi].14// Returns iterator to the start of the inserted range.15template <typename T>16typename std::vector<T>::iterator AddPowers(std::vector<T>* dst, T lo, T hi,17                                            int mult) {18  BM_CHECK_GE(lo, 0);19  BM_CHECK_GE(hi, lo);20  BM_CHECK_GE(mult, 2);21 22  const size_t start_offset = dst->size();23 24  static const T kmax = std::numeric_limits<T>::max();25 26  // Space out the values in multiples of "mult"27  for (T i = static_cast<T>(1); i <= hi; i *= static_cast<T>(mult)) {28    if (i >= lo) {29      dst->push_back(i);30    }31    // Break the loop here since multiplying by32    // 'mult' would move outside of the range of T33    if (i > kmax / mult) break;34  }35 36  return dst->begin() + static_cast<int>(start_offset);37}38 39template <typename T>40void AddNegatedPowers(std::vector<T>* dst, T lo, T hi, int mult) {41  // We negate lo and hi so we require that they cannot be equal to 'min'.42  BM_CHECK_GT(lo, std::numeric_limits<T>::min());43  BM_CHECK_GT(hi, std::numeric_limits<T>::min());44  BM_CHECK_GE(hi, lo);45  BM_CHECK_LE(hi, 0);46 47  // Add positive powers, then negate and reverse.48  // Casts necessary since small integers get promoted49  // to 'int' when negating.50  const auto lo_complement = static_cast<T>(-lo);51  const auto hi_complement = static_cast<T>(-hi);52 53  const auto it = AddPowers(dst, hi_complement, lo_complement, mult);54 55  std::for_each(it, dst->end(), [](T& t) { t *= -1; });56  std::reverse(it, dst->end());57}58 59template <typename T>60void AddRange(std::vector<T>* dst, T lo, T hi, int mult) {61  static_assert(std::is_integral<T>::value && std::is_signed<T>::value,62                "Args type must be a signed integer");63 64  BM_CHECK_GE(hi, lo);65  BM_CHECK_GE(mult, 2);66 67  // Add "lo"68  dst->push_back(lo);69 70  // Handle lo == hi as a special case, so we then know71  // lo < hi and so it is safe to add 1 to lo and subtract 172  // from hi without falling outside of the range of T.73  if (lo == hi) return;74 75  // Ensure that lo_inner <= hi_inner below.76  if (lo + 1 == hi) {77    dst->push_back(hi);78    return;79  }80 81  // Add all powers of 'mult' in the range [lo+1, hi-1] (inclusive).82  const auto lo_inner = static_cast<T>(lo + 1);83  const auto hi_inner = static_cast<T>(hi - 1);84 85  // Insert negative values86  if (lo_inner < 0) {87    AddNegatedPowers(dst, lo_inner, std::min(hi_inner, T{-1}), mult);88  }89 90  // Treat 0 as a special case (see discussion on #762).91  if (lo < 0 && hi >= 0) {92    dst->push_back(0);93  }94 95  // Insert positive values96  if (hi_inner > 0) {97    AddPowers(dst, std::max(lo_inner, T{1}), hi_inner, mult);98  }99 100  // Add "hi" (if different from last value).101  if (hi != dst->back()) {102    dst->push_back(hi);103  }104}105 106}  // namespace internal107}  // namespace benchmark108 109#endif  // BENCHMARK_REGISTER_H110