/****************************************************************************** * Top contributors (to current version): * Tim King, Mathias Preiner * * This file is part of the cvc5 project. * * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS * in the top-level source directory and their institutional affiliations. * All rights reserved. See the file COPYING in the top-level source * directory for licensing information. * **************************************************************************** * * This provides a templated Maybe construct. * * This class provides a templated Maybe construct. * This follows the rough pattern of the Maybe monad in haskell. * A Maybe is an algebraic type that is either Nothing | Just T * * T must support T() and operator=. * * This has a couple of uses: * - There is no reasonable value or particularly clean way to represent * Nothing using a value of T * - High level of assurance that a value is not used before it is set. */ #include "cvc5_public.h" #ifndef CVC5__UTIL__MAYBE_H #define CVC5__UTIL__MAYBE_H #include #include "base/exception.h" namespace cvc5 { template class Maybe { public: Maybe() : d_just(false), d_value(){} Maybe(const T& val): d_just(true), d_value(val){} Maybe& operator=(const T& v){ d_just = true; d_value = v; return *this; } inline bool nothing() const { return !d_just; } inline bool just() const { return d_just; } explicit operator bool() const noexcept { return just(); } void clear() { if(just()){ d_just = false; d_value = T(); } } const T& value() const { if (nothing()) { throw Exception("Maybe::value() requires the maybe to be set."); } return d_value; } private: bool d_just; T d_value; }; template inline std::ostream& operator<<(std::ostream& out, const Maybe& m){ out << "{"; if(m.nothing()){ out << "Nothing"; }else{ out << "Just "; out << m.value(); } out << "}"; return out; } } // namespace cvc5 #endif /* CVC5__UTIL__MAYBE_H */