CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
lang_stream_stack.hpp
1#ifndef CPPAD_CG_LANG_STREAM_STACK_INCLUDED
2#define CPPAD_CG_LANG_STREAM_STACK_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2019 Joao Leal
6 *
7 * CppADCodeGen is distributed under multiple licenses:
8 *
9 * - Eclipse Public License Version 1.0 (EPL1), and
10 * - GNU General Public License Version 3 (GPL3).
11 *
12 * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13 * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14 * ----------------------------------------------------------------------------
15 * Author: Joao Leal
16 */
17
18#include <ostream>
19
20namespace CppAD {
21namespace cg {
22
23namespace _private {
24
25template<class Base>
27private:
29 std::string _text;
30public:
32 _node(&node) {
33 }
34
35 inline LangStreamOperation(std::string text) :
36 _node(nullptr),
37 _text(std::move(text)) {
38 }
39
40 OperationNode<Base>* getNode() const {
41 return _node;
42 }
43
44 const std::string& getText() const {
45 return _text;
46 }
47};
48
49}
50
57template<class Base>
59private:
60 std::ostream& _out;
61 std::forward_list<_private::LangStreamOperation<Base> > _cache;
62 typename std::forward_list<_private::LangStreamOperation<Base> >::iterator _it;
63public:
64 inline LangStreamStack(std::ostream& out) :
65 _out(out),
66 _it(_cache.before_begin()) {
67 }
68
69 inline bool empty() const {
70 return _cache.empty();
71 }
72
73 inline void clear() {
74 _cache.clear();
75 _it = _cache.before_begin();
76 }
77
78 inline void flush() {
79 if (empty())
80 return;
81
82 while (!_cache.empty() && _cache.begin()->getNode() == nullptr) {
83 _out << _cache.begin()->getText();
84 _cache.erase_after(_cache.before_begin());
85 }
86 _it = _cache.before_begin();
87 }
88
89 inline OperationNode<Base>& startNewOperationNode() {
90 CPPAD_ASSERT_KNOWN(!_cache.empty(), "Cannot extract an operation node from an empty list")
91 CPPAD_ASSERT_KNOWN(_cache.begin()->getNode() != nullptr, "The first element in the list is not an OperationNode")
92 OperationNode<Base>* node = _cache.begin()->getNode();
93 _cache.erase_after(_cache.before_begin());
94 _it = _cache.before_begin();
95
96 return *node;
97 }
98
99 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, std::string text) {
100 if (lss._it == lss._cache.before_begin()) {
101 lss._out << text;
102 } else {
103 lss._it = lss._cache.emplace_after(lss._it, std::move(text));
104 }
105 return lss;
106 }
107
108 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, int i) {
109 return (lss << std::to_string(i));
110 }
111
112 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, long int i) {
113 return (lss << std::to_string(i));
114 }
115
116 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, long long int i) {
117 return (lss << std::to_string(i));
118 }
119
120 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, unsigned int i) {
121 return (lss << std::to_string(i));
122 }
123
124 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, long unsigned int i) {
125 return (lss << std::to_string(i));
126 }
127
128 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, long long unsigned int i) {
129 return (lss << std::to_string(i));
130 }
131
132 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, char text) {
133 return (lss << std::string(1, text));
134 }
135
136 friend inline LangStreamStack<Base>& operator<<(LangStreamStack<Base>& lss, OperationNode<Base>& node) {
137 lss._it = lss._cache.emplace_after(lss._it, node);
138
139 return lss;
140 }
141};
142
143} // END cg namespace
144} // END CppAD namespace
145
146#endif