@@ -152,6 +152,39 @@ typedef struct
152152
153153namespace zmq
154154{
155+
156+ #ifdef ZMQ_CPP11
157+ namespace detail
158+ {
159+ template <class T > using void_t = void ;
160+
161+ template <class Iter >
162+ using iter_value_t = typename std::iterator_traits<Iter>::value_type;
163+
164+ template <class Range >
165+ using range_iter_t = decltype (
166+ std::begin (std::declval<typename std::remove_reference<Range>::type &>()));
167+
168+ template <class Range >
169+ using range_value_t = iter_value_t <range_iter_t <Range>>;
170+
171+ template <class T , class = void > struct is_range : std::false_type
172+ {
173+ };
174+
175+ template <class T >
176+ struct is_range <
177+ T,
178+ void_t <decltype (
179+ std::begin (std::declval<typename std::remove_reference<T>::type &>())
180+ == std::end(std::declval<typename std::remove_reference<T>::type &>()))>>
181+ : std::true_type
182+ {
183+ };
184+
185+ } // namespace detail
186+ #endif
187+
155188typedef zmq_free_fn free_fn;
156189typedef zmq_pollitem_t pollitem_t ;
157190
@@ -278,10 +311,12 @@ class message_t
278311 }
279312
280313#if defined(ZMQ_BUILD_DRAFT_API) && defined(ZMQ_CPP11)
281- // TODO: this function is too greedy, must add
282- // SFINAE for begin and end support.
283- template <typename T>
284- explicit message_t (const T &msg_) : message_t(std::begin(msg_), std::end(msg_))
314+ template <class Range ,
315+ typename = typename std::enable_if<
316+ detail::is_range<Range>::value
317+ && std::is_trivially_copyable<detail::range_value_t <Range>>::value
318+ && !std::is_same<Range, message_t >::value>::type>
319+ explicit message_t (const Range &rng) : message_t(std::begin(rng), std::end(rng))
285320 {
286321 }
287322#endif
0 commit comments