Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ target_compile_features(cpp_core INTERFACE cxx_std_23)
set(CMAKE_CXX_MODULE_STD 23)
set(CMAKE_CXX_MODULE_EXTENSIONS OFF)

include(CTest)

if(BUILD_TESTING)
add_library(cpp_core_status_code_compile_test OBJECT tests/status_code_compile_test.cpp)
target_link_libraries(cpp_core_status_code_compile_test PRIVATE cpp_core::cpp_core)
endif()

# Install rules --------------------------------------------------------------
include(GNUInstallDirs)

Expand Down
2 changes: 1 addition & 1 deletion include/cpp_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@

#include "cpp_core/error_callback.h"
#include "cpp_core/serial.h"
#include "cpp_core/status_codes.h"
#include "cpp_core/status_code.h"
#include "cpp_core/version.hpp"
2 changes: 1 addition & 1 deletion include/cpp_core/error_handling.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "status_codes.h"
#include "status_code.h"

#include <concepts>
#include <string>
Expand Down
4 changes: 2 additions & 2 deletions include/cpp_core/interface/serial_abort_read.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ extern "C"
* @brief Abort a blocking read operation running in a different thread.
*
* The target read function returns immediately with
* ::cpp_core::StatusCodes::kAbortReadError.
* ::cpp_core::StatusCode::Io::kAbortReadError.
*
* @param handle Port handle.
* @param error_callback [optional] Callback to invoke on error. Defined in error_callback.h. Default is `nullptr`.
* @return 0 on success or a negative error code from ::cpp_core::StatusCodes on error.
* @return 0 on success or a negative error code from ::cpp_core::StatusCode on error.
*/
MODULE_API auto serialAbortRead(int64_t handle, ErrorCallbackT error_callback = nullptr) -> int;

Expand Down
4 changes: 2 additions & 2 deletions include/cpp_core/interface/serial_abort_write.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ extern "C"
* @brief Abort a blocking write operation running in a different thread.
*
* The target write function returns immediately with
* ::cpp_core::StatusCodes::kAbortWriteError.
* ::cpp_core::StatusCode::Io::kAbortWriteError.
*
* @param handle Port handle.
* @param error_callback [optional] Callback to invoke on error. Defined in error_callback.h. Default is `nullptr`.
* @return 0 on success or a negative error code from ::cpp_core::StatusCodes on error.
* @return 0 on success or a negative error code from ::cpp_core::StatusCode on error.
*/
MODULE_API auto serialAbortWrite(int64_t handle, ErrorCallbackT error_callback = nullptr) -> int;

Expand Down
2 changes: 1 addition & 1 deletion include/cpp_core/result.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "status_codes.h"
#include "status_code.h"

#include <concepts>
#include <expected>
Expand Down
139 changes: 139 additions & 0 deletions include/cpp_core/status_code.h
Comment thread
Katze719 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#pragma once

#include <cstdint>
#include <string_view>

namespace cpp_core::status_codes
{

namespace detail
{

using ValueType = std::int64_t;

inline constexpr ValueType kCategoryMultiplier{100};

template <typename Category, ValueType NumericValue> struct Code
{
static constexpr ValueType kValue = NumericValue;
std::string_view kName; // NOLINT(readability-identifier-naming)

// NOLINTNEXTLINE(google-explicit-constructor, hicpp-explicit-conversions)
constexpr operator ValueType() const noexcept
{
return kValue;
}
[[nodiscard]] constexpr auto value() const noexcept -> ValueType
{
return kValue;
}
[[nodiscard]] constexpr auto name() const noexcept -> std::string_view
{
return kName;
}
[[nodiscard]] constexpr auto category() const noexcept -> std::string_view
{
return Category::kCategoryName;
}
};

template <typename Derived> struct CategoryBase
{
private:
constexpr CategoryBase() = default;

protected:
template <ValueType LocalCode> static consteval auto computeValue() -> ValueType
{
static_assert(Derived::kCategoryCode >= 0, "Category code must not be negative");
static_assert(LocalCode >= 0, "Code index must not be negative");
static_assert(LocalCode < kCategoryMultiplier, "Category overflow (max 99 codes)");
static_assert(Derived::kCategoryCode <=
(std::numeric_limits<ValueType>::max() - kCategoryMultiplier + 1) / kCategoryMultiplier,
"Category code too large, multiplication would overflow");
return -((Derived::kCategoryCode * kCategoryMultiplier) + LocalCode);
}

template <ValueType LocalCode> using Code = detail::Code<Derived, computeValue<LocalCode>()>;

friend Derived;
};

} // namespace detail

struct StatusCode
{
using ValueType = detail::ValueType;
static constexpr ValueType kSuccess = 0;

struct Configuration : detail::CategoryBase<Configuration>
{
static constexpr ValueType kCategoryCode = 1;
static constexpr std::string_view kCategoryName{"Configuration"};

static constexpr Code<0> kSetBaudrateError{"SetBaudrateError"};
static constexpr Code<1> kSetDataBitsError{"SetDataBitsError"};
static constexpr Code<2> kSetParityError{"SetParityError"};
static constexpr Code<3> kSetStopBitsError{"SetStopBitsError"};
static constexpr Code<4> kSetFlowControlError{"SetFlowControlError"};
static constexpr Code<5> kSetTimeoutError{"SetTimeoutError"};
};

struct Connection : detail::CategoryBase<Connection>
{
static constexpr ValueType kCategoryCode = 2;
static constexpr std::string_view kCategoryName{"Connection"};

static constexpr Code<0> kNotFoundError{"NotFoundError"};
static constexpr Code<1> kInvalidHandleError{"InvalidHandleError"};
static constexpr Code<2> kCloseHandleError{"CloseHandleError"};
};

struct Io : detail::CategoryBase<Io>
{
static constexpr ValueType kCategoryCode = 3;
static constexpr std::string_view kCategoryName{"Io"};

static constexpr Code<0> kReadError{"ReadError"};
static constexpr Code<1> kWriteError{"WriteError"};
static constexpr Code<2> kAbortReadError{"AbortReadError"};
static constexpr Code<3> kAbortWriteError{"AbortWriteError"};
static constexpr Code<4> kBufferError{"BufferError"};
static constexpr Code<5> kClearBufferInError{"ClearBufferInError"};
static constexpr Code<6> kClearBufferOutError{"ClearBufferOutError"};
};

struct Control : detail::CategoryBase<Control>
{
static constexpr ValueType kCategoryCode = 4;
static constexpr std::string_view kCategoryName{"Control"};

static constexpr Code<0> kSetDtrError{"SetDtrError"};
static constexpr Code<1> kSetRtsError{"SetRtsError"};
static constexpr Code<2> kGetModemStatusError{"GetModemStatusError"};
static constexpr Code<3> kSendBreakError{"SendBreakError"};
static constexpr Code<4> kGetStateError{"GetStateError"};
static constexpr Code<5> kSetStateError{"SetStateError"};
};

[[nodiscard]] static constexpr auto isError(ValueType code) noexcept -> bool
{
return code < 0;
}
[[nodiscard]] static constexpr auto isSuccess(ValueType code) noexcept -> bool
{
return code >= 0;
}
template <typename Category> [[nodiscard]] static constexpr auto belongsTo(ValueType code) noexcept -> bool
{
return code < 0 && (-code) / detail::kCategoryMultiplier == Category::kCategoryCode;
}
};

} // namespace cpp_core::status_codes

namespace cpp_core
{
using StatusCodes = ::cpp_core::status_codes::detail::ValueType;
using ::cpp_core::status_codes::StatusCode;
} // namespace cpp_core
31 changes: 0 additions & 31 deletions include/cpp_core/status_codes.h

This file was deleted.

108 changes: 0 additions & 108 deletions include/cpp_core/status_codes.hpp

This file was deleted.

Loading