function_detector.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // (C) Copyright Ion Gaztanaga 2009-2013.
  4. //
  5. // Distributed under the Boost Software License, Version 1.0.
  6. // (See accompanying file LICENSE_1_0.txt or copy at
  7. // http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // See http://www.boost.org/libs/intrusive for documentation.
  10. //
  11. /////////////////////////////////////////////////////////////////////////////
  12. // This code was modified from the code posted by Alexandre Courpron in his
  13. // article "Interface Detection" in The Code Project:
  14. // http://www.codeproject.com/KB/architecture/Detector.aspx
  15. ///////////////////////////////////////////////////////////////////////////////
  16. // Copyright 2007 Alexandre Courpron
  17. //
  18. // Permission to use, copy, modify, redistribute and sell this software,
  19. // provided that this copyright notice appears on all copies of the software.
  20. ///////////////////////////////////////////////////////////////////////////////
  21. #ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
  22. #define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP
  23. #ifndef BOOST_CONFIG_HPP
  24. # include <boost/config.hpp>
  25. #endif
  26. #if defined(BOOST_HAS_PRAGMA_ONCE)
  27. # pragma once
  28. #endif
  29. namespace boost {
  30. namespace intrusive {
  31. namespace function_detector {
  32. typedef char NotFoundType;
  33. struct StaticFunctionType { NotFoundType x [2]; };
  34. struct NonStaticFunctionType { NotFoundType x [3]; };
  35. enum
  36. { NotFound = 0,
  37. StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ),
  38. NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType )
  39. };
  40. } //namespace boost {
  41. } //namespace intrusive {
  42. } //namespace function_detector {
  43. #define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \
  44. namespace boost { \
  45. namespace intrusive { \
  46. namespace function_detector { \
  47. template < class T, \
  48. class NonStaticType, \
  49. class NonStaticConstType, \
  50. class StaticType > \
  51. class DetectMember_##InstantiationKey_##Identifier { \
  52. template < NonStaticType > \
  53. struct TestNonStaticNonConst ; \
  54. \
  55. template < NonStaticConstType > \
  56. struct TestNonStaticConst ; \
  57. \
  58. template < StaticType > \
  59. struct TestStatic ; \
  60. \
  61. template <class U > \
  62. static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \
  63. \
  64. template <class U > \
  65. static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \
  66. \
  67. template <class U> \
  68. static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \
  69. \
  70. template <class U> \
  71. static NotFoundType Test( ... ); \
  72. public : \
  73. static const int check = NotFound + (sizeof(Test<T>(0, 0)) - sizeof(NotFoundType));\
  74. };\
  75. }}} //namespace boost::intrusive::function_detector {
  76. #define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \
  77. ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\
  78. ReturnType (Class::*)Params,\
  79. ReturnType (Class::*)Params const,\
  80. ReturnType (*)Params \
  81. >::check
  82. #endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP