Welcome to Open Discussion
I believe there is a way to implement all these operations without preprocessor metaprogramming. Here's how concatenation can be implemented.
#include <cstdio> template <size_t... Is> struct int_pack { typedef int_pack type; }; template <class S, size_t I> struct append; template <size_t... Is, size_t I> struct append<int_pack<Is...>, I> : int_pack<Is..., I> {}; template <size_t N> struct make_int_pack : append<typename make_int_pack<N - 1>::type, N - 1> {}; template <> struct make_int_pack<0> : int_pack<> {}; template <size_t N> class constexpr_string { public: typedef const char Chars[N + 1]; constexpr constexpr_string(Chars& c) : constexpr_string(c, typename make_int_pack<N>::type()) {} template <class... C> constexpr explicit constexpr_string(C... c) : data_{c..., '\0'} {} constexpr char operator[](size_t i) const { return data_[i]; } constexpr Chars& c_str() const { return data_; } private: template <size_t... Ns> constexpr constexpr_string(const Chars& c, int_pack<Ns...>) : data_{c[Ns]...} {} Chars data_; }; template <size_t N, size_t M, size_t... Ns, size_t... Ms> constexpr constexpr_string<N + M> CatImpl( const constexpr_string<N>& a, const constexpr_string<M>& b, int_pack<Ns...>, int_pack<Ms...>) { return constexpr_string<N + M>(a[Ns]..., b[Ms]...); } template <size_t N, size_t M> constexpr constexpr_string<N + M - 2> Cat(const char (&a)[N], const char (&b)[M]) { return CatImpl<N - 1, M - 1>( a, b, make_int_pack<N - 1>(), make_int_pack<M - 1>()); } int main() { const char* s = Cat("Hello ", "World!"); puts(s); }
HTH, Roman Perepelitsa.
Log in to post a comment.
Welcome to Open Discussion
I believe there is a way to implement all these operations without preprocessor metaprogramming. Here's how concatenation can be implemented.
HTH,
Roman Perepelitsa.