NYFRUAGKJW5ARRBK2KV74YZOYSI2HS23GBKADEPT6DD6SXON6ROQC
WIH7D6VWMT5Z36YBJN2PJ4Q35IUDNZIYGNIX6HTMXPMUXTRAYTSAC
PZPJ7F4OAINZC3D6HE3BDLZR7LNUEOTCFWOHU324SB4K4W7U7IBAC
RM3OVL2ZMAPPRXTFFRCGWSYK7UQUSEDJ3VFJWEL6I4WYF5IRBX3QC
6FA27FLNKYSKFHX7IJTITDYWHUYYFYDEYF24SPWZF22OXCGLI3EAC
4CVWQ5M3SLVLFHBDDQUWITF465YOUI7VYG7W6VWDOOXTHNZCXITAC
7OON6I5DETIRCQ24MOUVJ5QWQIMPTNP2PCRAA3BFOUMZ3I6PZOKQC
: tests.out
$* &> /dev/null
#include "cpp-gen/Term.h"
#include "cpp-gen/Minterm.h"
#include <catch2/catch_test_macros.hpp>
#include <bitset>
#include <limits>
#include <string>
#include <tuple>
// std::get helper
namespace detail {
template <std::size_t, typename>
struct std_get_f;
template <std::size_t _i, typename ..._Ts>
struct std_get_f<_i, std::tuple<_Ts...>> {
using Function =
std::tuple_element_t<_i, std::tuple<_Ts...>> const &(std::tuple<_Ts...> const &);
static constexpr
auto value =
static_cast<Function *>(&std::get<_i, _Ts...>);
};
} // namespace detail
template <std::size_t _i, typename _T>
constexpr auto std_get =
detail::std_get_f<_i, _T>::value;
constexpr
bool isOdd(int const &value) {
return value & 1;
}
constexpr
bool isEven(int const &value) {
return !isOdd(value);
}
constexpr
int popCount(int const &value) {
int result = 0;
for (std::size_t i = 0; i < std::numeric_limits<int>::digits; ++i) {
result += (value >> i) & 1;
}
return result;
}
TEST_CASE("popCount") {
CHECK(0 == popCount(0x00));
CHECK(1 == popCount(0x01));
CHECK(1 == popCount(0x02));
CHECK(2 == popCount(0x03));
CHECK(1 == popCount(0x04));
CHECK(2 == popCount(0x05));
CHECK(2 == popCount(0x06));
CHECK(3 == popCount(0x07));
CHECK(1 == popCount(0x08));
CHECK(2 == popCount(0x09));
CHECK(2 == popCount(0x0A));
CHECK(3 == popCount(0x0B));
CHECK(2 == popCount(0x0C));
CHECK(3 == popCount(0x0D));
CHECK(3 == popCount(0x0E));
CHECK(4 == popCount(0x0F));
CHECK(1 == popCount(0x10));
CHECK(2 == popCount(0x11));
CHECK(2 == popCount(0x12));
CHECK(3 == popCount(0x13));
CHECK(2 == popCount(0x14));
CHECK(3 == popCount(0x15));
CHECK(3 == popCount(0x16));
CHECK(4 == popCount(0x17));
CHECK(2 == popCount(0x18));
CHECK(3 == popCount(0x19));
CHECK(3 == popCount(0x1A));
CHECK(4 == popCount(0x1B));
CHECK(3 == popCount(0x1C));
CHECK(4 == popCount(0x1D));
CHECK(4 == popCount(0x1E));
CHECK(5 == popCount(0x1F));
}
// Foo
struct Foo {
std::string name;
int value;
};
// Bar
struct Bar {
int value;
};
// Aggregate
struct Aggregate {
Foo foo;
Bar bar;
};
constexpr
auto aggFooValue =
Term<&Aggregate::foo, &Foo::value>{};
constexpr
auto aggBarValue =
Term<&Aggregate::bar, &Bar::value>{};
constexpr
auto fooEqBar =
aggFooValue == aggBarValue;
// Pair of Foo
using FooFoo = std::pair<Foo, Foo>;
constexpr
auto fooEqFoo =
Term<&FooFoo::first, &Foo::value>{} == Term<&FooFoo::second, &Foo::value>{};
// Tuple of Foo
using FooFooFoo = std::tuple<Foo, Foo, Foo>;
constexpr
auto fooEqFoo2 =
Term<std_get<0, FooFooFoo>, &Foo::value>{} == Term<std_get<1, FooFooFoo>, &Foo::value>{};
//
// Constraints
//
TEST_CASE("Term popCount") {
CHECK(2 == Term<&Aggregate::foo, &Foo::value, popCount>{}({Foo{"foo", 3}, {7}}));
CHECK_FALSE(Term<&Aggregate::foo, &Foo::value, popCount, isOdd>{}({Foo{"foo", 3}, {7}}));
CHECK(1 == Term<&Aggregate::foo, &Foo::value, popCount>{}({Foo{"foo", 2}, {7}}));
CHECK(Term<&Aggregate::foo, &Foo::value, popCount, isOdd>{}({Foo{"foo", 2}, {7}}));
}
TEST_CASE("Minterm") {
{ using MT = Minterm<
Term<&Foo::value, isOdd>,
Term<&Foo::value, popCount, isOdd>
>;
CHECK(MT({"", 0}).value == std::bitset<2>(0b00));
CHECK(MT({"", 1}).value == std::bitset<2>(0b11));
CHECK(MT({"", 2}).value == std::bitset<2>(0b10));
CHECK(MT({"", 3}).value == std::bitset<2>(0b01));
}
{ using MT = Minterm<
Term<&Aggregate::foo, &Foo::value, isOdd>,
Term<&Aggregate::foo, &Foo::value, popCount, isOdd>,
Term<&Aggregate::bar, &Bar::value, isEven>,
Term<&Aggregate::bar, &Bar::value, popCount, isEven>
>;
CHECK(MT({Foo{"", 0}, Bar{0}}).value == std::bitset<4>(0b1100));
CHECK(MT({Foo{"", 0}, Bar{1}}).value == std::bitset<4>(0b0000));
CHECK(MT({Foo{"", 0}, Bar{2}}).value == std::bitset<4>(0b0100));
CHECK(MT({Foo{"", 0}, Bar{3}}).value == std::bitset<4>(0b1000));
CHECK(MT({Foo{"", 1}, Bar{0}}).value == std::bitset<4>(0b1111));
CHECK(MT({Foo{"", 1}, Bar{1}}).value == std::bitset<4>(0b0011));
CHECK(MT({Foo{"", 1}, Bar{2}}).value == std::bitset<4>(0b0111));
CHECK(MT({Foo{"", 1}, Bar{3}}).value == std::bitset<4>(0b1011));
CHECK(MT({Foo{"", 2}, Bar{0}}).value == std::bitset<4>(0b1110));
CHECK(MT({Foo{"", 2}, Bar{1}}).value == std::bitset<4>(0b0010));
CHECK(MT({Foo{"", 2}, Bar{2}}).value == std::bitset<4>(0b0110));
CHECK(MT({Foo{"", 2}, Bar{3}}).value == std::bitset<4>(0b1010));
CHECK(MT({Foo{"", 3}, Bar{0}}).value == std::bitset<4>(0b1101));
CHECK(MT({Foo{"", 3}, Bar{1}}).value == std::bitset<4>(0b0001));
CHECK(MT({Foo{"", 3}, Bar{2}}).value == std::bitset<4>(0b0101));
CHECK(MT({Foo{"", 3}, Bar{3}}).value == std::bitset<4>(0b1001));
}
}
TEST_CASE("Equal") {
CHECK((Term<popCount>{} == Term<popCount>{})(13));
Foo foo { "foo", 5 };
Bar bar { 0 };
CHECK_FALSE(fooEqBar({foo, bar}));
CHECK_FALSE(fooEqFoo({foo, Foo{"foo2", 4}}));
CHECK(fooEqFoo2({Foo{"foo0", 0}, Foo{"foo1", 0}, Foo{"foo2", 0}}));
bar.value = 5;
CHECK(fooEqBar({foo, bar}));
CHECK(fooEqFoo({foo, Foo{"foo2", 5}}));
CHECK_FALSE(fooEqFoo2({Foo{"foo0", 0}, Foo{"foo1", 1}, Foo{"foo2", 2}}));
}
#include <iostream>
#include <string>
template <typename ...>
struct List {};
template <typename _L, typename _R>
struct Equal {
static_assert(std::is_same_v<typename _L::Operand, typename _R::Operand>);
using Operand = std::decay_t<typename _L::Operand>;
using Result = bool;
}
};
template <std::size_t _i, typename ..._Ts>
struct std_get_f<_i, std::tuple<_Ts...>> {
using Function =
std::tuple_element_t<_i, std::tuple<_Ts...>> const &(*)(std::tuple<_Ts...> const &);
static constexpr
};
} // namespace detail
struct Constraints {
static_assert(
(std::is_same_v<bool, typename std::decay_t<_Terms>::Result> && ...),
"All Constraints must have a Result type of bool"
);
using Operand = detail::Operand<_Terms...>;
using Minterm = std::bitset<sizeof...(_Terms)>;
template <std::size_t _bit, typename _Head, typename ..._Tail>
constexpr
void populate(Minterm &minterm, Operand const &operand, List<_Head, _Tail...>) const {
minterm[_bit] = _Head{}(operand);
if constexpr (sizeof...(_Tail)) {
populate<_bit + 1>(minterm, operand, List<_Tail...>{});
}
}
// Foo
struct Foo {
std::string name;
int value;
};
// Bar
struct Bar {
int value;
};
// Aggregate
struct Aggregate {
Foo foo;
Bar bar;
};
constexpr
auto aggFooValue =
Term<&Aggregate::foo, &Foo::value>{};
constexpr
auto aggBarValue =
Term<&Aggregate::bar, &Bar::value>{};
constexpr
auto fooEqBar =
aggFooValue == aggBarValue;
// Pair of Foo
using FooFoo = std::pair<Foo, Foo>;
constexpr
auto fooEqFoo =
Term<&FooFoo::first, &Foo::value>{} == Term<&FooFoo::second, &Foo::value>{};
// Tuple of Foo
using FooFooFoo = std::tuple<Foo, Foo, Foo>;
constexpr
auto fooEqFoo2 =
Term<std_get<0, FooFooFoo>, &Foo::value>{} == Term<std_get<1, FooFooFoo>, &Foo::value>{};
//
// Main
//
constexpr
auto fooBarOdd =
Constraints<
Term<&Aggregate::foo, &Foo::value, isOdd>,
>{};
//
// Assertions
//
template <typename _Term>
struct TermClosure {
_Term term;
typename _Term::Operand operand;
};
template <typename ..._Terms>
bool check(_Terms &&...terms) {
return (std::get<0>(terms)(std::get<1>(terms)) && ...);
}
Term<&Aggregate::foo, &Foo::value, popcount, isOdd>,
Term<&Aggregate::bar, &Bar::value, isEven>,
Term<&Aggregate::bar, &Bar::value, popcount, isOdd>
//
// Constraints
//
int main () {
std::cout << "Hello, world!\n";
Foo foo { "foo", 5 };
Bar bar { 0 };
bar.value = 5;
return 0;
}
std::cout << fooEqBar({foo, bar}) << ' ' << fooEqFoo({foo, Foo{"foo2", 5}}) << ' ' << fooEqFoo2({Foo{"foo0", 0}, Foo{"foo1", 1}, Foo{"foo2", 2}}) << '\n';
std::cout << Term<&Foo::value, isOdd>{}(foo) << '\n';
for (int i = 0; i < 10; ++i) {
}
std::cout << i << ": " << fooBarOdd(Aggregate{Foo{"foo", i}, Bar{i >> 1}}) << ' ' << popcount(i) << ' ' << isOdd(popcount(i)) << '\n';
std::cout << popcount(4) << '\n';
std::cout << fooEqBar({foo, bar}) << ' ' << fooEqFoo({foo, Foo{"foo2", 4}}) << ' ' << fooEqFoo2({Foo{"foo0", 0}, Foo{"foo1", 0}, Foo{"foo2", 0}}) << '\n';
//
//
// Userland!
//
//
constexpr
bool isEven(int const &value) {
return !isOdd(value);
}
}
constexpr
int popcount(int const &value) {
int result = 0;
for (std::size_t i = 0; i < std::numeric_limits<int>::digits; ++i) {
result += (value >> i) & 1;
}
return result;
constexpr
bool isOdd(int const &value) {
return value & 1;
}
constexpr
Minterm operator()(Operand const &operand) const {
Minterm minterm {};
populate<0>(minterm, operand, List<_Terms...>{});
return minterm;
}
};
namespace detail {
template <typename ..._Terms> struct operand_f;
template <typename ..._Terms> using Operand = typename operand_f<_Terms...>::value;
template <typename _Head, typename ..._Tail>
struct operand_f<_Head, _Tail...> {
using value = typename _Head::Operand;
};
} // namespace detail
template <typename ..._Terms>
template <std::size_t _i, typename _T>
constexpr auto std_get =
detail::std_get_f<_i, _T>::value;
//
// A list of constraints
//
auto value =
static_cast<Function>(&std::get<_i, _Ts...>);
template <auto ..._l, auto ..._r>
constexpr
Equal<Term<_l ...>, Term<_r ...>> operator==(Term<_l ...>, Term<_r ...>) {
return {};
}
// std::get helper
namespace detail {
template <std::size_t, typename>
struct std_get_f;
constexpr
Result operator()(Operand &operand) const {
return _L{}(operand) == _R{}(operand);
constexpr
Result operator()(Operand const &operand) const {
return _L{}(operand) == _R{}(operand);
}
#include <tuple>
#include <type_traits>
#include <limits>
#include <bitset>
#include "cpp-gen/Term.h"
: 1
summary: cpp-gen project repository
:
role: prerequisite
location: https://pkg.cppget.org/1/stable
trust: 70:64:FE:E4:E0:F3:60:F1:B4:51:E1:FA:12:5C:E0:B3:DB:DF:96:33:39:B9:2E:E5:C2:68:63:4C:A6:47:39:43
depends: catch2 ^ 3.3.2
}
};
//
// Equality compare
//
template <typename _L, typename _R>
struct Equal {
static_assert(std::is_same_v<typename _L::Operand, typename _R::Operand>);
using Operand = std::decay_t<typename _L::Operand>;
using Result = bool;
constexpr
Result operator()(Operand const &operand) const {
return _L{}(operand) == _R{}(operand);
}
constexpr
Result operator()(Operand &operand) const {
return _L{}(operand) == _R{}(operand);
template <auto ..._l, auto ..._r>
constexpr
Equal<Term<_l ...>, Term<_r ...>> operator==(Term<_l ...>, Term<_r ...>) {
return {};
}
#pragma once
#include <bitset>
#include <type_traits>
namespace detail {
template <typename ...>
struct List {};
template <typename ..._Terms> struct head_f;
template <typename ..._Terms> using Head = typename head_f<_Terms...>::value;
template <typename _Head, typename ..._Tail>
struct head_f<_Head, _Tail...> {
using value = _Head;
};
} // namespace detail
template <typename ..._Terms>
struct Minterm {
static_assert(
(std::is_same_v<bool, typename _Terms::Result> && ...),
"All Minterm Terms must have a Result type of bool"
);
using Operand = typename detail::Head<_Terms...>::Operand;
using Value = std::bitset<sizeof...(_Terms)>;
Value value;
constexpr
Minterm(Operand const &operand) {
populate<0>(value, operand, detail::List<_Terms...>{});
}
template <std::size_t _bit, typename _Head, typename ..._Tail>
constexpr
void populate(Value &minterm, Operand const &operand, detail::List<_Head, _Tail...>) const {
minterm[_bit] = _Head{}(operand);
if constexpr (sizeof...(_Tail)) {
populate<_bit + 1>(minterm, operand, detail::List<_Tail...>{});
}
}
};
project = cpp-gen
using version
using config
using test
/config.build
/root/
/bootstrap/
build/