#ifndef CONCAT_HPP_ #define CONCAT_HPP_ #include "symbol.hpp" namespace detail { template< unsigned int N , unsigned int Index , class ...Symbols > struct get_impl_wrapper; template< class ...Symbols > class concat_impl; template<> class concat_impl<> : public symbol { public: template< class CharType > constexpr concat_impl( const_string< CharType > str , std::size_t begin = 0 ) : symbol( begin ) { } }; template< class Head , class ...Tail > class concat_impl< Head , Tail... > : public concat_impl< Tail... > { public: template< class CharType > constexpr concat_impl( const_string< CharType > str , std::size_t begin = 0 ) : concat_impl< Tail... >( str , Head( str , begin ).end() ) , obj( str , begin ) { } private: template< unsigned int N , unsigned int Index , class ...Symbols > friend struct get_impl_wrapper; Head obj; }; template< unsigned int N , unsigned int Index , class ...Symbols > struct get_impl_wrapper { static_assert( sizeof...( Symbols ) != 0 , "get< N >( concat ) - N too big" ); static constexpr void get_impl( concat_impl<> ) { } }; template< unsigned int N , unsigned int Index , class Head , class ...Tail > struct get_impl_wrapper< N , Index , Head , Tail... > { static constexpr auto get_impl( concat_impl< Head , Tail... > conc ) -> decltype( get_impl_wrapper< N , Index + 1 , Tail... >::get_impl( conc ) ) { return get_impl_wrapper< N , Index + 1 , Tail... >::get_impl( conc ); } }; template< unsigned int N , class Head , class ...Symbols > struct get_impl_wrapper< N , N , Head , Symbols... > { static constexpr Head get_impl( concat_impl< Head , Symbols... > conc ) { return conc.obj; } }; } template< class ...Symbols > class concat : public detail::concat_impl< Symbols... > { public: template< class CharType > constexpr concat( const_string< CharType > str , std::size_t begin = 0 ) : detail::concat_impl< Symbols... >( str , begin ) { } template< unsigned int N > constexpr auto get() -> decltype( detail::get_impl_wrapper< N , 0 , Symbols... >::get_impl( *static_cast< concat< Symbols... >* >( 0 ) ) ) { return detail::get_impl_wrapper< N , 0 , Symbols... >::get_impl( *this ); } }; template< unsigned int N , class ...Symbols > constexpr auto get( concat< Symbols... > conc ) -> decltype( detail::get_impl_wrapper< N , 0 , Symbols... >::get_impl( conc ) ) { return detail::get_impl_wrapper< N , 0 , Symbols... >::get_impl( conc ); } #endif