fork download
  1. #include <iostream>
  2.  
  3. template<typename T>
  4. constexpr T shift_left(const T value) { return value << 1; }
  5.  
  6. template<typename T>
  7. constexpr T increment(const T value) { return value + 1; }
  8.  
  9. template<typename T>
  10. constexpr T bicrement(const T value) { return value + 2; }
  11.  
  12. template<typename T>
  13. constexpr T test(const T value) { return bicrement(shift_left(increment(value))); }
  14.  
  15. template <typename T, T(*INC)(const T), T start = {}>
  16. struct managed_enum
  17. {
  18. enum
  19. {
  20. a = start,
  21. b = INC(a),
  22. c = INC(b),
  23. };
  24. };
  25.  
  26. template <typename T, T(*INC)(const T), T start = {}>
  27. struct managed_strong_enum
  28. {
  29. enum class value : T
  30. {
  31. a = start,
  32. b = INC(a),
  33. c = INC(b),
  34. };
  35. };
  36.  
  37. int main()
  38. {
  39. using shifted = managed_enum<int, shift_left<int>, 1>;
  40. using increment = managed_enum<int, increment<int>>;
  41. using bicrement = managed_enum<int, bicrement<int>>;
  42.  
  43. using test = managed_strong_enum<int, test<int>, 5>;
  44.  
  45. std::cout << "[<< 1] -> a: " << shifted::a
  46. << "\tb: " << shifted::b
  47. << "\tc: " << shifted::c << '\n';
  48.  
  49. std::cout << "[ +1 ] -> a: " << increment::a
  50. << "\tb: " << increment::b
  51. << "\tc: " << increment::c << '\n';
  52.  
  53. std::cout << "[ +2 ] -> a: " << bicrement::a
  54. << "\tb: " << bicrement::b
  55. << "\tc: " << bicrement::c << '\n';
  56.  
  57. std::cout << "[test] -> a: " << int(test::value::a)
  58. << "\tb: " << int(test::value::b)
  59. << "\tc: " << int(test::value::c) << '\n';
  60.  
  61. return 0;
  62. }
Success #stdin #stdout 0s 3140KB
stdin
Standard input is empty
stdout
[<< 1] -> a: 1	b: 2	c: 4
[ +1 ] -> a: 0	b: 1	c: 2
[ +2 ] -> a: 0	b: 2	c: 4
[test] -> a: 5	b: 14	c: 32