solinject
1.0.0
C++17 Dependency Injection header-only library
|
Go to the documentation of this file.
50 Token token(impl::TokenType::Key,
"");
52 while (GetNextToken(token))
54 auto configurationItems = ParseConfigurationItem(token);
56 for (
auto&& item : configurationItems)
67 using byte =
unsigned char;
84 bool IsEndOfInput() {
return m_Pos >= m_Input.
size(); }
88 void Skip(
size_t bytesCount = 1)
98 if (m_Input.
size() <= 3)
101 byte bom[] = { 0xEF, 0xBB, 0xBF };
109 size_t GetCodepointSize()
111 byte firstByte = m_Input[m_Pos];
113 if ((firstByte & 0b1000
'0000u) == 0)
115 else if ((firstByte & 0b1110'0000u) == 0b1100
'0000u)
117 else if ((firstByte & 0b1111'0000u) == 0b1110
'0000u)
119 else if ((firstByte & 0b1111'1000u) == 0b1111
'0000u)
122 throw std::runtime_error("Invalid UTF8 character");
128 void ResetStateAndReturnToken(Token& token, bool skipTypeGuess = false)
130 using namespace impl;
133 if (m_Lexem == "Self")
134 m_CurrentType = TokenType::Self;
135 else if (m_Lexem == "Singleton")
136 m_CurrentType = TokenType::Singleton;
137 else if (m_Lexem == "Transient")
138 m_CurrentType = TokenType::Transient;
139 else if (m_Lexem == "Shared")
140 m_CurrentType = TokenType::Shared;
141 else if (m_Lexem == "Scoped")
142 m_CurrentType = TokenType::Scoped;
143 else if (m_Lexem == "None")
144 m_CurrentType = TokenType::None;
146 token = Token(m_CurrentType, m_Lexem);
148 m_CurrentType = TokenType::Key;
155 while (!IsEndOfInput())
157 size_t codepointSize = GetCodepointSize();
159 if (codepointSize > 1)
166 byte codepoint = m_Input[m_Pos];
170 if (codepoint == '\n
')
177 void TokenizeQuotedLiteral()
181 while (!IsEndOfInput())
183 size_t codepointSize = GetCodepointSize();
185 if (codepointSize > 1)
187 m_Lexem.append(m_Input.data() + m_Pos, codepointSize);
188 Skip(codepointSize - 1);
192 byte codepoint = m_Input[m_Pos];
196 if (codepoint == '\
"')
199 m_Lexem += codepoint;
203 m_CurrentType = impl::TokenType::Key;
207 void TokenizeEscapedCharacter()
211 size_t codepointSize = GetCodepointSize();
213 m_Lexem.append(m_Input.data() + m_Pos, codepointSize);
214 Skip(codepointSize - 1);
220 bool GetNextToken(Token& token)
222 using namespace impl;
224 for (; !IsEndOfInput(); m_Pos++)
226 size_t codepointSize = GetCodepointSize();
227 if (codepointSize > 1)
229 m_Lexem.append(m_Input.data() + m_Pos, codepointSize);
230 Skip(codepointSize - 1);
234 byte codepoint = m_Input[m_Pos];
239 TokenizeQuotedLiteral();
240 ResetStateAndReturnToken(token, true);
244 TokenizeEscapedCharacter();
252 ResetStateAndReturnToken(token);
261 ResetStateAndReturnToken(token);
272 ResetStateAndReturnToken(token);
276 token = Token(TokenType::OpeningCurlyBracket, "");
283 ResetStateAndReturnToken(token);
287 token = Token(TokenType::ClosingCurlyBracket, "");
292 m_Lexem += codepoint;
300 ResetStateAndReturnToken(token);
310 std::vector<ConfigurationItem> ParseConfigurationItem(const Token& initialToken)
312 using namespace impl;
314 solinject_req_assert(initialToken.Type() == TokenType::Key);
316 std::string interfaceKey = initialToken.Content();
317 std::vector<ConfigurationItem> result;
318 Token token(TokenType::Key, "");
320 if (!GetNextToken(token))
321 throw std::runtime_error("Unexpected end of input
");
323 switch (token.Type())
326 case TokenType::Self:
328 ParseImplementationRegistration(interfaceKey, token)
331 case TokenType::OpeningCurlyBracket:
332 result = ParseMultipleImplementationRegistrations(interfaceKey);
343 ConfigurationItem ParseImplementationRegistration(std::string interfaceKey, const Token& initialToken)
345 using namespace impl;
348 initialToken.Type() == TokenType::Key ||
349 initialToken.Type() == TokenType::Self
352 std::string implementationKey;
354 switch (initialToken.Type())
357 implementationKey = initialToken.Content();
359 case TokenType::Self:
360 implementationKey = interfaceKey;
363 using namespace std::string_literals;
364 throw std::runtime_error("Unexpected token:
"s + initialToken.Content());
367 Token token(TokenType::Key, "");
369 if (!GetNextToken(token))
370 throw std::runtime_error("Unexpected end of input
");
372 ServiceLifetime lifetime = ServiceLifetime::Singleton;
374 switch (token.Type())
376 case TokenType::Singleton:
377 lifetime = ServiceLifetime::Singleton;
380 case TokenType::Transient:
381 lifetime = ServiceLifetime::Transient;
384 case TokenType::Shared:
385 lifetime = ServiceLifetime::Shared;
388 case TokenType::Scoped:
389 lifetime = ServiceLifetime::Scoped;
393 using namespace std::string_literals;
394 throw std::runtime_error("Unexpected token:
"s + token.Content());
397 return ConfigurationItem(interfaceKey, implementationKey, lifetime);
403 std::vector<ConfigurationItem> ParseMultipleImplementationRegistrations(std::string interfaceKey)
405 using namespace impl;
407 Token token(TokenType::Key, "");
408 std::vector<ConfigurationItem> result;
410 while(GetNextToken(token))
412 if (token.Type() == TokenType::ClosingCurlyBracket)
416 ParseImplementationRegistration(interfaceKey, token)
Configuration Parse(const std::string &input)
Parses configuration.
Definition: ConfigurationParser.hpp:42
TokenType
sol::di::impl::ConfigurationParserToken type
Definition: ConfigurationParserToken.hpp:29
DI Configuration parser.
Definition: ConfigurationParser.hpp:36
#define solinject_req_assert(expression)
Required assert, which is disabled only when the assert() macro from assert.h is disabled.
Definition: Defines.hpp:41
void AddConfigurationItem(ConfigurationItem item)
Adds a configuration item.
Definition: Configuration.hpp:80
ConfigurationParser token
Definition: ConfigurationParserToken.hpp:43
DI configuration.
Definition: Configuration.hpp:31