fork download
  1. #include <boost/variant.hpp>
  2. #include <iostream>
  3.  
  4. struct Nil {};
  5. auto nil = Nil{};
  6.  
  7. template <typename T>
  8. struct Cons;
  9.  
  10. template <typename T>
  11. using List = boost::variant<Nil, boost::recursive_wrapper<Cons<T>>>;
  12.  
  13. template <typename T>
  14. struct Cons {
  15. Cons( T val, List<T> list ) : head( val ), tail( list ) {}
  16.  
  17. T head;
  18. List<T> tail;
  19. };
  20.  
  21. template <typename T>
  22. class length_visitor : public boost::static_visitor<size_t> {
  23. public:
  24. int operator()( Nil ) const {
  25. return 0;
  26. }
  27.  
  28. int operator()( const Cons<T>& c ) const {
  29. return 1 + length( c.tail );
  30. }
  31. };
  32.  
  33. template <typename T>
  34. auto cons( T head, List<T> tail ) {
  35. return List<T>( Cons<T>( head, tail ) );
  36. }
  37.  
  38. template <typename T>
  39. auto cons( T head, Nil ) {
  40. return List<T>( Cons<T>( head, List<T>( Nil{} ) ) );
  41. }
  42.  
  43. template <typename T>
  44. size_t length( const List<T>& list ) {
  45. return boost::apply_visitor( length_visitor<T>(), list );
  46. }
  47.  
  48. int main() {
  49.  
  50. auto l = cons( 3, cons( 2, cons( 1, nil ) ) );
  51. std::cout << length( l ) << std::endl;
  52.  
  53. return 0;
  54. }
  55.  
Success #stdin #stdout 0s 3244KB
stdin
Standard input is empty
stdout
3