<commit_before>#pragma once
#include <type_traits>
#include <stdexcept>
#include <static_if.hpp>

namespace
{

template<typename I>
I ipow_imp(I base, I exp)
{
    constexpr I zero(0);
    constexpr I two(2);
    I result(1);
    while(exp != zero)
    {
        if (exp % two)
            result *= base;
        exp /= two;
        base *= base;
    }
    return result;
}

}

template <typename I>
I ipow(I base, I exp)
{
    if (exp == 0)
        return 1;
    if (base == 1)
        return 1;

    bool stop = false;
    I result;

    cpp::static_if<std::is_signed<I>::value>([&](auto)
    {
        if (base == -1)
        {
            stop = true;
            result = exp % 2 ? -1 : 1;
        }
    });
    if (stop)
        return result;

    cpp::static_if<std::is_signed<I>::value>([&](auto)
    {
        if(exp < 0)
            throw std::domain_error("Integer pow() with exp < 0 and |base| != 1");
    });

    if (base == 0)
        return 0;

    cpp::static_if<std::is_signed<I>::value>([&](auto)
    {
        if (exp > std::numeric_limits<I>::digits)
            throw std::range_error("Integer pow() with exp > digits and |base| > 1");
        if (base == -2)
        {
            stop = true;
            result = ((I)1 << exp) * (exp % 2 ? -1 : 1);
        }
    });
    if (stop)
        return result;

    if (exp >= std::numeric_limits<I>::digits)
        throw std::range_error("Integer pow() with exp >= digits and base not in {-2, -1, 0, 1}");
    if (base == 2)
        return (I)1 << exp;

    return ipow_imp(base, exp);
}
<commit_msg>Assert ipow template parameter is integral<commit_after>#pragma once
#include <type_traits>
#include <stdexcept>
#include <static_if.hpp>

namespace
{

template<typename I>
I ipow_imp(I base, I exp)
{
    constexpr I zero(0);
    constexpr I two(2);
    I result(1);
    while(exp != zero)
    {
        if (exp % two)
            result *= base;
        exp /= two;
        base *= base;
    }
    return result;
}

}

template <typename I>
I ipow(I base, I exp)
{
    static_assert(std::is_integral<I>::value,
                  "I must be an integral type");
    if (exp == 0)
        return 1;
    if (base == 1)
        return 1;

    bool stop = false;
    I result;

    cpp::static_if<std::is_signed<I>::value>([&](auto)
    {
        if (base == -1)
        {
            stop = true;
            result = exp % 2 ? -1 : 1;
        }
    });
    if (stop)
        return result;

    cpp::static_if<std::is_signed<I>::value>([&](auto)
    {
        if(exp < 0)
            throw std::domain_error("Integer pow() with exp < 0 and |base| != 1");
    });

    if (base == 0)
        return 0;

    cpp::static_if<std::is_signed<I>::value>([&](auto)
    {
        if (exp > std::numeric_limits<I>::digits)
            throw std::range_error("Integer pow() with exp > digits and |base| > 1");
        if (base == -2)
        {
            stop = true;
            result = ((I)1 << exp) * (exp % 2 ? -1 : 1);
        }
    });
    if (stop)
        return result;

    if (exp >= std::numeric_limits<I>::digits)
        throw std::range_error("Integer pow() with exp >= digits and base not in {-2, -1, 0, 1}");
    if (base == 2)
        return (I)1 << exp;

    return ipow_imp(base, exp);
}

{'fraction_non_alphanumeric': 0.16340269277845776, 'fraction_numerical': 0.017135862913096694, 'mean_word_length': 1.885260370697264, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '869149', 'n_tokens_mistral': 1195, 'n_tokens_neox': 1130, 'n_words': 306}