@@ -335,12 +335,16 @@ namespace bencode {
335335 };
336336
337337 template <typename T>
338- concept sequence = iterable<T> && !std::convertible_to<T, std::string_view>;
338+ concept stringish = iterable<T> && requires (T &t) {
339+ std::size (t);
340+ requires std::same_as<std::iter_value_t <decltype (std::begin (t))>, char >;
341+ };
339342
340343 template <typename T>
341- concept mapping = sequence <T> && requires {
344+ concept mapping = iterable <T> && requires {
342345 typename T::key_type;
343346 typename T::mapped_type;
347+ requires stringish<typename T::key_type>;
344348 };
345349
346350 template <std::integral Integer>
@@ -736,28 +740,42 @@ namespace bencode {
736740 }
737741
738742 template <detail::output_iterator_ref Iter>
739- inline void encode (Iter &&iter, integer value) {
743+ inline void encode_to (Iter &&iter, integer value) {
740744 *iter++ = u8 ' i' ;
741745 detail::write_integer (iter, value);
742746 *iter++ = u8 ' e' ;
743747 }
744748
749+ template <detail::output_iterator_ref Iter, detail::stringish Str>
750+ requires (!std::is_array_v<Str>)
751+ inline void encode_to(Iter &&iter, const Str &value) {
752+ detail::write_integer (iter, std::size (value));
753+ *iter++ = u8 ' :' ;
754+ std::copy (std::begin (value), std::end (value), iter);
755+ }
756+
745757 template <detail::output_iterator_ref Iter>
746- inline void encode (Iter &&iter, const string_view & value) {
747- detail::write_integer (iter, value. size () );
758+ inline void encode_to (Iter &&iter, const char * value, std:: size_t length ) {
759+ detail::write_integer (iter, length );
748760 *iter++ = u8 ' :' ;
749- std::copy (value.begin (), value.end (), iter);
761+ std::copy (value, value + length, iter);
762+ }
763+
764+ template <detail::output_iterator_ref Iter, std::size_t N>
765+ inline void encode_to (Iter &&iter, const char (&value)[N]) {
766+ // Don't write the null terminator.
767+ encode_to (std::forward<Iter>(iter), value, N - 1 );
750768 }
751769
752- template <detail::output_iterator_ref Iter, detail::sequence Seq>
753- void encode (Iter &&iter, const Seq &value) {
770+ template <detail::output_iterator_ref Iter, detail::iterable Seq>
771+ void encode_to (Iter &&iter, const Seq &value) {
754772 detail::list_encoder e (iter);
755773 for (auto &&i : value)
756774 e.add (i);
757775 }
758776
759777 template <detail::output_iterator_ref Iter, detail::mapping Map>
760- void encode (Iter &&iter, const Map &value) {
778+ void encode_to (Iter &&iter, const Map &value) {
761779 detail::dict_encoder e (iter);
762780 for (auto &&i : value)
763781 e.add (i.first , i.second );
@@ -771,7 +789,7 @@ namespace bencode {
771789
772790 template <typename T>
773791 void operator ()(T &&operand) const {
774- encode (iter, std::forward<T>(operand));
792+ encode_to (iter, std::forward<T>(operand));
775793 }
776794 private:
777795 Iter &iter;
@@ -781,38 +799,38 @@ namespace bencode {
781799 template <detail::output_iterator_ref Iter,
782800 template <typename ...> typename Variant, typename I, typename S,
783801 template <typename ...> typename L, template <typename ...> typename D>
784- void encode (Iter &&iter, const basic_data<Variant, I, S, L, D> &value) {
802+ void encode_to (Iter &&iter, const basic_data<Variant, I, S, L, D> &value) {
785803 variant_traits<Variant>::visit (detail::encode_visitor (iter), value);
786804 }
787805
788806 namespace detail {
789807 template <detail::output_iterator_ref Iter>
790808 template <typename T>
791809 inline list_encoder<Iter> & list_encoder<Iter>::add(T &&value) {
792- encode (iter, std::forward<T>(value));
810+ encode_to (iter, std::forward<T>(value));
793811 return *this ;
794812 }
795813
796814 template <detail::output_iterator_ref Iter>
797815 template <typename T>
798816 inline dict_encoder<Iter> &
799817 dict_encoder<Iter>::add(const string_view &key, T &&value) {
800- encode (iter, key);
801- encode (iter, std::forward<T>(value));
818+ encode_to (iter, key);
819+ encode_to (iter, std::forward<T>(value));
802820 return *this ;
803821 }
804822 }
805823
806- template <typename T>
807- std::string encode (T &&t) {
824+ template <typename ... T>
825+ std::string encode (T &&... t) {
808826 std::stringstream ss;
809- encode (std::ostreambuf_iterator (ss), std::forward<T>(t));
827+ encode_to (std::ostreambuf_iterator (ss), std::forward<T>(t)... );
810828 return ss.str ();
811829 }
812830
813- template <typename T>
814- void encode (std::ostream &os, T &&t) {
815- encode (std::ostreambuf_iterator (os), std::forward<T>(t));
831+ template <typename ... T>
832+ void encode_to (std::ostream &os, T &&... t) {
833+ encode_to (std::ostreambuf_iterator (os), std::forward<T>(t)... );
816834 }
817835
818836}
0 commit comments