.. Copyright (c) 2011-2021 Keith O'Hara

   Distributed under the terms of the Apache License, Version 2.0.

   The full license is in the file LICENSE, distributed with this software.

Compile-time Functionality
==========================

StatsLib is designed to operate equally well as a compile-time computation engine. Compile-time computation allows the compiler to replace function calls (e.g., ``dnorm(0,0,1)``) with static values in the source code. That is, functions are evaluated during the compilation process, rather than at run-time. This capability is made possible due to the templated ``constexpr`` design of the library and can be verified by inspecting the assembly code generated by the compiler. 

The compile-time features are enabled using the ``constexpr`` specifier. The example below computes the pdf, cdf, and quantile function of the Laplace distribution.

.. code:: cpp

    #include "stats.hpp"

    int main()
    {
        
        constexpr double dens_1  = stats::dlaplace(1.0,1.0,2.0); // answer = 0.25
        constexpr double prob_1  = stats::plaplace(1.0,1.0,2.0); // answer = 0.5
        constexpr double quant_1 = stats::qlaplace(0.1,1.0,2.0); // answer = -2.218875...

        return 0;
    }

Inspecting the assembly code generated by Clang (without any optimization):

.. code:: asm

    LCPI0_0:
        .quad	-4611193153885729483    ## double -2.2188758248682015
    LCPI0_1:
        .quad	4602678819172646912     ## double 0.5
    LCPI0_2:
        .quad	4598175219545276417     ## double 0.25000000000000006
        .section	__TEXT,__text,regular,pure_instructions
        .globl	_main
        .p2align	4, 0x90
    _main:                                  ## @main
        push	rbp
        mov	rbp, rsp
        xor	eax, eax
        movsd	xmm0, qword ptr [rip + LCPI0_0] ## xmm0 = mem[0],zero
        movsd	xmm1, qword ptr [rip + LCPI0_1] ## xmm1 = mem[0],zero
        movsd	xmm2, qword ptr [rip + LCPI0_2] ## xmm2 = mem[0],zero
        mov	dword ptr [rbp - 4], 0
        movsd	qword ptr [rbp - 16], xmm2
        movsd	qword ptr [rbp - 24], xmm1
        movsd	qword ptr [rbp - 32], xmm0
        pop	rbp
        ret

We see that functions call have been replaced by numeric values.
