literal.hpp 1.85 KB
Newer Older
Paul's avatar
Paul committed
1
2
3
4
#ifndef GUARD_RTGLIB_LITERAL_HPP
#define GUARD_RTGLIB_LITERAL_HPP

#include <rtg/shape.hpp>
Paul's avatar
Paul committed
5
#include <rtg/argument.hpp>
Paul's avatar
Paul committed
6
#include <rtg/tensor_view.hpp>
Paul's avatar
Paul committed
7
#include <rtg/raw_data.hpp>
Paul's avatar
Paul committed
8
9
10

namespace rtg {

Paul's avatar
Paul committed
11
struct literal : raw_data<literal>
Paul's avatar
Paul committed
12
{
Paul's avatar
Paul committed
13
    literal() : buffer(), shape_() {}
Paul's avatar
Paul committed
14

Paul's avatar
Paul committed
15
16
    template <class T>
    literal(T x) : buffer(sizeof(T), 0), shape_(shape::get_type<T>{})
Paul's avatar
Paul committed
17
18
19
20
21
    {
        static_assert(std::is_trivial<T>{}, "Literals can only be trivial types");
        *(reinterpret_cast<T*>(buffer.data())) = x;
    }

Paul's avatar
Paul committed
22
23
    template <class T>
    literal(shape s, const std::vector<T>& x) : buffer(s.bytes(), 0), shape_(s)
Paul's avatar
Paul committed
24
    {
Paul's avatar
Paul committed
25
26
        assert(s.packed());
        static_assert(std::is_trivial<T>{}, "Literals can only be trivial types");
Paul's avatar
Paul committed
27
        s.visit_type([&](auto as) { std::copy(x.begin(), x.end(), as.from(buffer.data())); });
Paul's avatar
Paul committed
28
29
    }

Paul's avatar
Paul committed
30
31
    template <class T>
    literal(shape s, const std::initializer_list<T>& x) : buffer(s.bytes(), 0), shape_(s)
Paul's avatar
Paul committed
32
33
    {
        assert(s.packed());
Paul's avatar
Paul committed
34
        static_assert(std::is_trivial<T>{}, "Literals can only be trivial types");
Paul's avatar
Paul committed
35
        s.visit_type([&](auto as) { std::copy(x.begin(), x.end(), as.from(buffer.data())); });
Paul's avatar
Paul committed
36
37
    }

Paul's avatar
Paul committed
38
39
    template <class Iterator>
    literal(shape s, Iterator start, Iterator end) : buffer(s.bytes(), 0), shape_(s)
Paul's avatar
Paul committed
40
41
    {
        assert(s.packed());
Paul's avatar
Paul committed
42
        s.visit_type([&](auto as) { std::copy(start, end, as.from(buffer.data())); });
Paul's avatar
Paul committed
43
44
    }

Paul's avatar
Paul committed
45
    literal(shape s, const char* x) : buffer(x, x + s.bytes()), shape_(s) {}
Paul's avatar
Paul committed
46

Paul's avatar
Paul committed
47
    bool empty() const { return this->buffer.empty(); }
Paul's avatar
Paul committed
48

Paul's avatar
Paul committed
49
50
51
    const char* data() const { return this->buffer.data(); }

    const shape& get_shape() const { return this->shape_; }
Paul's avatar
Paul committed
52

Paul's avatar
Paul committed
53
54
55
    argument get_argument() const
    {
        auto b = buffer;
Paul's avatar
Paul committed
56
        return {shape_, [b]() mutable { return b.data(); }};
Paul's avatar
Paul committed
57
58
    }

Paul's avatar
Paul committed
59
    private:
Paul's avatar
Paul committed
60
61
62
63
    std::vector<char> buffer;
    shape shape_;
};

Paul's avatar
Paul committed
64
} // namespace rtg
Paul's avatar
Paul committed
65
66

#endif