Created
August 9, 2012 18:57
-
-
Save phadej/3307109 to your computer and use it in GitHub Desktop.
Keulii
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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