/*============================================================================= Copyright (c) 2011-2016 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_STRING_SHIFT_CONCAT_HPP #define SPROUT_STRING_SHIFT_CONCAT_HPP #include #include #include #include #include #include namespace sprout { namespace detail { template inline SPROUT_CONSTEXPR std::size_t checked_length(std::size_t n) { return n <= N ? n : throw std::length_error("length exceeded") ; } } // namespace detail namespace detail { template inline SPROUT_CONSTEXPR sprout::basic_string string_rshift( sprout::basic_string const& lhs, std::size_t lsize, T const& rhs, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(lsize + 1), (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + 1 ? rhs : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_rshift( sprout::basic_string const& lhs, std::size_t lsize, T const* rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(lsize + rsize), (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + rsize ? rhs[Indexes - lsize] : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_rshift( sprout::basic_string const& lhs, std::size_t lsize, sprout::basic_string const& rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(lsize + rsize), (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + rsize ? rhs[Indexes - lsize] : T() )... ); } template inline SPROUT_INITIALIZER_LIST_CONSTEXPR sprout::basic_string string_rshift( sprout::basic_string const& lhs, std::size_t lsize, std::initializer_list rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(lsize + rsize), (Indexes < lsize ? lhs[Indexes] : Indexes < lsize + rsize ? rhs.begin()[Indexes - lsize] : T() )... ); } } // namespace detail // // operator<< // template inline SPROUT_CONSTEXPR sprout::basic_string operator<<(sprout::basic_string const& lhs, T const& rhs) { return sprout::detail::string_rshift( lhs, lhs.size(), rhs, sprout::make_index_tuple::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator<<(sprout::basic_string const& lhs, T const* rhs) { return sprout::detail::string_rshift( lhs, lhs.size(), rhs, Traits::length(rhs), sprout::make_index_tuple::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator<<(sprout::basic_string const& lhs, sprout::basic_string const& rhs) { return sprout::detail::string_rshift( lhs, lhs.size(), rhs, rhs.size(), sprout::make_index_tuple::make() ); } template inline SPROUT_INITIALIZER_LIST_CONSTEXPR sprout::basic_string operator<<(sprout::basic_string const& lhs, std::initializer_list rhs) { return sprout::detail::string_rshift( lhs, lhs.size(), rhs, rhs.size(), sprout::make_index_tuple::make() ); } namespace detail { template inline SPROUT_CONSTEXPR sprout::basic_string string_lshift( sprout::basic_string const& lhs, std::size_t lsize, T const& rhs, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(1 + lsize), (Indexes < 1 ? rhs : Indexes < 1 + lsize ? lhs[Indexes - 1] : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_lshift( sprout::basic_string const& lhs, std::size_t lsize, T const* rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(rsize + lsize), (Indexes < rsize ? rhs[Indexes] : Indexes < rsize + lsize ? lhs[Indexes - rsize] : T() )... ); } template inline SPROUT_CONSTEXPR sprout::basic_string string_lshift( sprout::basic_string const& lhs, std::size_t lsize, sprout::basic_string const& rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(rsize + lsize), (Indexes < rsize ? rhs[Indexes] : Indexes < rsize + lsize ? lhs[Indexes - rsize] : T() )... ); } template inline SPROUT_INITIALIZER_LIST_CONSTEXPR sprout::basic_string string_lshift( sprout::basic_string const& lhs, std::size_t lsize, std::initializer_list rhs, std::size_t rsize, sprout::index_tuple ) { typedef sprout::detail::string_construct_access access_type; return access_type::raw_construct( sprout::detail::checked_length(rsize + lsize), (Indexes < rsize ? rhs.begin()[Indexes] : Indexes < rsize + lsize ? lhs[Indexes - rsize] : T() )... ); } } // namespace detail // // operator>> // template inline SPROUT_CONSTEXPR sprout::basic_string operator>>(sprout::basic_string const& lhs, T const& rhs) { return sprout::detail::string_lshift( lhs, lhs.size(), rhs, sprout::make_index_tuple::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator>>(sprout::basic_string const& lhs, T const* rhs) { return sprout::detail::string_lshift( lhs, lhs.size(), rhs, Traits::length(rhs), sprout::make_index_tuple::make() ); } template inline SPROUT_CONSTEXPR sprout::basic_string operator>>(sprout::basic_string const& lhs, sprout::basic_string const& rhs) { return sprout::detail::string_lshift( lhs, lhs.size(), rhs, rhs.size(), sprout::make_index_tuple::make() ); } template inline SPROUT_INITIALIZER_LIST_CONSTEXPR sprout::basic_string operator>>(sprout::basic_string const& lhs, std::initializer_list rhs) { return sprout::detail::string_lshift( lhs, lhs.size(), rhs, rhs.size(), sprout::make_index_tuple::make() ); } } // namespace sprout #endif // #ifndef SPROUT_STRING_SHIFT_CONCAT_HPP