1f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifndef MARISA_BASE_H_
2f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_BASE_H_
3f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
4f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// Visual C++ does not provide stdint.h.
5f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifndef _MSC_VER
6f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <stdint.h>
7f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // _MSC_VER
8f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
9f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef __cplusplus
10f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <cstddef>
11f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <new>
12f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#else  // __cplusplus
13f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#include <stddef.h>
14f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // __cplusplus
15f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
16132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#if defined(__ANDROID__)
17132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#include <android/log.h>
18efeb3428f25c1d8c547ab2678c0baa580a8226f0Przemyslaw Szczepaniak#include <stdio.h>
19132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#endif  // __ANDROID__
20132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin
21f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef __cplusplus
22f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathextern "C" {
23f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // __cplusplus
24f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
25f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef _MSC_VER
26f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef unsigned __int8  marisa_uint8;
27f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef unsigned __int16 marisa_uint16;
28f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef unsigned __int32 marisa_uint32;
29f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef unsigned __int64 marisa_uint64;
30f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#else  // _MSC_VER
31f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef uint8_t  marisa_uint8;
32f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef uint16_t marisa_uint16;
33f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef uint32_t marisa_uint32;
34f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef uint64_t marisa_uint64;
35f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // _MSC_VER
36f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
37f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_UINT8_MAX  ((marisa_uint8)-1)
38f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_UINT16_MAX ((marisa_uint16)-1)
39f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_UINT32_MAX ((marisa_uint32)-1)
40f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_UINT64_MAX ((marisa_uint64)-1)
41f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_SIZE_MAX   ((size_t)-1)
42f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
43f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_ZERO_TERMINATED MARISA_UINT32_MAX
44f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_NOT_FOUND       MARISA_UINT32_MAX
45f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_MISMATCH        MARISA_UINT32_MAX
46f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
47f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_MAX_LENGTH     (MARISA_UINT32_MAX - 1)
48f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_MAX_NUM_KEYS   (MARISA_UINT32_MAX - 1)
49f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
50f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// marisa_status provides a list of error codes. Most of functions in
51f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// libmarisa throw or return an error code.
52f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef enum marisa_status_ {
53f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_OK means that a requested operation has succeeded.
54f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_OK               = 0,
55f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
56f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_HANDLE_ERROR means that a given handle is invalid.
57f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_HANDLE_ERROR     = 1,
58f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
59f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_STATE_ERROR means that an object is not ready for a requested
60f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // operation. For example, an operation to modify a fixed container throws
61f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // an exception with this error code.
62f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_STATE_ERROR      = 2,
63f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
64f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_PARAM_ERROR means that a given argument is invalid. For example,
65f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // some functions throw an exception with this error code when an
66f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // out-of-range value or a NULL pointer is given.
67f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_PARAM_ERROR      = 3,
68f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
69f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_SIZE_ERROR means that a size exceeds its limit. This error code
70f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // is used when a building dictionary is too large or std::length_error is
71f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // catched.
72f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_SIZE_ERROR       = 4,
73f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
74f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_MEMORY_ERROR means that a memory allocation has failed.
75f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_MEMORY_ERROR     = 5,
76f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
77f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_IO_ERROR means that an I/O failure.
78f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_IO_ERROR         = 6,
79f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
80f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_UNEXPECTED_ERROR means that an unexpected error has occurred.
81f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_UNEXPECTED_ERROR = 7
82f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} marisa_status;
83f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
84f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// marisa_strerror() returns a name of an error code.
85f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathconst char *marisa_strerror(marisa_status status);
86f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
87f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// Flags and masks for dictionary settings are defined as follows. Please note
88f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// that unspecified value/flags will be replaced with default value/flags.
89f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef enum marisa_flags_ {
90f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // A dictionary consinsts of 3 tries in default. If you want to change the
91f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // number of tries, please give it with other flags.
92f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_MIN_NUM_TRIES     = 0x00001,
93f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_MAX_NUM_TRIES     = 0x000FF,
94f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_DEFAULT_NUM_TRIES = 0x00003,
95f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
96f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // MARISA_PATRICIA_TRIE is usually a better choice. MARISA_PREFIX_TRIE is
97f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // provided for comparing prefix/patricia tries.
98f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_PATRICIA_TRIE     = 0x00100,
99f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_PREFIX_TRIE       = 0x00200,
100f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_DEFAULT_TRIE      = MARISA_PATRICIA_TRIE,
101f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
102f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // There are 3 kinds of TAIL implementations.
103f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // - MARISA_WITHOUT_TAIL:
104f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   builds a dictionary without a TAIL. Its last trie has only 1-byte
105f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   labels.
106f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // - MARISA_BINARY_TAIL:
107f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   builds a dictionary with a binary-mode TAIL. Its last labels are stored
108f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   as binary data.
109f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // - MARISA_TEXT_TAIL:
110f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   builds a dictionary with a text-mode TAIL if its last labels do not
111f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   contain NULL characters. The last labels are stored as zero-terminated
112f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  //   string. Otherwise, a dictionary is built with a binary-mode TAIL.
113f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_WITHOUT_TAIL      = 0x01000,
114f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_BINARY_TAIL       = 0x02000,
115f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_TEXT_TAIL         = 0x04000,
116f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_DEFAULT_TAIL      = MARISA_TEXT_TAIL,
117f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
118f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // libmarisa arranges nodes in ascending order of their labels
119f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // (MARISA_LABEL_ORDER) or in descending order of their weights
120f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // (MARISA_WEIGHT_ORDER). MARISA_WEIGHT_ORDER is generally a better choice
121f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // because it enables faster lookups, but MARISA_LABEL_ORDER is still useful
122f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // if an application needs to predict keys in label order.
123f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_LABEL_ORDER       = 0x10000,
124f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_WEIGHT_ORDER      = 0x20000,
125f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_DEFAULT_ORDER     = MARISA_WEIGHT_ORDER,
126f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
127f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // The default settings. 0 is equivalent to MARISA_DEFAULT_FLAGS.
128f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_DEFAULT_FLAGS     = MARISA_DEFAULT_NUM_TRIES
129f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      | MARISA_DEFAULT_TRIE | MARISA_DEFAULT_TAIL | MARISA_DEFAULT_ORDER,
130f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
131f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_NUM_TRIES_MASK    = 0x000FF,
132f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_TRIE_MASK         = 0x00F00,
133f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_TAIL_MASK         = 0x0F000,
134f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_ORDER_MASK        = 0xF0000,
135f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_FLAGS_MASK        = 0xFFFFF
136f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath} marisa_flags;
137f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
138f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef __cplusplus
139f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath}  // extern "C"
140f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // __cplusplus
141f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
142f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath//#include <cstddef>
143f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
144f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef __cplusplus
145f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathnamespace marisa {
146f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
147f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef ::marisa_uint8  UInt8;
148f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef ::marisa_uint16 UInt16;
149f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef ::marisa_uint32 UInt32;
150f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef ::marisa_uint64 UInt64;
151f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
152f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtypedef ::marisa_status Status;
153f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
154f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// An exception object stores a filename, a line number and an error code.
155f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathclass Exception {
156f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath public:
157f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Exception(const char *filename, int line, Status status)
158f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      : filename_(filename), line_(line), status_(status) {}
159f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Exception(const Exception &ex)
160f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath      : filename_(ex.filename_), line_(ex.line_), status_(ex.status_) {}
161f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
162f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Exception &operator=(const Exception &rhs) {
163f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    filename_ = rhs.filename_;
164f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    line_ = rhs.line_;
165f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    status_ = rhs.status_;
166f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return *this;
167f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
168f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
169f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  const char *filename() const {
170f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return filename_;
171f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
172f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  int line() const {
173f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return line_;
174f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
175f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Status status() const {
176f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return status_;
177f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
178f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
179f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  // Same as std::exception, what() returns an error message.
180f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  const char *what() const {
181f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath    return ::marisa_strerror(status_);
182f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  }
183f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
184f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath private:
185f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  const char *filename_;
186f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  int line_;
187f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  Status status_;
188f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath};
189f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
190f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// MARISA_THROW adds a filename and a line number to an exception.
191132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#if !defined(__ANDROID__)
192f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_THROW(status) \
193f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  (throw Exception(__FILE__, __LINE__, status))
194132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#else
195132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin
196132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkininline int android_log_exception(int status) {
197132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin  char tmpbuf[100];
198132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin  snprintf(tmpbuf, sizeof(tmpbuf), "marisa exception: %d", status);
199132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin  __android_log_write(ANDROID_LOG_ERROR, "marisa-trie", tmpbuf);
200132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin  return 0;
201132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin}
202132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin
203132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#define MARISA_THROW(status) \
204132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin  (android_log_exception(status))
205132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin
206132a22eef895fffa8d8f25560aa57f0d8a49839aAlexander Gutkin#endif  // __ANDROID__
207f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
208f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// MARISA_THROW_IF throws an exception with `status' if `cond' is true.
209f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_THROW_IF(cond, status) \
210f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  (void)((!(cond)) || (MARISA_THROW(status), 0))
211f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
212f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// MARISA_DEBUG_IF is used for debugging. For example, MARISA_DEBUG_IF is used
213f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// to find out-of-range accesses in marisa::Vector, marisa::IntVector, etc.
214f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#ifdef _DEBUG
215f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_DEBUG_IF(cond, status) \
216f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_THROW_IF(cond, status)
217f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#else
218f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#define MARISA_DEBUG_IF(cond, status)
219f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif
220f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
221f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath// To not include <algorithm> only for std::swap().
222f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathtemplate <typename T>
223f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamathvoid Swap(T *lhs, T *rhs) {
224f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  MARISA_THROW_IF((lhs == NULL) || (rhs == NULL), MARISA_PARAM_ERROR);
225f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  T temp = *lhs;
226f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  *lhs = *rhs;
227f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath  *rhs = temp;
228f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath}
229f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
230f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath}  // namespace marisa
231f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // __cplusplus
232f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath
233f163f6985a63328d07e3de249ad3daf4a0c67d8aNarayan Kamath#endif  // MARISA_BASE_H_
234