Initial import of libdpf.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ryan Henry 2026-09-24 14:08:32 -06:00
commit e4e666f459
4563 changed files with 1690372 additions and 0 deletions

2808
doc/Doxyfile Normal file

File diff suppressed because it is too large Load diff

220
doc/DoxygenLayout.xml Normal file
View file

@ -0,0 +1,220 @@
<doxygenlayout version="1.0">
<!-- Generated by doxygen 1.9.6 -->
<!-- Navigation index tabs for HTML output -->
<navindex>
<tab type="mainpage" visible="yes" title=""/>
<tab type="pages" visible="yes" title="" intro=""/>
<tab type="examples" visible="no" title="Code Listings" intro=""/>
<tab type="usergroup" visible="yes" title="API reference">
<tab type="structs" visible="no" title="">
<tab type="structlist" visible="yes" title="" intro=""/>
<tab type="structindex" visible="$ALPHABETICAL_INDEX" title=""/>
</tab>
<tab type="classlist" visible="yes" title="List of classes" intro=""/>
<tab type="filelist" visible="yes" title="List of files" intro=""/>
</tab>
<!-- <tab type="user" visible="yes" url="@ref BibTeX" title="Citing libdpf++"/> -->
<!-- <tab type="user" visible="yes" url="../grotto" title="Switch to Gʀᴏᴛᴛᴏ"/> -->
<!-- <tab type="user" visible="yes" url="../subleq" title="Switch to Sᴜʙʟᴇǫ"/> -->
</navindex>
<!-- Layout definition for a class page -->
<class>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<inheritancegraph visible="$CLASS_GRAPH"/>
<collaborationgraph visible="$COLLABORATION_GRAPH"/>
<detaileddescription title=""/>
<memberdecl>
<nestedclasses visible="yes" title=""/>
<publictypes title=""/>
<services title=""/>
<interfaces title=""/>
<publicslots title=""/>
<signals title=""/>
<publicmethods title=""/>
<publicstaticmethods title=""/>
<publicattributes title=""/>
<publicstaticattributes title=""/>
<protectedtypes title=""/>
<protectedslots title=""/>
<protectedmethods title=""/>
<protectedstaticmethods title=""/>
<protectedattributes title=""/>
<protectedstaticattributes title=""/>
<packagetypes title=""/>
<packagemethods title=""/>
<packagestaticmethods title=""/>
<packageattributes title=""/>
<packagestaticattributes title=""/>
<properties title=""/>
<events title=""/>
<privatetypes title=""/>
<privateslots title=""/>
<privatemethods title=""/>
<privatestaticmethods title=""/>
<privateattributes title=""/>
<privatestaticattributes title=""/>
<friends title=""/>
<related title="" subtitle=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<enums title=""/>
<services title=""/>
<interfaces title=""/>
<constructors title=""/>
<functions title=""/>
<related title=""/>
<variables title=""/>
<properties title=""/>
<events title=""/>
</memberdef>
<allmemberslink visible="yes"/>
<usedfiles visible="$SHOW_USED_FILES"/>
<authorsection visible="yes"/>
</class>
<!-- Layout definition for a namespace page -->
<namespace>
<briefdescription visible="yes"/>
<detaileddescription title=""/>
<memberdecl>
<nestednamespaces visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<concepts visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection visible="yes"/>
</namespace>
<!-- Layout definition for a concept page -->
<concept>
<briefdescription visible="yes"/>
<includes visible="$SHOW_HEADERFILE"/>
<definition visible="yes" title=""/>
<detaileddescription title=""/>
<authorsection visible="yes"/>
</concept>
<!-- Layout definition for a file page -->
<file>
<briefdescription visible="yes"/>
<includes visible="$SHOW_INCLUDE_FILES"/>
<includegraph visible="$INCLUDE_GRAPH"/>
<includedbygraph visible="$INCLUDED_BY_GRAPH"/>
<sourcelink visible="yes"/>
<detaileddescription title=""/>
<memberdecl>
<interfaces visible="yes" title=""/>
<classes visible="yes" title=""/>
<structs visible="yes" title=""/>
<exceptions visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<constantgroups visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<functions title=""/>
<variables title=""/>
</memberdef>
<authorsection/>
</file>
<!-- Layout definition for a group page -->
<group>
<briefdescription visible="yes"/>
<groupgraph visible="$GROUP_GRAPHS"/>
<detaileddescription title=""/>
<memberdecl>
<nestedgroups visible="yes" title=""/>
<dirs visible="yes" title=""/>
<files visible="yes" title=""/>
<namespaces visible="yes" title=""/>
<concepts visible="yes" title=""/>
<classes visible="yes" title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
<membergroups visible="yes"/>
</memberdecl>
<memberdef>
<pagedocs/>
<inlineclasses title=""/>
<defines title=""/>
<typedefs title=""/>
<sequences title=""/>
<dictionaries title=""/>
<enums title=""/>
<enumvalues title=""/>
<functions title=""/>
<variables title=""/>
<signals title=""/>
<publicslots title=""/>
<protectedslots title=""/>
<privateslots title=""/>
<events title=""/>
<properties title=""/>
<friends title=""/>
</memberdef>
<authorsection visible="yes"/>
</group>
<!-- Layout definition for a directory page -->
<directory>
<briefdescription visible="yes"/>
<directorygraph visible="yes"/>
<detaileddescription title=""/>
<memberdecl>
<dirs visible="yes"/>
<files visible="yes"/>
</memberdecl>
</directory>
</doxygenlayout>

BIN
doc/assets/libdpf-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
doc/assets/libdpf.psd Normal file

Binary file not shown.

32
doc/directories.dox Normal file
View file

@ -0,0 +1,32 @@
/// @dir ./doc
/// @brief input files used by `Doxygen` to produce this documentation
/// @dir ./doc/assets
/// @brief image files
/// @dir ./examples
/// @brief sample code listings to demonstrate use of various `libdpf++` features
/// @dir ./examples/evaluation
/// @brief evaluation
/// @dir ./examples/input_types
/// @brief inputs
/// @dir ./examples/output_types
/// @brief outputs
/// @dir ./examples/iterables
/// @brief iterable
/// @dir ./include
/// @brief location of `dph.hpp` and many other `libdpf++` headers in `include/dpf`
/// @dir ./include/dpf
/// @brief location of most `libdpf++` headers
/// @dir ./test
/// @brief collection of `GTest` test cases
/// @dir ./thirdparty
/// @brief submodules and other third-party content

102
doc/examples.dox Normal file
View file

@ -0,0 +1,102 @@
// input_types
/// @{
/// @example input_types/integral_types.cpp integral_types.cpp
/// @brief an example of `int` in use
/// @example input_types/extended_types.cpp extended_types.cpp
/// @brief an example of `int128_t` in use
/// @example input_types/modint.cpp modint.cpp
/// @brief an example of `dpf::modint` in use
/// @example input_types/bitstring.cpp bitstring.cpp
/// @brief an example of `dpf::bitstring` in use
/// @example input_types/keyword.cpp keyword.cpp
/// @brief an example of `dpf::keyword` in use
/// @example input_types/xor_wrapper.cpp xor_wrapper.cpp
/// @brief an example of `dpf::memoizers` in use
/// @example input_types/custom.cpp custom.cpp
/// @brief an example of `dpf::output_buffers` in use
/// @}
// output_types
/// @{
/// @example output_types/integral_types.cpp integral_types.cpp
/// @brief an example of `dpf::eval_point` in use
/// @example output_types/extended_types.cpp extended_types.cpp
/// @brief an example of `dpf::eval_interval` in use
/// @example output_types/bit.cpp bit.cpp
/// @brief an example of `dpf::eval_full` in use
/// @example output_types/bitstring.cpp bitstring.cpp
/// @brief an example of `dpf::eval_sequence` in use
/// @example output_types/wildcard.cpp wildcard.cpp
/// @brief an example of `dpf::eval_sequence` in use
/// @example output_types/xor_wrapper.cpp xor_wrapper.cpp
/// @brief an example of `dpf::memoizers` in use
/// @example output_types/custom.cpp custom.cpp
/// @brief an example of `dpf::output_buffers` in use
/// @}
// evaluations
/// @{
/// @example evaluation/eval_point.cpp eval_point.cpp
/// @brief an example of `dpf::eval_point` in use
/// @example evaluation/eval_interval.cpp eval_interval.cpp
/// @brief an example of `dpf::eval_interval` in use
/// @example evaluation/eval_full.cpp eval_full.cpp
/// @brief an example of `dpf::eval_full` in use
/// @example evaluation/eval_sequence.cpp eval_sequence.cpp
/// @brief an example of `dpf::eval_sequence` in use
/// @example evaluation/memoizers.cpp memoizers.cpp
/// @brief an example of `dpf::memoizers` in use
/// @example evaluation/output_buffers.cpp output_buffers.cpp
/// @brief an example of `dpf::output_buffers` in use
/// @}
/// @{
/// @example iterables/setbit_index_iterable.cpp setbit_index_iterable.cpp
/// @brief an example of `dpf::setbit_index_iterable` in use
/// @example iterables/advice_bit_iterable.cpp advice_bit_iterable.cpp
/// @brief an example of `dpf::advice_bit_iterable` in use
/// @example iterables/parallel_bit_iterable.cpp parallel_bit_iterable.cpp
/// @brief an example of `dpf::parallel_bit_iterable` in use
/// @example iterables/subinterval_iterable.cpp subinterval_iterable.cpp
/// @brief an example of `dpf::subinterval_iterable` in use
/// @example iterables/subsequence_iterable.cpp subsequence_iterable.cpp
/// @brief an example of `dpf::subsequence_iterable` in use
/// @example iterables/zip_iterable.cpp zip_iterable.cpp
/// @brief an example of `dpf::zip_iterable` in use
/// @}

18
doc/footer.html Normal file
View file

@ -0,0 +1,18 @@
<!-- HTML footer for doxygen 1.9.6-->
<!-- start footer part -->
<!--BEGIN GENERATE_TREEVIEW-->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
$navpath
<li class="footer">$generatedby <a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion </li>
</ul>
</div>
<!--END GENERATE_TREEVIEW-->
<!--BEGIN !GENERATE_TREEVIEW-->
<hr class="footer"/><address class="footer"><small>
$generatedby&#160;<a href="https://www.doxygen.org/index.html"><img class="footer" src="$relpath^doxygen.svg" width="104" height="31" alt="doxygen"/></a> $doxygenversion
</small></address>
<!--END !GENERATE_TREEVIEW-->
</body>
</html>

64
doc/header.html Normal file
View file

@ -0,0 +1,64 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<link rel="icon" type="image/svg+xml" href="libdpf-logo.svg"/>
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-fragment-copy-button.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-paragraph-link.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-interactive-toc.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-tabs.js"></script>
<script type="text/javascript">
DoxygenAwesomeFragmentCopyButton.init()
DoxygenAwesomeDarkModeToggle.init()
DoxygenAwesomeParagraphLink.init()
DoxygenAwesomeInteractiveToc.init()
DoxygenAwesomeTabs.init()
</script>
$treeview
$search
$mathjax
$darkmode
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/brands.min.css" integrity="sha512-9YHSK59/rjvhtDcY/b+4rdnl0V4LPDWdkKceBl8ZLF5TB6745ml1AfluEU6dFWqwDw9lPvnauxFgpKvJqp7jiQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<!-- https://tholman.com/github-corners/ -->
<a href="https://github.com/DigitalLibertiesLab/libdpf" class="github-corner" title="View source on GitHub" target="_blank">
<svg viewBox="0 0 250 250" width="40" height="40" style="opacity: 0.8; position: absolute; top: 0; border: 0; right: 0; z-index: 99;" aria-hidden="true">
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path><path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2" fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path><path d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z" fill="currentColor" class="octo-body"></path></svg></a><style>.github-corner:hover .octo-arm{animation:octocat-wave 560ms ease-in-out}@keyframes octocat-wave{0%,100%{transform:rotate(0)}20%,60%{transform:rotate(-25deg)}40%,80%{transform:rotate(10deg)}}@media (max-width:500px){.github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{animation:octocat-wave 560ms ease-in-out}}</style>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<!--BEGIN TITLEAREA-->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr id="projectrow">
<!--BEGIN PROJECT_LOGO-->
<td colspan="3"><img alt="libdpf++" src="$relpath^$projectlogo" width="330px" height="116px" /></td>
<!--END PROJECT_LOGO-->
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN SEARCHENGINE-->
<tr><td colspan="2">$searchbox</td></tr>
<!--END SEARCHENGINE-->
<!--END DISABLE_INDEX-->
</tr>
</tbody>
</table>
</div>
<!--END TITLEAREA-->
<!-- end header part -->

0
doc/libdpf.bib Normal file
View file

269
doc/libdpf.md Normal file
View file

@ -0,0 +1,269 @@
\mainpage notitle
<a id="mainpage"/>
[TOC]
![](libdpf-tagline.png)
%LIBDPF_INCLUDE_GETTING_STARTED_INTRODUCTION%
- - -
<div style="float:left; color:#999;">&larr;&nbsp;Prev</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref basics)</div>
<!-- PAGE SEPARATOR -->
\page basics DPF Basics
[TOC]
%LIBDPF_INCLUDE_GETTING_DPF_BASICS%
- - -
<div style="float:left; color:#999;">[&larr;&nbsp;Prev](mainpage)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref getting_started)</div>
<!-- PAGE SEPARATOR -->
\page getting_started Getting Started
[TOC]
The getting started guide consists of the following subsections.
- \subpage input_types
- \subpage output_types
- \subpage evaluation
- \subpage iterables
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref mainpage)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref input_types)</div>
<!-- PAGE SEPARATOR -->
\page input_types Input Types
[TOC]
%LIBDPF_INCLUDE_GETTING_STARTED_INPUT_TYPES%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref getting_started)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref output_types)</div>
<!-- PAGE SEPARATOR -->
\page output_types Output Types
[TOC]
%LIBDPF_INCLUDE_GETTING_STARTED_OUTPUT_TYPES%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref input_types)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref evaluation)</div>
<!-- PAGE SEPARATOR -->
\page evaluation Evaluating DPFs
[TOC]
%LIBDPF_INCLUDE_GETTING_STARTED_EVALUATION%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref output_types)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref iterables)</div>
<!-- PAGE SEPARATOR -->
\page iterables Iterables
[TOC]
%LIBDPF_INCLUDE_GETTING_STARTED_ITERABLES%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref evaluation)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref pir)</div>
<!-- PAGE SEPARATOR -->
\page pir PIR
[TOC]
The getting started guide consists of the following subsections.
- \subpage pir1
- \subpage pir2
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref iterable)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref pir1)</div>
\page pir1 PIR1
[TOC]
%LIBDPF_INCLUDE_PIR_PIR1%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref evaluation)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref miscellany)</div>
\page miscellany Miscellany
[TOC]
The miscellany page consists of the following subpages.
- \subpage bugs
- \subpage changes
- \subpage todo
- \subpage submodules
- \subpage authors
- \subpage license
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref pir)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref bugs)</div>
<!-- PAGE SEPARATOR -->
\page bugs Bugs
[TOC]
%LIBDPF_INCLUDE_MISC_BUGS%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref miscellany)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref changes)</div>
<!-- PAGE SEPARATOR -->
\page changes CHANGELOG
[TOC]
%LIBDPF_INCLUDE_MISC_CHANGES%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref bugs)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref todo)</div>
<!-- PAGE SEPARATOR -->
\page todo TODO list
[TOC]
%LIBDPF_INCLUDE_MISC_TODO%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref changes)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref submodules)</div>
<!-- PAGE SEPARATOR -->
\page submodules Submodules
[TOC]
%LIBDPF_INCLUDE_MISC_SUBMODULES%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref todo)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref authors)</div>
<!-- PAGE SEPARATOR -->
\page authors Authors
[TOC]
%LIBDPF_INCLUDE_MISC_AUTHORS%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref submodules)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref license)</div>
<!-- PAGE SEPARATOR -->
\page license License
[TOC]
%LIBDPF_INCLUDE_MISC_LICENSE%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref authors)</div>
<div style="float:right;">[Next&nbsp;&rarr;](@ref listings)</a></div>
<!-- PAGE SEPARATOR -->
\page listings Code Listings
[TOC]
%LIBDPF_INCLUDE_CODE_LISTINGS%
- - -
<div style="float:left;">[&larr;&nbsp;Prev](@ref license)</div>
<div style="float:right; color:#999;">Next&nbsp;&rarr;</div>

20
doc/namespaces.dox Normal file
View file

@ -0,0 +1,20 @@
/// @namespace dpf
/// @brief the `::dpf` namespace
/// @details all components of `libdpf++` live in this namespace (or one of
/// the namespaces nested within it)
/// @namespace dpf::utils
/// @brief the `dpf::utils` namespace
/// @details this is where all the utils go
/// @namespace dpf::details
/// @brief the `dpf::details` namespace`
/// @details this is where details go
/// @namespace dpf::internal
/// @brief the `dpf::internal` namespace
/// @details this is where internal stuff goes
/// @namespace dpf::wildcards
/// @brief the `dpf::wildcards` namespace
/// @details this is where pre-define wildcards go

5
doc/pages/basics.md Normal file
View file

@ -0,0 +1,5 @@
<!-- # DPF Basics {#basics} -->
# Point functions {#point_functions}
# DPF Trees {#dpf_trees}

80
doc/pages/evaluation.md Normal file
View file

@ -0,0 +1,80 @@
<!-- # Evaluating DPFs {#evalaution} -->
Once a `DPF` generated, the *eval_* * functions are used to evaluate differents inputs.
The appropriate function depends on your specific needs. If you only need the DPF's output
for a single input value, use `eval_point`. For evaluating a continuous range of inputs,
`eval_interval` is suitable. To analyze the DPF's behavior across its entire domain, use `eval_full`.
The code likely offers different implementations of memoization and output buffers, allowing you to
optimize for memory usage or execution speed depending on your needs.\n
Using a PRG while making a `DPF` allows the user to check how much it cost to manipulate the `DPF`s.
# Memoizers
The `memoizers` remembers the most used path while the DPF is being created. These are usefull functions
to improve the speed and the cost of execution.
**Code samples**\n
For instance, in the code below the utilization of `dpf::make_basic_path_memoizer` reduced by 10 the time of execution
compare to the code that is commented that doesn't use the `memoizers`.
<div class="tabbed">
- <b class="tab-title">memoizers.cpp</b> \include{cpp} evaluation/memoizers.cpp
</div>
# dpf::eval_point
This function evaluate a single input of a DPF. The XOR result of the `eval_point` for both shares will only be equal to 1 if it represents the correct input in both evaluations. As input arguments it uses the `share` and the input to evaluate (note: it can't be a wildcard, otherwise it will throw an error).\n
**See also**\n
PIR
**Pro tip**\n
Use the `dpf::pathmemoizer` for a faster execution.\n
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">eval_point.cpp</b> \include{cpp} evaluation/eval_point.cpp
</div>
# dpf::eval_interval
This function evaluates a contiguous range of inputs. As input arguments it uses the `share` generated by `make_dpf`,
`from` and `to` for the range of inputs to evaluate.\n
**See also**\n
PIR
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">eval_interval.cpp</b> \include{cpp} evaluation/eval_interval.cpp
</div>
# dpf::eval_full
This function evaluate all the passible inputs it only uses as argument the `share` of the `DPF` to evaluate.
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">eval_full.cpp</b> \include{cpp} evaluation/eval_full.cpp
</div>
# dpf::eval_sequence
This function evaluate a subset of inputs that is not contiguous (useful for a `DPF` made with `keyword`),
it uses as arguments the `share` generated by `make_dpf`, `from` and `to` for the subset of inputs to evaluate.\n
For a better utilization, you can use the `make_sequence_recipe` it takes as input a sorted list and returns a `recipe`.
The cost of creating is a little bit worse than just calling `eval_sequence`, however once the `recipe` created
`eval_sequence` is faster and has a better cost.
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">eval_sequence.cpp</b> \include{cpp} evaluation/eval_sequence.cpp
</div>
# Output buffers

236
doc/pages/input_types.md Normal file
View file

@ -0,0 +1,236 @@
<!-- # Input Types {#input_types} -->
An *input type* is the type used as the domain for the `x`-coordinate of a
DPF. `libdpf++` ships with native support for a number of convenient input
types, which are enumerated below. See also the [formal requirements](@ref custom_input_types)
for a type not listed below to be used as an input type.
Within the `libdpf++` source, the (typically deduced) template parameter
`typename InputT` indicates the input type of the DPF under consideration.
Moreover, the `dpf::dpf_key` class (and some others) publicly expose the
clause
```
using input_type = InputT;
```
providing an easy way to programmatically determine the input type.
# Integer scalar types
Any integer scalar type&mdash;that is, any type `T` such that
`std::numeric_limits<T>::is_integer == true`&mdash;may be used as an input
type. In general, you should always opt for the "shortest" such type that
suits your needs, as shorter bitlengths translate to smaller DPF keys and
faster evaluations thereof.
**Pro tip**\n
Prefer the use of [fixed width integer types](https://en.cppreference.com/w/cpp/types/integer)
over [fundamental integer types](https://en.cppreference.com/w/cpp/language/types)
for specifying input types. For example, use `uint16_t` in place of
`unsigned short`, or `int32_t` in place of `int`. Doing so improves
portability and makes it easier to keep track of the resulting DPF depth.
**See also**\n
The `dpf::modint` class template for custom-bitlength integer types that
allow tighter control over size of DPF keys.
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">integral_types.cpp</b> \include{cpp} input_types/integral_types.cpp
</div>
# Extended-precision integer scalar types
The extended-precision (`128`-bit) integer scalar types provided as
compiler extensions by most major C++ compilers (e.g., `__int128` and `unsigned __int128`), including `g++` and
`clang++` when compiling for `64`-bit targets. (As these types are not
defined in the C++17 standard, `std::numeric_limits` is not specialized
for them, so that `std::numeric_limits<__int128>::is_integer` returns
`false`.)
**Pro tip**\n
Use `simde_uint128` (provided courtesy of (SIMD Everywhere)[https://github.com/simd-everywhere/simde])
to declare such 128-bit integers in compiler-independent way.
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">extended_types.cpp</b> \include{cpp} input_types/extended_types.cpp
</div>
# dpf::modint<Nbits>
Arbitrary-, yet fixed-bitlength unsigned integer types. `dpf::modint` is a
lightweight class template that adapts one of the above-mentioned integer
types for arithmetic modulo `2^Nbits`, where `std::size_t Nbits` is the
template parameter. The specialization chooses an appropriate type for
the underlying integer and uses bitmasking to lazily reduce that integer
when the value is read (by anything other than a like-sized `modint`).
This ensures that arithmetic on `modint`s is just as fast as arithmetic on
the underlying integer type. Specializations with `Nbits` from `1` through
`256` inclusive are supported. Compound assignments (`+=`, `-=`, `*=`,
`&=`, `|=`, `^=`) modify the object even when the returned reference is
discarded.
**Pro tip**\n
Choose the smallest `Nbits` possible to get DPFs of the shortest length --
and with the fastest evaluations -- possible.
**Defined in**\n
@ref dpf/modint.hpp
**Code samples**\n
Here are some examples of arithmetic operations with `dpf::modint`:
<div class="tabbed">
- <b class="tab-title">modint.cpp</b> \include{cpp} input_types/modint.cpp
</div>
# dpf::bitstring<Nbits>
Arbitrary-, yet fixed- bitlength binary strings types. `dpf::bitstring` is
a class template that represents a binary string of any given length.
Compared with `dpf::modint`, a `dpf::bitstring` is well suited to cases
where inputs do not semantically stand for numerical values. For example,
the input may be a pseudorandom identifier or a cryptographic key. There
is no fixed limit on the acceptable bitlength for a `dpf::bitstring`.
In contrast with `dpf::modint`, which uses a (possibly extended-precision)
integer type for its internal representation, the `dpf::bitstring` class
template derives from `dpf::static_bit_array` and, therefore, provides a
wealth of methods and helpers for interacting with its individual bits.
**Pro tip**\n
As always, choose the smallest `Nbits` possible to get DPFs of the
shortest length -- and with the fastest evaluations -- possible.
**Defined in**\n
@ref dpf/bitstring.hpp
**See also**\n
`dpf::bit` and `dpf::static_bit_array`
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">bitstring.cpp</b> \include{cpp} input_types/bitstring.cpp
</div>
# dpf::keyword<Alphabet, N>
Fixed-length strings over restricted alphabets. `dpf::keyword` is an alias
for the class template `dpf::basic_fixed_length_string`, which represents
a string of length `N` consisting solely of letters from
`alphabet`, where `std::size_t N` and `static const char alphabet[]` are
template parameters. To a first approximation, the `dpf::keyword` class
template views each eligible string as an integer expressed in
radix-`std::strlen(alphabet)` and then stores the associated binary number as its
internal representation. This produces representations that are
*significantly* shorter than that of the associated C-string, especially
when `alphabet` comprises few elements.
For example
\code{cpp}
const char cstr[] = "7fffae02";
std::cout << (sizeof(cstr) - 1) * CHAR_BIT << "\n"; // prints 64
using kw = dpf::keyword<8, dpf::alphabets::hex>;
kw str = "7fffae02";
std::cout << dpf::utils::bitlength_of_v<kw> << "\n"; // prints 32
using kw2 = dpf::keyword<8, dpf::alphabets::alphanumeric>;
kw2 str2 = "7fffae02";
std::cout << dpf::utils::bitlength_of_v<kw2> << "\n"; // prints 48
inline constexpr char my_alphabet[] = "7fae02";
using kw3 = dpf::keyword<8, my_alphabet>;
kw3 str3 = "7fffae02";
std::cout << dpf::utils::bitlength_of_v<kw3> << "\n"; // prints 21
using kw4 = dpf::keyword<8, dpf::alphabets::lowercase_alpha>;
kw4 str4 = "7fffae02"; // error (disallowed chars)
\endcode
**Pro tip**\n
Strings implicitly padded to length `N` with "zeros"; i.e., with the first
letter in `alphabet`. To allow for strings of length *less than* `N`,
simply set ``alphabet[0]='\0'``.
**Defined in**\n
@ref dpf/keyword.hpp
**See also**\n
The `dpf::alphabets` namespace for a catalog of predefined alphabets.
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">keyword.cpp</b> \include{cpp} input_types/keyword.cpp
</div>
# dpf::xor_wrapper<T>
An element of `GF(2)^N` for `N=8*sizeof(T)`. `xor_wrapper` is a
lightweight class template that adapts "integer-like" types so that
arithmetic behaves like component-wise `GF(2)^N` arithmetic; that is,
(binary `+` and `-` both become `^`; binary `*` becomes `&`; unary `-`
becomes a nop). This is useful for cases where instances of the input type
are to be XOR-shared among two parties. `xor_wrapper` may be specialized
with any of the above-mentioned input types.
**Defined in**\n
@ref dpf/xor_wrapper.hpp
**Code samples**\n
<div class="tabbed">
- <b class="tab-title">xor_wrapper</b> \include{cpp} input_types/xor_wrapper.cpp
</div>
- - -
# Custom input type requirements {#custom_input_types}
A type can be a DPF input when the library can walk its bits and, for interval
or full-domain evaluation, order its values.
The walk uses `dpf::utils::msb_of<T>::value` as a mask. That mask must support
`mask & x` (the tested bit) and `mask >>= 1` (the next-lower bit). `dpf::utils::bitlength_of<T>`
is the number of steps; for a type that is not an integer it defaults to
`CHAR_BIT * sizeof(T)`, so specialize it when the meaningful width is smaller.
`dpf::utils::mod_pow_2<T>` extracts the low bits that select an output inside a
packed leaf (`offset_within_block`).
Interval and full-domain evaluation also need `operator>`, `operator<`, and
`std::numeric_limits<T>::min()` / `max()`. Sequence evaluation needs
`dpf::utils::countl_zero_symmetric_difference<T>` when the default, which
truncates to 64 bits, is not correct for `T`.
A complete example is `test/tests/helpers/custom_input_type.hpp`. The
comparison must be a real order:
\code{cpp}
bool operator>(input_type lhs, input_type rhs) { return lhs.i > rhs.i; }
\endcode
`msb_of` for a 32-bit payload looks like this. The mask type has to be the
type stored in `msb_of<T>::value`, and `mask & x` has to compile:
\code{cpp}
namespace dpf::utils {
template <> struct msb_of<input_type> {
static constexpr input_type value{int32_t{1} << 31};
};
template <> struct mod_pow_2<input_type> {
std::size_t operator()(input_type val, std::size_t n) const noexcept {
if (n == 0) return 0;
return static_cast<std::size_t>(static_cast<uint32_t>(val.i) & ((std::size_t{1} << n) - 1));
}
};
}
\endcode

33
doc/pages/introduction.md Normal file
View file

@ -0,0 +1,33 @@
# Introduction
## Synopsis {#synopsis}
`libdpf++` is a fast and extensible, header-only C++17 implementation of
`(2,2)-`*distributed point functions* (or *DPFs*). In addition to core DPF
functionality, `libdpf++` provides a plethora of data structures, helper
functions, and syntactic sugar designed to facilitate seamless integration
into higher-level cryptographic protocols and primitives. With its focus on
speed and ease of use, `libdpf++` is an ideal building block for implementing
private information retrieval (PIR), secure multiparty computation (MPC),
zero-knowledge arguments, anonymous messaging, and more.
## Features {#features}
- <i class="fa-solid fa-right-from-bracket"></i> input types
- <i class="fa-solid fa-right-to-bracket"></i> output types
- <i class="fa-solid fa-shuffle"></i> wildcards
- <i class="fa-brands fa-pagelines"></i> multiple leaves
- <i class="fa-solid fa-ellipsis"></i> evaluation types
- <i class="fa-solid fa-memory"></i> memoizers
- <i class="fa-solid fa-file-lines"></i> json serialization
- <i class="fa-solid fa-route"></i> asynchronous I/O
## Credits {#credits}
- Adithya Vadapalli (IIT Kanpur)
- Kyle Storrier (UCalgary)
- Allan Lyons (UCalgary)
## Disclaimer {#disclaimer}
We bet you $50 that there is at least one security bug in this code base. If you are you use this code, it is on you to verify that bug does not cross any of the same code paths as you.

13
doc/pages/iterables.md Normal file
View file

@ -0,0 +1,13 @@
<!-- # Iterables {#iterables} -->
# dpf::setbit_index_iterable
# dpf::subsequence_iterable
# dpf::subinterval_iterable
# dpf::zip_iterable
# dpf::parallel_bit_iterable
# dpf::advice_bit_iterable

122
doc/pages/listings.md Normal file
View file

@ -0,0 +1,122 @@
<!-- # Code Listings {#listings} -->
- \subpage input_type_examples
- \subpage output_type_examples
- \subpage evaluation_examples
- \subpage iteratable_examples
\page input_type_examples input_types
- \subpage input_types_2integral_types_8cpp
- \subpage input_types_2extended_types_8cpp
- \subpage input_types_2modint_8cpp
- \subpage input_types_2bitstring_8cpp
- \subpage input_types_2keyword_8cpp
- \subpage input_types_2xor_wrapper_8cpp
- \subpage input_types_2custom_8cpp
\page "input_types_2integral_types_8cpp" input_types/integral_types.cpp
\include{cpp} input_types/integral_types.cpp
\page "input_types_2extended_types_8cpp" input_types/extended_types.cpp
\include{cpp} input_types/extended_types.cpp
\page "input_types_2modint_8cpp" input_types/modint.cpp
\include{cpp} input_types/modint.cpp
\page "input_types_2bitstring_8cpp" input_types/bitstring.cpp
\include{cpp} input_types/bitstring.cpp
\page "input_types_2keyword_8cpp" input_types/keyword.cpp
\include{cpp} input_types/keyword.cpp
\page "input_types_2xor_wrapper_8cpp" input_types/xor_wrapper.cpp
\include{cpp} input_types/xor_wrapper.cpp
\page "input_types_2custom_8cpp" input_types/custom.cpp
\include{cpp} input_types/custom.cpp
\page output_type_examples output_types
- \subpage output_types_2integral_types_8cpp
- \subpage output_types_2extended_types_8cpp
- \subpage output_types_2bit_8cpp
- \subpage output_types_2bitstring_8cpp
- \subpage output_types_2wildcard_8cpp
- \subpage output_types_2xor_wrapper_8cpp
- \subpage output_types_2custom_8cpp
\page "output_types_2integral_types_8cpp" output_types/integral_types.cpp
\include{cpp} output_types/integral_types.cpp
\page "output_types_2extended_types_8cpp" output_types/extended_types.cpp
\include{cpp} output_types/extended_types.cpp
\page "output_types_2bit_8cpp" output_types/bit.cpp
\include{cpp} output_types/bit.cpp
\page "output_types_2bitstring_8cpp" output_types/bitstring.cpp
\include{cpp} output_types/bitstring.cpp
\page "output_types_2wildcard_8cpp" output_types/wildcard.cpp
\include{cpp} output_types/wildcard.cpp
\page "output_types_2xor_wrapper_8cpp" output_types/xor_wrapper.cpp
\include{cpp} output_types/xor_wrapper.cpp
\page "output_types_2custom_8cpp" output_types/custom.cpp
\include{cpp} output_types/custom.cpp
\page evaluation_examples evaluation
- \subpage evaluation_2eval_point_8cpp
- \subpage evaluation_2eval_interval_8cpp
- \subpage evaluation_2eval_full_8cpp
- \subpage evaluation_2eval_sequence_8cpp
- \subpage evaluation_2memoizers_8cpp
- \subpage evaluation_2output_buffers_8cpp
\page "evaluation_2eval_point_8cpp" evaluation/eval_point.cpp
\include{cpp} evaluation/eval_point.cpp
\page "evaluation_2eval_interval_8cpp" evaluation/eval_interval.cpp
\include{cpp} evaluation/eval_interval.cpp
\page "evaluation_2eval_full_8cpp" evaluation/eval_full.cpp
\include{cpp} evaluation/eval_full.cpp
\page "evaluation_2eval_sequence_8cpp" evaluation/eval_sequence.cpp
\include{cpp} evaluation/eval_sequence.cpp
\page "evaluation_2memoizers_8cpp" evaluation/memoizers.cpp
\include{cpp} evaluation/memoizers.cpp
\page "evaluation_2output_buffers_8cpp" evaluation/output_buffers.cpp
\include{cpp} evaluation/output_buffers.cpp
\page iteratable_examples iterables
- \subpage iterables_2setbit_index_iterable_8cpp
- \subpage iterables_2advice_bit_iterable_8cpp
- \subpage iterables_2parallel_bit_iterable_8cpp
- \subpage iterables_2subinterval_iterable_8cpp
- \subpage iterables_2subsequence_iterable_8cpp
- \subpage iterables_2zip_iterable_8cpp
\page "iterables_2setbit_index_iterable_8cpp" iterables/setbit_index_iterable.cpp
\include{cpp} iterables/setbit_index_iterable.cpp
\page "iterables_2advice_bit_iterable_8cpp" iterables/advice_bit_iterable.cpp
\include{cpp} iterables/advice_bit_iterable.cpp
\page "iterables_2parallel_bit_iterable_8cpp" iterables/parallel_bit_iterable.cpp
\include{cpp} iterables/parallel_bit_iterable.cpp
\page "iterables_2subinterval_iterable_8cpp" iterables/subinterval_iterable.cpp
\include{cpp} iterables/subinterval_iterable.cpp
\page "iterables_2subsequence_iterable_8cpp" iterables/subsequence_iterable.cpp
\include{cpp} iterables/subsequence_iterable.cpp
\page "iterables_2zip_iterable_8cpp" iterables/zip_iterable.cpp
\include{cpp} iterables/zip_iterable.cpp

90
doc/pages/output_types.md Normal file
View file

@ -0,0 +1,90 @@
<!-- # Output Types {#output_types} -->
An output type is the group element stored at the programmed input. Every
output of one DPF must have the same `dpf::utils::bitlength_of_output` width,
and each output type must be trivially copyable and standard layout. Leaf
addition and subtraction are the group operation; leaf multiplication scales
a leaf by one output element (used by wildcard Beaver triples and inner
products).
# Integer scalar types
Fixed-width integers (`uint32_t`, `int64_t`, and the other `psnip` widths)
are an additive group. Leaves use SIMD add, subtract, and multiply, including
`char`, `long long`, `char16_t`, `char32_t`, and `wchar_t` at 8, 16, 32, and
64 bits. `bool` is an 8-bit integer, not a packed bit. Use `dpf::bit` for one
bit.
`dpf::modint<N>` is an output as well as an input. Packed leaves add the
underlying word; values wider than one AES block add with `operator+`.
# Secret shares {#secret_shares}
`dpf::additive_share<T, Party>` and `dpf::subtractive_share<T, Party>` are
layout-identical wrappers around a number-like `T` (`Party` is `0` or `1`).
Reconstruction is `share0 + share1` for additive shares and `share0 - share1`
for subtractive shares. Creating from a plaintext puts the value on party 0
and zero on party 1.
Leaf evaluation returns subtractive shares of the payload. Comparison
(`lt`/`leq`/`gt`/`geq`) returns additive shares. Public plaintexts absorb on
party 0 only. Mixing additive and subtractive shares at the same party flips
the differing-scheme operand on party 1 so the opened secret stays correct.
Use `raw()` / `from_raw` / `retag` for intentional bit-level escapes.
`make_dpf` returns a `party_key` pair so each party's eval result is typed.
Pass plaintext domain points and payloads; use `reconstruct` (or `raw()`)
when you already hold shares.
# Extended-precision integer scalar types
`simde_int128`, `simde_uint128`, `uint128_t`, and `uint256_t` are additive.
Their leaf arithmetic is ordinary addition of those integers.
# dpf::bit
A one-bit output. The group is XOR: `operator+` and `operator-` are both XOR,
and a leaf multiply is AND with an all-zero or all-one mask. Many `dpf::bit`
outputs are packed into each leaf.
# dpf::bitstring<Nbits>
A fixed string of bits in the XOR group. `operator+`, `operator-`, and leaf
addition are XOR. The leftmost character of a literal or of `to_string` is
the most significant bit, matching `0b` notation. Bits above `Nbits` are not
part of the value.
# dpf::wildcard<T>
`dpf::wildcard_value<T>` is a placeholder. The leaf group is the group of
`T`. The value can be filled in later; until then evaluation of that output
throws. `operator()` accepts both lvalues and rvalues.
`float` and `double` wildcards are bitwise, not IEEE arithmetic. Leaf
addition is XOR of the representation and leaf scaling is AND, which is an
exact group. It is not floating-point addition.
# dpf::xor_wrapper<T>
An element of `GF(2)^n` for `n = 8 * sizeof(T)`, or `n = N` for
`dpf::xint<N>`. `operator+` and `operator-` are XOR, `operator*` is AND, and
`++` / `--` flip the low bit (the same XOR with 1). Leaf addition is XOR and
leaf scaling is AND.
# Custom output type requirements {#custom_output_types}
Specialize `dpf::leaf_arithmetic::add_t`, `subtract_t`, and `multiply_t` for
the exterior node type (`simde__m128i` for the default AES PRG, and
`simde__m256i` when that node is used). Each functor's call operator receives
two nodes for addition and subtraction, or a node and one output value for
multiplication, and returns a node.
When the output is larger than one node, the leaf is
`std::array<node, block_length>`. That path uses `operator+` and `operator-`
on the output type when those expressions are valid, and otherwise XORs the
blocks. Prefer an explicit specialization when the group is not
component-wise `+` of one output object.
Outputs must be trivially copyable and standard layout. `dpf::utils::make_from_integral_value<T>`
should build `T` from the integer `1` when tests or `make_default` need a
nonzero payload. See `test/tests/helpers/custom_output_type_small.hpp`.

180
doc/stylesheet.css Normal file
View file

@ -0,0 +1,180 @@
.github-corner svg {
fill: var(--primary-light-color);
color: var(--page-background-color);
width: 96px;
height: 96px;
}
@media screen and (max-width: 767px) {
.github-corner svg {
width: 72px;
height: 72px;
}
#projectnumber {
margin-right: 22px;
}
}
.alter-theme-button {
display: inline-block;
cursor: pointer;
background: var(--primary-color);
color: var(--page-background-color) !important;
border-radius: var(--border-radius-medium);
padding: var(--spacing-small) var(--spacing-medium);
text-decoration: none;
}
.alter-theme-button:hover {
background: var(--primary-dark-color);
}
html.dark-mode .darkmode_inverted_image img, /* < doxygen 1.9.3 */
html.dark-mode .darkmode_inverted_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
filter: brightness(89%) hue-rotate(180deg) invert();
}
.bordered_image {
border-radius: var(--border-radius-small);
border: 1px solid var(--separator-color);
display: inline-block;
overflow: hidden;
}
html.dark-mode .bordered_image img, /* < doxygen 1.9.3 */
html.dark-mode .bordered_image object[type="image/svg+xml"] /* doxygen 1.9.3 */ {
border-radius: var(--border-radius-small);
}
.title_screenshot {
filter: drop-shadow(0px 3px 10px rgba(0,0,0,0.22));
max-width: 500px;
margin: var(--spacing-large) 0;
}
.title_screenshot .caption {
display: none;
}
.bugs\.html::before {
content: "\f188";
}
.changes\.html::before {
content: "\f1da";
}
.submodules\.html::before {
content: "\f1b3";
}
.todo\.html::before {
content: "\f46c";;
}
.authors\.html::before {
content: "\f0c0";
}
.license\.html::before {
content: "\f0e3";
}
.index\.html\:synopsis::before {
content: "\f52b";
}
.index\.html\:features::before {
content: "\f5a2";
}
.index\.html\:credits::before {
content: "\e1a8";
}
.index\.html\:disclaimer::before {
content: "\f3ed";
}
.basics\.html\:point_functions::before {
content: "\e4bd";
}
.basics\.html\:dpf_trees::before {
content: "\f1bb";
}
/*
point function: \e4bd
dpf trees: \e4bd
*/
.basics\.html\:point_functions::before,
.basics\.html\:dpf_trees::before,
.index\.html\:synopsis::before,
.index\.html\:features::before,
.index\.html\:credits::before,
.index\.html\:disclaimer::before,
.bugs\.html::before,
.changes\.html::before, .submodules\.html::before, .todo\.html::before,
.authors\.html::before, .license\.html::before,
.input_types_2integral_types_8cpp\.html::before,
.input_types_2extended_types_8cpp\.html::before,
.input_types_2modint_8cpp\.html::before,
.input_types_2bitstring_8cpp\.html::before,
.input_types_2keyword_8cpp\.html::before,
.input_types_2xor_wrapper_8cpp\.html::before,
.input_types_2custom_8cpp\.html::before,
.output_types_2integral_types_8cpp\.html::before,
.output_types_2extended_types_8cpp\.html::before,
.output_types_2bit_8cpp\.html::before,
.output_types_2bitstring_8cpp\.html::before,
.output_types_2wildcard_8cpp\.html::before,
.output_types_2xor_wrapper_8cpp\.html::before,
.output_types_2custom_8cpp\.html::before,
.evaluation_2eval_point_8cpp\.html::before,
.evaluation_2eval_interval_8cpp\.html::before,
.evaluation_2eval_full_8cpp\.html::before,
.evaluation_2eval_sequence_8cpp\.html::before,
.evaluation_2memoizers_8cpp\.html::before,
.evaluation_2output_buffers_8cpp\.html::before,
.iterables_2setbit_index_iterable_8cpp\.html::before,
.iterables_2advice_bit_iterable_8cpp\.html::before,
.iterables_2parallel_bit_iterable_8cpp\.html::before,
.iterables_2subinterval_iterable_8cpp\.html::before,
.iterables_2subsequence_iterable_8cpp\.html::before,
.iterables_2zip_iterable_8cpp\.html::before {
display: inline-block;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
scale: 0.9;
font: var(--fa-font-solid);
margin-left:-1em;
width: 1.5em;
text-align: center;
}
.input_types_2integral_types_8cpp\.html::before,
.input_types_2extended_types_8cpp\.html::before,
.input_types_2modint_8cpp\.html::before,
.input_types_2bitstring_8cpp\.html::before,
.input_types_2keyword_8cpp\.html::before,
.input_types_2xor_wrapper_8cpp\.html::before,
.input_types_2custom_8cpp\.html::before,
.output_types_2integral_types_8cpp\.html::before,
.output_types_2extended_types_8cpp\.html::before,
.output_types_2bit_8cpp\.html::before,
.output_types_2bitstring_8cpp\.html::before,
.output_types_2wildcard_8cpp\.html::before,
.output_types_2xor_wrapper_8cpp\.html::before,
.output_types_2custom_8cpp\.html::before,
.evaluation_2eval_point_8cpp\.html::before,
.evaluation_2eval_interval_8cpp\.html::before,
.evaluation_2eval_full_8cpp\.html::before,
.evaluation_2eval_sequence_8cpp\.html::before,
.evaluation_2memoizers_8cpp\.html::before,
.evaluation_2output_buffers_8cpp\.html::before,
.iterables_2setbit_index_iterable_8cpp\.html::before,
.iterables_2advice_bit_iterable_8cpp\.html::before,
.iterables_2parallel_bit_iterable_8cpp\.html::before,
.iterables_2subinterval_iterable_8cpp\.html::before,
.iterables_2subsequence_iterable_8cpp\.html::before,
.iterables_2zip_iterable_8cpp\.html::before {
content: "\f1c9";
}