Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify and improve construction #44

Merged
merged 19 commits into from
Jun 22, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ on:
workflow_dispatch:

env:
VCPKG_COMMIT: "c8696863d371ab7f46e213d8f5ca923c4aef2a00"
VCPKG_COMMIT: "943c5ef1c8f6b5e6ced092b242c8299caae2ff01"

jobs:
version_bump:
Expand Down Expand Up @@ -227,7 +227,7 @@ jobs:
uses: KyleMayes/install-llvm-action@v1
with:
version: "17.0"

- name: Fix clang installations
if: matrix.os == 'ubuntu-22.04'
run: |
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ on:
schedule:
- cron: "44 8 * * 1"
env:
VCPKG_COMMIT: "c8696863d371ab7f46e213d8f5ca923c4aef2a00"
VCPKG_COMMIT: "943c5ef1c8f6b5e6ced092b242c8299caae2ff01"

jobs:
analyze:
Expand Down
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"clangd.path": "clangd-17",
"clangd.arguments": [
"-compile-commands-dir=${workspaceFolder}/build/dev"
],
"clang-format.executable": "clang-format-17",
"cpplint.filters": [
"-build/c++11",
Expand Down Expand Up @@ -114,4 +117,4 @@
"connectionId": "twig-energy",
"projectKey": "twig-energy_stronk"
}
}
}
2 changes: 1 addition & 1 deletion CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"name": "clang-tidy",
"hidden": true,
"cacheVariables": {
"CMAKE_CXX_CLANG_TIDY": "clang-tidy-17;--header-filter=${sourceDir}/*"
"CMAKE_CXX_CLANG_TIDY": "clang-tidy-17;--header-filter=^${sourceDir}/(include|tests|benchmarks)"
}
},
{
Expand Down
26 changes: 17 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
#include <iostream>
#include <string>

#include <stronk/can_stream.h>
#include <stronk/stronk.h>

struct FirstName : twig::stronk<FirstName, std::string, twig::can_stream>
struct FirstName : twig::stronk<FirstName, std::string, twig::can_ostream>
{
using stronk::stronk;
};
Expand All @@ -42,7 +43,7 @@ struct LastName : twig::stronk<LastName, std::string>
// Strong types protects you from accidentally passing the wrong argument to the wrong parameter.
void print_name(const LastName& lastname, const FirstName& firstname)
{
// The twig::can_stream skill overloads the `operator<<(ostream&)` for your type.
// The twig::can_ostream skill overloads the `operator<<(ostream&)` for your type.
std::cout << firstname << " ";
// You can also access the underlying type by using the .unwrap<Type>() function.
std::cout << lastname.unwrap<LastName>() << std::endl;
Expand All @@ -56,10 +57,12 @@ auto main() -> int

On top of providing strong type utilities, `stronk` also enables unit-like behavior:

```cpp :file=./examples/unit_energy_example.cpp:line_start=0:line_end=23
```cpp :file=./examples/unit_energy_example.cpp:line_start=0:line_end=25
#include <ratio>
#include <type_traits>

#include <stronk/prefabs.h>
#include <stronk/stronk.h>
#include <stronk/unit.h>

// We introduce a unit type with a default set of skills with the `stronk_default_unit` prefab
Expand All @@ -84,7 +87,7 @@ void watts_and_identity_units()

Different units can be combined by multiplying or dividing them:

```cpp :file=./examples/unit_energy_example.cpp:line_start=24:line_end=45
```cpp :file=./examples/unit_energy_example.cpp:line_start=26:line_end=47
// Lets introduce hours as a new unit_like type
struct Hours : twig::stronk<Hours, double, twig::unit>
{
Expand All @@ -110,7 +113,7 @@ void watt_hours_and_generating_new_units()

These new generated types are also units which can be used to generate new units:

```cpp :file=./examples/unit_energy_example.cpp:line_start=46:line_end=65
```cpp :file=./examples/unit_energy_example.cpp:line_start=48:line_end=67
// Lets introduce a type for euros, and start combining more types.
struct Euro : twig::stronk<Euro, double, twig::unit>
{
Expand Down Expand Up @@ -147,7 +150,7 @@ Skills adds functionality to your stronk types. We have implemented a number of
- `can_divide`: binary `operator/` and `operator=/` (not compatible with units, we encourage you to use units instead)
- `can_abs`: overloads `twig::abs`
- `can_isnan`: overloads `twig::isnan`
- `can_stream`: overloads `operator<<(std::ostream)`, stream the underlying value to the stream.
- `can_stream`: overloads `operator<<(std::ostream)` and `operator<<(std::istream)`, stream the underlying value to the stream, or create from stream. For only `ostream` or `istream` functionality, use `can_ostream` or `can_istream` respectively.
- `can_order`: `operator<=>`, note you probably also want to add `can_equate`, since the compiler cannot generate equality with the `operator<=>` for stronk types.
- `can_equate`: `operator==` with regular equality
- `can_equate_with_is_close`: `operator==` but with numpy's `is_close` definition of equal
Expand All @@ -162,7 +165,8 @@ Skills adds functionality to your stronk types. We have implemented a number of
- `can_iterate` adds the `can_const_iterate` as well implementing `begin()`, `end()`.
- `can_const_index` implements `operator[](const auto&) const` and `at(const auto&) const`
- `can_index` adds the `can_const_index` as well implementing `operator[](const auto&)` and `at(const auto&)`.
- `can_forward_constructor_args` adds a constructor which forwards arguments to the inner class.
- `can_increment` adds both `operator++` operators.
- `can_decrement` adds both `operator--` operators.

### Units
- `unit`: enables unit behavior for multiplication and division.
Expand All @@ -189,8 +193,12 @@ 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=29
#include <stronk/specializers.h>
```cpp :file=./examples/specializers_example.cpp:line_end=33
#include <cstdint>
#include <type_traits>

#include <stronk/stronk.h>
#include <stronk/unit.h>

// Lets consider the following units:
struct Distance : twig::stronk<Distance, double, twig::unit>
Expand Down
15 changes: 5 additions & 10 deletions benchmarks/src/benchmark_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <random>
#include <sstream>
#include <string>
#include <type_traits>

#include <stronk/prefabs.h>
#include <stronk/stronk.h>
Expand Down Expand Up @@ -35,7 +36,7 @@ template<typename T>
auto default_max_for_random() -> T
{
if constexpr (std::is_floating_point_v<T>) {
return T(1.0);
return T {1.0};
} else {
return std::numeric_limits<T>::max();
}
Expand Down Expand Up @@ -70,18 +71,15 @@ auto rand(T mi, T ma) -> T
template<typename T>
auto rand() -> T
{
return rand<T>(T(0), default_max_for_random<T>());
return rand<T>(T {0}, default_max_for_random<T>());
}

} // namespace details

template<typename T>
struct generate_randomish
{
auto operator()() const -> T
{
return details::rand<T>();
}
auto operator()() const -> T { return details::rand<T>(); }
};
template<>
struct generate_randomish<std::string>
Expand All @@ -99,10 +97,7 @@ struct generate_randomish<std::string>
template<twig::stronk_like T>
struct generate_randomish<T>
{
auto operator()() const -> T
{
return T {generate_randomish<typename T::underlying_type> {}()};
}
auto operator()() const -> T { return T {generate_randomish<typename T::underlying_type> {}()}; }
};

template<typename T>
Expand Down
17 changes: 14 additions & 3 deletions benchmarks/src/construction_benchmarks.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
#include <cstddef>
#include <cstdint>
#include <string>
#include <vector>

#include <benchmark/benchmark.h>

#include "./benchmark_helpers.h"

namespace
{
template<typename T>
static void benchmark_default_onto_reserved_vector(benchmark::State& state)
void benchmark_default_onto_reserved_vector(benchmark::State& state)
{
auto vec = std::vector<T>(static_cast<size_t>(state.range(0)));
benchmark::DoNotOptimize(vec.data());
Expand All @@ -17,6 +21,7 @@ static void benchmark_default_onto_reserved_vector(benchmark::State& state)
benchmark::ClobberMemory();
}
}
} // namespace

BENCHMARK_TEMPLATE(benchmark_default_onto_reserved_vector, int8_t)->Range(32ULL, 8ULL << 10ULL);
BENCHMARK_TEMPLATE(benchmark_default_onto_reserved_vector, int8_t_wrapping_type)->Range(32ULL, 8ULL << 10ULL);
Expand All @@ -27,8 +32,10 @@ BENCHMARK_TEMPLATE(benchmark_default_onto_reserved_vector, int64_t_wrapping_type
BENCHMARK_TEMPLATE(benchmark_default_onto_reserved_vector, std::string)->Range(32ULL, 8ULL << 10ULL);
BENCHMARK_TEMPLATE(benchmark_default_onto_reserved_vector, string_wrapping_type)->Range(32ULL, 8ULL << 10ULL);

namespace
{
template<typename T>
static void benchmark_rand_onto_reserved_vector(benchmark::State& state)
void benchmark_rand_onto_reserved_vector(benchmark::State& state)
{
auto vec = std::vector<T>(static_cast<size_t>(state.range(0)));
benchmark::DoNotOptimize(vec.data());
Expand All @@ -39,6 +46,7 @@ static void benchmark_rand_onto_reserved_vector(benchmark::State& state)
benchmark::ClobberMemory();
}
}
} // namespace

BENCHMARK_TEMPLATE(benchmark_rand_onto_reserved_vector, int8_t)->Range(32ULL, 8ULL << 10ULL);
BENCHMARK_TEMPLATE(benchmark_rand_onto_reserved_vector, int8_t_wrapping_type)->Range(32ULL, 8ULL << 10ULL);
Expand All @@ -49,8 +57,10 @@ BENCHMARK_TEMPLATE(benchmark_rand_onto_reserved_vector, int64_t_wrapping_type)->
BENCHMARK_TEMPLATE(benchmark_rand_onto_reserved_vector, std::string)->Range(32ULL, 8ULL << 10ULL);
BENCHMARK_TEMPLATE(benchmark_rand_onto_reserved_vector, string_wrapping_type)->Range(32ULL, 8ULL << 10ULL);

namespace
{
template<typename T>
static void benchmark_copy_vector_of(benchmark::State& state)
void benchmark_copy_vector_of(benchmark::State& state)
{
auto vec = std::vector<T>(static_cast<size_t>(state.range(0)));
std::generate(vec.begin(), vec.end(), []() { return generate_randomish<T> {}(); });
Expand All @@ -61,6 +71,7 @@ static void benchmark_copy_vector_of(benchmark::State& state)
benchmark::ClobberMemory();
}
}
} // namespace

BENCHMARK_TEMPLATE(benchmark_copy_vector_of, int8_t)->Range(32ULL, 8ULL << 10ULL);
BENCHMARK_TEMPLATE(benchmark_copy_vector_of, int8_t_wrapping_type)->Range(32ULL, 8ULL << 10ULL);
Expand Down
38 changes: 27 additions & 11 deletions benchmarks/src/unit_benchmarks.cpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
#include <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <vector>

#include <benchmark/benchmark.h>
#include <fmt/core.h>

#include "./benchmark_helpers.h"

namespace
{
template<typename T>
static void benchmark_add_units(benchmark::State& state)
void benchmark_add_units(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<T>(static_cast<size_t>(state.range(0)));
std::generate(vec_a.begin(), vec_a.end(), []() { return generate_randomish<T> {}(); });
std::generate(vec_b.begin(), vec_b.end(), []() { return generate_randomish<T> {}(); });
std::ranges::generate(vec_a, []() { return generate_randomish<T> {}(); });
std::ranges::generate(vec_b, []() { return generate_randomish<T> {}(); });

for (auto _ : state) {
for (auto i = 0ULL; i < static_cast<size_t>(state.range(0)); i++) {
Expand All @@ -23,7 +29,7 @@ static void benchmark_add_units(benchmark::State& state)
}

template<typename T, size_t WidthV>
static void benchmark_add_units_simd(benchmark::State& state)
void benchmark_add_units_simd(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<T>(static_cast<size_t>(state.range(0)));
Expand All @@ -42,6 +48,7 @@ static void benchmark_add_units_simd(benchmark::State& state)
}
}
}
} // namespace

// // benchmark_add_units
BENCHMARK_TEMPLATE(benchmark_add_units, int8_t)->Arg(8192);
Expand All @@ -63,8 +70,10 @@ BENCHMARK_TEMPLATE(benchmark_add_units_simd, int64_t_wrapping_type, 32)->Arg(819
BENCHMARK_TEMPLATE(benchmark_add_units_simd, double, 32)->Arg(8192 / 32);
BENCHMARK_TEMPLATE(benchmark_add_units_simd, double_wrapping_type, 32)->Arg(8192 / 32);

namespace
{
template<typename T>
static void benchmark_subtract_units(benchmark::State& state)
void benchmark_subtract_units(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<T>(static_cast<size_t>(state.range(0)));
Expand All @@ -82,7 +91,7 @@ static void benchmark_subtract_units(benchmark::State& state)
}

template<typename T, size_t WidthV>
static void benchmark_subtract_units_simd(benchmark::State& state)
void benchmark_subtract_units_simd(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<T>(static_cast<size_t>(state.range(0)));
Expand All @@ -101,6 +110,7 @@ static void benchmark_subtract_units_simd(benchmark::State& state)
}
}
}
} // namespace

BENCHMARK_TEMPLATE(benchmark_subtract_units, int8_t)->Arg(8192);
BENCHMARK_TEMPLATE(benchmark_subtract_units, int8_t_wrapping_type)->Arg(8192);
Expand All @@ -121,8 +131,10 @@ BENCHMARK_TEMPLATE(benchmark_subtract_units_simd, int64_t_wrapping_type, 32)->Ar
BENCHMARK_TEMPLATE(benchmark_subtract_units_simd, double, 32)->Arg(8192 / 32);
BENCHMARK_TEMPLATE(benchmark_subtract_units_simd, double_wrapping_type, 32)->Arg(8192 / 32);

namespace
{
template<typename T, typename O>
static void benchmark_multiply_units(benchmark::State& state)
void benchmark_multiply_units(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<O>(static_cast<size_t>(state.range(0)));
Expand All @@ -141,7 +153,7 @@ static void benchmark_multiply_units(benchmark::State& state)
}

template<typename T, typename O, size_t WidthV>
static void benchmark_multiply_units_simd(benchmark::State& state)
void benchmark_multiply_units_simd(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<O>(static_cast<size_t>(state.range(0)));
Expand All @@ -161,6 +173,7 @@ static void benchmark_multiply_units_simd(benchmark::State& state)
}
}
}
} // namespace

BENCHMARK_TEMPLATE(benchmark_multiply_units, int8_t, int8_t)->Arg(8192);
BENCHMARK_TEMPLATE(benchmark_multiply_units, int8_t_wrapping_type, int8_t_wrapping_type)->Arg(8192);
Expand Down Expand Up @@ -192,8 +205,10 @@ BENCHMARK_TEMPLATE(benchmark_multiply_units_simd, int64_t_wrapping_type, double_
BENCHMARK_TEMPLATE(benchmark_multiply_units_simd, double, int64_t, 32)->Arg(8192 / 32);
BENCHMARK_TEMPLATE(benchmark_multiply_units_simd, double_wrapping_type, int64_t_wrapping_type, 32)->Arg(8192 / 32);

namespace
{
template<typename T, typename O>
static void benchmark_divide_units(benchmark::State& state)
void benchmark_divide_units(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<O>(static_cast<size_t>(state.range(0)));
Expand All @@ -212,7 +227,7 @@ static void benchmark_divide_units(benchmark::State& state)
}

template<typename T, typename O, size_t WidthV>
static void benchmark_divide_units_simd(benchmark::State& state)
void benchmark_divide_units_simd(benchmark::State& state)
{
auto vec_a = std::vector<T>(static_cast<size_t>(state.range(0)));
auto vec_b = std::vector<O>(static_cast<size_t>(state.range(0)));
Expand All @@ -232,6 +247,7 @@ static void benchmark_divide_units_simd(benchmark::State& state)
}
}
}
} // namespace

BENCHMARK_TEMPLATE(benchmark_divide_units, int8_t, int8_t)->Arg(8192);
BENCHMARK_TEMPLATE(benchmark_divide_units, int8_t_wrapping_type, int8_t_wrapping_type)->Arg(8192);
Expand Down
Loading
Loading