ArgTraits.h 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. // -*- Mode: c++; c-basic-offset: 4; tab-width: 4; -*-
  2. /******************************************************************************
  3. *
  4. * file: ArgTraits.h
  5. *
  6. * Copyright (c) 2007, Daniel Aarno, Michael E. Smoot .
  7. * Copyright (c) 2017 Google LLC
  8. * All rights reserved.
  9. *
  10. * See the file COPYING in the top directory of this distribution for
  11. * more information.
  12. *
  13. * THE SOFTWARE IS PROVIDED _AS IS_, WITHOUT WARRANTY OF ANY KIND, EXPRESS
  14. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  16. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  18. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  19. * DEALINGS IN THE SOFTWARE.
  20. *
  21. *****************************************************************************/
  22. // This is an internal tclap file, you should probably not have to
  23. // include this directly
  24. #ifndef TCLAP_ARGTRAITS_H
  25. #define TCLAP_ARGTRAITS_H
  26. namespace TCLAP {
  27. // We use two empty structs to get compile type specialization
  28. // function to work
  29. /**
  30. * A value like argument value type is a value that can be set using
  31. * operator>>. This is the default value type.
  32. */
  33. struct ValueLike {
  34. typedef ValueLike ValueCategory;
  35. virtual ~ValueLike() {}
  36. };
  37. /**
  38. * A string like argument value type is a value that can be set using
  39. * operator=(string). Useful if the value type contains spaces which
  40. * will be broken up into individual tokens by operator>>.
  41. */
  42. struct StringLike {
  43. virtual ~StringLike() {}
  44. };
  45. /**
  46. * A class can inherit from this object to make it have string like
  47. * traits. This is a compile time thing and does not add any overhead
  48. * to the inherenting class.
  49. */
  50. struct StringLikeTrait {
  51. typedef StringLike ValueCategory;
  52. virtual ~StringLikeTrait() {}
  53. };
  54. /**
  55. * A class can inherit from this object to make it have value like
  56. * traits. This is a compile time thing and does not add any overhead
  57. * to the inherenting class.
  58. */
  59. struct ValueLikeTrait {
  60. typedef ValueLike ValueCategory;
  61. virtual ~ValueLikeTrait() {}
  62. };
  63. /**
  64. * Arg traits are used to get compile type specialization when parsing
  65. * argument values. Using an ArgTraits you can specify the way that
  66. * values gets assigned to any particular type during parsing. The two
  67. * supported types are StringLike and ValueLike. ValueLike is the
  68. * default and means that operator>> will be used to assign values to
  69. * the type.
  70. */
  71. template<typename T>
  72. class ArgTraits {
  73. // This is a bit silly, but what we want to do is:
  74. // 1) If there exists a specialization of ArgTraits for type X,
  75. // use it.
  76. //
  77. // 2) If no specialization exists but X has the typename
  78. // X::ValueCategory, use the specialization for X::ValueCategory.
  79. //
  80. // 3) If neither (1) nor (2) defines the trait, use the default
  81. // which is ValueLike.
  82. // This is the "how":
  83. //
  84. // test<T>(0) (where 0 is the NULL ptr) will match
  85. // test(typename C::ValueCategory*) iff type T has the
  86. // corresponding typedef. If it does not test(...) will be
  87. // matched. This allows us to determine if T::ValueCategory
  88. // exists by checking the sizeof for the test function (return
  89. // value must have different sizeof).
  90. template<typename C> static short test(typename C::ValueCategory*);
  91. template<typename C> static long test(...);
  92. static const bool hasTrait = sizeof(test<T>(0)) == sizeof(short);
  93. template <typename C, bool>
  94. struct DefaultArgTrait {
  95. typedef ValueLike ValueCategory;
  96. };
  97. template <typename C>
  98. struct DefaultArgTrait<C, true> {
  99. typedef typename C::ValueCategory ValueCategory;
  100. };
  101. public:
  102. typedef typename DefaultArgTrait<T, hasTrait>::ValueCategory ValueCategory;
  103. };
  104. } // namespace
  105. #endif