<commit_before>/**
 * types.h - Implementation of types that are independent of host system
 * The types are used in algorithms affected by size of a variable
 *
 * @author <NAME>, <NAME>
 * Copyright 2019 MIPT-MIPS project
 */

#include <infra/macro.h>
#include <infra/types.h>

#include <iomanip>

#ifdef USE_GNUC_INT128

// Contains the most possible power of output base to be stored in uint64
// To print 128 number, you have to divide it by uint64, print the result
// and print the remainder afterwards.
struct Separator
{
    std::size_t power = 0;
    uint128 value = 1;
    explicit constexpr Separator(std::size_t base)
    {
        for (value = 1; value * base <= UINT64_MAX; value *= base)
            ++power;
    }
};

// RAII wrapper to restore std::ostream flags
class FlagsKeeper
{
public:
    explicit FlagsKeeper( std::ostream& out) : out( out), flags( out.flags()) { }
    ~FlagsKeeper() { out.flags( flags); }
private:
    std::ostream& out;
    const std::ios_base::fmtflags flags;
};

template<size_t BASE>
static std::ostream& dump(std::ostream& out, uint128 value)
{
    static const constexpr auto separator = Separator(BASE);
    if (value <= UINT64_MAX)
        return out << narrow_cast<uint64>( value);

    FlagsKeeper flags_keeper( out);
    dump<BASE>(out, value / separator.value);
    return out << std::setfill('0') << std::setw(separator.power) << std::noshowbase << (value % separator.value);
}

std::ostream& operator<<( std::ostream& out, uint128 value)
{
    if (( out.flags() & std::ios::dec) != 0)
        return dump<10>( out, value);<commit_msg>Add rule of five to FlagsKeeper (#988)<commit_after>/**
 * types.h - Implementation of types that are independent of host system
 * The types are used in algorithms affected by size of a variable
 *
 * @author <NAME>, <NAME>
 * Copyright 2019 MIPT-MIPS project
 */

#include <infra/macro.h>
#include <infra/types.h>

#include <iomanip>

#ifdef USE_GNUC_INT128

// Contains the most possible power of output base to be stored in uint64
// To print 128 number, you have to divide it by uint64, print the result
// and print the remainder afterwards.
struct Separator
{
    std::size_t power = 0;
    uint128 value = 1;
    explicit constexpr Separator(std::size_t base)
    {
        for (value = 1; value * base <= UINT64_MAX; value *= base)
            ++power;
    }

    uint128 get_lo_part(uint128 v) const noexcept
    {
        return v % value;
    }

    uint128 get_hi_part(uint128 v) const noexcept
    {
        return v / value;
    }
};

// RAII wrapper to restore std::ostream flags
class FlagsKeeper
{
public:
    explicit FlagsKeeper( std::ostream& out) : out( out), flags( out.flags()) { }
    ~FlagsKeeper() { out.flags( flags); }
    FlagsKeeper( const FlagsKeeper&) = delete;
    FlagsKeeper( FlagsKeeper&&) = delete;
    FlagsKeeper& operator=( const FlagsKeeper&) = delete;
    FlagsKeeper& operator=( FlagsKeeper&&) = delete;
private:
    std::ostream& out;
    const std::ios_base::fmtflags flags;
};

template<size_t BASE>
static std::ostream& dump(std::ostream& out, uint128 value)
{
    static const constexpr auto separator = Separator(BASE);
    if (value <= UINT64_MAX)
        return out << narrow_cast<uint64>( value);

    FlagsKeeper flags_keeper( out);
    return dump<BASE>(out, separator.get_hi_part( value))
        << std::setfill('0') << std::setw(separator.power) << std::noshowbase
        << separator.get_lo_part( value);
}

std::ostream& operator<<( std::ostream& out, uint128 value)
{
    if (( out.flags() & std::ios::dec) != 0)
        return dump<10>( out, value);
{'fraction_non_alphanumeric': 0.1293007769145394, 'fraction_numerical': 0.02413984461709212, 'mean_word_length': 3.50625, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 21, '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': '7292865', 'n_tokens_mistral': 1246, 'n_tokens_neox': 1140, 'n_words': 366}