Skip to content

Instantly share code, notes, and snippets.

@phadej
Created August 9, 2012 18:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phadej/3307109 to your computer and use it in GitHub Desktop.
Save phadej/3307109 to your computer and use it in GitHub Desktop.
Keulii
// works with clang++ bundled with xcode 4.4
// clang++ -std=c++11 -stdlib=libc++ maybe.cc -o maybe
#include <iostream>
#include <utility>
// didn't realize how to make this a class to hide members
template <typename T>
struct maybe {
// private:
enum { nothing, just } type;
union {
char nothing; // smaller possible placeholder, not elegant still
T value;
} data;
// public:
static constexpr maybe makeNothing() {
return { nothing, .data.nothing = 0 };
}
static constexpr maybe makeJust(T value) {
return { just, .data.value = value };
}
constexpr bool isNothing() const {
return type == nothing;
}
constexpr bool isJust() const {
return !isNothing();
}
constexpr const T &fromJust() const {
return data.value;
}
};
// own pair type, std::pair is not literate
template <typename T, typename U>
struct pair {
T first;
U second;
constexpr pair(const T first, const U second)
: first(std::move(first)), second(std::move(second)) {}
};
template <typename T, typename U>
std::ostream &operator<<(std::ostream &os, const pair<T,U> &p) {
return os << '<' << p.first << ',' << p.second << '>';
}
template <typename T, typename U>
std::ostream &operator<<(std::ostream &os, const std::pair<T,U> &p) {
return os << '<' << p.first << ',' << p.second << '>';
}
int main(int argc, char **argv) {
// basic examples
std::cout << "nothing : " << maybe<int>::makeNothing().isNothing() << std::endl;
{
maybe<int> m = maybe<int>::makeJust(313);
std::cout << "just : " << m.isJust() << "; with value: " << m.fromJust() << std::endl;
}
// static assert!
static_assert(maybe<int>::makeNothing().isNothing(), "nothing should be nothing!");
// ... but we can get everything, this will not work, even we know this at compile time.
// static_assert(maybe<int>::makeJust(argc).isJust(), "just should be just");
// composite types
typedef pair<int,int> intpair;
std::cout << "pair : " << maybe<intpair>::makeJust(intpair(715,517)).fromJust() << std::endl;
std::cout << "std::pair : " << maybe<std::pair<int,int>>::makeJust(std::make_pair(715, 517)).fromJust() << std::endl;
// this works for our pair, because it is literal type
static_assert(maybe<intpair>::makeNothing().isNothing(), "nothing is still nothing");
// .. but not for std::pair, yet?
// static_assert(maybe<std::pair<int,int>>::makeNothing().isNothing(), "nothing is still nothing");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment