fix string view reference movement in bytecode
diff --git a/README.md b/README.md
index 746909a..181d710 100644
--- a/README.md
+++ b/README.md
@@ -82,10 +82,10 @@
 Environment env_default;
 
 // With global path to template files and where files will be saved
-Environment env_1 = Environment("../path/templates/");
+Environment env_1 {"../path/templates/"};
 
 // With separate input and output path
-Environment env_2 = Environment("../path/templates/", "../path/results/");
+Environment env_2 {"../path/templates/", "../path/results/"};
 
 // Choose between dot notation (like Jinja2) and JSON pointer to access elements
 env.set_element_notation(ElementNotation::Dot); // (default) e.g. time.start
diff --git a/include/inja/bytecode.hpp b/include/inja/bytecode.hpp
index 724f0b7..8bb2663 100644
--- a/include/inja/bytecode.hpp
+++ b/include/inja/bytecode.hpp
@@ -116,7 +116,7 @@
   uint32_t flags: 2;
 
   json value;
-  std::string_view str;
+  std::string str;
 
   Bytecode(): args(0), flags(0) {}
   explicit Bytecode(Op op, unsigned int args = 0): op(op), args(args), flags(0) {}
diff --git a/include/inja/lexer.hpp b/include/inja/lexer.hpp
index fee3e9a..cd65738 100644
--- a/include/inja/lexer.hpp
+++ b/include/inja/lexer.hpp
@@ -208,9 +208,13 @@
 
   Token scan_id() {
     for (;;) {
-      if (m_pos >= m_in.size()) break;
+      if (m_pos >= m_in.size()) {
+        break;
+      }
       char ch = m_in[m_pos];
-      if (!std::isalnum(ch) && ch != '.' && ch != '/' && ch != '_' && ch != '-') break;
+      if (!std::isalnum(ch) && ch != '.' && ch != '/' && ch != '_' && ch != '-') {
+        break;
+      }
       m_pos += 1;
     }
     return make_token(Token::Kind::Id);
@@ -218,11 +222,14 @@
 
   Token scan_number() {
     for (;;) {
-      if (m_pos >= m_in.size()) break;
+      if (m_pos >= m_in.size()) {
+        break;
+      }
       char ch = m_in[m_pos];
       // be very permissive in lexer (we'll catch errors when conversion happens)
-      if (!std::isdigit(ch) && ch != '.' && ch != 'e' && ch != 'E' && ch != '+' && ch != '-')
+      if (!std::isdigit(ch) && ch != '.' && ch != 'e' && ch != 'E' && ch != '+' && ch != '-') {
         break;
+      }
       m_pos += 1;
     }
     return make_token(Token::Kind::Number);
@@ -233,12 +240,13 @@
     for (;;) {
       if (m_pos >= m_in.size()) break;
       char ch = m_in[m_pos++];
-      if (ch == '\\')
+      if (ch == '\\') {
         escape = true;
-      else if (!escape && ch == m_in[m_tok_start])
+      } else if (!escape && ch == m_in[m_tok_start]) {
         break;
-      else
+      } else {
         escape = false;
+      }
     }
     return make_token(Token::Kind::String);
   }
diff --git a/include/inja/parser.hpp b/include/inja/parser.hpp
index f4696fa..0ca3e29 100644
--- a/include/inja/parser.hpp
+++ b/include/inja/parser.hpp
@@ -381,12 +381,6 @@
       }
       // sys::path::remove_dots(pathname, true, sys::path::Style::posix);
 
-      // parse it only if it's new
-      // TemplateStorage::iterator included;
-      // bool is_new {true};
-      // std::tie(included, is_new) = m_included_templates.emplace(pathname);
-      // if (is_new) included->second = parse_template(pathname);
-
       Template include_template = parse_template(pathname);
       m_included_templates.emplace(pathname, include_template);
 
diff --git a/include/inja/renderer.hpp b/include/inja/renderer.hpp
index f3b984d..8f868f7 100644
--- a/include/inja/renderer.hpp
+++ b/include/inja/renderer.hpp
@@ -28,18 +28,20 @@
   std::vector<const json*>& get_args(const Bytecode& bc) {
     m_tmp_args.clear();
 
-    bool hasImm = ((bc.flags & Bytecode::Flag::ValueMask) != Bytecode::Flag::ValuePop);
+    bool has_imm = ((bc.flags & Bytecode::Flag::ValueMask) != Bytecode::Flag::ValuePop);
 
     // get args from stack
     unsigned int pop_args = bc.args;
-    if (hasImm) --pop_args;
+    if (has_imm) {
+      pop_args -= 1;
+    }
 
     for (auto i = std::prev(m_stack.end(), pop_args); i != m_stack.end(); i++) {
       m_tmp_args.push_back(&(*i));
     }
 
     // get immediate arg
-    if (hasImm) {
+    if (has_imm) {
       m_tmp_args.push_back(get_imm(bc));
     }
 
@@ -48,9 +50,12 @@
 
   void pop_args(const Bytecode& bc) {
     unsigned int popArgs = bc.args;
-    if ((bc.flags & Bytecode::Flag::ValueMask) != Bytecode::Flag::ValuePop)
-      --popArgs;
-    for (unsigned int i = 0; i < popArgs; ++i) m_stack.pop_back();
+    if ((bc.flags & Bytecode::Flag::ValueMask) != Bytecode::Flag::ValuePop) {
+      popArgs -= 1;
+    }
+    for (unsigned int i = 0; i < popArgs; ++i) {
+      m_stack.pop_back();
+    }
   }
 
   const json* get_imm(const Bytecode& bc) {
@@ -169,11 +174,13 @@
       const auto& bc = tmpl.bytecodes[i];
 
       switch (bc.op) {
-        case Bytecode::Op::Nop:
+        case Bytecode::Op::Nop: {
           break;
-        case Bytecode::Op::PrintText:
+        }
+        case Bytecode::Op::PrintText: {
           os << bc.str;
           break;
+        }
         case Bytecode::Op::PrintValue: {
           const json& val = *get_args(bc)[0];
           if (val.is_string())
@@ -184,9 +191,10 @@
           pop_args(bc);
           break;
         }
-        case Bytecode::Op::Push:
+        case Bytecode::Op::Push: {
           m_stack.emplace_back(*get_imm(bc));
           break;
+        }
         case Bytecode::Op::Upper: {
           auto result = get_args(bc)[0]->get<std::string>();
           std::transform(result.begin(), result.end(), result.begin(), ::toupper);
@@ -443,9 +451,10 @@
           m_stack.emplace_back(std::move(result));
           break;
         }
-        case Bytecode::Op::Jump:
+        case Bytecode::Op::Jump: {
           i = bc.args - 1;  // -1 due to ++i in loop
           break;
+        }
         case Bytecode::Op::ConditionalJump: {
           if (!truthy(m_stack.back())) {
             i = bc.args - 1;  // -1 due to ++i in loop
diff --git a/include/inja/template.hpp b/include/inja/template.hpp
index c40cda3..2e171e1 100644
--- a/include/inja/template.hpp
+++ b/include/inja/template.hpp
@@ -9,29 +9,9 @@
 
 namespace inja {
 
-class Template {
-  friend class Parser;
-  friend class Renderer;
-
+struct Template {
   std::vector<Bytecode> bytecodes;
   std::string content;
-
- public:
-  Template() {}
-  Template(const Template& oth): bytecodes(oth.bytecodes), content(oth.content) {}
-  Template(Template&& oth): bytecodes(std::move(oth.bytecodes)), content(std::move(oth.content)) {}
-
-  Template& operator=(const Template& oth) {
-    bytecodes = oth.bytecodes;
-    content = oth.content;
-    return *this;
-  }
-
-  Template& operator=(Template&& oth) {
-    bytecodes = std::move(oth.bytecodes);
-    content = std::move(oth.content);
-    return *this;
-  }
 };
 
 using TemplateStorage = std::map<std::string, Template>;
diff --git a/test/unit-files.cpp b/test/unit-files.cpp
index dab55fc..25d3ca4 100644
--- a/test/unit-files.cpp
+++ b/test/unit-files.cpp
@@ -5,26 +5,28 @@
 using json = nlohmann::json;
 
 
+const std::string test_file_directory {"../test/data/"};
+
 TEST_CASE("loading") {
-	inja::Environment env = inja::Environment();
+	inja::Environment env;
 	json data;
 	data["name"] = "Jeff";
 
 	SECTION("Files should be loaded") {
-		CHECK( env.load_file("../test/data/simple.txt") == "Hello {{ name }}." );
+		CHECK( env.load_file(test_file_directory + "simple.txt") == "Hello {{ name }}." );
 	}
 
 	SECTION("Files should be rendered") {
-		CHECK( env.render_file("../test/data/simple.txt", data) == "Hello Jeff." );
+		CHECK( env.render_file(test_file_directory + "simple.txt", data) == "Hello Jeff." );
 	}
 
 	SECTION("File includes should be rendered") {
-		CHECK( env.render_file("../test/data/include.txt", data) == "Answer: Hello Jeff." );
+		CHECK( env.render_file(test_file_directory + "include.txt", data) == "Answer: Hello Jeff." );
 	}
 }
 
 TEST_CASE("complete-files") {
-	inja::Environment env = inja::Environment("../test/data/");
+	inja::Environment env {test_file_directory};
 
 	for (std::string test_name : {"simple-file", "nested", "nested-line", "html"}) {
 		SECTION(test_name) {
@@ -34,8 +36,8 @@
 }
 
 TEST_CASE("global-path") {
-	inja::Environment env = inja::Environment("../test/data/", "./");
-	inja::Environment env_result = inja::Environment("./");
+	inja::Environment env {test_file_directory, "./"};
+	inja::Environment env_result {"./"};
 	json data;
 	data["name"] = "Jeff";
 
diff --git a/test/unit-renderer.cpp b/test/unit-renderer.cpp
index 12c223a..e78127a 100644
--- a/test/unit-renderer.cpp
+++ b/test/unit-renderer.cpp
@@ -43,6 +43,7 @@
 		CHECK( env.render("Hello {{ names.1 }}!", data) == "Hello Seb!" );
 		CHECK( env.render("Hello {{ brother.name }}!", data) == "Hello Chris!" );
 		CHECK( env.render("Hello {{ brother.daughter0.name }}!", data) == "Hello Maria!" );
+		CHECK( env.render("{{ \"{{ no_value }}\" }}", data) == "{{ no_value }}" );
 
 		CHECK_THROWS_WITH( env.render("{{unknown}}", data), "[inja.exception.render_error] variable 'unknown' not found" );
 	}
@@ -215,6 +216,7 @@
 		CHECK( env.render("{{ default(nothing, 0) }}", data) == "0" );
 		CHECK( env.render("{{ default(name, \"nobody\") }}", data) == "Peter" );
 		CHECK( env.render("{{ default(surname, \"nobody\") }}", data) == "nobody" );
+		CHECK( env.render("{{ default(surname, \"{{ surname }}\") }}", data) == "{{ surname }}" );
 		CHECK_THROWS_WITH( env.render("{{ default(surname, lastname) }}", data), "[inja.exception.render_error] variable 'lastname' not found" );
 	}