callgate.hxx 2.2 KB

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