--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __GRAPH_BUILDER_H__
+#define __GRAPH_BUILDER_H__
+
+// loco-internal headers
+#include "loco/IR/Graph.h"
+
+// repo-internal headers
+#include <stdex/Memory.h>
+
+// C++ standard headers
+#include <stack>
+
+//
+// This file includes a stack-based loco graph builder
+//
+// HOW TO USE
+//
+// loco::Graph *g = ...
+// auto builder = make_graph_builder(g);
+//
+// builder->push<YourAwesomeLayer>(...);
+//
+
+class GraphBuilder final
+{
+public:
+ class Stack final
+ {
+ public:
+ Stack() = default;
+
+ public:
+ loco::Node *top(void) const { return _content.top(); }
+
+ public:
+ loco::Node *pop(void)
+ {
+ auto ret = top();
+ _content.pop();
+ return ret;
+ }
+
+ public:
+ void push(loco::Node *node) { _content.push(node); }
+
+ private:
+ std::stack<loco::Node *> _content;
+ };
+
+ class Context final
+ {
+ public:
+ Context(loco::Graph *graph) : _graph{graph}
+ {
+ // DO NOTHING
+ }
+
+ public:
+ loco::Graph *graph(void) { return _graph; }
+ Stack *stack(void) { return &_stack; }
+
+ private:
+ loco::Graph *_graph = nullptr;
+ Stack _stack;
+ };
+
+public:
+ GraphBuilder(loco::Graph *graph) : _context{graph}
+ {
+ // DO NOTHING
+ }
+
+public:
+ // "Layer" is in theory a subgraph builder.
+ template <typename Layer, typename... Args>
+ auto push(Args &&... args)
+ -> decltype(static_cast<Layer *>(nullptr)->operator()(static_cast<Context *>(nullptr)))
+ {
+ Layer layer{std::forward<Args>(args)...};
+ return layer(ctx());
+ }
+
+public:
+ loco::Node *pop(void) { return ctx()->stack()->pop(); }
+
+private:
+ Context *ctx(void) { return &_context; }
+
+private:
+ Context _context;
+};
+
+static inline std::unique_ptr<GraphBuilder> make_graph_builder(loco::Graph *g)
+{
+ return stdex::make_unique<GraphBuilder>(g);
+}
+
+#endif // __GRAPH_BUILDER_H__
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd. All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "GraphBuilder.h"
+
+#include "loco/IR/Nodes.h"
+#include "loco/IR/CanonicalDialect.h"
+#include "loco/IR/CanonicalOpcode.h"
+
+#include <gtest/gtest.h>
+
+TEST(GraphBuilderTest, Usecase_000)
+{
+ struct SampleLayer final
+ {
+ loco::Node *operator()(GraphBuilder::Context *ctx)
+ {
+ auto node = ctx->graph()->nodes()->create<loco::ConstGen>();
+ ctx->stack()->push(node);
+ return node;
+ }
+ };
+
+ auto g = loco::make_graph();
+ auto gbuilder = make_graph_builder(g.get());
+
+ gbuilder->push<SampleLayer>();
+
+ auto node = gbuilder->pop();
+
+ ASSERT_EQ(g->nodes()->size(), 1);
+ ASSERT_EQ(node->dialect(), loco::CanonicalDialect::get());
+ ASSERT_EQ(node->opnum(), static_cast<uint32_t>(loco::CanonicalOpcode::ConstGen));
+}