<commit_before>/**
@file EndianUtils.hpp
@brief Endian utilities.

@author <NAME>
@copyright 2010-2013 <NAME> under the MIT license;
see @ref index or the accompanying LICENSE file for full text.
*/

#ifndef DUCT_ENDIANUTILS_HPP_
#define DUCT_ENDIANUTILS_HPP_

#include "./config.hpp"

#include <cstddef>
#include <type_traits>
#include <algorithm>

namespace duct {

// Forward declarations
enum class Endian : unsigned;

/**
	@addtogroup endian_utils
	@{
*/

/**
	Endian types.
*/
enum class Endian : unsigned {
	/** System's endian. */
	SYSTEM = DUCT_BYTEORDER,
	/** Little endian. */
	LITTLE = DUCT_ENDIAN_LITTLE,
	/** Big endian. */
	BIG = DUCT_ENDIAN_BIG
};

/** @cond INTERNAL */
namespace {

// Can't do partial template function specialization
// (grumble grumble)
template<
	typename T,
	std::size_t = sizeof(T)
>
struct bs_impl;

// Convenience
template<
	typename T
>
struct bs_impl<T, 1u> {
	static constexpr T
	swap(
		T value
	) {
		return value;
	}
};

// Specialize for floating-point types
template<>
struct bs_impl<float> {
	static float
	swap(
		float value
	) {
		char& b = reinterpret_cast<char&>(value);
		std::reverse(&b, &b + sizeof(float));
		return value;
	}
};

// *long* double, you say? Never heard of such an arcane thing!
template<>
struct bs_impl<double> {
	static double
	swap(
		double value
	) {
		char& b = reinterpret_cast<char&>(value);
		std::reverse(&b, &b + sizeof(double));
		return value;
	}
};

// NB: These cannot be constexpr; the bswap macros can potentially
// use asm instructions
template<
	typename T
>
struct bs_impl<T, 2u> {
	static T
	swap(
		T value
	) {
	#if (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) != 0
		#pragma GCC diagnostic push
		#pragma GCC diagnostic ignored "-Wold-style-cast"
	#endif
		return static_cast<T>(
			bswap_16(reinterpret_cast<uint16_t&>(value))
		);
	#if (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) != 0
		#pragma GCC diagnostic pop
	#endif
	}
};

template<
	typename T
>
struct bs_impl<T, 4u> {
	static T
	swap(
		T value
	) {
	#if (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) != 0
		#pragma GCC diagnostic push
		#pragma GCC diagnostic ignored "-Wold-style-cast"
	#endif
		return static_cast<T>(
			bswap_32(reinterpret_cast<uint32_t&>(value))
		);
	#if (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) != 0
		#pragma GCC diagnostic pop
	#endif
	}
};

template<
	typename T
>
struct bs_impl<T, 8u> {
	static T
	swap(
		T value
	) {
	#if (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) != 0
		#pragma GCC diagnostic push
		#pragma GCC diagnostic ignored "-Wold-style-cast"
	#endif
		return static_cast<T>(
			bswap_64(reinterpret_cast<uint64_t&>(value))
		);
	#if (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) != 0
		#pragma GCC diagnostic pop
	#endif
	}
};

} // anonymous namespace
/** @endcond */ // INTERNAL

/**
	Reverse the bytes in an arithmetic value.

	@returns The byte-swapped value.
	@tparam T Arithmetic value type; inferred from @a value.
	@param value Value to swap.
*/<commit_msg>EndianUtils: diagnostic-ignored -Wold-style-cast for Clang 3.4+.<commit_after>/**
@file EndianUtils.hpp
@brief Endian utilities.

@author <NAME>
@copyright 2010-2013 <NAME> under the MIT license;
see @ref index or the accompanying LICENSE file for full text.
*/

#ifndef DUCT_ENDIANUTILS_HPP_
#define DUCT_ENDIANUTILS_HPP_

#include "./config.hpp"

#include <cstddef>
#include <type_traits>
#include <algorithm>

namespace duct {

// Forward declarations
enum class Endian : unsigned;

/**
	@addtogroup endian_utils
	@{
*/

/**
	Endian types.
*/
enum class Endian : unsigned {
	/** System's endian. */
	SYSTEM = DUCT_BYTEORDER,
	/** Little endian. */
	LITTLE = DUCT_ENDIAN_LITTLE,
	/** Big endian. */
	BIG = DUCT_ENDIAN_BIG
};

/** @cond INTERNAL */
namespace {

// Can't do partial template function specialization
// (grumble grumble)
template<
	typename T,
	std::size_t = sizeof(T)
>
struct bs_impl;

// Convenience
template<
	typename T
>
struct bs_impl<T, 1u> {
	static constexpr T
	swap(
		T value
	) {
		return value;
	}
};

// Specialize for floating-point types
template<>
struct bs_impl<float> {
	static float
	swap(
		float value
	) {
		char& b = reinterpret_cast<char&>(value);
		std::reverse(&b, &b + sizeof(float));
		return value;
	}
};

// *long* double, you say? Never heard of such an arcane thing!
template<>
struct bs_impl<double> {
	static double
	swap(
		double value
	) {
		char& b = reinterpret_cast<char&>(value);
		std::reverse(&b, &b + sizeof(double));
		return value;
	}
};

#if !defined(DUCT_ENDIAN_IGNORE_OLD_CASTS) && (			\
	 (DUCT_COMPILER & DUCT_FLAG_COMPILER_GCC) ||		\
	((DUCT_COMPILER & DUCT_FLAG_COMPILER_CLANG) &&		\
	  DUCT_COMPILER > DUCT_FLAG_COMPILER_CLANG33))
//
	#define DUCT_ENDIAN_IGNORE_OLD_CASTS
#endif

// NB: These cannot be constexpr; the bswap macros can potentially
// use asm instructions
template<
	typename T
>
struct bs_impl<T, 2u> {
	static T
	swap(
		T value
	) {
	#ifdef DUCT_ENDIAN_IGNORE_OLD_CASTS
		#pragma GCC diagnostic push
		#pragma GCC diagnostic ignored "-Wold-style-cast"
	#endif
		return static_cast<T>(
			bswap_16(reinterpret_cast<uint16_t&>(value))
		);
	#ifdef DUCT_ENDIAN_IGNORE_OLD_CASTS
		#pragma GCC diagnostic pop
	#endif
	}
};

template<
	typename T
>
struct bs_impl<T, 4u> {
	static T
	swap(
		T value
	) {
	#ifdef DUCT_ENDIAN_IGNORE_OLD_CASTS
		#pragma GCC diagnostic push
		#pragma GCC diagnostic ignored "-Wold-style-cast"
	#endif
		return static_cast<T>(
			bswap_32(reinterpret_cast<uint32_t&>(value))
		);
	#ifdef DUCT_ENDIAN_IGNORE_OLD_CASTS
		#pragma GCC diagnostic pop
	#endif
	}
};

template<
	typename T
>
struct bs_impl<T, 8u> {
	static T
	swap(
		T value
	) {
	#ifdef DUCT_ENDIAN_IGNORE_OLD_CASTS
		#pragma GCC diagnostic push
		#pragma GCC diagnostic ignored "-Wold-style-cast"
	#endif
		return static_cast<T>(
			bswap_64(reinterpret_cast<uint64_t&>(value))
		);
	#ifdef DUCT_ENDIAN_IGNORE_OLD_CASTS
		#pragma GCC diagnostic pop
	#endif
	}
};

} // anonymous namespace
/** @endcond */ // INTERNAL

/**
	Reverse the bytes in an arithmetic value.

	@returns The byte-swapped value.
	@tparam T Arithmetic value type; inferred from @a value.
	@param value Value to swap.
*/
{'fraction_non_alphanumeric': 0.12066710268149117, 'fraction_numerical': 0.00948332243296272, 'mean_word_length': 4.034567901234568, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 56, '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': '3700990', 'n_tokens_mistral': 2532, 'n_tokens_neox': 2295, 'n_words': 604}