refactor: start to refactor project
This commit is contained in:
1 parent
bec36b4b3c
commit
df3b602110
70 files changed
+2093
-779
No files matched your search
+58
-38
@@ -1,7 +1,7 @@
|
||||
# Configure version file
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_LIST_DIR}/../cmake/YYCCVersion.hpp.in
|
||||
${CMAKE_CURRENT_LIST_DIR}/YYCC/YYCCVersion.hpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/yycc/version.hpp.in
|
||||
${CMAKE_CURRENT_LIST_DIR}/yycc/version.hpp
|
||||
@ONLY
|
||||
)
|
||||
|
||||
@@ -11,48 +11,68 @@ add_library(YYCCommonplace STATIC "")
|
||||
target_sources(YYCCommonplace
|
||||
PRIVATE
|
||||
# Sources
|
||||
YYCC/COMHelper.cpp
|
||||
YYCC/ArgParser.cpp
|
||||
YYCC/ConfigManager.cpp
|
||||
YYCC/ConsoleHelper.cpp
|
||||
YYCC/DialogHelper.cpp
|
||||
YYCC/EncodingHelper.cpp
|
||||
YYCC/ExceptionHelper.cpp
|
||||
YYCC/StdPatch.cpp
|
||||
YYCC/IOHelper.cpp
|
||||
YYCC/StringHelper.cpp
|
||||
YYCC/WinFctHelper.cpp
|
||||
# Natvis (only for MSVC)
|
||||
$<$<CXX_COMPILER_ID:MSVC>:YYCC.natvis>
|
||||
yycc/string/reinterpret.cpp
|
||||
yycc/string/op.cpp
|
||||
# YYCC/COMHelper.cpp
|
||||
# YYCC/ArgParser.cpp
|
||||
# YYCC/ConfigManager.cpp
|
||||
# YYCC/ConsoleHelper.cpp
|
||||
# YYCC/DialogHelper.cpp
|
||||
# YYCC/EncodingHelper.cpp
|
||||
# YYCC/ExceptionHelper.cpp
|
||||
# YYCC/StdPatch.cpp
|
||||
# YYCC/IOHelper.cpp
|
||||
# YYCC/StringHelper.cpp
|
||||
# YYCC/WinFctHelper.cpp
|
||||
# # Natvis (only for MSVC)
|
||||
# $<$<CXX_COMPILER_ID:MSVC>:YYCC.natvis>
|
||||
)
|
||||
target_sources(YYCCommonplace
|
||||
PUBLIC
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
# Headers
|
||||
# Common headers
|
||||
YYCC/Constraints.hpp
|
||||
YYCC/COMHelper.hpp
|
||||
YYCC/ArgParser.hpp
|
||||
YYCC/ConfigManager.hpp
|
||||
YYCC/ConsoleHelper.hpp
|
||||
YYCC/DialogHelper.hpp
|
||||
YYCC/EncodingHelper.hpp
|
||||
YYCC/EnumHelper.hpp
|
||||
YYCC/ExceptionHelper.hpp
|
||||
YYCC/StdPatch.hpp
|
||||
YYCC/IOHelper.hpp
|
||||
YYCC/ParserHelper.hpp
|
||||
YYCC/StringHelper.hpp
|
||||
YYCC/WinFctHelper.hpp
|
||||
# Windows including guard pair
|
||||
YYCC/WinImportPrefix.hpp
|
||||
YYCC/WinImportSuffix.hpp
|
||||
# Internal
|
||||
YYCC/YYCCVersion.hpp
|
||||
YYCC/YYCCInternal.hpp
|
||||
# Exposed
|
||||
YYCCommonplace.hpp
|
||||
yycc.hpp
|
||||
yycc/version.hpp
|
||||
yycc/prelude/core.hpp
|
||||
yycc/prelude/rust.hpp
|
||||
yycc/macro/version_cmp.hpp
|
||||
yycc/macro/os_detector.hpp
|
||||
yycc/macro/class_copy_move.hpp
|
||||
yycc/string.hpp
|
||||
yycc/string/reinterpret.hpp
|
||||
yycc/string/op.hpp
|
||||
yycc/rust/primitive.hpp
|
||||
yycc/windows/unsafe_suppressor.hpp
|
||||
yycc/windows/import_guard_head.hpp
|
||||
yycc/windows/import_guard_tail.hpp
|
||||
yycc/constraint.hpp
|
||||
yycc/constraint/builder.hpp
|
||||
|
||||
# # Headers
|
||||
# # Common headers
|
||||
# YYCC/Constraints.hpp
|
||||
# YYCC/COMHelper.hpp
|
||||
# YYCC/ArgParser.hpp
|
||||
# YYCC/ConfigManager.hpp
|
||||
# YYCC/ConsoleHelper.hpp
|
||||
# YYCC/DialogHelper.hpp
|
||||
# YYCC/EncodingHelper.hpp
|
||||
# YYCC/EnumHelper.hpp
|
||||
# YYCC/ExceptionHelper.hpp
|
||||
# YYCC/StdPatch.hpp
|
||||
# YYCC/IOHelper.hpp
|
||||
# YYCC/ParserHelper.hpp
|
||||
# YYCC/StringHelper.hpp
|
||||
# YYCC/WinFctHelper.hpp
|
||||
# # Windows including guard pair
|
||||
# YYCC/WinImportPrefix.hpp
|
||||
# YYCC/WinImportSuffix.hpp
|
||||
# # Internal
|
||||
# YYCC/YYCCVersion.hpp
|
||||
# YYCC/YYCCInternal.hpp
|
||||
# # Exposed
|
||||
# YYCCommonplace.hpp
|
||||
)
|
||||
# Setup header infomations
|
||||
target_include_directories(YYCCommonplace
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
// Library Version and Comparison Macros
|
||||
#include "yycc/version.hpp"
|
||||
#include "yycc/macro/version_cmp.hpp"
|
||||
|
||||
// Operating System Identifier Macros
|
||||
#include "yycc/macro/os_detector.hpp"
|
||||
|
||||
// Windows Shitty Behavior Disable Macros
|
||||
#include "yycc/windows/unsafe_suppressor.hpp"
|
||||
|
||||
// Batch Class Move / Copy Function Macros
|
||||
#include "yycc/macro/class_copy_move.hpp"
|
||||
|
||||
namespace yycc {}
|
||||
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
#include "macro/class_copy_move.hpp"
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
#include <algorithm>
|
||||
|
||||
/// @brief The namespace containing generic constraint concept used varied in other modules.
|
||||
namespace yycc::constraint {
|
||||
|
||||
/// @brief Function prototype used in Constraint for checking whether given value is valid.
|
||||
/// @details Analyze given value, and return true if value is legal, otherwise false.
|
||||
template<typename T>
|
||||
using FnCheck = std::function<bool(const T&)>;
|
||||
/// @brief Function prototype used in Constraint for clamping given value into a valid value.
|
||||
/// @details Analyze given value, return clamped value.
|
||||
template<typename T>
|
||||
using FnClamp = std::function<T(const T&)>;
|
||||
|
||||
/**
|
||||
* @brief The constraint applied to settings to limit its stored value.
|
||||
* @tparam T The data type this constraint need to be processed with.
|
||||
* @details
|
||||
* Constraint class contains various features:
|
||||
* \li Check: Check whether given value is in range.
|
||||
* \li Clamp: Clamp given value into valid value.
|
||||
* Every instances of Constraint can have some, or none of these features.
|
||||
* So it is essential to check whether instance has corresponding features before using it.
|
||||
*/
|
||||
template<typename T>
|
||||
class Constraint {
|
||||
public:
|
||||
Constraint(FnCheck<T>&& fn_check, FnClamp<T>&& fn_clamp) :
|
||||
fn_check(std::move(fn_check)), fn_clamp(std::move(fn_clamp)) {}
|
||||
YYCC_DELETE_COPY(Constraint)
|
||||
YYCC_DEFAULT_MOVE(Constraint)
|
||||
|
||||
/**
|
||||
* @brief Perform Check feature.
|
||||
* @param[in] value The valid for checking.
|
||||
* @return True if valid is okey, otherwise false.
|
||||
* @exception std::logic_error Raised if this feature is not supported.
|
||||
*/
|
||||
bool check(const T& value) const {
|
||||
if (!support_check()) {
|
||||
throw std::logic_error("this Constraint do not support check operation");
|
||||
} else {
|
||||
return fn_check(value);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Perform Clamp feature.
|
||||
* @param[in] value The valid for clamping.
|
||||
* @return The result after clamping.
|
||||
* @exception std::logic_error Raised if this feature is not supported.
|
||||
*/
|
||||
T clamp(const T& value) const {
|
||||
if (!support_clamp()) {
|
||||
throw std::logic_error("this Constraint do not support clamp operation");
|
||||
} else {
|
||||
return fn_clamp(value);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Check whether this Constraint support Check feature.
|
||||
/// @return True if it support, otherwise false.
|
||||
bool support_check() const noexcept { return this->fn_check != nullptr; }
|
||||
/// @brief Check whether this Constraint support Clamp feature.
|
||||
/// @return True if it support, otherwise false.
|
||||
bool support_clamp() const noexcept { return this->fn_clamp != nullptr; }
|
||||
|
||||
private:
|
||||
/// @brief Pointer to Check feature function.
|
||||
FnCheck<T> fn_check;
|
||||
/// @brief Pointer to Clamp feature function.
|
||||
FnClamp<T> fn_clamp;
|
||||
};
|
||||
|
||||
} // namespace yycc::core::constraint
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
#include "../constraint.hpp"
|
||||
#include "../string.hpp"
|
||||
#include <set>
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
|
||||
/// @brief The namespace containing convenient function building common used Constraint instance.
|
||||
namespace yycc::constraint::builder {
|
||||
|
||||
/**
|
||||
* @brief Build Constraint for arithmetic values by minimum and maximum value range.
|
||||
* @tparam T An arithmetic or enum type (except bool) of underlying stored value.
|
||||
* @param[in] min_value The minimum value of range (inclusive).
|
||||
* @param[in] max_value The maximum value of range (inclusive).
|
||||
* @return The generated constraint instance which can be directly applied.
|
||||
*/
|
||||
template<typename T,
|
||||
std::enable_if_t<std::is_arithmetic_v<T> && !std::is_same_v<T, bool>, int> = 0>
|
||||
Constraint<T> min_max_constraint(T min_value, T max_value) {
|
||||
if (min_value > max_value)
|
||||
throw std::invalid_argument("the max value must be equal or greater than min value");
|
||||
|
||||
auto fn_check = [min_value, max_value](const T& val) -> bool {
|
||||
return (val <= max_value) && (val >= min_value);
|
||||
};
|
||||
auto fn_clamp = [min_value, max_value](const T& val) -> T {
|
||||
return std::clamp(val, min_value, max_value);
|
||||
};
|
||||
return Constraint<T>(std::move(fn_check), std::move(fn_clamp));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get constraint for enum values by enumerating all possible values.
|
||||
* @tparam T An enum type (except bool) of underlying stored value.
|
||||
* @param[in] il An initializer list storing all possible values.
|
||||
* @return The generated constraint instance which can be directly applied.
|
||||
*/
|
||||
template<typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
|
||||
Constraint<T> enum_constraint(const std::initializer_list<T>& il) {
|
||||
std::set<T> data(il);
|
||||
|
||||
auto fn_check = [data](const T& val) -> bool { return data.find(val) != data.end(); };
|
||||
return Constraint<T>(std::move(fn_check), nullptr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get constraint for string values by enumerating all possible values.
|
||||
* @param[in] il An initializer list storing all possible values.
|
||||
* @return The generated constraint instance which can be directly applied.
|
||||
* @remarks
|
||||
* Caller must make sure that the string view passed in initializer list is valid until this Constraint life time gone.
|
||||
* Becasue this generator will not copy your given string view into string.
|
||||
*/
|
||||
inline Constraint<NS_YYCC_STRING::u8string> GetStringEnumerationConstraint(
|
||||
const std::initializer_list<NS_YYCC_STRING::u8string_view>& il) {
|
||||
std::set<NS_YYCC_STRING::u8string_view> data(il);
|
||||
|
||||
auto fn_check = [data](const NS_YYCC_STRING::u8string& val) -> bool {
|
||||
return data.find(NS_YYCC_STRING::u8string_view(val)) != data.end();
|
||||
};
|
||||
return Constraint<NS_YYCC_STRING::u8string>(std::move(fn_check), nullptr);
|
||||
}
|
||||
|
||||
} // namespace yycc::constraint::builder
|
||||
|
||||
#undef NS_YYCC_STRING
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
/// @brief Explicitly remove copy (\c constructor and \c operator\=) for given class.
|
||||
#define YYCC_DELETE_COPY(CLSNAME) \
|
||||
CLSNAME(const CLSNAME&) = delete; \
|
||||
CLSNAME& operator=(const CLSNAME&) = delete;
|
||||
|
||||
/// @brief Explicitly remove move (\c constructor and \c operator\=) for given class.
|
||||
#define YYCC_DELETE_MOVE(CLSNAME) \
|
||||
CLSNAME(CLSNAME&&) = delete; \
|
||||
CLSNAME& operator=(CLSNAME&&) = delete;
|
||||
|
||||
/// @brief Explicitly remove (copy and move) (\c constructor and \c operator\=) for given class.
|
||||
#define YYCC_DELETE_COPY_MOVE(CLSNAME) \
|
||||
YYCC_DELETE_COPY(CLSNAME) \
|
||||
YYCC_DELETE_MOVE(CLSNAME)
|
||||
|
||||
/// @brief Explicitly set default copy (\c constructor and \c operator\=) for given class.
|
||||
#define YYCC_DEFAULT_COPY(CLSNAME) \
|
||||
CLSNAME(const CLSNAME&) = default; \
|
||||
CLSNAME& operator=(const CLSNAME&) = default;
|
||||
|
||||
/// @brief Explicitly set default move (\c constructor and \c operator\=) for given class.
|
||||
#define YYCC_DEFAULT_MOVE(CLSNAME) \
|
||||
CLSNAME(CLSNAME&&) = default; \
|
||||
CLSNAME& operator=(CLSNAME&&) = default;
|
||||
|
||||
/// @brief Explicitly set default (copy and move) (\c constructor and \c operator\=) for given class.
|
||||
#define YYCC_DEFAULT_COPY_MOVE(CLSNAME) \
|
||||
YYCC_DEFAULT_COPY(CLSNAME) \
|
||||
YYCC_DEFAULT_MOVE(CLSNAME)
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
// Define operating system macros
|
||||
#define YYCC_OS_WINDOWS 2
|
||||
#define YYCC_OS_LINUX 3
|
||||
// Check current operating system.
|
||||
#if defined(_WIN32)
|
||||
#define YYCC_OS YYCC_OS_WINDOWS
|
||||
#else
|
||||
#define YYCC_OS YYCC_OS_LINUX
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
/// @brief Return true if left version number is equal to right version number, otherwise false.
|
||||
#define YYCC_VERCMP_E(av1, av2, av3, bv1, bv2, bv3) ((av1) == (bv1) && (av2) == (bv2) && (av3) == (bv3))
|
||||
/// @brief Return true if left version number is not equal to right version number, otherwise false.
|
||||
#define YYCC_VERCMP_NE(av1, av2, av3, bv1, bv2, bv3) (!YYCC_VERCMP_E(av1, av2, av3, bv1, bv2, bv3))
|
||||
/// @brief Return true if left version number is greater than right version number, otherwise false.
|
||||
#define YYCC_VERCMP_G(av1, av2, av3, bv1, bv2, bv3) ( \
|
||||
((av1) > (bv1)) || \
|
||||
((av1) == (bv1) && (av2) > (bv2)) || \
|
||||
((av1) == (bv1) && (av2) == (bv2) && (av3) > (bv3)) \
|
||||
)
|
||||
/// @brief Return true if left version number is greater than or equal to right version number, otherwise false.
|
||||
#define YYCC_VERCMP_GE(av1, av2, av3, bv1, bv2, bv3) (YYCC_VERCMP_G(av1, av2, av3, bv1, bv2, bv3) || YYCC_VERCMP_E(av1, av2, av3, bv1, bv2, bv3))
|
||||
/// @brief Return true if left version number is not lower than right version number, otherwise false.
|
||||
#define YYCC_VERCMP_NL(av1, av2, av3, bv1, bv2, bv3) YYCC_VERCMP_GE(av1, av2, av3, bv1, bv2, bv3)
|
||||
/// @brief Return true if left version number is lower than right version number, otherwise false.
|
||||
#define YYCC_VERCMP_L(av1, av2, av3, bv1, bv2, bv3) ( \
|
||||
((av1) < (bv1)) || \
|
||||
((av1) == (bv1) && (av2) < (bv2)) || \
|
||||
((av1) == (bv1) && (av2) == (bv2) && (av3) < (bv3)) \
|
||||
)
|
||||
/// @brief Return true if left version number is lower than or equal to right version number, otherwise false.
|
||||
#define YYCC_VERCMP_LE(av1, av2, av3, bv1, bv2, bv3) (YYCC_VERCMP_L(av1, av2, av3, bv1, bv2, bv3) || YYCC_VERCMP_E(av1, av2, av3, bv1, bv2, bv3))
|
||||
/// @brief Return true if left version number is not greater than right version number, otherwise false.
|
||||
#define YYCC_VERCMP_NG(av1, av2, av3, bv1, bv2, bv3) YYCC_VERCMP_LE(av1, av2, av3, bv1, bv2, bv3)
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
// Prelude section
|
||||
#include "../string.hpp"
|
||||
namespace yycc::prelude {
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
|
||||
using u8char = NS_YYCC_STRING::u8char;
|
||||
using u8string = NS_YYCC_STRING::u8string;
|
||||
using u8string_view = NS_YYCC_STRING::u8string_view;
|
||||
|
||||
#undef NS_YYCC_STRING
|
||||
|
||||
} // namespace yycc::prelude
|
||||
|
||||
// Expose all members
|
||||
using namespace yycc::prelude;
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
// Include YYCC prelude first
|
||||
#include "core.hpp"
|
||||
|
||||
// Rust prelude section
|
||||
#include "../rust/primitive.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace yycc::prelude::rust {
|
||||
// Include primitive types
|
||||
|
||||
#define NS_RUST_PRIMITIVE ::yycc::rust::primitive
|
||||
|
||||
using i8 = NS_RUST_PRIMITIVE::i8;
|
||||
using i16 = NS_RUST_PRIMITIVE::i16;
|
||||
using i32 = NS_RUST_PRIMITIVE::i32;
|
||||
using i64 = NS_RUST_PRIMITIVE::i64;
|
||||
using u8 = NS_RUST_PRIMITIVE::u8;
|
||||
using u16 = NS_RUST_PRIMITIVE::u16;
|
||||
using u32 = NS_RUST_PRIMITIVE::u32;
|
||||
using u64 = NS_RUST_PRIMITIVE::u64;
|
||||
|
||||
using isize = NS_RUST_PRIMITIVE::isize;
|
||||
using usize = NS_RUST_PRIMITIVE::usize;
|
||||
|
||||
using f32 = NS_RUST_PRIMITIVE::f32;
|
||||
using f64 = NS_RUST_PRIMITIVE::f64;
|
||||
|
||||
using str = NS_RUST_PRIMITIVE::str;
|
||||
|
||||
#undef NS_RUST_PRIMITIVE
|
||||
|
||||
// Other types
|
||||
using String = ::yycc::string::u8string;
|
||||
template<typename T>
|
||||
using Vec = std::vector<T>;
|
||||
} // namespace yycc::prelude::rust
|
||||
|
||||
// Expose all members
|
||||
using namespace yycc::prelude::rust;
|
||||
Whitespace-only changes.
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#include <cinttypes>
|
||||
#include <cstddef>
|
||||
#include "../string.hpp"
|
||||
|
||||
namespace yycc::rust::primitive {
|
||||
|
||||
// `bool` is keyword so should not declare it anymore.
|
||||
// `char` is keyword so should not declare it anymore.
|
||||
|
||||
using i8 = std::int8_t;
|
||||
using i16 = std::int16_t;
|
||||
using i32 = std::int32_t;
|
||||
using i64 = std::int64_t;
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
using u32 = std::uint32_t;
|
||||
using u64 = std::uint64_t;
|
||||
|
||||
using isize = std::ptrdiff_t;
|
||||
using usize = std::size_t;
|
||||
|
||||
using f32 = float;
|
||||
using f64 = double;
|
||||
|
||||
using str = ::yycc::string::u8string_view;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
// Define the UTF8 char type we used.
|
||||
// And do a polyfill if no embedded char8_t type.
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace yycc::string {
|
||||
/**
|
||||
\typedef u8char_t
|
||||
\brief YYCC UTF8 char type.
|
||||
\details
|
||||
This char type is an alias to \c char8_t if your current C++ standard support it.
|
||||
Otherwise it is defined as <TT>unsigned char</TT> as C++ 20 stdandard does.
|
||||
*/
|
||||
/**
|
||||
\typedef u8string
|
||||
\brief YYCC UTF8 string container type.
|
||||
\details
|
||||
This type is defined as \c std::basic_string<yycc_char8_t>.
|
||||
It is equal to \c std::u8string if your current C++ standard support it.
|
||||
*/
|
||||
/**
|
||||
\typedef u8string_view
|
||||
\brief YYCC UTF8 string view type.
|
||||
\details
|
||||
This type is defined as \c std::basic_string_view<yycc_char8_t>.
|
||||
It is equal to \c std::u8string_view if your current C++ standard support it.
|
||||
*/
|
||||
|
||||
#if defined(__cpp_char8_t)
|
||||
using u8char = char8_t;
|
||||
using u8string = std::u8string;
|
||||
using u8string_view = std::u8string_view;
|
||||
#else
|
||||
using u8char = unsigned char;
|
||||
using u8string = std::basic_string<u8char>;
|
||||
using u8string_view = std::basic_string_view<u8char>;
|
||||
#endif
|
||||
} // namespace yycc::string
|
||||
@@ -0,0 +1,226 @@
|
||||
#include "op.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include "reinterpret.hpp"
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
#define NS_YYCC_STRING_REINTERPRET ::yycc::string::reinterpret
|
||||
|
||||
namespace yycc::string::op {
|
||||
|
||||
#pragma region Printf VPrintf
|
||||
|
||||
bool printf(NS_YYCC_STRING::u8string& strl, const NS_YYCC_STRING::u8char* format, ...) {
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
bool ret = vprintf(strl, format, argptr);
|
||||
va_end(argptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool vprintf(NS_YYCC_STRING::u8string& strl, const NS_YYCC_STRING::u8char* format, va_list argptr) {
|
||||
va_list args1;
|
||||
va_copy(args1, argptr);
|
||||
va_list args2;
|
||||
va_copy(args2, argptr);
|
||||
|
||||
// the return value is desired char count without NULL terminal.
|
||||
// minus number means error
|
||||
int count = std::vsnprintf(
|
||||
nullptr,
|
||||
0,
|
||||
NS_YYCC_STRING_REINTERPRET::as_ordinary(format),
|
||||
args1
|
||||
);
|
||||
if (count < 0) {
|
||||
// invalid length returned by vsnprintf.
|
||||
return false;
|
||||
}
|
||||
va_end(args1);
|
||||
|
||||
// resize std::string to desired count.
|
||||
// and pass its length + 1 to std::vsnprintf,
|
||||
// because std::vsnprintf only can write "buf_size - 1" chars with a trailing NULL.
|
||||
// however std::vsnprintf already have a trailing NULL, so we plus 1 for it.
|
||||
strl.resize(count);
|
||||
int write_result = std::vsnprintf(
|
||||
NS_YYCC_STRING_REINTERPRET::as_ordinary(strl.data()),
|
||||
strl.size() + 1,
|
||||
NS_YYCC_STRING_REINTERPRET::as_ordinary(format),
|
||||
args2
|
||||
);
|
||||
va_end(args2);
|
||||
|
||||
if (write_result < 0 || write_result > count) {
|
||||
// invalid write result in vsnprintf.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_YYCC_STRING::u8string printf(const NS_YYCC_STRING::u8char* format, ...) {
|
||||
NS_YYCC_STRING::u8string ret;
|
||||
|
||||
va_list argptr;
|
||||
va_start(argptr, format);
|
||||
vprintf(ret, format, argptr);
|
||||
va_end(argptr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
NS_YYCC_STRING::u8string vprintf(const NS_YYCC_STRING::u8char* format, va_list argptr) {
|
||||
NS_YYCC_STRING::u8string ret;
|
||||
|
||||
va_list argcpy;
|
||||
va_copy(argcpy, argptr);
|
||||
vprintf(ret, format, argcpy);
|
||||
va_end(argcpy);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Replace
|
||||
|
||||
void replace(NS_YYCC_STRING::u8string& strl, const NS_YYCC_STRING::u8string_view& _from_strl, const NS_YYCC_STRING::u8string_view& _to_strl) {
|
||||
// Reference: https://stackoverflow.com/questions/3418231/replace-part-of-a-string-with-another-string
|
||||
|
||||
// check requirements
|
||||
// from string should not be empty
|
||||
NS_YYCC_STRING::u8string from_strl(_from_strl);
|
||||
NS_YYCC_STRING::u8string to_strl(_to_strl);
|
||||
if (from_strl.empty()) return;
|
||||
|
||||
// start replace one by one
|
||||
size_t start_pos = 0;
|
||||
while ((start_pos = strl.find(from_strl, start_pos)) != NS_YYCC_STRING::u8string::npos) {
|
||||
strl.replace(start_pos, from_strl.size(), to_strl);
|
||||
start_pos += to_strl.size(); // In case 'to' contains 'from', like replacing 'x' with 'yx'
|
||||
}
|
||||
}
|
||||
|
||||
NS_YYCC_STRING::u8string replace(const NS_YYCC_STRING::u8string_view& _strl, const NS_YYCC_STRING::u8string_view& _from_strl, const NS_YYCC_STRING::u8string_view& _to_strl) {
|
||||
// prepare result
|
||||
NS_YYCC_STRING::u8string strl(_strl);
|
||||
replace(strl, _from_strl, _to_strl);
|
||||
// return value
|
||||
return strl;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Join
|
||||
|
||||
NS_YYCC_STRING::u8string join(JoinDataProvider fct_data, const NS_YYCC_STRING::u8string_view& decilmer) {
|
||||
NS_YYCC_STRING::u8string ret;
|
||||
bool is_first = true;
|
||||
NS_YYCC_STRING::u8string_view element;
|
||||
|
||||
// fetch element
|
||||
while (fct_data(element)) {
|
||||
// insert decilmer
|
||||
if (is_first) is_first = false;
|
||||
else {
|
||||
// append decilmer.
|
||||
ret.append(decilmer);
|
||||
}
|
||||
|
||||
// insert element if it is not empty
|
||||
if (!element.empty())
|
||||
ret.append(element);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Upper Lower
|
||||
|
||||
template<bool BIsToLower>
|
||||
static void generic_lower_upper(NS_YYCC_STRING::u8string& strl) {
|
||||
// References:
|
||||
// https://en.cppreference.com/w/cpp/algorithm/transform
|
||||
// https://en.cppreference.com/w/cpp/string/byte/tolower
|
||||
std::transform(
|
||||
strl.cbegin(), strl.cend(), strl.begin(),
|
||||
[](unsigned char c) -> char {
|
||||
if constexpr (BIsToLower) return std::tolower(c);
|
||||
else return std::toupper(c);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void lower(NS_YYCC_STRING::u8string& strl) {
|
||||
generic_lower_upper<true>(strl);
|
||||
}
|
||||
|
||||
NS_YYCC_STRING::u8string lower(const NS_YYCC_STRING::u8string_view& strl) {
|
||||
NS_YYCC_STRING::u8string ret(strl);
|
||||
lower(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void upper(NS_YYCC_STRING::u8string& strl) {
|
||||
generic_lower_upper<false>(strl);
|
||||
}
|
||||
|
||||
NS_YYCC_STRING::u8string upper(const NS_YYCC_STRING::u8string_view& strl) {
|
||||
// same as Lower, just replace char transform function.
|
||||
NS_YYCC_STRING::u8string ret(strl);
|
||||
upper(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Split
|
||||
|
||||
std::vector<NS_YYCC_STRING::u8string> split(const NS_YYCC_STRING::u8string_view& strl, const NS_YYCC_STRING::u8string_view& _decilmer) {
|
||||
// call split view
|
||||
auto view_result = split_view(strl, _decilmer);
|
||||
|
||||
// copy string view result to string
|
||||
std::vector<NS_YYCC_STRING::u8string> elems;
|
||||
elems.reserve(view_result.size());
|
||||
for (const auto& strl_view : view_result) {
|
||||
elems.emplace_back(NS_YYCC_STRING::u8string(strl_view));
|
||||
}
|
||||
// return copied result
|
||||
return elems;
|
||||
}
|
||||
|
||||
std::vector<NS_YYCC_STRING::u8string_view> split_view(const NS_YYCC_STRING::u8string_view& strl, const NS_YYCC_STRING::u8string_view& _decilmer) {
|
||||
// Reference:
|
||||
// https://stackoverflow.com/questions/14265581/parse-split-a-string-in-c-using-string-delimiter-standard-c
|
||||
|
||||
// prepare return value
|
||||
std::vector<NS_YYCC_STRING::u8string_view> elems;
|
||||
|
||||
// if string need to be splitted is empty, return original string (empty string).
|
||||
// if decilmer is empty, return original string.
|
||||
NS_YYCC_STRING::u8string decilmer(_decilmer);
|
||||
if (strl.empty() || decilmer.empty()) {
|
||||
elems.emplace_back(strl);
|
||||
return elems;
|
||||
}
|
||||
|
||||
// start spliting
|
||||
std::size_t previous = 0, current;
|
||||
while ((current = strl.find(decilmer.c_str(), previous)) != NS_YYCC_STRING::u8string::npos) {
|
||||
elems.emplace_back(strl.substr(previous, current - previous));
|
||||
previous = current + decilmer.size();
|
||||
}
|
||||
// try insert last part but prevent possible out of range exception
|
||||
if (previous <= strl.size()) {
|
||||
elems.emplace_back(strl.substr(previous));
|
||||
}
|
||||
return elems;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
#pragma once
|
||||
#include <cstdarg>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include "../string.hpp"
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
|
||||
namespace yycc::string::op {
|
||||
|
||||
/**
|
||||
* @brief Perform a string formatting operation.
|
||||
* @param[out] strl
|
||||
* The string container receiving the result.
|
||||
* There is no guarantee that the content is not modified when function failed.
|
||||
* @param[in] format The format string.
|
||||
* @param[in] ... Argument list of format string.
|
||||
* @return True if success, otherwise false.
|
||||
*/
|
||||
bool printf(NS_YYCC_STRING::u8string& strl, const NS_YYCC_STRING::u8char* format, ...);
|
||||
/**
|
||||
* @brief Perform a string formatting operation.
|
||||
* @param[out] strl
|
||||
* The string container receiving the result.
|
||||
* There is no guarantee that the content is not modified when function failed.
|
||||
* @param[in] format The format string.
|
||||
* @param[in] argptr Argument list of format string.
|
||||
* @return True if success, otherwise false.
|
||||
*/
|
||||
bool vprintf(NS_YYCC_STRING::u8string& strl, const NS_YYCC_STRING::u8char* format, va_list argptr);
|
||||
/**
|
||||
* @brief Perform a string formatting operation.
|
||||
* @param[in] format The format string.
|
||||
* @param[in] ... Argument list of format string.
|
||||
* @return The formatting result. Empty string if error happened.
|
||||
*/
|
||||
NS_YYCC_STRING::u8string printf(const NS_YYCC_STRING::u8char* format, ...);
|
||||
/**
|
||||
* @brief Perform a string formatting operation.
|
||||
* @param[in] format The format string.
|
||||
* @param[in] argptr Argument list of format string.
|
||||
* @return The formatting result. Empty string if error happened.
|
||||
*/
|
||||
NS_YYCC_STRING::u8string vprintf(const NS_YYCC_STRING::u8char* format, va_list argptr);
|
||||
|
||||
/**
|
||||
* @brief Modify given string with all occurrences of substring \e old replaced by \e new.
|
||||
* @param[in,out] strl The string for replacing
|
||||
* @param[in] _from_strl The \e old string.
|
||||
* @param[in] _to_strl The \e new string.
|
||||
*/
|
||||
void replace(NS_YYCC_STRING::u8string& strl, const NS_YYCC_STRING::u8string_view& _from_strl, const NS_YYCC_STRING::u8string_view& _to_strl);
|
||||
/**
|
||||
* @brief Return a copy with all occurrences of substring \e old replaced by \e new.
|
||||
* @param[in] _strl The string for replacing
|
||||
* @param[in] _from_strl The \e old string.
|
||||
* @param[in] _to_strl The \e new string.
|
||||
* @return The result of replacement.
|
||||
*/
|
||||
NS_YYCC_STRING::u8string replace(const NS_YYCC_STRING::u8string_view& _strl, const NS_YYCC_STRING::u8string_view& _from_strl, const NS_YYCC_STRING::u8string_view& _to_strl);
|
||||
|
||||
/**
|
||||
* @brief The data provider of general join function.
|
||||
* @details
|
||||
* For programmer using lambda to implement this function pointer:
|
||||
* \li During calling, implementation should assign the reference of string view passed in argument
|
||||
* to the string which need to be joined.
|
||||
* \li Function return true to continue joining. otherwise return false to stop joining.
|
||||
* The argument content assigned in the calling returning false is not included in join process.
|
||||
*/
|
||||
using JoinDataProvider = std::function<bool(NS_YYCC_STRING::u8string_view&)>;
|
||||
/**
|
||||
* @brief Universal join function.
|
||||
* @details
|
||||
* This function use function pointer as a general data provider interface,
|
||||
* so this function suit for all types container.
|
||||
* You can use this universal join function for any custom container by
|
||||
* using C++ lambda syntax to create a code block adapted to this function pointer.
|
||||
* @param[in] fct_data The function pointer in JoinDataProvider type prividing the data to be joined.
|
||||
* @param[in] decilmer The decilmer used for joining.
|
||||
* @return The result string of joining.
|
||||
*/
|
||||
NS_YYCC_STRING::u8string join(JoinDataProvider fct_data, const NS_YYCC_STRING::u8string_view& decilmer);
|
||||
/**
|
||||
* @brief Specialized join function for standard library container.
|
||||
* @tparam InputIt
|
||||
* Must meet the requirements of LegacyInputIterator.
|
||||
* It also can be dereferenced and then implicitly converted to NS_YYCC_STRING::u8string_view.
|
||||
* @param[in] first The beginning of the range of elements to join.
|
||||
* @param[in] last The terminal of the range of elements to join (exclusive).
|
||||
* @param[in] decilmer The decilmer used for joining.
|
||||
* @return The result string of joining.
|
||||
*/
|
||||
template<class InputIt>
|
||||
NS_YYCC_STRING::u8string join(InputIt first, InputIt last, const NS_YYCC_STRING::u8string_view& decilmer) {
|
||||
return join([&first, &last](NS_YYCC_STRING::u8string_view& view) -> bool {
|
||||
// if we reach tail, return false to stop join process
|
||||
if (first == last) return false;
|
||||
// otherwise fetch data, inc iterator and return.
|
||||
view = *first;
|
||||
++first;
|
||||
return true;
|
||||
}, decilmer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Convert given string to lowercase.
|
||||
* @param[in,out] strl The string to be lowercase.
|
||||
*/
|
||||
void lower(NS_YYCC_STRING::u8string& strl);
|
||||
/**
|
||||
* @brief Return a copy of the string converted to lowercase.
|
||||
* @param[in] strl The string to be lowercase.
|
||||
* @return The copy of the string converted to lowercase.
|
||||
*/
|
||||
NS_YYCC_STRING::u8string lower(const NS_YYCC_STRING::u8string_view& strl);
|
||||
/**
|
||||
* @brief Convert given string to uppercase.
|
||||
* @param[in,out] strl The string to be uppercase.
|
||||
*/
|
||||
void upper(NS_YYCC_STRING::u8string& strl);
|
||||
/**
|
||||
* @brief Return a copy of the string converted to uppercase.
|
||||
* @param[in] strl The string to be uppercase.
|
||||
* @return The copy of the string converted to uppercase.
|
||||
*/
|
||||
NS_YYCC_STRING::u8string upper(const NS_YYCC_STRING::u8string_view& strl);
|
||||
|
||||
/**
|
||||
* @brief Split given string with specified decilmer.
|
||||
* @param[in] strl The string need to be splitting.
|
||||
* @param[in] _decilmer The decilmer for splitting.
|
||||
* @return
|
||||
* The split result.
|
||||
* \par
|
||||
* If given string or decilmer are empty,
|
||||
* the result container will only contain 1 entry which is equal to given string.
|
||||
*/
|
||||
std::vector<NS_YYCC_STRING::u8string> split(const NS_YYCC_STRING::u8string_view& strl, const NS_YYCC_STRING::u8string_view& _decilmer);
|
||||
/**
|
||||
* @brief Split given string with specified decilmer as string view.
|
||||
* @param[in] strl The string need to be splitting.
|
||||
* @param[in] _decilmer The decilmer for splitting.
|
||||
* @return
|
||||
* The split result with string view format.
|
||||
* This will not produce any copy of original string.
|
||||
* \par
|
||||
* If given string or decilmer are empty,
|
||||
* the result container will only contain 1 entry which is equal to given string.
|
||||
* @see Split(const NS_YYCC_STRING::u8string_view&, const NS_YYCC_STRING::u8char*)
|
||||
*/
|
||||
std::vector<NS_YYCC_STRING::u8string_view> split_view(const NS_YYCC_STRING::u8string_view& strl, const NS_YYCC_STRING::u8string_view& _decilmer);
|
||||
|
||||
}
|
||||
|
||||
#undef NS_YYCC_STRING
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "reinterpret.hpp"
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
|
||||
namespace yycc::string::reinterpret {
|
||||
|
||||
const NS_YYCC_STRING::u8char* as_utf8(const char* src) {
|
||||
return reinterpret_cast<const NS_YYCC_STRING::u8char*>(src);
|
||||
}
|
||||
NS_YYCC_STRING::u8char* as_utf8(char* src) {
|
||||
return reinterpret_cast<NS_YYCC_STRING::u8char*>(src);
|
||||
}
|
||||
NS_YYCC_STRING::u8string as_utf8(const std::string_view& src) {
|
||||
return NS_YYCC_STRING::u8string(reinterpret_cast<const NS_YYCC_STRING::u8char*>(src.data()), src.size());
|
||||
}
|
||||
NS_YYCC_STRING::u8string_view as_utf8_view(const std::string_view& src) {
|
||||
return NS_YYCC_STRING::u8string_view(reinterpret_cast<const NS_YYCC_STRING::u8char*>(src.data()), src.size());
|
||||
}
|
||||
|
||||
const char* as_ordinary(const NS_YYCC_STRING::u8char* src) {
|
||||
return reinterpret_cast<const char*>(src);
|
||||
}
|
||||
char* as_ordinary(NS_YYCC_STRING::u8char* src) {
|
||||
return reinterpret_cast<char*>(src);
|
||||
}
|
||||
std::string as_ordinary(const NS_YYCC_STRING::u8string_view& src) {
|
||||
return std::string(reinterpret_cast<const char*>(src.data()), src.size());
|
||||
}
|
||||
std::string_view as_ordinary_view(const NS_YYCC_STRING::u8string_view& src) {
|
||||
return std::string_view(reinterpret_cast<const char*>(src.data()), src.size());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include "../string.hpp"
|
||||
|
||||
#define NS_YYCC_STRING ::yycc::string
|
||||
|
||||
namespace yycc::string::reinterpret {
|
||||
|
||||
#define _YYCC_U8(strl) u8 ## strl ///< The assistant macro for YYCC_U8.
|
||||
#define YYCC_U8(strl) (reinterpret_cast<const ::yycc::string::u8char*>(_YYCC_U8(strl))) ///< The macro for creating UTF8 string literal. See \ref library_encoding.
|
||||
#define YYCC_U8_CHAR(chr) (static_cast<::yycc::string::u8char>(chr)) ///< The macro for casting ordinary char type into YYCC UTF8 char type.
|
||||
|
||||
const NS_YYCC_STRING::u8char* as_utf8(const char* src);
|
||||
NS_YYCC_STRING::u8char* as_utf8(char* src);
|
||||
NS_YYCC_STRING::u8string as_utf8(const std::string_view& src);
|
||||
NS_YYCC_STRING::u8string_view as_utf8_view(const std::string_view& src);
|
||||
|
||||
const char* as_ordinary(const NS_YYCC_STRING::u8char* src);
|
||||
char* as_ordinary(NS_YYCC_STRING::u8char* src);
|
||||
std::string as_ordinary(const NS_YYCC_STRING::u8string_view& src);
|
||||
std::string_view as_ordinary_view(const NS_YYCC_STRING::u8string_view& src);
|
||||
|
||||
}
|
||||
|
||||
#undef NS_YYCC_STRING
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define YYCC_VER_MAJOR 2
|
||||
#define YYCC_VER_MINOR 0
|
||||
#define YYCC_VER_PATCH 0
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define YYCC_VER_MAJOR @PROJECT_VERSION_MAJOR@
|
||||
#define YYCC_VER_MINOR @PROJECT_VERSION_MINOR@
|
||||
#define YYCC_VER_PATCH @PROJECT_VERSION_PATCH@
|
||||
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,19 @@
|
||||
// It is by design that no pragma once or #if to prevent deplicated including.
|
||||
// Because this header is the part of wrapper, not a real header.
|
||||
// #pragma once
|
||||
|
||||
#include "../macro/os_detector.hpp"
|
||||
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
||||
// Define 2 macros to disallow Windows generate MIN and MAX macros
|
||||
// which cause std::min and std::max can not function as normal.
|
||||
#if !defined(WIN32_LEAN_AND_MEAN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
|
||||
#if !defined(NOMINMAX)
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
// It is by design that no pragma once or #if to prevent deplicated including.
|
||||
// Because this header is the part of wrapper, not a real header.
|
||||
// #pragma once
|
||||
|
||||
#include "../macro/os_detector.hpp"
|
||||
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
||||
// Windows also will generate following macros
|
||||
// which may cause the function sign is different in Windows and other platforms.
|
||||
// So we simply remove them.
|
||||
// Because #undef will not throw error if there are no matched macro,
|
||||
// so we simply #undef them directly.
|
||||
#undef GetObject
|
||||
#undef GetClassName
|
||||
#undef LoadImage
|
||||
#undef GetTempPath
|
||||
#undef GetModuleFileName
|
||||
#undef CopyFile
|
||||
#undef MoveFile
|
||||
#undef DeleteFile
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "../macro/os_detector.hpp"
|
||||
|
||||
// If we are in Windows,
|
||||
// we need add 2 macros to disable Windows shitty warnings and errors of
|
||||
// depracted functions and not secure functions.
|
||||
#if YYCC_OS == YYCC_OS_WINDOWS
|
||||
|
||||
#if !defined(_CRT_SECURE_NO_WARNINGS)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#if !defined(_CRT_NONSTDC_NO_DEPRECATE)
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user