mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Generalize the accepts_type trait a bit, and move to internals.h, rename the _invoke_functor function, and templatize it to avoid need to depend on Packet defintion
This commit is contained in:
@@ -30,6 +30,10 @@
|
||||
#ifndef TINS_INTERNALS_H
|
||||
#define TINS_INTERNALS_H
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <stdint.h>
|
||||
@@ -200,6 +204,34 @@ template<>
|
||||
struct is_unsigned_integral<uint64_t> {
|
||||
static const bool value = true;
|
||||
};
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
|
||||
// Part of C++14 standard library
|
||||
template<bool B, class T = void>
|
||||
using enable_if_t = typename std::enable_if<B,T>::type;
|
||||
|
||||
// Template metaprogramming trait to determine if a functor can accept another parameter as an argument
|
||||
template <class T, class P, class=void>
|
||||
struct accepts_type : std::false_type { };
|
||||
|
||||
template <class T, class P>
|
||||
struct accepts_type<T, P, enable_if_t<
|
||||
std::is_same< decltype( std::declval<T>()(std::declval<P>()) ), bool>::value
|
||||
>> : std::true_type { };
|
||||
|
||||
// use enable_if to invoke the Packet& version of the sniff_loop handler if possible - otherwise fail to old behavior
|
||||
template <class Functor, class Packet>
|
||||
bool invoke_loop_cb(Functor& f, Packet& p, typename std::enable_if<accepts_type<Functor, Packet>::value, bool>::type* = 0) {
|
||||
return f(p);
|
||||
}
|
||||
|
||||
template <class Functor, class Packet>
|
||||
bool invoke_loop_cb(Functor& f, Packet& p, typename std::enable_if<!accepts_type<Functor, Packet>::value, bool>::type* = 0) {
|
||||
return f(*p.pdu());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Internals
|
||||
} // namespace Tins
|
||||
/**
|
||||
|
||||
@@ -43,10 +43,6 @@
|
||||
#include "exceptions.h"
|
||||
#include "internals.h"
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
#include <type_traits>
|
||||
#endif
|
||||
|
||||
namespace Tins {
|
||||
class SnifferIterator;
|
||||
class SnifferConfiguration;
|
||||
@@ -577,39 +573,13 @@ namespace Tins {
|
||||
unsigned _timeout;
|
||||
};
|
||||
|
||||
#if TINS_IS_CXX11
|
||||
|
||||
template<bool B, class T = void>
|
||||
using enable_if_t = typename std::enable_if<B,T>::type;
|
||||
|
||||
/* Template metaprogramming trait to determine if a functor can accept a Packet& as an argument */
|
||||
template <class T, class=void>
|
||||
struct takes_packet : std::false_type { };
|
||||
|
||||
template <class T>
|
||||
struct takes_packet<T, enable_if_t<
|
||||
std::is_same< decltype( std::declval<T>()(std::declval<Packet>()) ), bool>::value
|
||||
>> : std::true_type { };
|
||||
|
||||
/* use enable_if to invoke the Packet& version of the sniff_loop handler if possible - otherwise fail to old behavior */
|
||||
template <class Functor>
|
||||
bool _invoke_functor(Functor& f, Packet& p, typename std::enable_if<takes_packet<Functor>::value, bool>::type* = 0) {
|
||||
return f(p);
|
||||
}
|
||||
|
||||
template <class Functor>
|
||||
bool _invoke_functor(Functor& f, Packet& p, typename std::enable_if<!takes_packet<Functor>::value, bool>::type* = 0) {
|
||||
return f(*p.pdu());
|
||||
}
|
||||
#endif
|
||||
|
||||
template<class Functor>
|
||||
void Tins::BaseSniffer::sniff_loop(Functor function, uint32_t max_packets) {
|
||||
for(iterator it = begin(); it != end(); ++it) {
|
||||
try {
|
||||
// If the functor returns false, we're done
|
||||
#if TINS_IS_CXX11
|
||||
if (!_invoke_functor(function, *it))
|
||||
if (!Tins::Internals::invoke_loop_cb<Functor, Packet>(function, *it))
|
||||
return;
|
||||
#else
|
||||
if(!function(*it))
|
||||
|
||||
Reference in New Issue
Block a user