key_from_key.h 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #ifndef KEY_FROM_KEY_H
  15. #define KEY_FROM_KEY_H
  16. #include <functional>
  17. namespace isc {
  18. namespace dhcp {
  19. /// @brief Utility class which cascades two key extractors.
  20. ///
  21. /// The key extractor (a.k.a. key extraction class) is used by the
  22. /// key-based indices to obtain the indexing keys from the elements of
  23. /// a multi_index_container. The standard key extractors can be used
  24. /// to retrieve indexing key values by accessing members or methods
  25. /// exposed by the elements (objects or structures) stored in a
  26. /// multi_index_container. For example, if a container holds objects
  27. /// of type A, then the public members of object A or its accessors can
  28. /// be used by the standard extractor classes such as "member" or
  29. /// "const_mem_fun" respectively. Assume more complex scenario, where
  30. /// multi_index_container holds objects of a type A, object A exposes
  31. /// its public member B, which in turn exposes the accessor function
  32. /// returning object C. One may want to use the value C (e.g. integer)
  33. /// to index objects A in the container. This can't be solved by using
  34. /// standard key extractors because object C is nested in B and thus
  35. /// it is not directly accessible from A. However, it is possible
  36. /// to specify two distinct key extractors, one used to extract value
  37. /// C from B, another one to extract value B from A. These two extractors
  38. /// can be then wrapped by another key extractor which can be used
  39. /// to obtain index key C from object A. This key extractor is implemented
  40. /// as a functor class. The functor calls functors specified as
  41. /// template parameters to retrieve the index value from the cascaded
  42. /// structure.
  43. ///
  44. /// @tparam KeyExtractor1 extractor used to extract the key value from
  45. /// the object containing it.
  46. /// @tparam KeyExtractor2 extractor used to extract the nested object
  47. /// containing a key.
  48. template<typename KeyExtractor1, typename KeyExtractor2>
  49. class KeyFromKeyExtractor {
  50. public:
  51. typedef typename KeyExtractor1::result_type result_type;
  52. /// @brief Constructor.
  53. KeyFromKeyExtractor()
  54. : key1_(KeyExtractor1()), key2_(KeyExtractor2()) { };
  55. /// @brief Extract key value from the object hierarchy.
  56. ///
  57. /// @param arg the key value.
  58. ///
  59. /// @tparam key value type.
  60. template<typename T>
  61. result_type operator() (T& arg) const {
  62. return (key1_(key2_(arg)));
  63. }
  64. private:
  65. /// Key Extractor used to extract the key value from the
  66. /// object containing it.
  67. KeyExtractor1 key1_;
  68. /// Key Extractor used to extract the nested object
  69. /// containing a key.
  70. KeyExtractor2 key2_;
  71. };
  72. } // end of isc::dhcp namespace
  73. } // end of isc namespace
  74. #endif // KEY_FROM_KEY_H