namespace yycc::macro {
/**
\page macro Library Macros
In this page we will introduce the macros defined by this library
which can not be grouped in other topic.
\section macro__version_cmp Library Version and Version Comparison
Version is a important things in modern software development, especially for a library.
In YYCC, we use Semantic Versioning as our version standard.
For more infomations about it, please see: https://semver.org/
First, YYCC has its own version and it can be visited by
\c YYCC_VER_MAJOR, \c YYCC_VER_MINOR, and \c YYCC_VER_PATCH.
Each part of Semantic Versioning is provided individually.
YYCC also provide a bunch of macros to compare 2 versions.
It also provides a way to check YYCC version in program using YYCC,
because some of them rely on a specific version of YYCC.
There is a list of these comparison macros.
\li YYCC_VERCMP_E
\li YYCC_VERCMP_NE
\li YYCC_VERCMP_G
\li YYCC_VERCMP_GE
\li YYCC_VERCMP_NL
\li YYCC_VERCMP_L
\li YYCC_VERCMP_LE
\li YYCC_VERCMP_NG
You may notice all of these macros are all start with \c YYCC_VERCMP_,
and their tails are inspired from x86 ASM comparison jump code.
For example, \c E means "equal" and \c NE means "not equal",
\c G means "greater", \c GE means "greater or equal", and \c NG means "not gretaer".
All of these macros take 6 arguments,
for the first 3 arguments, we call them "left version".
From left to right they are the major part, minor part and patch part of semantic version.
And for the last 3 arguments, we call them "right version".
From left to right they are the major part, minor part and patch part of semantic version.
There is a example about checking whether YYCC library version is exactly what we wanted version.
\code
#if YYCC_VERCMP_NE(YYCC_VER_MAJOR, YYCC_VER_MINOR, YYCC_VER_PATCH, 1, 3 ,0)
#error "Not Matched YYCC Version"
#endif
\endcode
\section macro__copy_move Class Copy / Move Functions
YYCC provides several macros to manage copy and move constructors and assignment operators for classes.
These include macros to delete, default, declare, and implement copy and move operations.
-
\c YYCC_DELETE_COPY(CLSNAME): Explicitly remove copy constructor and copy assignment operator for the given class.
- CLSNAME(const CLSNAME&) = delete;
- CLSNAME& operator=(const CLSNAME&) = delete;
-
\c YYCC_DELETE_MOVE(CLSNAME): Explicitly remove move constructor and move assignment operator for the given class.
- CLSNAME(CLSNAME&&) noexcept = delete;
- CLSNAME& operator=(CLSNAME&&) noexcept = delete;
- \c YYCC_DELETE_COPY_MOVE(CLSNAME): The combination of \c YYCC_DELETE_COPY and \c YYCC_DELETE_MOVE.
-
\c YYCC_DEFAULT_COPY(CLSNAME): Explicitly set default copy constructor and copy assignment operator for the given class.
- CLSNAME(const CLSNAME&) = default;
- CLSNAME& operator=(const CLSNAME&) = default;
-
\c YYCC_DEFAULT_MOVE(CLSNAME): Explicitly set default move constructor and move assignment operator for the given class.
- CLSNAME(CLSNAME&&) noexcept = default;
- CLSNAME& operator=(CLSNAME&&) noexcept = default;
- \c YYCC_DEFAULT_COPY_MOVE(CLSNAME): The combination of \c YYCC_DEFAULT_COPY and \c YYCC_DEFAULT_MOVE.
-
\c YYCC_DECL_COPY(CLSNAME): Make declaration of copy constructor and assignment operator for the given class to avoid typos.
- CLSNAME(const CLSNAME&);
- CLSNAME& operator=(const CLSNAME&);
-
\c YYCC_DECL_MOVE(CLSNAME): Make declaration of move constructor and assignment operator for the given class to avoid typos.
- CLSNAME(CLSNAME&&) noexcept;
- CLSNAME& operator=(CLSNAME&&) noexcept;
- \c YYCC_DECL_COPY_MOVE(CLSNAME): The combination of \c YYCC_DECL_COPY and \c YYCC_DECL_MOVE.
- \c YYCC_IMPL_COPY_CTOR(CLSNAME, RHS): Make implementation signature of copy constructor for the given class with the right operand name to avoid typos.
- \c YYCC_IMPL_COPY_OPER(CLSNAME, RHS): Make implementation signature of copy assignment operator for the given class with the right operand name to avoid typos.
- \c YYCC_IMPL_MOVE_CTOR(CLSNAME, RHS): Make implementation signature of move constructor for the given class with the right operand name to avoid typos.
- \c YYCC_IMPL_MOVE_OPER(CLSNAME, RHS): Make implementation signature of move assignment operator for the given class with the right operand name to avoid typos.
Please note that \c YYCC_DECL_ and \c YYCC_IMPL_ should be used together.
These macros are designed to make sure that you write correct function signatures.
There is an example about how to use it.
In HPP file, you can write:
\code
class Foo {
YYCC_DECL_COPY_MOVE(Foo)
};
\endcode
And in corresponding CPP file, you should write:
\code
YYCC_IMPL_COPY_CTOR(Foo, rhs)
{
// Copy members from rhs
}
YYCC_IMPL_COPY_OPER(Foo, rhs)
{
// Copy members from rhs
return *this;
}
YYCC_IMPL_MOVE_CTOR(Foo, rhs)
{
// Move members from rhs
}
YYCC_IMPL_MOVE_OPER(Foo, rhs)
{
// Move members from rhs
return *this;
}
\endcode
\section macro__platform_checker OS Detector
In many cross platform applications,
programmer usually write code adapted to different platforms in one source file
and enable them respectively by macros representing the target platform.
As a cross platform library,
YYCC also has this feature and you can utilize it if you don't have other ways to so the same things.
\subsection macro__platform_checker__macro Macro
YYCC always define one of following macros to indicate the system of target platform.
\li \c YYCC_OS_WINDOWS: Windows environment.
\li \c YYCC_OS_LINUX: Linux environment.
\li \c YYCC_OS_MACOS: macOS environment.
Assume \c blabla() function is Windows specific.
There is an example about how to use it:
\code
#if defined(YYCC_OS_WINDOWS)
// Code specific to Windows
blabla();
#endif
\endcode
\subsection macro__platform_checker__constexpr_function Constexpr Function
Additionally, YYCC also provides a bunch of constexpr functions to check whether the target platform is what we want.
More precisely, os::get_os() function returns an enum value os::OsKind indicating the target platform.
There is an example about how to use it:
\code
if constexpr (os::get_os() == os::OsKind::Windows) {
// Code specific to Windows
blabla();
}
\endcode
\section macro__compiler_detector Compiler Detector
YYCC provides macros and constexpr functions to detect the compiler being used for compilation.
\subsection macro__compiler_detector__macro Macro
YYCC defines one of following macros to indicate which compiler is being used.
\li \c YYCC_CC_MSVC: MSVC compiler (Microsoft Visual C++)
\li \c YYCC_CC_GCC: GCC compiler (GNU Compiler Collection)
\li \c YYCC_CC_CLANG: Clang compiler
There is an example about how to use it:
\code
#if defined(YYCC_CC_MSVC)
// Code specific to MSVC
blabla();
#endif
\endcode
\subsection macro__compiler_detector__constexpr_function Constexpr Function
YYCC also provides a constexpr function to check which compiler is being used at compile time.
More precisely, compiler::get_compiler() function returns an enum value compiler::CompilerKind indicating the compiler being used.
There is an example about how to use it:
\code
if constexpr (compiler::get_compiler() == compiler::CompilerKind::Msvc) {
// Code specific to MSVC
blabla();
}
\endcode
\section macro__endian_detector Endian Detector
YYCC provides macros and constexpr functions to detect the endianness of the target platform.
\subsection macro__endian_detector__macro Macro
YYCC always defines one of following macros to indicate the endianness of the target platform.
\li \c YYCC_ENDIAN_LITTLE: Little endian system
\li \c YYCC_ENDIAN_BIG: Big endian system
There is an example about how to use it:
\code
#if defined(YYCC_ENDIAN_LITTLE)
// Code specific to little endian systems
blabla();
#endif
\endcode
\subsection macro__endian_detector__constexpr_function Constexpr Function
YYCC also provides a constexpr function to check the endianness of the target platform.
More precisely, endian::get_endian() function returns an enum value endian::EndianKind indicating the endianness.
There is an example about how to use it:
\code
if constexpr (endian::get_endian() == endian::EndianKind::Little) {
// Code specific to little endian systems
blabla();
}
\endcode
\section macro__stl_detector STL Detector
YYCC provides macros to detect which Standard Template Library (STL) implementation is being used.
\subsection macro__stl_detector__macro Macro
YYCC defines one of following macros to indicate which STL implementation is being used.
\li \c YYCC_STL_MSSTL: Microsoft STL
\li \c YYCC_STL_GNUSTL: GNU STL
\li \c YYCC_STL_CLANGSTL: Clang STL
There is an example about how to use it:
\code
#if defined(YYCC_STL_MSSTL)
// Code specific to Microsoft STL
blabla();
#endif
\endcode
\subsection macro__stl_detector__constexpr_function Constexpr Function
YYCC also provides a constexpr function to check which STL implementation is being used at compile time.
More precisely, stl::get_stl() function returns an enum value stl::StlKind indicating the STL implementation.
There is an example about how to use it:
\code
if constexpr (stl::get_stl() == stl::StlKind::MsStl) {
// Code specific to Microsoft STL
blabla();
}
\endcode
\section macro__ptr_size_detector Pointer Size Detector
YYCC provides macros and constexpr functions to detect the pointer size of the target platform.
\subsection macro__ptr_size_detector__macro Macro
YYCC always define one of following macros to indicate the pointer size of target platform.
\li \c YYCC_PTRSIZE_32: 32-bit environment
\li \c YYCC_PTRSIZE_64: 64-bit environment
There is an example about how to use it:
\code
#if defined(YYCC_PTRSIZE_32)
// Code specific to 32-bit environment
blabla();
#endif
\endcode
\subsection macro__ptr_size_detector__constexpr_function Constexpr Function
YYCC also provides a constexpr function to check the pointer size of the target platform.
More precisely, ptr_size::get_ptr_size() function returns an enum value ptr_size::PtrSizeKind indicating the pointer size.
There is an example about how to use it:
\code
if constexpr (ptr_size::get_ptr_size() == ptr_size::PtrSizeKind::Bits32) {
// Code specific to 32-bit environment
blabla();
}
\endcode
*/
}