Skip to content

Commit

Permalink
Greatly improved concepts/traits definition.
Browse files Browse the repository at this point in the history
The improvement was based on feedback[1] from "Felipe Magno de Almeida"
<felipe.m.almeida@gmail.com>.

[1] http://pastie.org/9196937
  • Loading branch information
vinipsmaker committed May 21, 2014
1 parent b9c5962 commit 6b7dc4b
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 58 deletions.
64 changes: 13 additions & 51 deletions include/boost/http/traits.hpp
Expand Up @@ -13,69 +13,31 @@ struct is_message: public std::true_type {}; //< TODO: refine concept

namespace detail {

template<class T, bool>
struct has_outgoing_state_helper
{
static constexpr bool value = false;
};

template<class T>
struct has_outgoing_state_helper<T, true>
{
static constexpr bool f(...) {return false;}

static constexpr bool f(decltype((static_cast<T const*>(0))->outgoing_state())*)
{
return std::is_same<decltype((static_cast<T*>(0))->outgoing_state()),
boost::http::outgoing_state>::value;
}

static constexpr bool value = f(0);
};
template <typename T, typename Enable = std::true_type>
struct has_outgoing_state : std::false_type
{};

template<class T, bool = is_class<T>::value /* TODO: make it work on is_final<T>::value */>
template <typename T>
struct has_outgoing_state
{
static bool constexpr value = false;
};

template<class T>
struct has_outgoing_state<T, true>
{
struct Fallback {
int outgoing_state;
};

struct Derived : T, Fallback { };

template<typename C, C>
struct ChT;

template<typename C>
static std::false_type f(ChT<int Fallback::*, &C::outgoing_state>*);

template<typename C>
static std::true_type f(...);

static bool constexpr value2 = decltype(f<Derived>(0))::value;

static bool constexpr value = value2 && has_outgoing_state_helper<T, value2>::value;
};
<T, typename std::is_convertible<decltype(static_cast<T const*>(nullptr)
->outgoing_state()),
boost::http::outgoing_state>::type>
: std::true_type
{};

template<class T>
bool constexpr is_http_socket_helper()
constexpr bool is_http_socket_helper()
{
return is_message<T>::value
&& has_outgoing_state<T>::value;
return is_message<T>::value && has_outgoing_state<T>::value;
}

} // namespace detail

template<class T>
struct is_socket
: public std::conditional<detail::is_http_socket_helper<T>(),
std::true_type, std::false_type>::type
: std::integral_constant<bool, detail::is_http_socket_helper<T>()>
{};

} // namespace http
} // namespace boost

29 changes: 22 additions & 7 deletions src/tests/socket_concept.cpp
Expand Up @@ -5,31 +5,46 @@
#include <boost/http/traits.hpp>

class A
{
};
{};

class B
struct B
{
public:
boost::http::outgoing_state outgoing_state() const;
};

class C: public B
struct C: B
{
};

class D
struct D
{
public:
int outgoing_state() const;
};

struct E
{
boost::http::outgoing_state outgoing_state();
};

struct F
{
struct X
{
operator boost::http::outgoing_state();
};

X outgoing_state() const;
};

BOOST_AUTO_TEST_CASE(Simple_attributes) {
using namespace boost::http;

BOOST_CHECK(!is_socket<int>::value);
BOOST_CHECK(!is_socket<A>::value);
BOOST_CHECK(is_socket<B>::value);
BOOST_CHECK(is_socket<C>::value);
BOOST_CHECK(!is_socket<D>::value);
BOOST_CHECK(!is_socket<E>::value);
BOOST_CHECK(is_socket<F>::value);
BOOST_CHECK(is_socket<basic_socket<embedded_server>>::value);
}

0 comments on commit 6b7dc4b

Please sign in to comment.