diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-08-22 17:18:24 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-08-22 17:18:24 +0200 |
commit | 2959b2348fe969458cff8add0ed85eff4c93df97 (patch) | |
tree | 16e5d914bea5b87bd60775c609b5190b65deeaa5 | |
parent | 83f40728c71c68007119f068b635f9c9ca2e2fc2 (diff) |
Improve "callable" detection in serializer stream interface
This version "sees" operator() in the base.
-rw-r--r-- | xml/serializer | 13 | ||||
-rw-r--r-- | xml/serializer.ixx | 11 |
2 files changed, 10 insertions, 14 deletions
diff --git a/xml/serializer b/xml/serializer index ee5779b..6251392 100644 --- a/xml/serializer +++ b/xml/serializer @@ -292,16 +292,11 @@ namespace xml std::size_t depth_; }; - // Stream-like interface for serializer. If the passed argument - // is a function with the void f(serializer&) signature or is a - // function object with the void operator() (serializer&) const - // operator, then this function (object) is called with the passed - // serializer. Otherwise, the argument is passed to the serializer's - // characters() function. + // Stream-like interface for serializer. If the passed argument is + // callable with the serializer as its argument, then this function + // (object) is called with the passed serializer. Otherwise, the + // argument is passed to the serializer's characters() function. // - serializer& - operator<< (serializer&, void (*func) (serializer&)); - template <typename T> serializer& operator<< (serializer&, const T& value); diff --git a/xml/serializer.ixx b/xml/serializer.ixx index 465fede..59d329f 100644 --- a/xml/serializer.ixx +++ b/xml/serializer.ixx @@ -155,26 +155,27 @@ namespace xml namespace details { - // Detect whether T defines void operator(A) const. + // Detect whether T is callable with argument A. // template <typename T, typename A> - struct is_functor + struct is_callable { typedef char no[1]; typedef char yes[2]; + template <typename X> static X declval (); - template <typename X, X> struct check; + template <int> struct check; template <typename> static no& test (...); template <typename X> - static yes& test (check<void (X::*) (A) const, &X::operator ()>*); + static yes& test (check<sizeof (declval<X> () (declval<A> ()), 0)>*); static const bool value = sizeof (test<T> (0)) == sizeof (yes); }; - template <typename T, bool = is_functor<T, serializer&>::value> + template <typename T, bool = is_callable<const T&, serializer&>::value> struct inserter; template <typename T> |