Initial import of libdpf.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
commit
e4e666f459
4563 changed files with 1690372 additions and 0 deletions
619
test/tests/wildcard_test.cpp
Normal file
619
test/tests/wildcard_test.cpp
Normal file
|
|
@ -0,0 +1,619 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "asio.hpp"
|
||||
#define LIBDPF_HAS_ASIO
|
||||
#include "dpf.hpp"
|
||||
|
||||
template <std::size_t I = 0,
|
||||
typename DpfKey0,
|
||||
typename DpfKey1,
|
||||
typename ConcreteT>
|
||||
void assign_leaf(DpfKey0 & dpf0, DpfKey1 & dpf1, const ConcreteT y_shr0, const ConcreteT y_shr1)
|
||||
{
|
||||
asio::io_context io_context;
|
||||
std::thread server([&io_context, &dpf0, &y_shr0]()
|
||||
{
|
||||
asio::ip::tcp::acceptor acceptor(io_context, asio::ip::tcp::endpoint(asio::ip::tcp::v4(), 31337));
|
||||
asio::ip::tcp::socket peer{io_context};
|
||||
asio::ip::tcp::endpoint ep{};
|
||||
acceptor.accept(peer, ep);
|
||||
auto future = dpf0.template async_assign_leaf<I>(peer, y_shr0, asio::use_future);
|
||||
io_context.run();
|
||||
future.wait();
|
||||
});
|
||||
std::thread client([&io_context, &dpf1, &y_shr1]()
|
||||
{
|
||||
asio::ip::tcp::socket peer(io_context);
|
||||
asio::ip::tcp::resolver resolver(io_context);
|
||||
asio::connect(peer, resolver.resolve("localhost", "31337"));
|
||||
auto future = dpf1.template async_assign_leaf<I>(peer, y_shr1, asio::use_future);
|
||||
io_context.run();
|
||||
future.wait();
|
||||
});
|
||||
client.join();
|
||||
server.join();
|
||||
}
|
||||
|
||||
TEST(WildcardTest, SingleLeafFailEvalBeforeVernalization)
|
||||
{
|
||||
using input_type = uint8_t;
|
||||
using output_type = dpf::wildcard_value<uint32_t>;
|
||||
using dpf_type = dpf::utils::dpf_type_t<dpf::prg::aes128, dpf::prg::aes128, input_type, output_type>;
|
||||
input_type x = 0xAA;
|
||||
output_type y;
|
||||
auto [dpf0, dpf1] = dpf::make_dpf(x, y);
|
||||
|
||||
ASSERT_THROW(dpf::eval_point(dpf0, x), std::runtime_error);
|
||||
ASSERT_THROW(dpf::eval_point(dpf1, x), std::runtime_error);
|
||||
|
||||
input_type from = 0x33, to = 0xCC;
|
||||
ASSERT_THROW(dpf::eval_interval(dpf0, from, to), std::runtime_error);
|
||||
ASSERT_THROW(dpf::eval_interval(dpf1, from, to), std::runtime_error);
|
||||
|
||||
ASSERT_THROW(dpf::eval_full(dpf0), std::runtime_error);
|
||||
ASSERT_THROW(dpf::eval_full(dpf1), std::runtime_error);
|
||||
|
||||
std::array<input_type, 16> points{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
|
||||
ASSERT_THROW(dpf::eval_sequence(dpf0, std::begin(points), std::end(points)), std::runtime_error);
|
||||
ASSERT_THROW(dpf::eval_sequence(dpf1, std::begin(points), std::end(points)), std::runtime_error);
|
||||
|
||||
ASSERT_THROW(dpf::eval_sequence_breadth_first(dpf0, std::begin(points), std::end(points)), std::runtime_error);
|
||||
ASSERT_THROW(dpf::eval_sequence_breadth_first(dpf1, std::begin(points), std::end(points)), std::runtime_error);
|
||||
|
||||
auto recipe0 = dpf::make_sequence_recipe(dpf0, std::begin(points), std::end(points));
|
||||
auto recipe1 = dpf::make_sequence_recipe(dpf1, std::begin(points), std::end(points));
|
||||
ASSERT_THROW(dpf::eval_sequence(dpf0, recipe0), std::runtime_error);
|
||||
ASSERT_THROW(dpf::eval_sequence(dpf1, recipe1), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST(WildcardTest, MultiLeafFailEvalBeforeVernalization)
|
||||
{
|
||||
using input_type = uint8_t;
|
||||
using output_type0 = uint32_t;
|
||||
using output_type1 = dpf::wildcard_value<uint32_t>;
|
||||
using dpf_type = dpf::utils::dpf_type_t<dpf::prg::aes128, dpf::prg::aes128, input_type, output_type0, output_type1>;
|
||||
input_type x = 0xAA;
|
||||
output_type0 y0 = 0xAAAAAAAA;
|
||||
output_type1 y1;
|
||||
auto [dpf0, dpf1] = dpf::make_dpf(x, y0, y1);
|
||||
|
||||
ASSERT_NO_THROW((dpf::eval_point<0>(dpf0, x)));
|
||||
ASSERT_NO_THROW((dpf::eval_point<0>(dpf1, x)));
|
||||
ASSERT_THROW((dpf::eval_point<1>(dpf0, x)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_point<1>(dpf1, x)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_point<0, 1>(dpf0, x)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_point<0, 1>(dpf1, x)), std::runtime_error);
|
||||
|
||||
input_type from = 0x33, to = 0xCC;
|
||||
ASSERT_NO_THROW((dpf::eval_interval<0>(dpf0, from, to)));
|
||||
ASSERT_NO_THROW((dpf::eval_interval<0>(dpf1, from, to)));
|
||||
ASSERT_THROW((dpf::eval_interval<1>(dpf0, from, to)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_interval<1>(dpf1, from, to)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_interval<0, 1>(dpf0, from, to)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_interval<0, 1>(dpf1, from, to)), std::runtime_error);
|
||||
|
||||
ASSERT_NO_THROW((dpf::eval_full<0>(dpf0)));
|
||||
ASSERT_NO_THROW((dpf::eval_full<0>(dpf1)));
|
||||
ASSERT_THROW((dpf::eval_full<1>(dpf0)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_full<1>(dpf1)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_full<0, 1>(dpf0)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_full<0, 1>(dpf1)), std::runtime_error);
|
||||
|
||||
std::array<input_type, 16> points{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
|
||||
ASSERT_NO_THROW((dpf::eval_sequence<0>(dpf0, std::begin(points), std::end(points))));
|
||||
ASSERT_NO_THROW((dpf::eval_sequence<0>(dpf1, std::begin(points), std::end(points))));
|
||||
ASSERT_THROW((dpf::eval_sequence<1>(dpf0, std::begin(points), std::end(points))), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_sequence<1>(dpf1, std::begin(points), std::end(points))), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_sequence<0, 1>(dpf0, std::begin(points), std::end(points))), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_sequence<0, 1>(dpf1, std::begin(points), std::end(points))), std::runtime_error);
|
||||
|
||||
auto recipe0 = dpf::make_sequence_recipe(dpf0, std::begin(points), std::end(points));
|
||||
auto recipe1 = dpf::make_sequence_recipe(dpf1, std::begin(points), std::end(points));
|
||||
ASSERT_NO_THROW((dpf::eval_sequence<0>(dpf0, recipe0)));
|
||||
ASSERT_NO_THROW((dpf::eval_sequence<0>(dpf1, recipe1)));
|
||||
ASSERT_THROW((dpf::eval_sequence<1>(dpf0, recipe0)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_sequence<1>(dpf1, recipe1)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_sequence<0, 1>(dpf0, recipe0)), std::runtime_error);
|
||||
ASSERT_THROW((dpf::eval_sequence<0, 1>(dpf1, recipe1)), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST(WildcardTest, SingleLeafSuccess)
|
||||
{
|
||||
using input_type = uint8_t;
|
||||
using concrete_type = uint32_t;
|
||||
using output_type = dpf::wildcard_value<concrete_type>;
|
||||
using dpf_type = dpf::utils::dpf_type_t<dpf::prg::aes128, dpf::prg::aes128, input_type, output_type>;
|
||||
input_type x = 0xAA, from = 0x33, to = 0xCC;
|
||||
output_type y;
|
||||
concrete_type y_exp = 0xAAAAAAAA,
|
||||
y_shr0 = 0x12345678,
|
||||
y_shr1 = y_exp - y_shr0,
|
||||
zero_output = 0;
|
||||
auto [dpf0, dpf1] = dpf::make_dpf(x, y);
|
||||
|
||||
assign_leaf(dpf0, dpf1, y_shr0, y_shr1);
|
||||
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i)
|
||||
{
|
||||
auto y0 = *dpf::eval_point(dpf0, i);
|
||||
auto y1 = *dpf::eval_point(dpf1, i);
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(y0, y1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(y0, y1), zero_output);
|
||||
}
|
||||
}
|
||||
|
||||
auto [bufint0, iterint0] = dpf::eval_interval(dpf0, from, to);
|
||||
auto [bufint1, iterint1] = dpf::eval_interval(dpf1, from, to);
|
||||
auto itint0 = std::begin(iterint0);
|
||||
auto itint1 = std::begin(iterint1);
|
||||
for (std::size_t i = from; i <= to; ++i, ++itint0, ++itint1)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itint0, *itint1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itint0, *itint1), zero_output);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itint0, std::end(iterint0));
|
||||
ASSERT_EQ(itint1, std::end(iterint1));
|
||||
|
||||
auto [bufful0, iterful0] = dpf::eval_full(dpf0);
|
||||
auto [bufful1, iterful1] = dpf::eval_full(dpf1);
|
||||
auto itful0 = std::begin(iterful0);
|
||||
auto itful1 = std::begin(iterful1);
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i, ++itful0, ++itful1)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itful0, *itful1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itful0, *itful1), zero_output);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itful0, std::end(iterful0));
|
||||
ASSERT_EQ(itful1, std::end(iterful1));
|
||||
|
||||
std::array<input_type, 16> points{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
|
||||
auto [bufseq0, iterseq0] = dpf::eval_sequence(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufseq1, iterseq1] = dpf::eval_sequence(dpf1, std::begin(points), std::end(points));
|
||||
auto itseq0 = std::begin(iterseq0);
|
||||
auto itseq1 = std::begin(iterseq1);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itseq0, ++itseq1)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itseq0, *itseq1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itseq0, *itseq1), zero_output);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itseq0, std::end(iterseq0));
|
||||
ASSERT_EQ(itseq1, std::end(iterseq1));
|
||||
|
||||
auto [bufbre0, iterbre0] = dpf::eval_sequence_breadth_first(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufbre1, iterbre1] = dpf::eval_sequence_breadth_first(dpf1, std::begin(points), std::end(points));
|
||||
auto itbre0 = std::begin(iterbre0);
|
||||
auto itbre1 = std::begin(iterbre1);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itbre0, ++itbre1)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itbre0, *itbre1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itbre0, *itbre1), zero_output);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itbre0, std::end(iterbre0));
|
||||
ASSERT_EQ(itbre1, std::end(iterbre1));
|
||||
|
||||
auto recipe0 = dpf::make_sequence_recipe(dpf0, std::begin(points), std::end(points));
|
||||
auto recipe1 = dpf::make_sequence_recipe(dpf1, std::begin(points), std::end(points));
|
||||
auto [bufrec0, iterrec0] = dpf::eval_sequence(dpf0, recipe0);
|
||||
auto [bufrec1, iterrec1] = dpf::eval_sequence(dpf1, recipe1);
|
||||
auto itrec0 = std::begin(iterrec0);
|
||||
auto itrec1 = std::begin(iterrec1);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itrec0, ++itrec1)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itrec0, *itrec1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itrec0, *itrec1), zero_output);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itrec0, std::end(iterrec0));
|
||||
ASSERT_EQ(itrec1, std::end(iterrec1));
|
||||
}
|
||||
|
||||
TEST(WildcardTest, MultiLeafSuccess)
|
||||
{
|
||||
using input_type = uint8_t;
|
||||
using output_type0 = uint32_t;
|
||||
using concrete_type = uint32_t;
|
||||
using output_type1 = dpf::wildcard_value<concrete_type>;
|
||||
using dpf_type = dpf::utils::dpf_type_t<dpf::prg::aes128, dpf::prg::aes128, input_type, output_type0, output_type1>;
|
||||
input_type x = 0xAA, from = 0x33, to = 0xCC;
|
||||
output_type0 y0 = 0x55555555,
|
||||
zero_output0 = 0;
|
||||
output_type1 y1;
|
||||
concrete_type y_exp = 0xAAAAAAAA,
|
||||
y_shr0 = 0x12345678,
|
||||
y_shr1 = y_exp - y_shr0,
|
||||
zero_output1 = 0;
|
||||
auto [dpf0, dpf1] = dpf::make_dpf(x, y0, y1);
|
||||
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i)
|
||||
{
|
||||
auto ypoi0 = *dpf::eval_point<0>(dpf0, i);
|
||||
auto ypoi1 = *dpf::eval_point<0>(dpf1, i);
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(ypoi0, ypoi1), y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(ypoi0, ypoi1), zero_output0);
|
||||
}
|
||||
}
|
||||
|
||||
auto [bufint00, iterint00] = dpf::eval_interval<0>(dpf0, from, to);
|
||||
auto [bufint01, iterint01] = dpf::eval_interval<0>(dpf1, from, to);
|
||||
auto itint00 = std::begin(iterint00);
|
||||
auto itint01 = std::begin(iterint01);
|
||||
for (std::size_t i = from; i <= to; ++i, ++itint00, ++itint01)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itint00, *itint01), y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itint00, *itint01), zero_output0);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itint00, std::end(iterint00));
|
||||
ASSERT_EQ(itint01, std::end(iterint01));
|
||||
|
||||
auto [bufful00, iterful00] = dpf::eval_full<0>(dpf0);
|
||||
auto [bufful01, iterful01] = dpf::eval_full<0>(dpf1);
|
||||
auto itful00 = std::begin(iterful00);
|
||||
auto itful01 = std::begin(iterful01);
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i, ++itful00, ++itful01)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itful00, *itful01), y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itful00, *itful01), zero_output0);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itful00, std::end(iterful00));
|
||||
ASSERT_EQ(itful01, std::end(iterful01));
|
||||
|
||||
std::array<input_type, 16> points{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF};
|
||||
auto [bufseq00, iterseq00] = dpf::eval_sequence<0>(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufseq01, iterseq01] = dpf::eval_sequence<0>(dpf1, std::begin(points), std::end(points));
|
||||
auto itseq00 = std::begin(iterseq00);
|
||||
auto itseq01 = std::begin(iterseq01);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itseq00, ++itseq01)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itseq00, *itseq01), y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itseq00, *itseq01), zero_output0);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itseq00, std::end(iterseq00));
|
||||
ASSERT_EQ(itseq01, std::end(iterseq01));
|
||||
|
||||
auto [bufbre00, iterbre00] = dpf::eval_sequence_breadth_first<0>(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufbre01, iterbre01] = dpf::eval_sequence_breadth_first<0>(dpf1, std::begin(points), std::end(points));
|
||||
auto itbre00 = std::begin(iterbre00);
|
||||
auto itbre01 = std::begin(iterbre01);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itbre00, ++itbre01)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itbre00, *itbre01), y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itbre00, *itbre01), zero_output0);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itbre00, std::end(iterbre00));
|
||||
ASSERT_EQ(itbre01, std::end(iterbre01));
|
||||
|
||||
auto recipe0 = dpf::make_sequence_recipe(dpf0, std::begin(points), std::end(points));
|
||||
auto recipe1 = dpf::make_sequence_recipe(dpf1, std::begin(points), std::end(points));
|
||||
auto [bufrec00, iterrec00] = dpf::eval_sequence<0>(dpf0, recipe0);
|
||||
auto [bufrec01, iterrec01] = dpf::eval_sequence<0>(dpf1, recipe1);
|
||||
auto itrec00 = std::begin(iterrec00);
|
||||
auto itrec01 = std::begin(iterrec01);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itrec00, ++itrec01)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itrec00, *itrec01), y0);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itrec00, *itrec01), zero_output0);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itrec00, std::end(iterrec00));
|
||||
ASSERT_EQ(itrec01, std::end(iterrec01));
|
||||
|
||||
assign_leaf<1>(dpf0, dpf1, y_shr0, y_shr1);
|
||||
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i)
|
||||
{
|
||||
auto ypoi0 = *dpf::eval_point<1>(dpf0, i);
|
||||
auto ypoi1 = *dpf::eval_point<1>(dpf1, i);
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(ypoi0, ypoi1), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(ypoi0, ypoi1), zero_output1);
|
||||
}
|
||||
}
|
||||
|
||||
auto [bufint10, iterint10] = dpf::eval_interval<1>(dpf0, from, to);
|
||||
auto [bufint11, iterint11] = dpf::eval_interval<1>(dpf1, from, to);
|
||||
auto itint10 = std::begin(iterint10);
|
||||
auto itint11 = std::begin(iterint11);
|
||||
for (std::size_t i = from; i <= to; ++i, ++itint10, ++itint11)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itint10, *itint11), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itint10, *itint11), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itint10, std::end(iterint10));
|
||||
ASSERT_EQ(itint11, std::end(iterint11));
|
||||
|
||||
auto [bufful10, iterful10] = dpf::eval_full<1>(dpf0);
|
||||
auto [bufful11, iterful11] = dpf::eval_full<1>(dpf1);
|
||||
auto itful10 = std::begin(iterful10);
|
||||
auto itful11 = std::begin(iterful11);
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i, ++itful10, ++itful11)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itful10, *itful11), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itful10, *itful11), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itful10, std::end(iterful10));
|
||||
ASSERT_EQ(itful11, std::end(iterful11));
|
||||
|
||||
auto [bufseq10, iterseq10] = dpf::eval_sequence<1>(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufseq11, iterseq11] = dpf::eval_sequence<1>(dpf1, std::begin(points), std::end(points));
|
||||
auto itseq10 = std::begin(iterseq10);
|
||||
auto itseq11 = std::begin(iterseq11);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itseq10, ++itseq11)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itseq10, *itseq11), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itseq10, *itseq11), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itseq10, std::end(iterseq10));
|
||||
ASSERT_EQ(itseq11, std::end(iterseq11));
|
||||
|
||||
auto [bufbre10, iterbre10] = dpf::eval_sequence_breadth_first<1>(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufbre11, iterbre11] = dpf::eval_sequence_breadth_first<1>(dpf1, std::begin(points), std::end(points));
|
||||
auto itbre10 = std::begin(iterbre10);
|
||||
auto itbre11 = std::begin(iterbre11);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itbre10, ++itbre11)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itbre10, *itbre11), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itbre10, *itbre11), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itbre10, std::end(iterbre10));
|
||||
ASSERT_EQ(itbre11, std::end(iterbre11));
|
||||
|
||||
auto [bufrec10, iterrec10] = dpf::eval_sequence<1>(dpf0, recipe0);
|
||||
auto [bufrec11, iterrec11] = dpf::eval_sequence<1>(dpf1, recipe1);
|
||||
auto itrec10 = std::begin(iterrec10);
|
||||
auto itrec11 = std::begin(iterrec11);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itrec10, ++itrec11)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itrec10, *itrec11), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(*itrec10, *itrec11), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itrec10, std::end(iterrec10));
|
||||
ASSERT_EQ(itrec11, std::end(iterrec11));
|
||||
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i)
|
||||
{
|
||||
auto ypoi0 = dpf::eval_point<0, 1>(dpf0, i);
|
||||
auto ypoi1 = dpf::eval_point<0, 1>(dpf1, i);
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(static_cast<output_type0>(dpf::reconstruct(std::get<0>(ypoi0), std::get<0>(ypoi1))), y0);
|
||||
ASSERT_EQ(static_cast<concrete_type>(dpf::reconstruct(std::get<1>(ypoi0), std::get<1>(ypoi1))), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(static_cast<output_type0>(dpf::reconstruct(std::get<0>(ypoi0), std::get<0>(ypoi1))), zero_output0);
|
||||
ASSERT_EQ(static_cast<concrete_type>(dpf::reconstruct(std::get<1>(ypoi0), std::get<1>(ypoi1))), zero_output1);
|
||||
}
|
||||
}
|
||||
|
||||
auto [bufintmul0, iterintmul0] = dpf::eval_interval<0, 1>(dpf0, from, to);
|
||||
auto [bufintmul1, iterintmul1] = dpf::eval_interval<0, 1>(dpf1, from, to);
|
||||
auto zipint0 = dpf::tuple_as_zip(iterintmul0);
|
||||
auto zipint1 = dpf::tuple_as_zip(iterintmul1);
|
||||
auto itintmul0 = std::begin(zipint0);
|
||||
auto itintmul1 = std::begin(zipint1);
|
||||
for (std::size_t i = from; i <= to; ++i, ++itintmul0, ++itintmul1)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itintmul0), std::get<0>(*itintmul1)), y0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itintmul0), std::get<1>(*itintmul1)), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itintmul0), std::get<0>(*itintmul1)), zero_output0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itintmul0), std::get<1>(*itintmul1)), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itintmul0, std::end(zipint0));
|
||||
ASSERT_EQ(itintmul1, std::end(zipint1));
|
||||
|
||||
auto [buffulmul0, iterfulmul0] = dpf::eval_full<0, 1>(dpf0);
|
||||
auto [buffulmul1, iterfulmul1] = dpf::eval_full<0, 1>(dpf1);
|
||||
auto zipful0 = dpf::tuple_as_zip(iterfulmul0);
|
||||
auto zipful1 = dpf::tuple_as_zip(iterfulmul1);
|
||||
auto itfulmul0 = std::begin(zipful0);
|
||||
auto itfulmul1 = std::begin(zipful1);
|
||||
for (std::size_t i = std::numeric_limits<input_type>::min(); i <= std::numeric_limits<input_type>::max(); ++i, ++itfulmul0, ++itfulmul1)
|
||||
{
|
||||
if (i == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itfulmul0), std::get<0>(*itfulmul1)), y0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itfulmul0), std::get<1>(*itfulmul1)), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itfulmul0), std::get<0>(*itfulmul1)), zero_output0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itfulmul0), std::get<1>(*itfulmul1)), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itfulmul0, std::end(zipful0));
|
||||
ASSERT_EQ(itfulmul1, std::end(zipful1));
|
||||
|
||||
auto [bufseqmul0, iterseqmul0] = dpf::eval_sequence<0, 1>(dpf0, std::begin(points), std::end(points));
|
||||
auto [bufseqmul1, iterseqmul1] = dpf::eval_sequence<0, 1>(dpf1, std::begin(points), std::end(points));
|
||||
auto zipseq0 = dpf::tuple_as_zip(iterseqmul0);
|
||||
auto zipseq1 = dpf::tuple_as_zip(iterseqmul1);
|
||||
auto itseqmul0 = std::begin(zipseq0);
|
||||
auto itseqmul1 = std::begin(zipseq1);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itseqmul0, ++itseqmul1)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itseqmul0), std::get<0>(*itseqmul1)), y0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itseqmul0), std::get<1>(*itseqmul1)), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itseqmul0), std::get<0>(*itseqmul1)), zero_output0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itseqmul0), std::get<1>(*itseqmul1)), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itseqmul0, std::end(zipseq0));
|
||||
ASSERT_EQ(itseqmul1, std::end(zipseq1));
|
||||
|
||||
auto [bufrecmul0, iterrecmul0] = dpf::eval_sequence<0, 1>(dpf0, recipe0);
|
||||
auto [bufrecmul1, iterrecmul1] = dpf::eval_sequence<0, 1>(dpf1, recipe1);
|
||||
auto ziprec0 = dpf::tuple_as_zip(iterrecmul0);
|
||||
auto ziprec1 = dpf::tuple_as_zip(iterrecmul1);
|
||||
auto itrecmul0 = std::begin(ziprec0);
|
||||
auto itrecmul1 = std::begin(ziprec1);
|
||||
for (std::size_t i = 0; i < points.size(); ++i, ++itrecmul0, ++itrecmul1)
|
||||
{
|
||||
if (points[i] == x)
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itrecmul0), std::get<0>(*itrecmul1)), y0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itrecmul0), std::get<1>(*itrecmul1)), y_exp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<0>(*itrecmul0), std::get<0>(*itrecmul1)), zero_output0);
|
||||
ASSERT_EQ(dpf::reconstruct(std::get<1>(*itrecmul0), std::get<1>(*itrecmul1)), zero_output1);
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(itrecmul0, std::end(ziprec0));
|
||||
ASSERT_EQ(itrecmul1, std::end(ziprec1));
|
||||
}
|
||||
|
||||
TEST(WildcardTest, PackedSmallWildcardsAtNonTerminalAssignAll)
|
||||
{
|
||||
// Four packed uint8 wildcards at a non-terminal prefix, plus a concrete
|
||||
// deepest output. Assign every wildcard leaf through the asio path.
|
||||
using concrete_t = uint8_t;
|
||||
dpf::wildcard_value<concrete_t> w;
|
||||
uint16_t x = 0x55aa;
|
||||
auto [dpf0, dpf1] = dpf::make_dpf(x,
|
||||
dpf::at<10>(w, w, w, w),
|
||||
uint16_t{99});
|
||||
|
||||
ASSERT_THROW((void)dpf::eval_point(dpf::out<0, 10>, dpf0, x), std::runtime_error);
|
||||
ASSERT_EQ(static_cast<uint16_t>(
|
||||
dpf::reconstruct(*dpf::eval_point(dpf::out<4>, dpf0, x), *dpf::eval_point(dpf::out<4>, dpf1, x))),
|
||||
uint16_t{99});
|
||||
|
||||
const concrete_t want[4] = {1, 2, 3, 4};
|
||||
const concrete_t shr0[4] = {10, 20, 30, 40};
|
||||
assign_leaf<0>(dpf0, dpf1, shr0[0], static_cast<concrete_t>(want[0] - shr0[0]));
|
||||
assign_leaf<1>(dpf0, dpf1, shr0[1], static_cast<concrete_t>(want[1] - shr0[1]));
|
||||
assign_leaf<2>(dpf0, dpf1, shr0[2], static_cast<concrete_t>(want[2] - shr0[2]));
|
||||
assign_leaf<3>(dpf0, dpf1, shr0[3], static_cast<concrete_t>(want[3] - shr0[3]));
|
||||
|
||||
ASSERT_EQ(static_cast<concrete_t>(
|
||||
dpf::reconstruct(*dpf::eval_point(dpf::out<0, 10>, dpf0, x), *dpf::eval_point(dpf::out<0, 10>, dpf1, x))),
|
||||
want[0]);
|
||||
ASSERT_EQ(static_cast<concrete_t>(
|
||||
dpf::reconstruct(*dpf::eval_point(dpf::out<3, 10>, dpf0, x), *dpf::eval_point(dpf::out<3, 10>, dpf1, x))),
|
||||
want[3]);
|
||||
ASSERT_EQ(static_cast<concrete_t>(
|
||||
dpf::reconstruct(
|
||||
*dpf::eval_point(dpf::out<0, 10>, dpf0,
|
||||
static_cast<uint16_t>(x ^ (1u << 6))),
|
||||
*dpf::eval_point(dpf::out<0, 10>, dpf1,
|
||||
static_cast<uint16_t>(x ^ (1u << 6))))),
|
||||
concrete_t{0});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue