#ifndef _ADV_TAPE_HPP
#define _ADV_TAPE_HPP
#include "Context.hpp"
#include <vector>
namespace adv
{
struct AbsNormalForm;
class Tape final
{
public:
~Tape();
Tape() = delete;
Tape(const Tape&) = delete;
Tape(Tape&&);
Tape(Context&& ctx);
Tape& operator=(const Tape&) = delete;
Tape& operator=(Tape&&);
std::size_t num_indeps() const;
std::size_t num_deps() const;
std::size_t num_abs() const;
Tape abs_decompose() const;
private:
struct Impl;
Impl* m_impl;
Tape(void*);
const void* get_impl() const;
friend std::vector<double> zero_order(const Tape&, const std::vector<double>&);
friend std::pair<std::vector<double>, std::vector<double>> first_order(const Tape& tape, const std::vector<double>& x, const std::vector<double>& dx);
friend std::pair<std::vector<double>, std::vector<double>> first_order_reverse(const Tape& tape, const std::vector<double>& x_, const std::vector<double>& ybar_);
friend std::vector<double> jacobian(const Tape& tape, const std::vector<double>& x);
friend std::vector<double> jacobian_reverse(const Tape& tape, const std::vector<double>& x);
friend AbsNormalForm abs_normal(const Tape& tape, const std::vector<double>& x);
};
}
#endif