Skip to content

Latest commit

 

History

History
103 lines (79 loc) · 2.28 KB

230.md

File metadata and controls

103 lines (79 loc) · 2.28 KB
Info

Example

#include <cassert>

consteval int f(int i) { return i; }

constexpr int g(int i) {
    if consteval {
        return f(i) + 1; // ok: immediate function context
    } else {
        return 42;
    }
}

consteval int h(int i) {
    return f(i) + 1; // ok: immediate function context
}

static_assert(42 + 1 == h(42));

int main() {
  int i = 42;
  //h(i); // error: the value of 'i' is not usable in a constant expression
  assert(42 == g(i));
}

https://godbolt.org/z/rjeodeMoP

Puzzle

  • Can you implement a add_or_sub algorithm which adds args… to N in consteval context and subs args... from N otherwise?
template<auto N = 0>
constexpr auto add_or_sub = [](const auto... args); // TODO

int main() {
  using namespace boost::ut;

  "add or sub test"_test = [] {
    should("add in consteval context") = [] {
      expect(constant<0_i == add_or_sub<0>()>);
      expect(constant<1_i == add_or_sub<0>(1)>);
      expect(constant<2_i == add_or_sub<1>(1)>);
      expect(constant<4_i == add_or_sub<1>(1, 2)>);
      expect(constant<16_i == add_or_sub<2>(3, 4, 7)>);
    };

    should("sub in non-consteval context") = [] {
      expect(0_i == add_or_sub<0>());
      expect(-1_i == add_or_sub<0>(1));
      expect(0_i == add_or_sub<1>(1));
      expect(-2_i == add_or_sub<1>(1, 2));
      expect(-12_i == add_or_sub<2>(3, 4, 7));

      const auto i = 42;
      expect(-44_i == add_or_sub<>(2, i));

      auto x = 7;
      expect(-51_i == add_or_sub<1>(1, x, 2, i));
    };
  };
}

https://godbolt.org/z/xssv8MY4W

Solutions

template<auto N = 0>
constexpr auto add_or_sub = [](const auto... args) {
  if consteval {
    return (N + ... + args);
  } else {
    return (N - ... - args);
  }
};

https://godbolt.org/z/8vqoPb5dT

template<auto N = 0>
constexpr auto add_or_sub = [](const auto... args) {
    const auto sum_of_args = (args + ... + 0);
    if consteval {
        return N + sum_of_args;
    } else {
        return N - sum_of_args;
    }
};

https://godbolt.org/z/5xerzMjq3