match.hpp 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. //
  2. // match.hpp
  3. // case-matcher
  4. //
  5. // Created by Sam Jaffe on 9/10/16.
  6. //
  7. #pragma once
  8. #include <tuple>
  9. namespace matcher {
  10. struct {} any;
  11. using any_t = decltype(any);
  12. template <typename T>
  13. bool operator==(T const &, any_t) { return true; }
  14. template <typename T>
  15. bool operator==(any_t, T const &) { return true; }
  16. template <typename... Args>
  17. struct matcher {
  18. public:
  19. matcher(Args &&... args) : value(std::forward<Args>(args)...) {}
  20. operator bool( ) const { return true; }
  21. bool unmatched( ) const { return ! satisfied; }
  22. template <typename... NArgs>
  23. bool matches(NArgs &&... args) const {
  24. return value == std::tuple<NArgs...>(std::forward<NArgs>(args)...);
  25. }
  26. private:
  27. std::tuple<Args...> value;
  28. bool satisfied = false;
  29. };
  30. template <typename... Args>
  31. matcher<Args...> make_matcher(Args &&... args) {
  32. return matcher<Args...>(std::forward<Args>(args)...);
  33. }
  34. }
  35. #define match( ... ) \
  36. if ( auto const & _matcher_local = \
  37. ::matcher::make_matcher( __VA_ARGS__ ) )
  38. #define with( ... ) \
  39. if ( _matcher_local.unmatched( ) && \
  40. _matcher_local.matches( __VA_ARGS__ ) )