Welcome to mirror list, hosted at ThFree Co, Russian Federation.

query_params.hpp « search - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 049c0f7de9a217641c56fc83863e54bf1bcd0f64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#pragma once

#include "indexer/scales.hpp"

#include "coding/string_utf8_multilang.hpp"

#include "base/assert.hpp"
#include "base/small_set.hpp"
#include "base/string_utils.hpp"

#include <algorithm>
#include <cstdint>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>

namespace search
{
class TokenRange;

class QueryParams
{
public:
  using String = strings::UniString;
  using TypeIndices = std::vector<uint32_t>;
  using Langs = base::SafeSmallSet<StringUtf8Multilang::kMaxSupportedLanguages>;

  class Token
  {
  public:
    Token() = default;
    Token(String const & original) : m_original(original) {}

    void AddSynonym(std::string const & s);
    void AddSynonym(String const & s);

    // Calls |fn| on the original token and on synonyms.
    template <typename Fn>
    std::enable_if_t<std::is_same<std::result_of_t<Fn(String)>, void>::value> ForEach(
        Fn && fn) const
    {
      fn(m_original);
      std::for_each(m_synonyms.begin(), m_synonyms.end(), std::forward<Fn>(fn));
    }

    // Calls |fn| on the original token and on synonyms until |fn| return false.
    template <typename Fn>
    std::enable_if_t<std::is_same<std::result_of_t<Fn(String)>, bool>::value> ForEach(
        Fn && fn) const
    {
      if (!fn(m_original))
        return;
      for (auto const & synonym : m_synonyms)
      {
        if (!fn(synonym))
          return;
      }
    }

    template <typename Fn>
    std::enable_if_t<std::is_same<std::result_of_t<Fn(String)>, bool>::value, bool> AnyOf(
        Fn && fn) const
    {
      if (fn(m_original))
        return true;

      return std::any_of(m_synonyms.begin(), m_synonyms.end(), std::forward<Fn>(fn));
    }

    String const & GetOriginal() const { return m_original; }

    void Clear()
    {
      m_original.clear();
      m_synonyms.clear();
    }

  private:
    friend std::string DebugPrint(QueryParams::Token const & token);

    String m_original;
    std::vector<String> m_synonyms;
  };

  QueryParams() = default;

  template <typename It>
  void InitNoPrefix(It tokenBegin, It tokenEnd)
  {
    Clear();
    for (; tokenBegin != tokenEnd; ++tokenBegin)
      m_tokens.emplace_back(*tokenBegin);
    m_typeIndices.resize(GetNumTokens());
    AddSynonyms();
  }

  template <typename It>
  void InitWithPrefix(It tokenBegin, It tokenEnd, String const & prefix)
  {
    Clear();
    for (; tokenBegin != tokenEnd; ++tokenBegin)
      m_tokens.emplace_back(*tokenBegin);
    m_prefixToken = Token(prefix);
    m_hasPrefix = true;
    m_typeIndices.resize(GetNumTokens());
    AddSynonyms();
  }

  size_t GetNumTokens() const { return m_hasPrefix ? m_tokens.size() + 1 : m_tokens.size(); }

  bool LastTokenIsPrefix() const { return m_hasPrefix; }

  bool IsEmpty() const { return GetNumTokens() == 0; }
  void Clear();

  bool IsCategorySynonym(size_t i) const;
  TypeIndices & GetTypeIndices(size_t i);
  TypeIndices const & GetTypeIndices(size_t i) const;

  bool IsPrefixToken(size_t i) const;
  Token const & GetToken(size_t i) const;
  Token & GetToken(size_t i);

  // Returns true if all tokens in |range| have integral synonyms.
  bool IsNumberTokens(TokenRange const & range) const;

  void RemoveToken(size_t i);

  Langs & GetLangs() { return m_langs; }
  Langs const & GetLangs() const { return m_langs; }
  bool LangExists(int8_t lang) const { return m_langs.Contains(lang); }

  void SetCategorialRequest(bool isCategorial) { m_isCategorialRequest = isCategorial; }
  bool IsCategorialRequest() const { return m_isCategorialRequest; }

  int GetScale() const { return m_scale; }

private:
  friend std::string DebugPrint(QueryParams const & params);

  void AddSynonyms();

  std::vector<Token> m_tokens;
  Token m_prefixToken;
  bool m_hasPrefix = false;
  bool m_isCategorialRequest = false;

  std::vector<TypeIndices> m_typeIndices;

  Langs m_langs;
  int m_scale = scales::GetUpperScale();
};
}  // namespace search