From b62d3a1a171e8baaa08a98df7636bd3865b0805e Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Mon, 16 Feb 2015 17:37:03 +0100 Subject: [PATCH] Adds phantom type (to be used for state/input/output) --- lib/phantom.hpp | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/phantom_test.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 lib/phantom.hpp create mode 100644 src/phantom_test.cpp diff --git a/lib/phantom.hpp b/lib/phantom.hpp new file mode 100644 index 0000000..e03b80f --- /dev/null +++ b/lib/phantom.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include +#include + +template +struct phantom : boost::operators>, boost::shiftable> { + phantom(Base y) : x(y) {} + explicit operator Base() const { return x; } + Base base() const { return x; } + + Base x; + +#define IMPL(op) \ + phantom & operator op (phantom rh) { \ + x op rh.x; \ + return *this; \ + } + + IMPL(+=) + IMPL(-=) + IMPL(*=) + IMPL(/=) + IMPL(%=) + IMPL(|=) + IMPL(&=) + IMPL(^=) + IMPL(<<=) + IMPL(>>=) +#undef IMPL + + phantom & operator++() { ++x; return *this; } + phantom & operator--() { --x; return *this; } + + bool operator<(phantom rh) const { return x < rh.x; } + bool operator==(phantom rh) const { return x == rh.x; } +}; + +template +std::ostream & operator<<(std::ostream & out, phantom p){ return out << p.x; } + +template +std::istream & operator>>(std::istream & in, phantom & p){ return in >> p.x; } + diff --git a/src/phantom_test.cpp b/src/phantom_test.cpp new file mode 100644 index 0000000..ea3e7aa --- /dev/null +++ b/src/phantom_test.cpp @@ -0,0 +1,30 @@ +#include +#include + +template +using phantom_int = phantom; + +struct state_tag; +using state = phantom_int; + +struct input_tag; +using input = phantom_int; + +int main(int argc, char *argv[]){ + state x = 5; + x += 5; + + input y = 9; + y -= 9; + y++; + + std::cout << (x - 1) << std::endl; + std::cout << (y << 1) << std::endl; + // std::cout << x+y << std::endl; // does not compile + + for(input i = 0; i < 10; ++i){ + std::cout << i << ", "; + } + std::cout << std::endl; +} +