1// © 2018 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
3
4#include "unicode/utypes.h"
5
6#if !UCONFIG_NO_FORMATTING
7#ifndef __SOURCE_NUMPARSE_COMPOSITIONS__
8#define __SOURCE_NUMPARSE_COMPOSITIONS__
9
10#include "numparse_types.h"
11
12U_NAMESPACE_BEGIN
13
14// Export an explicit template instantiation of the MaybeStackArray that is used as a data member of ArraySeriesMatcher.
15// When building DLLs for Windows this is required even though no direct access to the MaybeStackArray leaks out of the i18n library.
16// (See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.)
17#if U_PF_WINDOWS <= U_PLATFORM && U_PLATFORM <= U_PF_CYGWIN
18template class U_I18N_API MaybeStackArray<const numparse::impl::NumberParseMatcher*, 3>;
19#endif
20
21namespace numparse {
22namespace impl {
23
24/**
25 * Base class for AnyMatcher and SeriesMatcher.
26 */
27// Exported as U_I18N_API for tests
28class U_I18N_API CompositionMatcher : public NumberParseMatcher {
29 protected:
30 // No construction except by subclasses!
31 CompositionMatcher() = default;
32
33 // To be overridden by subclasses (used for iteration):
34 virtual const NumberParseMatcher* const* begin() const = 0;
35
36 // To be overridden by subclasses (used for iteration):
37 virtual const NumberParseMatcher* const* end() const = 0;
38};
39
40
41// NOTE: AnyMatcher is no longer being used. The previous definition is shown below.
42// The implementation can be found in SVN source control, deleted around March 30, 2018.
43///**
44// * Composes a number of matchers, and succeeds if any of the matchers succeed. Always greedily chooses
45// * the first matcher in the list to succeed.
46// *
47// * NOTE: In C++, this is a base class, unlike ICU4J, which uses a factory-style interface.
48// *
49// * @author sffc
50// * @see SeriesMatcher
51// */
52//class AnyMatcher : public CompositionMatcher {
53// public:
54// bool match(StringSegment& segment, ParsedNumber& result, UErrorCode& status) const override;
55//
56// bool smokeTest(const StringSegment& segment) const override;
57//
58// void postProcess(ParsedNumber& result) const override;
59//
60// protected:
61// // No construction except by subclasses!
62// AnyMatcher() = default;
63//};
64
65
66/**
67 * Composes a number of matchers, running one after another. Matches the input string only if all of the
68 * matchers in the series succeed. Performs greedy matches within the context of the series.
69 *
70 * @author sffc
71 * @see AnyMatcher
72 */
73// Exported as U_I18N_API for tests
74class U_I18N_API SeriesMatcher : public CompositionMatcher {
75 public:
76 bool match(StringSegment& segment, ParsedNumber& result, UErrorCode& status) const override;
77
78 bool smokeTest(const StringSegment& segment) const override;
79
80 void postProcess(ParsedNumber& result) const override;
81
82 virtual int32_t length() const = 0;
83
84 protected:
85 // No construction except by subclasses!
86 SeriesMatcher() = default;
87};
88
89/**
90 * An implementation of SeriesMatcher that references an array of matchers.
91 *
92 * The object adopts the array, but NOT the matchers contained inside the array.
93 */
94// Exported as U_I18N_API for tests
95class U_I18N_API ArraySeriesMatcher : public SeriesMatcher {
96 public:
97 ArraySeriesMatcher(); // WARNING: Leaves the object in an unusable state
98
99 typedef MaybeStackArray<const NumberParseMatcher*, 3> MatcherArray;
100
101 /** The array is std::move'd */
102 ArraySeriesMatcher(MatcherArray& matchers, int32_t matchersLen);
103
104 UnicodeString toString() const override;
105
106 int32_t length() const override;
107
108 protected:
109 const NumberParseMatcher* const* begin() const override;
110
111 const NumberParseMatcher* const* end() const override;
112
113 private:
114 MatcherArray fMatchers;
115 int32_t fMatchersLen;
116};
117
118
119} // namespace impl
120} // namespace numparse
121U_NAMESPACE_END
122
123#endif //__SOURCE_NUMPARSE_COMPOSITIONS__
124#endif /* #if !UCONFIG_NO_FORMATTING */
125