@@ -737,7 +737,9 @@ class mutable_buffer
737
737
constexpr mutable_buffer () noexcept : _data(nullptr ), _size(0 ) {}
738
738
constexpr mutable_buffer (void *p, size_t n) noexcept : _data(p), _size(n)
739
739
{
740
+ #ifdef ZMQ_CPP14
740
741
assert (p != nullptr || n == 0 );
742
+ #endif
741
743
}
742
744
743
745
constexpr void *data () const noexcept { return _data; }
@@ -770,7 +772,12 @@ class const_buffer
770
772
{
771
773
public:
772
774
constexpr const_buffer () noexcept : _data(nullptr ), _size(0 ) {}
773
- constexpr const_buffer (const void *p, size_t n) noexcept : _data(p), _size(n) {}
775
+ constexpr const_buffer (const void *p, size_t n) noexcept : _data(p), _size(n)
776
+ {
777
+ #ifdef ZMQ_CPP14
778
+ assert (p != nullptr || n == 0 );
779
+ #endif
780
+ }
774
781
constexpr const_buffer (const mutable_buffer &mb) noexcept :
775
782
_data(mb.data()),
776
783
_size(mb.size())
@@ -817,43 +824,21 @@ constexpr mutable_buffer buffer(const mutable_buffer& mb) noexcept
817
824
{
818
825
return mb;
819
826
}
820
- constexpr mutable_buffer buffer (const mutable_buffer& mb, size_t n) noexcept
827
+ inline mutable_buffer buffer (const mutable_buffer& mb, size_t n) noexcept
821
828
{
822
829
return mutable_buffer (mb.data (), (std::min)(mb.size (), n));
823
830
}
824
831
constexpr const_buffer buffer (const const_buffer& cb) noexcept
825
832
{
826
833
return cb;
827
834
}
828
- constexpr const_buffer buffer (const const_buffer& cb, size_t n) noexcept
835
+ inline const_buffer buffer (const const_buffer& cb, size_t n) noexcept
829
836
{
830
837
return const_buffer (cb.data (), (std::min)(cb.size (), n));
831
838
}
832
839
833
840
namespace detail
834
841
{
835
- // utility functions for containers with data and size
836
- // data is nullptr if the container is empty
837
- template <class T > mutable_buffer buffar_mut_ds (T &data) noexcept
838
- {
839
- return mutable_buffer (data.size () != 0u ? data.data () : nullptr ,
840
- data.size () * sizeof (*data.data ()));
841
- }
842
- template <class T > mutable_buffer buffar_mut_ds (T &data, size_t n_bytes) noexcept
843
- {
844
- return mutable_buffer (data.size () != 0u ? data.data () : nullptr ,
845
- (std::min)(data.size () * sizeof (*data.data ()), n_bytes));
846
- }
847
- template <class T > const_buffer buffar_const_ds (const T &data) noexcept
848
- {
849
- return const_buffer (data.size () != 0u ? data.data () : nullptr ,
850
- data.size () * sizeof (*data.data ()));
851
- }
852
- template <class T > const_buffer buffar_const_ds (const T &data, size_t n_bytes) noexcept
853
- {
854
- return const_buffer (data.size () != 0u ? data.data () : nullptr ,
855
- (std::min)(data.size () * sizeof (*data.data ()), n_bytes));
856
- }
857
842
template <class T > struct is_pod_like
858
843
{
859
844
// NOTE: The networking draft N4771 section 16.11 requires
@@ -863,148 +848,149 @@ template<class T> struct is_pod_like
863
848
static constexpr bool value =
864
849
std::is_trivially_copyable<T>::value && std::is_standard_layout<T>::value;
865
850
};
851
+
852
+ template <class C > constexpr auto seq_size (const C &c) noexcept -> decltype(c.size())
853
+ {
854
+ return c.size ();
855
+ }
856
+ template <class T , size_t N>
857
+ constexpr size_t seq_size (const T (&/* array*/ )[N]) noexcept
858
+ {
859
+ return N;
860
+ }
861
+
862
+ template <class Seq >
863
+ auto buffer_contiguous_sequence (Seq &&seq) noexcept
864
+ -> decltype(buffer(std::addressof(*std::begin (seq)), size_t{}))
865
+ {
866
+ using T = typename std::remove_cv<
867
+ typename std::remove_reference<decltype (*std::begin (seq))>::type>::type;
868
+ static_assert (detail::is_pod_like<T>::value, " T must be POD" );
869
+
870
+ const auto size = seq_size (seq);
871
+ return buffer (size != 0u ? std::addressof (*std::begin (seq)) : nullptr ,
872
+ size * sizeof (T));
873
+ }
874
+ template <class Seq >
875
+ auto buffer_contiguous_sequence (Seq &&seq, size_t n_bytes) noexcept
876
+ -> decltype(buffer_contiguous_sequence(seq))
877
+ {
878
+ using T = typename std::remove_cv<
879
+ typename std::remove_reference<decltype (*std::begin (seq))>::type>::type;
880
+ static_assert (detail::is_pod_like<T>::value, " T must be POD" );
881
+
882
+ const auto size = seq_size (seq);
883
+ return buffer (size != 0u ? std::addressof (*std::begin (seq)) : nullptr ,
884
+ (std::min)(size * sizeof (T), n_bytes));
885
+ }
886
+
866
887
} // namespace detail
867
888
868
889
// C array
869
890
template <class T , size_t N> mutable_buffer buffer (T (&data)[N]) noexcept
870
891
{
871
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
872
- static_assert (N > 0 , " N > 0" );
873
- return mutable_buffer (static_cast <T *>(data), N * sizeof (T));
892
+ return detail::buffer_contiguous_sequence (data);
874
893
}
875
894
template <class T , size_t N>
876
895
mutable_buffer buffer (T (&data)[N], size_t n_bytes) noexcept
877
896
{
878
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
879
- static_assert (N > 0 , " N > 0" );
880
- return mutable_buffer (static_cast <T *>(data), (std::min)(N * sizeof (T), n_bytes));
897
+ return detail::buffer_contiguous_sequence (data, n_bytes);
881
898
}
882
899
template <class T , size_t N> const_buffer buffer (const T (&data)[N]) noexcept
883
900
{
884
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
885
- static_assert (N > 0 , " N > 0" );
886
- return const_buffer (static_cast <const T *>(data), N * sizeof (T));
901
+ return detail::buffer_contiguous_sequence (data);
887
902
}
888
903
template <class T , size_t N>
889
904
const_buffer buffer (const T (&data)[N], size_t n_bytes) noexcept
890
905
{
891
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
892
- static_assert (N > 0 , " N > 0" );
893
- return const_buffer (static_cast <const T *>(data),
894
- (std::min)(N * sizeof (T), n_bytes));
906
+ return detail::buffer_contiguous_sequence (data, n_bytes);
895
907
}
896
908
// std::array
897
909
template <class T , size_t N> mutable_buffer buffer (std::array<T, N> &data) noexcept
898
910
{
899
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
900
- static_assert (N > 0 , " N > 0" );
901
- return mutable_buffer (data.data (), N * sizeof (T));
911
+ return detail::buffer_contiguous_sequence (data);
902
912
}
903
913
template <class T , size_t N>
904
914
mutable_buffer buffer (std::array<T, N> &data, size_t n_bytes) noexcept
905
915
{
906
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
907
- static_assert (N > 0 , " N > 0" );
908
- return mutable_buffer (data.data (), (std::min)(N * sizeof (T), n_bytes));
916
+ return detail::buffer_contiguous_sequence (data, n_bytes);
909
917
}
910
918
template <class T , size_t N>
911
919
const_buffer buffer (std::array<const T, N> &data) noexcept
912
920
{
913
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
914
- static_assert (N > 0 , " N > 0" );
915
- return const_buffer (data.data (), N * sizeof (T));
921
+ return detail::buffer_contiguous_sequence (data);
916
922
}
917
923
template <class T , size_t N>
918
924
const_buffer buffer (std::array<const T, N> &data, size_t n_bytes) noexcept
919
925
{
920
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
921
- static_assert (N > 0 , " N > 0" );
922
- return const_buffer (data.data (), (std::min)(N * sizeof (T), n_bytes));
926
+ return detail::buffer_contiguous_sequence (data, n_bytes);
923
927
}
924
928
template <class T , size_t N>
925
929
const_buffer buffer (const std::array<T, N> &data) noexcept
926
930
{
927
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
928
- static_assert (N > 0 , " N > 0" );
929
- return const_buffer (data.data (), N * sizeof (T));
931
+ return detail::buffer_contiguous_sequence (data);
930
932
}
931
933
template <class T , size_t N>
932
934
const_buffer buffer (const std::array<T, N> &data, size_t n_bytes) noexcept
933
935
{
934
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
935
- static_assert (N > 0 , " N > 0" );
936
- return const_buffer (data.data (), (std::min)(N * sizeof (T), n_bytes));
936
+ return detail::buffer_contiguous_sequence (data, n_bytes);
937
937
}
938
938
// std::vector
939
939
template <class T , class Allocator >
940
940
mutable_buffer buffer (std::vector<T, Allocator> &data) noexcept
941
941
{
942
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
943
- return detail::buffar_mut_ds (data);
942
+ return detail::buffer_contiguous_sequence (data);
944
943
}
945
944
template <class T , class Allocator >
946
945
mutable_buffer buffer (std::vector<T, Allocator> &data, size_t n_bytes) noexcept
947
946
{
948
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
949
- return detail::buffar_mut_ds (data, n_bytes);
947
+ return detail::buffer_contiguous_sequence (data, n_bytes);
950
948
}
951
949
template <class T , class Allocator >
952
950
const_buffer buffer (const std::vector<T, Allocator> &data) noexcept
953
951
{
954
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
955
- return detail::buffar_const_ds (data);
952
+ return detail::buffer_contiguous_sequence (data);
956
953
}
957
954
template <class T , class Allocator >
958
955
const_buffer buffer (const std::vector<T, Allocator> &data, size_t n_bytes) noexcept
959
956
{
960
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
961
- return detail::buffar_const_ds (data, n_bytes);
957
+ return detail::buffer_contiguous_sequence (data, n_bytes);
962
958
}
963
959
// std::basic_string
964
960
template <class T , class Traits , class Allocator >
965
961
mutable_buffer buffer (std::basic_string<T, Traits, Allocator> &data) noexcept
966
962
{
967
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
968
- // before C++17 string::data() returned const char*
969
- return mutable_buffer (data.size () != 0u ? &data[0 ] : nullptr ,
970
- data.size () * sizeof (T));
963
+ return detail::buffer_contiguous_sequence (data);
971
964
}
972
965
template <class T , class Traits , class Allocator >
973
966
mutable_buffer buffer (std::basic_string<T, Traits, Allocator> &data,
974
967
size_t n_bytes) noexcept
975
968
{
976
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
977
- // before C++17 string::data() returned const char*
978
- return mutable_buffer (data.size () != 0u ? &data[0 ] : nullptr ,
979
- (std::min)(data.size () * sizeof (T), n_bytes));
969
+ return detail::buffer_contiguous_sequence (data, n_bytes);
980
970
}
981
971
template <class T , class Traits , class Allocator >
982
972
const_buffer buffer (const std::basic_string<T, Traits, Allocator> &data) noexcept
983
973
{
984
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
985
- return detail::buffar_const_ds (data);
974
+ return detail::buffer_contiguous_sequence (data);
986
975
}
987
976
template <class T , class Traits , class Allocator >
988
977
const_buffer buffer (const std::basic_string<T, Traits, Allocator> &data,
989
978
size_t n_bytes) noexcept
990
979
{
991
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
992
- return detail::buffar_const_ds (data, n_bytes);
980
+ return detail::buffer_contiguous_sequence (data, n_bytes);
993
981
}
994
982
995
983
#ifdef ZMQ_CPP17
996
984
// std::basic_string_view
997
985
template <class T , class Traits >
998
986
const_buffer buffer (std::basic_string_view<T, Traits> data) noexcept
999
987
{
1000
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
1001
- return detail::buffar_const_ds (data);
988
+ return detail::buffer_contiguous_sequence (data);
1002
989
}
1003
990
template <class T , class Traits >
1004
991
const_buffer buffer (std::basic_string_view<T, Traits> data, size_t n_bytes) noexcept
1005
992
{
1006
- static_assert (detail::is_pod_like<T>::value, " T must be POD" );
1007
- return detail::buffar_const_ds (data, n_bytes);
993
+ return detail::buffer_contiguous_sequence (data, n_bytes);
1008
994
}
1009
995
#endif
1010
996
0 commit comments