summaryrefslogtreecommitdiffstats
path: root/include/ixion/cell.hpp
blob: 59f09bb6cb2c6934ebbbb2ed8b022b137c9c04c2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#ifndef INCLUDED_IXION_CELL_HPP
#define INCLUDED_IXION_CELL_HPP

#include "types.hpp"
#include "formula_tokens_fwd.hpp"

#include <memory>
#include <vector>
#include <string>

namespace ixion {

class formula_result;
class formula_cell;
class model_context;
struct abs_address_t;
struct rc_address_t;

// calc_status is internal.
struct calc_status;
using calc_status_ptr_t = boost::intrusive_ptr<calc_status>;

class IXION_DLLPUBLIC formula_cell
{
    struct impl;
    std::unique_ptr<impl> mp_impl;

public:
    formula_cell(const formula_cell&) = delete;
    formula_cell& operator= (formula_cell) = delete;

    formula_cell();
    formula_cell(const formula_tokens_store_ptr_t& tokens);

    formula_cell(
        row_t group_row, col_t group_col,
        const calc_status_ptr_t& cs,
        const formula_tokens_store_ptr_t& tokens);

    ~formula_cell();

    const formula_tokens_store_ptr_t& get_tokens() const;
    void set_tokens(const formula_tokens_store_ptr_t& tokens);

    double get_value(formula_result_wait_policy_t policy) const;
    std::string_view get_string(formula_result_wait_policy_t policy) const;

    void interpret(model_context& context, const abs_address_t& pos);

    /**
     * Determine if this cell contains circular reference by walking through
     * all its reference tokens.
     */
    void check_circular(const model_context& cxt, const abs_address_t& pos);

    /**
     * Reset cell's internal state.
     */
    void reset();

    /**
     * Get a series of all reference tokens included in the formula
     * expression stored in this cell.
     *
     * @param cxt model context instance.
     * @param pos position of the cell.
     *
     * @return an array of reference formula tokens.  Each element is a
     *         pointer to the actual token instance stored in the cell object.
     *         Be aware that the pointer is valid only as long as the actual
     *         token instance is alive.
     */
    std::vector<const formula_token*> get_ref_tokens(
        const model_context& cxt, const abs_address_t& pos) const;

    /**
     * Get the cached result without post-processing in case of a grouped
     * formula cell.
     *
     * @param policy action to take in case the result is not yet available.
     *
     * @return formula result.
     */
    const formula_result& get_raw_result_cache(formula_result_wait_policy_t policy) const;

    /**
     * Get the cached result as a single cell.  For a non-grouped formula
     * cell, it should be identical to the value from the get_raw_result_cache()
     * call.  For a grouped formula cell, you'll get a single value assigned to
     * the position of the cell in case the original result is a matrix value.
     *
     * @param policy action to take in case the result is not yet available.
     *
     * @return formula result.
     */
    formula_result get_result_cache(formula_result_wait_policy_t policy) const;

    /**
     * Set a cached result to this formula cell instance.
     *
     *
     * @param result cached result.
     */
    void set_result_cache(formula_result result);

    formula_group_t get_group_properties() const;

    /**
     * Get the absolute parent position of a grouped formula cell.  If the
     * cell is not grouped, it simply returns the original position passed to
     * this method.
     *
     * @param pos original position from which to calculate the parent
     *            position.
     *
     * @return parent position of the grouped formula cell.
     */
    abs_address_t get_parent_position(const abs_address_t& pos) const;
};

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */