variant_vector.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_WIN_VARIANT_VECTOR_H_
  5. #define BASE_WIN_VARIANT_VECTOR_H_
  6. #include <objbase.h>
  7. #include <oleauto.h>
  8. #include <type_traits>
  9. #include <utility>
  10. #include <vector>
  11. #include "base/base_export.h"
  12. #include "base/check.h"
  13. #include "base/logging.h"
  14. #include "base/win/scoped_variant.h"
  15. #include "base/win/variant_util.h"
  16. namespace base {
  17. namespace win {
  18. // This class has RAII semantics and is used to build a vector for a specific
  19. // OLE VARTYPE, and handles converting the data to a VARIANT or VARIANT
  20. // SAFEARRAY. It can be populated similarly to a STL vector<T>, but without the
  21. // compile-time requirement of knowing what element type the VariantVector will
  22. // store. The VariantVector only allows one variant type to be stored at a time.
  23. //
  24. // This class can release ownership of its contents to a VARIANT, and will
  25. // automatically allocate + populate a SAFEARRAY as needed or when explicitly
  26. // requesting that the results be released as a SAFEARRAY.
  27. class BASE_EXPORT VariantVector final {
  28. public:
  29. VariantVector();
  30. VariantVector(VariantVector&& other);
  31. VariantVector& operator=(VariantVector&& other);
  32. VariantVector(const VariantVector&) = delete;
  33. VariantVector& operator=(const VariantVector&) = delete;
  34. ~VariantVector();
  35. bool operator==(const VariantVector& other) const;
  36. bool operator!=(const VariantVector& other) const;
  37. // Returns the variant type for data stored in the VariantVector.
  38. VARTYPE Type() const { return vartype_; }
  39. // Returns the number of elements in the VariantVector.
  40. size_t Size() const { return vector_.size(); }
  41. // Returns whether or not there are any elements.
  42. bool Empty() const { return vector_.empty(); }
  43. // Resets VariantVector to its default state, releasing any managed content.
  44. void Reset();
  45. // Helper template method for selecting the correct |Insert| call based
  46. // on the underlying type that is expected for a VARTYPE.
  47. template <VARTYPE ExpectedVartype,
  48. std::enable_if_t<ExpectedVartype != VT_BOOL, int> = 0>
  49. void Insert(typename internal::VariantUtil<ExpectedVartype>::Type value) {
  50. if (vartype_ == VT_EMPTY)
  51. vartype_ = ExpectedVartype;
  52. AssertVartype<ExpectedVartype>();
  53. ScopedVariant scoped_variant;
  54. scoped_variant.Set(value);
  55. vector_.push_back(std::move(scoped_variant));
  56. }
  57. // Specialize VT_BOOL to accept a bool type instead of VARIANT_BOOL,
  58. // this is to make calling insert with VT_BOOL safer.
  59. template <VARTYPE ExpectedVartype,
  60. std::enable_if_t<ExpectedVartype == VT_BOOL, int> = 0>
  61. void Insert(bool value) {
  62. if (vartype_ == VT_EMPTY)
  63. vartype_ = ExpectedVartype;
  64. AssertVartype<ExpectedVartype>();
  65. ScopedVariant scoped_variant;
  66. scoped_variant.Set(value);
  67. vector_.push_back(std::move(scoped_variant));
  68. }
  69. // Specialize VT_DATE because ScopedVariant has a separate SetDate method,
  70. // this is because VT_R8 and VT_DATE share the same underlying type.
  71. template <>
  72. void Insert<VT_DATE>(typename internal::VariantUtil<VT_DATE>::Type value) {
  73. if (vartype_ == VT_EMPTY)
  74. vartype_ = VT_DATE;
  75. AssertVartype<VT_DATE>();
  76. ScopedVariant scoped_variant;
  77. scoped_variant.SetDate(value);
  78. vector_.push_back(std::move(scoped_variant));
  79. }
  80. // Populates a VARIANT based on what is stored, transferring ownership
  81. // of managed contents.
  82. // This is only valid when the VariantVector is empty or has a single element.
  83. // The VariantVector is then reset.
  84. VARIANT ReleaseAsScalarVariant();
  85. // Populates a VARIANT as a SAFEARRAY, even if there is only one element.
  86. // The VariantVector is then reset.
  87. VARIANT ReleaseAsSafearrayVariant();
  88. // Lexicographical comparison between a VariantVector and a VARIANT.
  89. // The return value is 0 if the variants are equal, 1 if this object is
  90. // greater than |other|, -1 if it is smaller.
  91. int Compare(const VARIANT& other, bool ignore_case = false) const;
  92. // Lexicographical comparison between a VariantVector and a SAFEARRAY.
  93. int Compare(SAFEARRAY* safearray, bool ignore_case = false) const;
  94. // Lexicographical comparison between two VariantVectors.
  95. int Compare(const VariantVector& other, bool ignore_case = false) const;
  96. private:
  97. // Returns true if the current |vartype_| is compatible with |ExpectedVartype|
  98. // for inserting into |vector_|.
  99. template <VARTYPE ExpectedVartype>
  100. void AssertVartype() const {
  101. DCHECK(internal::VariantUtil<ExpectedVartype>::IsConvertibleTo(vartype_))
  102. << "Type mismatch, " << ExpectedVartype << " is not convertible to "
  103. << Type();
  104. }
  105. // Creates a SAFEARRAY and populates it with teh values held by each VARIANT
  106. // in |vector_|, transferring ownership to the new SAFEARRAY.
  107. // The VariantVector is reset when successful.
  108. template <VARTYPE ElementVartype>
  109. SAFEARRAY* CreateAndPopulateSafearray();
  110. VARTYPE vartype_ = VT_EMPTY;
  111. std::vector<ScopedVariant> vector_;
  112. };
  113. } // namespace win
  114. } // namespace base
  115. #endif // BASE_WIN_VARIANT_VECTOR_H_