mirror of
https://github.com/arcan1s/result.git
synced 2025-04-24 07:27:18 +00:00
initial import
This commit is contained in:
parent
7a4647371b
commit
de94719320
66
.clang-format
Normal file
66
.clang-format
Normal 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
13
AUTHORS
Normal 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
21
COPYING
Normal 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
68
README.md
Normal 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
158
result.hpp
Normal 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_ */
|
Loading…
Reference in New Issue
Block a user