variant_vector.h 5.1 KB

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