Skip to content

Commit

Permalink
[312] - Did you know that C++20 added support for Unevaluated asm-dec…
Browse files Browse the repository at this point in the history
…laration in constexpr functions?
  • Loading branch information
kris-jusiak committed Jan 8, 2023
1 parent 2bc52e0 commit 9559b46
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

### Tips

* [[312]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/312.md) - Did you know that C++20 added support for Unevaluated asm-declaration in constexpr functions?
* [[311]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/311.md) - Did you know DRY (Don’t Repeat Yourself) comparisons pattern?
* [[310]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/310.md) - Did you know that C+23 permitts static constexpr variables in constexpr functions?
* [[309]](https://github.com/QuantlabFinancial/cpp_tip_of_the_week/blob/master/tips/309.md) - Did you know that C++20 added support for constexpr std::vector?
Expand Down
90 changes: 89 additions & 1 deletion tips/311.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,95 @@ auto any_of(Args && ... args) {
return Comp<Args...> {
std::make_tuple(std::forward<Args>(args)...)
};

}
```
> https://godbolt.org/z/vj8d8jeo9
```cpp
template <class... Ts>
struct any_of {
any_of(Ts... args) : args{args...} {}
auto operator==(auto rhs) const {
return std::apply([&](auto... lhs) { return (... or (lhs == rhs)); }, args);
}
private:
std::tuple<Ts...> args;
};
```

> https://godbolt.org/z/efjx5c68M

```cpp
template <typename ... Ts>
struct any_of{
any_of(Ts const & ... args):t(args...){}
bool operator==(auto const & i) {
return std::apply( [&i](auto const & ...args){
return ((args==i)||...);
}
, t
);
}
std::tuple<Ts...> t;
};
```
> https://godbolt.org/z/KTTcrMTj5
```cpp
template<typename T=int, typename ... Vs>
class any_of {
std::array<T, sizeof ... (Vs)> values;
public:
any_of (Vs ... vs) {
if constexpr (sizeof ... (Vs)) {
this->values = std::array{vs...};
}
}
constexpr bool operator==(const T& other) {
return std::any_of(
std::cbegin(this->values),
std::cend(this->values),
[&other](auto x) { return x == other; } );
}
}
```

> https://godbolt.org/z/37cccv9fv
```cpp
template <typename... Ts>
struct any_of {
any_of(Ts... ts):values{ts...}{}

auto operator == (auto t){
return std::any_of(std::begin(values), std::end(values), [=](auto x){ return t == x;});
}

private:
std::array<int, sizeof...(Ts)> values;
};
```

> https://godbolt.org/z/TKWsroz55
```cpp
template <class... Ts>
struct any_of {
any_of(Ts... values) : values_{values...} {}

bool operator==(auto to) const {
return std::apply([&](auto&&... value) { return ((value == to) || ...); }, values_);
}

private:
std::tuple<Ts...> values_;
};
```

> https://godbolt.org/z/TYv3vYrKE
68 changes: 68 additions & 0 deletions tips/312.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<details open><summary>Info</summary><p>

* Did you know that C++20 added support for Unevaluated asm-declaration in constexpr functions?

* https://wg21.link/P1668

</p></details><details open><summary>Example</summary><p>

```cpp
constexpr auto get = [](auto value) {
if consteval {
return value;
} else {
auto result = 0;
asm("movl $42, %%eax\n" : "=r" (result) );
return result;
}
};

static_assert(0 == get(0));
static_assert(4 == get(4));
static_assert(2 == get(2));

consteval auto fn() {
return get(0);
}

int main(int argc, char**) {
assert(42 == get(0));
assert(42 == get(argc));
return fn();
}
```
> https://godbolt.org/z/z5jYdsa9P
</p></details><details open><summary>Puzzle</summary><p>
> Can you implement `const_sub_or_asm_add` which subtract given numbers using C++ operators if values can be constant evaluated and adds them using inline assembly otherwise?
```cpp
constexpr auto const_sub_or_asm_add = [](auto lhs, auto rhs) {
return 0; /*TODO*/
};
static_assert(1 == const_sub_or_asm_add(2, 1));
static_assert(-1 == const_sub_or_asm_add(3, 4));
int main(int argc, char**) {
{
constexpr auto c = const_sub_or_asm_add(1, 2);
assert(-1 == c);
}
{
auto c = const_sub_or_asm_add(1, 2);
assert(3 == c);
}
{
assert(3 == const_sub_or_asm_add(1, 2));
assert(1 == const_sub_or_asm_add(argc, 0));
assert(2 == const_sub_or_asm_add(argc, argc));
}
}
```

> https://godbolt.org/z/897a3fn8M

0 comments on commit 9559b46

Please sign in to comment.