Commit 42ba1a22 authored by Eric Niebler's avatar Eric Niebler Committed by Facebook Github Bot

folly::FutureException inherits from std::logic_error, like std::future_error;...

folly::FutureException inherits from std::logic_error, like std::future_error; becomes smaller and nothrow-copy

Summary:
folly::FutureException was inheriting from std::exception and managing its own message in a std::string data member.
That is suboptimal for the following reasons:

1) The analagous std:: type, std::future_error, inherits from std::logic_error. According to the Principle of Least
   Astonishment, folly::FutureExpception should follow suit.
2) std::logic_error has a nothrow copy constructor. (This is typically implemented with a ref-counted string.)
   std::string does not. By explicitly managing its own message, folly::FutureException picks up a throwing copy
   constructor. Exception classes should try to be nothrow copyable.
3) With most stdlib implementations, std::string is larger by a lot than the std:: exceptions. By changing
   folly::FutureException as suggested, its size drops from 40 bytes to 16 on clang and gcc >=5.0.

Also, I took the liberty of fixing some copy-pastas that gave some of these exception types explicit default
constructors.

Reviewed By: yfeldblum

Differential Revision: D4367909

fbshipit-source-id: 1639d404237493f929db6116a760c2d0e599877d
parent 42f55fa5
...@@ -16,64 +16,42 @@ ...@@ -16,64 +16,42 @@
#pragma once #pragma once
#include <exception> #include <stdexcept>
#include <string> #include <string>
namespace folly { namespace folly {
class FutureException : public std::exception { class FutureException : public std::logic_error {
public:
public: using std::logic_error::logic_error;
explicit FutureException(std::string message_arg)
: message(message_arg) {}
~FutureException() throw(){}
virtual const char *what() const throw() {
return message.c_str();
}
bool operator==(const FutureException &other) const{
return other.message == this->message;
}
bool operator!=(const FutureException &other) const{
return !(*this == other);
}
protected:
std::string message;
}; };
class BrokenPromise : public FutureException { class BrokenPromise : public FutureException {
public: public:
explicit BrokenPromise(std::string type) : explicit BrokenPromise(const std::string& type)
FutureException( : FutureException("Broken promise for type name `" + type + '`') {}
(std::string("Broken promise for type name `") + type) + '`') { }
explicit BrokenPromise(const char* type) : BrokenPromise(std::string(type)) {}
}; };
class NoState : public FutureException { class NoState : public FutureException {
public: public:
explicit NoState() : FutureException("No state") { } NoState() : FutureException("No state") {}
}; };
class PromiseAlreadySatisfied : public FutureException { class PromiseAlreadySatisfied : public FutureException {
public: public:
explicit PromiseAlreadySatisfied() : PromiseAlreadySatisfied() : FutureException("Promise already satisfied") {}
FutureException("Promise already satisfied") { }
}; };
class FutureNotReady : public FutureException { class FutureNotReady : public FutureException {
public: public:
explicit FutureNotReady() : FutureNotReady() : FutureException("Future not ready") {}
FutureException("Future not ready") { }
}; };
class FutureAlreadyRetrieved : public FutureException { class FutureAlreadyRetrieved : public FutureException {
public: public:
explicit FutureAlreadyRetrieved () : FutureAlreadyRetrieved() : FutureException("Future already retrieved") {}
FutureException("Future already retrieved") { }
}; };
class FutureCancellation : public FutureException { class FutureCancellation : public FutureException {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment