Implemented more STL and page allocation for malloc.
This commit is contained in:
parent
edd9ee85c7
commit
193e3a19dc
9
bastl/include/cfloat
Normal file
9
bastl/include/cfloat
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CFLOAT_INCLUDED)
|
||||
#define BAD_APPLE_OS_CFLOAT_INCLUDED
|
||||
|
||||
#include <float.h>
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CFLOAT_INCLUDED)
|
21
bastl/include/climits
Normal file
21
bastl/include/climits
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CLIMITS_INCLUDED)
|
||||
#define BAD_APPLE_OS_CLIMITS_INCLUDED
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#if !defined(LLONG_MIN)
|
||||
#define LLONG_MIN (-LLONG_MAX - 1LL)
|
||||
#endif
|
||||
|
||||
#if !defined(LLONG_MAX)
|
||||
#define LLONG_MAX __LONG_LONG_MAX__
|
||||
#endif
|
||||
|
||||
#if !defined(ULLONG_MAX)
|
||||
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
|
||||
#endif
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CLIMITS_INCLUDED)
|
9
bastl/include/cmath
Normal file
9
bastl/include/cmath
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_CMATH_INCLUDED)
|
||||
#define BAD_APPLE_OS_CMATH_INCLUDED
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_CMATH_INCLUDED)
|
477
bastl/include/limits
Normal file
477
bastl/include/limits
Normal file
@ -0,0 +1,477 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_LIMITS_INCLUDED)
|
||||
#define BAD_APPLE_OS_LIMITS_INCLUDED
|
||||
|
||||
#include <cfloat>
|
||||
#include <climits>
|
||||
#include <cmath>
|
||||
#include <cstdint>
|
||||
|
||||
namespace std
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
inline constexpr double LOG10_2 = 0.3010299956639812;
|
||||
}
|
||||
enum float_round_style
|
||||
{
|
||||
round_indeterminate = -1,
|
||||
round_toward_zero = 0,
|
||||
round_to_nearest = 1,
|
||||
round_toward_infinity = 2,
|
||||
round_toward_neg_infinity = 3
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class numeric_limits
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = false;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = false;
|
||||
static constexpr bool is_exact = false;
|
||||
static constexpr bool has_infinity = false;
|
||||
static constexpr bool has_quiet_NaN = false;
|
||||
static constexpr bool has_signaling_NaN = false;
|
||||
static constexpr float_round_style round_style = round_toward_zero;
|
||||
static constexpr bool is_iec559 = false;
|
||||
static constexpr bool is_bounded = false;
|
||||
static constexpr bool is_modulo = false;
|
||||
static constexpr int digits = 0;
|
||||
static constexpr int digits10 = 0;
|
||||
static constexpr int max_digits10 = 0;
|
||||
static constexpr int radix = 0;
|
||||
static constexpr int min_exponent = 0;
|
||||
static constexpr int min_exponent10 = 0;
|
||||
static constexpr int max_exponent = 0;
|
||||
static constexpr int max_exponent10 = 0;
|
||||
static constexpr bool traps = false;
|
||||
static constexpr bool tinyness_before = false;
|
||||
|
||||
static constexpr T min() noexcept { return T(); }
|
||||
static constexpr T lowest() noexcept { return T(); }
|
||||
static constexpr T max() noexcept { return T(); }
|
||||
static constexpr T epsilon() noexcept { return T(); }
|
||||
static constexpr T round_error() noexcept { return T(); }
|
||||
static constexpr T infinity() noexcept { return T(); }
|
||||
static constexpr T quiet_NaN() noexcept { return T(); }
|
||||
static constexpr T signaling_NaN() noexcept { return T(); }
|
||||
static constexpr T denorm_min() noexcept { return T(); }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<bool>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr int digits = 1;
|
||||
static constexpr int radix = 2;
|
||||
|
||||
static constexpr bool min() noexcept { return false; }
|
||||
static constexpr bool lowest() noexcept { return false; }
|
||||
static constexpr bool max() noexcept { return true; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<char>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = (CHAR_MIN < 0);
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = (CHAR_BIT - is_signed);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr char min() noexcept { return CHAR_MIN; }
|
||||
static constexpr char lowest() noexcept { return CHAR_MIN; }
|
||||
static constexpr char max() noexcept { return CHAR_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<signed char>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = (CHAR_BIT - 1);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr signed char min() noexcept { return SCHAR_MIN; }
|
||||
static constexpr signed char lowest() noexcept { return SCHAR_MIN; }
|
||||
static constexpr signed char max() noexcept { return SCHAR_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<unsigned char>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr unsigned char min() noexcept { return 0; }
|
||||
static constexpr unsigned char lowest() noexcept { return 0; }
|
||||
static constexpr unsigned char max() noexcept { return UCHAR_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<wchar_t>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = (WCHAR_MIN < 0);
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(wchar_t) - is_signed;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr wchar_t min() noexcept { return WCHAR_MIN; }
|
||||
static constexpr wchar_t lowest() noexcept { return WCHAR_MIN; }
|
||||
static constexpr wchar_t max() noexcept { return WCHAR_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<char8_t>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr char8_t min() noexcept { return 0; }
|
||||
static constexpr char8_t lowest() noexcept { return 0; }
|
||||
static constexpr char8_t max() noexcept { return UCHAR_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<char16_t>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(char16_t);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr char16_t min() noexcept { return 0; }
|
||||
static constexpr char16_t lowest() noexcept { return 0; }
|
||||
static constexpr char16_t max() noexcept { return UINT_LEAST16_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<char32_t>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(char32_t);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr char32_t min() noexcept { return 0; }
|
||||
static constexpr char32_t lowest() noexcept { return 0; }
|
||||
static constexpr char32_t max() noexcept { return UINT_LEAST32_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<short>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(short) - 1;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr short min() noexcept { return SHRT_MIN; }
|
||||
static constexpr short lowest() noexcept { return SHRT_MIN; }
|
||||
static constexpr short max() noexcept { return SHRT_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<unsigned short>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(short);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr unsigned short min() noexcept { return 0; }
|
||||
static constexpr unsigned short lowest() noexcept { return 0; }
|
||||
static constexpr unsigned short max() noexcept { return USHRT_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<int>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(int) - 1;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr int min() noexcept { return INT_MIN; }
|
||||
static constexpr int lowest() noexcept { return INT_MIN; }
|
||||
static constexpr int max() noexcept { return INT_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<unsigned int>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(int);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr unsigned int min() noexcept { return 0; }
|
||||
static constexpr unsigned int lowest() noexcept { return 0; }
|
||||
static constexpr unsigned int max() noexcept { return UINT_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<long>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(long) - 1;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr long min() noexcept { return LONG_MIN; }
|
||||
static constexpr long lowest() noexcept { return LONG_MIN; }
|
||||
static constexpr long max() noexcept { return LONG_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<unsigned long>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(long);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr unsigned long min() noexcept { return 0; }
|
||||
static constexpr unsigned long lowest() noexcept { return 0; }
|
||||
static constexpr unsigned long max() noexcept { return ULONG_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<long long>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(long long) - 1;
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr long long min() noexcept { return LLONG_MIN; }
|
||||
static constexpr long long lowest() noexcept { return LLONG_MIN; }
|
||||
static constexpr long long max() noexcept { return LLONG_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<unsigned long long>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = false;
|
||||
static constexpr bool is_integer = true;
|
||||
static constexpr bool is_exact = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr bool is_modulo = true;
|
||||
static constexpr int digits = CHAR_BIT * sizeof(long long);
|
||||
static constexpr int digits10 = static_cast<int>(digits * detail::LOG10_2);
|
||||
static constexpr int radix = 2;
|
||||
static constexpr bool traps = true;
|
||||
|
||||
static constexpr unsigned long long min() noexcept { return 0; }
|
||||
static constexpr unsigned long long lowest() noexcept { return 0; }
|
||||
static constexpr unsigned long long max() noexcept { return ULLONG_MAX; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<float>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool has_infinity = true;
|
||||
static constexpr bool has_quiet_NaN = true;
|
||||
static constexpr bool has_signaling_NaN = true;
|
||||
static constexpr float_round_style round_style = round_to_nearest;
|
||||
static constexpr bool is_iec559 = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr int digits = FLT_MANT_DIG;
|
||||
static constexpr int digits10 = FLT_DIG;
|
||||
static constexpr int max_digits10 = FLT_DECIMAL_DIG;
|
||||
static constexpr int radix = FLT_RADIX;
|
||||
static constexpr int min_exponent = FLT_MIN_EXP;
|
||||
static constexpr int min_exponent10 = FLT_MIN_10_EXP;
|
||||
static constexpr int max_exponent = FLT_MAX_EXP;
|
||||
static constexpr int max_exponent10 = FLT_MAX_10_EXP;
|
||||
|
||||
static constexpr float min() noexcept { return FLT_MIN; }
|
||||
static constexpr float lowest() noexcept { return -FLT_MAX; }
|
||||
static constexpr float max() noexcept { return FLT_MAX; }
|
||||
static constexpr float epsilon() noexcept { return FLT_EPSILON; }
|
||||
static constexpr float round_error() noexcept { return 0.5f; }
|
||||
static constexpr float infinity() noexcept { return HUGE_VALF; }
|
||||
static constexpr float quiet_NaN() noexcept { return FLT_QNAN; }
|
||||
static constexpr float signaling_NaN() noexcept { return FLT_SNAN; }
|
||||
static constexpr float denorm_min() noexcept { return FLT_TRUE_MIN; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<double>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool has_infinity = true;
|
||||
static constexpr bool has_quiet_NaN = true;
|
||||
static constexpr bool has_signaling_NaN = true;
|
||||
static constexpr float_round_style round_style = round_to_nearest;
|
||||
static constexpr bool is_iec559 = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr int digits = DBL_MANT_DIG;
|
||||
static constexpr int digits10 = DBL_DIG;
|
||||
static constexpr int max_digits10 = DBL_DECIMAL_DIG;
|
||||
static constexpr int radix = FLT_RADIX;
|
||||
static constexpr int min_exponent = DBL_MIN_EXP;
|
||||
static constexpr int min_exponent10 = DBL_MIN_10_EXP;
|
||||
static constexpr int max_exponent = DBL_MAX_EXP;
|
||||
static constexpr int max_exponent10 = DBL_MAX_10_EXP;
|
||||
|
||||
static constexpr double min() noexcept { return DBL_MIN; }
|
||||
static constexpr double lowest() noexcept { return -DBL_MAX; }
|
||||
static constexpr double max() noexcept { return DBL_MAX; }
|
||||
static constexpr double epsilon() noexcept { return DBL_EPSILON; }
|
||||
static constexpr double round_error() noexcept { return 0.5; }
|
||||
static constexpr double infinity() noexcept { return HUGE_VAL; }
|
||||
static constexpr double quiet_NaN() noexcept { return DBL_QNAN; }
|
||||
static constexpr double signaling_NaN() noexcept { return DBL_SNAN; }
|
||||
static constexpr double denorm_min() noexcept { return DBL_TRUE_MIN; }
|
||||
};
|
||||
|
||||
template<>
|
||||
class numeric_limits<long double>
|
||||
{
|
||||
public:
|
||||
static constexpr bool is_specialized = true;
|
||||
static constexpr bool is_signed = true;
|
||||
static constexpr bool has_infinity = true;
|
||||
static constexpr bool has_quiet_NaN = true;
|
||||
static constexpr bool has_signaling_NaN = true;
|
||||
static constexpr float_round_style round_style = round_to_nearest;
|
||||
static constexpr bool is_iec559 = true;
|
||||
static constexpr bool is_bounded = true;
|
||||
static constexpr int digits = LDBL_MANT_DIG;
|
||||
static constexpr int digits10 = LDBL_DIG;
|
||||
static constexpr int max_digits10 = LDBL_DECIMAL_DIG;
|
||||
static constexpr int radix = FLT_RADIX;
|
||||
static constexpr int min_exponent = LDBL_MIN_EXP;
|
||||
static constexpr int min_exponent10 = LDBL_MIN_10_EXP;
|
||||
static constexpr int max_exponent = LDBL_MAX_EXP;
|
||||
static constexpr int max_exponent10 = LDBL_MAX_10_EXP;
|
||||
|
||||
static constexpr long double min() noexcept { return LDBL_MIN; }
|
||||
static constexpr long double lowest() noexcept { return -LDBL_MAX; }
|
||||
static constexpr long double max() noexcept { return LDBL_MAX; }
|
||||
static constexpr long double epsilon() noexcept { return LDBL_EPSILON; }
|
||||
static constexpr long double round_error() noexcept { return 0.5l; }
|
||||
static constexpr long double infinity() noexcept { return HUGE_VALL; }
|
||||
static constexpr long double quiet_NaN() noexcept { return LDBL_QNAN; }
|
||||
static constexpr long double signaling_NaN() noexcept { return LDBL_SNAN; }
|
||||
static constexpr long double denorm_min() noexcept { return LDBL_TRUE_MIN; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_LIMITS_INCLUDED)
|
@ -5,9 +5,42 @@
|
||||
#define BAD_APPLE_OS_MEMORY_HPP_INCLUDED
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T>
|
||||
struct allocator
|
||||
{
|
||||
using value_type = T;
|
||||
using size_type = std::size_t;
|
||||
using propagate_on_container_move_assignment = true_type;
|
||||
|
||||
constexpr allocator() noexcept = default;
|
||||
constexpr allocator(const allocator&) noexcept = default;
|
||||
|
||||
template<typename U>
|
||||
constexpr allocator(const allocator<U>&) noexcept {}
|
||||
|
||||
[[nodiscard]] constexpr T* allocate(size_t n)
|
||||
{
|
||||
if (numeric_limits<size_t>::max() / sizeof(T) < n)
|
||||
{
|
||||
__ba_throw bad_array_new_length();
|
||||
}
|
||||
return static_cast<T*>(::operator new(n * sizeof(T))); // TODO: alignment for bigger types
|
||||
}
|
||||
|
||||
constexpr void deallocate(T* p, size_t n)
|
||||
{
|
||||
(void) n;
|
||||
::operator delete(p); // TODO: bigger alignments
|
||||
}
|
||||
};
|
||||
|
||||
constexpr void* align(std::size_t alignment, std::size_t size, void*& ptr, std::size_t& space) noexcept
|
||||
{
|
||||
if (space < size) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace std
|
||||
{
|
||||
class bad_alloc : public std::exception
|
||||
class bad_alloc : public exception
|
||||
{
|
||||
public:
|
||||
bad_alloc() noexcept = default;
|
||||
@ -15,6 +15,11 @@ public:
|
||||
|
||||
const char * what() const noexcept override;
|
||||
};
|
||||
|
||||
class bad_array_new_length : public bad_alloc
|
||||
{
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
inline void* operator new(std::size_t, void* placement) noexcept
|
||||
|
@ -4,7 +4,7 @@
|
||||
#if !defined(BAD_APPLE_OS_STDEXCEPT_INCLUDED)
|
||||
#define BAD_APPLE_OS_STDEXCEPT_INCLUDED
|
||||
|
||||
#include "exception"
|
||||
#include <exception>
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
@ -86,6 +86,24 @@ struct type_identity
|
||||
|
||||
template<typename T>
|
||||
using type_identity_t = type_identity<T>::type;
|
||||
|
||||
template<typename T, T v>
|
||||
struct integral_constant
|
||||
{
|
||||
using value_type = T;
|
||||
using type = integral_constant<T, v>;
|
||||
|
||||
static constexpr T value = v;
|
||||
|
||||
constexpr operator value_type() const noexcept { return v; }
|
||||
constexpr value_type operator()() const noexcept { return v; }
|
||||
};
|
||||
|
||||
template<bool B>
|
||||
using bool_constant = integral_constant<bool, B>;
|
||||
|
||||
using true_type = integral_constant<bool, true>;
|
||||
using false_type = integral_constant<bool, false>;
|
||||
}
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_TYPE_TRAITS_INCLUDED)
|
||||
|
@ -6,13 +6,14 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T, typename TAlloc = void> // TODO: allocator
|
||||
template<typename T, typename Allocator = allocator<T>>
|
||||
class vector
|
||||
{
|
||||
public:
|
||||
@ -29,9 +30,10 @@ private:
|
||||
T* _elements = nullptr;
|
||||
size_type _size = 0;
|
||||
size_type _capacity = 0;
|
||||
Allocator _allocator = {};
|
||||
public:
|
||||
constexpr vector() noexcept = default;
|
||||
constexpr vector(const vector& other) noexcept
|
||||
constexpr vector(const vector& other) noexcept : _allocator(other._allocator)
|
||||
{
|
||||
resize(other.size());
|
||||
for (size_type idx = 0; idx < size(); ++idx)
|
||||
@ -42,16 +44,22 @@ public:
|
||||
constexpr vector(vector&& other) noexcept
|
||||
: _elements(exchange(other._elements, nullptr)),
|
||||
_size(exchange(other._size, 0)),
|
||||
_capacity(exchange(other._capacity, 0))
|
||||
_capacity(exchange(other._capacity, 0)),
|
||||
_allocator(exchange(other._allocator, {}))
|
||||
{
|
||||
}
|
||||
constexpr explicit vector(size_type count, const value_type& value = value_type())
|
||||
constexpr explicit vector(const Allocator& allocator) noexcept : _allocator(allocator) {}
|
||||
constexpr explicit vector(size_type count, const value_type& value = value_type(), const Allocator& allocator = {}) : _allocator(allocator)
|
||||
{
|
||||
resize(count, value);
|
||||
}
|
||||
constexpr ~vector() noexcept
|
||||
{
|
||||
delete _elements;
|
||||
for (size_type idx = 0; idx < size(); ++idx)
|
||||
{
|
||||
_elements[idx].~T();
|
||||
}
|
||||
_allocator.deallocate(_elements, _capacity);
|
||||
}
|
||||
constexpr vector& operator=(const vector& other)
|
||||
{
|
||||
@ -302,7 +310,7 @@ private:
|
||||
if (capacity() == newCapacity) {
|
||||
return;
|
||||
}
|
||||
T* newElements = static_cast<T*>(malloc(newCapacity * sizeof(T)));
|
||||
T* newElements = _allocator.allocate(newCapacity * sizeof(T));
|
||||
if (newElements == nullptr)
|
||||
{
|
||||
__ba_throw bad_alloc();
|
||||
@ -312,7 +320,7 @@ private:
|
||||
::new (&newElements[idx]) T(move(_elements[idx]));
|
||||
_elements[idx].~T();
|
||||
}
|
||||
free(_elements);
|
||||
_allocator.deallocate(_elements, _capacity);
|
||||
_elements = newElements;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
|
43
targets/_any/include/math.h
Normal file
43
targets/_any/include/math.h
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !defined(BAD_APPLE_OS_MATH_H_INCLUDED)
|
||||
#define BAD_APPLE_OS_MATH_H_INCLUDED
|
||||
|
||||
#if !defined(HUGE_VALF)
|
||||
#define HUGE_VALF (__builtin_inff())
|
||||
#endif
|
||||
|
||||
#if !defined(FLT_QNAN)
|
||||
#define FLT_QNAN (__builtin_nanf(""))
|
||||
#endif
|
||||
|
||||
#if !defined(FLT_SNAN)
|
||||
#define FLT_SNAN (__builtin_nansf(""))
|
||||
#endif
|
||||
|
||||
#if !defined(HUGE_VAL)
|
||||
#define HUGE_VAL (__builtin_inf())
|
||||
#endif
|
||||
|
||||
#if !defined(DBL_QNAN)
|
||||
#define DBL_QNAN (__builtin_nan(""))
|
||||
#endif
|
||||
|
||||
#if !defined(DBL_SNAN)
|
||||
#define DBL_SNAN (__builtin_nans(""))
|
||||
#endif
|
||||
|
||||
#if !defined(HUGE_VALL)
|
||||
#define HUGE_VALL (__builtin_infl())
|
||||
#endif
|
||||
|
||||
#if !defined(LDBL_QNAN)
|
||||
#define LDBL_QNAN (__builtin_nanl(""))
|
||||
#endif
|
||||
|
||||
#if !defined(LDBL_SNAN)
|
||||
#define LDBL_SNAN (__builtin_nansl(""))
|
||||
#endif
|
||||
|
||||
#endif // !defined(BAD_APPLE_OS_MATH_H_INCLUDED)
|
@ -40,8 +40,8 @@ enum class MemoryType
|
||||
|
||||
struct MemoryRange
|
||||
{
|
||||
std::uint64_t pageBase;
|
||||
std::uint64_t numPages;
|
||||
std::uint64_t pageBase = 0;
|
||||
std::uint64_t numPages = 0;
|
||||
MemoryType type = MemoryType::USABLE;
|
||||
|
||||
MemoryRange& operator=(const MemoryRange&) noexcept = default;
|
||||
@ -51,11 +51,31 @@ struct MemoryRange
|
||||
}
|
||||
};
|
||||
|
||||
struct AllocatePagesOptions
|
||||
{
|
||||
std::size_t numPages = 1;
|
||||
bool bigPages = false;
|
||||
};
|
||||
|
||||
struct PageRange
|
||||
{
|
||||
std::uint64_t mBase = 0;
|
||||
std::uint64_t numPages = 0;
|
||||
|
||||
explicit operator bool() const noexcept { return numPages > 0; }
|
||||
bool operator!() const noexcept { return numPages == 0; }
|
||||
|
||||
[[nodiscard]] std::span<std::uint8_t> getMemory() const noexcept
|
||||
{
|
||||
std::uint8_t* basePtr = std::bit_cast<std::uint8_t*>(mBase << 12);
|
||||
return {basePtr, basePtr + (numPages * 512)};
|
||||
}
|
||||
};
|
||||
|
||||
[[nodiscard]] bool setupPaging(std::span<const MemoryRange> memoryRanges) noexcept;
|
||||
[[nodiscard]] const char* memoryTypeName(MemoryType type) noexcept;
|
||||
|
||||
[[nodiscard]] void* allocatePages(unsigned numConsecutive) noexcept;
|
||||
[[nodiscard]] inline void* allocatePage() noexcept { return allocatePages(1); }
|
||||
[[nodiscard]] PageRange allocatePages(const AllocatePagesOptions& options = {}) noexcept;
|
||||
|
||||
void setupIdentityPaging(std::uint64_t page) noexcept;
|
||||
void setupIdentityPaging2M(std::uint64_t page) noexcept;
|
||||
@ -69,10 +89,16 @@ inline void identityMapRegion(void* start, std::size_t bytes) noexcept
|
||||
}
|
||||
|
||||
template<typename T = void>
|
||||
inline T* pageToPointer(std::uint64_t page) noexcept
|
||||
[[nodiscard]] inline T* pageToPointer(std::uint64_t page) noexcept
|
||||
{
|
||||
return std::bit_cast<T*>(page << 12);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline std::size_t bytesToPages(std::size_t bytes, bool bigPages = false) noexcept
|
||||
{
|
||||
const std::size_t pageBytes = bigPages ? (2 << 20) : 4096;
|
||||
return (bytes + pageBytes - 1) / pageBytes;
|
||||
}
|
||||
}
|
||||
|
||||
void __ba_initInitialHeap() noexcept;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include "os/memory.hpp"
|
||||
#include "os/tty.hpp"
|
||||
|
||||
namespace
|
||||
@ -33,18 +34,6 @@ void __ba_initInitialHeap() noexcept
|
||||
gNextBlock->nextBlock = nullptr;
|
||||
}
|
||||
|
||||
void __ba_registerAllocatableMemory(void* memory, size_t size) noexcept
|
||||
{
|
||||
if (size < sizeof(max_align_t))
|
||||
{
|
||||
return;
|
||||
}
|
||||
MallocBlock* newBlock = static_cast<MallocBlock*>(memory);
|
||||
newBlock->nextBlock = gNextBlock;
|
||||
newBlock->elements = size / sizeof(max_align_t);
|
||||
gNextBlock = newBlock;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void abort()
|
||||
@ -94,7 +83,21 @@ void* malloc(size_t size) noexcept
|
||||
prevBlock = block;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
baos::PageRange pages = baos::allocatePages({
|
||||
.numPages = std::max(1ul, baos::bytesToPages(size, /* bigPages = */ true)),
|
||||
.bigPages = true
|
||||
});
|
||||
if (!pages) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::span<std::uint8_t> memory = pages.getMemory();
|
||||
MallocBlock* newBlock = std::bit_cast<MallocBlock*>(memory.begin());
|
||||
newBlock->nextBlock = gNextBlock;
|
||||
newBlock->elements = memory.size();
|
||||
gNextBlock = newBlock;
|
||||
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void free(void* memory) noexcept
|
||||
|
@ -188,7 +188,7 @@ bool allocateIdentityMappedPages(std::size_t numPages, std::size_t pageAlignment
|
||||
if (!allocateMemoryRange(numPages, pageAlignment, page)) {
|
||||
return false;
|
||||
}
|
||||
setupIdentityPaging2M(page);
|
||||
setupIdentityPaging(page, page + numPages);
|
||||
outPage = page;
|
||||
return true;
|
||||
}
|
||||
@ -272,6 +272,27 @@ const char* memoryTypeName(MemoryType type) noexcept
|
||||
return "<INVALID>";
|
||||
}
|
||||
|
||||
PageRange allocatePages(const AllocatePagesOptions& options) noexcept
|
||||
{
|
||||
if (options.numPages == 0) {
|
||||
return {};
|
||||
}
|
||||
std::uint64_t page = 0;
|
||||
const std::uint64_t numPages = options.numPages * (options.bigPages ? BIG_PAGE_SIZE : 1);
|
||||
if (!allocateIdentityMappedPages(
|
||||
/* numPages = */ numPages,
|
||||
/* pageAlignment = */ options.bigPages ? BIG_PAGE_ALIGNMENT : 1,
|
||||
/* outPage = */ page
|
||||
))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
.mBase = page,
|
||||
.numPages = numPages
|
||||
};
|
||||
}
|
||||
|
||||
void setupIdentityPaging(std::uint64_t page) noexcept
|
||||
{
|
||||
PageTableEntry& pageTableEntry = getOrCreatePage(page);
|
||||
|
Loading…
x
Reference in New Issue
Block a user