Skip to content
DBJ Error Concept aka DBJ ERRC
C++
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.vscode
.gitattributes
.gitignore
LICENSE
README.md
canonical.cpp
dbj_errc.h

README.md

DBJ Error Concept aka DBJ ERRC

(c) 2019 by dbj@dbj.org, licence Appache 2.0

There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.

C.A.R. Hoare

DBJ ERRC Architecture

This concept is an deliberate homage to the GO language error concept

Caveat Emptor: Good Architecture is design agnostic. Good design is implementation agnostic.

	    return structure
	+-----------------------------+
	|   optional value            |
	+-----------------------------+
	|   optional error            |
	+-----------------------------+
  1. Each new function conforming to this concept should return one structure with exactly two elements.
  2. First element represents an optional value returned Second element represents an optional error returned
  3. Each element existence is optional. Non existent element is considered 'empty'. An 'empty' return type is the one where both value and error are 'empty'.
  4. Existence of the error does not mean there is no value returned.

DBJ ERRC Design

  1. Existence or lack of value or error returned, defines the logic of consuming the return from new functions complying to this concept.
  2. There are no common interfaces of returned value or returned error. The concept is not 'implement the interface' but rather 'conform to the interface'
  3. Thus there is no inheritance for subtyping. Inheritance for subclassing is considered bad.
  4. Actual value or error types are not prescribed. Thus operations on them are to be, and must be, decoupled from the DBJ ERRC core
  5. Implementations should use as much as possible from what is already available.

DBJ ERRC ISO C++ implementation requirements

  1. return value must be an instance of std::pair
  2. both first and second must be inside std::option
  3. any of them can be std::nullopt

Try to avoid c++ exceptions at any cost.

The whole of DBJ ERRC ISO C++ code, common to all standard C++ implementations

// dbj_errc.h
// (c) 2019 by dbj@dbj.org
// Licence Appache 2.0
#pragma once

#include <optional>
#include <utility>

namespace dbj::errc {

template<typename VALUE_TYPE, typename ERROR_TYPE>
struct error_concept final
{
using type = error_concept;
using value_type = VALUE_TYPE;
using error_type = ERROR_TYPE;

using value_option = std::optional<VALUE_TYPE>;
using error_option = std::optional<ERROR_TYPE>;
   
using return_type = std::pair<
   value_option,
   error_option
>;

/* 
make and return an 'empty' return type 
*/
static return_type make () noexcept {
   return { std::nullopt, std::nullopt };
}

/*
we do not overload 'make' in order to make 
code simpler *and* the calling code simpler to read

we use standard ISO C++ where arguments are passed by value

make no error, just value
*/
static return_type make_val(value_type val_) noexcept {
   return { val_, std::nullopt };
}

/*
make no value, just error
*/
static return_type make_err(error_type err_) noexcept {
   return { std::nullopt, err_ };
}

/*
make both value and error
*/
static return_type make_val_err(value_type val_, error_type err_) noexcept {
   return { val_, err_ };
}

}; // error_concept

} // namespace dbj::errc

Canonical ISO C++ client code

Use the name spaces

using namespace std  ;
using ec = dbj::errc ;

Define the type required for the program

using my_errc = ec::error_concept< string, string > ;

Some functionality, where we show the dbj_errc return type creation. This is a new dbj_errc conformant function because it returns the correct structure.

my_errc::return_type my_cleaner ( string input_ ) noexcept
{
// return error and empty value
if ( input_.empty() )
	return my_errc::make_err("Input is empty.");

input_.clear() ;

// return value and empty error
return my_errc::make_val( input_ ) ;
}

The calling code:

auto [val,err] = my_cleaner( string{"some content"} ) ;

if ( err )
{
   cout << "\nmy_cleaner returned an error: " << (*err).c_str() ;
} 

if ( val ){
   cout << "\nmy_cleaner returned an value." ;
   cout << "\nsize of the returned string is: " << (*val).size() ;
}

Existence of the error does not mean there is no value returned.

Contact: dbj at dbj dot org

You can’t perform that action at this time.