mirror of
https://github.com/arcan1s/result.git
synced 2025-04-28 01:07:20 +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