Skip to content

Latest commit

 

History

History
285 lines (206 loc) · 11.5 KB

File metadata and controls

285 lines (206 loc) · 11.5 KB

cpplib

What is it?

This is a boilerplate C++ library.

Initialy this library was a part of my another home project - a game-logic engine I'm working on time to time. But the primary intention of that engine, and after all this library as well, was to train my C++ skills: try new language features, cover "missing" parts of STL library I'm interested in, add features needed for my other home projects. That's it, a playground in a form of boilerplate library.

NOTE The contents of this library is a permanent subject of change.

NOTE This repository contains only blob-updates from the original repository maintained privately. So, unfortunately git log records becoming almost useless here.

Structure

NOTE This section covers most (but not all) parts of the library.

Desired STL/language features

[include/cpp/]

Basic types

[include/lib/]

  • types - Fundamental types aliases
  • literals - User-defined literals for fundamental types.
  • pointers - std smart-pointers aliases
  • references - std::reference_wrapper aliases
  • flags - Helper for enumerated flags
Template Library

[include/lib/tl/]

  • noncopyable - Standard noncopyable/nonmovable classes
  • listener - Listener interface implementation
  • delegate - C#-like delegate implementation
  • result - Rust-like result implementation
  • linkable - one-to-one object linking interface
Binary data abstractions

[include/lib/data/]

  • buffer - Data buffer
  • stream - Read and write streams
  • serialize - Serialization library
  • hash - Stream-based hash
  • codec - Stream-based codec (encoder/decoder)
Utility

[include/lib/utils/]

  • string - Different string-related functions
  • enum - Enumeration support (helpers + to_string)
  • case_string - Case-conversion object (e.g. Pascal, Camel, Snake)
  • ids_pool - Simple pool of ID's implementation
  • value - Multitype value (integer, float, string)
Different
  • cli - Command-line interface support
  • ecs - Simple Entity Component System
  • debug - Useful classes for debug
  • test - Simple unit-test library
  • socket - Client-server socket abstraction
  • system - System related stuff (e.g. error handling)
Implementations

[include/lib/impl/]

Compilation

NOTE C++23 version support required.

GCC, Clang

Tested on Linux:

  • GCC 13.2.0 (x86_64, i686, aarch64, arm-gnueabi, arm-gnueabihf)
  • Clang 16.0.6 (x86_64, aarch64)
  • Clang 17.0.4 (aarch64-android24)
# Building:
mkdir ./build
cd ./build
cmake -DCMAKE_BUILD_TYPE=Debug ../  # 'CMAKE_BUILD_TYPE' can be 'Debug' or 'Release'.
make -j 4                           # '-j N' where 'N' is the number of threads.

# Testing:
make run-test
# or
./test_cpplib                       # Type 'exit' or 'help' for 'Cli' test.

# Hexdump with CP437 charset output:
./hexdump_cpplib ./hexdump_cpplib | head -n 10

# Some graphics fun in the command line. :)
./graphics_plasma_cpplib            # Hit <Enter> to quit.
MinGW-w64

Tested on x86_64 and i686 architectures:

  • GCC 11.4.0 on Cygwin
  • GCC 12.2.0 on Linux
  • Not tested with MSYS2 :(
# Building:
mkdir ./build
cd ./build
cmake --toolchain=../cmake/toolchain.x86_64-mingw-w64.cmake -DCMAKE_BUILD_TYPE=Debug ../
                                    # 'CMAKE_BUILD_TYPE' can be 'Debug' or 'Release'.
                                    # Toolchain files used in cases when CMake installation
                                    # doesn't have native MinGW-w64 support:
                                    #     * 'toolchain.x86_64-mingw-w64.cmake' used for x64 build;
                                    #     * 'toolchain.i686-mingw-w64.cmake' used for x86 build.
make -j 4                           # '-j N' where 'N' is the number of threads.

# At this step some MinGW-w64 libraries probably need to be copied into './build' directory:
#     * 'libgcc_s_seh-1.dll', 'libstdc++-6.dll', and 'libwinpthread-1.dll' for x64 on Linux;
#     * 'libgcc_s_dw2-1.dll', 'libstdc++-6.dll', and 'libwinpthread-1.dll' for x86 on Linux;
#     * 'libgcc_s_seh-1.dll', 'libstdc++-6.dll', and 'libwinpthread-1.dll' for x64 on Cygwin;
#     * 'libgcc_s_sjlj-1.dll', 'libstdc++-6.dll', and 'libwinpthread-1.dll' for x86 on Cygwin.

# Testing:
make run-test
# or
./test_cpplib.exe                   # Type 'exit' or 'help' for 'Cli' test.
                                    # On Linux it's possible to check with Wine:
                                    # $ wine ./test_cpplib.exe

# Hexdump with CP437 charset output:
./hexdump_cpplib.exe ./hexdump_cpplib.exe | head -n 10
                                    # On Linux it's possible to check with Wine:
                                    # $ wine ./hexdump_cpplib.exe ./hexdump_cpplib.exe | head -n 10
MSVC

Tested on x64 and Win32 architectures:

  • MSVC 19.37.32822 on Windows
REM Open 'x64 Native Tools Command Prompt for VS 2022' for x64 build,
REM or open 'x86 Native Tools Command Prompt for VS 2022' for x86 build.

REM Building:
MKDIR build
CD build
cmake -A x64 ..\                  & REM '-A x64' for x64 build;
                                    REM '-A Win32' for x86 build.

msbuild cpplib.sln -p:Configuration=Debug -p:Platform=x64
                                    REM 'Configuration' may be 'Debug' or 'Release';
                                    REM 'Platform' may be 'x64' or 'Win32' (depends on toolset).

REM Testing:
Debug\test_cpplib.exe             & REM Type 'exit' or 'help' for 'Cli' test.
REM or
REM Release\test_cpplib.exe

REM Hexdump with CP437 charset output:
Debug\hexdump_cpplib.exe Debug\hexdump_cpplib.exe
                                    REM ...but be ready to hit <Ctrl>+<C>. :)

Specifics

Both headers and sources are placed in the include directory

There are two reasons for that. First of all I'm still waiting for complete modules support. Secondary, it's easier for me to maintain hpp and cpp files if they are placed side-to-side.

Headers within a library are included by relative paths

Historically the library was planned as a header-only one. Later I get off this idea, but wanted to allow parts of the library used in-place without any changes within external project. Just an easy drop-in. If user want to use only few classes (header-only ones) of the library, it's possible to include them even by absolute path. This may be useful e.g. for debug classes.

Some places has strange/mixed code style

Remember, it's a playground?

Experimenting forsure will include readability and style. And yes, what considered readable for me not always will be readable for anyone other and vice versa. Perhaps, some day I'll put a codestyle guidelines to follow, but for now there is no such. So, all the "strange" places always have some idea (good or not) on the background.

  • Alternative operator representations are used for all logical operators (and, or, not instead of &&, ||, !). As for me, this should be a default for C++. Taking into account a not so rare typo like if (!Illusion) ... , it's a way to pythonify the code - make it more readable and error-proof.

  • C-Style cast is used for all non-object casting (like integers, floats, enumerations). It's a long story of getting frustrated to write 13 more symbols for "the same thing". But yeah, probably, some day all the C-Style casts will be removed.

  • Lambda's used (lines 179 and 236) for scoped blocks with return statement instead of do ... break ... while ( false ); pattern (note, CPPLIB__TEST__... has return statement inside). I've found it as a more natural way to organize such blocks.

  • ADL not used for str() function. For now it's considered all the str function overloads should be defined in root (::lib) namespace. At least, current implementation of LIB_UTILS_ENUM_NAMES depends on it.

  • Here is an example of mixed cases (lines 31 and 37). The idea is to split lower and upper interfaces by using different cases: for low-level interfaces use lower_snake_case, for user-level use camelCase.

  • Strange formatting can be found here (lines 61-64) - experimenting on ways to format code to split main part while-conditions and simple sleep body. You may consider it also as another kind of pythonification.

Not all the classes covered by tests

Furthermore. Many of the tests cover tested classes only partially. Sometimes I need to cover the whole interface by tests, sometimes, only desired functionality, sometimes I'm too lazy or have no time to write a test.

Bugs/ABI breaking

Definitely. Or at least perhaps. I'll trying to keep code clean and standard-compliant. But still... It's a C++, someday you'll break at least a strict aliasing rule.

License

All the sources are released under MIT License.

Some parts of the source code are released under CC BY-SA 3.0 license.