1 #ifndef CPPAD_CG_OPERATION_STACK_HPP 2 #define CPPAD_CG_OPERATION_STACK_HPP 24 enum class StackNavigationStep {
43 size_t nodeIndex) noexcept :
56 inline size_t argumentIndex()
const {
69 size_t parentNodeScope;
70 StackNavigationStep nextStep;
74 size_t parentNodeScope) noexcept :
76 parentNodeScope(parentNodeScope),
77 nextStep(StackNavigationStep::Analyze) {
87 template<
class Element>
90 std::vector<Element> _stack;
96 inline bool empty()
const {
97 return _stack.empty();
100 inline size_t size()
const {
101 return _stack.size();
104 inline void pop_back() {
108 inline Element& back() {
109 return _stack.back();
112 template<
class... Args>
113 inline void emplace_back(Args&&... args) {
114 if (_stack.size() == _stack.capacity()) {
115 _stack.reserve((_stack.size() * 3) / 2 + 1);
117 _stack.emplace_back(std::forward<Args>(args)...);
120 inline Element& operator[](
size_t i) {
129 size_t parentNodeScope) {
133 for (
auto itArg = args.rbegin(); itArg != args.rend(); ++itArg) {
134 if (itArg->getOperation() !=
nullptr) {
135 size_t index = std::distance(begin(args), itArg.base()) - 1;
136 this->emplace_back(node, index, parentNodeScope);
149 for (
auto itArg = args.rbegin(); itArg != args.rend(); ++itArg) {
150 if (itArg->getOperation() !=
nullptr) {
151 size_t index = std::distance(begin(args), itArg.base()) - 1;
152 this->emplace_back(node, index);
177 template<
class Base,
typename FunctionAnalysis,
typename FunctionPostProcess>
179 size_t currentScopeColor,
180 FunctionAnalysis& nodeAnalysis,
181 FunctionPostProcess& nodePostProcessAnalysis,
185 std::unique_ptr<OperationNode<Base>> fakeSuperRoot;
188 stack.emplace_back(*fakeSuperRoot, 0, currentScopeColor);
190 stack.pushNodeArguments(root, currentScopeColor);
193 while (!stack.empty()) {
195 if (stack.back().nextStep == StackNavigationStep::Analyze) {
196 size_t i = stack.size() - 1;
198 bool complete = nodeAnalysis(stack[i], stack);
201 stack[i].nextStep = StackNavigationStep::ChildrenVisited;
203 stack[i].nextStep = StackNavigationStep::Exit;
205 }
else if (stack.back().nextStep == StackNavigationStep::ChildrenVisited) {
206 nodePostProcessAnalysis(stack.back());
207 stack.back().nextStep = StackNavigationStep::Exit;
230 template<
class Base,
typename FunctionAnalysis>
232 FunctionAnalysis& nodeAnalysis,
236 std::unique_ptr<OperationNode<Base>> fakeSuperRoot;
239 stack.emplace_back(*fakeSuperRoot, 0);
241 stack.pushNodeArguments(root);
244 while (!stack.empty()) {
245 auto nodeEl = stack.back();
248 nodeAnalysis(nodeEl, stack);
const std::vector< Argument< Base > > & getArguments() const
static std::unique_ptr< OperationNode< Base > > makeTemporaryNode(CGOpCode op, const std::vector< size_t > &info, const std::vector< Argument< Base > > &args)