callgate.hxx 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #ifndef PQXX_H_CALLGATE
  2. #define PQXX_H_CALLGATE
  3. /*
  4. Here's what a typical gate class definition looks like:
  5. #include <pqxx/internal/callgate.hxx>
  6. namespace pqxx
  7. {
  8. namespace internal
  9. {
  10. namespace gate
  11. {
  12. class PQXX_PRIVATE @gateclass@ : callgate<@host@>
  13. {
  14. friend class @client@;
  15. @gateclass@(reference x) : super(x) {}
  16. // Methods here. Use home() to access the host-class object.
  17. };
  18. } // namespace pqxx::internal::gate
  19. } // namespace pqxx::internal
  20. } // namespace pqxx
  21. */
  22. namespace pqxx
  23. {
  24. namespace internal
  25. {
  26. /// Base class for call gates.
  27. /**
  28. * A call gate defines a limited, private interface on the host class that
  29. * specified client classes can access.
  30. *
  31. * The metaphor works as follows: the gate stands in front of a "home," which is
  32. * really a class, and only lets specific friends in.
  33. *
  34. * To implement a call gate that gives client C access to host H,
  35. * - derive a gate class from callgate<H>;
  36. * - make the gate class a friend of H;
  37. * - make C a friend of the gate class; and
  38. * - implement "stuff C can do with H" as private members in the gate class.
  39. *
  40. * This special kind of "gated" friendship gives C private access to H, but only
  41. * through an expressly limited interface. The gate class can access its host
  42. * object as home().
  43. *
  44. * Keep gate classes entirely stateless. They should be ultra-lightweight
  45. * wrappers for their host classes, and be optimized away as much as possible by
  46. * the compiler. Once you start adding state, you're on a slippery slope away
  47. * from the pure, clean, limited interface pattern that gate classes are meant
  48. * to implement.
  49. *
  50. * Ideally, all member functions of the gate class should be one-liners passing
  51. * calls straight on to the host class. It can be useful however to break this
  52. * rule temporarily during inter-class refactoring.
  53. */
  54. template<typename HOME> class PQXX_PRIVATE callgate
  55. {
  56. protected:
  57. /// This class, to keep constructors easy.
  58. using super = callgate<HOME>;
  59. /// A reference to the host class. Helps keep constructors easy.
  60. using reference = HOME &;
  61. callgate(reference x) : m_home(x) {}
  62. /// The home object. The gate class has full "private" access.
  63. reference home() const noexcept { return m_home; }
  64. private:
  65. reference m_home;
  66. };
  67. } // namespace pqxx::internal
  68. } // namespace pqxx
  69. #endif