constantify
diff --git a/include/inja/exceptions.hpp b/include/inja/exceptions.hpp
index 2cf89f6..2784da8 100644
--- a/include/inja/exceptions.hpp
+++ b/include/inja/exceptions.hpp
@@ -14,10 +14,10 @@
 };
 
 struct InjaError : public std::runtime_error {
-  std::string type;
-  std::string message;
+  const std::string type;
+  const std::string message;
 
-  SourceLocation location;
+  const SourceLocation location;
 
   explicit InjaError(const std::string &type, const std::string &message)
       : std::runtime_error("[inja.exception." + type + "] " + message), type(type), message(message), location({0, 0}) {}
diff --git a/include/inja/function_storage.hpp b/include/inja/function_storage.hpp
index 7767f9b..a0b62b2 100644
--- a/include/inja/function_storage.hpp
+++ b/include/inja/function_storage.hpp
@@ -69,14 +69,14 @@
     None,
   };
 
-  const int VARIADIC {-1};
-
   struct FunctionData {
-    Operation operation;
-
-    CallbackFunction callback;
+    const Operation operation;
+    const CallbackFunction callback;
   };
 
+private:
+  const int VARIADIC {-1};
+
   std::map<std::pair<std::string, int>, FunctionData> function_storage = {
     {std::make_pair("at", 2), FunctionData { Operation::At }},
     {std::make_pair("default", 2), FunctionData { Operation::Default }},
diff --git a/include/inja/node.hpp b/include/inja/node.hpp
index 2beadfd..84a8b8a 100644
--- a/include/inja/node.hpp
+++ b/include/inja/node.hpp
@@ -76,7 +76,7 @@
 
 class TextNode : public AstNode {
 public:
-  size_t length;
+  const size_t length;
 
   explicit TextNode(size_t pos, size_t length): AstNode(pos), length(length) { }
 
@@ -96,7 +96,7 @@
 
 class LiteralNode : public ExpressionNode {
 public:
-  nlohmann::json value;
+  const nlohmann::json value;
 
   explicit LiteralNode(const nlohmann::json& value, size_t pos) : ExpressionNode(pos), value(value) { }
 
@@ -107,8 +107,8 @@
 
 class JsonNode : public ExpressionNode {
 public:
-  std::string name;
-  json::json_pointer ptr;
+  const std::string name;
+  const json::json_pointer ptr;
 
   static std::string convert_dot_to_json_ptr(nonstd::string_view ptr_name) {
     std::string result;
@@ -261,7 +261,7 @@
 
 class ForArrayStatementNode : public ForStatementNode {
 public:
-  std::string value;
+  const std::string value;
 
   explicit ForArrayStatementNode(const std::string& value, BlockNode *const parent, size_t pos) : ForStatementNode(parent, pos), value(value) { }
 
@@ -272,8 +272,8 @@
 
 class ForObjectStatementNode : public ForStatementNode {
 public:
-  std::string key;
-  std::string value;
+  const std::string key;
+  const std::string value;
 
   explicit ForObjectStatementNode(const std::string& key, const std::string& value, BlockNode *const parent, size_t pos) : ForStatementNode(parent, pos), key(key), value(value) { }
 
@@ -289,7 +289,7 @@
   BlockNode false_statement;
   BlockNode *const parent;
 
-  bool is_nested;
+  const bool is_nested;
   bool has_false_statement {false};
 
   explicit IfStatementNode(BlockNode *const parent, size_t pos) : StatementNode(pos), parent(parent), is_nested(false) { }
@@ -302,7 +302,7 @@
 
 class IncludeStatementNode : public StatementNode {
 public:
-  std::string file;
+  const std::string file;
 
   explicit IncludeStatementNode(const std::string& file, size_t pos) : StatementNode(pos), file(file) { }
 
@@ -313,7 +313,7 @@
 
 class SetStatementNode : public StatementNode {
 public:
-  std::string key;
+  const std::string key;
   ExpressionListNode expression;
 
   explicit SetStatementNode(const std::string& key, size_t pos) : StatementNode(pos), key(key) { }
diff --git a/single_include/inja/inja.hpp b/single_include/inja/inja.hpp
index d7aec6d..d5ab05e 100644
--- a/single_include/inja/inja.hpp
+++ b/single_include/inja/inja.hpp
@@ -1582,14 +1582,14 @@
     None,
   };
 
-  const int VARIADIC {-1};
-
   struct FunctionData {
-    Operation operation;
-
-    CallbackFunction callback;
+    const Operation operation;
+    const CallbackFunction callback;
   };
 
+private:
+  const int VARIADIC {-1};
+
   std::map<std::pair<std::string, int>, FunctionData> function_storage = {
     {std::make_pair("at", 2), FunctionData { Operation::At }},
     {std::make_pair("default", 2), FunctionData { Operation::Default }},
@@ -1681,10 +1681,10 @@
 };
 
 struct InjaError : public std::runtime_error {
-  std::string type;
-  std::string message;
+  const std::string type;
+  const std::string message;
 
-  SourceLocation location;
+  const SourceLocation location;
 
   explicit InjaError(const std::string &type, const std::string &message)
       : std::runtime_error("[inja.exception." + type + "] " + message), type(type), message(message), location({0, 0}) {}
@@ -2356,7 +2356,7 @@
 
 class TextNode : public AstNode {
 public:
-  size_t length;
+  const size_t length;
 
   explicit TextNode(size_t pos, size_t length): AstNode(pos), length(length) { }
 
@@ -2376,7 +2376,7 @@
 
 class LiteralNode : public ExpressionNode {
 public:
-  nlohmann::json value;
+  const nlohmann::json value;
 
   explicit LiteralNode(const nlohmann::json& value, size_t pos) : ExpressionNode(pos), value(value) { }
 
@@ -2387,8 +2387,8 @@
 
 class JsonNode : public ExpressionNode {
 public:
-  std::string name;
-  json::json_pointer ptr;
+  const std::string name;
+  const json::json_pointer ptr;
 
   static std::string convert_dot_to_json_ptr(nonstd::string_view ptr_name) {
     std::string result;
@@ -2541,7 +2541,7 @@
 
 class ForArrayStatementNode : public ForStatementNode {
 public:
-  std::string value;
+  const std::string value;
 
   explicit ForArrayStatementNode(const std::string& value, BlockNode *const parent, size_t pos) : ForStatementNode(parent, pos), value(value) { }
 
@@ -2552,8 +2552,8 @@
 
 class ForObjectStatementNode : public ForStatementNode {
 public:
-  std::string key;
-  std::string value;
+  const std::string key;
+  const std::string value;
 
   explicit ForObjectStatementNode(const std::string& key, const std::string& value, BlockNode *const parent, size_t pos) : ForStatementNode(parent, pos), key(key), value(value) { }
 
@@ -2569,7 +2569,7 @@
   BlockNode false_statement;
   BlockNode *const parent;
 
-  bool is_nested;
+  const bool is_nested;
   bool has_false_statement {false};
 
   explicit IfStatementNode(BlockNode *const parent, size_t pos) : StatementNode(pos), parent(parent), is_nested(false) { }
@@ -2582,7 +2582,7 @@
 
 class IncludeStatementNode : public StatementNode {
 public:
-  std::string file;
+  const std::string file;
 
   explicit IncludeStatementNode(const std::string& file, size_t pos) : StatementNode(pos), file(file) { }
 
@@ -2593,7 +2593,7 @@
 
 class SetStatementNode : public StatementNode {
 public:
-  std::string key;
+  const std::string key;
   ExpressionListNode expression;
 
   explicit SetStatementNode(const std::string& key, size_t pos) : StatementNode(pos), key(key) { }