Added fennec::allocation and all necessary dependencies
This commit is contained in:
parent
1a27e37f66
commit
67c8ad9a0d
@ -4,6 +4,7 @@ project(fennec)
|
|||||||
set(CMAKE_CXX_STANDARD 26)
|
set(CMAKE_CXX_STANDARD 26)
|
||||||
set(CMAKE_C_STANDARD 26)
|
set(CMAKE_C_STANDARD 26)
|
||||||
|
|
||||||
|
# any necessary include directories
|
||||||
include_directories(include)
|
include_directories(include)
|
||||||
|
|
||||||
add_library(fennec STATIC
|
add_library(fennec STATIC
|
||||||
@ -22,12 +23,15 @@ add_library(fennec STATIC
|
|||||||
include/fennec/lang/conditional_types.h
|
include/fennec/lang/conditional_types.h
|
||||||
include/fennec/lang/intrinsics.h
|
include/fennec/lang/intrinsics.h
|
||||||
include/fennec/lang/limits.h
|
include/fennec/lang/limits.h
|
||||||
|
include/fennec/lang/numeric_transforms.h
|
||||||
include/fennec/lang/sequences.h
|
include/fennec/lang/sequences.h
|
||||||
include/fennec/lang/type_traits.h
|
include/fennec/lang/type_traits.h
|
||||||
include/fennec/lang/type_transforms.h
|
include/fennec/lang/type_transforms.h
|
||||||
include/fennec/lang/types.h
|
include/fennec/lang/types.h
|
||||||
include/fennec/lang/utility.h
|
include/fennec/lang/utility.h
|
||||||
|
include/fennec/lang/variadics.h
|
||||||
|
|
||||||
|
include/fennec/lang/detail/__numeric_transforms.h
|
||||||
include/fennec/lang/detail/__type_traits.h
|
include/fennec/lang/detail/__type_traits.h
|
||||||
|
|
||||||
|
|
||||||
@ -35,9 +39,11 @@ add_library(fennec STATIC
|
|||||||
include/fennec/memory/allocator.h
|
include/fennec/memory/allocator.h
|
||||||
include/fennec/memory/bits.h
|
include/fennec/memory/bits.h
|
||||||
include/fennec/memory/memory.h
|
include/fennec/memory/memory.h
|
||||||
include/fennec/memory/new.h
|
include/fennec/memory/new.h source/memory/new.cpp
|
||||||
|
include/fennec/memory/pointers.h
|
||||||
|
include/fennec/memory/ptr_traits.h
|
||||||
|
|
||||||
source/memory/new.cpp
|
include/fennec/memory/detail/__ptr_traits.h
|
||||||
|
|
||||||
|
|
||||||
# MATH =================================================================================================================
|
# MATH =================================================================================================================
|
||||||
@ -65,21 +71,30 @@ add_library(fennec STATIC
|
|||||||
include/fennec/math/detail/__types.h
|
include/fennec/math/detail/__types.h
|
||||||
include/fennec/math/detail/__vector_traits.h
|
include/fennec/math/detail/__vector_traits.h
|
||||||
|
|
||||||
|
include/fennec/lang/detail/__variadics.h
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(metaprogramming)
|
add_subdirectory(metaprogramming)
|
||||||
|
|
||||||
|
# add metaprogramming templates as a dependency and also force documentation to be generated when fennec is compiled
|
||||||
add_dependencies(fennec fennecdocs metaprogramming)
|
add_dependencies(fennec fennecdocs metaprogramming)
|
||||||
|
|
||||||
|
# Compiler Warning Flags
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
add_compile_options("/W4" "/WX")
|
add_compile_options("/W4" "/WX") # All MSVC Warnings throw as Errors
|
||||||
else()
|
else()
|
||||||
add_compile_options("-Wall" "-Wextra" "-pedantic" "-Werror")
|
add_compile_options("-Wall" "-Wextra" "-pedantic" "-Werror") # All gcc/etc. Warnings throw as errors
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_compile_options(fennec PUBLIC "-mavx" "-mavx2" "-mavx512f")
|
#target_compile_options(fennec PUBLIC "-mavx" "-mavx2" "-mavx512f") # SIMD Instructions, currently unused
|
||||||
target_link_options(fennec PRIVATE "-nostdlib" "-nocstdlib")
|
|
||||||
|
|
||||||
|
target_link_options(fennec PRIVATE "-nostdlib") # Do not compile base fennec library with c++ stdlib
|
||||||
|
# fennec does not use the C++ stdlib because it is bloated, difficult to read, and implementation defined.
|
||||||
|
# This implementation is designed to be as readable as possible, and expose information that would otherwise be obfuscated
|
||||||
|
|
||||||
|
|
||||||
|
# add the test suite as a sub-project
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
|
||||||
|
|
||||||
@ -90,20 +105,21 @@ add_subdirectory(test)
|
|||||||
find_package(Doxygen)
|
find_package(Doxygen)
|
||||||
|
|
||||||
if(DOXYGEN_FOUND)
|
if(DOXYGEN_FOUND)
|
||||||
get_filename_component(DOXYGEN_PROJECT_NAME ${PROJECT_SOURCE_DIR} NAME)
|
get_filename_component(DOXYGEN_PROJECT_NAME ${PROJECT_SOURCE_DIR} NAME) # Set Doxy Project name to the name of the root dir
|
||||||
set(DOXYGEN_CONFIG_IN "${PROJECT_SOURCE_DIR}/doxy/Doxyfile.in")
|
set(DOXYGEN_CONFIG_IN "${PROJECT_SOURCE_DIR}/doxy/Doxyfile.in") # Input config file with preprocessor arguments
|
||||||
set(DOXYGEN_CONFIG_OUT "${PROJECT_SOURCE_DIR}/doxy/Doxyfile")
|
set(DOXYGEN_CONFIG_OUT "${PROJECT_SOURCE_DIR}/doxy/Doxyfile") # Generated config file from input
|
||||||
|
|
||||||
configure_file(${DOXYGEN_CONFIG_IN} ${DOXYGEN_CONFIG_OUT} @ONLY)
|
configure_file(${DOXYGEN_CONFIG_IN} ${DOXYGEN_CONFIG_OUT} @ONLY) # Execute preprocessing step
|
||||||
message("Doxygen Build Started.")
|
message("Doxygen Build Started.")
|
||||||
|
|
||||||
|
# Target for building docs
|
||||||
add_custom_target(fennecdocs ALL
|
add_custom_target(fennecdocs ALL
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_CONFIG_OUT}
|
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_CONFIG_OUT}
|
||||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
COMMENT "Generating Doxygen Documentation"
|
COMMENT "Generating Doxygen Documentation"
|
||||||
|
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
|
# Target for cleaning docs
|
||||||
add_custom_target(fennecdocs-clean ALL
|
add_custom_target(fennecdocs-clean ALL
|
||||||
COMMAND rm -r "${PROJECT_SOURCE_DIR}/docs/"
|
COMMAND rm -r "${PROJECT_SOURCE_DIR}/docs/"
|
||||||
COMMENT "Cleaning Doxygen Documentation"
|
COMMENT "Cleaning Doxygen Documentation"
|
||||||
|
@ -52,23 +52,58 @@ template<bool_t B, typename T, typename F>
|
|||||||
struct conditional;
|
struct conditional;
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
/// \brief Shorthand for ```typename conditional<ConditionV, TrueT, FalseT>::type```
|
/// \brief Shorthand for ```typename conditional<ConditionV, TrueT, FalseT>::type```
|
||||||
template<bool_t B, typename T, typename F>
|
template<bool_t B, typename T, typename F>
|
||||||
using conditional_t
|
using conditional_t
|
||||||
= typename conditional<B, T, F>::type;
|
= typename conditional<B, T, F>::type;
|
||||||
|
|
||||||
|
|
||||||
// specialization of fennec::conditional for \c true case
|
// specialization of fennec::conditional for `true` case
|
||||||
template<typename T, typename F>
|
template<typename T, typename F>
|
||||||
struct conditional<true, T, F>
|
struct conditional<true, T, F>
|
||||||
: type_transform<T>{};
|
: type_transform<T>{};
|
||||||
|
|
||||||
|
|
||||||
// specialization of fennec::conditional for \c false case
|
// specialization of fennec::conditional for `false` case
|
||||||
template<typename T, typename F>
|
template<typename T, typename F>
|
||||||
struct conditional<false, T, F>
|
struct conditional<false, T, F>
|
||||||
: type_transform<F>{};
|
: type_transform<F>{};
|
||||||
|
|
||||||
|
|
||||||
|
// fennec::detect ======================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Detect whether `DetectT<ArgsT...>` is a valid type
|
||||||
|
///
|
||||||
|
/// \details The chosen type is stored in `detect::type` and
|
||||||
|
/// a boolean value is stored in `detect::is_detected` representing whether `DetectT<ArgsT>`
|
||||||
|
/// \tparam DefaultT Default type
|
||||||
|
/// \tparam DetectT Type to detect
|
||||||
|
/// \tparam ArgsT Any template arguments for `DetectT<ArgsT>`
|
||||||
|
template<typename DefaultT, template<typename...> typename DetectT, typename...ArgsT>
|
||||||
|
struct detect
|
||||||
|
{
|
||||||
|
using type = DefaultT;
|
||||||
|
static constexpr bool is_detected = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// true case
|
||||||
|
template<typename DefaultT, template<typename...> typename DetectT, typename...ArgsT>
|
||||||
|
requires requires { typename DetectT<ArgsT...>; }
|
||||||
|
struct detect<DefaultT, DetectT, ArgsT...>
|
||||||
|
{
|
||||||
|
using type = DetectT<ArgsT...>;
|
||||||
|
static constexpr bool is_detected = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Shorthand for ```typename detect<DefaultT, DetectT, ArgsT...>::type```
|
||||||
|
template<typename DefaultT, template<typename...> typename DetectT, typename...ArgsT>
|
||||||
|
using detect_t
|
||||||
|
= typename detect<DefaultT, DetectT, ArgsT...>::type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //CONDITIONAL_TYPES_H
|
#endif //CONDITIONAL_TYPES_H
|
||||||
|
64
include/fennec/lang/detail/__numeric_transforms.h
Normal file
64
include/fennec/lang/detail/__numeric_transforms.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_LANG_DETAIL_NUMERIC_TRANSFORMS_H
|
||||||
|
#define FENNEC_LANG_DETAIL_NUMERIC_TRANSFORMS_H
|
||||||
|
|
||||||
|
#include <fennec/lang/types.h>
|
||||||
|
#include <fennec/lang/type_transforms.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename> struct __make_unsigned : undefined_t {};
|
||||||
|
|
||||||
|
template<> struct __make_unsigned<char_t> : type_transform<uchar_t> {};
|
||||||
|
template<> struct __make_unsigned<uchar_t> : type_transform<uchar_t> {};
|
||||||
|
template<> struct __make_unsigned<schar_t> : type_transform<uchar_t> {};
|
||||||
|
template<> struct __make_unsigned<short_t> : type_transform<ushort_t> {};
|
||||||
|
template<> struct __make_unsigned<ushort_t> : type_transform<ushort_t> {};
|
||||||
|
template<> struct __make_unsigned<uint_t> : type_transform<uint_t> {};
|
||||||
|
template<> struct __make_unsigned<int_t> : type_transform<uint_t> {};
|
||||||
|
template<> struct __make_unsigned<long_t> : type_transform<ulong_t> {};
|
||||||
|
template<> struct __make_unsigned<ulong_t> : type_transform<ulong_t> {};
|
||||||
|
template<> struct __make_unsigned<llong_t> : type_transform<ullong_t> {};
|
||||||
|
template<> struct __make_unsigned<ullong_t> : type_transform<ullong_t> {};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename> struct __make_signed : undefined_t {};
|
||||||
|
|
||||||
|
template<> struct __make_signed<char_t> : type_transform<schar_t> {};
|
||||||
|
template<> struct __make_signed<uchar_t> : type_transform<schar_t> {};
|
||||||
|
template<> struct __make_signed<schar_t> : type_transform<schar_t> {};
|
||||||
|
template<> struct __make_signed<short_t> : type_transform<short_t> {};
|
||||||
|
template<> struct __make_signed<ushort_t> : type_transform<short_t> {};
|
||||||
|
template<> struct __make_signed<uint_t> : type_transform<int_t> {};
|
||||||
|
template<> struct __make_signed<int_t> : type_transform<int_t> {};
|
||||||
|
template<> struct __make_signed<long_t> : type_transform<long_t> {};
|
||||||
|
template<> struct __make_signed<ulong_t> : type_transform<long_t> {};
|
||||||
|
template<> struct __make_signed<llong_t> : type_transform<llong_t> {};
|
||||||
|
template<> struct __make_signed<ullong_t> : type_transform<llong_t> {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_LANG_DETAIL_NUMERIC_TRANSFORMS_H
|
@ -28,36 +28,40 @@ namespace fennec
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename> struct __is_void_helper : false_type {};
|
// Nothing interesting to note here
|
||||||
template<> struct __is_void_helper<void> : true_type {};
|
|
||||||
|
|
||||||
template<typename> struct __is_bool_helper : false_type {};
|
template<typename> struct __is_void : false_type {};
|
||||||
template<> struct __is_bool_helper<bool_t> : true_type {};
|
template<> struct __is_void<void> : true_type {};
|
||||||
|
|
||||||
template<typename> struct __is_integral_helper : false_type {};
|
template<typename> struct __is_bool : false_type {};
|
||||||
template<> struct __is_integral_helper<bool_t> : true_type {};
|
template<> struct __is_bool<bool_t> : true_type {};
|
||||||
template<> struct __is_integral_helper<char_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<char8_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<char16_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<char32_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<schar_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<uchar_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<wchar_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<short_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<ushort_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<int_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<uint_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<long_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<ulong_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<llong_t> : true_type {};
|
|
||||||
template<> struct __is_integral_helper<ullong_t> : true_type {};
|
|
||||||
|
|
||||||
template<typename TypeT> struct __is_signed_helper : bool_constant<TypeT(-1) < TypeT(0)> {};
|
// Provides definitions for all builtin int types
|
||||||
template<typename TypeT> struct __is_unsigned_helper : bool_constant<TypeT(-1) >= TypeT(0)> {};
|
template<typename> struct __is_integral : false_type {};
|
||||||
|
template<> struct __is_integral<bool_t> : true_type {};
|
||||||
|
template<> struct __is_integral<char_t> : true_type {};
|
||||||
|
template<> struct __is_integral<char8_t> : true_type {};
|
||||||
|
template<> struct __is_integral<char16_t> : true_type {};
|
||||||
|
template<> struct __is_integral<char32_t> : true_type {};
|
||||||
|
template<> struct __is_integral<schar_t> : true_type {};
|
||||||
|
template<> struct __is_integral<uchar_t> : true_type {};
|
||||||
|
template<> struct __is_integral<wchar_t> : true_type {};
|
||||||
|
template<> struct __is_integral<short_t> : true_type {};
|
||||||
|
template<> struct __is_integral<ushort_t> : true_type {};
|
||||||
|
template<> struct __is_integral<int_t> : true_type {};
|
||||||
|
template<> struct __is_integral<uint_t> : true_type {};
|
||||||
|
template<> struct __is_integral<long_t> : true_type {};
|
||||||
|
template<> struct __is_integral<ulong_t> : true_type {};
|
||||||
|
template<> struct __is_integral<llong_t> : true_type {};
|
||||||
|
template<> struct __is_integral<ullong_t> : true_type {};
|
||||||
|
|
||||||
template<typename> struct __is_floating_point_helper : false_type {};
|
// Most unsigned types will underflow `-1` to the types maximum value
|
||||||
template<> struct __is_floating_point_helper<float_t> : true_type {};
|
template<typename TypeT> struct __is_signed : bool_constant<TypeT(-1) < TypeT(0)> {};
|
||||||
template<> struct __is_floating_point_helper<double_t> : true_type {};
|
template<typename TypeT> struct __is_unsigned : bool_constant<TypeT(-1) >= TypeT(0)> {};
|
||||||
|
|
||||||
|
template<typename> struct __is_floating_point : false_type {};
|
||||||
|
template<> struct __is_floating_point<float_t> : true_type {};
|
||||||
|
template<> struct __is_floating_point<double_t> : true_type {};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
include/fennec/lang/detail/__variadics.h
Normal file
36
include/fennec/lang/detail/__variadics.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_LANG_DETAIL_VARIADICS_H
|
||||||
|
#define FENNEC_LANG_DETAIL_VARIADICS_H
|
||||||
|
|
||||||
|
#include <fennec/lang/type_transforms.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename FirstT, typename... RestT> struct __first_element : type_transform<FirstT>{};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_LANG_DETAIL_VARIADICS_H
|
@ -20,10 +20,82 @@
|
|||||||
#ifndef FENNEC_LANG_INTRINSICS_H
|
#ifndef FENNEC_LANG_INTRINSICS_H
|
||||||
#define FENNEC_LANG_INTRINSICS_H
|
#define FENNEC_LANG_INTRINSICS_H
|
||||||
|
|
||||||
|
// Most major compilers support __has_builtin
|
||||||
#if defined(__has_builtin)
|
#if defined(__has_builtin)
|
||||||
|
|
||||||
|
|
||||||
// bitcast is slightly more efficient for build times than using memcpy
|
// bitcast is slightly more efficient for build times than using memcpy
|
||||||
# define FENNEC_HAS_BUILTIN_BITCAST __has_builtin(__builtin_bit_cast)
|
#if __has_builtin(__builtin_bit_cast)
|
||||||
|
# define FENNEC_HAS_BUILTIN_BIT_CAST 1
|
||||||
|
# define FENNEC_BUILTIN_BIT_CAST(type, arg) __builtin_bit_cast(type, arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_BIT_CAST 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// addressof is very difficult to implement without intrinsics.
|
||||||
|
#if __has_builtin(__builtin_addressof)
|
||||||
|
# define FENNEC_HAS_BUILTIN_ADDRESSOF 1
|
||||||
|
# define FENNEC_BUILTIN_ADDRESSOF(arg) __builtin_addressof(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_ADDRESSOF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Type Traits
|
||||||
|
|
||||||
|
// can_convert is also very difficult to implement without intrinsics
|
||||||
|
#if __has_builtin(__is_convertible)
|
||||||
|
# define FENNEC_HAS_BUILTIN_CAN_CONVERT 1
|
||||||
|
# define FENNEC_BUILTIN_CAN_CONVERT(arg0, arg1) __is_convertible(arg0, arg1)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_CAN_CONVERT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics.
|
||||||
|
#if __has_builtin(__is_empty)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_EMPTY 1
|
||||||
|
# define FENNEC_BUILTIN_IS_EMPTY(arg) __is_empty(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_EMPTY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics
|
||||||
|
#if __has_builtin(__is_polymorphic)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 1
|
||||||
|
# define FENNEC_BUILTIN_IS_POLYMORPHIC(arg) __is_polymorphic(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_POLYMORPHIC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics
|
||||||
|
#if __has_builtin(__is_final)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_FINAL 1
|
||||||
|
# define FENNEC_BUILTIN_IS_FINAL(arg) __is_final(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_FINAL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Inconsistent without intrinsics
|
||||||
|
#if __has_builtin(__is_abstract)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 1
|
||||||
|
# define FENNEC_BUILTIN_IS_ABSTRACT(arg) __is_abstract(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_ABSTRACT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Impossible without instrinsics
|
||||||
|
#if __has_builtin(__is_standard_layout)
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 1
|
||||||
|
# define FENNEC_BUILTIN_IS_STANDARD_LAYOUT(arg) __is_standard_layout(arg)
|
||||||
|
#else
|
||||||
|
# define FENNEC_HAS_BUILTIN_IS_STANDARD_LAYOUT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// For compilers without or differently named builtins
|
||||||
|
#else
|
||||||
|
|
||||||
|
// TODO: More compiler support
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -39,6 +39,9 @@ enum float_round_style
|
|||||||
, round_toward_neg_infinity = 3
|
, round_toward_neg_infinity = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Helper for getting traits of a numeric type
|
||||||
|
/// \tparam TypeT Numeric types, may be overloaded for custom types
|
||||||
template<typename TypeT> struct numeric_limits
|
template<typename TypeT> struct numeric_limits
|
||||||
{
|
{
|
||||||
static constexpr bool is_specialized = false;
|
static constexpr bool is_specialized = false;
|
||||||
@ -78,6 +81,7 @@ template<typename TypeT> struct numeric_limits
|
|||||||
static constexpr TypeT denorm_min() { return TypeT(); }
|
static constexpr TypeT denorm_min() { return TypeT(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Overload for the builtin floating point type
|
||||||
template<> struct numeric_limits<float>
|
template<> struct numeric_limits<float>
|
||||||
{
|
{
|
||||||
static constexpr bool is_specialized = true;
|
static constexpr bool is_specialized = true;
|
||||||
@ -115,6 +119,7 @@ template<> struct numeric_limits<float>
|
|||||||
static constexpr double denorm_min() { return FLT_DENORM_MIN; }
|
static constexpr double denorm_min() { return FLT_DENORM_MIN; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Overload for the bultin double precision floating point type
|
||||||
template<> struct numeric_limits<double>
|
template<> struct numeric_limits<double>
|
||||||
{
|
{
|
||||||
static constexpr bool is_specialized = true;
|
static constexpr bool is_specialized = true;
|
||||||
|
46
include/fennec/lang/numeric_transforms.h
Normal file
46
include/fennec/lang/numeric_transforms.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file numeric_transforms.h
|
||||||
|
/// \brief modify numeric types at compile time
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef FENNEC_LANG_NUMERIC_TRANSFORMS_H
|
||||||
|
#define FENNEC_LANG_NUMERIC_TRANSFORMS_H
|
||||||
|
|
||||||
|
#include <fennec/lang/type_transforms.h>
|
||||||
|
#include <fennec/lang/detail/__numeric_transforms.h>
|
||||||
|
|
||||||
|
// TODO: Document
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename TypeT> struct make_signed : detail::__make_signed<remove_cv_t<TypeT>> {};
|
||||||
|
template<typename TypeT> struct make_unsigned : detail::__make_unsigned<remove_cv_t<TypeT>> {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_LANG_NUMERIC_TRANSFORMS_H
|
@ -46,7 +46,7 @@ namespace fennec
|
|||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> struct is_void
|
template<typename T> struct is_void
|
||||||
: detail::__is_void_helper<remove_cvr_t<T>>{};
|
: detail::__is_void<remove_cvr_t<T>>{};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -66,7 +66,7 @@ template<typename T> constexpr bool_t is_void_v
|
|||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> struct is_bool
|
template<typename T> struct is_bool
|
||||||
: detail::__is_bool_helper<remove_cvr_t<T>>{};
|
: detail::__is_bool<remove_cvr_t<T>>{};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -86,7 +86,7 @@ template<typename T> constexpr bool_t is_bool_v
|
|||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> struct is_integral
|
template<typename T> struct is_integral
|
||||||
: detail::__is_integral_helper<remove_cvr_t<T>> {};
|
: detail::__is_integral<remove_cvr_t<T>> {};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -103,7 +103,7 @@ template<typename T> constexpr bool_t is_integral_v
|
|||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> struct is_signed
|
template<typename T> struct is_signed
|
||||||
: detail::__is_signed_helper<remove_cvr_t<T>> {};
|
: detail::__is_signed<remove_cvr_t<T>> {};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -120,7 +120,7 @@ template<typename T> constexpr bool_t is_signed_v
|
|||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> struct is_unsigned
|
template<typename T> struct is_unsigned
|
||||||
: detail::__is_unsigned_helper<remove_cvr_t<T>> {};
|
: detail::__is_unsigned<remove_cvr_t<T>> {};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -140,7 +140,7 @@ template<typename T> constexpr bool_t is_unsigned_v
|
|||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T> struct is_floating_point
|
template<typename T> struct is_floating_point
|
||||||
: detail::__is_floating_point_helper<remove_cvr_t<T>>{};
|
: detail::__is_floating_point<remove_cvr_t<T>>{};
|
||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
@ -173,13 +173,14 @@ template<typename T> constexpr bool_t is_arithmetic_v
|
|||||||
|
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// \brief check if
|
/// \brief check if the two types are identical
|
||||||
///
|
///
|
||||||
/// \details
|
/// \details
|
||||||
/// \tparam T type to check
|
/// \tparam T type to check
|
||||||
template<typename T0, typename T1> struct is_same
|
template<typename T0, typename T1> struct is_same
|
||||||
: false_type {};
|
: false_type {};
|
||||||
|
|
||||||
|
// true case
|
||||||
template<typename T> struct is_same<T, T>
|
template<typename T> struct is_same<T, T>
|
||||||
: true_type {};
|
: true_type {};
|
||||||
|
|
||||||
@ -190,6 +191,24 @@ template<typename T> struct is_same<T, T>
|
|||||||
template<typename T0, typename T1> constexpr bool_t is_same_v
|
template<typename T0, typename T1> constexpr bool_t is_same_v
|
||||||
= is_same<T0, T1> {};
|
= is_same<T0, T1> {};
|
||||||
|
|
||||||
|
// fennec::can_convert =================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief check if type `T0` can be converted `T1`
|
||||||
|
/// \tparam T0 First type
|
||||||
|
/// \tparam T1 Second type
|
||||||
|
template<typename T0, typename T1> struct can_convert
|
||||||
|
: bool_constant<FENNEC_BUILTIN_CAN_CONVERT(T0, T1)> {};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief shorthand
|
||||||
|
/// \param T0 First type
|
||||||
|
/// \param T1 Second type
|
||||||
|
template<typename T0, typename T1> using can_convert_v = typename can_convert<T0, T1>::type;
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FENNEC_LANG_TYPE_TRAITS_H
|
#endif // FENNEC_LANG_TYPE_TRAITS_H
|
||||||
|
@ -197,6 +197,16 @@ using size_t = __SIZE_TYPE__;
|
|||||||
///
|
///
|
||||||
/// \brief Signed Integer Type Returned by the Subtraction of two Pointers
|
/// \brief Signed Integer Type Returned by the Subtraction of two Pointers
|
||||||
using ptrdiff_t = __PTRDIFF_TYPE__;
|
using ptrdiff_t = __PTRDIFF_TYPE__;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief undefined class for SFINAE
|
||||||
|
class undefined_t;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Void type used for SFINAE
|
||||||
|
template<typename...>
|
||||||
|
using void_t = void;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
66
include/fennec/lang/variadics.h
Normal file
66
include/fennec/lang/variadics.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright © 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \file variadics.h
|
||||||
|
/// \brief basic types of the c++ language
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \details
|
||||||
|
/// \author Medusa Slockbower
|
||||||
|
///
|
||||||
|
/// \copyright Copyright © 2025 Medusa Slockbower ([GPLv3](https://www.gnu.org/licenses/gpl-3.0.en.html))
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
#ifndef FENNEC_LANG_VARIADICS_H
|
||||||
|
#define FENNEC_LANG_VARIADICS_H
|
||||||
|
|
||||||
|
#include <fennec/lang/detail/__variadics.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Get the first element of a template parameter pack
|
||||||
|
/// \tparam TypesT the Parameter Pack
|
||||||
|
template<typename...TypesT> struct first_element : detail::__first_element<TypesT...> {};
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief alias for first_element<TypesT>::type
|
||||||
|
template<typename...TypesT> using first_element_t = typename first_element<TypesT...>::type;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// \brief Take a Template with a Pack `ClassT<ArgsT...>` and replace the first `ArgT` of `ArgsT...` with `SubT`
|
||||||
|
template<typename ClassT, typename SubT> struct replace_first_element { };
|
||||||
|
|
||||||
|
// Implementation
|
||||||
|
template<
|
||||||
|
template<typename, typename...> class ClassT // The Base Template
|
||||||
|
, typename SubT, typename OriginT // The Original Type and Type to Substitute
|
||||||
|
, typename... RestT> // The Rest of the Parameter Pack
|
||||||
|
struct replace_first_element<ClassT<OriginT, RestT...>, SubT> // Specialization
|
||||||
|
{ using type = ClassT<SubT, RestT...>; }; // Definition
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FENNEC_LANG_VARIADICS_H
|
@ -24,11 +24,15 @@
|
|||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename ScalarT, size_t...IndicesV> struct vector;
|
template<typename ScalarT, size_t...IndicesV> struct vector; // Forward def for vectors
|
||||||
template<typename ScalarT, size_t RowsV, size_t...ColIndicesV> struct matrix;
|
template<typename ScalarT, size_t RowsV, size_t...ColIndicesV> struct matrix; // Forward def for matrices
|
||||||
|
|
||||||
template<typename ScalarT, size_t SizeV> using vec = decltype(detail::__gen_vector<vector, ScalarT>(make_index_sequence<SizeV>{}));
|
// Simplified interface for creating sized vectors or matrices
|
||||||
template<typename ScalarT, size_t RowsV, size_t ColsV> using mat = decltype(detail::__gen_matrix<matrix, ScalarT, RowsV>(make_index_sequence<ColsV>{}));
|
template<typename ScalarT, size_t SizeV> using vec
|
||||||
|
= decltype(detail::__gen_vector<vector, ScalarT>(make_index_sequence<SizeV>{})); // Gets the type returned by this function
|
||||||
|
|
||||||
|
template<typename ScalarT, size_t RowsV, size_t ColsV> using mat
|
||||||
|
= decltype(detail::__gen_matrix<matrix, ScalarT, RowsV>(make_index_sequence<ColsV>{})); // Gets the type returned by this function
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +28,11 @@ namespace detail
|
|||||||
{
|
{
|
||||||
|
|
||||||
template<template<typename, size_t...> typename VectorT, typename ScalarT, size_t...IndicesV>
|
template<template<typename, size_t...> typename VectorT, typename ScalarT, size_t...IndicesV>
|
||||||
VectorT<ScalarT, IndicesV...> __gen_vector(index_sequence<IndicesV...>);
|
VectorT<ScalarT, IndicesV...> __gen_vector(index_sequence<IndicesV...>); // Helper for substituting a size N with sequence of integers
|
||||||
|
|
||||||
|
|
||||||
template<template<typename, size_t...> typename MatrixT, typename ScalarT, size_t RowsV, size_t...IndicesV>
|
template<template<typename, size_t...> typename MatrixT, typename ScalarT, size_t RowsV, size_t...IndicesV>
|
||||||
MatrixT<ScalarT, RowsV, IndicesV...> __gen_matrix(index_sequence<IndicesV...>);
|
MatrixT<ScalarT, RowsV, IndicesV...> __gen_matrix(index_sequence<IndicesV...>); // Helper for substituting a size Columns with sequence of integers
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,43 +30,47 @@ namespace fennec
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// Helpers for vector traits
|
||||||
|
|
||||||
template<typename>
|
template<typename>
|
||||||
struct __is_vector_helper
|
struct __is_vector_helper
|
||||||
: false_type {};
|
: false_type {}; // Default false case
|
||||||
|
|
||||||
|
|
||||||
template<typename ScalarT, size_t...IndicesV>
|
template<typename ScalarT, size_t...IndicesV>
|
||||||
struct __is_vector_helper<vector<ScalarT, IndicesV...>>
|
struct __is_vector_helper<vector<ScalarT, IndicesV...>>
|
||||||
: true_type {};
|
: true_type {}; // True for vectors
|
||||||
|
|
||||||
|
|
||||||
template<typename VectorT, typename DataT, typename ScalarT, size_t...IndicesV>
|
template<typename VectorT, typename DataT, typename ScalarT, size_t...IndicesV>
|
||||||
struct __is_vector_helper<swizzle<VectorT, DataT, ScalarT, IndicesV...>>
|
struct __is_vector_helper<swizzle<VectorT, DataT, ScalarT, IndicesV...>>
|
||||||
: true_type {};
|
: true_type {}; // True for swizzles
|
||||||
|
|
||||||
|
// get number of components of a type
|
||||||
template<typename>
|
template<typename>
|
||||||
struct __component_count_helper;
|
struct __component_count_helper;
|
||||||
|
|
||||||
|
// numeric types reduce to 1
|
||||||
template<typename TypeT> requires(is_arithmetic_v<TypeT>)
|
template<typename TypeT> requires(is_arithmetic_v<TypeT>)
|
||||||
struct __component_count_helper<TypeT>
|
struct __component_count_helper<TypeT>
|
||||||
: integral_constant<size_t, 1> {};
|
: integral_constant<size_t, 1> {};
|
||||||
|
|
||||||
|
// Vectors reduce to the number of elements
|
||||||
template<typename ScalarT, size_t...IndicesV>
|
template<typename ScalarT, size_t...IndicesV>
|
||||||
struct __component_count_helper<vector<ScalarT, IndicesV...>>
|
struct __component_count_helper<vector<ScalarT, IndicesV...>>
|
||||||
: integral_constant<size_t, sizeof...(IndicesV)> {};
|
: integral_constant<size_t, sizeof...(IndicesV)> {};
|
||||||
|
|
||||||
|
// Swizzles reduce to number of elements
|
||||||
template<typename VectorT, typename DataT, typename ScalarT, size_t...IndicesV>
|
template<typename VectorT, typename DataT, typename ScalarT, size_t...IndicesV>
|
||||||
struct __component_count_helper<swizzle<VectorT, DataT, ScalarT, IndicesV...>>
|
struct __component_count_helper<swizzle<VectorT, DataT, ScalarT, IndicesV...>>
|
||||||
: integral_constant<size_t, sizeof...(IndicesV)> {};
|
: integral_constant<size_t, sizeof...(IndicesV)> {};
|
||||||
|
|
||||||
|
// Matrices reduce to the number of cells
|
||||||
template<typename ScalarT, size_t RowsV, size_t...ColIndicesV>
|
template<typename ScalarT, size_t RowsV, size_t...ColIndicesV>
|
||||||
struct __component_count_helper<matrix<ScalarT, RowsV, ColIndicesV...>>
|
struct __component_count_helper<matrix<ScalarT, RowsV, ColIndicesV...>>
|
||||||
: integral_constant<size_t, RowsV * sizeof...(ColIndicesV)> {};
|
: integral_constant<size_t, RowsV * sizeof...(ColIndicesV)> {};
|
||||||
|
|
||||||
|
// default case reduces to 0
|
||||||
template<typename>
|
template<typename>
|
||||||
struct __component_count_helper
|
struct __component_count_helper
|
||||||
: integral_constant<size_t, 0> {};
|
: integral_constant<size_t, 0> {};
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#define FENNEC_MATH_RELATIONAL_H
|
#define FENNEC_MATH_RELATIONAL_H
|
||||||
#include <fennec/lang/types.h>
|
#include <fennec/lang/types.h>
|
||||||
|
|
||||||
|
// TODO: Document
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -20,13 +20,192 @@
|
|||||||
#ifndef FENNEC_MEMORY_ALLOCATOR_H
|
#ifndef FENNEC_MEMORY_ALLOCATOR_H
|
||||||
#define FENNEC_MEMORY_ALLOCATOR_H
|
#define FENNEC_MEMORY_ALLOCATOR_H
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <type_traits>
|
||||||
#include <memory>
|
#include <fennec/memory/ptr_traits.h>
|
||||||
|
#include <fennec/lang/conditional_types.h>
|
||||||
|
#include <fennec/lang/types.h>
|
||||||
|
#include <fennec/lang/type_traits.h>
|
||||||
|
#include <fennec/math/common.h>
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
std::allocator<char> alloc;
|
template<class Alloc>
|
||||||
|
struct allocator_traits
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
// These help with using concepts in `detect_t`
|
||||||
|
template<typename ClassT> using __pointer = typename ClassT::pointer_t;
|
||||||
|
template<typename ClassT> using __const_pointer = typename ClassT::const_pointer_t;
|
||||||
|
template<typename ClassT> using __void_pointer = typename ClassT::void_pointer_t;
|
||||||
|
template<typename ClassT> using __void_const_pointer = typename ClassT::void_const_pointer_t;
|
||||||
|
|
||||||
|
// Propagation Patterns
|
||||||
|
template<typename ClassT> using __propagate_on_containter_copy_assignment = typename ClassT::propagate_on_containter_copy_assignment;
|
||||||
|
template<typename ClassT> using __propagate_on_containter_move_assignment = typename ClassT::propagate_on_containter_move_assignment;
|
||||||
|
template<typename ClassT> using __propagate_on_containter_swap = typename ClassT::propagate_on_containter_swap;
|
||||||
|
|
||||||
|
template<typename ClassT> using __is_always_equal = typename ClassT::is_always_equal;
|
||||||
|
|
||||||
|
template<typename AllocT, typename TypeT>
|
||||||
|
struct __rebind : replace_first_element<AllocT, TypeT> {};
|
||||||
|
|
||||||
|
template<typename AllocT, typename TypeT>
|
||||||
|
requires requires { typename AllocT::template rebind<TypeT>::other; }
|
||||||
|
struct __rebind<AllocT, TypeT> { using type = typename AllocT::template rebind<TypeT>::other; };
|
||||||
|
|
||||||
|
// This detects AllocT::diff_t if present, otherwise uses the diff_t associated with PtrT
|
||||||
|
// It works using SFINAE, 'typename = void' forces the second __diff to be evaluated first when
|
||||||
|
// __diff is substituted using only two template arguments. That one uses 'type = typename AllocT::diff_t'
|
||||||
|
// however, if it fails, the compiler moves on to the original definition. __size works in the same manner.
|
||||||
|
template<typename AllocT, typename PtrT, typename = void>
|
||||||
|
struct __diff { using type = typename ptr_traits<PtrT>::diff_t; };
|
||||||
|
|
||||||
|
template<typename AllocT, typename PtrT>
|
||||||
|
struct __diff<AllocT, PtrT, void_t<typename AllocT::diff_t>> { using type = typename AllocT::diff_t; };
|
||||||
|
|
||||||
|
template<typename AllocT, typename DiffT, typename = void>
|
||||||
|
struct __size : std::make_unsigned<DiffT> {};
|
||||||
|
|
||||||
|
template<typename AllocT, typename DiffT>
|
||||||
|
struct __size<AllocT, DiffT, void_t<typename AllocT::size_t>> { using type = typename AllocT::size_t; };
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// \brief Alias for the allocator type
|
||||||
|
using alloc_t = Alloc;
|
||||||
|
|
||||||
|
/// \brief Alias for the value type of the allocator
|
||||||
|
using value_t = typename Alloc::value_t;
|
||||||
|
|
||||||
|
/// \brief Alias for a pointer to the value type. Will use `Alloc::pointer_t` if present
|
||||||
|
using pointer_t = detect_t<value_t*, __pointer, Alloc>;
|
||||||
|
|
||||||
|
/// \brief Alias for a const pointer to the value type. Will use `Alloc::const_pointer_t` if present
|
||||||
|
using const_pointer_t = detect_t<const value_t*, __const_pointer, Alloc>;
|
||||||
|
|
||||||
|
/// \brief Alias for a pointer to void. Will use `Alloc::void_pointer_t` if present
|
||||||
|
using void_pointer_t = detect_t<void*, __void_pointer, Alloc>;
|
||||||
|
|
||||||
|
/// \brief Alias for a const pointer to void. Will use `Alloc::const_void_pointer_t` if present
|
||||||
|
using const_void_pointer_t = detect_t<const void*, __void_const_pointer, Alloc>;
|
||||||
|
|
||||||
|
/// \brief Alias for differences between pointers. Will use `Alloc::diff_t` if present
|
||||||
|
using diff_t = typename __diff<Alloc, pointer_t>::type;
|
||||||
|
|
||||||
|
/// \brief Alias for the size of allocations. Will use `Alloc::size_t` if present
|
||||||
|
using size_t = typename __size<Alloc, pointer_t>::type;
|
||||||
|
|
||||||
|
// TODO: Document propagation
|
||||||
|
using propagate_on_container_copy_assignment = detect_t<false_type, __propagate_on_containter_copy_assignment, Alloc>;
|
||||||
|
using propagate_on_container_move_assignment = detect_t<false_type, __propagate_on_containter_move_assignment, Alloc>;
|
||||||
|
using propagate_on_container_swap = detect_t<false_type, __propagate_on_containter_swap, Alloc>;
|
||||||
|
|
||||||
|
/// \brief Checks if this allocator type is always equal to another allocator of similar type
|
||||||
|
using is_always_equal = detect_t<false_type, __is_always_equal, Alloc>;
|
||||||
|
|
||||||
|
/// \brief Rebinds the allocator type to produce an element type of type `TypeT`
|
||||||
|
template<typename TypeT> using rebind = typename __rebind<Alloc, TypeT>::type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Allocator implementation, uses `new` and `delete` operators.
|
||||||
|
/// \tparam T The data type to allocate
|
||||||
|
template<typename T>
|
||||||
|
class allocator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// \brief Alias for the data type used for metaprogramming
|
||||||
|
using value_t = T;
|
||||||
|
|
||||||
|
/// \brief Metaprogramming utility to rebind an allocator to a different data type
|
||||||
|
template<typename R> using rebind = allocator<R>;
|
||||||
|
|
||||||
|
/// \brief Default Constructor
|
||||||
|
constexpr allocator() = default;
|
||||||
|
|
||||||
|
/// \brief Default Destructor
|
||||||
|
constexpr ~allocator() = default;
|
||||||
|
|
||||||
|
/// \brief Copy Constructor
|
||||||
|
constexpr allocator(const allocator&) = default;
|
||||||
|
|
||||||
|
/// \brief Copy Assignment
|
||||||
|
constexpr allocator& operator=(const allocator&) = default;
|
||||||
|
|
||||||
|
|
||||||
|
/// \brief Equality operator
|
||||||
|
constexpr bool_t operator==(const allocator&) { return true; }
|
||||||
|
|
||||||
|
/// \brief Inequality operator
|
||||||
|
constexpr bool_t operator!=(const allocator&) { return false; }
|
||||||
|
|
||||||
|
/// \brief Equality operator for allocators of same type but with different data type
|
||||||
|
template<typename U> constexpr bool_t operator==(const allocator<U>&) { return true; }
|
||||||
|
|
||||||
|
/// \brief Inequality operator for allocators of same type but with different data type
|
||||||
|
template<typename U> constexpr bool_t operator!=(const allocator<U>&) { return true; }
|
||||||
|
|
||||||
|
/// \brief Allocate a block of memory large enough to hold `n` elements of type `T`
|
||||||
|
constexpr T* allocate(size_t n) { return ::operator new(n * sizeof(T)); }
|
||||||
|
|
||||||
|
/// \brief Deallocate a block of memory with type `T`
|
||||||
|
constexpr void deallocate(T* ptr) { return ::operator delete(ptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Container to hold an allocation
|
||||||
|
/// \tparam T The data type of the allocation
|
||||||
|
template<typename T, class AllocT>
|
||||||
|
class allocation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// TODO: Document
|
||||||
|
|
||||||
|
using alloc_t = typename allocator_traits<AllocT>::template rebind<T>;
|
||||||
|
using element_t = T;
|
||||||
|
using size_t = size_t;
|
||||||
|
using diff_t = ptrdiff_t;
|
||||||
|
|
||||||
|
allocation() : _data(nullptr), _capacity(0) {}
|
||||||
|
allocation(size_t n) : _data(_alloc.al), _capacity(n) {}
|
||||||
|
~allocation() { if (_data) _alloc.deallocate(_data); }
|
||||||
|
|
||||||
|
void allocate(size_t n)
|
||||||
|
{
|
||||||
|
if (_data)
|
||||||
|
_alloc.deallocate(_data);
|
||||||
|
|
||||||
|
_data = alloc_t::allocate(_capacity = n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void release()
|
||||||
|
{
|
||||||
|
if (_data)
|
||||||
|
_alloc.deallocate(_data);
|
||||||
|
_data = nullptr;
|
||||||
|
_capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reallocate(size_t n)
|
||||||
|
{
|
||||||
|
if (_data == nullptr)
|
||||||
|
return _alloc.allocate(_capacity = n);
|
||||||
|
|
||||||
|
element_t* old = _data;
|
||||||
|
_data = alloc_t::allocate(n);
|
||||||
|
fennec::memcpy(_data, old, min(_capacity, n) * sizeof(T));
|
||||||
|
_alloc.deallocate(old);
|
||||||
|
_capacity = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
alloc_t _alloc;
|
||||||
|
element_t* _data;
|
||||||
|
size_t _capacity;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,8 +36,8 @@ namespace fennec
|
|||||||
template<typename ToT, typename FromT> requires(sizeof(ToT) == sizeof(FromT))
|
template<typename ToT, typename FromT> requires(sizeof(ToT) == sizeof(FromT))
|
||||||
constexpr ToT bit_cast(const FromT& from)
|
constexpr ToT bit_cast(const FromT& from)
|
||||||
{
|
{
|
||||||
if constexpr(FENNEC_HAS_BUILTIN_BITCAST)
|
if constexpr(FENNEC_HAS_BUILTIN_BIT_CAST)
|
||||||
return __builtin_bit_cast(ToT, from);
|
return FENNEC_BUILTIN_BIT_CAST(ToT, from);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ToT to;
|
ToT to;
|
||||||
|
@ -13,12 +13,15 @@ namespace fennec
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// helper for copying 2 bytes at once
|
||||||
constexpr size_t __memcpy_16(void* dst, const void* src)
|
constexpr size_t __memcpy_16(void* dst, const void* src)
|
||||||
{ *static_cast<uint16_t*>(dst) = *static_cast<const uint16_t*>(src); return 2; }
|
{ *static_cast<uint16_t*>(dst) = *static_cast<const uint16_t*>(src); return 2; }
|
||||||
|
|
||||||
|
// helper for copying 4 bytes at once
|
||||||
constexpr size_t __memcpy_32(void* dst, const void* src)
|
constexpr size_t __memcpy_32(void* dst, const void* src)
|
||||||
{ *static_cast<uint32_t*>(dst) = *static_cast<const uint32_t*>(src); return 4; }
|
{ *static_cast<uint32_t*>(dst) = *static_cast<const uint32_t*>(src); return 4; }
|
||||||
|
|
||||||
|
// helper for copying 8 bytes at once
|
||||||
constexpr size_t __memcpy_64(void* dst, const void* src)
|
constexpr size_t __memcpy_64(void* dst, const void* src)
|
||||||
{ *static_cast<uint64_t*>(dst) = *static_cast<const uint64_t*>(src); return 8; }
|
{ *static_cast<uint64_t*>(dst) = *static_cast<const uint64_t*>(src); return 8; }
|
||||||
|
|
||||||
|
92
include/fennec/memory/detail/__ptr_traits.h
Normal file
92
include/fennec/memory/detail/__ptr_traits.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright (C) 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//2
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_MEMORY_DETAIL_PTR_TRAITS_H
|
||||||
|
#define FENNEC_MEMORY_DETAIL_PTR_TRAITS_H
|
||||||
|
|
||||||
|
#include <fennec/lang/conditional_types.h>
|
||||||
|
#include <fennec/lang/types.h>
|
||||||
|
#include <fennec/lang/type_traits.h>
|
||||||
|
#include <fennec/lang/variadics.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
// helper to get the element type of the pointer class
|
||||||
|
template<typename ClassT, typename = void>
|
||||||
|
struct __ptr_get_element : first_element<ClassT> { }; // Default case, return the first template parameter
|
||||||
|
|
||||||
|
// overload for types that have a member `ClassT::element_t`
|
||||||
|
template<typename ClassT> requires requires { typename ClassT::element_t; }
|
||||||
|
struct __ptr_get_element { using type = typename ClassT::element_t; };
|
||||||
|
|
||||||
|
// helper for generating `pointer_to`
|
||||||
|
template<typename PtrT, typename ElemT, bool_t = is_void_v<ElemT>>
|
||||||
|
struct __ptr_traits_ptr_to
|
||||||
|
{
|
||||||
|
using pointer_t = PtrT;
|
||||||
|
using element_t = ElemT;
|
||||||
|
|
||||||
|
static constexpr pointer_t pointer_to(element_t& obj)
|
||||||
|
{ return pointer_t::pointer_to(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// overload for C style pointers
|
||||||
|
template<typename ElemT>
|
||||||
|
struct __ptr_traits_ptr_to<ElemT*, ElemT, false>
|
||||||
|
{
|
||||||
|
using pointer_t = ElemT*;
|
||||||
|
using element_t = ElemT;
|
||||||
|
|
||||||
|
static constexpr pointer_t pointer_to(element_t& obj)
|
||||||
|
{ return addressof(obj); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// underlying implementation for classes that behave like pointers
|
||||||
|
template<typename ClassT, typename ElemT, bool_t = is_void_v<ElemT>>
|
||||||
|
struct __ptr_traits_impl : __ptr_traits_ptr_to<ClassT, ElemT>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
template<typename TypeT>
|
||||||
|
using __diff_t = typename TypeT::diff_t; // Helper to prevent substitution issues with detecting the difference type
|
||||||
|
|
||||||
|
template<typename BaseT, typename OElemT> // Helper to prevent substitution issues with detecting a defined rebind
|
||||||
|
using __rebind_helper = type_transform<typename BaseT::template rebind<OElemT>>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
using pointer_t = ClassT;
|
||||||
|
using element_t = __ptr_get_element<ClassT>;
|
||||||
|
using diff_t = __diff_t<ClassT>;
|
||||||
|
|
||||||
|
template<class U> using rebind = detect_t<replace_first_element<ClassT, U>, __rebind_helper, ClassT, ElemT>;
|
||||||
|
};
|
||||||
|
|
||||||
|
// overload for an undefined type
|
||||||
|
template<typename ClassT> struct __ptr_traits_impl<ClassT, undefined_t> {};
|
||||||
|
|
||||||
|
// overload for void element
|
||||||
|
template<typename PtrT, typename ElemT> struct __ptr_traits_ptr_to<PtrT, ElemT, true> { };
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_MEMORY_DETAIL_PTR_TRAITS_H
|
@ -25,6 +25,14 @@
|
|||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Returns the address of an object regardless of whether the `&` operators is implemented.
|
||||||
|
/// \tparam TypeT The type of the objects
|
||||||
|
/// \param obj The object to find the address of
|
||||||
|
/// \return The true address of the
|
||||||
|
template<typename TypeT>
|
||||||
|
constexpr TypeT* addressof(TypeT& obj) { return FENNEC_BUILTIN_ADDRESSOF(obj); }
|
||||||
|
|
||||||
///
|
///
|
||||||
/// \copydetails fennec::memchr(const void*, int, size_t)
|
/// \copydetails fennec::memchr(const void*, int, size_t)
|
||||||
constexpr void* memchr(void* arr, int ch, size_t n)
|
constexpr void* memchr(void* arr, int ch, size_t n)
|
||||||
@ -52,7 +60,7 @@ constexpr const void* memchr(const void* arr, int ch, size_t n)
|
|||||||
/// \param lhs The first object, interpreted as an array of bytes
|
/// \param lhs The first object, interpreted as an array of bytes
|
||||||
/// \param rhs The second object, interpreted as an array of bytes
|
/// \param rhs The second object, interpreted as an array of bytes
|
||||||
/// \param n The number of bytes to parse
|
/// \param n The number of bytes to parse
|
||||||
/// \returns \f$0\f$ if the first \f$n\f$ bytes of \f$lhs\f$ and \f$rhs\f$ are equivalent. Otherwise returns \f$1\f$
|
/// \returns \f$0\f$ if the first \f$n\f$ bytes of \f$lhs\f$ and \f$rhs\f$ are equivalent. Otherwise, returns \f$1\f$
|
||||||
/// for the first byte \f$b\f$ where \f$lhs[b] > \f$ rhs[b]\f$, and \f$-1\f$ for \f$
|
/// for the first byte \f$b\f$ where \f$lhs[b] > \f$ rhs[b]\f$, and \f$-1\f$ for \f$
|
||||||
constexpr int memcmp(const void* lhs, const void* rhs, size_t n)
|
constexpr int memcmp(const void* lhs, const void* rhs, size_t n)
|
||||||
{
|
{
|
||||||
@ -145,6 +153,21 @@ constexpr void* memset(void* dst, int ch, size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeT>
|
||||||
|
struct default_delete
|
||||||
|
{
|
||||||
|
constexpr default_delete() noexcept = default;
|
||||||
|
|
||||||
|
template<class U> default_delete(const default_delete<U>&) noexcept;
|
||||||
|
template<class U> default_delete(const default_delete<U[]>&) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename TypeT>
|
||||||
|
struct default_delete<TypeT[]>
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FENNEC_MEMORY_H
|
#endif // FENNEC_MEMORY_H
|
||||||
|
@ -25,9 +25,6 @@
|
|||||||
|
|
||||||
#include <fennec/lang/types.h>
|
#include <fennec/lang/types.h>
|
||||||
|
|
||||||
// TODO: Document
|
|
||||||
// TODO: Memory Debugging
|
|
||||||
|
|
||||||
namespace fennec
|
namespace fennec
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -39,8 +36,6 @@ enum class align_t : size_t;
|
|||||||
/// \brief Type to handle explicit nothrow definitions
|
/// \brief Type to handle explicit nothrow definitions
|
||||||
struct nothrow_t { explicit nothrow_t() noexcept { } };
|
struct nothrow_t { explicit nothrow_t() noexcept { } };
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FENNEC_MEMORY_NEW_H
|
#endif // FENNEC_MEMORY_NEW_H
|
||||||
|
46
include/fennec/memory/pointers.h
Normal file
46
include/fennec/memory/pointers.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright (C) 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//2
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_LANG_POINTERS_H
|
||||||
|
#define FENNEC_LANG_POINTERS_H
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TypeT, class DeleteT = >
|
||||||
|
class unique_ptr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using element_t = TypeT;
|
||||||
|
using pointer_t = element_t*;
|
||||||
|
|
||||||
|
constexpr unique_ptr() : unique_ptr(nullptr) {}
|
||||||
|
constexpr unique_ptr(pointer_t ptr) : _handle(ptr) {}
|
||||||
|
constexpr unique_ptr(unique_ptr&& other) : _handle(other._handle) { other._handle = nullptr; }
|
||||||
|
|
||||||
|
constexpr ~unique_ptr() { if(_handle) ::operator delete(_handle); }
|
||||||
|
|
||||||
|
constexpr unique_ptr& operator=(unique_ptr&& r) noexcept
|
||||||
|
{ _handle = r._handle; r._handle = nullptr; return *this; }
|
||||||
|
|
||||||
|
pointer_t release() { pointer_t retval = _handle; _handle = nullptr; return retval; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
pointer_t _handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FENNEC_LANG_POINTERS_H
|
48
include/fennec/memory/ptr_traits.h
Normal file
48
include/fennec/memory/ptr_traits.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// =====================================================================================================================
|
||||||
|
// fennec, a free and open source game engine
|
||||||
|
// Copyright (C) 2025 Medusa Slockbower
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//2
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
// =====================================================================================================================
|
||||||
|
|
||||||
|
#ifndef FENNEC_MEMORY_PTR_TRAITS_H
|
||||||
|
#define FENNEC_MEMORY_PTR_TRAITS_H
|
||||||
|
|
||||||
|
#include <fennec/lang/types.h>
|
||||||
|
#include <fennec/memory/detail/__ptr_traits.h>
|
||||||
|
|
||||||
|
namespace fennec
|
||||||
|
{
|
||||||
|
|
||||||
|
///
|
||||||
|
/// \brief Class for retrieving the traits of Pointer-like types
|
||||||
|
/// \tparam ClassT The Pointer class type
|
||||||
|
template<typename ClassT>
|
||||||
|
struct ptr_traits
|
||||||
|
: detail::__ptr_traits_impl<ClassT, detail::__ptr_get_element<ClassT>> {};
|
||||||
|
|
||||||
|
// overload for C-Style Pointers
|
||||||
|
template<typename ElemT>
|
||||||
|
struct ptr_traits<ElemT*> : detail::__ptr_traits_ptr_to<ElemT*, ElemT>
|
||||||
|
{
|
||||||
|
using pointer_t = ElemT*;
|
||||||
|
using element_t = ElemT;
|
||||||
|
using diff_t = ptrdiff_t;
|
||||||
|
|
||||||
|
template<typename U> using rebind = U*;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // FENNEC_MEMORY_PTR_TRAITS_H
|
@ -21,6 +21,10 @@
|
|||||||
|
|
||||||
#ifdef FENNEC_MEMORY_DEBUGGER
|
#ifdef FENNEC_MEMORY_DEBUGGER
|
||||||
|
|
||||||
|
// TODO: Memory Debugging
|
||||||
|
|
||||||
|
// General concept is to create a table of allocated memory addresses.
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// Allocation functions
|
// Allocation functions
|
||||||
|
Loading…
x
Reference in New Issue
Block a user