Skip to content

Commit

Permalink
feature/improve specializing (#32)
Browse files Browse the repository at this point in the history
* Added a class for specializing the type of the unit operations - making it easier not to have to rely on macros

* Reverted the removal off install include dir, after discussion with friendlyanon

* Cleaned up

* Cleaned up a lot of the specialization

* Reduce number of classes

* A few cleanup steps

* Add a versioning

* Hopefully fix coverage build

* Make windows behave

* Remove more warnings

* Improve documentation for specializer

* Review comments
  • Loading branch information
anders-wind authored Nov 25, 2022
1 parent c7c421c commit 60144eb
Show file tree
Hide file tree
Showing 19 changed files with 436 additions and 231 deletions.
26 changes: 13 additions & 13 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ BraceWrapping:
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyRecord: false
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
Expand All @@ -55,7 +55,7 @@ BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: true
BreakStringLiterals: true
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
CommentPragmas: "^ IWYU pragma:"
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
Expand All @@ -73,16 +73,16 @@ ForEachMacros:
IncludeBlocks: Regroup
IncludeCategories:
# Standard library headers come before anything else
- Regex: '^<[a-z_]+>'
- Regex: "^<[a-z_]+>"
Priority: -1
- Regex: '^<.+\.h(pp)?>'
Priority: 1
- Regex: '^<.*'
- Regex: "^<.*"
Priority: 2
- Regex: '.*'
- Regex: ".*"
Priority: 3
IncludeIsMainRegex: ''
IncludeIsMainSourceRegex: ''
IncludeIsMainRegex: ""
IncludeIsMainSourceRegex: ""
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
Expand All @@ -94,8 +94,8 @@ InsertTrailingCommas: Wrapped
JavaScriptQuotes: Double
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MacroBlockBegin: ""
MacroBlockEnd: ""
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
Expand All @@ -120,9 +120,9 @@ RawStringFormats:
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
- "c++"
- "C++"
CanonicalDelimiter: ""
BasedOnStyle: google
- Language: TextProto
Delimiters:
Expand All @@ -140,7 +140,7 @@ RawStringFormats:
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: ''
CanonicalDelimiter: ""
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
Expand Down
18 changes: 14 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ env:
VCPKG_COMMIT: "6f7ffeb18f99796233b958aaaf14ec7bd4fb64b2"

jobs:
version_bump:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0

- name: Test version bumped
run: echo "$(git diff HEAD origin/main version.py)" | grep __version__ -wq

lint:
runs-on: ubuntu-22.04

Expand All @@ -28,7 +38,7 @@ jobs:
run: pip3 install codespell

- name: Lint
run: cmake -D FORMAT_COMMAND=clang-format-13 -P cmake/lint.cmake
run: cmake -D FORMAT_COMMAND=clang-format-14 -P cmake/lint.cmake

- name: Spell check
if: always()
Expand Down Expand Up @@ -61,7 +71,7 @@ jobs:
}

- name: Configure
env: { CXX: clang++-13 }
env: { CXX: clang++-14 }
run: cmake --preset=ci-coverage

- name: Build
Expand Down Expand Up @@ -96,7 +106,7 @@ jobs:
}

- name: Configure
env: { CXX: clang++-13 }
env: { CXX: clang++-14 }
run: cmake --preset=ci-sanitize

- name: Build
Expand Down Expand Up @@ -143,7 +153,7 @@ jobs:

- name: Install static analyzers
if: matrix.os == 'ubuntu-22.04'
run: sudo apt-get install clang-tidy-13 cppcheck -y -q
run: sudo apt-get install clang-tidy-14 cppcheck -y -q

- name: Install vcpkg
uses: friendlyanon/setup-vcpkg@v1
Expand Down
111 changes: 111 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
{
"clang-format.executable": "clang-format-14",
"cpplint.filters": [
"-build/c++11",
"-build/include_order",
"-legal/copyright",
"-readability/braces",
"-runtime/references",
"-runtime/string",
"-whitespace"
],
"files.associations": {
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"bitset": "cpp",
"chrono": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"complex": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"string": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"source_location": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"fstream": "cpp",
"initializer_list": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ostream": "cpp",
"semaphore": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"variant": "cpp",
"forward_list": "cpp",
"unordered_set": "cpp",
"shared_mutex": "cpp",
"*.inc": "cpp",
"__hash_table": "cpp",
"__bit_reference": "cpp",
"__bits": "cpp",
"__config": "cpp",
"__debug": "cpp",
"__locale": "cpp",
"__node_handle": "cpp",
"__nullptr": "cpp",
"__split_buffer": "cpp",
"__string": "cpp",
"__threading_support": "cpp",
"__tuple": "cpp",
"ios": "cpp",
"locale": "cpp",
"__tree": "cpp",
"__errc": "cpp"
},
"cSpell.words": [
"absl",
"decltype",
"stronk",
"structs",
"VCPKG"
],
"sonarlint.pathToCompileCommands": "${workspaceFolder}/build/dev/compile_commands.json"
}
43 changes: 12 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ In case you want to specialize the resulting type of unit multiplication and div

By default the units are generated with the `stronk_default_prefab` type.

```cpp :file=./examples/specializers_example.cpp:line_end=36
```cpp :file=./examples/specializers_example.cpp:line_end=29
#include <stronk/specializers.h>

// Lets consider the following units:
Expand All @@ -203,45 +203,26 @@ struct Time : twig::stronk<Time, double, twig::unit>
using stronk::stronk;
};

// Note: For the specializer macros you need to call them from within the twig namespace:
namespace twig
// Lets say you want to use a custom defined stronk type for certain unit combinations.
// Lets introduce our own `Speed` type:
struct Speed : twig::stronk<Speed, double, twig::divided_unit<Distance, Time>::skill>
{
// Lets say we want to have Distance / Time specialized to be hashable.
// We can use the STRONK_SPECIALIZE_DIVIDE macro to specialize the generated type.
STRONK_SPECIALIZE_DIVIDE(Distance, Time, can_hash);
// Now any expression resulting the `Distance{} / Time{}` type will result in a unit type with the can_hash skill

} // namespace twig

// Lets specialize Time^2 to use int64_t as its underlying type.
template<>
struct twig::underlying_multiply_operation<Time, Time>
{
using res_type = int64_t;

STRONK_FORCEINLINE
constexpr static auto multiply(const typename Time::underlying_type& v1,
const typename Time::underlying_type& v2) noexcept -> res_type
{
return static_cast<int64_t>(v1 * v2);
}
using stronk::stronk;
};
```
// Notice we are adding the twig::divided_unit skill instead of twig::unit

You can also specialize the underlying type of multiplying two units:
By default the `underlying_type` is the default result of multiplying or dividing the underlying types of the two units themselves.
```cpp :file=./examples/specializers_example.cpp:line_start=23:line_end=29
// Lets specialize Time^2 to use int64_t as its underlying type.
// To make it possible for stronk to find this type we need to specialize `unit_lookup`:
template<>
struct twig::underlying_multiply_operation<Time, Time>
struct twig::unit_lookup<twig::divided_unit<Distance, Time>::unit_description_t, double>
{
using res_type = int64_t;
using type = Speed;
};

// The above of course also works for `multiplied_unit` and `unit_multiplied_resulting_unit_type`
```

# Using Stronk in Your Project
The project is CMake FetchContent ready and we are working on exposing it on vcpkg.
The project is CMake FetchContent ready and is available on [vcpkg](https://github.com/microsoft/vcpkg/tree/master/ports/stronk).
After retrieving stronk, add the following to your CMakeLists.txt

```cmake
Expand Down
4 changes: 4 additions & 0 deletions cmake/install-rules.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ set(CMAKE_INSTALL_LIBDIR lib CACHE PATH "")
include(CMakePackageConfigHelpers)
include(GNUInstallDirs)

if(PROJECT_IS_TOP_LEVEL)
set(CMAKE_INSTALL_INCLUDEDIR "include/stronk-${PROJECT_VERSION}" CACHE PATH "")
endif()

# find_package(<package>) call for consumers to find this project
set(package stronk)

Expand Down
2 changes: 1 addition & 1 deletion cmake/lint-targets.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(
"; separated patterns relative to the project source dir to format"
)

set(FORMAT_COMMAND clang-format CACHE STRING "Formatter to use")
set(FORMAT_COMMAND clang-format-14 CACHE STRING "Formatter to use")

add_custom_target(
format-check
Expand Down
24 changes: 14 additions & 10 deletions cmake/lint.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ macro(default name)
endif()
endmacro()

default(FORMAT_COMMAND clang-format)
default(FORMAT_COMMAND clang-format-14)
default(
PATTERNS
source/*.cpp source/*.hpp
include/*.hpp
test/*.cpp test/*.hpp
example/*.cpp example/*.hpp
PATTERNS
source/*.cpp source/*.hpp
include/*.hpp
test/*.cpp test/*.hpp
example/*.cpp example/*.hpp
)
default(FIX NO)

set(flag --output-replacements-xml)
set(args OUTPUT_VARIABLE output)

if(FIX)
set(flag -i)
set(args "")
Expand All @@ -30,18 +31,21 @@ string(LENGTH "${CMAKE_SOURCE_DIR}/" path_prefix_length)

foreach(file IN LISTS files)
execute_process(
COMMAND "${FORMAT_COMMAND}" --style=file "${flag}" "${file}"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE result
${args}
COMMAND "${FORMAT_COMMAND}" --style=file "${flag}" "${file}"
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
RESULT_VARIABLE result
${args}
)

if(NOT result EQUAL "0")
message(FATAL_ERROR "'${file}': formatter returned with ${result}")
endif()

if(NOT FIX AND output MATCHES "\n<replacement offset")
string(SUBSTRING "${file}" "${path_prefix_length}" -1 relative_file)
list(APPEND badly_formatted "${relative_file}")
endif()

set(output "")
endforeach()

Expand Down
Loading

0 comments on commit 60144eb

Please sign in to comment.