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