-
Notifications
You must be signed in to change notification settings - Fork 0
Peach Exceptions #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
cc341b3
99852cd
004f962
25cdb5e
3589d83
7fac1d4
79cab40
557e6e9
d08f6d7
24a3f54
1014e65
f9498f7
c8124df
2abcd1f
1c7bcf7
44923fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,9 @@ | ||
| /.idea | ||
| /cmake-build-debug | ||
| /.git | ||
| cmake-build-debug/ | ||
| .git/ | ||
| tests/ | ||
| .vs/ | ||
| out/ | ||
| /out | ||
| /build | ||
| build/ | ||
| .idea/ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,42 @@ | ||
| cmake_minimum_required(VERSION 3.16.5) | ||
|
|
||
| project(PeachLibrary) | ||
| project(peach_library | ||
| VERSION 0.1 | ||
| LANGUAGES CXX | ||
| ) | ||
|
|
||
| set(CMAKE_CXX_STANDARD 20) | ||
| option(COMPONENT_TARGETS_ENABLED "enable individual config targets" YES) | ||
|
|
||
| add_library(PeachLibrary STATIC pe_exceptions/pe_exception.cpp) | ||
| add_subdirectory(exceptions) | ||
|
|
||
| set_target_properties(PeachLibrary PROPERTIES LINKER_LANGUAGE CXX) | ||
| include(CMakePackageConfigHelpers) | ||
|
|
||
| # generate the version file for the config file | ||
| write_basic_package_version_file( | ||
| ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake | ||
| VERSION ${PROJECT_VERSION} | ||
| COMPATIBILITY SameMajorVersion | ||
| ) | ||
|
|
||
| # create config file | ||
| configure_package_config_file( | ||
| config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake | ||
| INSTALL_DESTINATION lib/cmake/${PROJECT_NAME} | ||
| NO_CHECK_REQUIRED_COMPONENTS_MACRO | ||
| ) | ||
|
|
||
| # generate the export targets for the build tree. | ||
| # Note: The file created by this command is specific to the build | ||
| # tree and should never be installed! | ||
| export( | ||
| EXPORT ${PROJECT_NAME}-targets | ||
| FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-targets.cmake | ||
| NAMESPACE ${PROJECT_NAME}:: | ||
| ) | ||
|
|
||
| # install cmake project config files | ||
| install( | ||
| FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake | ||
| ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake | ||
| DESTINATION lib/cmake/${PROJECT_NAME} | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| { | ||
| "configurations": [ | ||
| { | ||
| "name": "x64-Clang-Debug", | ||
| "generator": "Ninja", | ||
| "configurationType": "Debug", | ||
| "buildRoot": "${projectDir}\\out\\build\\${name}", | ||
| "installRoot": "${projectDir}\\out\\install\\${name}", | ||
| "cmakeCommandArgs": "", | ||
| "buildCommandArgs": "", | ||
| "ctestCommandArgs": "", | ||
| "inheritEnvironments": [ "msvc_x64_x64" ] | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Im pretty sure these files should be hidden?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would suggest to either remove this file from git or make is obvious that it is a IDE dependent file. |
||
| } | ||
| ] | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| @PACKAGE_INIT@ | ||
|
|
||
| if(@COMPONENT_TARGETS_ENABLED@) | ||
| set(_supported_components exceptions) | ||
|
|
||
| foreach(_comp ${peach_library_FIND_COMPONENTS}) | ||
| if(NOT _comp IN_LIST _supported_components) | ||
| set(peach_library_FOUND False) | ||
| set(peach_library_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}") | ||
| endif() | ||
| include("${CMAKE_CURRENT_LIST_DIR}/peach_library-${_comp}-targets.cmake") | ||
| endforeach() | ||
| else() | ||
| include("${CMAKE_CURRENT_LIST_DIR}/peach_library-targets.cmake") | ||
| endif() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| set(component exceptions) | ||
|
|
||
| add_library(${component} STATIC src/exception.cpp) | ||
|
|
||
| target_compile_features(${component} PRIVATE cxx_std_20) | ||
|
|
||
| target_include_directories(${component} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> | ||
| $<INSTALL_INTERFACE:include> | ||
| ) | ||
|
|
||
| install( | ||
| TARGETS ${component} | ||
| EXPORT ${PROJECT_NAME}-targets | ||
| LIBRARY DESTINATION lib | ||
| ARCHIVE DESTINATION lib | ||
| RUNTIME DESTINATION bin | ||
| INCLUDES DESTINATION include | ||
| ) | ||
|
|
||
| if(COMPONENT_TARGETS_ENABLED) | ||
| # generate and install export file for this component target | ||
| install( | ||
| EXPORT ${PROJECT_NAME}-targets | ||
| FILE ${PROJECT_NAME}-${component}-targets.cmake | ||
| NAMESPACE ${PROJECT_NAME}:: | ||
| DESTINATION lib/cmake/${PROJECT_NAME} | ||
| ) | ||
| endif() | ||
|
|
||
| # install header files | ||
| install( | ||
| DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ | ||
| TYPE INCLUDE | ||
| FILES_MATCHING | ||
| PATTERN "*.hpp" | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| #ifndef PEACH_BASE_EXCEPTION_HPP | ||
| #define PEACH_BASE_EXCEPTION_HPP | ||
|
|
||
| #include <concepts> | ||
| #include <fstream> | ||
| #include <ostream> | ||
| #include <stdexcept> | ||
| #include <string> | ||
| #include <string_view> | ||
|
|
||
| namespace peach::detail | ||
| { | ||
| class BaseException : virtual public std::runtime_error | ||
| { | ||
| public: | ||
| BaseException( ) = default; | ||
|
|
||
| // clang-format off | ||
| BaseException( const BaseException& ) noexcept = default; | ||
| BaseException(BaseException&& ) noexcept = default; | ||
|
|
||
| BaseException& operator=(BaseException&& ) = default; | ||
| BaseException& operator=( const BaseException& ) = delete; | ||
| // clang-format on | ||
|
|
||
| virtual const std::string& what_str( ) const noexcept = 0; | ||
| virtual void print_to_console( ) const noexcept = 0; | ||
|
|
||
| virtual ~BaseException( ) { }; | ||
| }; | ||
|
|
||
| template< typename T > | ||
| std::ostream& operator<<( std::ostream& output_file, | ||
| const T& rhs ) requires( std::derived_from< T, BaseException > ) | ||
| { | ||
| output_file << rhs.what_str( ); | ||
|
|
||
| return output_file; | ||
| } | ||
|
|
||
| } // namespace peach::detail | ||
|
|
||
| #endif // PEACH_BASE_EXCEPTION_HPP |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| #ifndef PEACH_PREFIX_MANAGER_HPP | ||
| #define PEACH_PREFIX_MANAGER_HPP | ||
|
|
||
| #include <string> | ||
|
|
||
| namespace peach | ||
| { | ||
| enum class ExceptionTypes; | ||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since the |
||
| } // namespace peach | ||
|
|
||
| namespace peach | ||
| { | ||
|
|
||
| // Short info: | ||
| // * Provides general way to set default prefix | ||
| // Link docu: | ||
| class PrefixManager | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Creating instances of this does not really make any sense. So either the constructor should be protected (for inheritance to work), or we replace the class with a namespace that stores the default prefix (preferred by me). |
||
| { | ||
| public: | ||
| PrefixManager( ) noexcept = default; | ||
|
|
||
| PrefixManager( const PrefixManager& ) noexcept = delete; | ||
| PrefixManager( PrefixManager&& ) noexcept = delete; | ||
|
|
||
| PrefixManager& operator=( PrefixManager&& ) = delete; | ||
| PrefixManager& operator=( const PrefixManager& ) = delete; | ||
|
|
||
| // clang-format off | ||
| static void set_default_prefix( const std::string& prefix ) noexcept | ||
| { | ||
| m_default_prefix = prefix; | ||
| } | ||
| // clang-format on | ||
|
|
||
| inline static std::string m_default_prefix = { "LOG" }; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this might be protected |
||
|
|
||
| ~PrefixManager( ) noexcept = default; | ||
| }; | ||
|
|
||
| // Short info: | ||
| // * Defines and manages a prefix for each specific ExceptionType | ||
| // Link docu: | ||
| template< ExceptionTypes V > class Prefix : private PrefixManager | ||
| { | ||
| public: | ||
| static Prefix& get( ) noexcept | ||
| { | ||
| static Prefix< V > instance { }; | ||
| return instance; | ||
| } | ||
|
|
||
| Prefix( ) noexcept = default; | ||
|
|
||
| Prefix( const Prefix& ) noexcept = delete; | ||
| Prefix( Prefix&& ) noexcept = delete; | ||
|
|
||
| Prefix& operator=( Prefix&& ) = delete; | ||
| Prefix& operator=( const Prefix& ) = delete; | ||
|
|
||
| // clang-format off | ||
| void set_prefix( const std::string& prefix ) noexcept | ||
| { | ||
| m_prefix = prefix; | ||
| } | ||
|
|
||
| std::string get_prefix( ) const noexcept | ||
| { | ||
| if ( m_prefix.empty( ) ) | ||
| return m_default_prefix; | ||
|
|
||
| return m_prefix; | ||
| } | ||
| // clang-format on | ||
|
|
||
| std::string m_prefix; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should be private. |
||
|
|
||
| ~Prefix( ) noexcept = default; | ||
| }; | ||
|
|
||
| } // namespace peach | ||
|
|
||
| #endif // PEACH_PREFIX_MANAGER_HPP | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,84 @@ | ||||||
| #ifndef PEACH_EXCEPTION_HPP | ||||||
| #define PEACH_EXCEPTION_HPP | ||||||
|
|
||||||
| #include "core/base_exception.hpp" | ||||||
| #include "core/prefix_manager.hpp" | ||||||
|
|
||||||
| #include "utils/exception_constants.hpp" | ||||||
| #include "utils/exception_format.hpp" | ||||||
|
|
||||||
| #include <iostream> | ||||||
| #include <source_location> | ||||||
| #include <stdexcept> | ||||||
| #include <string> | ||||||
| #include <type_traits> | ||||||
| #include <utility> | ||||||
|
|
||||||
| namespace peach | ||||||
| { | ||||||
| // Short info: | ||||||
| // * This has to be explicitly defined by the user inside the peach namespace | ||||||
| // Link docu: | ||||||
| enum class ExceptionTypes; | ||||||
|
|
||||||
| // Short info: | ||||||
| // * The method what() isnt templated in the base class, so we cannot override what() | ||||||
| // * First ctor handles the case when std::source_location information is wanted, second does it without | ||||||
| // Link docu: | ||||||
| template< ExceptionTypes Val > class PeachException : virtual public detail::BaseException | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see no need to use virtual inheritance here. |
||||||
| { | ||||||
| public: | ||||||
| template< typename... Tys > | ||||||
| explicit PeachException( const std::source_location sl, Tys&&... args ) | ||||||
| : std::runtime_error { detail::format_error( sl.line( ), sl.file_name( ), | ||||||
| Prefix< Val >::get( ).get_prefix( ), | ||||||
| std::forward< Tys >( args )... ) } | ||||||
|
|
||||||
| { | ||||||
| m_err_msg = this->what( ); | ||||||
|
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are we sure this is legal?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this should be fine, as we do not overwrite
Suggested change
|
||||||
| m_prefix = Prefix< Val >::get( ).get_prefix( ); | ||||||
| } | ||||||
|
|
||||||
| template< typename... Tys > | ||||||
| explicit PeachException( Tys&&... args ) | ||||||
| : std::runtime_error { detail::format_error( detail::constants::kNoSourceLocation, "", | ||||||
|
joren-dev marked this conversation as resolved.
|
||||||
| Prefix< Val >::get( ).get_prefix( ), | ||||||
| std::forward< Tys >( args )... ) } | ||||||
| { | ||||||
| m_err_msg = this->what( ); | ||||||
| m_prefix = Prefix< Val >::get( ).get_prefix( ); | ||||||
| } | ||||||
|
|
||||||
| PeachException( const PeachException& ) noexcept = default; | ||||||
| PeachException( PeachException&& ) noexcept = default; | ||||||
|
|
||||||
| PeachException& operator=( PeachException&& ) = delete; | ||||||
| PeachException& operator=( const PeachException& ) = delete; | ||||||
|
|
||||||
| void print_to_console( ) const noexcept | ||||||
| { | ||||||
| // TODO: possibly determine if compiled application has a console available! | ||||||
| std::cerr << m_prefix << R"(( " )" << m_err_msg.substr( 0, m_err_msg.size( ) - 2 ) | ||||||
| << R"( " ))" << '\n'; | ||||||
| } | ||||||
|
Comment on lines
+58
to
+63
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would actually want to get rid of this, they can already get this precise message in a string, the user can just |
||||||
|
|
||||||
| const std::string& what_str( ) const noexcept { return m_err_msg; } | ||||||
|
|
||||||
| ~PeachException( ) = default; | ||||||
|
|
||||||
| private: | ||||||
| std::string m_err_msg; | ||||||
| std::string m_prefix; | ||||||
| }; | ||||||
|
|
||||||
| namespace detail | ||||||
| { | ||||||
| std::source_location | ||||||
| get_source_location_details( const std::source_location sl = std::source_location::current()) noexcept; | ||||||
| } // namespace detail | ||||||
|
|
||||||
| #define SL detail::get_source_location_details( ) | ||||||
|
|
||||||
| } // namespace peach | ||||||
|
|
||||||
| #endif // PEACH_EXCEPTION_HPP | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #ifndef PEACH_EXCEPTION_CONSTANTS_HPP | ||
| #define PEACH_EXCEPTION_CONSTANTS_HPP | ||
|
|
||
| namespace peach::detail::constants | ||
| { | ||
| constexpr int kNoSourceLocation { -1 }; | ||
|
|
||
| } // namespace peach::detail::constants | ||
|
|
||
| #endif // PEACH_EXCEPTION_CONSTANTS_HPP |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe reorder this to look nicer and remove the duplicate build folder