Project

neither

A header-only C++ Either type for error handling — lift errors into the type-system with the same performance as error-codes and without the pitfalls of exceptions.

C++14CMake

neither is a header-only C++ library providing an Either type — a clean, type-safe way to handle errors that outperforms exceptions and is safer than raw error-codes.

The Problem

C++ offers two dominant error-handling strategies, each with trade-offs:

  • Exceptions — easy to use but not enforced by the type-system, not zero-cost, and unsupported on some platforms.
  • Error-codes — zero overhead but return values are occupied, forcing out-parameters and making functional composition hard.

neither offers a third path: Either types.

What is an Either?

An Either<L, R> holds a value of either type L (left, typically an error) or type R (right, typically a result). The error is encoded directly in the return type, so the compiler enforces handling it.

#include <neither/neither.hpp>
using namespace neither;
 
Either<std::string, float> safeSqrt(float x) {
  if (x < 0) return left("x must be >= 0");
  return right(std::sqrt(x));
}

Usage

// Chain transformations — errors short-circuit automatically
auto result = safeSqrt(-1.0f)
  .rightMap([](float x) { return x * 2.0f; })           // only runs on success
  .leftMap([](std::string e) { return "Error: " + e; }) // only runs on error
  .join(); // both sides are now std::string
 
std::cout << result << "\n"; // "Error: x must be >= 0"

Key methods:

  • rightMap(f) — transform the success value, pass errors through unchanged
  • leftMap(f) — transform the error value, pass successes through unchanged
  • join() — unwrap when both sides have been unified to the same type

Performance

The compiler recognizes and inlines chained maps:

// These two are equivalent after optimization:
e.leftMap(f).leftMap(g)
e.leftMap([](auto x) { return g(f(x)); })

The branches introduced by leftMap/rightMap are eliminated by the optimizer. Assembly output shows no difference between Either-based and error-code-based approaches after optimization.

Installation

neither is header-only:

git clone https://github.com/loopperfect/neither

Add the include/ directory to your compiler's include path. Requires C++14.