initial import

This commit is contained in:
Evgenii Alekseev 2017-10-22 04:43:17 +03:00
parent 7a4647371b
commit de94719320
5 changed files with 326 additions and 0 deletions

66
.clang-format Normal file
View File

@ -0,0 +1,66 @@
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: true
AlignConsecutiveAssignments: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: Linux
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
TabWidth: 8
UseTab: Never
...

13
AUTHORS Normal file
View File

@ -0,0 +1,13 @@
Current developers:
Evgeniy Alekseev aka arcanis <esalexeev (at) gmail (dot) com>
Packagers:
Konstantin Voinov (openSuSe)
Translators:
@Mermouy (French)
Ernesto Avilés Vzqz (Spanish)
@underr (Brazillian Portuguese)
Виктор Слободян (Ukrainian)
Steve Lemuel (Chinese)
Mariusz Kocoń (Polish)

21
COPYING Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Evgeniy Alekseev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

68
README.md Normal file
View File

@ -0,0 +1,68 @@
# result
Simple header-only variant-driven C++17 `Result<T,E>` implementation.
## Requirements
* c++17 or c++1z with support of variant
## Usage example
```cpp
#include <cassert>
#include <iostream>
#include "result.h"
using namespace std::string_literals;
enum class ErrorCode { Error };
using IError = Result::Error<ErrorCode>;
template <class T> using IResult = Result::Result<T, ErrorCode>;
class Test
{
public:
Test() = default;
~Test() = default;
friend std::ostream &operator<<(std::ostream &os, const Test &)
{
os << "I'm test class";
return os;
};
};
template <class T> Result::Content print_example(IResult<T> r)
{
switch (r.type()) {
case Result::Content::Value:
std::cout << "Result has value " << r.get() << std::endl;
return Result::Content::Value;
case Result::Content::Error:
std::cout << "Result has error " << r.error().message() << std::endl;
return Result::Content::Error;
case Result::Content::Empty:
std::cout << "Result does not contain anything" << std::endl;
return Result::Content::Empty;
}
}
int main()
{
assert(print_example<int>(42) == Result::Content::Value);
assert(print_example<int>(IError("int error"s)) == Result::Content::Error);
assert(print_example<std::string>("a string"s) == Result::Content::Value);
assert(print_example<std::string>(IError("std::string error"s))
== Result::Content::Error);
assert(print_example<Test>(Test()) == Result::Content::Value);
assert(print_example<Test>(IError("Test error"s))
== Result::Content::Error);
return 0;
}
```

158
result.hpp Normal file
View File

@ -0,0 +1,158 @@
/*
* Copyright (c) 2017 Evgeniy Alekseev
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
*
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*/
#ifndef _RESULT_H_
#define _RESULT_H_
#include <string>
#include <variant>
/**
* @addtogroup Result
* @brief Result namespace
*/
namespace Result
{
/**
* @enum Content
* @brief Result content type enumeration
* @var Content::Empty
* invalid content
* @var Content::Value
* Result contains value
* @var Content::Error
* Result contains error
*/
enum class Content { Empty, Value, Error };
/**
* @brief Error representation
* @tparam ErrorEnum
* error code enumeration
*/
template <typename ErrorEnum> class Error
{
public:
/**
* @brief Error class default constructor
* @param message
* human readable error message
* @param code
* machine readable error code
*/
explicit Error(std::string message, ErrorEnum code)
: m_code(code)
{
m_message = std::move(message);
};
/**
* @brief Error class constructor with default error code
* @param message
* human readable error message
*/
Error(ErrorEnum code)
: Error("", code){};
/**
* @brief Error class constructor with empty error message
* @param code
* machine readable error code
*/
Error(std::string message)
: Error(message, static_cast<ErrorEnum>(0)){};
/**
* @brief Error class destructor
*/
~Error() = default;
/**
* @brief error message
* @return human readable error message
*/
std::string message() const { return m_message; };
/**
* @brief error code
* @return machine readable error code
*/
ErrorEnum code() const { return m_code; };
private:
/**
* @brief human readable error message
*/
std::string m_message;
/**
* @brief machine readable error code
*/
ErrorEnum m_code;
};
/**
* @brief Result main class
* @tparam T
* value class name
* @tparam ErrorEnum
* error code enumeration
*/
template <class T, typename ErrorEnum>
class Result : public std::variant<T, Error<ErrorEnum>>
{
public:
/**
* @brief Result constructor with value
* @param value
* result value
*/
Result(T value)
: std::variant<T, Error<ErrorEnum>>(value){};
/**
* @brief Result constructor with error
* @param error
* result error
*/
Result(Error<ErrorEnum> error)
: std::variant<T, Error<ErrorEnum>>(error){};
/**
* @brief get result value
* @throw std::bad_variant_access
* @return result value if holded
*/
T get() { return std::get<T>(*this); };
/**
* @brief get result error
* @throw std::bad_variant_access
* @return result error if holded
*/
Error<ErrorEnum> error() { return std::get<Error<ErrorEnum>>(*this); };
/**
* @brief get result content
*/
Content type() const
{
switch (this->index()) {
case 0:
return Content::Value;
case 1:
return Content::Error;
case std::variant_npos:
default:
return Content::Empty;
};
};
};
};
#endif /* _RESULT_H_ */