-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
优化 Huffman 编码实现,重构分数类构造函数,添加内存对齐分配功能,更新异常处理,增强 Any 类的类型安全性
- Loading branch information
Showing
19 changed files
with
1,481 additions
and
799 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,97 +1,160 @@ | ||
/*! | ||
* \file field_count.hpp | ||
* \brief Field Count | ||
* \author Max Qian <lightapt.com> | ||
* \date 2024-05-25 | ||
* \copyright Copyright (C) 2023-2024 Max Qian <lightapt.com> | ||
*/ | ||
#ifndef ATOMMETA_FIELD_COUNT_HPP | ||
#define ATOMMETA_FIELD_COUNT_HPP | ||
|
||
#ifndef ATOM_META_FIELD_COUNT_HPP | ||
#define ATOM_META_FIELD_COUNT_HPP | ||
#include <array> | ||
namespace atom::meta::details { | ||
struct Any; | ||
|
||
#include <type_traits> | ||
#include <utility> | ||
struct Any { | ||
constexpr Any(int) {} | ||
|
||
namespace atom::meta { | ||
template <typename T> | ||
requires std::is_copy_constructible_v<T> | ||
operator T&(); | ||
|
||
/*! | ||
* \brief A struct that can be converted to any type. | ||
*/ | ||
struct Any { | ||
/*! | ||
* \brief Constexpr conversion operator to any type. | ||
* \tparam T The type to convert to. | ||
* \return An instance of type T. | ||
*/ | ||
template <typename T> | ||
explicit consteval operator T() const noexcept; | ||
requires std::is_move_constructible_v<T> | ||
operator T&&(); | ||
|
||
struct Empty {}; | ||
|
||
template <typename T> | ||
requires(!std::is_copy_constructible_v<T> && | ||
!std::is_move_constructible_v<T> && | ||
!std::is_constructible_v<T, Empty>) | ||
operator T(); | ||
}; | ||
|
||
/*! | ||
* \brief Checks if a type T is constructible with braces. | ||
* \tparam T The type to check. | ||
* \tparam I The index sequence. | ||
* \param[in] indices The index sequence. | ||
* \return True if T is constructible with braces, false otherwise. | ||
*/ | ||
template <typename T, std::size_t... I> | ||
consteval auto isBracesConstructible( | ||
std::index_sequence<I...> /*indices*/) noexcept -> bool { | ||
return requires { T{((void)I, std::declval<Any>())...}; }; | ||
template <typename T, std::size_t N> | ||
consteval auto tryInitializeWithN() -> std::size_t { | ||
return []<std::size_t... Is>(std::index_sequence<Is...>) { | ||
return requires { T{Any(Is)...}; }; | ||
}(std::make_index_sequence<N>{}); | ||
} | ||
|
||
/*! | ||
* \brief Recursively counts the number of fields in a type T. | ||
* \tparam T The type to count fields in. | ||
* \tparam N The current count of fields. | ||
* \return The number of fields in type T. | ||
*/ | ||
template <typename T, std::size_t N = 0> | ||
consteval auto fieldCount() noexcept -> std::size_t { | ||
if constexpr (!isBracesConstructible<T>( | ||
std::make_index_sequence<N + 1>{})) { | ||
consteval auto totalCountOfFields() -> std::size_t { | ||
if constexpr (tryInitializeWithN<T, N>() && | ||
!tryInitializeWithN<T, N + 1>()) { | ||
return N; | ||
} else { | ||
return fieldCount<T, N + 1>(); | ||
return totalCountOfFields<T, N + 1>(); | ||
} | ||
} | ||
} // namespace atom::meta::details | ||
|
||
/*! | ||
* \brief A template struct to hold type information. | ||
* \tparam T The type to hold information for. | ||
*/ | ||
template <typename T> | ||
struct TypeInfo; | ||
namespace atom::meta::details { | ||
|
||
template <typename T, std::size_t N1, std::size_t N2, std::size_t N3> | ||
consteval auto tryInitializeWithThreeParts() -> std::size_t { | ||
return []<std::size_t... I1, std::size_t... I2, std::size_t... I3>( | ||
std::index_sequence<I1...>, std::index_sequence<I2...>, | ||
std::index_sequence<I3...>) { | ||
return requires { T{Any(I1)..., {Any(I2)...}, Any(I3)...}; }; | ||
}(std::make_index_sequence<N1>{}, std::make_index_sequence<N2>{}, | ||
std::make_index_sequence<N3>{}); | ||
} | ||
|
||
template <typename T, std::size_t position, std::size_t N> | ||
constexpr auto tryPlaceNInPos() -> bool { | ||
constexpr auto Total = totalCountOfFields<T>(); | ||
if constexpr (N == 0) { | ||
return true; | ||
} else if constexpr (position + N <= Total) { | ||
return tryInitializeWithThreeParts<T, position, N, | ||
Total - position - N>(); | ||
} else { | ||
return false; | ||
} | ||
} | ||
|
||
template <typename T, std::size_t pos, std::size_t N = 0, std::size_t Max = 10> | ||
constexpr auto hasExtraElements() -> bool { | ||
constexpr auto Total = totalCountOfFields<T>(); | ||
if constexpr (tryInitializeWithThreeParts<T, pos, N, Total - pos - 1>()) { | ||
return false; | ||
} else if constexpr (N + 1 <= Max) { | ||
return hasExtraElements<T, pos, N + 1>(); | ||
} else { | ||
return true; | ||
} | ||
} | ||
|
||
template <typename T, std::size_t pos> | ||
constexpr auto searchMaxInPos() -> std::size_t { | ||
constexpr auto Total = totalCountOfFields<T>(); | ||
if constexpr (!hasExtraElements<T, pos>()) { | ||
return 1; | ||
} else { | ||
std::size_t result = 0; | ||
[&]<std::size_t... Is>(std::index_sequence<Is...>) { | ||
((tryPlaceNInPos<T, pos, Is>() ? result = Is : 0), ...); | ||
}(std::make_index_sequence<Total + 1>()); | ||
return result; | ||
} | ||
} | ||
|
||
template <typename T, std::size_t N = 0> | ||
constexpr auto searchAllExtraIndex(auto&& array) { | ||
constexpr auto total = totalCountOfFields<T>(); | ||
constexpr auto value = std::max<std::size_t>(searchMaxInPos<T, N>(), 1); | ||
array[N] = value; | ||
if constexpr (N + value < total) { | ||
searchAllExtraIndex<T, N + value>(array); | ||
} | ||
} | ||
|
||
/*! | ||
* \brief Gets the number of fields in a type T. | ||
* \tparam T The type to get the field count for. | ||
* \return The number of fields in type T. | ||
*/ | ||
template <typename T> | ||
consteval auto fieldCountOf() noexcept -> std::size_t { | ||
if constexpr (std::is_aggregate_v<T>) { | ||
if constexpr (requires { TypeInfo<T>::count; }) { | ||
return TypeInfo<T>::count; | ||
} else { | ||
return fieldCount<T>(); | ||
} | ||
constexpr auto trueCountOfFields() { | ||
constexpr auto max = totalCountOfFields<T>(); | ||
if constexpr (max == 0) { | ||
return 0; | ||
} else { | ||
return 0; // Non-aggregate types are considered to have 0 fields | ||
std::array<std::size_t, max> indices = {1}; | ||
searchAllExtraIndex<T>(indices); | ||
std::size_t result = max; | ||
std::size_t index = 0; | ||
while (index < max) { | ||
auto n = indices[index]; | ||
result -= n - 1; | ||
index += n; | ||
} | ||
return result; | ||
} | ||
} | ||
} // namespace atom::meta::details | ||
|
||
namespace atom::meta { | ||
template <typename T> | ||
struct type_info; | ||
|
||
/*! | ||
* \brief Gets the number of elements in an array. | ||
* \tparam T The type of the array elements. | ||
* \tparam N The number of elements in the array. | ||
* \return The number of elements in the array. | ||
/** | ||
* @brief Retrieve the count of fields of a struct | ||
* @warning cannot get the count of fields of a struct which has reference | ||
* type member in gcc 13 because the internal error occurs in below occasion | ||
* @code | ||
* struct Number { operator int&(); }; | ||
* int& x = { Number{} }; | ||
* | ||
* internal compiler error: in reference_binding, at cp/call.cc:2020 | ||
* @endcode | ||
* | ||
*/ | ||
template <typename T, std::size_t N> | ||
consteval auto fieldCountOf() noexcept -> std::size_t { | ||
return N; | ||
template <typename T> | ||
requires std::is_aggregate_v<T> | ||
consteval auto fieldCountOf() { | ||
if constexpr (requires { type_info<T>::count; }) { | ||
return type_info<T>::count; | ||
} else { | ||
return details::trueCountOfFields<T>(); | ||
} | ||
} | ||
|
||
template <typename T> | ||
requires(!std::is_aggregate_v<T>) | ||
consteval auto fieldCountOf() { | ||
return 0; | ||
} | ||
} // namespace atom::meta | ||
|
||
#endif // ATOM_META_FIELD_COUNT_HPP | ||
#endif // ATOMMETA_FIELD_COUNT_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.