File: notated_num.cpp

package info (click to toggle)
satdump 1.2.2%2Bgb79af48-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 81,648 kB
  • sloc: cpp: 276,768; ansic: 164,598; lisp: 1,219; sh: 283; xml: 106; makefile: 7
file content (107 lines) | stat: -rw-r--r-- 2,906 bytes parent folder | download | duplicates (2)
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
#include <regex>
#include "common/rimgui.h"
#include "common/dsp_source_sink/format_notated.h"
#include "logger.h"
#include "notated_num.h"

namespace widgets
{
    template <typename T>
    NotatedNum<T>::NotatedNum(std::string d_id, T input_int, std::string units) : val{input_int}, d_id{d_id}, units{units}
    {
        last_display = display_val = format_notated(val, units);
    }

    template <typename T>
    NotatedNum<T>::~NotatedNum()
    {
    }

    template <typename T>
    void NotatedNum<T>::parse_input()
    {
        // Clean up string
        display_val.erase(std::remove_if(display_val.begin(), display_val.end(), ::isspace), display_val.end());
        std::regex regexp(units, std::regex_constants::icase);
        display_val = std::regex_replace(display_val, regexp, "");

        // Sanity check
        if (display_val.empty())
        {
            display_val = last_display;
            return;
        }

        // Get order of magnitude suffix, if present
        T multiplier = 1;
        bool had_suffix = true;
        const char suffix = toupper(display_val.back());
        if (suffix == 'K')
            multiplier = 1e3;
        else if (suffix == 'M')
            multiplier = 1e6;
        else if (suffix == 'G')
            multiplier = 1e9;
        else if constexpr (std::is_same<T, int32_t>::value)
            had_suffix = false;
        else
        {
            if (suffix == 'T')
                multiplier = 1e12;
            else if (suffix == 'P')
                multiplier = 1e15;
            else
                had_suffix = false;
        }

        // Remove suffix
        if (had_suffix)
            display_val.pop_back();

        // Try to parse the rest of it as a number
        T decoded_int;
        try
        {
            decoded_int = std::stod(display_val) * multiplier;
        }
        catch (std::exception &e)
        {
            logger->trace("Ignoring bad int input - " + std::string(e.what()));
            display_val = last_display;
            return;
        }

        // Value is good - update and re-render
        val = decoded_int;
        last_display = display_val = format_notated(val, units);
    }

    template <typename T>
    bool NotatedNum<T>::draw()
    {
        RImGui::InputText(d_id.c_str(), &display_val, ImGuiInputTextFlags_AutoSelectAll);
        bool retval = RImGui::IsItemDeactivatedAfterEdit();
        if (retval)
            parse_input();

        return retval;
    }

    template <typename T>
    T NotatedNum<T>::get()
    {
        return val;
    }

    template <typename T>
    void NotatedNum<T>::set(T input_int)
    {
        val = input_int;
        last_display = display_val = format_notated(val, units);
    }

    template class NotatedNum<int>;
    template class NotatedNum<uint64_t>;
    template class NotatedNum<int64_t>;
    template class NotatedNum<double>;
}