aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2020-07-20 22:10:44 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2020-07-20 22:10:44 +0000
commitb7cf80ced84df9148b968e6830d22ceccad5bcbf (patch)
tree159f00cd01a7aa45f76f71f43f672a58c8f54197
parentd5f74d315e62f5d93a346252d924483979f55ea9 (diff)
parent6705e199cac3df9b1f27a3f19f388fb9a01952c7 (diff)
downloadmarisa-trie-b7cf80ced84df9148b968e6830d22ceccad5bcbf.tar.gz
Merge "Merge tag v0.2.6 (e54f296bb52d16693931c8b963744931ef1e37f7)." am: dd2e280359 am: 2ea6e854d5 am: a7cf57e5e4 am: 4362d91ea1 am: 6705e199ca
Original change: https://android-review.googlesource.com/c/platform/external/marisa-trie/+/1364599 Change-Id: I1cb038177f96183ed4f155ff4761f721cf0a7c9f
-rw-r--r--.gitignore57
-rw-r--r--AUTHORS1
-rw-r--r--COPYING.md34
l---------LICENSE1
-rw-r--r--METADATA17
-rw-r--r--MODULE_LICENSE_BSD0
-rw-r--r--Makefile.am24
-rw-r--r--README.md61
-rw-r--r--bindings/Makefile16
-rw-r--r--bindings/marisa-swig.cxx253
-rw-r--r--bindings/marisa-swig.h183
-rw-r--r--bindings/marisa-swig.i28
-rw-r--r--bindings/perl/Makefile.PL7
-rw-r--r--bindings/perl/benchmark.pl93
-rw-r--r--bindings/perl/marisa-swig.cxx253
-rw-r--r--bindings/perl/marisa-swig.h183
-rw-r--r--bindings/perl/marisa-swig_wrap.cxx5160
-rw-r--r--bindings/perl/marisa.pm297
-rw-r--r--bindings/perl/sample.pl62
-rw-r--r--bindings/python/benchmark.py81
-rw-r--r--bindings/python/marisa-swig.cxx253
-rw-r--r--bindings/python/marisa-swig.h183
-rw-r--r--bindings/python/marisa-swig_wrap.cxx6090
-rw-r--r--bindings/python/marisa.py206
-rw-r--r--bindings/python/sample.py57
-rw-r--r--bindings/python/setup.py9
-rw-r--r--bindings/ruby/benchmark.rb90
-rw-r--r--bindings/ruby/extconf.rb5
-rw-r--r--bindings/ruby/marisa-swig.cxx253
-rw-r--r--bindings/ruby/marisa-swig.h183
-rw-r--r--bindings/ruby/marisa-swig_wrap.cxx4708
-rw-r--r--bindings/ruby/sample.rb61
-rw-r--r--configure.ac278
-rw-r--r--docs/readme.en.html752
-rw-r--r--docs/readme.ja.html762
-rw-r--r--docs/style.css245
-rw-r--r--include/Makefile.am3
-rw-r--r--include/marisa.h14
-rw-r--r--include/marisa/Makefile.am13
-rw-r--r--include/marisa/agent.h73
-rw-r--r--include/marisa/base.h196
-rw-r--r--include/marisa/exception.h82
-rw-r--r--include/marisa/iostream.h18
-rw-r--r--include/marisa/key.h85
-rw-r--r--include/marisa/keyset.h80
-rw-r--r--include/marisa/query.h71
-rw-r--r--include/marisa/scoped-array.h48
-rw-r--r--include/marisa/scoped-ptr.h52
-rw-r--r--include/marisa/stdio.h15
-rw-r--r--include/marisa/trie.h64
-rw-r--r--lib/Makefile.am1
-rw-r--r--lib/marisa/Makefile.am19
-rw-r--r--lib/marisa/agent.cc51
-rw-r--r--lib/marisa/grimoire/Makefile.am8
-rw-r--r--lib/marisa/grimoire/algorithm.h26
-rw-r--r--lib/marisa/grimoire/algorithm/Makefile.am2
-rw-r--r--lib/marisa/grimoire/algorithm/sort.h196
-rw-r--r--lib/marisa/grimoire/intrin.h138
-rw-r--r--lib/marisa/grimoire/io.h18
-rw-r--r--lib/marisa/grimoire/io/Makefile.am17
-rw-r--r--lib/marisa/grimoire/io/mapper.cc163
-rw-r--r--lib/marisa/grimoire/io/mapper.h67
-rw-r--r--lib/marisa/grimoire/io/reader.cc147
-rw-r--r--lib/marisa/grimoire/io/reader.h66
-rw-r--r--lib/marisa/grimoire/io/writer.cc148
-rw-r--r--lib/marisa/grimoire/io/writer.h65
-rw-r--r--lib/marisa/grimoire/trie.h16
-rw-r--r--lib/marisa/grimoire/trie/Makefile.am23
-rw-r--r--lib/marisa/grimoire/trie/cache.h81
-rw-r--r--lib/marisa/grimoire/trie/config.h155
-rw-r--r--lib/marisa/grimoire/trie/entry.h81
-rw-r--r--lib/marisa/grimoire/trie/header.h61
-rw-r--r--lib/marisa/grimoire/trie/history.h65
-rw-r--r--lib/marisa/grimoire/trie/key.h226
-rw-r--r--lib/marisa/grimoire/trie/louds-trie.cc878
-rw-r--r--lib/marisa/grimoire/trie/louds-trie.h134
-rw-r--r--lib/marisa/grimoire/trie/range.h115
-rw-r--r--lib/marisa/grimoire/trie/state.h117
-rw-r--r--lib/marisa/grimoire/trie/tail.cc218
-rw-r--r--lib/marisa/grimoire/trie/tail.h72
-rw-r--r--lib/marisa/grimoire/vector.h18
-rw-r--r--lib/marisa/grimoire/vector/Makefile.am17
-rw-r--r--lib/marisa/grimoire/vector/bit-vector.cc844
-rw-r--r--lib/marisa/grimoire/vector/bit-vector.h179
-rw-r--r--lib/marisa/grimoire/vector/flat-vector.h205
-rw-r--r--lib/marisa/grimoire/vector/pop-count.h110
-rw-r--r--lib/marisa/grimoire/vector/rank-index.h82
-rw-r--r--lib/marisa/grimoire/vector/vector.h256
-rw-r--r--lib/marisa/keyset.cc181
-rw-r--r--lib/marisa/trie.cc249
-rw-r--r--m4/.gitkeep0
-rw-r--r--marisa.pc.in11
-rw-r--r--tests/Makefile.am30
-rw-r--r--tests/base-test.cc313
-rw-r--r--tests/io-test.cc252
-rw-r--r--tests/marisa-assert.h26
-rw-r--r--tests/marisa-test.cc389
-rw-r--r--tests/trie-test.cc506
-rw-r--r--tests/vector-test.cc466
-rw-r--r--tools/Makefile.am40
-rw-r--r--tools/cmdopt.cc298
-rw-r--r--tools/cmdopt.h58
-rw-r--r--tools/marisa-benchmark.cc420
-rw-r--r--tools/marisa-build.cc207
-rw-r--r--tools/marisa-common-prefix-search.cc144
-rw-r--r--tools/marisa-dump.cc153
-rw-r--r--tools/marisa-lookup.cc111
-rw-r--r--tools/marisa-predictive-search.cc144
-rw-r--r--tools/marisa-reverse-lookup.cc111
-rw-r--r--vs2008/base-test/base-test.vcproj200
-rw-r--r--vs2008/io-test/io-test.vcproj199
-rw-r--r--vs2008/libmarisa/libmarisa.vcproj349
-rw-r--r--vs2008/marisa-benchmark/marisa-benchmark.vcproj203
-rw-r--r--vs2008/marisa-build/marisa-build.vcproj203
-rw-r--r--vs2008/marisa-common-prefix-search/marisa-common-prefix-search.vcproj203
-rw-r--r--vs2008/marisa-dump/marisa-dump.vcproj203
-rw-r--r--vs2008/marisa-lookup/marisa-lookup.vcproj203
-rw-r--r--vs2008/marisa-predictive-search/marisa-predictive-search.vcproj203
-rw-r--r--vs2008/marisa-reverse-lookup/marisa-reverse-lookup.vcproj203
-rw-r--r--vs2008/marisa-test/marisa-test.vcproj199
-rw-r--r--vs2008/trie-test/trie-test.vcproj199
-rw-r--r--vs2008/vector-test/vector-test.vcproj199
-rw-r--r--vs2008/vs2008.sln123
-rw-r--r--vs2008/vs2008.suobin0 -> 34304 bytes
124 files changed, 33843 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1635a1a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,57 @@
+.deps/
+.libs/
+*.a
+*.app
+*.dll
+*.dylib
+*.exe
+*.la
+*.lai
+*.lib
+*.lo
+*.log
+*.m4
+*.o
+*.obj
+*.out
+*.slo
+*.so
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache/
+compile
+config.guess
+config.log
+config.status
+config.sub
+configure
+depcomp
+install-sh
+libtool
+ltmain.sh
+marisa.pc
+missing
+stamp-h1
+test-driver
+tests/base-test
+tests/base-test.trs
+tests/io-test
+tests/io-test.dat
+tests/io-test.trs
+tests/marisa-test
+tests/marisa-test.dat
+tests/marisa-test.trs
+tests/trie-test
+tests/trie-test.dat
+tests/trie-test.trs
+tests/vector-test
+tests/vector-test.dat
+tests/vector-test.trs
+tools/marisa-benchmark
+tools/marisa-build
+tools/marisa-common-prefix-search
+tools/marisa-dump
+tools/marisa-lookup
+tools/marisa-predictive-search
+tools/marisa-reverse-lookup
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..4ee985a
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1 @@
+Susumu Yata <susumu.yata@gmail.com>
diff --git a/COPYING.md b/COPYING.md
new file mode 100644
index 0000000..8b63336
--- /dev/null
+++ b/COPYING.md
@@ -0,0 +1,34 @@
+### COPYING
+
+libmarisa and its command line tools are dual-licensed under the BSD 2-clause license and the LGPL.
+
+#### The BSD 2-clause license
+
+Copyright (c) 2010-2019, Susumu Yata
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#### The LGPL 2.1 or any later version
+
+marisa-trie - A static and space-efficient trie data structure.
+Copyright (C) 2010-2019 Susumu Yata
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..3a39080
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+COPYING.md \ No newline at end of file
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..21a4d89
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,17 @@
+name: "marisa-trie"
+description:
+ "A space-efficient trie data structure."
+
+third_party {
+ url {
+ type: HOMEPAGE
+ value: "https://github.com/s-yata/marisa-trie/"
+ }
+ url {
+ type: GIT
+ value: "https://github.com/s-yata/marisa-trie.git"
+ }
+ version: "v0.2.6"
+ last_upgrade_date { year: 2020 month: 7 day: 17 }
+ license_type: NOTICE
+}
diff --git a/MODULE_LICENSE_BSD b/MODULE_LICENSE_BSD
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_BSD
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..865b6c2
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,24 @@
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = include lib tools tests
+
+pkgconfigdir = ${libdir}/pkgconfig
+pkgconfig_DATA = marisa.pc
+
+EXTRA_DIST = \
+ bindings/Makefile \
+ bindings/perl/Makefile.PL \
+ bindings/perl/marisa.pm \
+ bindings/python/setup.py \
+ bindings/python/marisa.py \
+ bindings/ruby/extconf.rb \
+ bindings/*.cxx \
+ bindings/*.h \
+ bindings/*.i \
+ bindings/*/*.cxx \
+ bindings/*/*.h \
+ bindings/*/sample.* \
+ docs/*.html \
+ docs/*.css \
+ vs2008/vs2008.* \
+ vs2008/*/*
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b2f0452
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+### README
+
+#### Project name
+
+marisa-trie
+
+#### Project summary
+
+MARISA: Matching Algorithm with Recursively Implemented StorAge
+
+#### Latest version
+
+0.2.6
+
+#### Description
+
+Matching Algorithm with Recursively Implemented StorAge (MARISA) is a static and space-efficient trie data structure. And libmarisa is a C++ library to provide an implementation of MARISA. Also, the package of libmarisa contains a set of command line tools for building and operating a MARISA-based dictionary.
+
+A MARISA-based dictionary supports not only lookup but also reverse lookup, common prefix search and predictive search.
+
+* Lookup is to check whether or not a given string exists in a dictionary.
+* Reverse lookup is to restore a key from its ID.
+* Common prefix search is to find keys from prefixes of a given string.
+* Predictive search is to find keys starting with a given string.
+
+The biggest advantage of libmarisa is that its dictionary size is considerably more compact than others. See below for the dictionary size of other implementations.
+
+* Input
+ * Source: enwiki-20121101-all-titles-in-ns0.gz
+ * Contents: all page titles of English Wikipedia (Nov. 2012)
+ * Number of keys: 9,805,576
+ * Total size: 200,435,403 bytes (plain) / 54,933,690 bytes (gzipped)
+
+|Implementation|Size (bytes)|Remarks |
+|:-------------|-----------:|--------------------------:|
+|darts-clone | 376,613,888|Compacted double-array trie|
+|tx-trie | 127,727,058|LOUDS-based trie |
+|marisa-trie | 50,753,560|MARISA trie |
+
+#### Documentation
+
+* README (English): https://s-yata.github.io/marisa-trie/docs/readme.en.html
+* README (Japanese): https://s-yata.github.io/marisa-trie/docs/readme.ja.html
+
+#### Build instructions
+
+You can get the latest version via `git clone`. Then, you can generate a `configure` script via `autoreconf -i`. After that, you can build and install libmarisa and its command line tools via `configure` and `make`. For details, see also documentation in `docs`.
+
+```
+$ git clone https://github.com/s-yata/marisa-trie.git
+$ cd marisa-trie
+$ autoreconf -i
+$ ./configure --enable-native-code
+$ make
+$ make install
+```
+
+#### Source code license
+
+* The BSD 2-clause License
+* The LGPL 2.1 or any later version
diff --git a/bindings/Makefile b/bindings/Makefile
new file mode 100644
index 0000000..1fa64ba
--- /dev/null
+++ b/bindings/Makefile
@@ -0,0 +1,16 @@
+ALL: swig-perl swig-python swig-ruby
+
+swig-perl:
+ swig -Wall -c++ -perl -outdir perl marisa-swig.i
+ mv marisa-swig_wrap.cxx perl
+ cp marisa-swig.cxx marisa-swig.h perl
+
+swig-python:
+ swig -Wall -c++ -python -outdir python marisa-swig.i
+ mv marisa-swig_wrap.cxx python
+ cp marisa-swig.cxx marisa-swig.h python
+
+swig-ruby:
+ swig -Wall -c++ -ruby -outdir ruby marisa-swig.i
+ mv marisa-swig_wrap.cxx ruby
+ cp marisa-swig.cxx marisa-swig.h ruby
diff --git a/bindings/marisa-swig.cxx b/bindings/marisa-swig.cxx
new file mode 100644
index 0000000..281ccb2
--- /dev/null
+++ b/bindings/marisa-swig.cxx
@@ -0,0 +1,253 @@
+#include <cstring>
+#include <new>
+
+#include "marisa-swig.h"
+
+namespace marisa_swig {
+
+void Key::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = key_.ptr();
+ *length_out = key_.length();
+}
+
+size_t Key::id() const {
+ return key_.id();
+}
+
+float Key::weight() const {
+ return key_.weight();
+}
+
+void Query::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = query_.ptr();
+ *length_out = query_.length();
+}
+
+size_t Query::id() const {
+ return query_.id();
+}
+
+Keyset::Keyset() : keyset_(new (std::nothrow) marisa::Keyset) {
+ MARISA_THROW_IF(keyset_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Keyset::~Keyset() {
+ delete keyset_;
+}
+
+void Keyset::push_back(const marisa::Key &key) {
+ keyset_->push_back(key);
+}
+
+void Keyset::push_back(const char *ptr, size_t length, float weight) {
+ keyset_->push_back(ptr, length, weight);
+}
+
+const Key &Keyset::key(size_t i) const {
+ return reinterpret_cast<const Key &>((*keyset_)[i]);
+}
+
+void Keyset::key_str(size_t i,
+ const char **ptr_out, size_t *length_out) const {
+ *ptr_out = (*keyset_)[i].ptr();
+ *length_out = (*keyset_)[i].length();
+}
+
+size_t Keyset::key_id(size_t i) const {
+ return (*keyset_)[i].id();
+}
+
+size_t Keyset::num_keys() const {
+ return keyset_->num_keys();
+}
+
+bool Keyset::empty() const {
+ return keyset_->empty();
+}
+
+size_t Keyset::size() const {
+ return keyset_->size();
+}
+
+size_t Keyset::total_length() const {
+ return keyset_->total_length();
+}
+
+void Keyset::reset() {
+ keyset_->reset();
+}
+
+void Keyset::clear() {
+ keyset_->clear();
+}
+
+Agent::Agent()
+ : agent_(new (std::nothrow) marisa::Agent), buf_(NULL), buf_size_(0) {
+ MARISA_THROW_IF(agent_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Agent::~Agent() {
+ delete agent_;
+ delete [] buf_;
+}
+
+void Agent::set_query(const char *ptr, size_t length) {
+ if (length > buf_size_) {
+ size_t new_buf_size = (buf_size_ != 0) ? buf_size_ : 1;
+ if (length >= (MARISA_SIZE_MAX / 2)) {
+ new_buf_size = MARISA_SIZE_MAX;
+ } else {
+ while (new_buf_size < length) {
+ new_buf_size *= 2;
+ }
+ }
+ char *new_buf = new (std::nothrow) char[new_buf_size];
+ MARISA_THROW_IF(new_buf == NULL, MARISA_MEMORY_ERROR);
+ delete [] buf_;
+ buf_ = new_buf;
+ buf_size_ = new_buf_size;
+ }
+ std::memcpy(buf_, ptr, length);
+ agent_->set_query(buf_, length);
+}
+
+void Agent::set_query(size_t id) {
+ agent_->set_query(id);
+}
+
+const Key &Agent::key() const {
+ return reinterpret_cast<const Key &>(agent_->key());
+}
+
+const Query &Agent::query() const {
+ return reinterpret_cast<const Query &>(agent_->query());
+}
+
+void Agent::key_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->key().ptr();
+ *length_out = agent_->key().length();
+}
+
+size_t Agent::key_id() const {
+ return agent_->key().id();
+}
+
+void Agent::query_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->query().ptr();
+ *length_out = agent_->query().length();
+}
+
+size_t Agent::query_id() const {
+ return agent_->query().id();
+}
+
+Trie::Trie() : trie_(new (std::nothrow) marisa::Trie) {
+ MARISA_THROW_IF(trie_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Trie::~Trie() {
+ delete trie_;
+}
+
+void Trie::build(Keyset &keyset, int config_flags) {
+ trie_->build(*keyset.keyset_, config_flags);
+}
+
+void Trie::mmap(const char *filename) {
+ trie_->mmap(filename);
+}
+
+void Trie::load(const char *filename) {
+ trie_->load(filename);
+}
+
+void Trie::save(const char *filename) const {
+ trie_->save(filename);
+}
+
+bool Trie::lookup(Agent &agent) const {
+ return trie_->lookup(*agent.agent_);
+}
+
+void Trie::reverse_lookup(Agent &agent) const {
+ trie_->reverse_lookup(*agent.agent_);
+}
+
+bool Trie::common_prefix_search(Agent &agent) const {
+ return trie_->common_prefix_search(*agent.agent_);
+}
+
+bool Trie::predictive_search(Agent &agent) const {
+ return trie_->predictive_search(*agent.agent_);
+}
+
+size_t Trie::lookup(const char *ptr, size_t length) const {
+ marisa::Agent agent;
+ agent.set_query(ptr, length);
+ if (!trie_->lookup(agent)) {
+ return MARISA_INVALID_KEY_ID;
+ }
+ return agent.key().id();
+}
+
+void Trie::reverse_lookup(size_t id,
+ const char **ptr_out_to_be_deleted, size_t *length_out) const {
+ marisa::Agent agent;
+ agent.set_query(id);
+ trie_->reverse_lookup(agent);
+ char * const buf = new (std::nothrow) char[agent.key().length()];
+ MARISA_THROW_IF(buf == NULL, MARISA_MEMORY_ERROR);
+ std::memcpy(buf, agent.key().ptr(), agent.key().length());
+ *ptr_out_to_be_deleted = buf;
+ *length_out = agent.key().length();
+}
+
+size_t Trie::num_tries() const {
+ return trie_->num_tries();
+}
+
+size_t Trie::num_keys() const {
+ return trie_->num_keys();
+}
+
+size_t Trie::num_nodes() const {
+ return trie_->num_nodes();
+}
+
+TailMode Trie::tail_mode() const {
+ if (trie_->tail_mode() == ::MARISA_TEXT_TAIL) {
+ return TEXT_TAIL;
+ } else {
+ return BINARY_TAIL;
+ }
+}
+
+NodeOrder Trie::node_order() const {
+ if (trie_->node_order() == ::MARISA_LABEL_ORDER) {
+ return LABEL_ORDER;
+ } else {
+ return WEIGHT_ORDER;
+ }
+}
+
+bool Trie::empty() const {
+ return trie_->empty();
+}
+
+size_t Trie::size() const {
+ return trie_->size();
+}
+
+size_t Trie::total_size() const {
+ return trie_->total_size();
+}
+
+size_t Trie::io_size() const {
+ return trie_->io_size();
+}
+
+void Trie::clear() {
+ trie_->clear();
+}
+
+} // namespace marisa_swig
diff --git a/bindings/marisa-swig.h b/bindings/marisa-swig.h
new file mode 100644
index 0000000..f09a9a7
--- /dev/null
+++ b/bindings/marisa-swig.h
@@ -0,0 +1,183 @@
+#ifndef MARISA_SWIG_H_
+#define MARISA_SWIG_H_
+
+#include <marisa.h>
+
+namespace marisa_swig {
+
+#define MARISA_SWIG_ENUM_COPY(name) name = MARISA_ ## name
+
+enum ErrorCode {
+ MARISA_SWIG_ENUM_COPY(OK),
+ MARISA_SWIG_ENUM_COPY(STATE_ERROR),
+ MARISA_SWIG_ENUM_COPY(NULL_ERROR),
+ MARISA_SWIG_ENUM_COPY(BOUND_ERROR),
+ MARISA_SWIG_ENUM_COPY(RANGE_ERROR),
+ MARISA_SWIG_ENUM_COPY(CODE_ERROR),
+ MARISA_SWIG_ENUM_COPY(RESET_ERROR),
+ MARISA_SWIG_ENUM_COPY(SIZE_ERROR),
+ MARISA_SWIG_ENUM_COPY(MEMORY_ERROR),
+ MARISA_SWIG_ENUM_COPY(IO_ERROR),
+ MARISA_SWIG_ENUM_COPY(FORMAT_ERROR)
+};
+
+enum NumTries {
+ MARISA_SWIG_ENUM_COPY(MIN_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(MAX_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_NUM_TRIES)
+};
+
+enum CacheLevel {
+ MARISA_SWIG_ENUM_COPY(HUGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(LARGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(NORMAL_CACHE),
+ MARISA_SWIG_ENUM_COPY(SMALL_CACHE),
+ MARISA_SWIG_ENUM_COPY(TINY_CACHE),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_CACHE)
+};
+
+enum TailMode {
+ MARISA_SWIG_ENUM_COPY(TEXT_TAIL),
+ MARISA_SWIG_ENUM_COPY(BINARY_TAIL),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_TAIL)
+};
+
+enum NodeOrder {
+ MARISA_SWIG_ENUM_COPY(LABEL_ORDER),
+ MARISA_SWIG_ENUM_COPY(WEIGHT_ORDER),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_ORDER)
+};
+
+#undef MARISA_SWIG_ENUM_COPY
+
+class Key {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+ float weight() const;
+
+ private:
+ const marisa::Key key_;
+
+ Key();
+ Key(const Key &key);
+ Key &operator=(const Key &);
+};
+
+class Query {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+
+ private:
+ const marisa::Query query_;
+
+ Query();
+ Query(const Query &query);
+ Query &operator=(const Query &);
+};
+
+class Keyset {
+ friend class Trie;
+
+ public:
+ Keyset();
+ ~Keyset();
+
+ void push_back(const marisa::Key &key);
+ void push_back(const char *ptr, std::size_t length, float weight = 1.0);
+
+ const Key &key(std::size_t i) const;
+
+ void key_str(std::size_t i,
+ const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id(std::size_t i) const;
+
+ std::size_t num_keys() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_length() const;
+
+ void reset();
+ void clear();
+
+ private:
+ marisa::Keyset *keyset_;
+
+ Keyset(const Keyset &);
+ Keyset &operator=(const Keyset &);
+};
+
+class Agent {
+ friend class Trie;
+
+ public:
+ Agent();
+ ~Agent();
+
+ void set_query(const char *ptr, std::size_t length);
+ void set_query(std::size_t id);
+
+ const Key &key() const;
+ const Query &query() const;
+
+ void key_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id() const;
+
+ void query_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t query_id() const;
+
+ private:
+ marisa::Agent *agent_;
+ char *buf_;
+ std::size_t buf_size_;
+
+ Agent(const Agent &);
+ Agent &operator=(const Agent &);
+};
+
+class Trie {
+ public:
+ Trie();
+ ~Trie();
+
+ void build(Keyset &keyset, int config_flags = 0);
+
+ void mmap(const char *filename);
+ void load(const char *filename);
+ void save(const char *filename) const;
+
+ bool lookup(Agent &agent) const;
+ void reverse_lookup(Agent &agent) const;
+ bool common_prefix_search(Agent &agent) const;
+ bool predictive_search(Agent &agent) const;
+
+ std::size_t lookup(const char *ptr, std::size_t length) const;
+ void reverse_lookup(std::size_t id,
+ const char **ptr_out_to_be_deleted, std::size_t *length_out) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_size() const;
+ std::size_t io_size() const;
+
+ void clear();
+
+ private:
+ marisa::Trie *trie_;
+
+ Trie(const Trie &);
+ Trie &operator=(const Trie &);
+};
+
+} // namespace marisa_swig
+
+#endif // MARISA_SWIG_H_
diff --git a/bindings/marisa-swig.i b/bindings/marisa-swig.i
new file mode 100644
index 0000000..d14bbbc
--- /dev/null
+++ b/bindings/marisa-swig.i
@@ -0,0 +1,28 @@
+%module marisa
+
+%include "cstring.i"
+%include "exception.i"
+
+%{
+#include "marisa-swig.h"
+%}
+
+%apply (char *STRING, int LENGTH) { (const char *ptr, std::size_t length) };
+
+%cstring_output_allocate_size(const char **ptr_out, std::size_t *length_out, );
+%cstring_output_allocate_size(const char **ptr_out_to_be_deleted,
+ std::size_t *length_out, delete [] (*$1));
+
+%exception {
+ try {
+ $action
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+}
+
+%include "marisa-swig.h"
+
+%constant size_t INVALID_KEY_ID = MARISA_INVALID_KEY_ID;
diff --git a/bindings/perl/Makefile.PL b/bindings/perl/Makefile.PL
new file mode 100644
index 0000000..554892e
--- /dev/null
+++ b/bindings/perl/Makefile.PL
@@ -0,0 +1,7 @@
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+ 'NAME' => 'marisa',
+ 'LIBS' => ['-lmarisa'],
+ 'OBJECT' => 'marisa-swig.o marisa-swig_wrap.o'
+);
diff --git a/bindings/perl/benchmark.pl b/bindings/perl/benchmark.pl
new file mode 100644
index 0000000..4e5bb69
--- /dev/null
+++ b/bindings/perl/benchmark.pl
@@ -0,0 +1,93 @@
+use Time::HiRes;
+use marisa;
+
+my $time_begin = Time::HiRes::gettimeofday();
+my @keys = <STDIN>;
+foreach my $key (@keys) {
+ chomp($key);
+}
+my $time_end = Time::HiRes::gettimeofday();
+print "input: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+my %hash;
+foreach my $key (@keys) {
+ $hash{$key} = 0;
+}
+$time_end = Time::HiRes::gettimeofday();
+print "hash_build: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+foreach my $key (@keys) {
+ $hash{$key};
+}
+$time_end = Time::HiRes::gettimeofday();
+print "hash_lookup: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+my $keyset = new marisa::Keyset;
+foreach my $key (@keys) {
+ $keyset->push_back($key)
+}
+$time_end = Time::HiRes::gettimeofday();
+print "keyset_build: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+$trie = new marisa::Trie;
+$trie->build($keyset);
+$time_end = Time::HiRes::gettimeofday();
+print "trie_build: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+my $agent = new marisa::Agent;
+foreach my $key (@keys) {
+ $agent->set_query($key);
+ $trie->lookup($agent);
+ $agent->key_id();
+}
+$time_end = Time::HiRes::gettimeofday();
+print "trie_agent_lookup: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+foreach my $key (@keys) {
+ $trie->lookup($key);
+}
+$time_end = Time::HiRes::gettimeofday();
+print "trie_lookup: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+my $max_key_id = $trie->size() - 1;
+for (0..$max_key_id) {
+ $agent->set_query($_);
+ $trie->reverse_lookup($agent);
+ $agent->key_str();
+}
+$time_end = Time::HiRes::gettimeofday();
+print "trie_agent_reverse_lookup: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+for (0..$max_key_id) {
+ $trie->reverse_lookup($_);
+}
+$time_end = Time::HiRes::gettimeofday();
+print "trie_reverse_lookup: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+foreach my $key (@keys) {
+ $agent->set_query($key);
+ while ($trie->common_prefix_search($agent)) {
+ $agent->key_str();
+ }
+}
+$time_end = Time::HiRes::gettimeofday();
+print "trie_agent_common_prefix_search: ", $time_end - $time_begin, "\n";
+
+$time_begin = Time::HiRes::gettimeofday();
+foreach my $key (@keys) {
+ $agent->set_query($key);
+ while ($trie->predictive_search($agent)) {
+ $agent->key_str();
+ }
+}
+$time_end = Time::HiRes::gettimeofday();
+print "trie_agent_predictive_search: ", $time_end - $time_begin, "\n";
diff --git a/bindings/perl/marisa-swig.cxx b/bindings/perl/marisa-swig.cxx
new file mode 100644
index 0000000..281ccb2
--- /dev/null
+++ b/bindings/perl/marisa-swig.cxx
@@ -0,0 +1,253 @@
+#include <cstring>
+#include <new>
+
+#include "marisa-swig.h"
+
+namespace marisa_swig {
+
+void Key::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = key_.ptr();
+ *length_out = key_.length();
+}
+
+size_t Key::id() const {
+ return key_.id();
+}
+
+float Key::weight() const {
+ return key_.weight();
+}
+
+void Query::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = query_.ptr();
+ *length_out = query_.length();
+}
+
+size_t Query::id() const {
+ return query_.id();
+}
+
+Keyset::Keyset() : keyset_(new (std::nothrow) marisa::Keyset) {
+ MARISA_THROW_IF(keyset_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Keyset::~Keyset() {
+ delete keyset_;
+}
+
+void Keyset::push_back(const marisa::Key &key) {
+ keyset_->push_back(key);
+}
+
+void Keyset::push_back(const char *ptr, size_t length, float weight) {
+ keyset_->push_back(ptr, length, weight);
+}
+
+const Key &Keyset::key(size_t i) const {
+ return reinterpret_cast<const Key &>((*keyset_)[i]);
+}
+
+void Keyset::key_str(size_t i,
+ const char **ptr_out, size_t *length_out) const {
+ *ptr_out = (*keyset_)[i].ptr();
+ *length_out = (*keyset_)[i].length();
+}
+
+size_t Keyset::key_id(size_t i) const {
+ return (*keyset_)[i].id();
+}
+
+size_t Keyset::num_keys() const {
+ return keyset_->num_keys();
+}
+
+bool Keyset::empty() const {
+ return keyset_->empty();
+}
+
+size_t Keyset::size() const {
+ return keyset_->size();
+}
+
+size_t Keyset::total_length() const {
+ return keyset_->total_length();
+}
+
+void Keyset::reset() {
+ keyset_->reset();
+}
+
+void Keyset::clear() {
+ keyset_->clear();
+}
+
+Agent::Agent()
+ : agent_(new (std::nothrow) marisa::Agent), buf_(NULL), buf_size_(0) {
+ MARISA_THROW_IF(agent_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Agent::~Agent() {
+ delete agent_;
+ delete [] buf_;
+}
+
+void Agent::set_query(const char *ptr, size_t length) {
+ if (length > buf_size_) {
+ size_t new_buf_size = (buf_size_ != 0) ? buf_size_ : 1;
+ if (length >= (MARISA_SIZE_MAX / 2)) {
+ new_buf_size = MARISA_SIZE_MAX;
+ } else {
+ while (new_buf_size < length) {
+ new_buf_size *= 2;
+ }
+ }
+ char *new_buf = new (std::nothrow) char[new_buf_size];
+ MARISA_THROW_IF(new_buf == NULL, MARISA_MEMORY_ERROR);
+ delete [] buf_;
+ buf_ = new_buf;
+ buf_size_ = new_buf_size;
+ }
+ std::memcpy(buf_, ptr, length);
+ agent_->set_query(buf_, length);
+}
+
+void Agent::set_query(size_t id) {
+ agent_->set_query(id);
+}
+
+const Key &Agent::key() const {
+ return reinterpret_cast<const Key &>(agent_->key());
+}
+
+const Query &Agent::query() const {
+ return reinterpret_cast<const Query &>(agent_->query());
+}
+
+void Agent::key_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->key().ptr();
+ *length_out = agent_->key().length();
+}
+
+size_t Agent::key_id() const {
+ return agent_->key().id();
+}
+
+void Agent::query_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->query().ptr();
+ *length_out = agent_->query().length();
+}
+
+size_t Agent::query_id() const {
+ return agent_->query().id();
+}
+
+Trie::Trie() : trie_(new (std::nothrow) marisa::Trie) {
+ MARISA_THROW_IF(trie_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Trie::~Trie() {
+ delete trie_;
+}
+
+void Trie::build(Keyset &keyset, int config_flags) {
+ trie_->build(*keyset.keyset_, config_flags);
+}
+
+void Trie::mmap(const char *filename) {
+ trie_->mmap(filename);
+}
+
+void Trie::load(const char *filename) {
+ trie_->load(filename);
+}
+
+void Trie::save(const char *filename) const {
+ trie_->save(filename);
+}
+
+bool Trie::lookup(Agent &agent) const {
+ return trie_->lookup(*agent.agent_);
+}
+
+void Trie::reverse_lookup(Agent &agent) const {
+ trie_->reverse_lookup(*agent.agent_);
+}
+
+bool Trie::common_prefix_search(Agent &agent) const {
+ return trie_->common_prefix_search(*agent.agent_);
+}
+
+bool Trie::predictive_search(Agent &agent) const {
+ return trie_->predictive_search(*agent.agent_);
+}
+
+size_t Trie::lookup(const char *ptr, size_t length) const {
+ marisa::Agent agent;
+ agent.set_query(ptr, length);
+ if (!trie_->lookup(agent)) {
+ return MARISA_INVALID_KEY_ID;
+ }
+ return agent.key().id();
+}
+
+void Trie::reverse_lookup(size_t id,
+ const char **ptr_out_to_be_deleted, size_t *length_out) const {
+ marisa::Agent agent;
+ agent.set_query(id);
+ trie_->reverse_lookup(agent);
+ char * const buf = new (std::nothrow) char[agent.key().length()];
+ MARISA_THROW_IF(buf == NULL, MARISA_MEMORY_ERROR);
+ std::memcpy(buf, agent.key().ptr(), agent.key().length());
+ *ptr_out_to_be_deleted = buf;
+ *length_out = agent.key().length();
+}
+
+size_t Trie::num_tries() const {
+ return trie_->num_tries();
+}
+
+size_t Trie::num_keys() const {
+ return trie_->num_keys();
+}
+
+size_t Trie::num_nodes() const {
+ return trie_->num_nodes();
+}
+
+TailMode Trie::tail_mode() const {
+ if (trie_->tail_mode() == ::MARISA_TEXT_TAIL) {
+ return TEXT_TAIL;
+ } else {
+ return BINARY_TAIL;
+ }
+}
+
+NodeOrder Trie::node_order() const {
+ if (trie_->node_order() == ::MARISA_LABEL_ORDER) {
+ return LABEL_ORDER;
+ } else {
+ return WEIGHT_ORDER;
+ }
+}
+
+bool Trie::empty() const {
+ return trie_->empty();
+}
+
+size_t Trie::size() const {
+ return trie_->size();
+}
+
+size_t Trie::total_size() const {
+ return trie_->total_size();
+}
+
+size_t Trie::io_size() const {
+ return trie_->io_size();
+}
+
+void Trie::clear() {
+ trie_->clear();
+}
+
+} // namespace marisa_swig
diff --git a/bindings/perl/marisa-swig.h b/bindings/perl/marisa-swig.h
new file mode 100644
index 0000000..f09a9a7
--- /dev/null
+++ b/bindings/perl/marisa-swig.h
@@ -0,0 +1,183 @@
+#ifndef MARISA_SWIG_H_
+#define MARISA_SWIG_H_
+
+#include <marisa.h>
+
+namespace marisa_swig {
+
+#define MARISA_SWIG_ENUM_COPY(name) name = MARISA_ ## name
+
+enum ErrorCode {
+ MARISA_SWIG_ENUM_COPY(OK),
+ MARISA_SWIG_ENUM_COPY(STATE_ERROR),
+ MARISA_SWIG_ENUM_COPY(NULL_ERROR),
+ MARISA_SWIG_ENUM_COPY(BOUND_ERROR),
+ MARISA_SWIG_ENUM_COPY(RANGE_ERROR),
+ MARISA_SWIG_ENUM_COPY(CODE_ERROR),
+ MARISA_SWIG_ENUM_COPY(RESET_ERROR),
+ MARISA_SWIG_ENUM_COPY(SIZE_ERROR),
+ MARISA_SWIG_ENUM_COPY(MEMORY_ERROR),
+ MARISA_SWIG_ENUM_COPY(IO_ERROR),
+ MARISA_SWIG_ENUM_COPY(FORMAT_ERROR)
+};
+
+enum NumTries {
+ MARISA_SWIG_ENUM_COPY(MIN_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(MAX_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_NUM_TRIES)
+};
+
+enum CacheLevel {
+ MARISA_SWIG_ENUM_COPY(HUGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(LARGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(NORMAL_CACHE),
+ MARISA_SWIG_ENUM_COPY(SMALL_CACHE),
+ MARISA_SWIG_ENUM_COPY(TINY_CACHE),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_CACHE)
+};
+
+enum TailMode {
+ MARISA_SWIG_ENUM_COPY(TEXT_TAIL),
+ MARISA_SWIG_ENUM_COPY(BINARY_TAIL),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_TAIL)
+};
+
+enum NodeOrder {
+ MARISA_SWIG_ENUM_COPY(LABEL_ORDER),
+ MARISA_SWIG_ENUM_COPY(WEIGHT_ORDER),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_ORDER)
+};
+
+#undef MARISA_SWIG_ENUM_COPY
+
+class Key {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+ float weight() const;
+
+ private:
+ const marisa::Key key_;
+
+ Key();
+ Key(const Key &key);
+ Key &operator=(const Key &);
+};
+
+class Query {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+
+ private:
+ const marisa::Query query_;
+
+ Query();
+ Query(const Query &query);
+ Query &operator=(const Query &);
+};
+
+class Keyset {
+ friend class Trie;
+
+ public:
+ Keyset();
+ ~Keyset();
+
+ void push_back(const marisa::Key &key);
+ void push_back(const char *ptr, std::size_t length, float weight = 1.0);
+
+ const Key &key(std::size_t i) const;
+
+ void key_str(std::size_t i,
+ const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id(std::size_t i) const;
+
+ std::size_t num_keys() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_length() const;
+
+ void reset();
+ void clear();
+
+ private:
+ marisa::Keyset *keyset_;
+
+ Keyset(const Keyset &);
+ Keyset &operator=(const Keyset &);
+};
+
+class Agent {
+ friend class Trie;
+
+ public:
+ Agent();
+ ~Agent();
+
+ void set_query(const char *ptr, std::size_t length);
+ void set_query(std::size_t id);
+
+ const Key &key() const;
+ const Query &query() const;
+
+ void key_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id() const;
+
+ void query_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t query_id() const;
+
+ private:
+ marisa::Agent *agent_;
+ char *buf_;
+ std::size_t buf_size_;
+
+ Agent(const Agent &);
+ Agent &operator=(const Agent &);
+};
+
+class Trie {
+ public:
+ Trie();
+ ~Trie();
+
+ void build(Keyset &keyset, int config_flags = 0);
+
+ void mmap(const char *filename);
+ void load(const char *filename);
+ void save(const char *filename) const;
+
+ bool lookup(Agent &agent) const;
+ void reverse_lookup(Agent &agent) const;
+ bool common_prefix_search(Agent &agent) const;
+ bool predictive_search(Agent &agent) const;
+
+ std::size_t lookup(const char *ptr, std::size_t length) const;
+ void reverse_lookup(std::size_t id,
+ const char **ptr_out_to_be_deleted, std::size_t *length_out) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_size() const;
+ std::size_t io_size() const;
+
+ void clear();
+
+ private:
+ marisa::Trie *trie_;
+
+ Trie(const Trie &);
+ Trie &operator=(const Trie &);
+};
+
+} // namespace marisa_swig
+
+#endif // MARISA_SWIG_H_
diff --git a/bindings/perl/marisa-swig_wrap.cxx b/bindings/perl/marisa-swig_wrap.cxx
new file mode 100644
index 0000000..1db1a59
--- /dev/null
+++ b/bindings/perl/marisa-swig_wrap.cxx
@@ -0,0 +1,5160 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.40
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGPERL
+#define SWIG_CASTRANK_MODE
+
+
+#ifdef __cplusplus
+/* SwigValueWrapper is described in swig.swg */
+template<typename T> class SwigValueWrapper {
+ struct SwigMovePointer {
+ T *ptr;
+ SwigMovePointer(T *p) : ptr(p) { }
+ ~SwigMovePointer() { delete ptr; }
+ SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+ } pointer;
+ SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
+ SwigValueWrapper(const SwigValueWrapper<T>& rhs);
+public:
+ SwigValueWrapper() : pointer(0) { }
+ SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+ operator T&() const { return *pointer.ptr; }
+ T *operator&() { return pointer.ptr; }
+};
+
+template <typename T> T SwigValueInit() {
+ return T();
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+# pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * swigrun.swg
+ *
+ * This file contains generic C API SWIG runtime support for pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+ or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "4"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+ You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+ creating a static or dynamic library from the SWIG runtime code.
+ In 99.9% of the cases, SWIG just needs to declare them as 'static'.
+
+ But only do this if strictly necessary, ie, if you have problems
+ with your compiler or suchlike.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+/* Generic buffer size */
+#ifndef SWIG_BUFFER_SIZE
+# define SWIG_BUFFER_SIZE 1024
+#endif
+
+/* Flags for pointer conversions */
+#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_OWN 0x1
+
+
+/*
+ Flags/methods for returning states.
+
+ The SWIG conversion methods, as ConvertPtr, return and integer
+ that tells if the conversion was successful or not. And if not,
+ an error code can be returned (see swigerrors.swg for the codes).
+
+ Use the following macros/flags to set or process the returning
+ states.
+
+ In old versions of SWIG, code such as the following was usually written:
+
+ if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
+ // success code
+ } else {
+ //fail code
+ }
+
+ Now you can be more explicit:
+
+ int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ } else {
+ // fail code
+ }
+
+ which is the same really, but now you can also do
+
+ Type *ptr;
+ int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ if (SWIG_IsNewObj(res) {
+ ...
+ delete *ptr;
+ } else {
+ ...
+ }
+ } else {
+ // fail code
+ }
+
+ I.e., now SWIG_ConvertPtr can return new objects and you can
+ identify the case and take care of the deallocation. Of course that
+ also requires SWIG_ConvertPtr to return new result values, such as
+
+ int SWIG_ConvertPtr(obj, ptr,...) {
+ if (<obj is ok>) {
+ if (<need new object>) {
+ *ptr = <ptr to new allocated object>;
+ return SWIG_NEWOBJ;
+ } else {
+ *ptr = <ptr to old object>;
+ return SWIG_OLDOBJ;
+ }
+ } else {
+ return SWIG_BADOBJ;
+ }
+ }
+
+ Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
+ more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
+ SWIG errors code.
+
+ Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
+ allows to return the 'cast rank', for example, if you have this
+
+ int food(double)
+ int fooi(int);
+
+ and you call
+
+ food(1) // cast rank '1' (1 -> 1.0)
+ fooi(1) // cast rank '0'
+
+ just use the SWIG_AddCast()/SWIG_CheckState()
+*/
+
+#define SWIG_OK (0)
+#define SWIG_ERROR (-1)
+#define SWIG_IsOK(r) (r >= 0)
+#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
+
+/* The CastRankLimit says how many bits are used for the cast rank */
+#define SWIG_CASTRANKLIMIT (1 << 8)
+/* The NewMask denotes the object was created (using new/malloc) */
+#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
+/* The TmpMask is for in/out typemaps that use temporal objects */
+#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
+/* Simple returning values */
+#define SWIG_BADOBJ (SWIG_ERROR)
+#define SWIG_OLDOBJ (SWIG_OK)
+#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
+#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
+/* Check, add and del mask methods */
+#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
+#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
+#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
+#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
+#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
+#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
+
+/* Cast-Rank Mode */
+#if defined(SWIG_CASTRANK_MODE)
+# ifndef SWIG_TypeRank
+# define SWIG_TypeRank unsigned long
+# endif
+# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
+# define SWIG_MAXCASTRANK (2)
+# endif
+# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
+# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
+ return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
+}
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+ return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
+}
+#else /* no cast-rank mode */
+# define SWIG_AddCast
+# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
+#endif
+
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *, int *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store information on one type */
+typedef struct swig_type_info {
+ const char *name; /* mangled name of this type */
+ const char *str; /* human readable name of this type */
+ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
+ struct swig_cast_info *cast; /* linked list of types that can cast into this type */
+ void *clientdata; /* language specific type data */
+ int owndata; /* flag if the structure owns the clientdata */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+ swig_type_info *type; /* pointer to type that is equivalent to this type */
+ swig_converter_func converter; /* function to cast the void pointers */
+ struct swig_cast_info *next; /* pointer to next cast in linked list */
+ struct swig_cast_info *prev; /* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+ swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
+ size_t size; /* Number of types in this module */
+ struct swig_module_info *next; /* Pointer to next element in circularly linked list */
+ swig_type_info **type_initial; /* Array of initially generated type structures */
+ swig_cast_info **cast_initial; /* Array of initially generated casting structures */
+ void *clientdata; /* Language specific module data */
+} swig_module_info;
+
+/*
+ Compare two type names skipping the space characters, therefore
+ "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+ Return 0 when the two name types are equivalent, as in
+ strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+ const char *f2, const char *l2) {
+ for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+ while ((*f1 == ' ') && (f1 != l1)) ++f1;
+ while ((*f2 == ' ') && (f2 != l2)) ++f2;
+ if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
+ }
+ return (int)((l1 - f1) - (l2 - f2));
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCompare(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+
+/*
+ Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (strcmp(iter->type->name, c) == 0) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (iter->type == from) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
+}
+
+/*
+ Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+ swig_type_info *lastty = ty;
+ if (!ty || !ty->dcast) return ty;
+ while (ty && (ty->dcast)) {
+ ty = (*ty->dcast)(ptr);
+ if (ty) lastty = ty;
+ }
+ return lastty;
+}
+
+/*
+ Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+ return ty->name;
+}
+
+/*
+ Return the pretty name associated with this type,
+ that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+ /* The "str" field contains the equivalent pretty names of the
+ type, separated by vertical-bar characters. We choose
+ to print the last name, as it is often (?) the most
+ specific. */
+ if (!type) return NULL;
+ if (type->str != NULL) {
+ const char *last_name = type->str;
+ const char *s;
+ for (s = type->str; *s; s++)
+ if (*s == '|') last_name = s+1;
+ return last_name;
+ }
+ else
+ return type->name;
+}
+
+/*
+ Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+ swig_cast_info *cast = ti->cast;
+ /* if (ti->clientdata == clientdata) return; */
+ ti->clientdata = clientdata;
+
+ while (cast) {
+ if (!cast->converter) {
+ swig_type_info *tc = cast->type;
+ if (!tc->clientdata) {
+ SWIG_TypeClientData(tc, clientdata);
+ }
+ }
+ cast = cast->next;
+ }
+}
+SWIGRUNTIME void
+SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
+ SWIG_TypeClientData(ti, clientdata);
+ ti->owndata = 1;
+}
+
+/*
+ Search for a swig_type_info structure only by mangled name
+ Search is a O(log #types)
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ swig_module_info *iter = start;
+ do {
+ if (iter->size) {
+ register size_t l = 0;
+ register size_t r = iter->size - 1;
+ do {
+ /* since l+r >= 0, we can (>> 1) instead (/ 2) */
+ register size_t i = (l + r) >> 1;
+ const char *iname = iter->types[i]->name;
+ if (iname) {
+ register int compare = strcmp(name, iname);
+ if (compare == 0) {
+ return iter->types[i];
+ } else if (compare < 0) {
+ if (i) {
+ r = i - 1;
+ } else {
+ break;
+ }
+ } else if (compare > 0) {
+ l = i + 1;
+ }
+ } else {
+ break; /* should never happen */
+ }
+ } while (l <= r);
+ }
+ iter = iter->next;
+ } while (iter != end);
+ return 0;
+}
+
+/*
+ Search for a swig_type_info structure for either a mangled name or a human readable name.
+ It first searches the mangled names of the types, which is a O(log #types)
+ If a type is not found it then searches the human readable names, which is O(#types).
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ /* STEP 1: Search the name field using binary search */
+ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+ if (ret) {
+ return ret;
+ } else {
+ /* STEP 2: If the type hasn't been found, do a complete search
+ of the str field (the human readable name) */
+ swig_module_info *iter = start;
+ do {
+ register size_t i = 0;
+ for (; i < iter->size; ++i) {
+ if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+ return iter->types[i];
+ }
+ iter = iter->next;
+ } while (iter != end);
+ }
+
+ /* neither found a match */
+ return 0;
+}
+
+/*
+ Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+ static const char hex[17] = "0123456789abcdef";
+ register const unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register unsigned char uu = *u;
+ *(c++) = hex[(uu & 0xf0) >> 4];
+ *(c++) = hex[uu & 0xf];
+ }
+ return c;
+}
+
+/*
+ Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+ register unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register char d = *(c++);
+ register unsigned char uu;
+ if ((d >= '0') && (d <= '9'))
+ uu = ((d - '0') << 4);
+ else if ((d >= 'a') && (d <= 'f'))
+ uu = ((d - ('a'-10)) << 4);
+ else
+ return (char *) 0;
+ d = *(c++);
+ if ((d >= '0') && (d <= '9'))
+ uu |= (d - '0');
+ else if ((d >= 'a') && (d <= 'f'))
+ uu |= (d - ('a'-10));
+ else
+ return (char *) 0;
+ *u = uu;
+ }
+ return c;
+}
+
+/*
+ Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+ char *r = buff;
+ if ((2*sizeof(void *) + 2) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,&ptr,sizeof(void *));
+ if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+ strcpy(r,name);
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ *ptr = (void *) 0;
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+ char *r = buff;
+ size_t lname = (name ? strlen(name) : 0);
+ if ((2*sz + 2 + lname) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ if (lname) {
+ strncpy(r,name,lname+1);
+ } else {
+ *r = 0;
+ }
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ memset(ptr,0,sz);
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Errors in SWIG */
+#define SWIG_UnknownError -1
+#define SWIG_IOError -2
+#define SWIG_RuntimeError -3
+#define SWIG_IndexError -4
+#define SWIG_TypeError -5
+#define SWIG_DivisionByZero -6
+#define SWIG_OverflowError -7
+#define SWIG_SyntaxError -8
+#define SWIG_ValueError -9
+#define SWIG_SystemError -10
+#define SWIG_AttributeError -11
+#define SWIG_MemoryError -12
+#define SWIG_NullReferenceError -13
+
+
+
+#ifdef __cplusplus
+/* Needed on some windows machines---since MS plays funny games with the header files under C++ */
+#include <math.h>
+#include <stdlib.h>
+extern "C" {
+#endif
+#include "EXTERN.h"
+#include "perl.h"
+#include "XSUB.h"
+
+/* Add in functionality missing in older versions of Perl. Much of this is based on Devel-PPPort on cpan. */
+
+/* Add PERL_REVISION, PERL_VERSION, PERL_SUBVERSION if missing */
+#ifndef PERL_REVISION
+# if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION))
+# define PERL_PATCHLEVEL_H_IMPLICIT
+# include <patchlevel.h>
+# endif
+# if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL)))
+# include <could_not_find_Perl_patchlevel.h>
+# endif
+# ifndef PERL_REVISION
+# define PERL_REVISION (5)
+# define PERL_VERSION PATCHLEVEL
+# define PERL_SUBVERSION SUBVERSION
+# endif
+#endif
+
+#if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE)
+#define PerlIO_exportFILE(fh,fl) (FILE*)(fh)
+#endif
+
+#ifndef SvIOK_UV
+# define SvIOK_UV(sv) (SvIOK(sv) && (SvUVX(sv) == SvIVX(sv)))
+#endif
+
+#ifndef SvUOK
+# define SvUOK(sv) SvIOK_UV(sv)
+#endif
+
+#if ((PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)))
+# define PL_sv_undef sv_undef
+# define PL_na na
+# define PL_errgv errgv
+# define PL_sv_no sv_no
+# define PL_sv_yes sv_yes
+# define PL_markstack_ptr markstack_ptr
+#endif
+
+#ifndef IVSIZE
+# ifdef LONGSIZE
+# define IVSIZE LONGSIZE
+# else
+# define IVSIZE 4 /* A bold guess, but the best we can make. */
+# endif
+#endif
+
+#ifndef INT2PTR
+# if (IVSIZE == PTRSIZE) && (UVSIZE == PTRSIZE)
+# define PTRV UV
+# define INT2PTR(any,d) (any)(d)
+# else
+# if PTRSIZE == LONGSIZE
+# define PTRV unsigned long
+# else
+# define PTRV unsigned
+# endif
+# define INT2PTR(any,d) (any)(PTRV)(d)
+# endif
+
+# define NUM2PTR(any,d) (any)(PTRV)(d)
+# define PTR2IV(p) INT2PTR(IV,p)
+# define PTR2UV(p) INT2PTR(UV,p)
+# define PTR2NV(p) NUM2PTR(NV,p)
+
+# if PTRSIZE == LONGSIZE
+# define PTR2ul(p) (unsigned long)(p)
+# else
+# define PTR2ul(p) INT2PTR(unsigned long,p)
+# endif
+#endif /* !INT2PTR */
+
+#ifndef SvPV_nolen
+# define SvPV_nolen(x) SvPV(x,PL_na)
+#endif
+
+#ifndef get_sv
+# define get_sv perl_get_sv
+#endif
+
+#ifndef ERRSV
+# define ERRSV get_sv("@",FALSE)
+#endif
+
+#ifndef pTHX_
+#define pTHX_
+#endif
+
+#include <string.h>
+#ifdef __cplusplus
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * error manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGINTERN const char*
+SWIG_Perl_ErrorType(int code) {
+ const char* type = 0;
+ switch(code) {
+ case SWIG_MemoryError:
+ type = "MemoryError";
+ break;
+ case SWIG_IOError:
+ type = "IOError";
+ break;
+ case SWIG_RuntimeError:
+ type = "RuntimeError";
+ break;
+ case SWIG_IndexError:
+ type = "IndexError";
+ break;
+ case SWIG_TypeError:
+ type = "TypeError";
+ break;
+ case SWIG_DivisionByZero:
+ type = "ZeroDivisionError";
+ break;
+ case SWIG_OverflowError:
+ type = "OverflowError";
+ break;
+ case SWIG_SyntaxError:
+ type = "SyntaxError";
+ break;
+ case SWIG_ValueError:
+ type = "ValueError";
+ break;
+ case SWIG_SystemError:
+ type = "SystemError";
+ break;
+ case SWIG_AttributeError:
+ type = "AttributeError";
+ break;
+ default:
+ type = "RuntimeError";
+ }
+ return type;
+}
+
+
+
+
+/* -----------------------------------------------------------------------------
+ * perlrun.swg
+ *
+ * This file contains the runtime support for Perl modules
+ * and includes code for managing global variables and pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef PERL_OBJECT
+#define SWIG_PERL_OBJECT_DECL CPerlObj *SWIGUNUSEDPARM(pPerl),
+#define SWIG_PERL_OBJECT_CALL pPerl,
+#else
+#define SWIG_PERL_OBJECT_DECL
+#define SWIG_PERL_OBJECT_CALL
+#endif
+
+/* Common SWIG API */
+
+/* for raw pointers */
+#define SWIG_ConvertPtr(obj, pp, type, flags) SWIG_Perl_ConvertPtr(SWIG_PERL_OBJECT_CALL obj, pp, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj, pp, type, flags,own) SWIG_Perl_ConvertPtrAndOwn(SWIG_PERL_OBJECT_CALL obj, pp, type, flags, own)
+#define SWIG_NewPointerObj(p, type, flags) SWIG_Perl_NewPointerObj(SWIG_PERL_OBJECT_CALL p, type, flags)
+
+/* for raw packed data */
+#define SWIG_ConvertPacked(obj, p, s, type) SWIG_Perl_ConvertPacked(SWIG_PERL_OBJECT_CALL obj, p, s, type)
+#define SWIG_NewPackedObj(p, s, type) SWIG_Perl_NewPackedObj(SWIG_PERL_OBJECT_CALL p, s, type)
+
+/* for class or struct pointers */
+#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
+
+/* for C or C++ function pointers */
+#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_ConvertPtr(obj, pptr, type, 0)
+#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_NewPointerObj(ptr, type, 0)
+
+/* for C++ member pointers, ie, member methods */
+#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type) SWIG_NewPackedObj(ptr, sz, type)
+
+
+/* Runtime API */
+
+#define SWIG_GetModule(clientdata) SWIG_Perl_GetModule()
+#define SWIG_SetModule(clientdata, pointer) SWIG_Perl_SetModule(pointer)
+
+
+/* Error manipulation */
+
+#define SWIG_ErrorType(code) SWIG_Perl_ErrorType(code)
+#define SWIG_Error(code, msg) sv_setpvf(GvSV(PL_errgv),"%s %s\n", SWIG_ErrorType(code), msg)
+#define SWIG_fail goto fail
+
+/* Perl-specific SWIG API */
+
+#define SWIG_MakePtr(sv, ptr, type, flags) SWIG_Perl_MakePtr(SWIG_PERL_OBJECT_CALL sv, ptr, type, flags)
+#define SWIG_MakePackedObj(sv, p, s, type) SWIG_Perl_MakePackedObj(SWIG_PERL_OBJECT_CALL sv, p, s, type)
+#define SWIG_SetError(str) SWIG_Error(SWIG_RuntimeError, str)
+
+
+#define SWIG_PERL_DECL_ARGS_1(arg1) (SWIG_PERL_OBJECT_DECL arg1)
+#define SWIG_PERL_CALL_ARGS_1(arg1) (SWIG_PERL_OBJECT_CALL arg1)
+#define SWIG_PERL_DECL_ARGS_2(arg1, arg2) (SWIG_PERL_OBJECT_DECL arg1, arg2)
+#define SWIG_PERL_CALL_ARGS_2(arg1, arg2) (SWIG_PERL_OBJECT_CALL arg1, arg2)
+
+/* -----------------------------------------------------------------------------
+ * pointers/data manipulation
+ * ----------------------------------------------------------------------------- */
+
+/* For backward compatibility only */
+#define SWIG_POINTER_EXCEPTION 0
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SWIG_OWNER SWIG_POINTER_OWN
+#define SWIG_SHADOW SWIG_OWNER << 1
+
+#define SWIG_MAYBE_PERL_OBJECT SWIG_PERL_OBJECT_DECL
+
+/* SWIG Perl macros */
+
+/* Macro to declare an XS function */
+#ifndef XSPROTO
+# define XSPROTO(name) void name(pTHX_ CV* cv)
+#endif
+
+/* Macro to call an XS function */
+#ifdef PERL_OBJECT
+# define SWIG_CALLXS(_name) _name(cv,pPerl)
+#else
+# ifndef MULTIPLICITY
+# define SWIG_CALLXS(_name) _name(cv)
+# else
+# define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv)
+# endif
+#endif
+
+#ifdef PERL_OBJECT
+#define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef int (CPerlObj::*SwigMagicFunc)(SV *, MAGIC *);
+#ifdef __cplusplus
+}
+#endif
+
+#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b)
+#define SWIGCLASS_STATIC
+
+#else /* PERL_OBJECT */
+
+#define MAGIC_PPERL
+#define SWIGCLASS_STATIC static SWIGUNUSED
+
+#ifndef MULTIPLICITY
+#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef int (*SwigMagicFunc)(SV *, MAGIC *);
+#ifdef __cplusplus
+}
+#endif
+
+#else /* MULTIPLICITY */
+
+#define SWIG_MAGIC(a,b) (struct interpreter *interp, SV *a, MAGIC *b)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef int (*SwigMagicFunc)(struct interpreter *, SV *, MAGIC *);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MULTIPLICITY */
+#endif /* PERL_OBJECT */
+
+/* Workaround for bug in perl 5.6.x croak and earlier */
+#if (PERL_VERSION < 8)
+# ifdef PERL_OBJECT
+# define SWIG_croak_null() SWIG_Perl_croak_null(pPerl)
+static void SWIG_Perl_croak_null(CPerlObj *pPerl)
+# else
+static void SWIG_croak_null()
+# endif
+{
+ SV *err=ERRSV;
+# if (PERL_VERSION < 6)
+ croak("%_", err);
+# else
+ if (SvOK(err) && !SvROK(err)) croak("%_", err);
+ croak(Nullch);
+# endif
+}
+#else
+# define SWIG_croak_null() croak(Nullch)
+#endif
+
+
+/*
+ Define how strict is the cast between strings and integers/doubles
+ when overloading between these types occurs.
+
+ The default is making it as strict as possible by using SWIG_AddCast
+ when needed.
+
+ You can use -DSWIG_PERL_NO_STRICT_STR2NUM at compilation time to
+ disable the SWIG_AddCast, making the casting between string and
+ numbers less strict.
+
+ In the end, we try to solve the overloading between strings and
+ numerical types in the more natural way, but if you can avoid it,
+ well, avoid it using %rename, for example.
+*/
+#ifndef SWIG_PERL_NO_STRICT_STR2NUM
+# ifndef SWIG_PERL_STRICT_STR2NUM
+# define SWIG_PERL_STRICT_STR2NUM
+# endif
+#endif
+#ifdef SWIG_PERL_STRICT_STR2NUM
+/* string takes precedence */
+#define SWIG_Str2NumCast(x) SWIG_AddCast(x)
+#else
+/* number takes precedence */
+#define SWIG_Str2NumCast(x) x
+#endif
+
+
+
+#include <stdlib.h>
+
+SWIGRUNTIME const char *
+SWIG_Perl_TypeProxyName(const swig_type_info *type) {
+ if (!type) return NULL;
+ if (type->clientdata != NULL) {
+ return (const char*) type->clientdata;
+ }
+ else {
+ return type->name;
+ }
+}
+
+/* Identical to SWIG_TypeCheck, except for strcmp comparison */
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeProxyCheck(const char *c, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if ( (!iter->type->clientdata && (strcmp(iter->type->name, c) == 0)) ||
+ (iter->type->clientdata && (strcmp((char*)iter->type->clientdata, c) == 0)) ) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/* Function for getting a pointer value */
+
+SWIGRUNTIME int
+SWIG_Perl_ConvertPtrAndOwn(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_info *_t, int flags, int *own) {
+ swig_cast_info *tc;
+ void *voidptr = (void *)0;
+ SV *tsv = 0;
+
+ if (own)
+ *own = 0;
+
+ /* If magical, apply more magic */
+ if (SvGMAGICAL(sv))
+ mg_get(sv);
+
+ /* Check to see if this is an object */
+ if (sv_isobject(sv)) {
+ IV tmp = 0;
+ tsv = (SV*) SvRV(sv);
+ if ((SvTYPE(tsv) == SVt_PVHV)) {
+ MAGIC *mg;
+ if (SvMAGICAL(tsv)) {
+ mg = mg_find(tsv,'P');
+ if (mg) {
+ sv = mg->mg_obj;
+ if (sv_isobject(sv)) {
+ tsv = (SV*)SvRV(sv);
+ tmp = SvIV(tsv);
+ }
+ }
+ } else {
+ return SWIG_ERROR;
+ }
+ } else {
+ tmp = SvIV(tsv);
+ }
+ voidptr = INT2PTR(void *,tmp);
+ } else if (! SvOK(sv)) { /* Check for undef */
+ *(ptr) = (void *) 0;
+ return SWIG_OK;
+ } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */
+ if (!SvROK(sv)) {
+ *(ptr) = (void *) 0;
+ return SWIG_OK;
+ } else {
+ return SWIG_ERROR;
+ }
+ } else { /* Don't know what it is */
+ return SWIG_ERROR;
+ }
+ if (_t) {
+ /* Now see if the types match */
+ char *_c = HvNAME(SvSTASH(SvRV(sv)));
+ tc = SWIG_TypeProxyCheck(_c,_t);
+ if (!tc) {
+ return SWIG_ERROR;
+ }
+ {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,voidptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own);
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
+ } else {
+ *ptr = voidptr;
+ }
+
+ /*
+ * DISOWN implementation: we need a perl guru to check this one.
+ */
+ if (tsv && (flags & SWIG_POINTER_DISOWN)) {
+ /*
+ * almost copy paste code from below SWIG_POINTER_OWN setting
+ */
+ SV *obj = sv;
+ HV *stash = SvSTASH(SvRV(obj));
+ GV *gv = *(GV**) hv_fetch(stash, "OWNER", 5, TRUE);
+ if (isGV(gv)) {
+ HV *hv = GvHVn(gv);
+ /*
+ * To set ownership (see below), a newSViv(1) entry is added.
+ * Hence, to remove ownership, we delete the entry.
+ */
+ if (hv_exists_ent(hv, obj, 0)) {
+ hv_delete_ent(hv, obj, 0, 0);
+ }
+ }
+ }
+ return SWIG_OK;
+}
+
+SWIGRUNTIME int
+SWIG_Perl_ConvertPtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_info *_t, int flags) {
+ return SWIG_Perl_ConvertPtrAndOwn(sv, ptr, _t, flags, 0);
+}
+
+SWIGRUNTIME void
+SWIG_Perl_MakePtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, swig_type_info *t, int flags) {
+ if (ptr && (flags & (SWIG_SHADOW | SWIG_POINTER_OWN))) {
+ SV *self;
+ SV *obj=newSV(0);
+ HV *hash=newHV();
+ HV *stash;
+ sv_setref_pv(obj, (char *) SWIG_Perl_TypeProxyName(t), ptr);
+ stash=SvSTASH(SvRV(obj));
+ if (flags & SWIG_POINTER_OWN) {
+ HV *hv;
+ GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE);
+ if (!isGV(gv))
+ gv_init(gv, stash, "OWNER", 5, FALSE);
+ hv=GvHVn(gv);
+ hv_store_ent(hv, obj, newSViv(1), 0);
+ }
+ sv_magic((SV *)hash, (SV *)obj, 'P', Nullch, 0);
+ SvREFCNT_dec(obj);
+ self=newRV_noinc((SV *)hash);
+ sv_setsv(sv, self);
+ SvREFCNT_dec((SV *)self);
+ sv_bless(sv, stash);
+ }
+ else {
+ sv_setref_pv(sv, (char *) SWIG_Perl_TypeProxyName(t), ptr);
+ }
+}
+
+SWIGRUNTIMEINLINE SV *
+SWIG_Perl_NewPointerObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int flags) {
+ SV *result = sv_newmortal();
+ SWIG_MakePtr(result, ptr, t, flags);
+ return result;
+}
+
+SWIGRUNTIME void
+SWIG_Perl_MakePackedObj(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, int sz, swig_type_info *type) {
+ char result[1024];
+ char *r = result;
+ if ((2*sz + 1 + strlen(SWIG_Perl_TypeProxyName(type))) > 1000) return;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ strcpy(r,SWIG_Perl_TypeProxyName(type));
+ sv_setpv(sv, result);
+}
+
+SWIGRUNTIME SV *
+SWIG_Perl_NewPackedObj(SWIG_MAYBE_PERL_OBJECT void *ptr, int sz, swig_type_info *type) {
+ SV *result = sv_newmortal();
+ SWIG_Perl_MakePackedObj(result, ptr, sz, type);
+ return result;
+}
+
+/* Convert a packed value value */
+SWIGRUNTIME int
+SWIG_Perl_ConvertPacked(SWIG_MAYBE_PERL_OBJECT SV *obj, void *ptr, int sz, swig_type_info *ty) {
+ swig_cast_info *tc;
+ const char *c = 0;
+
+ if ((!obj) || (!SvOK(obj))) return SWIG_ERROR;
+ c = SvPV_nolen(obj);
+ /* Pointer values must start with leading underscore */
+ if (*c != '_') return SWIG_ERROR;
+ c++;
+ c = SWIG_UnpackData(c,ptr,sz);
+ if (ty) {
+ tc = SWIG_TypeCheck(c,ty);
+ if (!tc) return SWIG_ERROR;
+ }
+ return SWIG_OK;
+}
+
+
+/* Macros for low-level exception handling */
+#define SWIG_croak(x) { SWIG_Error(SWIG_RuntimeError, x); SWIG_fail; }
+
+
+typedef XSPROTO(SwigPerlWrapper);
+typedef SwigPerlWrapper *SwigPerlWrapperPtr;
+
+/* Structure for command table */
+typedef struct {
+ const char *name;
+ SwigPerlWrapperPtr wrapper;
+} swig_command_info;
+
+/* Information for constant table */
+
+#define SWIG_INT 1
+#define SWIG_FLOAT 2
+#define SWIG_STRING 3
+#define SWIG_POINTER 4
+#define SWIG_BINARY 5
+
+/* Constant information structure */
+typedef struct swig_constant_info {
+ int type;
+ const char *name;
+ long lvalue;
+ double dvalue;
+ void *pvalue;
+ swig_type_info **ptype;
+} swig_constant_info;
+
+
+/* Structure for variable table */
+typedef struct {
+ const char *name;
+ SwigMagicFunc set;
+ SwigMagicFunc get;
+ swig_type_info **type;
+} swig_variable_info;
+
+/* Magic variable code */
+#ifndef PERL_OBJECT
+#define swig_create_magic(s,a,b,c) _swig_create_magic(s,a,b,c)
+ #ifndef MULTIPLICITY
+ SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *))
+ #else
+ SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *))
+ #endif
+#else
+# define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c)
+SWIGRUNTIME void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *))
+#endif
+{
+ MAGIC *mg;
+ sv_magic(sv,sv,'U',(char *) name,strlen(name));
+ mg = mg_find(sv,'U');
+ mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL));
+ mg->mg_virtual->svt_get = (SwigMagicFunc) get;
+ mg->mg_virtual->svt_set = (SwigMagicFunc) set;
+ mg->mg_virtual->svt_len = 0;
+ mg->mg_virtual->svt_clear = 0;
+ mg->mg_virtual->svt_free = 0;
+}
+
+
+SWIGRUNTIME swig_module_info *
+SWIG_Perl_GetModule(void) {
+ static void *type_pointer = (void *)0;
+ SV *pointer;
+
+ /* first check if pointer already created */
+ if (!type_pointer) {
+ pointer = get_sv("swig_runtime_data::type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, FALSE | GV_ADDMULTI);
+ if (pointer && SvOK(pointer)) {
+ type_pointer = INT2PTR(swig_type_info **, SvIV(pointer));
+ }
+ }
+
+ return (swig_module_info *) type_pointer;
+}
+
+SWIGRUNTIME void
+SWIG_Perl_SetModule(swig_module_info *module) {
+ SV *pointer;
+
+ /* create a new pointer */
+ pointer = get_sv("swig_runtime_data::type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, TRUE | GV_ADDMULTI);
+ sv_setiv(pointer, PTR2IV(module));
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Workaround perl5 global namespace pollution. Note that undefining library
+ * functions like fopen will not solve the problem on all platforms as fopen
+ * might be a macro on Windows but not necessarily on other operating systems. */
+#ifdef do_open
+ #undef do_open
+#endif
+#ifdef do_close
+ #undef do_close
+#endif
+#ifdef do_exec
+ #undef do_exec
+#endif
+#ifdef scalar
+ #undef scalar
+#endif
+#ifdef list
+ #undef list
+#endif
+#ifdef apply
+ #undef apply
+#endif
+#ifdef convert
+ #undef convert
+#endif
+#ifdef Error
+ #undef Error
+#endif
+#ifdef form
+ #undef form
+#endif
+#ifdef vform
+ #undef vform
+#endif
+#ifdef LABEL
+ #undef LABEL
+#endif
+#ifdef METHOD
+ #undef METHOD
+#endif
+#ifdef Move
+ #undef Move
+#endif
+#ifdef yylex
+ #undef yylex
+#endif
+#ifdef yyparse
+ #undef yyparse
+#endif
+#ifdef yyerror
+ #undef yyerror
+#endif
+#ifdef invert
+ #undef invert
+#endif
+#ifdef ref
+ #undef ref
+#endif
+#ifdef read
+ #undef read
+#endif
+#ifdef write
+ #undef write
+#endif
+#ifdef eof
+ #undef eof
+#endif
+#ifdef bool
+ #undef bool
+#endif
+#ifdef close
+ #undef close
+#endif
+#ifdef rewind
+ #undef rewind
+#endif
+#ifdef free
+ #undef free
+#endif
+#ifdef malloc
+ #undef malloc
+#endif
+#ifdef calloc
+ #undef calloc
+#endif
+#ifdef Stat
+ #undef Stat
+#endif
+#ifdef check
+ #undef check
+#endif
+#ifdef seekdir
+ #undef seekdir
+#endif
+#ifdef open
+ #undef open
+#endif
+#ifdef readdir
+ #undef readdir
+#endif
+#ifdef bind
+ #undef bind
+#endif
+
+
+
+#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
+
+#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
+
+
+
+ #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0)
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_char swig_types[0]
+#define SWIGTYPE_p_marisa__Key swig_types[1]
+#define SWIGTYPE_p_marisa_swig__Agent swig_types[2]
+#define SWIGTYPE_p_marisa_swig__Key swig_types[3]
+#define SWIGTYPE_p_marisa_swig__Keyset swig_types[4]
+#define SWIGTYPE_p_marisa_swig__Query swig_types[5]
+#define SWIGTYPE_p_marisa_swig__Trie swig_types[6]
+#define SWIGTYPE_p_p_char swig_types[7]
+#define SWIGTYPE_p_std__size_t swig_types[8]
+static swig_type_info *swig_types[10];
+static swig_module_info swig_module = {swig_types, 9, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+#define SWIG_init boot_marisa
+
+#define SWIG_name "marisac::boot_marisa"
+#define SWIG_prefix "marisac::"
+
+#define SWIGVERSION 0x010340
+#define SWIG_VERSION SWIGVERSION
+
+
+#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a))
+#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a))
+
+
+#include <stdexcept>
+
+
+#ifdef __cplusplus
+extern "C"
+#endif
+#ifndef PERL_OBJECT
+#ifndef MULTIPLICITY
+SWIGEXPORT void SWIG_init (CV* cv);
+#else
+SWIGEXPORT void SWIG_init (pTHXo_ CV* cv);
+#endif
+#else
+SWIGEXPORT void SWIG_init (CV *cv, CPerlObj *);
+#endif
+
+
+#include "marisa-swig.h"
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_long SWIG_PERL_DECL_ARGS_1(long value)
+{
+ SV *obj = sv_newmortal();
+ sv_setiv(obj, (IV) value);
+ return obj;
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_int SWIG_PERL_DECL_ARGS_1(int value)
+{
+ return SWIG_From_long SWIG_PERL_CALL_ARGS_1(value);
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_FromCharPtrAndSize(const char* carray, size_t size)
+{
+ SV *obj = sv_newmortal();
+ if (carray) {
+ sv_setpvn(obj, carray, size);
+ } else {
+ sv_setsv(obj, &PL_sv_undef);
+ }
+ return obj;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_double SWIG_PERL_DECL_ARGS_2(SV *obj, double *val)
+{
+ if (SvNIOK(obj)) {
+ if (val) *val = SvNV(obj);
+ return SWIG_OK;
+ } else if (SvIOK(obj)) {
+ if (val) *val = (double) SvIV(obj);
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ const char *nptr = SvPV_nolen(obj);
+ if (nptr) {
+ char *endptr;
+ double v = strtod(nptr, &endptr);
+ if (errno == ERANGE) {
+ errno = 0;
+ return SWIG_OverflowError;
+ } else {
+ if (*endptr == '\0') {
+ if (val) *val = v;
+ return SWIG_Str2NumCast(SWIG_OK);
+ }
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_unsigned_SS_long SWIG_PERL_DECL_ARGS_1(unsigned long value)
+{
+ SV *obj = sv_newmortal();
+ sv_setuv(obj, (UV) value);
+ return obj;
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_size_t SWIG_PERL_DECL_ARGS_1(size_t value)
+{
+ return SWIG_From_unsigned_SS_long SWIG_PERL_CALL_ARGS_1(static_cast< unsigned long >(value));
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_double SWIG_PERL_DECL_ARGS_1(double value)
+{
+ SV *obj = sv_newmortal();
+ sv_setnv(obj, value);
+ return obj;
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_float SWIG_PERL_DECL_ARGS_1(float value)
+{
+ return SWIG_From_double SWIG_PERL_CALL_ARGS_1(value);
+}
+
+
+SWIGINTERN swig_type_info*
+SWIG_pchar_descriptor(void)
+{
+ static int init = 0;
+ static swig_type_info* info = 0;
+ if (!init) {
+ info = SWIG_TypeQuery("_p_char");
+ init = 1;
+ }
+ return info;
+}
+
+
+SWIGINTERN int
+SWIG_AsCharPtrAndSize(SV *obj, char** cptr, size_t* psize, int *alloc)
+{
+ if (SvMAGICAL(obj)) {
+ SV *tmp = sv_newmortal();
+ SvSetSV(tmp, obj);
+ obj = tmp;
+ }
+ if (SvPOK(obj)) {
+ STRLEN len = 0;
+ char *cstr = SvPV(obj, len);
+ size_t size = len + 1;
+ if (cptr) {
+ if (alloc) {
+ if (*alloc == SWIG_NEWOBJ) {
+ *cptr = reinterpret_cast< char* >(memcpy((new char[size]), cstr, sizeof(char)*(size)));
+ } else {
+ *cptr = cstr;
+ *alloc = SWIG_OLDOBJ;
+ }
+ }
+ }
+ if (psize) *psize = size;
+ return SWIG_OK;
+ } else {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ if (pchar_descriptor) {
+ char* vptr = 0;
+ if (SWIG_ConvertPtr(obj, (void**)&vptr, pchar_descriptor, 0) == SWIG_OK) {
+ if (cptr) *cptr = vptr;
+ if (psize) *psize = vptr ? (strlen(vptr) + 1) : 0;
+ if (alloc) *alloc = SWIG_OLDOBJ;
+ return SWIG_OK;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+#include <float.h>
+
+
+SWIGINTERN int
+SWIG_AsVal_float SWIG_PERL_DECL_ARGS_2(SV * obj, float *val)
+{
+ double v;
+ int res = SWIG_AsVal_double SWIG_PERL_CALL_ARGS_2(obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < -FLT_MAX || v > FLT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = static_cast< float >(v);
+ }
+ }
+ return res;
+}
+
+
+
+
+
+#include <math.h>
+
+
+SWIGINTERNINLINE int
+SWIG_CanCastAsInteger(double *d, double min, double max) {
+ double x = *d;
+ if ((min <= x && x <= max)) {
+ double fx = floor(x);
+ double cx = ceil(x);
+ double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */
+ if ((errno == EDOM) || (errno == ERANGE)) {
+ errno = 0;
+ } else {
+ double summ, reps, diff;
+ if (rd < x) {
+ diff = x - rd;
+ } else if (rd > x) {
+ diff = rd - x;
+ } else {
+ return 1;
+ }
+ summ = rd + x;
+ reps = diff/summ;
+ if (reps < 8*DBL_EPSILON) {
+ *d = rd;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_unsigned_SS_long SWIG_PERL_DECL_ARGS_2(SV *obj, unsigned long *val)
+{
+ if (SvUOK(obj)) {
+ if (val) *val = SvUV(obj);
+ return SWIG_OK;
+ } else if (SvIOK(obj)) {
+ long v = SvIV(obj);
+ if (v >= 0) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ return SWIG_OverflowError;
+ }
+ } else {
+ int dispatch = 0;
+ const char *nptr = SvPV_nolen(obj);
+ if (nptr) {
+ char *endptr;
+ unsigned long v;
+ errno = 0;
+ v = strtoul(nptr, &endptr,0);
+ if (errno == ERANGE) {
+ errno = 0;
+ return SWIG_OverflowError;
+ } else {
+ if (*endptr == '\0') {
+ if (val) *val = v;
+ return SWIG_Str2NumCast(SWIG_OK);
+ }
+ }
+ }
+ if (!dispatch) {
+ double d;
+ int res = SWIG_AddCast(SWIG_AsVal_double SWIG_PERL_CALL_ARGS_2(obj,&d));
+ if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
+ if (val) *val = (unsigned long)(d);
+ return res;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERNINLINE int
+SWIG_AsVal_size_t SWIG_PERL_DECL_ARGS_2(SV * obj, size_t *val)
+{
+ unsigned long v;
+ int res = SWIG_AsVal_unsigned_SS_long SWIG_PERL_CALL_ARGS_2(obj, val ? &v : 0);
+ if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v);
+ return res;
+}
+
+
+SWIGINTERNINLINE SV *
+SWIG_From_bool SWIG_PERL_DECL_ARGS_1(bool value)
+{
+ SV *obj = sv_newmortal();
+ if (value) {
+ sv_setsv(obj, &PL_sv_yes);
+ } else {
+ sv_setsv(obj, &PL_sv_no);
+ }
+ return obj;
+}
+
+
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+# define LLONG_MAX __LONG_LONG_MAX__
+# define LLONG_MIN (-LLONG_MAX - 1LL)
+# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+
+
+SWIGINTERN int
+SWIG_AsVal_long SWIG_PERL_DECL_ARGS_2(SV *obj, long* val)
+{
+ if (SvIOK(obj)) {
+ if (val) *val = SvIV(obj);
+ return SWIG_OK;
+ } else {
+ int dispatch = 0;
+ const char *nptr = SvPV_nolen(obj);
+ if (nptr) {
+ char *endptr;
+ long v;
+ errno = 0;
+ v = strtol(nptr, &endptr,0);
+ if (errno == ERANGE) {
+ errno = 0;
+ return SWIG_OverflowError;
+ } else {
+ if (*endptr == '\0') {
+ if (val) *val = v;
+ return SWIG_Str2NumCast(SWIG_OK);
+ }
+ }
+ }
+ if (!dispatch) {
+ double d;
+ int res = SWIG_AddCast(SWIG_AsVal_double SWIG_PERL_CALL_ARGS_2(obj,&d));
+ if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
+ if (val) *val = (long)(d);
+ return res;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_int SWIG_PERL_DECL_ARGS_2(SV * obj, int *val)
+{
+ long v;
+ int res = SWIG_AsVal_long SWIG_PERL_CALL_ARGS_2(obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < INT_MIN || v > INT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = static_cast< int >(v);
+ }
+ }
+ return res;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef PERL_OBJECT
+#define MAGIC_CLASS _wrap_marisa_var::
+class _wrap_marisa_var : public CPerlObj {
+public:
+#else
+#define MAGIC_CLASS
+#endif
+SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *SWIGUNUSEDPARM(sv), MAGIC *SWIGUNUSEDPARM(mg)) {
+ MAGIC_PPERL
+ croak("Value is read-only.");
+ return 0;
+}
+
+
+#ifdef PERL_OBJECT
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+XS(_wrap_Key_str) {
+ {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ int argvi = 0;
+ dXSARGS;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Key_str(self,length_out);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Key_str" "', argument " "1"" of type '" "marisa_swig::Key const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ ((marisa_swig::Key const *)arg1)->str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+ if (*arg2) {
+ if (argvi >= items) EXTEND(sp,1); ST(argvi) = SWIG_FromCharPtrAndSize(*arg2,*arg3); argvi++ ;
+ ;
+ }
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Key_id) {
+ {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Key_id(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Key_id" "', argument " "1"" of type '" "marisa_swig::Key const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Key const *)arg1)->id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Key_weight) {
+ {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ float result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Key_weight(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Key_weight" "', argument " "1"" of type '" "marisa_swig::Key const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ result = (float)((marisa_swig::Key const *)arg1)->weight();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_float SWIG_PERL_CALL_ARGS_1(static_cast< float >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_delete_Key) {
+ {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: delete_Key(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Key, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Key" "', argument " "1"" of type '" "marisa_swig::Key *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Query_str) {
+ {
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ int argvi = 0;
+ dXSARGS;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Query_str(self,length_out);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Query_str" "', argument " "1"" of type '" "marisa_swig::Query const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ ((marisa_swig::Query const *)arg1)->str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+ if (*arg2) {
+ if (argvi >= items) EXTEND(sp,1); ST(argvi) = SWIG_FromCharPtrAndSize(*arg2,*arg3); argvi++ ;
+ ;
+ }
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Query_id) {
+ {
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Query_id(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Query_id" "', argument " "1"" of type '" "marisa_swig::Query const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Query const *)arg1)->id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_delete_Query) {
+ {
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: delete_Query(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Query, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Query" "', argument " "1"" of type '" "marisa_swig::Query *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_new_Keyset) {
+ {
+ int argvi = 0;
+ marisa_swig::Keyset *result = 0 ;
+ dXSARGS;
+
+ if ((items < 0) || (items > 0)) {
+ SWIG_croak("Usage: new_Keyset();");
+ }
+ {
+ try {
+ result = (marisa_swig::Keyset *)new marisa_swig::Keyset();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Keyset, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
+ XSRETURN(argvi);
+ fail:
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_delete_Keyset) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: delete_Keyset(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Keyset" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_push_back__SWIG_0) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ marisa::Key *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 ;
+ int res2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Keyset_push_back(self,key);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_push_back" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa__Key, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Keyset_push_back" "', argument " "2"" of type '" "marisa::Key const &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Keyset_push_back" "', argument " "2"" of type '" "marisa::Key const &""'");
+ }
+ arg2 = reinterpret_cast< marisa::Key * >(argp2);
+ {
+ try {
+ (arg1)->push_back((marisa::Key const &)*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_push_back__SWIG_1) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ float arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ float val4 ;
+ int ecode4 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 3) || (items > 3)) {
+ SWIG_croak("Usage: Keyset_push_back(self,ptr,length,weight);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_push_back" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Keyset_push_back" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ ecode4 = SWIG_AsVal_float SWIG_PERL_CALL_ARGS_2(ST(2), &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Keyset_push_back" "', argument " "4"" of type '" "float""'");
+ }
+ arg4 = static_cast< float >(val4);
+ {
+ try {
+ (arg1)->push_back((char const *)arg2,arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_push_back__SWIG_2) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Keyset_push_back(self,ptr,length);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_push_back" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Keyset_push_back" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ (arg1)->push_back((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_push_back) {
+ dXSARGS;
+
+ {
+ unsigned long _index = 0;
+ SWIG_TypeRank _rank = 0;
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(1), &vptr, SWIGTYPE_p_marisa__Key, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 1;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_1:
+
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ int res = SWIG_AsCharPtrAndSize(ST(1), 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (items > 2) {
+ {
+ {
+ int res = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(2), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ }
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 2;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_2:
+
+ if (items == 3) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_3;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ int res = SWIG_AsCharPtrAndSize(ST(1), 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_3;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ {
+ int res = SWIG_AsVal_float SWIG_PERL_CALL_ARGS_2(ST(2), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_3;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 3;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_3:
+
+ dispatch:
+ switch(_index) {
+ case 1:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Keyset_push_back__SWIG_0); return;
+ case 2:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Keyset_push_back__SWIG_2); return;
+ case 3:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Keyset_push_back__SWIG_1); return;
+ }
+ }
+
+ croak("No matching function for overloaded 'Keyset_push_back'");
+ XSRETURN(0);
+}
+
+
+XS(_wrap_Keyset_key) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ int argvi = 0;
+ marisa_swig::Key *result = 0 ;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Keyset_key(self,i);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_key" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Keyset_key" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ result = (marisa_swig::Key *) &((marisa_swig::Keyset const *)arg1)->key(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Key, 0 | SWIG_SHADOW); argvi++ ;
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_key_str) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ char **arg3 = (char **) 0 ;
+ std::size_t *arg4 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ char *temp3 = 0 ;
+ std::size_t tempn3 ;
+ int argvi = 0;
+ dXSARGS;
+
+ arg3 = &temp3; arg4 = &tempn3;
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Keyset_key_str(self,i,length_out);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_key_str" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Keyset_key_str" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ ((marisa_swig::Keyset const *)arg1)->key_str(arg2,(char const **)arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+ if (*arg3) {
+ if (argvi >= items) EXTEND(sp,1); ST(argvi) = SWIG_FromCharPtrAndSize(*arg3,*arg4); argvi++ ;
+ ;
+ }
+
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_key_id) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Keyset_key_id(self,i);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_key_id" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Keyset_key_id" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->key_id(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_num_keys) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Keyset_num_keys(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_num_keys" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->num_keys();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_empty) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ bool result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Keyset_empty(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_empty" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = (bool)((marisa_swig::Keyset const *)arg1)->empty();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_size) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Keyset_size(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_size" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_total_length) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Keyset_total_length(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_total_length" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->total_length();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_reset) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Keyset_reset(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_reset" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ (arg1)->reset();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Keyset_clear) {
+ {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Keyset_clear(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_clear" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ (arg1)->clear();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_new_Agent) {
+ {
+ int argvi = 0;
+ marisa_swig::Agent *result = 0 ;
+ dXSARGS;
+
+ if ((items < 0) || (items > 0)) {
+ SWIG_croak("Usage: new_Agent();");
+ }
+ {
+ try {
+ result = (marisa_swig::Agent *)new marisa_swig::Agent();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Agent, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
+ XSRETURN(argvi);
+ fail:
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_delete_Agent) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: delete_Agent(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Agent" "', argument " "1"" of type '" "marisa_swig::Agent *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_set_query__SWIG_0) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Agent_set_query(self,ptr,length);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_set_query" "', argument " "1"" of type '" "marisa_swig::Agent *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Agent_set_query" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ (arg1)->set_query((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_set_query__SWIG_1) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Agent_set_query(self,id);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_set_query" "', argument " "1"" of type '" "marisa_swig::Agent *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ ecode2 = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Agent_set_query" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ (arg1)->set_query(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_set_query) {
+ dXSARGS;
+
+ {
+ unsigned long _index = 0;
+ SWIG_TypeRank _rank = 0;
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ {
+ int res = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 1;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_1:
+
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ int res = SWIG_AsCharPtrAndSize(ST(1), 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (items > 2) {
+ {
+ {
+ int res = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(2), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ }
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 2;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_2:
+
+ dispatch:
+ switch(_index) {
+ case 1:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Agent_set_query__SWIG_1); return;
+ case 2:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Agent_set_query__SWIG_0); return;
+ }
+ }
+
+ croak("No matching function for overloaded 'Agent_set_query'");
+ XSRETURN(0);
+}
+
+
+XS(_wrap_Agent_key) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ marisa_swig::Key *result = 0 ;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Agent_key(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_key" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = (marisa_swig::Key *) &((marisa_swig::Agent const *)arg1)->key();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Key, 0 | SWIG_SHADOW); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_query) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ marisa_swig::Query *result = 0 ;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Agent_query(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_query" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = (marisa_swig::Query *) &((marisa_swig::Agent const *)arg1)->query();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Query, 0 | SWIG_SHADOW); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_key_str) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ int argvi = 0;
+ dXSARGS;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Agent_key_str(self,length_out);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_key_str" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ ((marisa_swig::Agent const *)arg1)->key_str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+ if (*arg2) {
+ if (argvi >= items) EXTEND(sp,1); ST(argvi) = SWIG_FromCharPtrAndSize(*arg2,*arg3); argvi++ ;
+ ;
+ }
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_key_id) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Agent_key_id(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_key_id" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Agent const *)arg1)->key_id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_query_str) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ int argvi = 0;
+ dXSARGS;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Agent_query_str(self,length_out);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_query_str" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ ((marisa_swig::Agent const *)arg1)->query_str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+ if (*arg2) {
+ if (argvi >= items) EXTEND(sp,1); ST(argvi) = SWIG_FromCharPtrAndSize(*arg2,*arg3); argvi++ ;
+ ;
+ }
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Agent_query_id) {
+ {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Agent_query_id(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_query_id" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Agent const *)arg1)->query_id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_new_Trie) {
+ {
+ int argvi = 0;
+ marisa_swig::Trie *result = 0 ;
+ dXSARGS;
+
+ if ((items < 0) || (items > 0)) {
+ SWIG_croak("Usage: new_Trie();");
+ }
+ {
+ try {
+ result = (marisa_swig::Trie *)new marisa_swig::Trie();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Trie, SWIG_OWNER | SWIG_SHADOW); argvi++ ;
+ XSRETURN(argvi);
+ fail:
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_delete_Trie) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: delete_Trie(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Trie" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_build__SWIG_0) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Keyset *arg2 = 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 3) || (items > 3)) {
+ SWIG_croak("Usage: Trie_build(self,keyset,config_flags);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_build" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa_swig__Keyset, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Keyset * >(argp2);
+ ecode3 = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(2), &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Trie_build" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = static_cast< int >(val3);
+ {
+ try {
+ (arg1)->build(*arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_build__SWIG_1) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Keyset *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_build(self,keyset);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_build" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa_swig__Keyset, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Keyset * >(argp2);
+ {
+ try {
+ (arg1)->build(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_build) {
+ dXSARGS;
+
+ {
+ unsigned long _index = 0;
+ SWIG_TypeRank _rank = 0;
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(1), &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 1;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_1:
+
+ if (items == 3) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(1), &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ {
+ int res = SWIG_AsVal_int SWIG_PERL_CALL_ARGS_2(ST(2), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 2;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_2:
+
+ dispatch:
+ switch(_index) {
+ case 1:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Trie_build__SWIG_1); return;
+ case 2:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Trie_build__SWIG_0); return;
+ }
+ }
+
+ croak("No matching function for overloaded 'Trie_build'");
+ XSRETURN(0);
+}
+
+
+XS(_wrap_Trie_mmap) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_mmap(self,filename);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_mmap" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_mmap" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ (arg1)->mmap((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_load) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_load(self,filename);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_load" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_load" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ (arg1)->load((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_save) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_save(self,filename);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_save" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_save" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->save((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_lookup__SWIG_0) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int argvi = 0;
+ bool result;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_lookup(self,agent);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->lookup(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_reverse_lookup__SWIG_0) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_reverse_lookup(self,agent);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_reverse_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_reverse_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_reverse_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->reverse_lookup(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_common_prefix_search) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int argvi = 0;
+ bool result;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_common_prefix_search(self,agent);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_common_prefix_search" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_common_prefix_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_common_prefix_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->common_prefix_search(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_predictive_search) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int argvi = 0;
+ bool result;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_predictive_search(self,agent);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_predictive_search" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(ST(1), &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_predictive_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_predictive_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->predictive_search(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_lookup__SWIG_1) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_lookup(self,ptr,length);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_lookup" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->lookup((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ XSRETURN(argvi);
+ fail:
+
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_lookup) {
+ dXSARGS;
+
+ {
+ unsigned long _index = 0;
+ SWIG_TypeRank _rank = 0;
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(1), &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 1;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_1:
+
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ int res = SWIG_AsCharPtrAndSize(ST(1), 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (items > 2) {
+ {
+ {
+ int res = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(2), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ }
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 2;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_2:
+
+ dispatch:
+ switch(_index) {
+ case 1:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Trie_lookup__SWIG_0); return;
+ case 2:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Trie_lookup__SWIG_1); return;
+ }
+ }
+
+ croak("No matching function for overloaded 'Trie_lookup'");
+ XSRETURN(0);
+}
+
+
+XS(_wrap_Trie_reverse_lookup__SWIG_1) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ std::size_t arg2 ;
+ char **arg3 = (char **) 0 ;
+ std::size_t *arg4 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ char *temp3 = 0 ;
+ std::size_t tempn3 ;
+ int argvi = 0;
+ dXSARGS;
+
+ arg3 = &temp3; arg4 = &tempn3;
+ if ((items < 2) || (items > 2)) {
+ SWIG_croak("Usage: Trie_reverse_lookup(self,id,length_out);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_reverse_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ ecode2 = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Trie_reverse_lookup" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->reverse_lookup(arg2,(char const **)arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+ if (*arg3) {
+ if (argvi >= items) EXTEND(sp,1); ST(argvi) = SWIG_FromCharPtrAndSize(*arg3,*arg4); argvi++ ;
+ delete [] (*arg3);
+ }
+
+
+
+ XSRETURN(argvi);
+ fail:
+
+
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_reverse_lookup) {
+ dXSARGS;
+
+ {
+ unsigned long _index = 0;
+ SWIG_TypeRank _rank = 0;
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(1), &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_1;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 1;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_1:
+
+ if (items == 2) {
+ SWIG_TypeRank _ranki = 0;
+ SWIG_TypeRank _rankm = 0;
+ SWIG_TypeRank _pi = 1;
+ int _v = 0;
+ {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(ST(0), &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ {
+ {
+ int res = SWIG_AsVal_size_t SWIG_PERL_CALL_ARGS_2(ST(1), NULL);
+ _v = SWIG_CheckState(res);
+ }
+ }
+ if (!_v) goto check_2;
+ _ranki += _v*_pi;
+ _rankm += _pi;
+ _pi *= SWIG_MAXCASTRANK;
+ if (!_index || (_ranki < _rank)) {
+ _rank = _ranki; _index = 2;
+ if (_rank == _rankm) goto dispatch;
+ }
+ }
+ check_2:
+
+ dispatch:
+ switch(_index) {
+ case 1:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Trie_reverse_lookup__SWIG_0); return;
+ case 2:
+ ++PL_markstack_ptr; SWIG_CALLXS(_wrap_Trie_reverse_lookup__SWIG_1); return;
+ }
+ }
+
+ croak("No matching function for overloaded 'Trie_reverse_lookup'");
+ XSRETURN(0);
+}
+
+
+XS(_wrap_Trie_num_tries) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_num_tries(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_num_tries" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_tries();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_num_keys) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_num_keys(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_num_keys" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_keys();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_num_nodes) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_num_nodes(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_num_nodes" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_nodes();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_tail_mode) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ marisa_swig::TailMode result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_tail_mode(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_tail_mode" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (marisa_swig::TailMode)((marisa_swig::Trie const *)arg1)->tail_mode();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_node_order) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ marisa_swig::NodeOrder result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_node_order(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_node_order" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (marisa_swig::NodeOrder)((marisa_swig::Trie const *)arg1)->node_order();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_empty) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ bool result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_empty(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_empty" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->empty();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_bool SWIG_PERL_CALL_ARGS_1(static_cast< bool >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_size) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_size(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_size" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_total_size) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_total_size(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_total_size" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->total_size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_io_size) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ std::size_t result;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_io_size(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_io_size" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->io_size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(result)); argvi++ ;
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+XS(_wrap_Trie_clear) {
+ {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int argvi = 0;
+ dXSARGS;
+
+ if ((items < 1) || (items > 1)) {
+ SWIG_croak("Usage: Trie_clear(self);");
+ }
+ res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_clear" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ (arg1)->clear();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ ST(argvi) = sv_newmortal();
+
+ XSRETURN(argvi);
+ fail:
+
+ SWIG_croak_null();
+ }
+}
+
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa__Key = {"_p_marisa__Key", "marisa::Key *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Agent = {"_p_marisa_swig__Agent", "marisa_swig::Agent *", 0, 0, (void*)"marisa::Agent", 0};
+static swig_type_info _swigt__p_marisa_swig__Key = {"_p_marisa_swig__Key", "marisa_swig::Key *", 0, 0, (void*)"marisa::Key", 0};
+static swig_type_info _swigt__p_marisa_swig__Keyset = {"_p_marisa_swig__Keyset", "marisa_swig::Keyset *", 0, 0, (void*)"marisa::Keyset", 0};
+static swig_type_info _swigt__p_marisa_swig__Query = {"_p_marisa_swig__Query", "marisa_swig::Query *", 0, 0, (void*)"marisa::Query", 0};
+static swig_type_info _swigt__p_marisa_swig__Trie = {"_p_marisa_swig__Trie", "marisa_swig::Trie *", 0, 0, (void*)"marisa::Trie", 0};
+static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__size_t = {"_p_std__size_t", "std::size_t *", 0, 0, (void*)0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+ &_swigt__p_char,
+ &_swigt__p_marisa__Key,
+ &_swigt__p_marisa_swig__Agent,
+ &_swigt__p_marisa_swig__Key,
+ &_swigt__p_marisa_swig__Keyset,
+ &_swigt__p_marisa_swig__Query,
+ &_swigt__p_marisa_swig__Trie,
+ &_swigt__p_p_char,
+ &_swigt__p_std__size_t,
+};
+
+static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa__Key[] = { {&_swigt__p_marisa__Key, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Agent[] = { {&_swigt__p_marisa_swig__Agent, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Key[] = { {&_swigt__p_marisa_swig__Key, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Keyset[] = { {&_swigt__p_marisa_swig__Keyset, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Query[] = { {&_swigt__p_marisa_swig__Query, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Trie[] = { {&_swigt__p_marisa_swig__Trie, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__size_t[] = { {&_swigt__p_std__size_t, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+ _swigc__p_char,
+ _swigc__p_marisa__Key,
+ _swigc__p_marisa_swig__Agent,
+ _swigc__p_marisa_swig__Key,
+ _swigc__p_marisa_swig__Keyset,
+ _swigc__p_marisa_swig__Query,
+ _swigc__p_marisa_swig__Trie,
+ _swigc__p_p_char,
+ _swigc__p_std__size_t,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+static swig_constant_info swig_constants[] = {
+{0,0,0,0,0,0}
+};
+#ifdef __cplusplus
+}
+#endif
+static swig_variable_info swig_variables[] = {
+{0,0,0,0}
+};
+static swig_command_info swig_commands[] = {
+{"marisac::Key_str", _wrap_Key_str},
+{"marisac::Key_id", _wrap_Key_id},
+{"marisac::Key_weight", _wrap_Key_weight},
+{"marisac::delete_Key", _wrap_delete_Key},
+{"marisac::Query_str", _wrap_Query_str},
+{"marisac::Query_id", _wrap_Query_id},
+{"marisac::delete_Query", _wrap_delete_Query},
+{"marisac::new_Keyset", _wrap_new_Keyset},
+{"marisac::delete_Keyset", _wrap_delete_Keyset},
+{"marisac::Keyset_push_back", _wrap_Keyset_push_back},
+{"marisac::Keyset_key", _wrap_Keyset_key},
+{"marisac::Keyset_key_str", _wrap_Keyset_key_str},
+{"marisac::Keyset_key_id", _wrap_Keyset_key_id},
+{"marisac::Keyset_num_keys", _wrap_Keyset_num_keys},
+{"marisac::Keyset_empty", _wrap_Keyset_empty},
+{"marisac::Keyset_size", _wrap_Keyset_size},
+{"marisac::Keyset_total_length", _wrap_Keyset_total_length},
+{"marisac::Keyset_reset", _wrap_Keyset_reset},
+{"marisac::Keyset_clear", _wrap_Keyset_clear},
+{"marisac::new_Agent", _wrap_new_Agent},
+{"marisac::delete_Agent", _wrap_delete_Agent},
+{"marisac::Agent_set_query", _wrap_Agent_set_query},
+{"marisac::Agent_key", _wrap_Agent_key},
+{"marisac::Agent_query", _wrap_Agent_query},
+{"marisac::Agent_key_str", _wrap_Agent_key_str},
+{"marisac::Agent_key_id", _wrap_Agent_key_id},
+{"marisac::Agent_query_str", _wrap_Agent_query_str},
+{"marisac::Agent_query_id", _wrap_Agent_query_id},
+{"marisac::new_Trie", _wrap_new_Trie},
+{"marisac::delete_Trie", _wrap_delete_Trie},
+{"marisac::Trie_build", _wrap_Trie_build},
+{"marisac::Trie_mmap", _wrap_Trie_mmap},
+{"marisac::Trie_load", _wrap_Trie_load},
+{"marisac::Trie_save", _wrap_Trie_save},
+{"marisac::Trie_common_prefix_search", _wrap_Trie_common_prefix_search},
+{"marisac::Trie_predictive_search", _wrap_Trie_predictive_search},
+{"marisac::Trie_lookup", _wrap_Trie_lookup},
+{"marisac::Trie_reverse_lookup", _wrap_Trie_reverse_lookup},
+{"marisac::Trie_num_tries", _wrap_Trie_num_tries},
+{"marisac::Trie_num_keys", _wrap_Trie_num_keys},
+{"marisac::Trie_num_nodes", _wrap_Trie_num_nodes},
+{"marisac::Trie_tail_mode", _wrap_Trie_tail_mode},
+{"marisac::Trie_node_order", _wrap_Trie_node_order},
+{"marisac::Trie_empty", _wrap_Trie_empty},
+{"marisac::Trie_size", _wrap_Trie_size},
+{"marisac::Trie_total_size", _wrap_Trie_total_size},
+{"marisac::Trie_io_size", _wrap_Trie_io_size},
+{"marisac::Trie_clear", _wrap_Trie_clear},
+{0,0}
+};
+/* -----------------------------------------------------------------------------
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+ *
+ * The generated swig_type_info structures are assigned staticly to an initial
+ * array. We just loop through that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+ *
+ * First off, we lookup the cast->type name to see if it is already loaded.
+ * There are three cases to handle:
+ * 1) If the cast->type has already been loaded AND the type we are adding
+ * casting info to has not been loaded (it is in this module), THEN we
+ * replace the cast->type pointer with the type pointer that has already
+ * been loaded.
+ * 2) If BOTH types (the one we are adding casting info to, and the
+ * cast->type) are loaded, THEN the cast info has already been loaded by
+ * the previous module so we just ignore it.
+ * 3) Finally, if cast->type has not already been loaded, then we add that
+ * swig_cast_info to the linked list (because the cast->type) pointer will
+ * be correct.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* c-mode */
+#endif
+#endif
+
+#if 0
+#define SWIGRUNTIME_DEBUG
+#endif
+
+
+SWIGRUNTIME void
+SWIG_InitializeModule(void *clientdata) {
+ size_t i;
+ swig_module_info *module_head, *iter;
+ int found, init;
+
+ clientdata = clientdata;
+
+ /* check to see if the circular list has been setup, if not, set it up */
+ if (swig_module.next==0) {
+ /* Initialize the swig_module */
+ swig_module.type_initial = swig_type_initial;
+ swig_module.cast_initial = swig_cast_initial;
+ swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
+ }
+
+ /* Try and load any already created modules */
+ module_head = SWIG_GetModule(clientdata);
+ if (!module_head) {
+ /* This is the first module loaded for this interpreter */
+ /* so set the swig module into the interpreter */
+ SWIG_SetModule(clientdata, &swig_module);
+ module_head = &swig_module;
+ } else {
+ /* the interpreter has loaded a SWIG module, but has it loaded this one? */
+ found=0;
+ iter=module_head;
+ do {
+ if (iter==&swig_module) {
+ found=1;
+ break;
+ }
+ iter=iter->next;
+ } while (iter!= module_head);
+
+ /* if the is found in the list, then all is done and we may leave */
+ if (found) return;
+ /* otherwise we must add out module into the list */
+ swig_module.next = module_head->next;
+ module_head->next = &swig_module;
+ }
+
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
+ /* Now work on filling in swig_module.types */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: size %d\n", swig_module.size);
+#endif
+ for (i = 0; i < swig_module.size; ++i) {
+ swig_type_info *type = 0;
+ swig_type_info *ret;
+ swig_cast_info *cast;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+#endif
+
+ /* if there is another module already loaded */
+ if (swig_module.next != &swig_module) {
+ type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+ }
+ if (type) {
+ /* Overwrite clientdata field */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found type %s\n", type->name);
+#endif
+ if (swig_module.type_initial[i]->clientdata) {
+ type->clientdata = swig_module.type_initial[i]->clientdata;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
+#endif
+ }
+ } else {
+ type = swig_module.type_initial[i];
+ }
+
+ /* Insert casting types */
+ cast = swig_module.cast_initial[i];
+ while (cast->type) {
+ /* Don't need to add information already in the list */
+ ret = 0;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
+#endif
+ if (swig_module.next != &swig_module) {
+ ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
+#endif
+ }
+ if (ret) {
+ if (type == swig_module.type_initial[i]) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
+#endif
+ cast->type = ret;
+ ret = 0;
+ } else {
+ /* Check for casting already in the list */
+ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
+#endif
+ if (!ocast) ret = 0;
+ }
+ }
+
+ if (!ret) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
+#endif
+ if (type->cast) {
+ type->cast->prev = cast;
+ cast->next = type->cast;
+ }
+ type->cast = cast;
+ }
+ cast++;
+ }
+ /* Set entry in modules->types array equal to the type */
+ swig_module.types[i] = type;
+ }
+ swig_module.types[i] = 0;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+ for (i = 0; i < swig_module.size; ++i) {
+ int j = 0;
+ swig_cast_info *cast = swig_module.cast_initial[i];
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+ while (cast->type) {
+ printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
+ cast++;
+ ++j;
+ }
+ printf("---- Total casts: %d\n",j);
+ }
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+#endif
+}
+
+/* This function will propagate the clientdata field of type to
+* any new swig_type_info structures that have been added into the list
+* of equivalent types. It is like calling
+* SWIG_TypeClientData(type, clientdata) a second time.
+*/
+SWIGRUNTIME void
+SWIG_PropagateClientData(void) {
+ size_t i;
+ swig_cast_info *equiv;
+ static int init_run = 0;
+
+ if (init_run) return;
+ init_run = 1;
+
+ for (i = 0; i < swig_module.size; i++) {
+ if (swig_module.types[i]->clientdata) {
+ equiv = swig_module.types[i]->cast;
+ while (equiv) {
+ if (!equiv->converter) {
+ if (equiv->type && !equiv->type->clientdata)
+ SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+ }
+ equiv = equiv->next;
+ }
+ }
+ }
+}
+
+#ifdef __cplusplus
+#if 0
+{
+ /* c-mode */
+#endif
+}
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+XS(SWIG_init) {
+ dXSARGS;
+ int i;
+
+ SWIG_InitializeModule(0);
+
+ /* Install commands */
+ for (i = 0; swig_commands[i].name; i++) {
+ newXS((char*) swig_commands[i].name,swig_commands[i].wrapper, (char*)__FILE__);
+ }
+
+ /* Install variables */
+ for (i = 0; swig_variables[i].name; i++) {
+ SV *sv;
+ sv = get_sv((char*) swig_variables[i].name, TRUE | 0x2 | GV_ADDMULTI);
+ if (swig_variables[i].type) {
+ SWIG_MakePtr(sv,(void *)1, *swig_variables[i].type,0);
+ } else {
+ sv_setiv(sv,(IV) 0);
+ }
+ swig_create_magic(sv, (char *) swig_variables[i].name, swig_variables[i].set, swig_variables[i].get);
+ }
+
+ /* Install constant */
+ for (i = 0; swig_constants[i].type; i++) {
+ SV *sv;
+ sv = get_sv((char*)swig_constants[i].name, TRUE | 0x2 | GV_ADDMULTI);
+ switch(swig_constants[i].type) {
+ case SWIG_INT:
+ sv_setiv(sv, (IV) swig_constants[i].lvalue);
+ break;
+ case SWIG_FLOAT:
+ sv_setnv(sv, (double) swig_constants[i].dvalue);
+ break;
+ case SWIG_STRING:
+ sv_setpv(sv, (char *) swig_constants[i].pvalue);
+ break;
+ case SWIG_POINTER:
+ SWIG_MakePtr(sv, swig_constants[i].pvalue, *(swig_constants[i].ptype),0);
+ break;
+ case SWIG_BINARY:
+ SWIG_MakePackedObj(sv, swig_constants[i].pvalue, swig_constants[i].lvalue, *(swig_constants[i].ptype));
+ break;
+ default:
+ break;
+ }
+ SvREADONLY_on(sv);
+ }
+
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "OK", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::OK)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "STATE_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::STATE_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "NULL_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::NULL_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "BOUND_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::BOUND_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "RANGE_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::RANGE_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "CODE_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::CODE_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "RESET_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::RESET_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "SIZE_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::SIZE_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "MEMORY_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::MEMORY_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "IO_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::IO_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "FORMAT_ERROR", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::FORMAT_ERROR)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "MIN_NUM_TRIES", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::MIN_NUM_TRIES)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "MAX_NUM_TRIES", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::MAX_NUM_TRIES)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "DEFAULT_NUM_TRIES", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::DEFAULT_NUM_TRIES)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "HUGE_CACHE", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::HUGE_CACHE)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "LARGE_CACHE", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::LARGE_CACHE)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "NORMAL_CACHE", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::NORMAL_CACHE)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "SMALL_CACHE", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::SMALL_CACHE)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "TINY_CACHE", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::TINY_CACHE)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "DEFAULT_CACHE", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::DEFAULT_CACHE)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "TEXT_TAIL", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::TEXT_TAIL)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "BINARY_TAIL", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::BINARY_TAIL)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "DEFAULT_TAIL", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::DEFAULT_TAIL)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "LABEL_ORDER", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::LABEL_ORDER)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "WEIGHT_ORDER", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::WEIGHT_ORDER)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "DEFAULT_ORDER", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_int SWIG_PERL_CALL_ARGS_1(static_cast< int >(marisa_swig::DEFAULT_ORDER)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Key, (void*) "marisa::Key");
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Query, (void*) "marisa::Query");
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Keyset, (void*) "marisa::Keyset");
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Agent, (void*) "marisa::Agent");
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Trie, (void*) "marisa::Trie");
+ /*@SWIG:/usr/share/swig1.3/perl5/perltypemaps.swg,65,%set_constant@*/ do {
+ SV *sv = get_sv((char*) SWIG_prefix "INVALID_KEY_ID", TRUE | 0x2 | GV_ADDMULTI);
+ sv_setsv(sv, SWIG_From_size_t SWIG_PERL_CALL_ARGS_1(static_cast< size_t >(MARISA_INVALID_KEY_ID)));
+ SvREADONLY_on(sv);
+ } while(0) /*@SWIG@*/;
+ ST(0) = &PL_sv_yes;
+ XSRETURN(1);
+}
+
diff --git a/bindings/perl/marisa.pm b/bindings/perl/marisa.pm
new file mode 100644
index 0000000..434a439
--- /dev/null
+++ b/bindings/perl/marisa.pm
@@ -0,0 +1,297 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 1.3.40
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+package marisa;
+use base qw(Exporter);
+use base qw(DynaLoader);
+package marisac;
+bootstrap marisa;
+package marisa;
+@EXPORT = qw();
+
+# ---------- BASE METHODS -------------
+
+package marisa;
+
+sub TIEHASH {
+ my ($classname,$obj) = @_;
+ return bless $obj, $classname;
+}
+
+sub CLEAR { }
+
+sub FIRSTKEY { }
+
+sub NEXTKEY { }
+
+sub FETCH {
+ my ($self,$field) = @_;
+ my $member_func = "swig_${field}_get";
+ $self->$member_func();
+}
+
+sub STORE {
+ my ($self,$field,$newval) = @_;
+ my $member_func = "swig_${field}_set";
+ $self->$member_func($newval);
+}
+
+sub this {
+ my $ptr = shift;
+ return tied(%$ptr);
+}
+
+
+# ------- FUNCTION WRAPPERS --------
+
+package marisa;
+
+
+############# Class : marisa::Key ##############
+
+package marisa::Key;
+use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
+@ISA = qw( marisa );
+%OWNER = ();
+%ITERATORS = ();
+*str = *marisac::Key_str;
+*id = *marisac::Key_id;
+*weight = *marisac::Key_weight;
+sub DESTROY {
+ return unless $_[0]->isa('HASH');
+ my $self = tied(%{$_[0]});
+ return unless defined $self;
+ delete $ITERATORS{$self};
+ if (exists $OWNER{$self}) {
+ marisac::delete_Key($self);
+ delete $OWNER{$self};
+ }
+}
+
+sub DISOWN {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ delete $OWNER{$ptr};
+}
+
+sub ACQUIRE {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ $OWNER{$ptr} = 1;
+}
+
+
+############# Class : marisa::Query ##############
+
+package marisa::Query;
+use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
+@ISA = qw( marisa );
+%OWNER = ();
+%ITERATORS = ();
+*str = *marisac::Query_str;
+*id = *marisac::Query_id;
+sub DESTROY {
+ return unless $_[0]->isa('HASH');
+ my $self = tied(%{$_[0]});
+ return unless defined $self;
+ delete $ITERATORS{$self};
+ if (exists $OWNER{$self}) {
+ marisac::delete_Query($self);
+ delete $OWNER{$self};
+ }
+}
+
+sub DISOWN {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ delete $OWNER{$ptr};
+}
+
+sub ACQUIRE {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ $OWNER{$ptr} = 1;
+}
+
+
+############# Class : marisa::Keyset ##############
+
+package marisa::Keyset;
+use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
+@ISA = qw( marisa );
+%OWNER = ();
+%ITERATORS = ();
+sub new {
+ my $pkg = shift;
+ my $self = marisac::new_Keyset(@_);
+ bless $self, $pkg if defined($self);
+}
+
+sub DESTROY {
+ return unless $_[0]->isa('HASH');
+ my $self = tied(%{$_[0]});
+ return unless defined $self;
+ delete $ITERATORS{$self};
+ if (exists $OWNER{$self}) {
+ marisac::delete_Keyset($self);
+ delete $OWNER{$self};
+ }
+}
+
+*push_back = *marisac::Keyset_push_back;
+*key = *marisac::Keyset_key;
+*key_str = *marisac::Keyset_key_str;
+*key_id = *marisac::Keyset_key_id;
+*num_keys = *marisac::Keyset_num_keys;
+*empty = *marisac::Keyset_empty;
+*size = *marisac::Keyset_size;
+*total_length = *marisac::Keyset_total_length;
+*reset = *marisac::Keyset_reset;
+*clear = *marisac::Keyset_clear;
+sub DISOWN {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ delete $OWNER{$ptr};
+}
+
+sub ACQUIRE {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ $OWNER{$ptr} = 1;
+}
+
+
+############# Class : marisa::Agent ##############
+
+package marisa::Agent;
+use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
+@ISA = qw( marisa );
+%OWNER = ();
+%ITERATORS = ();
+sub new {
+ my $pkg = shift;
+ my $self = marisac::new_Agent(@_);
+ bless $self, $pkg if defined($self);
+}
+
+sub DESTROY {
+ return unless $_[0]->isa('HASH');
+ my $self = tied(%{$_[0]});
+ return unless defined $self;
+ delete $ITERATORS{$self};
+ if (exists $OWNER{$self}) {
+ marisac::delete_Agent($self);
+ delete $OWNER{$self};
+ }
+}
+
+*set_query = *marisac::Agent_set_query;
+*key = *marisac::Agent_key;
+*query = *marisac::Agent_query;
+*key_str = *marisac::Agent_key_str;
+*key_id = *marisac::Agent_key_id;
+*query_str = *marisac::Agent_query_str;
+*query_id = *marisac::Agent_query_id;
+sub DISOWN {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ delete $OWNER{$ptr};
+}
+
+sub ACQUIRE {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ $OWNER{$ptr} = 1;
+}
+
+
+############# Class : marisa::Trie ##############
+
+package marisa::Trie;
+use vars qw(@ISA %OWNER %ITERATORS %BLESSEDMEMBERS);
+@ISA = qw( marisa );
+%OWNER = ();
+%ITERATORS = ();
+sub new {
+ my $pkg = shift;
+ my $self = marisac::new_Trie(@_);
+ bless $self, $pkg if defined($self);
+}
+
+sub DESTROY {
+ return unless $_[0]->isa('HASH');
+ my $self = tied(%{$_[0]});
+ return unless defined $self;
+ delete $ITERATORS{$self};
+ if (exists $OWNER{$self}) {
+ marisac::delete_Trie($self);
+ delete $OWNER{$self};
+ }
+}
+
+*build = *marisac::Trie_build;
+*mmap = *marisac::Trie_mmap;
+*load = *marisac::Trie_load;
+*save = *marisac::Trie_save;
+*common_prefix_search = *marisac::Trie_common_prefix_search;
+*predictive_search = *marisac::Trie_predictive_search;
+*lookup = *marisac::Trie_lookup;
+*reverse_lookup = *marisac::Trie_reverse_lookup;
+*num_tries = *marisac::Trie_num_tries;
+*num_keys = *marisac::Trie_num_keys;
+*num_nodes = *marisac::Trie_num_nodes;
+*tail_mode = *marisac::Trie_tail_mode;
+*node_order = *marisac::Trie_node_order;
+*empty = *marisac::Trie_empty;
+*size = *marisac::Trie_size;
+*total_size = *marisac::Trie_total_size;
+*io_size = *marisac::Trie_io_size;
+*clear = *marisac::Trie_clear;
+sub DISOWN {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ delete $OWNER{$ptr};
+}
+
+sub ACQUIRE {
+ my $self = shift;
+ my $ptr = tied(%$self);
+ $OWNER{$ptr} = 1;
+}
+
+
+# ------- VARIABLE STUBS --------
+
+package marisa;
+
+*OK = *marisac::OK;
+*STATE_ERROR = *marisac::STATE_ERROR;
+*NULL_ERROR = *marisac::NULL_ERROR;
+*BOUND_ERROR = *marisac::BOUND_ERROR;
+*RANGE_ERROR = *marisac::RANGE_ERROR;
+*CODE_ERROR = *marisac::CODE_ERROR;
+*RESET_ERROR = *marisac::RESET_ERROR;
+*SIZE_ERROR = *marisac::SIZE_ERROR;
+*MEMORY_ERROR = *marisac::MEMORY_ERROR;
+*IO_ERROR = *marisac::IO_ERROR;
+*FORMAT_ERROR = *marisac::FORMAT_ERROR;
+*MIN_NUM_TRIES = *marisac::MIN_NUM_TRIES;
+*MAX_NUM_TRIES = *marisac::MAX_NUM_TRIES;
+*DEFAULT_NUM_TRIES = *marisac::DEFAULT_NUM_TRIES;
+*HUGE_CACHE = *marisac::HUGE_CACHE;
+*LARGE_CACHE = *marisac::LARGE_CACHE;
+*NORMAL_CACHE = *marisac::NORMAL_CACHE;
+*SMALL_CACHE = *marisac::SMALL_CACHE;
+*TINY_CACHE = *marisac::TINY_CACHE;
+*DEFAULT_CACHE = *marisac::DEFAULT_CACHE;
+*TEXT_TAIL = *marisac::TEXT_TAIL;
+*BINARY_TAIL = *marisac::BINARY_TAIL;
+*DEFAULT_TAIL = *marisac::DEFAULT_TAIL;
+*LABEL_ORDER = *marisac::LABEL_ORDER;
+*WEIGHT_ORDER = *marisac::WEIGHT_ORDER;
+*DEFAULT_ORDER = *marisac::DEFAULT_ORDER;
+*INVALID_KEY_ID = *marisac::INVALID_KEY_ID;
+1;
diff --git a/bindings/perl/sample.pl b/bindings/perl/sample.pl
new file mode 100644
index 0000000..520f5fc
--- /dev/null
+++ b/bindings/perl/sample.pl
@@ -0,0 +1,62 @@
+use marisa;
+
+$keyset = new marisa::Keyset;
+$keyset->push_back("cake");
+$keyset->push_back("cookie");
+$keyset->push_back("ice");
+$keyset->push_back("ice-cream");
+
+$trie = new marisa::Trie;
+$trie->build($keyset);
+print("no. keys: ", $trie->num_keys(), "\n");
+print("no. tries: ", $trie->num_tries(), "\n");
+print("no. nodes: ", $trie->num_nodes(), "\n");
+print("size: ", $trie->io_size(), "\n");
+
+$agent = new marisa::Agent;
+
+$agent->set_query("cake");
+$trie->lookup($agent);
+print($agent->query_str(), ": ", $agent->key_id(), "\n");
+
+$agent->set_query("cookie");
+$trie->lookup($agent);
+print($agent->query_str(), ": ", $agent->key_id(), "\n");
+
+$agent->set_query("cockoo");
+if ($trie->lookup(agent)) {
+ print($agent->query_str(), ": not found\n");
+}
+
+print("ice: ", $trie->lookup("ice"), "\n");
+print("ice-cream: ", $trie->lookup("ice-cream"), "\n");
+if ($trie->lookup("ice-age") == $marisa::INVALID_KEY_ID) {
+ print("ice-age: not found\n");
+}
+
+$trie->save("sample.dic");
+$trie->load("sample.dic");
+
+$agent->set_query(0);
+$trie->reverse_lookup($agent);
+print($agent->query_id(), ": ", $agent->key_str(), "\n");
+$agent->set_query(1);
+$trie->reverse_lookup($agent);
+print($agent->query_id(), ": ", $agent->key_str(), "\n");
+
+print("2: ", $trie->reverse_lookup(2), "\n");
+print("3: ", $trie->reverse_lookup(3), "\n");
+
+$trie->mmap("sample.dic");
+
+$agent->set_query("ice-cream soda");
+while ($trie->common_prefix_search($agent)) {
+ print($agent->query_str(), ": ", $agent->key_str(), " (",
+ $agent->key_id(), ")\n");
+}
+
+$agent->set_query("ic");
+while ($trie->predictive_search($agent)) {
+ print($agent->query_str(), ": ", $agent->key_str(), " (",
+ $agent->key_id(), ")\n");
+}
diff --git a/bindings/python/benchmark.py b/bindings/python/benchmark.py
new file mode 100644
index 0000000..3ccdf54
--- /dev/null
+++ b/bindings/python/benchmark.py
@@ -0,0 +1,81 @@
+import datetime
+import marisa
+import sys
+
+time_begin = datetime.datetime.now()
+keys = []
+for line in sys.stdin:
+ keys.append(line.rstrip())
+time_end = datetime.datetime.now()
+print "input:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+dic = dict()
+for i in range(len(keys)):
+ dic[keys[i]] = i
+time_end = datetime.datetime.now()
+print "dict_build:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+for key in keys:
+ dic.get(key)
+time_end = datetime.datetime.now()
+print "dict_lookup:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+keyset = marisa.Keyset()
+for key in keys:
+ keyset.push_back(key)
+time_end = datetime.datetime.now()
+print "keyset_build:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+trie = marisa.Trie()
+trie.build(keyset)
+time_end = datetime.datetime.now()
+print "trie_build:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+agent = marisa.Agent()
+for key in keys:
+ agent.set_query(key)
+ trie.lookup(agent)
+ agent.key_id()
+time_end = datetime.datetime.now()
+print "trie_agent_lookup:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+for key in keys:
+ trie.lookup(key)
+time_end = datetime.datetime.now()
+print "trie_lookup:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+for i in range(len(keys)):
+ agent.set_query(i)
+ trie.reverse_lookup(agent)
+ agent.key_str()
+time_end = datetime.datetime.now()
+print "trie_agent_reverse_lookup:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+for i in range(len(keys)):
+ trie.reverse_lookup(i)
+time_end = datetime.datetime.now()
+print "trie_reverse_lookup:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+for key in keys:
+ agent.set_query(key)
+ while trie.common_prefix_search(agent):
+ agent.key_str()
+time_end = datetime.datetime.now()
+print "trie_agent_common_prefix_search:", time_end - time_begin
+
+time_begin = datetime.datetime.now()
+for key in keys:
+ agent.set_query(key)
+ while trie.predictive_search(agent):
+ agent.key_str()
+time_end = datetime.datetime.now()
+print "trie_agent_predictive_search:", time_end - time_begin
diff --git a/bindings/python/marisa-swig.cxx b/bindings/python/marisa-swig.cxx
new file mode 100644
index 0000000..281ccb2
--- /dev/null
+++ b/bindings/python/marisa-swig.cxx
@@ -0,0 +1,253 @@
+#include <cstring>
+#include <new>
+
+#include "marisa-swig.h"
+
+namespace marisa_swig {
+
+void Key::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = key_.ptr();
+ *length_out = key_.length();
+}
+
+size_t Key::id() const {
+ return key_.id();
+}
+
+float Key::weight() const {
+ return key_.weight();
+}
+
+void Query::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = query_.ptr();
+ *length_out = query_.length();
+}
+
+size_t Query::id() const {
+ return query_.id();
+}
+
+Keyset::Keyset() : keyset_(new (std::nothrow) marisa::Keyset) {
+ MARISA_THROW_IF(keyset_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Keyset::~Keyset() {
+ delete keyset_;
+}
+
+void Keyset::push_back(const marisa::Key &key) {
+ keyset_->push_back(key);
+}
+
+void Keyset::push_back(const char *ptr, size_t length, float weight) {
+ keyset_->push_back(ptr, length, weight);
+}
+
+const Key &Keyset::key(size_t i) const {
+ return reinterpret_cast<const Key &>((*keyset_)[i]);
+}
+
+void Keyset::key_str(size_t i,
+ const char **ptr_out, size_t *length_out) const {
+ *ptr_out = (*keyset_)[i].ptr();
+ *length_out = (*keyset_)[i].length();
+}
+
+size_t Keyset::key_id(size_t i) const {
+ return (*keyset_)[i].id();
+}
+
+size_t Keyset::num_keys() const {
+ return keyset_->num_keys();
+}
+
+bool Keyset::empty() const {
+ return keyset_->empty();
+}
+
+size_t Keyset::size() const {
+ return keyset_->size();
+}
+
+size_t Keyset::total_length() const {
+ return keyset_->total_length();
+}
+
+void Keyset::reset() {
+ keyset_->reset();
+}
+
+void Keyset::clear() {
+ keyset_->clear();
+}
+
+Agent::Agent()
+ : agent_(new (std::nothrow) marisa::Agent), buf_(NULL), buf_size_(0) {
+ MARISA_THROW_IF(agent_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Agent::~Agent() {
+ delete agent_;
+ delete [] buf_;
+}
+
+void Agent::set_query(const char *ptr, size_t length) {
+ if (length > buf_size_) {
+ size_t new_buf_size = (buf_size_ != 0) ? buf_size_ : 1;
+ if (length >= (MARISA_SIZE_MAX / 2)) {
+ new_buf_size = MARISA_SIZE_MAX;
+ } else {
+ while (new_buf_size < length) {
+ new_buf_size *= 2;
+ }
+ }
+ char *new_buf = new (std::nothrow) char[new_buf_size];
+ MARISA_THROW_IF(new_buf == NULL, MARISA_MEMORY_ERROR);
+ delete [] buf_;
+ buf_ = new_buf;
+ buf_size_ = new_buf_size;
+ }
+ std::memcpy(buf_, ptr, length);
+ agent_->set_query(buf_, length);
+}
+
+void Agent::set_query(size_t id) {
+ agent_->set_query(id);
+}
+
+const Key &Agent::key() const {
+ return reinterpret_cast<const Key &>(agent_->key());
+}
+
+const Query &Agent::query() const {
+ return reinterpret_cast<const Query &>(agent_->query());
+}
+
+void Agent::key_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->key().ptr();
+ *length_out = agent_->key().length();
+}
+
+size_t Agent::key_id() const {
+ return agent_->key().id();
+}
+
+void Agent::query_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->query().ptr();
+ *length_out = agent_->query().length();
+}
+
+size_t Agent::query_id() const {
+ return agent_->query().id();
+}
+
+Trie::Trie() : trie_(new (std::nothrow) marisa::Trie) {
+ MARISA_THROW_IF(trie_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Trie::~Trie() {
+ delete trie_;
+}
+
+void Trie::build(Keyset &keyset, int config_flags) {
+ trie_->build(*keyset.keyset_, config_flags);
+}
+
+void Trie::mmap(const char *filename) {
+ trie_->mmap(filename);
+}
+
+void Trie::load(const char *filename) {
+ trie_->load(filename);
+}
+
+void Trie::save(const char *filename) const {
+ trie_->save(filename);
+}
+
+bool Trie::lookup(Agent &agent) const {
+ return trie_->lookup(*agent.agent_);
+}
+
+void Trie::reverse_lookup(Agent &agent) const {
+ trie_->reverse_lookup(*agent.agent_);
+}
+
+bool Trie::common_prefix_search(Agent &agent) const {
+ return trie_->common_prefix_search(*agent.agent_);
+}
+
+bool Trie::predictive_search(Agent &agent) const {
+ return trie_->predictive_search(*agent.agent_);
+}
+
+size_t Trie::lookup(const char *ptr, size_t length) const {
+ marisa::Agent agent;
+ agent.set_query(ptr, length);
+ if (!trie_->lookup(agent)) {
+ return MARISA_INVALID_KEY_ID;
+ }
+ return agent.key().id();
+}
+
+void Trie::reverse_lookup(size_t id,
+ const char **ptr_out_to_be_deleted, size_t *length_out) const {
+ marisa::Agent agent;
+ agent.set_query(id);
+ trie_->reverse_lookup(agent);
+ char * const buf = new (std::nothrow) char[agent.key().length()];
+ MARISA_THROW_IF(buf == NULL, MARISA_MEMORY_ERROR);
+ std::memcpy(buf, agent.key().ptr(), agent.key().length());
+ *ptr_out_to_be_deleted = buf;
+ *length_out = agent.key().length();
+}
+
+size_t Trie::num_tries() const {
+ return trie_->num_tries();
+}
+
+size_t Trie::num_keys() const {
+ return trie_->num_keys();
+}
+
+size_t Trie::num_nodes() const {
+ return trie_->num_nodes();
+}
+
+TailMode Trie::tail_mode() const {
+ if (trie_->tail_mode() == ::MARISA_TEXT_TAIL) {
+ return TEXT_TAIL;
+ } else {
+ return BINARY_TAIL;
+ }
+}
+
+NodeOrder Trie::node_order() const {
+ if (trie_->node_order() == ::MARISA_LABEL_ORDER) {
+ return LABEL_ORDER;
+ } else {
+ return WEIGHT_ORDER;
+ }
+}
+
+bool Trie::empty() const {
+ return trie_->empty();
+}
+
+size_t Trie::size() const {
+ return trie_->size();
+}
+
+size_t Trie::total_size() const {
+ return trie_->total_size();
+}
+
+size_t Trie::io_size() const {
+ return trie_->io_size();
+}
+
+void Trie::clear() {
+ trie_->clear();
+}
+
+} // namespace marisa_swig
diff --git a/bindings/python/marisa-swig.h b/bindings/python/marisa-swig.h
new file mode 100644
index 0000000..f09a9a7
--- /dev/null
+++ b/bindings/python/marisa-swig.h
@@ -0,0 +1,183 @@
+#ifndef MARISA_SWIG_H_
+#define MARISA_SWIG_H_
+
+#include <marisa.h>
+
+namespace marisa_swig {
+
+#define MARISA_SWIG_ENUM_COPY(name) name = MARISA_ ## name
+
+enum ErrorCode {
+ MARISA_SWIG_ENUM_COPY(OK),
+ MARISA_SWIG_ENUM_COPY(STATE_ERROR),
+ MARISA_SWIG_ENUM_COPY(NULL_ERROR),
+ MARISA_SWIG_ENUM_COPY(BOUND_ERROR),
+ MARISA_SWIG_ENUM_COPY(RANGE_ERROR),
+ MARISA_SWIG_ENUM_COPY(CODE_ERROR),
+ MARISA_SWIG_ENUM_COPY(RESET_ERROR),
+ MARISA_SWIG_ENUM_COPY(SIZE_ERROR),
+ MARISA_SWIG_ENUM_COPY(MEMORY_ERROR),
+ MARISA_SWIG_ENUM_COPY(IO_ERROR),
+ MARISA_SWIG_ENUM_COPY(FORMAT_ERROR)
+};
+
+enum NumTries {
+ MARISA_SWIG_ENUM_COPY(MIN_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(MAX_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_NUM_TRIES)
+};
+
+enum CacheLevel {
+ MARISA_SWIG_ENUM_COPY(HUGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(LARGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(NORMAL_CACHE),
+ MARISA_SWIG_ENUM_COPY(SMALL_CACHE),
+ MARISA_SWIG_ENUM_COPY(TINY_CACHE),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_CACHE)
+};
+
+enum TailMode {
+ MARISA_SWIG_ENUM_COPY(TEXT_TAIL),
+ MARISA_SWIG_ENUM_COPY(BINARY_TAIL),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_TAIL)
+};
+
+enum NodeOrder {
+ MARISA_SWIG_ENUM_COPY(LABEL_ORDER),
+ MARISA_SWIG_ENUM_COPY(WEIGHT_ORDER),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_ORDER)
+};
+
+#undef MARISA_SWIG_ENUM_COPY
+
+class Key {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+ float weight() const;
+
+ private:
+ const marisa::Key key_;
+
+ Key();
+ Key(const Key &key);
+ Key &operator=(const Key &);
+};
+
+class Query {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+
+ private:
+ const marisa::Query query_;
+
+ Query();
+ Query(const Query &query);
+ Query &operator=(const Query &);
+};
+
+class Keyset {
+ friend class Trie;
+
+ public:
+ Keyset();
+ ~Keyset();
+
+ void push_back(const marisa::Key &key);
+ void push_back(const char *ptr, std::size_t length, float weight = 1.0);
+
+ const Key &key(std::size_t i) const;
+
+ void key_str(std::size_t i,
+ const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id(std::size_t i) const;
+
+ std::size_t num_keys() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_length() const;
+
+ void reset();
+ void clear();
+
+ private:
+ marisa::Keyset *keyset_;
+
+ Keyset(const Keyset &);
+ Keyset &operator=(const Keyset &);
+};
+
+class Agent {
+ friend class Trie;
+
+ public:
+ Agent();
+ ~Agent();
+
+ void set_query(const char *ptr, std::size_t length);
+ void set_query(std::size_t id);
+
+ const Key &key() const;
+ const Query &query() const;
+
+ void key_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id() const;
+
+ void query_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t query_id() const;
+
+ private:
+ marisa::Agent *agent_;
+ char *buf_;
+ std::size_t buf_size_;
+
+ Agent(const Agent &);
+ Agent &operator=(const Agent &);
+};
+
+class Trie {
+ public:
+ Trie();
+ ~Trie();
+
+ void build(Keyset &keyset, int config_flags = 0);
+
+ void mmap(const char *filename);
+ void load(const char *filename);
+ void save(const char *filename) const;
+
+ bool lookup(Agent &agent) const;
+ void reverse_lookup(Agent &agent) const;
+ bool common_prefix_search(Agent &agent) const;
+ bool predictive_search(Agent &agent) const;
+
+ std::size_t lookup(const char *ptr, std::size_t length) const;
+ void reverse_lookup(std::size_t id,
+ const char **ptr_out_to_be_deleted, std::size_t *length_out) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_size() const;
+ std::size_t io_size() const;
+
+ void clear();
+
+ private:
+ marisa::Trie *trie_;
+
+ Trie(const Trie &);
+ Trie &operator=(const Trie &);
+};
+
+} // namespace marisa_swig
+
+#endif // MARISA_SWIG_H_
diff --git a/bindings/python/marisa-swig_wrap.cxx b/bindings/python/marisa-swig_wrap.cxx
new file mode 100644
index 0000000..6186fb8
--- /dev/null
+++ b/bindings/python/marisa-swig_wrap.cxx
@@ -0,0 +1,6090 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.40
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGPYTHON
+#define SWIG_PYTHON_DIRECTOR_NO_VTABLE
+
+
+#ifdef __cplusplus
+/* SwigValueWrapper is described in swig.swg */
+template<typename T> class SwigValueWrapper {
+ struct SwigMovePointer {
+ T *ptr;
+ SwigMovePointer(T *p) : ptr(p) { }
+ ~SwigMovePointer() { delete ptr; }
+ SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+ } pointer;
+ SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
+ SwigValueWrapper(const SwigValueWrapper<T>& rhs);
+public:
+ SwigValueWrapper() : pointer(0) { }
+ SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+ operator T&() const { return *pointer.ptr; }
+ T *operator&() { return pointer.ptr; }
+};
+
+template <typename T> T SwigValueInit() {
+ return T();
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+# pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+
+/* Python.h has to appear first */
+#include <Python.h>
+
+/* -----------------------------------------------------------------------------
+ * swigrun.swg
+ *
+ * This file contains generic C API SWIG runtime support for pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+ or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "4"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+ You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+ creating a static or dynamic library from the SWIG runtime code.
+ In 99.9% of the cases, SWIG just needs to declare them as 'static'.
+
+ But only do this if strictly necessary, ie, if you have problems
+ with your compiler or suchlike.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+/* Generic buffer size */
+#ifndef SWIG_BUFFER_SIZE
+# define SWIG_BUFFER_SIZE 1024
+#endif
+
+/* Flags for pointer conversions */
+#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_OWN 0x1
+
+
+/*
+ Flags/methods for returning states.
+
+ The SWIG conversion methods, as ConvertPtr, return and integer
+ that tells if the conversion was successful or not. And if not,
+ an error code can be returned (see swigerrors.swg for the codes).
+
+ Use the following macros/flags to set or process the returning
+ states.
+
+ In old versions of SWIG, code such as the following was usually written:
+
+ if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
+ // success code
+ } else {
+ //fail code
+ }
+
+ Now you can be more explicit:
+
+ int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ } else {
+ // fail code
+ }
+
+ which is the same really, but now you can also do
+
+ Type *ptr;
+ int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ if (SWIG_IsNewObj(res) {
+ ...
+ delete *ptr;
+ } else {
+ ...
+ }
+ } else {
+ // fail code
+ }
+
+ I.e., now SWIG_ConvertPtr can return new objects and you can
+ identify the case and take care of the deallocation. Of course that
+ also requires SWIG_ConvertPtr to return new result values, such as
+
+ int SWIG_ConvertPtr(obj, ptr,...) {
+ if (<obj is ok>) {
+ if (<need new object>) {
+ *ptr = <ptr to new allocated object>;
+ return SWIG_NEWOBJ;
+ } else {
+ *ptr = <ptr to old object>;
+ return SWIG_OLDOBJ;
+ }
+ } else {
+ return SWIG_BADOBJ;
+ }
+ }
+
+ Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
+ more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
+ SWIG errors code.
+
+ Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
+ allows to return the 'cast rank', for example, if you have this
+
+ int food(double)
+ int fooi(int);
+
+ and you call
+
+ food(1) // cast rank '1' (1 -> 1.0)
+ fooi(1) // cast rank '0'
+
+ just use the SWIG_AddCast()/SWIG_CheckState()
+*/
+
+#define SWIG_OK (0)
+#define SWIG_ERROR (-1)
+#define SWIG_IsOK(r) (r >= 0)
+#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
+
+/* The CastRankLimit says how many bits are used for the cast rank */
+#define SWIG_CASTRANKLIMIT (1 << 8)
+/* The NewMask denotes the object was created (using new/malloc) */
+#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
+/* The TmpMask is for in/out typemaps that use temporal objects */
+#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
+/* Simple returning values */
+#define SWIG_BADOBJ (SWIG_ERROR)
+#define SWIG_OLDOBJ (SWIG_OK)
+#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
+#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
+/* Check, add and del mask methods */
+#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
+#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
+#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
+#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
+#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
+#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
+
+/* Cast-Rank Mode */
+#if defined(SWIG_CASTRANK_MODE)
+# ifndef SWIG_TypeRank
+# define SWIG_TypeRank unsigned long
+# endif
+# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
+# define SWIG_MAXCASTRANK (2)
+# endif
+# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
+# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
+ return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
+}
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+ return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
+}
+#else /* no cast-rank mode */
+# define SWIG_AddCast
+# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
+#endif
+
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *, int *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store information on one type */
+typedef struct swig_type_info {
+ const char *name; /* mangled name of this type */
+ const char *str; /* human readable name of this type */
+ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
+ struct swig_cast_info *cast; /* linked list of types that can cast into this type */
+ void *clientdata; /* language specific type data */
+ int owndata; /* flag if the structure owns the clientdata */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+ swig_type_info *type; /* pointer to type that is equivalent to this type */
+ swig_converter_func converter; /* function to cast the void pointers */
+ struct swig_cast_info *next; /* pointer to next cast in linked list */
+ struct swig_cast_info *prev; /* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+ swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
+ size_t size; /* Number of types in this module */
+ struct swig_module_info *next; /* Pointer to next element in circularly linked list */
+ swig_type_info **type_initial; /* Array of initially generated type structures */
+ swig_cast_info **cast_initial; /* Array of initially generated casting structures */
+ void *clientdata; /* Language specific module data */
+} swig_module_info;
+
+/*
+ Compare two type names skipping the space characters, therefore
+ "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+ Return 0 when the two name types are equivalent, as in
+ strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+ const char *f2, const char *l2) {
+ for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+ while ((*f1 == ' ') && (f1 != l1)) ++f1;
+ while ((*f2 == ' ') && (f2 != l2)) ++f2;
+ if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
+ }
+ return (int)((l1 - f1) - (l2 - f2));
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCompare(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+
+/*
+ Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (strcmp(iter->type->name, c) == 0) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (iter->type == from) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
+}
+
+/*
+ Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+ swig_type_info *lastty = ty;
+ if (!ty || !ty->dcast) return ty;
+ while (ty && (ty->dcast)) {
+ ty = (*ty->dcast)(ptr);
+ if (ty) lastty = ty;
+ }
+ return lastty;
+}
+
+/*
+ Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+ return ty->name;
+}
+
+/*
+ Return the pretty name associated with this type,
+ that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+ /* The "str" field contains the equivalent pretty names of the
+ type, separated by vertical-bar characters. We choose
+ to print the last name, as it is often (?) the most
+ specific. */
+ if (!type) return NULL;
+ if (type->str != NULL) {
+ const char *last_name = type->str;
+ const char *s;
+ for (s = type->str; *s; s++)
+ if (*s == '|') last_name = s+1;
+ return last_name;
+ }
+ else
+ return type->name;
+}
+
+/*
+ Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+ swig_cast_info *cast = ti->cast;
+ /* if (ti->clientdata == clientdata) return; */
+ ti->clientdata = clientdata;
+
+ while (cast) {
+ if (!cast->converter) {
+ swig_type_info *tc = cast->type;
+ if (!tc->clientdata) {
+ SWIG_TypeClientData(tc, clientdata);
+ }
+ }
+ cast = cast->next;
+ }
+}
+SWIGRUNTIME void
+SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
+ SWIG_TypeClientData(ti, clientdata);
+ ti->owndata = 1;
+}
+
+/*
+ Search for a swig_type_info structure only by mangled name
+ Search is a O(log #types)
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ swig_module_info *iter = start;
+ do {
+ if (iter->size) {
+ register size_t l = 0;
+ register size_t r = iter->size - 1;
+ do {
+ /* since l+r >= 0, we can (>> 1) instead (/ 2) */
+ register size_t i = (l + r) >> 1;
+ const char *iname = iter->types[i]->name;
+ if (iname) {
+ register int compare = strcmp(name, iname);
+ if (compare == 0) {
+ return iter->types[i];
+ } else if (compare < 0) {
+ if (i) {
+ r = i - 1;
+ } else {
+ break;
+ }
+ } else if (compare > 0) {
+ l = i + 1;
+ }
+ } else {
+ break; /* should never happen */
+ }
+ } while (l <= r);
+ }
+ iter = iter->next;
+ } while (iter != end);
+ return 0;
+}
+
+/*
+ Search for a swig_type_info structure for either a mangled name or a human readable name.
+ It first searches the mangled names of the types, which is a O(log #types)
+ If a type is not found it then searches the human readable names, which is O(#types).
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ /* STEP 1: Search the name field using binary search */
+ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+ if (ret) {
+ return ret;
+ } else {
+ /* STEP 2: If the type hasn't been found, do a complete search
+ of the str field (the human readable name) */
+ swig_module_info *iter = start;
+ do {
+ register size_t i = 0;
+ for (; i < iter->size; ++i) {
+ if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+ return iter->types[i];
+ }
+ iter = iter->next;
+ } while (iter != end);
+ }
+
+ /* neither found a match */
+ return 0;
+}
+
+/*
+ Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+ static const char hex[17] = "0123456789abcdef";
+ register const unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register unsigned char uu = *u;
+ *(c++) = hex[(uu & 0xf0) >> 4];
+ *(c++) = hex[uu & 0xf];
+ }
+ return c;
+}
+
+/*
+ Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+ register unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register char d = *(c++);
+ register unsigned char uu;
+ if ((d >= '0') && (d <= '9'))
+ uu = ((d - '0') << 4);
+ else if ((d >= 'a') && (d <= 'f'))
+ uu = ((d - ('a'-10)) << 4);
+ else
+ return (char *) 0;
+ d = *(c++);
+ if ((d >= '0') && (d <= '9'))
+ uu |= (d - '0');
+ else if ((d >= 'a') && (d <= 'f'))
+ uu |= (d - ('a'-10));
+ else
+ return (char *) 0;
+ *u = uu;
+ }
+ return c;
+}
+
+/*
+ Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+ char *r = buff;
+ if ((2*sizeof(void *) + 2) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,&ptr,sizeof(void *));
+ if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+ strcpy(r,name);
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ *ptr = (void *) 0;
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+ char *r = buff;
+ size_t lname = (name ? strlen(name) : 0);
+ if ((2*sz + 2 + lname) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ if (lname) {
+ strncpy(r,name,lname+1);
+ } else {
+ *r = 0;
+ }
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ memset(ptr,0,sz);
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Errors in SWIG */
+#define SWIG_UnknownError -1
+#define SWIG_IOError -2
+#define SWIG_RuntimeError -3
+#define SWIG_IndexError -4
+#define SWIG_TypeError -5
+#define SWIG_DivisionByZero -6
+#define SWIG_OverflowError -7
+#define SWIG_SyntaxError -8
+#define SWIG_ValueError -9
+#define SWIG_SystemError -10
+#define SWIG_AttributeError -11
+#define SWIG_MemoryError -12
+#define SWIG_NullReferenceError -13
+
+
+
+/* Compatibility macros for Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+
+#define PyClass_Check(obj) PyObject_IsInstance(obj, (PyObject *)&PyType_Type)
+#define PyInt_Check(x) PyLong_Check(x)
+#define PyInt_AsLong(x) PyLong_AsLong(x)
+#define PyInt_FromLong(x) PyLong_FromLong(x)
+#define PyString_Format(fmt, args) PyUnicode_Format(fmt, args)
+
+#endif
+
+#ifndef Py_TYPE
+# define Py_TYPE(op) ((op)->ob_type)
+#endif
+
+/* SWIG APIs for compatibility of both Python 2 & 3 */
+
+#if PY_VERSION_HEX >= 0x03000000
+# define SWIG_Python_str_FromFormat PyUnicode_FromFormat
+#else
+# define SWIG_Python_str_FromFormat PyString_FromFormat
+#endif
+
+
+/* Warning: This function will allocate a new string in Python 3,
+ * so please call SWIG_Python_str_DelForPy3(x) to free the space.
+ */
+SWIGINTERN char*
+SWIG_Python_str_AsChar(PyObject *str)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ char *cstr;
+ char *newstr;
+ Py_ssize_t len;
+ str = PyUnicode_AsUTF8String(str);
+ PyBytes_AsStringAndSize(str, &cstr, &len);
+ newstr = (char *) malloc(len+1);
+ memcpy(newstr, cstr, len+1);
+ Py_XDECREF(str);
+ return newstr;
+#else
+ return PyString_AsString(str);
+#endif
+}
+
+#if PY_VERSION_HEX >= 0x03000000
+# define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
+#else
+# define SWIG_Python_str_DelForPy3(x)
+#endif
+
+
+SWIGINTERN PyObject*
+SWIG_Python_str_FromChar(const char *c)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_FromString(c);
+#else
+ return PyString_FromString(c);
+#endif
+}
+
+/* Add PyOS_snprintf for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM)
+# define PyOS_snprintf _snprintf
+# else
+# define PyOS_snprintf snprintf
+# endif
+#endif
+
+/* A crude PyString_FromFormat implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+
+#ifndef SWIG_PYBUFFER_SIZE
+# define SWIG_PYBUFFER_SIZE 1024
+#endif
+
+static PyObject *
+PyString_FromFormat(const char *fmt, ...) {
+ va_list ap;
+ char buf[SWIG_PYBUFFER_SIZE * 2];
+ int res;
+ va_start(ap, fmt);
+ res = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+ return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf);
+}
+#endif
+
+/* Add PyObject_Del for old Pythons */
+#if PY_VERSION_HEX < 0x01060000
+# define PyObject_Del(op) PyMem_DEL((op))
+#endif
+#ifndef PyObject_DEL
+# define PyObject_DEL PyObject_Del
+#endif
+
+/* A crude PyExc_StopIteration exception for old Pythons */
+#if PY_VERSION_HEX < 0x02020000
+# ifndef PyExc_StopIteration
+# define PyExc_StopIteration PyExc_RuntimeError
+# endif
+# ifndef PyObject_GenericGetAttr
+# define PyObject_GenericGetAttr 0
+# endif
+#endif
+
+/* Py_NotImplemented is defined in 2.1 and up. */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef Py_NotImplemented
+# define Py_NotImplemented PyExc_RuntimeError
+# endif
+#endif
+
+/* A crude PyString_AsStringAndSize implementation for old Pythons */
+#if PY_VERSION_HEX < 0x02010000
+# ifndef PyString_AsStringAndSize
+# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;}
+# endif
+#endif
+
+/* PySequence_Size for old Pythons */
+#if PY_VERSION_HEX < 0x02000000
+# ifndef PySequence_Size
+# define PySequence_Size PySequence_Length
+# endif
+#endif
+
+/* PyBool_FromLong for old Pythons */
+#if PY_VERSION_HEX < 0x02030000
+static
+PyObject *PyBool_FromLong(long ok)
+{
+ PyObject *result = ok ? Py_True : Py_False;
+ Py_INCREF(result);
+ return result;
+}
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+/* -----------------------------------------------------------------------------
+ * error manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIME PyObject*
+SWIG_Python_ErrorType(int code) {
+ PyObject* type = 0;
+ switch(code) {
+ case SWIG_MemoryError:
+ type = PyExc_MemoryError;
+ break;
+ case SWIG_IOError:
+ type = PyExc_IOError;
+ break;
+ case SWIG_RuntimeError:
+ type = PyExc_RuntimeError;
+ break;
+ case SWIG_IndexError:
+ type = PyExc_IndexError;
+ break;
+ case SWIG_TypeError:
+ type = PyExc_TypeError;
+ break;
+ case SWIG_DivisionByZero:
+ type = PyExc_ZeroDivisionError;
+ break;
+ case SWIG_OverflowError:
+ type = PyExc_OverflowError;
+ break;
+ case SWIG_SyntaxError:
+ type = PyExc_SyntaxError;
+ break;
+ case SWIG_ValueError:
+ type = PyExc_ValueError;
+ break;
+ case SWIG_SystemError:
+ type = PyExc_SystemError;
+ break;
+ case SWIG_AttributeError:
+ type = PyExc_AttributeError;
+ break;
+ default:
+ type = PyExc_RuntimeError;
+ }
+ return type;
+}
+
+
+SWIGRUNTIME void
+SWIG_Python_AddErrorMsg(const char* mesg)
+{
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+
+ if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ char *tmp;
+ PyObject *old_str = PyObject_Str(value);
+ PyErr_Clear();
+ Py_XINCREF(type);
+
+ PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(old_str);
+ Py_DECREF(value);
+ } else {
+ PyErr_SetString(PyExc_RuntimeError, mesg);
+ }
+}
+
+#if defined(SWIG_PYTHON_NO_THREADS)
+# if defined(SWIG_PYTHON_THREADS)
+# undef SWIG_PYTHON_THREADS
+# endif
+#endif
+#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */
+# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL)
+# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */
+# define SWIG_PYTHON_USE_GIL
+# endif
+# endif
+# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
+# ifndef SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
+# endif
+# ifdef __cplusplus /* C++ code */
+ class SWIG_Python_Thread_Block {
+ bool status;
+ PyGILState_STATE state;
+ public:
+ void end() { if (status) { PyGILState_Release(state); status = false;} }
+ SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {}
+ ~SWIG_Python_Thread_Block() { end(); }
+ };
+ class SWIG_Python_Thread_Allow {
+ bool status;
+ PyThreadState *save;
+ public:
+ void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
+ SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
+ ~SWIG_Python_Thread_Allow() { end(); }
+ };
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block
+# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end()
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow
+# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end()
+# else /* C code */
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure()
+# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread()
+# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow)
+# endif
+# else /* Old thread way, not implemented, user must provide it */
+# if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK)
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_BLOCK)
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# endif
+# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW)
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# endif
+# if !defined(SWIG_PYTHON_THREAD_END_ALLOW)
+# define SWIG_PYTHON_THREAD_END_ALLOW
+# endif
+# endif
+#else /* No thread support */
+# define SWIG_PYTHON_INITIALIZE_THREADS
+# define SWIG_PYTHON_THREAD_BEGIN_BLOCK
+# define SWIG_PYTHON_THREAD_END_BLOCK
+# define SWIG_PYTHON_THREAD_BEGIN_ALLOW
+# define SWIG_PYTHON_THREAD_END_ALLOW
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Python API portion that goes into the runtime
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* cc-mode */
+#endif
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Constant declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Constant Types */
+#define SWIG_PY_POINTER 4
+#define SWIG_PY_BINARY 5
+
+/* Constant information structure */
+typedef struct swig_const_info {
+ int type;
+ char *name;
+ long lvalue;
+ double dvalue;
+ void *pvalue;
+ swig_type_info **ptype;
+} swig_const_info;
+
+
+/* -----------------------------------------------------------------------------
+ * Wrapper of PyInstanceMethod_New() used in Python 3
+ * It is exported to the generated module, used for -fastproxy
+ * ----------------------------------------------------------------------------- */
+SWIGRUNTIME PyObject* SWIG_PyInstanceMethod_New(PyObject *self, PyObject *func)
+{
+#if PY_VERSION_HEX >= 0x03000000
+ return PyInstanceMethod_New(func);
+#else
+ return NULL;
+#endif
+}
+
+#ifdef __cplusplus
+#if 0
+{ /* cc-mode */
+#endif
+}
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * pyrun.swg
+ *
+ * This file contains the runtime support for Python modules
+ * and includes code for managing global variables and pointer
+ * type checking.
+ *
+ * ----------------------------------------------------------------------------- */
+
+/* Common SWIG API */
+
+/* for raw pointers */
+#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
+#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own)
+#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags)
+#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty)
+#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src)
+#define swig_owntype int
+
+/* for raw packed data */
+#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+/* for class or struct pointers */
+#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
+
+/* for C or C++ function pointers */
+#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type)
+#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0)
+
+/* for C++ member pointers, ie, member methods */
+#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type)
+
+
+/* Runtime API */
+
+#define SWIG_GetModule(clientdata) SWIG_Python_GetModule()
+#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer)
+#define SWIG_NewClientData(obj) SwigPyClientData_New(obj)
+
+#define SWIG_SetErrorObj SWIG_Python_SetErrorObj
+#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg
+#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code)
+#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg)
+#define SWIG_fail goto fail
+
+
+/* Runtime API implementation */
+
+/* Error manipulation */
+
+SWIGINTERN void
+SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetObject(errtype, obj);
+ Py_DECREF(obj);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+SWIGINTERN void
+SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) {
+ SWIG_PYTHON_THREAD_BEGIN_BLOCK;
+ PyErr_SetString(errtype, (char *) msg);
+ SWIG_PYTHON_THREAD_END_BLOCK;
+}
+
+#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj)
+
+/* Set a constant value */
+
+SWIGINTERN void
+SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) {
+ PyDict_SetItemString(d, (char*) name, obj);
+ Py_DECREF(obj);
+}
+
+/* Append a value to the result obj */
+
+SWIGINTERN PyObject*
+SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
+#if !defined(SWIG_PYTHON_OUTPUT_TUPLE)
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyList_Check(result)) {
+ PyObject *o2 = result;
+ result = PyList_New(1);
+ PyList_SetItem(result, 0, o2);
+ }
+ PyList_Append(result,obj);
+ Py_DECREF(obj);
+ }
+ return result;
+#else
+ PyObject* o2;
+ PyObject* o3;
+ if (!result) {
+ result = obj;
+ } else if (result == Py_None) {
+ Py_DECREF(result);
+ result = obj;
+ } else {
+ if (!PyTuple_Check(result)) {
+ o2 = result;
+ result = PyTuple_New(1);
+ PyTuple_SET_ITEM(result, 0, o2);
+ }
+ o3 = PyTuple_New(1);
+ PyTuple_SET_ITEM(o3, 0, obj);
+ o2 = result;
+ result = PySequence_Concat(o2, o3);
+ Py_DECREF(o2);
+ Py_DECREF(o3);
+ }
+ return result;
+#endif
+}
+
+/* Unpack the argument tuple */
+
+SWIGINTERN int
+SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
+{
+ if (!args) {
+ if (!min && !max) {
+ return 1;
+ } else {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none",
+ name, (min == max ? "" : "at least "), (int)min);
+ return 0;
+ }
+ }
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple");
+ return 0;
+ } else {
+ register Py_ssize_t l = PyTuple_GET_SIZE(args);
+ if (l < min) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at least "), (int)min, (int)l);
+ return 0;
+ } else if (l > max) {
+ PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d",
+ name, (min == max ? "" : "at most "), (int)max, (int)l);
+ return 0;
+ } else {
+ register int i;
+ for (i = 0; i < l; ++i) {
+ objs[i] = PyTuple_GET_ITEM(args, i);
+ }
+ for (; l < max; ++l) {
+ objs[l] = 0;
+ }
+ return i + 1;
+ }
+ }
+}
+
+/* A functor is a function object with one single object argument */
+#if PY_VERSION_HEX >= 0x02020000
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL);
+#else
+#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj);
+#endif
+
+/*
+ Helper for static pointer initialization for both C and C++ code, for example
+ static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...);
+*/
+#ifdef __cplusplus
+#define SWIG_STATIC_POINTER(var) var
+#else
+#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Pointer declarations
+ * ----------------------------------------------------------------------------- */
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1)
+#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN)
+
+#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1)
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* cc-mode */
+#endif
+#endif
+
+/* How to access Py_None */
+#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# ifndef SWIG_PYTHON_NO_BUILD_NONE
+# ifndef SWIG_PYTHON_BUILD_NONE
+# define SWIG_PYTHON_BUILD_NONE
+# endif
+# endif
+#endif
+
+#ifdef SWIG_PYTHON_BUILD_NONE
+# ifdef Py_None
+# undef Py_None
+# define Py_None SWIG_Py_None()
+# endif
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_Py_None(void)
+{
+ PyObject *none = Py_BuildValue((char*)"");
+ Py_DECREF(none);
+ return none;
+}
+SWIGRUNTIME PyObject *
+SWIG_Py_None(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None();
+ return none;
+}
+#endif
+
+/* The python void return value */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Py_Void(void)
+{
+ PyObject *none = Py_None;
+ Py_INCREF(none);
+ return none;
+}
+
+/* SwigPyClientData */
+
+typedef struct {
+ PyObject *klass;
+ PyObject *newraw;
+ PyObject *newargs;
+ PyObject *destroy;
+ int delargs;
+ int implicitconv;
+} SwigPyClientData;
+
+SWIGRUNTIMEINLINE int
+SWIG_Python_CheckImplicit(swig_type_info *ty)
+{
+ SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
+ return data ? data->implicitconv : 0;
+}
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_ExceptionType(swig_type_info *desc) {
+ SwigPyClientData *data = desc ? (SwigPyClientData *) desc->clientdata : 0;
+ PyObject *klass = data ? data->klass : 0;
+ return (klass ? klass : PyExc_RuntimeError);
+}
+
+
+SWIGRUNTIME SwigPyClientData *
+SwigPyClientData_New(PyObject* obj)
+{
+ if (!obj) {
+ return 0;
+ } else {
+ SwigPyClientData *data = (SwigPyClientData *)malloc(sizeof(SwigPyClientData));
+ /* the klass element */
+ data->klass = obj;
+ Py_INCREF(data->klass);
+ /* the newraw method and newargs arguments used to create a new raw instance */
+ if (PyClass_Check(obj)) {
+ data->newraw = 0;
+ data->newargs = obj;
+ Py_INCREF(obj);
+ } else {
+#if (PY_VERSION_HEX < 0x02020000)
+ data->newraw = 0;
+#else
+ data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__");
+#endif
+ if (data->newraw) {
+ Py_INCREF(data->newraw);
+ data->newargs = PyTuple_New(1);
+ PyTuple_SetItem(data->newargs, 0, obj);
+ } else {
+ data->newargs = obj;
+ }
+ Py_INCREF(data->newargs);
+ }
+ /* the destroy method, aka as the C++ delete method */
+ data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__");
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ data->destroy = 0;
+ }
+ if (data->destroy) {
+ int flags;
+ Py_INCREF(data->destroy);
+ flags = PyCFunction_GET_FLAGS(data->destroy);
+#ifdef METH_O
+ data->delargs = !(flags & (METH_O));
+#else
+ data->delargs = 0;
+#endif
+ } else {
+ data->delargs = 0;
+ }
+ data->implicitconv = 0;
+ return data;
+ }
+}
+
+SWIGRUNTIME void
+SwigPyClientData_Del(SwigPyClientData* data)
+{
+ Py_XDECREF(data->newraw);
+ Py_XDECREF(data->newargs);
+ Py_XDECREF(data->destroy);
+}
+
+/* =============== SwigPyObject =====================*/
+
+typedef struct {
+ PyObject_HEAD
+ void *ptr;
+ swig_type_info *ty;
+ int own;
+ PyObject *next;
+} SwigPyObject;
+
+SWIGRUNTIME PyObject *
+SwigPyObject_long(SwigPyObject *v)
+{
+ return PyLong_FromVoidPtr(v->ptr);
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_format(const char* fmt, SwigPyObject *v)
+{
+ PyObject *res = NULL;
+ PyObject *args = PyTuple_New(1);
+ if (args) {
+ if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
+ PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
+ if (ofmt) {
+#if PY_VERSION_HEX >= 0x03000000
+ res = PyUnicode_Format(ofmt,args);
+#else
+ res = PyString_Format(ofmt,args);
+#endif
+ Py_DECREF(ofmt);
+ }
+ Py_DECREF(args);
+ }
+ }
+ return res;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_oct(SwigPyObject *v)
+{
+ return SwigPyObject_format("%o",v);
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_hex(SwigPyObject *v)
+{
+ return SwigPyObject_format("%x",v);
+}
+
+SWIGRUNTIME PyObject *
+#ifdef METH_NOARGS
+SwigPyObject_repr(SwigPyObject *v)
+#else
+SwigPyObject_repr(SwigPyObject *v, PyObject *args)
+#endif
+{
+ const char *name = SWIG_TypePrettyName(v->ty);
+ PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", name, v);
+ if (v->next) {
+#ifdef METH_NOARGS
+ PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
+#else
+ PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next, args);
+#endif
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *joined = PyUnicode_Concat(repr, nrep);
+ Py_DecRef(repr);
+ Py_DecRef(nrep);
+ repr = joined;
+#else
+ PyString_ConcatAndDel(&repr,nrep);
+#endif
+ }
+ return repr;
+}
+
+SWIGRUNTIME int
+SwigPyObject_print(SwigPyObject *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+ char *str;
+#ifdef METH_NOARGS
+ PyObject *repr = SwigPyObject_repr(v);
+#else
+ PyObject *repr = SwigPyObject_repr(v, NULL);
+#endif
+ if (repr) {
+ str = SWIG_Python_str_AsChar(repr);
+ fputs(str, fp);
+ SWIG_Python_str_DelForPy3(str);
+ Py_DECREF(repr);
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_str(SwigPyObject *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ?
+ SWIG_Python_str_FromChar(result) : 0;
+}
+
+SWIGRUNTIME int
+SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
+{
+ void *i = v->ptr;
+ void *j = w->ptr;
+ return (i < j) ? -1 : ((i > j) ? 1 : 0);
+}
+
+/* Added for Python 3.x, would it also be useful for Python 2.x? */
+SWIGRUNTIME PyObject*
+SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
+{
+ PyObject* res;
+ if( op != Py_EQ && op != Py_NE ) {
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+ if( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) )
+ res = Py_True;
+ else
+ res = Py_False;
+ Py_INCREF(res);
+ return res;
+}
+
+
+SWIGRUNTIME PyTypeObject* _PySwigObject_type(void);
+
+SWIGRUNTIME PyTypeObject*
+SwigPyObject_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+SwigPyObject_Check(PyObject *op) {
+ return (Py_TYPE(op) == SwigPyObject_type())
+ || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
+
+SWIGRUNTIME void
+SwigPyObject_dealloc(PyObject *v)
+{
+ SwigPyObject *sobj = (SwigPyObject *) v;
+ PyObject *next = sobj->next;
+ if (sobj->own == SWIG_POINTER_OWN) {
+ swig_type_info *ty = sobj->ty;
+ SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
+ PyObject *destroy = data ? data->destroy : 0;
+ if (destroy) {
+ /* destroy is always a VARARGS method */
+ PyObject *res;
+ if (data->delargs) {
+ /* we need to create a temporary object to carry the destroy operation */
+ PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
+ res = SWIG_Python_CallFunctor(destroy, tmp);
+ Py_DECREF(tmp);
+ } else {
+ PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
+ PyObject *mself = PyCFunction_GET_SELF(destroy);
+ res = ((*meth)(mself, v));
+ }
+ Py_XDECREF(res);
+ }
+#if !defined(SWIG_PYTHON_SILENT_MEMLEAK)
+ else {
+ const char *name = SWIG_TypePrettyName(ty);
+ printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
+ }
+#endif
+ }
+ Py_XDECREF(next);
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyObject*
+SwigPyObject_append(PyObject* v, PyObject* next)
+{
+ SwigPyObject *sobj = (SwigPyObject *) v;
+#ifndef METH_O
+ PyObject *tmp = 0;
+ if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL;
+ next = tmp;
+#endif
+ if (!SwigPyObject_Check(next)) {
+ return NULL;
+ }
+ sobj->next = next;
+ Py_INCREF(next);
+ return SWIG_Py_Void();
+}
+
+SWIGRUNTIME PyObject*
+#ifdef METH_NOARGS
+SwigPyObject_next(PyObject* v)
+#else
+SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ SwigPyObject *sobj = (SwigPyObject *) v;
+ if (sobj->next) {
+ Py_INCREF(sobj->next);
+ return sobj->next;
+ } else {
+ return SWIG_Py_Void();
+ }
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+SwigPyObject_disown(PyObject *v)
+#else
+SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ SwigPyObject *sobj = (SwigPyObject *)v;
+ sobj->own = 0;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+#ifdef METH_NOARGS
+SwigPyObject_acquire(PyObject *v)
+#else
+SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
+#endif
+{
+ SwigPyObject *sobj = (SwigPyObject *)v;
+ sobj->own = SWIG_POINTER_OWN;
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject*
+SwigPyObject_own(PyObject *v, PyObject *args)
+{
+ PyObject *val = 0;
+#if (PY_VERSION_HEX < 0x02020000)
+ if (!PyArg_ParseTuple(args,(char *)"|O:own",&val))
+#else
+ if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val))
+#endif
+ {
+ return NULL;
+ }
+ else
+ {
+ SwigPyObject *sobj = (SwigPyObject *)v;
+ PyObject *obj = PyBool_FromLong(sobj->own);
+ if (val) {
+#ifdef METH_NOARGS
+ if (PyObject_IsTrue(val)) {
+ SwigPyObject_acquire(v);
+ } else {
+ SwigPyObject_disown(v);
+ }
+#else
+ if (PyObject_IsTrue(val)) {
+ SwigPyObject_acquire(v,args);
+ } else {
+ SwigPyObject_disown(v,args);
+ }
+#endif
+ }
+ return obj;
+ }
+}
+
+#ifdef METH_O
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)SwigPyObject_append, METH_O, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)SwigPyObject_next, METH_NOARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_NOARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#else
+static PyMethodDef
+swigobject_methods[] = {
+ {(char *)"disown", (PyCFunction)SwigPyObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"},
+ {(char *)"acquire", (PyCFunction)SwigPyObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"},
+ {(char *)"own", (PyCFunction)SwigPyObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"},
+ {(char *)"append", (PyCFunction)SwigPyObject_append, METH_VARARGS, (char *)"appends another 'this' object"},
+ {(char *)"next", (PyCFunction)SwigPyObject_next, METH_VARARGS, (char *)"returns the next 'this' object"},
+ {(char *)"__repr__",(PyCFunction)SwigPyObject_repr, METH_VARARGS, (char *)"returns object representation"},
+ {0, 0, 0, 0}
+};
+#endif
+
+#if PY_VERSION_HEX < 0x02020000
+SWIGINTERN PyObject *
+SwigPyObject_getattr(SwigPyObject *sobj,char *name)
+{
+ return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name);
+}
+#endif
+
+SWIGRUNTIME PyTypeObject*
+_PySwigObject_type(void) {
+ static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
+
+ static PyNumberMethods SwigPyObject_as_number = {
+ (binaryfunc)0, /*nb_add*/
+ (binaryfunc)0, /*nb_subtract*/
+ (binaryfunc)0, /*nb_multiply*/
+ /* nb_divide removed in Python 3 */
+#if PY_VERSION_HEX < 0x03000000
+ (binaryfunc)0, /*nb_divide*/
+#endif
+ (binaryfunc)0, /*nb_remainder*/
+ (binaryfunc)0, /*nb_divmod*/
+ (ternaryfunc)0,/*nb_power*/
+ (unaryfunc)0, /*nb_negative*/
+ (unaryfunc)0, /*nb_positive*/
+ (unaryfunc)0, /*nb_absolute*/
+ (inquiry)0, /*nb_nonzero*/
+ 0, /*nb_invert*/
+ 0, /*nb_lshift*/
+ 0, /*nb_rshift*/
+ 0, /*nb_and*/
+ 0, /*nb_xor*/
+ 0, /*nb_or*/
+#if PY_VERSION_HEX < 0x03000000
+ 0, /*nb_coerce*/
+#endif
+ (unaryfunc)SwigPyObject_long, /*nb_int*/
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc)SwigPyObject_long, /*nb_long*/
+#else
+ 0, /*nb_reserved*/
+#endif
+ (unaryfunc)0, /*nb_float*/
+#if PY_VERSION_HEX < 0x03000000
+ (unaryfunc)SwigPyObject_oct, /*nb_oct*/
+ (unaryfunc)SwigPyObject_hex, /*nb_hex*/
+#endif
+#if PY_VERSION_HEX >= 0x03000000 /* 3.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index, nb_inplace_divide removed */
+#elif PY_VERSION_HEX >= 0x02050000 /* 2.5.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_index */
+#elif PY_VERSION_HEX >= 0x02020000 /* 2.2.0 */
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */
+#elif PY_VERSION_HEX >= 0x02000000 /* 2.0.0 */
+ 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */
+#endif
+ };
+
+ static PyTypeObject swigpyobject_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ (char *)"SwigPyObject", /* tp_name */
+ sizeof(SwigPyObject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)SwigPyObject_dealloc, /* tp_dealloc */
+ (printfunc)SwigPyObject_print, /* tp_print */
+#if PY_VERSION_HEX < 0x02020000
+ (getattrfunc)SwigPyObject_getattr, /* tp_getattr */
+#else
+ (getattrfunc)0, /* tp_getattr */
+#endif
+ (setattrfunc)0, /* tp_setattr */
+#if PY_VERSION_HEX >= 0x03000000
+ 0, /* tp_reserved in 3.0.1, tp_compare in 3.0.0 but not used */
+#else
+ (cmpfunc)SwigPyObject_compare, /* tp_compare */
+#endif
+ (reprfunc)SwigPyObject_repr, /* tp_repr */
+ &SwigPyObject_as_number, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)SwigPyObject_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigobject_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ (richcmpfunc)SwigPyObject_richcompare, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ swigobject_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ swigpyobject_type = tmp;
+ /* for Python 3 we already assigned ob_type in PyVarObject_HEAD_INIT() */
+#if PY_VERSION_HEX < 0x03000000
+ swigpyobject_type.ob_type = &PyType_Type;
+#endif
+ type_init = 1;
+ }
+ return &swigpyobject_type;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
+{
+ SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
+ if (sobj) {
+ sobj->ptr = ptr;
+ sobj->ty = ty;
+ sobj->own = own;
+ sobj->next = 0;
+ }
+ return (PyObject *)sobj;
+}
+
+/* -----------------------------------------------------------------------------
+ * Implements a simple Swig Packed type, and use it instead of string
+ * ----------------------------------------------------------------------------- */
+
+typedef struct {
+ PyObject_HEAD
+ void *pack;
+ swig_type_info *ty;
+ size_t size;
+} SwigPyPacked;
+
+SWIGRUNTIME int
+SwigPyPacked_print(SwigPyPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags))
+{
+ char result[SWIG_BUFFER_SIZE];
+ fputs("<Swig Packed ", fp);
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ fputs("at ", fp);
+ fputs(result, fp);
+ }
+ fputs(v->ty->name,fp);
+ fputs(">", fp);
+ return 0;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyPacked_repr(SwigPyPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
+ return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
+ } else {
+ return SWIG_Python_str_FromFormat("<Swig Packed %s>", v->ty->name);
+ }
+}
+
+SWIGRUNTIME PyObject *
+SwigPyPacked_str(SwigPyPacked *v)
+{
+ char result[SWIG_BUFFER_SIZE];
+ if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){
+ return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
+ } else {
+ return SWIG_Python_str_FromChar(v->ty->name);
+ }
+}
+
+SWIGRUNTIME int
+SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
+{
+ size_t i = v->size;
+ size_t j = w->size;
+ int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
+ return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size);
+}
+
+SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void);
+
+SWIGRUNTIME PyTypeObject*
+SwigPyPacked_type(void) {
+ static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type();
+ return type;
+}
+
+SWIGRUNTIMEINLINE int
+SwigPyPacked_Check(PyObject *op) {
+ return ((op)->ob_type == _PySwigPacked_type())
+ || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
+}
+
+SWIGRUNTIME void
+SwigPyPacked_dealloc(PyObject *v)
+{
+ if (SwigPyPacked_Check(v)) {
+ SwigPyPacked *sobj = (SwigPyPacked *) v;
+ free(sobj->pack);
+ }
+ PyObject_DEL(v);
+}
+
+SWIGRUNTIME PyTypeObject*
+_PySwigPacked_type(void) {
+ static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
+ static PyTypeObject swigpypacked_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX>=0x03000000
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* ob_size */
+#endif
+ (char *)"SwigPyPacked", /* tp_name */
+ sizeof(SwigPyPacked), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)SwigPyPacked_dealloc, /* tp_dealloc */
+ (printfunc)SwigPyPacked_print, /* tp_print */
+ (getattrfunc)0, /* tp_getattr */
+ (setattrfunc)0, /* tp_setattr */
+#if PY_VERSION_HEX>=0x03000000
+ 0, /* tp_reserved in 3.0.1 */
+#else
+ (cmpfunc)SwigPyPacked_compare, /* tp_compare */
+#endif
+ (reprfunc)SwigPyPacked_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ (hashfunc)0, /* tp_hash */
+ (ternaryfunc)0, /* tp_call */
+ (reprfunc)SwigPyPacked_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ swigpacked_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+ 0, /* tp_free */
+ 0, /* tp_is_gc */
+ 0, /* tp_bases */
+ 0, /* tp_mro */
+ 0, /* tp_cache */
+ 0, /* tp_subclasses */
+ 0, /* tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ swigpypacked_type = tmp;
+ /* for Python 3 the ob_type already assigned in PyVarObject_HEAD_INIT() */
+#if PY_VERSION_HEX < 0x03000000
+ swigpypacked_type.ob_type = &PyType_Type;
+#endif
+ type_init = 1;
+ }
+ return &swigpypacked_type;
+}
+
+SWIGRUNTIME PyObject *
+SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
+{
+ SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
+ if (sobj) {
+ void *pack = malloc(size);
+ if (pack) {
+ memcpy(pack, ptr, size);
+ sobj->pack = pack;
+ sobj->ty = ty;
+ sobj->size = size;
+ } else {
+ PyObject_DEL((PyObject *) sobj);
+ sobj = 0;
+ }
+ }
+ return (PyObject *) sobj;
+}
+
+SWIGRUNTIME swig_type_info *
+SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
+{
+ if (SwigPyPacked_Check(obj)) {
+ SwigPyPacked *sobj = (SwigPyPacked *)obj;
+ if (sobj->size != size) return 0;
+ memcpy(ptr, sobj->pack, size);
+ return sobj->ty;
+ } else {
+ return 0;
+ }
+}
+
+/* -----------------------------------------------------------------------------
+ * pointers/data manipulation
+ * ----------------------------------------------------------------------------- */
+
+SWIGRUNTIMEINLINE PyObject *
+_SWIG_This(void)
+{
+ return SWIG_Python_str_FromChar("this");
+}
+
+SWIGRUNTIME PyObject *
+SWIG_This(void)
+{
+ static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This();
+ return swig_this;
+}
+
+/* #define SWIG_PYTHON_SLOW_GETSET_THIS */
+
+/* TODO: I don't know how to implement the fast getset in Python 3 right now */
+#if PY_VERSION_HEX>=0x03000000
+#define SWIG_PYTHON_SLOW_GETSET_THIS
+#endif
+
+SWIGRUNTIME SwigPyObject *
+SWIG_Python_GetSwigThis(PyObject *pyobj)
+{
+ if (SwigPyObject_Check(pyobj)) {
+ return (SwigPyObject *) pyobj;
+ } else {
+ PyObject *obj = 0;
+#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000))
+ if (PyInstance_Check(pyobj)) {
+ obj = _PyInstance_Lookup(pyobj, SWIG_This());
+ } else {
+ PyObject **dictptr = _PyObject_GetDictPtr(pyobj);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0;
+ } else {
+#ifdef PyWeakref_CheckProxy
+ if (PyWeakref_CheckProxy(pyobj)) {
+ PyObject *wobj = PyWeakref_GET_OBJECT(pyobj);
+ return wobj ? SWIG_Python_GetSwigThis(wobj) : 0;
+ }
+#endif
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+ }
+ }
+#else
+ obj = PyObject_GetAttr(pyobj,SWIG_This());
+ if (obj) {
+ Py_DECREF(obj);
+ } else {
+ if (PyErr_Occurred()) PyErr_Clear();
+ return 0;
+ }
+#endif
+ if (obj && !SwigPyObject_Check(obj)) {
+ /* a PyObject is called 'this', try to get the 'real this'
+ SwigPyObject from it */
+ return SWIG_Python_GetSwigThis(obj);
+ }
+ return (SwigPyObject *)obj;
+ }
+}
+
+/* Acquire a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_AcquirePtr(PyObject *obj, int own) {
+ if (own == SWIG_POINTER_OWN) {
+ SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (sobj) {
+ int oldown = sobj->own;
+ sobj->own = own;
+ return oldown;
+ }
+ }
+ return 0;
+}
+
+/* Convert a pointer value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) {
+ if (!obj) return SWIG_ERROR;
+ if (obj == Py_None) {
+ if (ptr) *ptr = 0;
+ return SWIG_OK;
+ } else {
+ SwigPyObject *sobj = SWIG_Python_GetSwigThis(obj);
+ if (own)
+ *own = 0;
+ while (sobj) {
+ void *vptr = sobj->ptr;
+ if (ty) {
+ swig_type_info *to = sobj->ty;
+ if (to == ty) {
+ /* no type cast needed */
+ if (ptr) *ptr = vptr;
+ break;
+ } else {
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) {
+ sobj = (SwigPyObject *)sobj->next;
+ } else {
+ if (ptr) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ if (newmemory == SWIG_CAST_NEW_MEMORY) {
+ assert(own);
+ if (own)
+ *own = *own | SWIG_CAST_NEW_MEMORY;
+ }
+ }
+ break;
+ }
+ }
+ } else {
+ if (ptr) *ptr = vptr;
+ break;
+ }
+ }
+ if (sobj) {
+ if (own)
+ *own = *own | sobj->own;
+ if (flags & SWIG_POINTER_DISOWN) {
+ sobj->own = 0;
+ }
+ return SWIG_OK;
+ } else {
+ int res = SWIG_ERROR;
+ if (flags & SWIG_POINTER_IMPLICIT_CONV) {
+ SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
+ if (data && !data->implicitconv) {
+ PyObject *klass = data->klass;
+ if (klass) {
+ PyObject *impconv;
+ data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/
+ impconv = SWIG_Python_CallFunctor(klass, obj);
+ data->implicitconv = 0;
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ impconv = 0;
+ }
+ if (impconv) {
+ SwigPyObject *iobj = SWIG_Python_GetSwigThis(impconv);
+ if (iobj) {
+ void *vptr;
+ res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0);
+ if (SWIG_IsOK(res)) {
+ if (ptr) {
+ *ptr = vptr;
+ /* transfer the ownership to 'ptr' */
+ iobj->own = 0;
+ res = SWIG_AddCast(res);
+ res = SWIG_AddNewMask(res);
+ } else {
+ res = SWIG_AddCast(res);
+ }
+ }
+ }
+ Py_DECREF(impconv);
+ }
+ }
+ }
+ }
+ return res;
+ }
+ }
+}
+
+/* Convert a function ptr value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) {
+ if (!PyCFunction_Check(obj)) {
+ return SWIG_ConvertPtr(obj, ptr, ty, 0);
+ } else {
+ void *vptr = 0;
+
+ /* here we get the method pointer for callbacks */
+ const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
+ const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
+ if (desc)
+ desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
+ if (!desc)
+ return SWIG_ERROR;
+ if (ty) {
+ swig_cast_info *tc = SWIG_TypeCheck(desc,ty);
+ if (tc) {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ } else {
+ return SWIG_ERROR;
+ }
+ } else {
+ *ptr = vptr;
+ }
+ return SWIG_OK;
+ }
+}
+
+/* Convert a packed value value */
+
+SWIGRUNTIME int
+SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) {
+ swig_type_info *to = SwigPyPacked_UnpackData(obj, ptr, sz);
+ if (!to) return SWIG_ERROR;
+ if (ty) {
+ if (to != ty) {
+ /* check type cast? */
+ swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
+ if (!tc) return SWIG_ERROR;
+ }
+ }
+ return SWIG_OK;
+}
+
+/* -----------------------------------------------------------------------------
+ * Create a new pointer object
+ * ----------------------------------------------------------------------------- */
+
+/*
+ Create a new instance object, without calling __init__, and set the
+ 'this' attribute.
+*/
+
+SWIGRUNTIME PyObject*
+SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
+{
+#if (PY_VERSION_HEX >= 0x02020000)
+ PyObject *inst = 0;
+ PyObject *newraw = data->newraw;
+ if (newraw) {
+ inst = PyObject_Call(newraw, data->newargs, NULL);
+ if (inst) {
+#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ PyObject *dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ }
+ }
+#else
+ PyObject *key = SWIG_This();
+ PyObject_SetAttr(inst, key, swig_this);
+#endif
+ }
+ } else {
+#if PY_VERSION_HEX >= 0x03000000
+ inst = PyBaseObject_Type.tp_new((PyTypeObject*) data->newargs, Py_None, Py_None);
+ PyObject_SetAttr(inst, SWIG_This(), swig_this);
+ Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+#else
+ PyObject *dict = PyDict_New();
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+#endif
+ }
+ return inst;
+#else
+#if (PY_VERSION_HEX >= 0x02010000)
+ PyObject *inst;
+ PyObject *dict = PyDict_New();
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ inst = PyInstance_NewRaw(data->newargs, dict);
+ Py_DECREF(dict);
+ return (PyObject *) inst;
+#else
+ PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type);
+ if (inst == NULL) {
+ return NULL;
+ }
+ inst->in_class = (PyClassObject *)data->newargs;
+ Py_INCREF(inst->in_class);
+ inst->in_dict = PyDict_New();
+ if (inst->in_dict == NULL) {
+ Py_DECREF(inst);
+ return NULL;
+ }
+#ifdef Py_TPFLAGS_HAVE_WEAKREFS
+ inst->in_weakreflist = NULL;
+#endif
+#ifdef Py_TPFLAGS_GC
+ PyObject_GC_Init(inst);
+#endif
+ PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this);
+ return (PyObject *) inst;
+#endif
+#endif
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
+{
+ PyObject *dict;
+#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
+ PyObject **dictptr = _PyObject_GetDictPtr(inst);
+ if (dictptr != NULL) {
+ dict = *dictptr;
+ if (dict == NULL) {
+ dict = PyDict_New();
+ *dictptr = dict;
+ }
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ return;
+ }
+#endif
+ dict = PyObject_GetAttrString(inst, (char*)"__dict__");
+ PyDict_SetItem(dict, SWIG_This(), swig_this);
+ Py_DECREF(dict);
+}
+
+
+SWIGINTERN PyObject *
+SWIG_Python_InitShadowInstance(PyObject *args) {
+ PyObject *obj[2];
+ if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) {
+ return NULL;
+ } else {
+ SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
+ if (sthis) {
+ SwigPyObject_append((PyObject*) sthis, obj[1]);
+ } else {
+ SWIG_Python_SetSwigThis(obj[0], obj[1]);
+ }
+ return SWIG_Py_Void();
+ }
+}
+
+/* Create a new pointer object */
+
+SWIGRUNTIME PyObject *
+SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
+ if (!ptr) {
+ return SWIG_Py_Void();
+ } else {
+ int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
+ PyObject *robj = SwigPyObject_New(ptr, type, own);
+ SwigPyClientData *clientdata = type ? (SwigPyClientData *)(type->clientdata) : 0;
+ if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) {
+ PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj);
+ if (inst) {
+ Py_DECREF(robj);
+ robj = inst;
+ }
+ }
+ return robj;
+ }
+}
+
+/* Create a new packed object */
+
+SWIGRUNTIMEINLINE PyObject *
+SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) {
+ return ptr ? SwigPyPacked_New((void *) ptr, sz, type) : SWIG_Py_Void();
+}
+
+/* -----------------------------------------------------------------------------*
+ * Get type list
+ * -----------------------------------------------------------------------------*/
+
+#ifdef SWIG_LINK_RUNTIME
+void *SWIG_ReturnGlobalTypeList(void *);
+#endif
+
+SWIGRUNTIME swig_module_info *
+SWIG_Python_GetModule(void) {
+ static void *type_pointer = (void *)0;
+ /* first check if module already created */
+ if (!type_pointer) {
+#ifdef SWIG_LINK_RUNTIME
+ type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
+#else
+ type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ (char*)"type_pointer" SWIG_TYPE_TABLE_NAME);
+ if (PyErr_Occurred()) {
+ PyErr_Clear();
+ type_pointer = (void *)0;
+ }
+#endif
+ }
+ return (swig_module_info *) type_pointer;
+}
+
+#if PY_MAJOR_VERSION < 2
+/* PyModule_AddObject function was introduced in Python 2.0. The following function
+ is copied out of Python/modsupport.c in python version 2.3.4 */
+SWIGINTERN int
+PyModule_AddObject(PyObject *m, char *name, PyObject *o)
+{
+ PyObject *dict;
+ if (!PyModule_Check(m)) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs module as first arg");
+ return SWIG_ERROR;
+ }
+ if (!o) {
+ PyErr_SetString(PyExc_TypeError,
+ "PyModule_AddObject() needs non-NULL value");
+ return SWIG_ERROR;
+ }
+
+ dict = PyModule_GetDict(m);
+ if (dict == NULL) {
+ /* Internal error -- modules must have a dict! */
+ PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__",
+ PyModule_GetName(m));
+ return SWIG_ERROR;
+ }
+ if (PyDict_SetItemString(dict, name, o))
+ return SWIG_ERROR;
+ Py_DECREF(o);
+ return SWIG_OK;
+}
+#endif
+
+SWIGRUNTIME void
+SWIG_Python_DestroyModule(void *vptr)
+{
+ swig_module_info *swig_module = (swig_module_info *) vptr;
+ swig_type_info **types = swig_module->types;
+ size_t i;
+ for (i =0; i < swig_module->size; ++i) {
+ swig_type_info *ty = types[i];
+ if (ty->owndata) {
+ SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
+ if (data) SwigPyClientData_Del(data);
+ }
+ }
+ Py_DECREF(SWIG_This());
+}
+
+SWIGRUNTIME void
+SWIG_Python_SetModule(swig_module_info *swig_module) {
+ static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */
+
+#if PY_VERSION_HEX >= 0x03000000
+ /* Add a dummy module object into sys.modules */
+ PyObject *module = PyImport_AddModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION);
+#else
+ PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION,
+ swig_empty_runtime_method_table);
+#endif
+ PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule);
+ if (pointer && module) {
+ PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer);
+ } else {
+ Py_XDECREF(pointer);
+ }
+}
+
+/* The python cached type query */
+SWIGRUNTIME PyObject *
+SWIG_Python_TypeCache(void) {
+ static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
+ return cache;
+}
+
+SWIGRUNTIME swig_type_info *
+SWIG_Python_TypeQuery(const char *type)
+{
+ PyObject *cache = SWIG_Python_TypeCache();
+ PyObject *key = SWIG_Python_str_FromChar(type);
+ PyObject *obj = PyDict_GetItem(cache, key);
+ swig_type_info *descriptor;
+ if (obj) {
+ descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj);
+ } else {
+ swig_module_info *swig_module = SWIG_Python_GetModule();
+ descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
+ if (descriptor) {
+ obj = PyCObject_FromVoidPtr(descriptor, NULL);
+ PyDict_SetItem(cache, key, obj);
+ Py_DECREF(obj);
+ }
+ }
+ Py_DECREF(key);
+ return descriptor;
+}
+
+/*
+ For backward compatibility only
+*/
+#define SWIG_POINTER_EXCEPTION 0
+#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg)
+#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
+
+SWIGRUNTIME int
+SWIG_Python_AddErrMesg(const char* mesg, int infront)
+{
+ if (PyErr_Occurred()) {
+ PyObject *type = 0;
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+ char *tmp;
+ PyObject *old_str = PyObject_Str(value);
+ Py_XINCREF(type);
+ PyErr_Clear();
+ if (infront) {
+ PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
+ } else {
+ PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
+ }
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(old_str);
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIME int
+SWIG_Python_ArgFail(int argnum)
+{
+ if (PyErr_Occurred()) {
+ /* add information about failing argument */
+ char mesg[256];
+ PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum);
+ return SWIG_Python_AddErrMesg(mesg, 1);
+ } else {
+ return 0;
+ }
+}
+
+SWIGRUNTIMEINLINE const char *
+SwigPyObject_GetDesc(PyObject *self)
+{
+ SwigPyObject *v = (SwigPyObject *)self;
+ swig_type_info *ty = v ? v->ty : 0;
+ return ty ? ty->str : (char*)"";
+}
+
+SWIGRUNTIME void
+SWIG_Python_TypeError(const char *type, PyObject *obj)
+{
+ if (type) {
+#if defined(SWIG_COBJECT_TYPES)
+ if (obj && SwigPyObject_Check(obj)) {
+ const char *otype = (const char *) SwigPyObject_GetDesc(obj);
+ if (otype) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'SwigPyObject(%s)' is received",
+ type, otype);
+ return;
+ }
+ } else
+#endif
+ {
+ const char *otype = (obj ? obj->ob_type->tp_name : 0);
+ if (otype) {
+ PyObject *str = PyObject_Str(obj);
+ const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
+ if (cstr) {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
+ type, otype, cstr);
+ SWIG_Python_str_DelForPy3(cstr);
+ } else {
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
+ type, otype);
+ }
+ Py_XDECREF(str);
+ return;
+ }
+ }
+ PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
+ } else {
+ PyErr_Format(PyExc_TypeError, "unexpected type is received");
+ }
+}
+
+
+/* Convert a pointer value, signal an exception on a type mismatch */
+SWIGRUNTIME void *
+SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) {
+ void *result;
+ if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
+ PyErr_Clear();
+#if SWIG_POINTER_EXCEPTION
+ if (flags) {
+ SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
+ SWIG_Python_ArgFail(argnum);
+ }
+#endif
+ }
+ return result;
+}
+
+
+#ifdef __cplusplus
+#if 0
+{ /* cc-mode */
+#endif
+}
+#endif
+
+
+
+#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
+
+#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
+
+
+
+ #define SWIG_exception(code, msg) do { SWIG_Error(code, msg); SWIG_fail;; } while(0)
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_char swig_types[0]
+#define SWIGTYPE_p_marisa__Key swig_types[1]
+#define SWIGTYPE_p_marisa_swig__Agent swig_types[2]
+#define SWIGTYPE_p_marisa_swig__Key swig_types[3]
+#define SWIGTYPE_p_marisa_swig__Keyset swig_types[4]
+#define SWIGTYPE_p_marisa_swig__Query swig_types[5]
+#define SWIGTYPE_p_marisa_swig__Trie swig_types[6]
+#define SWIGTYPE_p_p_char swig_types[7]
+#define SWIGTYPE_p_std__size_t swig_types[8]
+static swig_type_info *swig_types[10];
+static swig_module_info swig_module = {swig_types, 9, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+#if (PY_VERSION_HEX <= 0x02000000)
+# if !defined(SWIG_PYTHON_CLASSIC)
+# error "This python version requires swig to be run with the '-classic' option"
+# endif
+#endif
+
+/*-----------------------------------------------
+ @(target):= _marisa.so
+ ------------------------------------------------*/
+#if PY_VERSION_HEX >= 0x03000000
+# define SWIG_init PyInit__marisa
+
+#else
+# define SWIG_init init_marisa
+
+#endif
+#define SWIG_name "_marisa"
+
+#define SWIGVERSION 0x010340
+#define SWIG_VERSION SWIGVERSION
+
+
+#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a))
+#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a))
+
+
+#include <stdexcept>
+
+
+namespace swig {
+ class SwigPtr_PyObject {
+ protected:
+ PyObject *_obj;
+
+ public:
+ SwigPtr_PyObject() :_obj(0)
+ {
+ }
+
+ SwigPtr_PyObject(const SwigPtr_PyObject& item) : _obj(item._obj)
+ {
+ Py_XINCREF(_obj);
+ }
+
+ SwigPtr_PyObject(PyObject *obj, bool initial_ref = true) :_obj(obj)
+ {
+ if (initial_ref) {
+ Py_XINCREF(_obj);
+ }
+ }
+
+ SwigPtr_PyObject & operator=(const SwigPtr_PyObject& item)
+ {
+ Py_XINCREF(item._obj);
+ Py_XDECREF(_obj);
+ _obj = item._obj;
+ return *this;
+ }
+
+ ~SwigPtr_PyObject()
+ {
+ Py_XDECREF(_obj);
+ }
+
+ operator PyObject *() const
+ {
+ return _obj;
+ }
+
+ PyObject *operator->() const
+ {
+ return _obj;
+ }
+ };
+}
+
+
+namespace swig {
+ struct SwigVar_PyObject : SwigPtr_PyObject {
+ SwigVar_PyObject(PyObject* obj = 0) : SwigPtr_PyObject(obj, false) { }
+
+ SwigVar_PyObject & operator = (PyObject* obj)
+ {
+ Py_XDECREF(_obj);
+ _obj = obj;
+ return *this;
+ }
+ };
+}
+
+
+#include "marisa-swig.h"
+
+
+ #define SWIG_From_long PyInt_FromLong
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_From_int (int value)
+{
+ return SWIG_From_long (value);
+}
+
+
+SWIGINTERN swig_type_info*
+SWIG_pchar_descriptor(void)
+{
+ static int init = 0;
+ static swig_type_info* info = 0;
+ if (!init) {
+ info = SWIG_TypeQuery("_p_char");
+ init = 1;
+ }
+ return info;
+}
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_FromCharPtrAndSize(const char* carray, size_t size)
+{
+ if (carray) {
+ if (size > INT_MAX) {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ return pchar_descriptor ?
+ SWIG_NewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : SWIG_Py_Void();
+ } else {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_FromStringAndSize(carray, static_cast< int >(size));
+#else
+ return PyString_FromStringAndSize(carray, static_cast< int >(size));
+#endif
+ }
+ } else {
+ return SWIG_Py_Void();
+ }
+}
+
+
+SWIGINTERNINLINE PyObject*
+SWIG_From_unsigned_SS_long (unsigned long value)
+{
+ return (value > LONG_MAX) ?
+ PyLong_FromUnsignedLong(value) : PyInt_FromLong(static_cast< long >(value));
+}
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_From_size_t (size_t value)
+{
+ return SWIG_From_unsigned_SS_long (static_cast< unsigned long >(value));
+}
+
+
+ #define SWIG_From_double PyFloat_FromDouble
+
+
+SWIGINTERNINLINE PyObject *
+SWIG_From_float (float value)
+{
+ return SWIG_From_double (value);
+}
+
+
+SWIGINTERN int
+SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+{
+#if PY_VERSION_HEX>=0x03000000
+ if (PyUnicode_Check(obj))
+#else
+ if (PyString_Check(obj))
+#endif
+ {
+ char *cstr; Py_ssize_t len;
+#if PY_VERSION_HEX>=0x03000000
+ if (!alloc && cptr) {
+ /* We can't allow converting without allocation, since the internal
+ representation of string in Python 3 is UCS-2/UCS-4 but we require
+ a UTF-8 representation.
+ TODO(bhy) More detailed explanation */
+ return SWIG_RuntimeError;
+ }
+ obj = PyUnicode_AsUTF8String(obj);
+ PyBytes_AsStringAndSize(obj, &cstr, &len);
+ if(alloc) *alloc = SWIG_NEWOBJ;
+#else
+ PyString_AsStringAndSize(obj, &cstr, &len);
+#endif
+ if (cptr) {
+ if (alloc) {
+ /*
+ In python the user should not be able to modify the inner
+ string representation. To warranty that, if you define
+ SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string
+ buffer is always returned.
+
+ The default behavior is just to return the pointer value,
+ so, be careful.
+ */
+#if defined(SWIG_PYTHON_SAFE_CSTRINGS)
+ if (*alloc != SWIG_OLDOBJ)
+#else
+ if (*alloc == SWIG_NEWOBJ)
+#endif
+ {
+ *cptr = reinterpret_cast< char* >(memcpy((new char[len + 1]), cstr, sizeof(char)*(len + 1)));
+ *alloc = SWIG_NEWOBJ;
+ }
+ else {
+ *cptr = cstr;
+ *alloc = SWIG_OLDOBJ;
+ }
+ } else {
+ #if PY_VERSION_HEX>=0x03000000
+ assert(0); /* Should never reach here in Python 3 */
+ #endif
+ *cptr = SWIG_Python_str_AsChar(obj);
+ }
+ }
+ if (psize) *psize = len + 1;
+#if PY_VERSION_HEX>=0x03000000
+ Py_XDECREF(obj);
+#endif
+ return SWIG_OK;
+ } else {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ if (pchar_descriptor) {
+ void* vptr = 0;
+ if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
+ if (cptr) *cptr = (char *) vptr;
+ if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
+ if (alloc) *alloc = SWIG_OLDOBJ;
+ return SWIG_OK;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+#include <float.h>
+
+
+SWIGINTERN int
+SWIG_AsVal_double (PyObject *obj, double *val)
+{
+ int res = SWIG_TypeError;
+ if (PyFloat_Check(obj)) {
+ if (val) *val = PyFloat_AsDouble(obj);
+ return SWIG_OK;
+ } else if (PyInt_Check(obj)) {
+ if (val) *val = PyInt_AsLong(obj);
+ return SWIG_OK;
+ } else if (PyLong_Check(obj)) {
+ double v = PyLong_AsDouble(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ PyErr_Clear();
+ }
+ }
+#ifdef SWIG_PYTHON_CAST_MODE
+ {
+ int dispatch = 0;
+ double d = PyFloat_AsDouble(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = d;
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ PyErr_Clear();
+ }
+ if (!dispatch) {
+ long v = PyLong_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
+ } else {
+ PyErr_Clear();
+ }
+ }
+ }
+#endif
+ return res;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_float (PyObject * obj, float *val)
+{
+ double v;
+ int res = SWIG_AsVal_double (obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < -FLT_MAX || v > FLT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = static_cast< float >(v);
+ }
+ }
+ return res;
+}
+
+
+
+
+
+#include <math.h>
+
+
+SWIGINTERNINLINE int
+SWIG_CanCastAsInteger(double *d, double min, double max) {
+ double x = *d;
+ if ((min <= x && x <= max)) {
+ double fx = floor(x);
+ double cx = ceil(x);
+ double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */
+ if ((errno == EDOM) || (errno == ERANGE)) {
+ errno = 0;
+ } else {
+ double summ, reps, diff;
+ if (rd < x) {
+ diff = x - rd;
+ } else if (rd > x) {
+ diff = rd - x;
+ } else {
+ return 1;
+ }
+ summ = rd + x;
+ reps = diff/summ;
+ if (reps < 8*DBL_EPSILON) {
+ *d = rd;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_unsigned_SS_long (PyObject *obj, unsigned long *val)
+{
+ if (PyInt_Check(obj)) {
+ long v = PyInt_AsLong(obj);
+ if (v >= 0) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ return SWIG_OverflowError;
+ }
+ } else if (PyLong_Check(obj)) {
+ unsigned long v = PyLong_AsUnsignedLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ PyErr_Clear();
+ }
+ }
+#ifdef SWIG_PYTHON_CAST_MODE
+ {
+ int dispatch = 0;
+ unsigned long v = PyLong_AsUnsignedLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ PyErr_Clear();
+ }
+ if (!dispatch) {
+ double d;
+ int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
+ if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
+ if (val) *val = (unsigned long)(d);
+ return res;
+ }
+ }
+ }
+#endif
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERNINLINE int
+SWIG_AsVal_size_t (PyObject * obj, size_t *val)
+{
+ unsigned long v;
+ int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0);
+ if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v);
+ return res;
+}
+
+
+SWIGINTERNINLINE PyObject*
+ SWIG_From_bool (bool value)
+{
+ return PyBool_FromLong(value ? 1 : 0);
+}
+
+
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+# define LLONG_MAX __LONG_LONG_MAX__
+# define LLONG_MIN (-LLONG_MAX - 1LL)
+# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+
+
+SWIGINTERN int
+SWIG_AsVal_long (PyObject *obj, long* val)
+{
+ if (PyInt_Check(obj)) {
+ if (val) *val = PyInt_AsLong(obj);
+ return SWIG_OK;
+ } else if (PyLong_Check(obj)) {
+ long v = PyLong_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_OK;
+ } else {
+ PyErr_Clear();
+ }
+ }
+#ifdef SWIG_PYTHON_CAST_MODE
+ {
+ int dispatch = 0;
+ long v = PyInt_AsLong(obj);
+ if (!PyErr_Occurred()) {
+ if (val) *val = v;
+ return SWIG_AddCast(SWIG_OK);
+ } else {
+ PyErr_Clear();
+ }
+ if (!dispatch) {
+ double d;
+ int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d));
+ if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
+ if (val) *val = (long)(d);
+ return res;
+ }
+ }
+ }
+#endif
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_int (PyObject * obj, int *val)
+{
+ long v;
+ int res = SWIG_AsVal_long (obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < INT_MIN || v > INT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = static_cast< int >(v);
+ }
+ }
+ return res;
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+SWIGINTERN PyObject *_wrap_Key_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ PyObject * obj0 = 0 ;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if (!PyArg_ParseTuple(args,(char *)"O:Key_str",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Key_str" "', argument " "1"" of type '" "marisa_swig::Key const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ ((marisa_swig::Key const *)arg1)->str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (*arg2) {
+ resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Key_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Key_id",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Key_id" "', argument " "1"" of type '" "marisa_swig::Key const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Key const *)arg1)->id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Key_weight(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ float result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Key_weight",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Key_weight" "', argument " "1"" of type '" "marisa_swig::Key const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ result = (float)((marisa_swig::Key const *)arg1)->weight();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_float(static_cast< float >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_Key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:delete_Key",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Key, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Key" "', argument " "1"" of type '" "marisa_swig::Key *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *Key_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+ SWIG_TypeNewClientData(SWIGTYPE_p_marisa_swig__Key, SWIG_NewClientData(obj));
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_Query_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ PyObject * obj0 = 0 ;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if (!PyArg_ParseTuple(args,(char *)"O:Query_str",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Query_str" "', argument " "1"" of type '" "marisa_swig::Query const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ ((marisa_swig::Query const *)arg1)->str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (*arg2) {
+ resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Query_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Query_id",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Query_id" "', argument " "1"" of type '" "marisa_swig::Query const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Query const *)arg1)->id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_Query(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:delete_Query",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Query, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Query" "', argument " "1"" of type '" "marisa_swig::Query *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *Query_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+ SWIG_TypeNewClientData(SWIGTYPE_p_marisa_swig__Query, SWIG_NewClientData(obj));
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_Keyset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)":new_Keyset")) SWIG_fail;
+ {
+ try {
+ result = (marisa_swig::Keyset *)new marisa_swig::Keyset();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Keyset, SWIG_POINTER_NEW | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_Keyset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:delete_Keyset",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Keyset" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_push_back__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ marisa::Key *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Keyset_push_back",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_push_back" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa__Key, 0 | 0);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Keyset_push_back" "', argument " "2"" of type '" "marisa::Key const &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Keyset_push_back" "', argument " "2"" of type '" "marisa::Key const &""'");
+ }
+ arg2 = reinterpret_cast< marisa::Key * >(argp2);
+ {
+ try {
+ (arg1)->push_back((marisa::Key const &)*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_push_back__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ float arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ float val4 ;
+ int ecode4 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OOO:Keyset_push_back",&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_push_back" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Keyset_push_back" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ ecode4 = SWIG_AsVal_float(obj2, &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "Keyset_push_back" "', argument " "4"" of type '" "float""'");
+ }
+ arg4 = static_cast< float >(val4);
+ {
+ try {
+ (arg1)->push_back((char const *)arg2,arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_push_back__SWIG_2(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Keyset_push_back",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_push_back" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Keyset_push_back" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ (arg1)->push_back((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_push_back(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[4];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = (int)PyObject_Length(args);
+ for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_ConvertPtr(argv[1], 0, SWIGTYPE_p_marisa__Key, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Keyset_push_back__SWIG_0(self, args);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ if (argc <= 2) {
+ return _wrap_Keyset_push_back__SWIG_2(self, args);
+ }
+ {
+ int res = SWIG_AsVal_size_t(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Keyset_push_back__SWIG_2(self, args);
+ }
+ }
+ }
+ }
+ if (argc == 3) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_float(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Keyset_push_back__SWIG_1(self, args);
+ }
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'Keyset_push_back'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " push_back(marisa_swig::Keyset *,marisa::Key const &)\n"
+ " push_back(marisa_swig::Keyset *,char const *,std::size_t,float)\n"
+ " push_back(marisa_swig::Keyset *,char const *,std::size_t)\n");
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ marisa_swig::Key *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Keyset_key",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_key" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Keyset_key" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ result = (marisa_swig::Key *) &((marisa_swig::Keyset const *)arg1)->key(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_key_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ char **arg3 = (char **) 0 ;
+ std::size_t *arg4 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ char *temp3 = 0 ;
+ std::size_t tempn3 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ arg3 = &temp3; arg4 = &tempn3;
+ if (!PyArg_ParseTuple(args,(char *)"OO:Keyset_key_str",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_key_str" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Keyset_key_str" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ ((marisa_swig::Keyset const *)arg1)->key_str(arg2,(char const **)arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (*arg3) {
+ resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg3,*arg4));
+ ;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_key_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Keyset_key_id",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_key_id" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Keyset_key_id" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->key_id(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_num_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Keyset_num_keys",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_num_keys" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->num_keys();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ bool result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Keyset_empty",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_empty" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = (bool)((marisa_swig::Keyset const *)arg1)->empty();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_bool(static_cast< bool >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Keyset_size",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_size" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_total_length(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Keyset_total_length",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_total_length" "', argument " "1"" of type '" "marisa_swig::Keyset const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->total_length();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_reset(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Keyset_reset",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_reset" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ (arg1)->reset();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Keyset_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Keyset_clear",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Keyset_clear" "', argument " "1"" of type '" "marisa_swig::Keyset *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ (arg1)->clear();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *Keyset_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+ SWIG_TypeNewClientData(SWIGTYPE_p_marisa_swig__Keyset, SWIG_NewClientData(obj));
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_Agent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)":new_Agent")) SWIG_fail;
+ {
+ try {
+ result = (marisa_swig::Agent *)new marisa_swig::Agent();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Agent, SWIG_POINTER_NEW | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_Agent(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:delete_Agent",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Agent" "', argument " "1"" of type '" "marisa_swig::Agent *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_set_query__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Agent_set_query",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_set_query" "', argument " "1"" of type '" "marisa_swig::Agent *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Agent_set_query" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ (arg1)->set_query((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_set_query__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Agent_set_query",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_set_query" "', argument " "1"" of type '" "marisa_swig::Agent *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Agent_set_query" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ (arg1)->set_query(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_set_query(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[3];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = (int)PyObject_Length(args);
+ for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_size_t(argv[1], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Agent_set_query__SWIG_1(self, args);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ if (argc <= 2) {
+ return _wrap_Agent_set_query__SWIG_0(self, args);
+ }
+ {
+ int res = SWIG_AsVal_size_t(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Agent_set_query__SWIG_0(self, args);
+ }
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'Agent_set_query'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " set_query(marisa_swig::Agent *,char const *,std::size_t)\n"
+ " set_query(marisa_swig::Agent *,std::size_t)\n");
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_key(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ marisa_swig::Key *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Agent_key",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_key" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = (marisa_swig::Key *) &((marisa_swig::Agent const *)arg1)->key();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_query(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ marisa_swig::Query *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Agent_query",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_query" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = (marisa_swig::Query *) &((marisa_swig::Agent const *)arg1)->query();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_key_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ PyObject * obj0 = 0 ;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if (!PyArg_ParseTuple(args,(char *)"O:Agent_key_str",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_key_str" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ ((marisa_swig::Agent const *)arg1)->key_str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (*arg2) {
+ resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_key_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Agent_key_id",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_key_id" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Agent const *)arg1)->key_id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_query_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ PyObject * obj0 = 0 ;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if (!PyArg_ParseTuple(args,(char *)"O:Agent_query_str",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_query_str" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ ((marisa_swig::Agent const *)arg1)->query_str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (*arg2) {
+ resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Agent_query_id(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Agent_query_id",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Agent_query_id" "', argument " "1"" of type '" "marisa_swig::Agent const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Agent const *)arg1)->query_id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *Agent_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+ SWIG_TypeNewClientData(SWIGTYPE_p_marisa_swig__Agent, SWIG_NewClientData(obj));
+ return SWIG_Py_Void();
+}
+
+SWIGINTERN PyObject *_wrap_new_Trie(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *result = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)":new_Trie")) SWIG_fail;
+ {
+ try {
+ result = (marisa_swig::Trie *)new marisa_swig::Trie();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Trie, SWIG_POINTER_NEW | 0 );
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_delete_Trie(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:delete_Trie",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, SWIG_POINTER_DISOWN | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "delete_Trie" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ delete arg1;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_build__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Keyset *arg2 = 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ PyObject * obj2 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OOO:Trie_build",&obj0,&obj1,&obj2)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_build" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa_swig__Keyset, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Keyset * >(argp2);
+ ecode3 = SWIG_AsVal_int(obj2, &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "Trie_build" "', argument " "3"" of type '" "int""'");
+ }
+ arg3 = static_cast< int >(val3);
+ {
+ try {
+ (arg1)->build(*arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_build__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Keyset *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_build",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_build" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa_swig__Keyset, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_build" "', argument " "2"" of type '" "marisa_swig::Keyset &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Keyset * >(argp2);
+ {
+ try {
+ (arg1)->build(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_build(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[4];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = (int)PyObject_Length(args);
+ for (ii = 0; (ii < argc) && (ii < 3); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Trie_build__SWIG_1(self, args);
+ }
+ }
+ }
+ if (argc == 3) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_int(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Trie_build__SWIG_0(self, args);
+ }
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'Trie_build'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " build(marisa_swig::Trie *,marisa_swig::Keyset &,int)\n"
+ " build(marisa_swig::Trie *,marisa_swig::Keyset &)\n");
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_mmap(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_mmap",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_mmap" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_mmap" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ (arg1)->mmap((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_load(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_load",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_load" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_load" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ (arg1)->load((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_save(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_save",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_save" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_save" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->save((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_lookup__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ bool result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_lookup",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->lookup(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_bool(static_cast< bool >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_reverse_lookup__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_reverse_lookup",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_reverse_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_reverse_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_reverse_lookup" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->reverse_lookup(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_common_prefix_search(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ bool result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_common_prefix_search",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_common_prefix_search" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_common_prefix_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_common_prefix_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->common_prefix_search(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_bool(static_cast< bool >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_predictive_search(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ bool result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_predictive_search",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_predictive_search" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_predictive_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "Trie_predictive_search" "', argument " "2"" of type '" "marisa_swig::Agent &""'");
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->predictive_search(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_bool(static_cast< bool >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_lookup__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_lookup",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Trie_lookup" "', argument " "2"" of type '" "char const *""'");
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->lookup((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return resultobj;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_lookup(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[3];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = (int)PyObject_Length(args);
+ for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Trie_lookup__SWIG_0(self, args);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ if (argc <= 2) {
+ return _wrap_Trie_lookup__SWIG_1(self, args);
+ }
+ {
+ int res = SWIG_AsVal_size_t(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Trie_lookup__SWIG_1(self, args);
+ }
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'Trie_lookup'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " lookup(marisa_swig::Trie const *,marisa_swig::Agent &)\n"
+ " lookup(marisa_swig::Trie const *,char const *,std::size_t)\n");
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_reverse_lookup__SWIG_1(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ std::size_t arg2 ;
+ char **arg3 = (char **) 0 ;
+ std::size_t *arg4 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ char *temp3 = 0 ;
+ std::size_t tempn3 ;
+ PyObject * obj0 = 0 ;
+ PyObject * obj1 = 0 ;
+
+ arg3 = &temp3; arg4 = &tempn3;
+ if (!PyArg_ParseTuple(args,(char *)"OO:Trie_reverse_lookup",&obj0,&obj1)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_reverse_lookup" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(obj1, &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Trie_reverse_lookup" "', argument " "2"" of type '" "std::size_t""'");
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->reverse_lookup(arg2,(char const **)arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ if (*arg3) {
+ resultobj = SWIG_Python_AppendOutput(resultobj, SWIG_FromCharPtrAndSize(*arg3,*arg4));
+ delete [] (*arg3);
+ }
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_reverse_lookup(PyObject *self, PyObject *args) {
+ int argc;
+ PyObject *argv[3];
+ int ii;
+
+ if (!PyTuple_Check(args)) SWIG_fail;
+ argc = (int)PyObject_Length(args);
+ for (ii = 0; (ii < argc) && (ii < 2); ii++) {
+ argv[ii] = PyTuple_GET_ITEM(args,ii);
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Trie_reverse_lookup__SWIG_0(self, args);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_size_t(argv[1], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Trie_reverse_lookup__SWIG_1(self, args);
+ }
+ }
+ }
+
+fail:
+ SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'Trie_reverse_lookup'.\n"
+ " Possible C/C++ prototypes are:\n"
+ " reverse_lookup(marisa_swig::Trie const *,marisa_swig::Agent &)\n"
+ " reverse_lookup(marisa_swig::Trie const *,std::size_t,char const **,std::size_t *)\n");
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_num_tries(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_num_tries",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_num_tries" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_tries();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_num_keys(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_num_keys",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_num_keys" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_keys();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_num_nodes(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_num_nodes",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_num_nodes" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_nodes();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_tail_mode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ marisa_swig::TailMode result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_tail_mode",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_tail_mode" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (marisa_swig::TailMode)((marisa_swig::Trie const *)arg1)->tail_mode();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_int(static_cast< int >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_node_order(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ marisa_swig::NodeOrder result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_node_order",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_node_order" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (marisa_swig::NodeOrder)((marisa_swig::Trie const *)arg1)->node_order();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_int(static_cast< int >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_empty(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ bool result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_empty",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_empty" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->empty();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_bool(static_cast< bool >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_size",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_size" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_total_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_total_size",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_total_size" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->total_size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_io_size(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+ std::size_t result;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_io_size",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_io_size" "', argument " "1"" of type '" "marisa_swig::Trie const *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->io_size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_From_size_t(static_cast< size_t >(result));
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *_wrap_Trie_clear(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *resultobj = 0;
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ PyObject * obj0 = 0 ;
+
+ if (!PyArg_ParseTuple(args,(char *)"O:Trie_clear",&obj0)) SWIG_fail;
+ res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Trie_clear" "', argument " "1"" of type '" "marisa_swig::Trie *""'");
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ (arg1)->clear();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ resultobj = SWIG_Py_Void();
+ return resultobj;
+fail:
+ return NULL;
+}
+
+
+SWIGINTERN PyObject *Trie_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+ PyObject *obj;
+ if (!PyArg_ParseTuple(args,(char*)"O:swigregister", &obj)) return NULL;
+ SWIG_TypeNewClientData(SWIGTYPE_p_marisa_swig__Trie, SWIG_NewClientData(obj));
+ return SWIG_Py_Void();
+}
+
+static PyMethodDef SwigMethods[] = {
+ { (char *)"SWIG_PyInstanceMethod_New", (PyCFunction)SWIG_PyInstanceMethod_New, METH_O, NULL},
+ { (char *)"Key_str", _wrap_Key_str, METH_VARARGS, NULL},
+ { (char *)"Key_id", _wrap_Key_id, METH_VARARGS, NULL},
+ { (char *)"Key_weight", _wrap_Key_weight, METH_VARARGS, NULL},
+ { (char *)"delete_Key", _wrap_delete_Key, METH_VARARGS, NULL},
+ { (char *)"Key_swigregister", Key_swigregister, METH_VARARGS, NULL},
+ { (char *)"Query_str", _wrap_Query_str, METH_VARARGS, NULL},
+ { (char *)"Query_id", _wrap_Query_id, METH_VARARGS, NULL},
+ { (char *)"delete_Query", _wrap_delete_Query, METH_VARARGS, NULL},
+ { (char *)"Query_swigregister", Query_swigregister, METH_VARARGS, NULL},
+ { (char *)"new_Keyset", _wrap_new_Keyset, METH_VARARGS, NULL},
+ { (char *)"delete_Keyset", _wrap_delete_Keyset, METH_VARARGS, NULL},
+ { (char *)"Keyset_push_back", _wrap_Keyset_push_back, METH_VARARGS, NULL},
+ { (char *)"Keyset_key", _wrap_Keyset_key, METH_VARARGS, NULL},
+ { (char *)"Keyset_key_str", _wrap_Keyset_key_str, METH_VARARGS, NULL},
+ { (char *)"Keyset_key_id", _wrap_Keyset_key_id, METH_VARARGS, NULL},
+ { (char *)"Keyset_num_keys", _wrap_Keyset_num_keys, METH_VARARGS, NULL},
+ { (char *)"Keyset_empty", _wrap_Keyset_empty, METH_VARARGS, NULL},
+ { (char *)"Keyset_size", _wrap_Keyset_size, METH_VARARGS, NULL},
+ { (char *)"Keyset_total_length", _wrap_Keyset_total_length, METH_VARARGS, NULL},
+ { (char *)"Keyset_reset", _wrap_Keyset_reset, METH_VARARGS, NULL},
+ { (char *)"Keyset_clear", _wrap_Keyset_clear, METH_VARARGS, NULL},
+ { (char *)"Keyset_swigregister", Keyset_swigregister, METH_VARARGS, NULL},
+ { (char *)"new_Agent", _wrap_new_Agent, METH_VARARGS, NULL},
+ { (char *)"delete_Agent", _wrap_delete_Agent, METH_VARARGS, NULL},
+ { (char *)"Agent_set_query", _wrap_Agent_set_query, METH_VARARGS, NULL},
+ { (char *)"Agent_key", _wrap_Agent_key, METH_VARARGS, NULL},
+ { (char *)"Agent_query", _wrap_Agent_query, METH_VARARGS, NULL},
+ { (char *)"Agent_key_str", _wrap_Agent_key_str, METH_VARARGS, NULL},
+ { (char *)"Agent_key_id", _wrap_Agent_key_id, METH_VARARGS, NULL},
+ { (char *)"Agent_query_str", _wrap_Agent_query_str, METH_VARARGS, NULL},
+ { (char *)"Agent_query_id", _wrap_Agent_query_id, METH_VARARGS, NULL},
+ { (char *)"Agent_swigregister", Agent_swigregister, METH_VARARGS, NULL},
+ { (char *)"new_Trie", _wrap_new_Trie, METH_VARARGS, NULL},
+ { (char *)"delete_Trie", _wrap_delete_Trie, METH_VARARGS, NULL},
+ { (char *)"Trie_build", _wrap_Trie_build, METH_VARARGS, NULL},
+ { (char *)"Trie_mmap", _wrap_Trie_mmap, METH_VARARGS, NULL},
+ { (char *)"Trie_load", _wrap_Trie_load, METH_VARARGS, NULL},
+ { (char *)"Trie_save", _wrap_Trie_save, METH_VARARGS, NULL},
+ { (char *)"Trie_common_prefix_search", _wrap_Trie_common_prefix_search, METH_VARARGS, NULL},
+ { (char *)"Trie_predictive_search", _wrap_Trie_predictive_search, METH_VARARGS, NULL},
+ { (char *)"Trie_lookup", _wrap_Trie_lookup, METH_VARARGS, NULL},
+ { (char *)"Trie_reverse_lookup", _wrap_Trie_reverse_lookup, METH_VARARGS, NULL},
+ { (char *)"Trie_num_tries", _wrap_Trie_num_tries, METH_VARARGS, NULL},
+ { (char *)"Trie_num_keys", _wrap_Trie_num_keys, METH_VARARGS, NULL},
+ { (char *)"Trie_num_nodes", _wrap_Trie_num_nodes, METH_VARARGS, NULL},
+ { (char *)"Trie_tail_mode", _wrap_Trie_tail_mode, METH_VARARGS, NULL},
+ { (char *)"Trie_node_order", _wrap_Trie_node_order, METH_VARARGS, NULL},
+ { (char *)"Trie_empty", _wrap_Trie_empty, METH_VARARGS, NULL},
+ { (char *)"Trie_size", _wrap_Trie_size, METH_VARARGS, NULL},
+ { (char *)"Trie_total_size", _wrap_Trie_total_size, METH_VARARGS, NULL},
+ { (char *)"Trie_io_size", _wrap_Trie_io_size, METH_VARARGS, NULL},
+ { (char *)"Trie_clear", _wrap_Trie_clear, METH_VARARGS, NULL},
+ { (char *)"Trie_swigregister", Trie_swigregister, METH_VARARGS, NULL},
+ { NULL, NULL, 0, NULL }
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa__Key = {"_p_marisa__Key", "marisa::Key *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Agent = {"_p_marisa_swig__Agent", "marisa_swig::Agent *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Key = {"_p_marisa_swig__Key", "marisa_swig::Key *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Keyset = {"_p_marisa_swig__Keyset", "marisa_swig::Keyset *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Query = {"_p_marisa_swig__Query", "marisa_swig::Query *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Trie = {"_p_marisa_swig__Trie", "marisa_swig::Trie *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__size_t = {"_p_std__size_t", "std::size_t *", 0, 0, (void*)0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+ &_swigt__p_char,
+ &_swigt__p_marisa__Key,
+ &_swigt__p_marisa_swig__Agent,
+ &_swigt__p_marisa_swig__Key,
+ &_swigt__p_marisa_swig__Keyset,
+ &_swigt__p_marisa_swig__Query,
+ &_swigt__p_marisa_swig__Trie,
+ &_swigt__p_p_char,
+ &_swigt__p_std__size_t,
+};
+
+static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa__Key[] = { {&_swigt__p_marisa__Key, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Agent[] = { {&_swigt__p_marisa_swig__Agent, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Key[] = { {&_swigt__p_marisa_swig__Key, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Keyset[] = { {&_swigt__p_marisa_swig__Keyset, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Query[] = { {&_swigt__p_marisa_swig__Query, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Trie[] = { {&_swigt__p_marisa_swig__Trie, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__size_t[] = { {&_swigt__p_std__size_t, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+ _swigc__p_char,
+ _swigc__p_marisa__Key,
+ _swigc__p_marisa_swig__Agent,
+ _swigc__p_marisa_swig__Key,
+ _swigc__p_marisa_swig__Keyset,
+ _swigc__p_marisa_swig__Query,
+ _swigc__p_marisa_swig__Trie,
+ _swigc__p_p_char,
+ _swigc__p_std__size_t,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+static swig_const_info swig_const_table[] = {
+{0, 0, 0, 0.0, 0, 0}};
+
+#ifdef __cplusplus
+}
+#endif
+/* -----------------------------------------------------------------------------
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+ *
+ * The generated swig_type_info structures are assigned staticly to an initial
+ * array. We just loop through that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+ *
+ * First off, we lookup the cast->type name to see if it is already loaded.
+ * There are three cases to handle:
+ * 1) If the cast->type has already been loaded AND the type we are adding
+ * casting info to has not been loaded (it is in this module), THEN we
+ * replace the cast->type pointer with the type pointer that has already
+ * been loaded.
+ * 2) If BOTH types (the one we are adding casting info to, and the
+ * cast->type) are loaded, THEN the cast info has already been loaded by
+ * the previous module so we just ignore it.
+ * 3) Finally, if cast->type has not already been loaded, then we add that
+ * swig_cast_info to the linked list (because the cast->type) pointer will
+ * be correct.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* c-mode */
+#endif
+#endif
+
+#if 0
+#define SWIGRUNTIME_DEBUG
+#endif
+
+
+SWIGRUNTIME void
+SWIG_InitializeModule(void *clientdata) {
+ size_t i;
+ swig_module_info *module_head, *iter;
+ int found, init;
+
+ clientdata = clientdata;
+
+ /* check to see if the circular list has been setup, if not, set it up */
+ if (swig_module.next==0) {
+ /* Initialize the swig_module */
+ swig_module.type_initial = swig_type_initial;
+ swig_module.cast_initial = swig_cast_initial;
+ swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
+ }
+
+ /* Try and load any already created modules */
+ module_head = SWIG_GetModule(clientdata);
+ if (!module_head) {
+ /* This is the first module loaded for this interpreter */
+ /* so set the swig module into the interpreter */
+ SWIG_SetModule(clientdata, &swig_module);
+ module_head = &swig_module;
+ } else {
+ /* the interpreter has loaded a SWIG module, but has it loaded this one? */
+ found=0;
+ iter=module_head;
+ do {
+ if (iter==&swig_module) {
+ found=1;
+ break;
+ }
+ iter=iter->next;
+ } while (iter!= module_head);
+
+ /* if the is found in the list, then all is done and we may leave */
+ if (found) return;
+ /* otherwise we must add out module into the list */
+ swig_module.next = module_head->next;
+ module_head->next = &swig_module;
+ }
+
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
+ /* Now work on filling in swig_module.types */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: size %d\n", swig_module.size);
+#endif
+ for (i = 0; i < swig_module.size; ++i) {
+ swig_type_info *type = 0;
+ swig_type_info *ret;
+ swig_cast_info *cast;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+#endif
+
+ /* if there is another module already loaded */
+ if (swig_module.next != &swig_module) {
+ type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+ }
+ if (type) {
+ /* Overwrite clientdata field */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found type %s\n", type->name);
+#endif
+ if (swig_module.type_initial[i]->clientdata) {
+ type->clientdata = swig_module.type_initial[i]->clientdata;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
+#endif
+ }
+ } else {
+ type = swig_module.type_initial[i];
+ }
+
+ /* Insert casting types */
+ cast = swig_module.cast_initial[i];
+ while (cast->type) {
+ /* Don't need to add information already in the list */
+ ret = 0;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
+#endif
+ if (swig_module.next != &swig_module) {
+ ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
+#endif
+ }
+ if (ret) {
+ if (type == swig_module.type_initial[i]) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
+#endif
+ cast->type = ret;
+ ret = 0;
+ } else {
+ /* Check for casting already in the list */
+ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
+#endif
+ if (!ocast) ret = 0;
+ }
+ }
+
+ if (!ret) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
+#endif
+ if (type->cast) {
+ type->cast->prev = cast;
+ cast->next = type->cast;
+ }
+ type->cast = cast;
+ }
+ cast++;
+ }
+ /* Set entry in modules->types array equal to the type */
+ swig_module.types[i] = type;
+ }
+ swig_module.types[i] = 0;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+ for (i = 0; i < swig_module.size; ++i) {
+ int j = 0;
+ swig_cast_info *cast = swig_module.cast_initial[i];
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+ while (cast->type) {
+ printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
+ cast++;
+ ++j;
+ }
+ printf("---- Total casts: %d\n",j);
+ }
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+#endif
+}
+
+/* This function will propagate the clientdata field of type to
+* any new swig_type_info structures that have been added into the list
+* of equivalent types. It is like calling
+* SWIG_TypeClientData(type, clientdata) a second time.
+*/
+SWIGRUNTIME void
+SWIG_PropagateClientData(void) {
+ size_t i;
+ swig_cast_info *equiv;
+ static int init_run = 0;
+
+ if (init_run) return;
+ init_run = 1;
+
+ for (i = 0; i < swig_module.size; i++) {
+ if (swig_module.types[i]->clientdata) {
+ equiv = swig_module.types[i]->cast;
+ while (equiv) {
+ if (!equiv->converter) {
+ if (equiv->type && !equiv->type->clientdata)
+ SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+ }
+ equiv = equiv->next;
+ }
+ }
+ }
+}
+
+#ifdef __cplusplus
+#if 0
+{
+ /* c-mode */
+#endif
+}
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Python-specific SWIG API */
+#define SWIG_newvarlink() SWIG_Python_newvarlink()
+#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr)
+#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants)
+
+ /* -----------------------------------------------------------------------------
+ * global variable support code.
+ * ----------------------------------------------------------------------------- */
+
+ typedef struct swig_globalvar {
+ char *name; /* Name of global variable */
+ PyObject *(*get_attr)(void); /* Return the current value */
+ int (*set_attr)(PyObject *); /* Set the value */
+ struct swig_globalvar *next;
+ } swig_globalvar;
+
+ typedef struct swig_varlinkobject {
+ PyObject_HEAD
+ swig_globalvar *vars;
+ } swig_varlinkobject;
+
+ SWIGINTERN PyObject *
+ swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
+#if PY_VERSION_HEX >= 0x03000000
+ return PyUnicode_InternFromString("<Swig global variables>");
+#else
+ return PyString_FromString("<Swig global variables>");
+#endif
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_str(swig_varlinkobject *v) {
+#if PY_VERSION_HEX >= 0x03000000
+ PyObject *str = PyUnicode_InternFromString("(");
+ PyObject *tail;
+ PyObject *joined;
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ tail = PyUnicode_FromString(var->name);
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+ if (var->next) {
+ tail = PyUnicode_InternFromString(", ");
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+ }
+ }
+ tail = PyUnicode_InternFromString(")");
+ joined = PyUnicode_Concat(str, tail);
+ Py_DecRef(str);
+ Py_DecRef(tail);
+ str = joined;
+#else
+ PyObject *str = PyString_FromString("(");
+ swig_globalvar *var;
+ for (var = v->vars; var; var=var->next) {
+ PyString_ConcatAndDel(&str,PyString_FromString(var->name));
+ if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
+ }
+ PyString_ConcatAndDel(&str,PyString_FromString(")"));
+#endif
+ return str;
+ }
+
+ SWIGINTERN int
+ swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
+ char *tmp;
+ PyObject *str = swig_varlink_str(v);
+ fprintf(fp,"Swig global variables ");
+ fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(str);
+ return 0;
+ }
+
+ SWIGINTERN void
+ swig_varlink_dealloc(swig_varlinkobject *v) {
+ swig_globalvar *var = v->vars;
+ while (var) {
+ swig_globalvar *n = var->next;
+ free(var->name);
+ free(var);
+ var = n;
+ }
+ }
+
+ SWIGINTERN PyObject *
+ swig_varlink_getattr(swig_varlinkobject *v, char *n) {
+ PyObject *res = NULL;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->get_attr)();
+ break;
+ }
+ var = var->next;
+ }
+ if (res == NULL && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN int
+ swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
+ int res = 1;
+ swig_globalvar *var = v->vars;
+ while (var) {
+ if (strcmp(var->name,n) == 0) {
+ res = (*var->set_attr)(p);
+ break;
+ }
+ var = var->next;
+ }
+ if (res == 1 && !PyErr_Occurred()) {
+ PyErr_SetString(PyExc_NameError,"Unknown C global variable");
+ }
+ return res;
+ }
+
+ SWIGINTERN PyTypeObject*
+ swig_varlink_type(void) {
+ static char varlink__doc__[] = "Swig var link object";
+ static PyTypeObject varlink_type;
+ static int type_init = 0;
+ if (!type_init) {
+ const PyTypeObject tmp
+ = {
+ /* PyObject header changed in Python 3 */
+#if PY_VERSION_HEX >= 0x03000000
+ PyVarObject_HEAD_INIT(&PyType_Type, 0)
+#else
+ PyObject_HEAD_INIT(NULL)
+ 0, /* Number of items in variable part (ob_size) */
+#endif
+ (char *)"swigvarlink", /* Type name (tp_name) */
+ sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */
+ 0, /* Itemsize (tp_itemsize) */
+ (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */
+ (printfunc) swig_varlink_print, /* Print (tp_print) */
+ (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */
+ (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */
+ 0, /* tp_compare */
+ (reprfunc) swig_varlink_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc) swig_varlink_str, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ 0, /* tp_flags */
+ varlink__doc__, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+#if PY_VERSION_HEX >= 0x02020000
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
+#endif
+#if PY_VERSION_HEX >= 0x02030000
+ 0, /* tp_del */
+#endif
+#ifdef COUNT_ALLOCS
+ 0,0,0,0 /* tp_alloc -> tp_next */
+#endif
+ };
+ varlink_type = tmp;
+ /* for Python 3 we already assigned ob_type in PyVarObject_HEAD_INIT() */
+#if PY_VERSION_HEX < 0x03000000
+ varlink_type.ob_type = &PyType_Type;
+#endif
+ type_init = 1;
+ }
+ return &varlink_type;
+ }
+
+ /* Create a variable linking object for use later */
+ SWIGINTERN PyObject *
+ SWIG_Python_newvarlink(void) {
+ swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
+ if (result) {
+ result->vars = 0;
+ }
+ return ((PyObject*) result);
+ }
+
+ SWIGINTERN void
+ SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
+ swig_varlinkobject *v = (swig_varlinkobject *) p;
+ swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
+ if (gv) {
+ size_t size = strlen(name)+1;
+ gv->name = (char *)malloc(size);
+ if (gv->name) {
+ strncpy(gv->name,name,size);
+ gv->get_attr = get_attr;
+ gv->set_attr = set_attr;
+ gv->next = v->vars;
+ }
+ }
+ v->vars = gv;
+ }
+
+ SWIGINTERN PyObject *
+ SWIG_globals(void) {
+ static PyObject *_SWIG_globals = 0;
+ if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink();
+ return _SWIG_globals;
+ }
+
+ /* -----------------------------------------------------------------------------
+ * constants/methods manipulation
+ * ----------------------------------------------------------------------------- */
+
+ /* Install Constants */
+ SWIGINTERN void
+ SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) {
+ PyObject *obj = 0;
+ size_t i;
+ for (i = 0; constants[i].type; ++i) {
+ switch(constants[i].type) {
+ case SWIG_PY_POINTER:
+ obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0);
+ break;
+ case SWIG_PY_BINARY:
+ obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype));
+ break;
+ default:
+ obj = 0;
+ break;
+ }
+ if (obj) {
+ PyDict_SetItemString(d, constants[i].name, obj);
+ Py_DECREF(obj);
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------------*/
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ /* -----------------------------------------------------------------------------*/
+
+ SWIGINTERN void
+ SWIG_Python_FixMethods(PyMethodDef *methods,
+ swig_const_info *const_table,
+ swig_type_info **types,
+ swig_type_info **types_initial) {
+ size_t i;
+ for (i = 0; methods[i].ml_name; ++i) {
+ const char *c = methods[i].ml_doc;
+ if (c && (c = strstr(c, "swig_ptr: "))) {
+ int j;
+ swig_const_info *ci = 0;
+ const char *name = c + 10;
+ for (j = 0; const_table[j].type; ++j) {
+ if (strncmp(const_table[j].name, name,
+ strlen(const_table[j].name)) == 0) {
+ ci = &(const_table[j]);
+ break;
+ }
+ }
+ if (ci) {
+ size_t shift = (ci->ptype) - types;
+ swig_type_info *ty = types_initial[shift];
+ size_t ldoc = (c - methods[i].ml_doc);
+ size_t lptr = strlen(ty->name)+2*sizeof(void*)+2;
+ char *ndoc = (char*)malloc(ldoc + lptr + 10);
+ if (ndoc) {
+ char *buff = ndoc;
+ void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0;
+ if (ptr) {
+ strncpy(buff, methods[i].ml_doc, ldoc);
+ buff += ldoc;
+ strncpy(buff, "swig_ptr: ", 10);
+ buff += 10;
+ SWIG_PackVoidPtr(buff, ptr, ty->name, lptr);
+ methods[i].ml_doc = ndoc;
+ }
+ }
+ }
+ }
+ }
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+/* -----------------------------------------------------------------------------*
+ * Partial Init method
+ * -----------------------------------------------------------------------------*/
+
+#ifdef __cplusplus
+extern "C"
+#endif
+
+SWIGEXPORT
+#if PY_VERSION_HEX >= 0x03000000
+PyObject*
+#else
+void
+#endif
+SWIG_init(void) {
+ PyObject *m, *d;
+#if PY_VERSION_HEX >= 0x03000000
+ static struct PyModuleDef SWIG_module = {
+ PyModuleDef_HEAD_INIT,
+ (char *) SWIG_name,
+ NULL,
+ -1,
+ SwigMethods,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+#endif
+
+ /* Fix SwigMethods to carry the callback ptrs when needed */
+ SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
+
+#if PY_VERSION_HEX >= 0x03000000
+ m = PyModule_Create(&SWIG_module);
+#else
+ m = Py_InitModule((char *) SWIG_name, SwigMethods);
+#endif
+ d = PyModule_GetDict(m);
+
+ SWIG_InitializeModule(0);
+ SWIG_InstallConstants(d,swig_const_table);
+
+
+ SWIG_Python_SetConstant(d, "OK",SWIG_From_int(static_cast< int >(marisa_swig::OK)));
+ SWIG_Python_SetConstant(d, "STATE_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::STATE_ERROR)));
+ SWIG_Python_SetConstant(d, "NULL_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::NULL_ERROR)));
+ SWIG_Python_SetConstant(d, "BOUND_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::BOUND_ERROR)));
+ SWIG_Python_SetConstant(d, "RANGE_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::RANGE_ERROR)));
+ SWIG_Python_SetConstant(d, "CODE_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::CODE_ERROR)));
+ SWIG_Python_SetConstant(d, "RESET_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::RESET_ERROR)));
+ SWIG_Python_SetConstant(d, "SIZE_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::SIZE_ERROR)));
+ SWIG_Python_SetConstant(d, "MEMORY_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::MEMORY_ERROR)));
+ SWIG_Python_SetConstant(d, "IO_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::IO_ERROR)));
+ SWIG_Python_SetConstant(d, "FORMAT_ERROR",SWIG_From_int(static_cast< int >(marisa_swig::FORMAT_ERROR)));
+ SWIG_Python_SetConstant(d, "MIN_NUM_TRIES",SWIG_From_int(static_cast< int >(marisa_swig::MIN_NUM_TRIES)));
+ SWIG_Python_SetConstant(d, "MAX_NUM_TRIES",SWIG_From_int(static_cast< int >(marisa_swig::MAX_NUM_TRIES)));
+ SWIG_Python_SetConstant(d, "DEFAULT_NUM_TRIES",SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_NUM_TRIES)));
+ SWIG_Python_SetConstant(d, "HUGE_CACHE",SWIG_From_int(static_cast< int >(marisa_swig::HUGE_CACHE)));
+ SWIG_Python_SetConstant(d, "LARGE_CACHE",SWIG_From_int(static_cast< int >(marisa_swig::LARGE_CACHE)));
+ SWIG_Python_SetConstant(d, "NORMAL_CACHE",SWIG_From_int(static_cast< int >(marisa_swig::NORMAL_CACHE)));
+ SWIG_Python_SetConstant(d, "SMALL_CACHE",SWIG_From_int(static_cast< int >(marisa_swig::SMALL_CACHE)));
+ SWIG_Python_SetConstant(d, "TINY_CACHE",SWIG_From_int(static_cast< int >(marisa_swig::TINY_CACHE)));
+ SWIG_Python_SetConstant(d, "DEFAULT_CACHE",SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_CACHE)));
+ SWIG_Python_SetConstant(d, "TEXT_TAIL",SWIG_From_int(static_cast< int >(marisa_swig::TEXT_TAIL)));
+ SWIG_Python_SetConstant(d, "BINARY_TAIL",SWIG_From_int(static_cast< int >(marisa_swig::BINARY_TAIL)));
+ SWIG_Python_SetConstant(d, "DEFAULT_TAIL",SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_TAIL)));
+ SWIG_Python_SetConstant(d, "LABEL_ORDER",SWIG_From_int(static_cast< int >(marisa_swig::LABEL_ORDER)));
+ SWIG_Python_SetConstant(d, "WEIGHT_ORDER",SWIG_From_int(static_cast< int >(marisa_swig::WEIGHT_ORDER)));
+ SWIG_Python_SetConstant(d, "DEFAULT_ORDER",SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_ORDER)));
+ SWIG_Python_SetConstant(d, "INVALID_KEY_ID",SWIG_From_size_t(static_cast< size_t >(MARISA_INVALID_KEY_ID)));
+#if PY_VERSION_HEX >= 0x03000000
+ return m;
+#else
+ return;
+#endif
+}
+
diff --git a/bindings/python/marisa.py b/bindings/python/marisa.py
new file mode 100644
index 0000000..5859a21
--- /dev/null
+++ b/bindings/python/marisa.py
@@ -0,0 +1,206 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 1.3.40
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+# This file is compatible with both classic and new-style classes.
+
+from sys import version_info
+if version_info >= (2,6,0):
+ def swig_import_helper():
+ from os.path import dirname
+ import imp
+ fp = None
+ try:
+ fp, pathname, description = imp.find_module('_marisa', [dirname(__file__)])
+ except ImportError:
+ import _marisa
+ return _marisa
+ if fp is not None:
+ try:
+ _mod = imp.load_module('_marisa', fp, pathname, description)
+ finally:
+ fp.close()
+ return _mod
+ _marisa = swig_import_helper()
+ del swig_import_helper
+else:
+ import _marisa
+del version_info
+try:
+ _swig_property = property
+except NameError:
+ pass # Python < 2.2 doesn't have 'property'.
+def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
+ if (name == "thisown"): return self.this.own(value)
+ if (name == "this"):
+ if type(value).__name__ == 'SwigPyObject':
+ self.__dict__[name] = value
+ return
+ method = class_type.__swig_setmethods__.get(name,None)
+ if method: return method(self,value)
+ if (not static) or hasattr(self,name):
+ self.__dict__[name] = value
+ else:
+ raise AttributeError("You cannot add attributes to %s" % self)
+
+def _swig_setattr(self,class_type,name,value):
+ return _swig_setattr_nondynamic(self,class_type,name,value,0)
+
+def _swig_getattr(self,class_type,name):
+ if (name == "thisown"): return self.this.own()
+ method = class_type.__swig_getmethods__.get(name,None)
+ if method: return method(self)
+ raise AttributeError(name)
+
+def _swig_repr(self):
+ try: strthis = "proxy of " + self.this.__repr__()
+ except: strthis = ""
+ return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+try:
+ _object = object
+ _newclass = 1
+except AttributeError:
+ class _object : pass
+ _newclass = 0
+
+
+OK = _marisa.OK
+STATE_ERROR = _marisa.STATE_ERROR
+NULL_ERROR = _marisa.NULL_ERROR
+BOUND_ERROR = _marisa.BOUND_ERROR
+RANGE_ERROR = _marisa.RANGE_ERROR
+CODE_ERROR = _marisa.CODE_ERROR
+RESET_ERROR = _marisa.RESET_ERROR
+SIZE_ERROR = _marisa.SIZE_ERROR
+MEMORY_ERROR = _marisa.MEMORY_ERROR
+IO_ERROR = _marisa.IO_ERROR
+FORMAT_ERROR = _marisa.FORMAT_ERROR
+MIN_NUM_TRIES = _marisa.MIN_NUM_TRIES
+MAX_NUM_TRIES = _marisa.MAX_NUM_TRIES
+DEFAULT_NUM_TRIES = _marisa.DEFAULT_NUM_TRIES
+HUGE_CACHE = _marisa.HUGE_CACHE
+LARGE_CACHE = _marisa.LARGE_CACHE
+NORMAL_CACHE = _marisa.NORMAL_CACHE
+SMALL_CACHE = _marisa.SMALL_CACHE
+TINY_CACHE = _marisa.TINY_CACHE
+DEFAULT_CACHE = _marisa.DEFAULT_CACHE
+TEXT_TAIL = _marisa.TEXT_TAIL
+BINARY_TAIL = _marisa.BINARY_TAIL
+DEFAULT_TAIL = _marisa.DEFAULT_TAIL
+LABEL_ORDER = _marisa.LABEL_ORDER
+WEIGHT_ORDER = _marisa.WEIGHT_ORDER
+DEFAULT_ORDER = _marisa.DEFAULT_ORDER
+class Key(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, Key, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, Key, name)
+ def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined")
+ __repr__ = _swig_repr
+ def str(self): return _marisa.Key_str(self)
+ def id(self): return _marisa.Key_id(self)
+ def weight(self): return _marisa.Key_weight(self)
+ __swig_destroy__ = _marisa.delete_Key
+ __del__ = lambda self : None;
+Key_swigregister = _marisa.Key_swigregister
+Key_swigregister(Key)
+
+class Query(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, Query, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, Query, name)
+ def __init__(self, *args, **kwargs): raise AttributeError("No constructor defined")
+ __repr__ = _swig_repr
+ def str(self): return _marisa.Query_str(self)
+ def id(self): return _marisa.Query_id(self)
+ __swig_destroy__ = _marisa.delete_Query
+ __del__ = lambda self : None;
+Query_swigregister = _marisa.Query_swigregister
+Query_swigregister(Query)
+
+class Keyset(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, Keyset, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, Keyset, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _marisa.new_Keyset()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _marisa.delete_Keyset
+ __del__ = lambda self : None;
+ def push_back(self, *args): return _marisa.Keyset_push_back(self, *args)
+ def key(self, *args): return _marisa.Keyset_key(self, *args)
+ def key_str(self, *args): return _marisa.Keyset_key_str(self, *args)
+ def key_id(self, *args): return _marisa.Keyset_key_id(self, *args)
+ def num_keys(self): return _marisa.Keyset_num_keys(self)
+ def empty(self): return _marisa.Keyset_empty(self)
+ def size(self): return _marisa.Keyset_size(self)
+ def total_length(self): return _marisa.Keyset_total_length(self)
+ def reset(self): return _marisa.Keyset_reset(self)
+ def clear(self): return _marisa.Keyset_clear(self)
+Keyset_swigregister = _marisa.Keyset_swigregister
+Keyset_swigregister(Keyset)
+
+class Agent(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, Agent, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, Agent, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _marisa.new_Agent()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _marisa.delete_Agent
+ __del__ = lambda self : None;
+ def set_query(self, *args): return _marisa.Agent_set_query(self, *args)
+ def key(self): return _marisa.Agent_key(self)
+ def query(self): return _marisa.Agent_query(self)
+ def key_str(self): return _marisa.Agent_key_str(self)
+ def key_id(self): return _marisa.Agent_key_id(self)
+ def query_str(self): return _marisa.Agent_query_str(self)
+ def query_id(self): return _marisa.Agent_query_id(self)
+Agent_swigregister = _marisa.Agent_swigregister
+Agent_swigregister(Agent)
+
+class Trie(_object):
+ __swig_setmethods__ = {}
+ __setattr__ = lambda self, name, value: _swig_setattr(self, Trie, name, value)
+ __swig_getmethods__ = {}
+ __getattr__ = lambda self, name: _swig_getattr(self, Trie, name)
+ __repr__ = _swig_repr
+ def __init__(self):
+ this = _marisa.new_Trie()
+ try: self.this.append(this)
+ except: self.this = this
+ __swig_destroy__ = _marisa.delete_Trie
+ __del__ = lambda self : None;
+ def build(self, *args): return _marisa.Trie_build(self, *args)
+ def mmap(self, *args): return _marisa.Trie_mmap(self, *args)
+ def load(self, *args): return _marisa.Trie_load(self, *args)
+ def save(self, *args): return _marisa.Trie_save(self, *args)
+ def common_prefix_search(self, *args): return _marisa.Trie_common_prefix_search(self, *args)
+ def predictive_search(self, *args): return _marisa.Trie_predictive_search(self, *args)
+ def lookup(self, *args): return _marisa.Trie_lookup(self, *args)
+ def reverse_lookup(self, *args): return _marisa.Trie_reverse_lookup(self, *args)
+ def num_tries(self): return _marisa.Trie_num_tries(self)
+ def num_keys(self): return _marisa.Trie_num_keys(self)
+ def num_nodes(self): return _marisa.Trie_num_nodes(self)
+ def tail_mode(self): return _marisa.Trie_tail_mode(self)
+ def node_order(self): return _marisa.Trie_node_order(self)
+ def empty(self): return _marisa.Trie_empty(self)
+ def size(self): return _marisa.Trie_size(self)
+ def total_size(self): return _marisa.Trie_total_size(self)
+ def io_size(self): return _marisa.Trie_io_size(self)
+ def clear(self): return _marisa.Trie_clear(self)
+Trie_swigregister = _marisa.Trie_swigregister
+Trie_swigregister(Trie)
+
+INVALID_KEY_ID = _marisa.INVALID_KEY_ID
+
+
diff --git a/bindings/python/sample.py b/bindings/python/sample.py
new file mode 100644
index 0000000..f3261e7
--- /dev/null
+++ b/bindings/python/sample.py
@@ -0,0 +1,57 @@
+import marisa
+
+keyset = marisa.Keyset()
+keyset.push_back("cake")
+keyset.push_back("cookie")
+keyset.push_back("ice")
+keyset.push_back("ice-cream")
+
+trie = marisa.Trie()
+trie.build(keyset)
+print("no. keys: %d" % trie.num_keys())
+print("no. tries: %d" % trie.num_tries())
+print("no. nodes: %d" % trie.num_nodes())
+print("size: %d" % trie.io_size())
+
+agent = marisa.Agent()
+
+agent.set_query("cake")
+trie.lookup(agent)
+print("%s: %d" % (agent.query_str(), agent.key_id()))
+
+agent.set_query("cookie")
+trie.lookup(agent)
+print("%s: %d" % (agent.query_str(), agent.key_id()))
+
+agent.set_query("cockoo")
+if not trie.lookup(agent):
+ print("%s: not found" % agent.query_str())
+
+print("ice: %d" % trie.lookup("ice"))
+print("ice-cream: %d" % trie.lookup("ice-cream"))
+if trie.lookup("ice-age") == marisa.INVALID_KEY_ID:
+ print("ice-age: not found")
+
+trie.save("sample.dic")
+trie.load("sample.dic")
+
+agent.set_query(0)
+trie.reverse_lookup(agent)
+print("%d: %s" % (agent.query_id(), agent.key_str()))
+
+agent.set_query(1)
+trie.reverse_lookup(agent)
+print("%d: %s" % (agent.query_id(), agent.key_str()))
+
+print("2: %s" % trie.reverse_lookup(2))
+print("3: %s" % trie.reverse_lookup(3))
+
+trie.mmap("sample.dic")
+
+agent.set_query("ice-cream soda")
+while trie.common_prefix_search(agent):
+ print("%s: %s (%d)" % (agent.query_str(), agent.key_str(), agent.key_id()))
+
+agent.set_query("ic")
+while trie.predictive_search(agent):
+ print("%s: %s (%d)" % (agent.query_str(), agent.key_str(), agent.key_id()))
diff --git a/bindings/python/setup.py b/bindings/python/setup.py
new file mode 100644
index 0000000..402226f
--- /dev/null
+++ b/bindings/python/setup.py
@@ -0,0 +1,9 @@
+from distutils.core import setup, Extension
+
+marisa_module = Extension("_marisa",
+ sources=["marisa-swig_wrap.cxx", "marisa-swig.cxx"],
+ libraries=["marisa"])
+
+setup(name = "marisa",
+ ext_modules = [marisa_module],
+ py_modules = ["marisa"])
diff --git a/bindings/ruby/benchmark.rb b/bindings/ruby/benchmark.rb
new file mode 100644
index 0000000..481fe73
--- /dev/null
+++ b/bindings/ruby/benchmark.rb
@@ -0,0 +1,90 @@
+require "marisa"
+
+time_begin = Time.now
+keys = STDIN.read.split("\n")
+time_end = Time.now
+print "input: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+hash = Hash.new
+for key in keys
+ hash[key] = 0
+end
+time_end = Time.now
+print "hash_build: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+hash = Hash.new
+for key in keys
+ hash[key]
+end
+time_end = Time.now
+print "hash_lookup: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+keyset = Marisa::Keyset.new
+for key in keys
+ keyset.push_back(key)
+end
+time_end = Time.now
+print "keyset_build: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+trie = Marisa::Trie.new
+trie.build(keyset)
+time_end = Time.now
+print "trie_build: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+agent = Marisa::Agent.new
+for key in keys
+ agent.set_query(key)
+ trie.lookup(agent)
+ agent.key_str
+end
+time_end = Time.now
+print "trie_agent_lookup: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+for key in keys
+ trie.lookup(key)
+end
+time_end = Time.now
+print "trie_lookup: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+max_key_id = trie.size() - 1
+0.upto(max_key_id) { |i|
+ agent.set_query(i)
+ trie.reverse_lookup(agent)
+ agent.key_str
+}
+time_end = Time.now
+print "trie_agent_reverse_lookup: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+0.upto(max_key_id) { |i|
+ trie.reverse_lookup(i)
+}
+time_end = Time.now
+print "trie_reverse_lookup: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+for key in keys
+ agent.set_query(key)
+ while trie.common_prefix_search(agent)
+ agent.key_str
+ end
+end
+time_end = Time.now
+print "trie_agent_common_prefix_search: ", time_end - time_begin, "\n"
+
+time_begin = Time.now
+for key in keys
+ agent.set_query(key)
+ while trie.predictive_search(agent)
+ agent.key_str
+ end
+end
+time_end = Time.now
+print "trie_agent_predictive_search: ", time_end - time_begin, "\n"
diff --git a/bindings/ruby/extconf.rb b/bindings/ruby/extconf.rb
new file mode 100644
index 0000000..0a7b8a8
--- /dev/null
+++ b/bindings/ruby/extconf.rb
@@ -0,0 +1,5 @@
+require "mkmf"
+
+have_library("marisa")
+
+create_makefile("marisa")
diff --git a/bindings/ruby/marisa-swig.cxx b/bindings/ruby/marisa-swig.cxx
new file mode 100644
index 0000000..281ccb2
--- /dev/null
+++ b/bindings/ruby/marisa-swig.cxx
@@ -0,0 +1,253 @@
+#include <cstring>
+#include <new>
+
+#include "marisa-swig.h"
+
+namespace marisa_swig {
+
+void Key::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = key_.ptr();
+ *length_out = key_.length();
+}
+
+size_t Key::id() const {
+ return key_.id();
+}
+
+float Key::weight() const {
+ return key_.weight();
+}
+
+void Query::str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = query_.ptr();
+ *length_out = query_.length();
+}
+
+size_t Query::id() const {
+ return query_.id();
+}
+
+Keyset::Keyset() : keyset_(new (std::nothrow) marisa::Keyset) {
+ MARISA_THROW_IF(keyset_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Keyset::~Keyset() {
+ delete keyset_;
+}
+
+void Keyset::push_back(const marisa::Key &key) {
+ keyset_->push_back(key);
+}
+
+void Keyset::push_back(const char *ptr, size_t length, float weight) {
+ keyset_->push_back(ptr, length, weight);
+}
+
+const Key &Keyset::key(size_t i) const {
+ return reinterpret_cast<const Key &>((*keyset_)[i]);
+}
+
+void Keyset::key_str(size_t i,
+ const char **ptr_out, size_t *length_out) const {
+ *ptr_out = (*keyset_)[i].ptr();
+ *length_out = (*keyset_)[i].length();
+}
+
+size_t Keyset::key_id(size_t i) const {
+ return (*keyset_)[i].id();
+}
+
+size_t Keyset::num_keys() const {
+ return keyset_->num_keys();
+}
+
+bool Keyset::empty() const {
+ return keyset_->empty();
+}
+
+size_t Keyset::size() const {
+ return keyset_->size();
+}
+
+size_t Keyset::total_length() const {
+ return keyset_->total_length();
+}
+
+void Keyset::reset() {
+ keyset_->reset();
+}
+
+void Keyset::clear() {
+ keyset_->clear();
+}
+
+Agent::Agent()
+ : agent_(new (std::nothrow) marisa::Agent), buf_(NULL), buf_size_(0) {
+ MARISA_THROW_IF(agent_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Agent::~Agent() {
+ delete agent_;
+ delete [] buf_;
+}
+
+void Agent::set_query(const char *ptr, size_t length) {
+ if (length > buf_size_) {
+ size_t new_buf_size = (buf_size_ != 0) ? buf_size_ : 1;
+ if (length >= (MARISA_SIZE_MAX / 2)) {
+ new_buf_size = MARISA_SIZE_MAX;
+ } else {
+ while (new_buf_size < length) {
+ new_buf_size *= 2;
+ }
+ }
+ char *new_buf = new (std::nothrow) char[new_buf_size];
+ MARISA_THROW_IF(new_buf == NULL, MARISA_MEMORY_ERROR);
+ delete [] buf_;
+ buf_ = new_buf;
+ buf_size_ = new_buf_size;
+ }
+ std::memcpy(buf_, ptr, length);
+ agent_->set_query(buf_, length);
+}
+
+void Agent::set_query(size_t id) {
+ agent_->set_query(id);
+}
+
+const Key &Agent::key() const {
+ return reinterpret_cast<const Key &>(agent_->key());
+}
+
+const Query &Agent::query() const {
+ return reinterpret_cast<const Query &>(agent_->query());
+}
+
+void Agent::key_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->key().ptr();
+ *length_out = agent_->key().length();
+}
+
+size_t Agent::key_id() const {
+ return agent_->key().id();
+}
+
+void Agent::query_str(const char **ptr_out, size_t *length_out) const {
+ *ptr_out = agent_->query().ptr();
+ *length_out = agent_->query().length();
+}
+
+size_t Agent::query_id() const {
+ return agent_->query().id();
+}
+
+Trie::Trie() : trie_(new (std::nothrow) marisa::Trie) {
+ MARISA_THROW_IF(trie_ == NULL, ::MARISA_MEMORY_ERROR);
+}
+
+Trie::~Trie() {
+ delete trie_;
+}
+
+void Trie::build(Keyset &keyset, int config_flags) {
+ trie_->build(*keyset.keyset_, config_flags);
+}
+
+void Trie::mmap(const char *filename) {
+ trie_->mmap(filename);
+}
+
+void Trie::load(const char *filename) {
+ trie_->load(filename);
+}
+
+void Trie::save(const char *filename) const {
+ trie_->save(filename);
+}
+
+bool Trie::lookup(Agent &agent) const {
+ return trie_->lookup(*agent.agent_);
+}
+
+void Trie::reverse_lookup(Agent &agent) const {
+ trie_->reverse_lookup(*agent.agent_);
+}
+
+bool Trie::common_prefix_search(Agent &agent) const {
+ return trie_->common_prefix_search(*agent.agent_);
+}
+
+bool Trie::predictive_search(Agent &agent) const {
+ return trie_->predictive_search(*agent.agent_);
+}
+
+size_t Trie::lookup(const char *ptr, size_t length) const {
+ marisa::Agent agent;
+ agent.set_query(ptr, length);
+ if (!trie_->lookup(agent)) {
+ return MARISA_INVALID_KEY_ID;
+ }
+ return agent.key().id();
+}
+
+void Trie::reverse_lookup(size_t id,
+ const char **ptr_out_to_be_deleted, size_t *length_out) const {
+ marisa::Agent agent;
+ agent.set_query(id);
+ trie_->reverse_lookup(agent);
+ char * const buf = new (std::nothrow) char[agent.key().length()];
+ MARISA_THROW_IF(buf == NULL, MARISA_MEMORY_ERROR);
+ std::memcpy(buf, agent.key().ptr(), agent.key().length());
+ *ptr_out_to_be_deleted = buf;
+ *length_out = agent.key().length();
+}
+
+size_t Trie::num_tries() const {
+ return trie_->num_tries();
+}
+
+size_t Trie::num_keys() const {
+ return trie_->num_keys();
+}
+
+size_t Trie::num_nodes() const {
+ return trie_->num_nodes();
+}
+
+TailMode Trie::tail_mode() const {
+ if (trie_->tail_mode() == ::MARISA_TEXT_TAIL) {
+ return TEXT_TAIL;
+ } else {
+ return BINARY_TAIL;
+ }
+}
+
+NodeOrder Trie::node_order() const {
+ if (trie_->node_order() == ::MARISA_LABEL_ORDER) {
+ return LABEL_ORDER;
+ } else {
+ return WEIGHT_ORDER;
+ }
+}
+
+bool Trie::empty() const {
+ return trie_->empty();
+}
+
+size_t Trie::size() const {
+ return trie_->size();
+}
+
+size_t Trie::total_size() const {
+ return trie_->total_size();
+}
+
+size_t Trie::io_size() const {
+ return trie_->io_size();
+}
+
+void Trie::clear() {
+ trie_->clear();
+}
+
+} // namespace marisa_swig
diff --git a/bindings/ruby/marisa-swig.h b/bindings/ruby/marisa-swig.h
new file mode 100644
index 0000000..f09a9a7
--- /dev/null
+++ b/bindings/ruby/marisa-swig.h
@@ -0,0 +1,183 @@
+#ifndef MARISA_SWIG_H_
+#define MARISA_SWIG_H_
+
+#include <marisa.h>
+
+namespace marisa_swig {
+
+#define MARISA_SWIG_ENUM_COPY(name) name = MARISA_ ## name
+
+enum ErrorCode {
+ MARISA_SWIG_ENUM_COPY(OK),
+ MARISA_SWIG_ENUM_COPY(STATE_ERROR),
+ MARISA_SWIG_ENUM_COPY(NULL_ERROR),
+ MARISA_SWIG_ENUM_COPY(BOUND_ERROR),
+ MARISA_SWIG_ENUM_COPY(RANGE_ERROR),
+ MARISA_SWIG_ENUM_COPY(CODE_ERROR),
+ MARISA_SWIG_ENUM_COPY(RESET_ERROR),
+ MARISA_SWIG_ENUM_COPY(SIZE_ERROR),
+ MARISA_SWIG_ENUM_COPY(MEMORY_ERROR),
+ MARISA_SWIG_ENUM_COPY(IO_ERROR),
+ MARISA_SWIG_ENUM_COPY(FORMAT_ERROR)
+};
+
+enum NumTries {
+ MARISA_SWIG_ENUM_COPY(MIN_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(MAX_NUM_TRIES),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_NUM_TRIES)
+};
+
+enum CacheLevel {
+ MARISA_SWIG_ENUM_COPY(HUGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(LARGE_CACHE),
+ MARISA_SWIG_ENUM_COPY(NORMAL_CACHE),
+ MARISA_SWIG_ENUM_COPY(SMALL_CACHE),
+ MARISA_SWIG_ENUM_COPY(TINY_CACHE),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_CACHE)
+};
+
+enum TailMode {
+ MARISA_SWIG_ENUM_COPY(TEXT_TAIL),
+ MARISA_SWIG_ENUM_COPY(BINARY_TAIL),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_TAIL)
+};
+
+enum NodeOrder {
+ MARISA_SWIG_ENUM_COPY(LABEL_ORDER),
+ MARISA_SWIG_ENUM_COPY(WEIGHT_ORDER),
+ MARISA_SWIG_ENUM_COPY(DEFAULT_ORDER)
+};
+
+#undef MARISA_SWIG_ENUM_COPY
+
+class Key {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+ float weight() const;
+
+ private:
+ const marisa::Key key_;
+
+ Key();
+ Key(const Key &key);
+ Key &operator=(const Key &);
+};
+
+class Query {
+ public:
+ void str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t id() const;
+
+ private:
+ const marisa::Query query_;
+
+ Query();
+ Query(const Query &query);
+ Query &operator=(const Query &);
+};
+
+class Keyset {
+ friend class Trie;
+
+ public:
+ Keyset();
+ ~Keyset();
+
+ void push_back(const marisa::Key &key);
+ void push_back(const char *ptr, std::size_t length, float weight = 1.0);
+
+ const Key &key(std::size_t i) const;
+
+ void key_str(std::size_t i,
+ const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id(std::size_t i) const;
+
+ std::size_t num_keys() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_length() const;
+
+ void reset();
+ void clear();
+
+ private:
+ marisa::Keyset *keyset_;
+
+ Keyset(const Keyset &);
+ Keyset &operator=(const Keyset &);
+};
+
+class Agent {
+ friend class Trie;
+
+ public:
+ Agent();
+ ~Agent();
+
+ void set_query(const char *ptr, std::size_t length);
+ void set_query(std::size_t id);
+
+ const Key &key() const;
+ const Query &query() const;
+
+ void key_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t key_id() const;
+
+ void query_str(const char **ptr_out, std::size_t *length_out) const;
+ std::size_t query_id() const;
+
+ private:
+ marisa::Agent *agent_;
+ char *buf_;
+ std::size_t buf_size_;
+
+ Agent(const Agent &);
+ Agent &operator=(const Agent &);
+};
+
+class Trie {
+ public:
+ Trie();
+ ~Trie();
+
+ void build(Keyset &keyset, int config_flags = 0);
+
+ void mmap(const char *filename);
+ void load(const char *filename);
+ void save(const char *filename) const;
+
+ bool lookup(Agent &agent) const;
+ void reverse_lookup(Agent &agent) const;
+ bool common_prefix_search(Agent &agent) const;
+ bool predictive_search(Agent &agent) const;
+
+ std::size_t lookup(const char *ptr, std::size_t length) const;
+ void reverse_lookup(std::size_t id,
+ const char **ptr_out_to_be_deleted, std::size_t *length_out) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_size() const;
+ std::size_t io_size() const;
+
+ void clear();
+
+ private:
+ marisa::Trie *trie_;
+
+ Trie(const Trie &);
+ Trie &operator=(const Trie &);
+};
+
+} // namespace marisa_swig
+
+#endif // MARISA_SWIG_H_
diff --git a/bindings/ruby/marisa-swig_wrap.cxx b/bindings/ruby/marisa-swig_wrap.cxx
new file mode 100644
index 0000000..eae2304
--- /dev/null
+++ b/bindings/ruby/marisa-swig_wrap.cxx
@@ -0,0 +1,4708 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 1.3.40
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+#define SWIGRUBY
+
+
+#ifdef __cplusplus
+/* SwigValueWrapper is described in swig.swg */
+template<typename T> class SwigValueWrapper {
+ struct SwigMovePointer {
+ T *ptr;
+ SwigMovePointer(T *p) : ptr(p) { }
+ ~SwigMovePointer() { delete ptr; }
+ SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+ } pointer;
+ SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
+ SwigValueWrapper(const SwigValueWrapper<T>& rhs);
+public:
+ SwigValueWrapper() : pointer(0) { }
+ SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+ operator T&() const { return *pointer.ptr; }
+ T *operator&() { return pointer.ptr; }
+};
+
+template <typename T> T SwigValueInit() {
+ return T();
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+# pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * This section contains generic SWIG labels for method/variable
+ * declarations/attributes, and other compiler dependent labels.
+ * ----------------------------------------------------------------------------- */
+
+/* template workaround for compilers that cannot correctly implement the C++ standard */
+#ifndef SWIGTEMPLATEDISAMBIGUATOR
+# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560)
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# elif defined(__HP_aCC)
+/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */
+/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */
+# define SWIGTEMPLATEDISAMBIGUATOR template
+# else
+# define SWIGTEMPLATEDISAMBIGUATOR
+# endif
+#endif
+
+/* inline attribute */
+#ifndef SWIGINLINE
+# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__))
+# define SWIGINLINE inline
+# else
+# define SWIGINLINE
+# endif
+#endif
+
+/* attribute recognised by some compilers to avoid 'unused' warnings */
+#ifndef SWIGUNUSED
+# if defined(__GNUC__)
+# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+# elif defined(__ICC)
+# define SWIGUNUSED __attribute__ ((__unused__))
+# else
+# define SWIGUNUSED
+# endif
+#endif
+
+#ifndef SWIG_MSC_UNSUPPRESS_4505
+# if defined(_MSC_VER)
+# pragma warning(disable : 4505) /* unreferenced local function has been removed */
+# endif
+#endif
+
+#ifndef SWIGUNUSEDPARM
+# ifdef __cplusplus
+# define SWIGUNUSEDPARM(p)
+# else
+# define SWIGUNUSEDPARM(p) p SWIGUNUSED
+# endif
+#endif
+
+/* internal SWIG method */
+#ifndef SWIGINTERN
+# define SWIGINTERN static SWIGUNUSED
+#endif
+
+/* internal inline SWIG method */
+#ifndef SWIGINTERNINLINE
+# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE
+#endif
+
+/* exporting methods */
+#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# ifndef GCC_HASCLASSVISIBILITY
+# define GCC_HASCLASSVISIBILITY
+# endif
+#endif
+
+#ifndef SWIGEXPORT
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# if defined(STATIC_LINKED)
+# define SWIGEXPORT
+# else
+# define SWIGEXPORT __declspec(dllexport)
+# endif
+# else
+# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY)
+# define SWIGEXPORT __attribute__ ((visibility("default")))
+# else
+# define SWIGEXPORT
+# endif
+# endif
+#endif
+
+/* calling conventions for Windows */
+#ifndef SWIGSTDCALL
+# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+# define SWIGSTDCALL __stdcall
+# else
+# define SWIGSTDCALL
+# endif
+#endif
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * swigrun.swg
+ *
+ * This file contains generic C API SWIG runtime support for pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* This should only be incremented when either the layout of swig_type_info changes,
+ or for whatever reason, the runtime changes incompatibly */
+#define SWIG_RUNTIME_VERSION "4"
+
+/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */
+#ifdef SWIG_TYPE_TABLE
+# define SWIG_QUOTE_STRING(x) #x
+# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x)
+# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE)
+#else
+# define SWIG_TYPE_TABLE_NAME
+#endif
+
+/*
+ You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for
+ creating a static or dynamic library from the SWIG runtime code.
+ In 99.9% of the cases, SWIG just needs to declare them as 'static'.
+
+ But only do this if strictly necessary, ie, if you have problems
+ with your compiler or suchlike.
+*/
+
+#ifndef SWIGRUNTIME
+# define SWIGRUNTIME SWIGINTERN
+#endif
+
+#ifndef SWIGRUNTIMEINLINE
+# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE
+#endif
+
+/* Generic buffer size */
+#ifndef SWIG_BUFFER_SIZE
+# define SWIG_BUFFER_SIZE 1024
+#endif
+
+/* Flags for pointer conversions */
+#define SWIG_POINTER_DISOWN 0x1
+#define SWIG_CAST_NEW_MEMORY 0x2
+
+/* Flags for new pointer objects */
+#define SWIG_POINTER_OWN 0x1
+
+
+/*
+ Flags/methods for returning states.
+
+ The SWIG conversion methods, as ConvertPtr, return and integer
+ that tells if the conversion was successful or not. And if not,
+ an error code can be returned (see swigerrors.swg for the codes).
+
+ Use the following macros/flags to set or process the returning
+ states.
+
+ In old versions of SWIG, code such as the following was usually written:
+
+ if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) {
+ // success code
+ } else {
+ //fail code
+ }
+
+ Now you can be more explicit:
+
+ int res = SWIG_ConvertPtr(obj,vptr,ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ } else {
+ // fail code
+ }
+
+ which is the same really, but now you can also do
+
+ Type *ptr;
+ int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags);
+ if (SWIG_IsOK(res)) {
+ // success code
+ if (SWIG_IsNewObj(res) {
+ ...
+ delete *ptr;
+ } else {
+ ...
+ }
+ } else {
+ // fail code
+ }
+
+ I.e., now SWIG_ConvertPtr can return new objects and you can
+ identify the case and take care of the deallocation. Of course that
+ also requires SWIG_ConvertPtr to return new result values, such as
+
+ int SWIG_ConvertPtr(obj, ptr,...) {
+ if (<obj is ok>) {
+ if (<need new object>) {
+ *ptr = <ptr to new allocated object>;
+ return SWIG_NEWOBJ;
+ } else {
+ *ptr = <ptr to old object>;
+ return SWIG_OLDOBJ;
+ }
+ } else {
+ return SWIG_BADOBJ;
+ }
+ }
+
+ Of course, returning the plain '0(success)/-1(fail)' still works, but you can be
+ more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the
+ SWIG errors code.
+
+ Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
+ allows to return the 'cast rank', for example, if you have this
+
+ int food(double)
+ int fooi(int);
+
+ and you call
+
+ food(1) // cast rank '1' (1 -> 1.0)
+ fooi(1) // cast rank '0'
+
+ just use the SWIG_AddCast()/SWIG_CheckState()
+*/
+
+#define SWIG_OK (0)
+#define SWIG_ERROR (-1)
+#define SWIG_IsOK(r) (r >= 0)
+#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError)
+
+/* The CastRankLimit says how many bits are used for the cast rank */
+#define SWIG_CASTRANKLIMIT (1 << 8)
+/* The NewMask denotes the object was created (using new/malloc) */
+#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1)
+/* The TmpMask is for in/out typemaps that use temporal objects */
+#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1)
+/* Simple returning values */
+#define SWIG_BADOBJ (SWIG_ERROR)
+#define SWIG_OLDOBJ (SWIG_OK)
+#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK)
+#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK)
+/* Check, add and del mask methods */
+#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
+#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
+#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
+#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r)
+#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r)
+#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK))
+
+/* Cast-Rank Mode */
+#if defined(SWIG_CASTRANK_MODE)
+# ifndef SWIG_TypeRank
+# define SWIG_TypeRank unsigned long
+# endif
+# ifndef SWIG_MAXCASTRANK /* Default cast allowed */
+# define SWIG_MAXCASTRANK (2)
+# endif
+# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1)
+# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK)
+SWIGINTERNINLINE int SWIG_AddCast(int r) {
+ return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r;
+}
+SWIGINTERNINLINE int SWIG_CheckState(int r) {
+ return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0;
+}
+#else /* no cast-rank mode */
+# define SWIG_AddCast
+# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0)
+#endif
+
+
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *(*swig_converter_func)(void *, int *);
+typedef struct swig_type_info *(*swig_dycast_func)(void **);
+
+/* Structure to store information on one type */
+typedef struct swig_type_info {
+ const char *name; /* mangled name of this type */
+ const char *str; /* human readable name of this type */
+ swig_dycast_func dcast; /* dynamic cast function down a hierarchy */
+ struct swig_cast_info *cast; /* linked list of types that can cast into this type */
+ void *clientdata; /* language specific type data */
+ int owndata; /* flag if the structure owns the clientdata */
+} swig_type_info;
+
+/* Structure to store a type and conversion function used for casting */
+typedef struct swig_cast_info {
+ swig_type_info *type; /* pointer to type that is equivalent to this type */
+ swig_converter_func converter; /* function to cast the void pointers */
+ struct swig_cast_info *next; /* pointer to next cast in linked list */
+ struct swig_cast_info *prev; /* pointer to the previous cast */
+} swig_cast_info;
+
+/* Structure used to store module information
+ * Each module generates one structure like this, and the runtime collects
+ * all of these structures and stores them in a circularly linked list.*/
+typedef struct swig_module_info {
+ swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */
+ size_t size; /* Number of types in this module */
+ struct swig_module_info *next; /* Pointer to next element in circularly linked list */
+ swig_type_info **type_initial; /* Array of initially generated type structures */
+ swig_cast_info **cast_initial; /* Array of initially generated casting structures */
+ void *clientdata; /* Language specific module data */
+} swig_module_info;
+
+/*
+ Compare two type names skipping the space characters, therefore
+ "char*" == "char *" and "Class<int>" == "Class<int >", etc.
+
+ Return 0 when the two name types are equivalent, as in
+ strncmp, but skipping ' '.
+*/
+SWIGRUNTIME int
+SWIG_TypeNameComp(const char *f1, const char *l1,
+ const char *f2, const char *l2) {
+ for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) {
+ while ((*f1 == ' ') && (f1 != l1)) ++f1;
+ while ((*f2 == ' ') && (f2 != l2)) ++f2;
+ if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1;
+ }
+ return (int)((l1 - f1) - (l2 - f2));
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if not equal, 1 if equal
+*/
+SWIGRUNTIME int
+SWIG_TypeEquiv(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+/*
+ Check type equivalence in a name list like <name1>|<name2>|...
+ Return 0 if equal, -1 if nb < tb, 1 if nb > tb
+*/
+SWIGRUNTIME int
+SWIG_TypeCompare(const char *nb, const char *tb) {
+ int equiv = 0;
+ const char* te = tb + strlen(tb);
+ const char* ne = nb;
+ while (!equiv && *ne) {
+ for (nb = ne; *ne; ++ne) {
+ if (*ne == '|') break;
+ }
+ equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0;
+ if (*ne) ++ne;
+ }
+ return equiv;
+}
+
+
+/*
+ Check the typename
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheck(const char *c, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (strcmp(iter->type->name, c) == 0) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
+*/
+SWIGRUNTIME swig_cast_info *
+SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+ if (ty) {
+ swig_cast_info *iter = ty->cast;
+ while (iter) {
+ if (iter->type == from) {
+ if (iter == ty->cast)
+ return iter;
+ /* Move iter to the top of the linked list */
+ iter->prev->next = iter->next;
+ if (iter->next)
+ iter->next->prev = iter->prev;
+ iter->next = ty->cast;
+ iter->prev = 0;
+ if (ty->cast) ty->cast->prev = iter;
+ ty->cast = iter;
+ return iter;
+ }
+ iter = iter->next;
+ }
+ }
+ return 0;
+}
+
+/*
+ Cast a pointer up an inheritance hierarchy
+*/
+SWIGRUNTIMEINLINE void *
+SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) {
+ return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory);
+}
+
+/*
+ Dynamic pointer casting. Down an inheritance hierarchy
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) {
+ swig_type_info *lastty = ty;
+ if (!ty || !ty->dcast) return ty;
+ while (ty && (ty->dcast)) {
+ ty = (*ty->dcast)(ptr);
+ if (ty) lastty = ty;
+ }
+ return lastty;
+}
+
+/*
+ Return the name associated with this type
+*/
+SWIGRUNTIMEINLINE const char *
+SWIG_TypeName(const swig_type_info *ty) {
+ return ty->name;
+}
+
+/*
+ Return the pretty name associated with this type,
+ that is an unmangled type name in a form presentable to the user.
+*/
+SWIGRUNTIME const char *
+SWIG_TypePrettyName(const swig_type_info *type) {
+ /* The "str" field contains the equivalent pretty names of the
+ type, separated by vertical-bar characters. We choose
+ to print the last name, as it is often (?) the most
+ specific. */
+ if (!type) return NULL;
+ if (type->str != NULL) {
+ const char *last_name = type->str;
+ const char *s;
+ for (s = type->str; *s; s++)
+ if (*s == '|') last_name = s+1;
+ return last_name;
+ }
+ else
+ return type->name;
+}
+
+/*
+ Set the clientdata field for a type
+*/
+SWIGRUNTIME void
+SWIG_TypeClientData(swig_type_info *ti, void *clientdata) {
+ swig_cast_info *cast = ti->cast;
+ /* if (ti->clientdata == clientdata) return; */
+ ti->clientdata = clientdata;
+
+ while (cast) {
+ if (!cast->converter) {
+ swig_type_info *tc = cast->type;
+ if (!tc->clientdata) {
+ SWIG_TypeClientData(tc, clientdata);
+ }
+ }
+ cast = cast->next;
+ }
+}
+SWIGRUNTIME void
+SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) {
+ SWIG_TypeClientData(ti, clientdata);
+ ti->owndata = 1;
+}
+
+/*
+ Search for a swig_type_info structure only by mangled name
+ Search is a O(log #types)
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_MangledTypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ swig_module_info *iter = start;
+ do {
+ if (iter->size) {
+ register size_t l = 0;
+ register size_t r = iter->size - 1;
+ do {
+ /* since l+r >= 0, we can (>> 1) instead (/ 2) */
+ register size_t i = (l + r) >> 1;
+ const char *iname = iter->types[i]->name;
+ if (iname) {
+ register int compare = strcmp(name, iname);
+ if (compare == 0) {
+ return iter->types[i];
+ } else if (compare < 0) {
+ if (i) {
+ r = i - 1;
+ } else {
+ break;
+ }
+ } else if (compare > 0) {
+ l = i + 1;
+ }
+ } else {
+ break; /* should never happen */
+ }
+ } while (l <= r);
+ }
+ iter = iter->next;
+ } while (iter != end);
+ return 0;
+}
+
+/*
+ Search for a swig_type_info structure for either a mangled name or a human readable name.
+ It first searches the mangled names of the types, which is a O(log #types)
+ If a type is not found it then searches the human readable names, which is O(#types).
+
+ We start searching at module start, and finish searching when start == end.
+ Note: if start == end at the beginning of the function, we go all the way around
+ the circular list.
+*/
+SWIGRUNTIME swig_type_info *
+SWIG_TypeQueryModule(swig_module_info *start,
+ swig_module_info *end,
+ const char *name) {
+ /* STEP 1: Search the name field using binary search */
+ swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name);
+ if (ret) {
+ return ret;
+ } else {
+ /* STEP 2: If the type hasn't been found, do a complete search
+ of the str field (the human readable name) */
+ swig_module_info *iter = start;
+ do {
+ register size_t i = 0;
+ for (; i < iter->size; ++i) {
+ if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name)))
+ return iter->types[i];
+ }
+ iter = iter->next;
+ } while (iter != end);
+ }
+
+ /* neither found a match */
+ return 0;
+}
+
+/*
+ Pack binary data into a string
+*/
+SWIGRUNTIME char *
+SWIG_PackData(char *c, void *ptr, size_t sz) {
+ static const char hex[17] = "0123456789abcdef";
+ register const unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register unsigned char uu = *u;
+ *(c++) = hex[(uu & 0xf0) >> 4];
+ *(c++) = hex[uu & 0xf];
+ }
+ return c;
+}
+
+/*
+ Unpack binary data from a string
+*/
+SWIGRUNTIME const char *
+SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
+ register unsigned char *u = (unsigned char *) ptr;
+ register const unsigned char *eu = u + sz;
+ for (; u != eu; ++u) {
+ register char d = *(c++);
+ register unsigned char uu;
+ if ((d >= '0') && (d <= '9'))
+ uu = ((d - '0') << 4);
+ else if ((d >= 'a') && (d <= 'f'))
+ uu = ((d - ('a'-10)) << 4);
+ else
+ return (char *) 0;
+ d = *(c++);
+ if ((d >= '0') && (d <= '9'))
+ uu |= (d - '0');
+ else if ((d >= 'a') && (d <= 'f'))
+ uu |= (d - ('a'-10));
+ else
+ return (char *) 0;
+ *u = uu;
+ }
+ return c;
+}
+
+/*
+ Pack 'void *' into a string buffer.
+*/
+SWIGRUNTIME char *
+SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) {
+ char *r = buff;
+ if ((2*sizeof(void *) + 2) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,&ptr,sizeof(void *));
+ if (strlen(name) + 1 > (bsz - (r - buff))) return 0;
+ strcpy(r,name);
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ *ptr = (void *) 0;
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sizeof(void *));
+}
+
+SWIGRUNTIME char *
+SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) {
+ char *r = buff;
+ size_t lname = (name ? strlen(name) : 0);
+ if ((2*sz + 2 + lname) > bsz) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r,ptr,sz);
+ if (lname) {
+ strncpy(r,name,lname+1);
+ } else {
+ *r = 0;
+ }
+ return buff;
+}
+
+SWIGRUNTIME const char *
+SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
+ if (*c != '_') {
+ if (strcmp(c,"NULL") == 0) {
+ memset(ptr,0,sz);
+ return name;
+ } else {
+ return 0;
+ }
+ }
+ return SWIG_UnpackData(++c,ptr,sz);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Errors in SWIG */
+#define SWIG_UnknownError -1
+#define SWIG_IOError -2
+#define SWIG_RuntimeError -3
+#define SWIG_IndexError -4
+#define SWIG_TypeError -5
+#define SWIG_DivisionByZero -6
+#define SWIG_OverflowError -7
+#define SWIG_SyntaxError -8
+#define SWIG_ValueError -9
+#define SWIG_SystemError -10
+#define SWIG_AttributeError -11
+#define SWIG_MemoryError -12
+#define SWIG_NullReferenceError -13
+
+
+
+#include <ruby.h>
+
+/* Remove global macros defined in Ruby's win32.h */
+#ifdef write
+# undef write
+#endif
+#ifdef read
+# undef read
+#endif
+#ifdef bind
+# undef bind
+#endif
+#ifdef close
+# undef close
+#endif
+#ifdef connect
+# undef connect
+#endif
+
+
+/* Ruby 1.7 defines NUM2LL(), LL2NUM() and ULL2NUM() macros */
+#ifndef NUM2LL
+#define NUM2LL(x) NUM2LONG((x))
+#endif
+#ifndef LL2NUM
+#define LL2NUM(x) INT2NUM((long) (x))
+#endif
+#ifndef ULL2NUM
+#define ULL2NUM(x) UINT2NUM((unsigned long) (x))
+#endif
+
+/* Ruby 1.7 doesn't (yet) define NUM2ULL() */
+#ifndef NUM2ULL
+#ifdef HAVE_LONG_LONG
+#define NUM2ULL(x) rb_num2ull((x))
+#else
+#define NUM2ULL(x) NUM2ULONG(x)
+#endif
+#endif
+
+/* RSTRING_LEN, etc are new in Ruby 1.9, but ->ptr and ->len no longer work */
+/* Define these for older versions so we can just write code the new way */
+#ifndef RSTRING_LEN
+# define RSTRING_LEN(x) RSTRING(x)->len
+#endif
+#ifndef RSTRING_PTR
+# define RSTRING_PTR(x) RSTRING(x)->ptr
+#endif
+#ifndef RSTRING_END
+# define RSTRING_END(x) (RSTRING_PTR(x) + RSTRING_LEN(x))
+#endif
+#ifndef RARRAY_LEN
+# define RARRAY_LEN(x) RARRAY(x)->len
+#endif
+#ifndef RARRAY_PTR
+# define RARRAY_PTR(x) RARRAY(x)->ptr
+#endif
+#ifndef RFLOAT_VALUE
+# define RFLOAT_VALUE(x) RFLOAT(x)->value
+#endif
+#ifndef DOUBLE2NUM
+# define DOUBLE2NUM(x) rb_float_new(x)
+#endif
+#ifndef RHASH_TBL
+# define RHASH_TBL(x) (RHASH(x)->tbl)
+#endif
+#ifndef RHASH_ITER_LEV
+# define RHASH_ITER_LEV(x) (RHASH(x)->iter_lev)
+#endif
+#ifndef RHASH_IFNONE
+# define RHASH_IFNONE(x) (RHASH(x)->ifnone)
+#endif
+#ifndef RHASH_SIZE
+# define RHASH_SIZE(x) (RHASH(x)->tbl->num_entries)
+#endif
+#ifndef RHASH_EMPTY_P
+# define RHASH_EMPTY_P(x) (RHASH_SIZE(x) == 0)
+#endif
+#ifndef RSTRUCT_LEN
+# define RSTRUCT_LEN(x) RSTRUCT(x)->len
+#endif
+#ifndef RSTRUCT_PTR
+# define RSTRUCT_PTR(x) RSTRUCT(x)->ptr
+#endif
+
+
+
+/*
+ * Need to be very careful about how these macros are defined, especially
+ * when compiling C++ code or C code with an ANSI C compiler.
+ *
+ * VALUEFUNC(f) is a macro used to typecast a C function that implements
+ * a Ruby method so that it can be passed as an argument to API functions
+ * like rb_define_method() and rb_define_singleton_method().
+ *
+ * VOIDFUNC(f) is a macro used to typecast a C function that implements
+ * either the "mark" or "free" stuff for a Ruby Data object, so that it
+ * can be passed as an argument to API functions like Data_Wrap_Struct()
+ * and Data_Make_Struct().
+ */
+
+#ifdef __cplusplus
+# ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */
+# define PROTECTFUNC(f) ((VALUE (*)()) f)
+# define VALUEFUNC(f) ((VALUE (*)()) f)
+# define VOIDFUNC(f) ((void (*)()) f)
+# else
+# ifndef ANYARGS /* These definitions should work for Ruby 1.6 */
+# define PROTECTFUNC(f) ((VALUE (*)()) f)
+# define VALUEFUNC(f) ((VALUE (*)()) f)
+# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
+# else /* These definitions should work for Ruby 1.7+ */
+# define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
+# define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
+# define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
+# endif
+# endif
+#else
+# define VALUEFUNC(f) (f)
+# define VOIDFUNC(f) (f)
+#endif
+
+/* Don't use for expressions have side effect */
+#ifndef RB_STRING_VALUE
+#define RB_STRING_VALUE(s) (TYPE(s) == T_STRING ? (s) : (*(volatile VALUE *)&(s) = rb_str_to_str(s)))
+#endif
+#ifndef StringValue
+#define StringValue(s) RB_STRING_VALUE(s)
+#endif
+#ifndef StringValuePtr
+#define StringValuePtr(s) RSTRING_PTR(RB_STRING_VALUE(s))
+#endif
+#ifndef StringValueLen
+#define StringValueLen(s) RSTRING_LEN(RB_STRING_VALUE(s))
+#endif
+#ifndef SafeStringValue
+#define SafeStringValue(v) do {\
+ StringValue(v);\
+ rb_check_safe_str(v);\
+} while (0)
+#endif
+
+#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
+#define rb_define_alloc_func(klass, func) rb_define_singleton_method((klass), "new", VALUEFUNC((func)), -1)
+#define rb_undef_alloc_func(klass) rb_undef_method(CLASS_OF((klass)), "new")
+#endif
+
+static VALUE _mSWIG = Qnil;
+
+/* -----------------------------------------------------------------------------
+ * error manipulation
+ * ----------------------------------------------------------------------------- */
+
+
+/* Define some additional error types */
+#define SWIG_ObjectPreviouslyDeletedError -100
+
+
+/* Define custom exceptions for errors that do not map to existing Ruby
+ exceptions. Note this only works for C++ since a global cannot be
+ initialized by a funtion in C. For C, fallback to rb_eRuntimeError.*/
+
+SWIGINTERN VALUE
+getNullReferenceError(void) {
+ static int init = 0;
+ static VALUE rb_eNullReferenceError ;
+ if (!init) {
+ init = 1;
+ rb_eNullReferenceError = rb_define_class("NullReferenceError", rb_eRuntimeError);
+ }
+ return rb_eNullReferenceError;
+}
+
+SWIGINTERN VALUE
+getObjectPreviouslyDeletedError(void) {
+ static int init = 0;
+ static VALUE rb_eObjectPreviouslyDeleted ;
+ if (!init) {
+ init = 1;
+ rb_eObjectPreviouslyDeleted = rb_define_class("ObjectPreviouslyDeleted", rb_eRuntimeError);
+ }
+ return rb_eObjectPreviouslyDeleted;
+}
+
+
+SWIGINTERN VALUE
+SWIG_Ruby_ErrorType(int SWIG_code) {
+ VALUE type;
+ switch (SWIG_code) {
+ case SWIG_MemoryError:
+ type = rb_eNoMemError;
+ break;
+ case SWIG_IOError:
+ type = rb_eIOError;
+ break;
+ case SWIG_RuntimeError:
+ type = rb_eRuntimeError;
+ break;
+ case SWIG_IndexError:
+ type = rb_eIndexError;
+ break;
+ case SWIG_TypeError:
+ type = rb_eTypeError;
+ break;
+ case SWIG_DivisionByZero:
+ type = rb_eZeroDivError;
+ break;
+ case SWIG_OverflowError:
+ type = rb_eRangeError;
+ break;
+ case SWIG_SyntaxError:
+ type = rb_eSyntaxError;
+ break;
+ case SWIG_ValueError:
+ type = rb_eArgError;
+ break;
+ case SWIG_SystemError:
+ type = rb_eFatal;
+ break;
+ case SWIG_AttributeError:
+ type = rb_eRuntimeError;
+ break;
+ case SWIG_NullReferenceError:
+ type = getNullReferenceError();
+ break;
+ case SWIG_ObjectPreviouslyDeletedError:
+ type = getObjectPreviouslyDeletedError();
+ break;
+ case SWIG_UnknownError:
+ type = rb_eRuntimeError;
+ break;
+ default:
+ type = rb_eRuntimeError;
+ }
+ return type;
+}
+
+
+/* This function is called when a user inputs a wrong argument to
+ a method.
+ */
+SWIGINTERN
+const char* Ruby_Format_TypeError( const char* msg,
+ const char* type,
+ const char* name,
+ const int argn,
+ VALUE input )
+{
+ char buf[128];
+ VALUE str;
+ VALUE asStr;
+ if ( msg && *msg )
+ {
+ str = rb_str_new2(msg);
+ }
+ else
+ {
+ str = rb_str_new(NULL, 0);
+ }
+
+ str = rb_str_cat2( str, "Expected argument " );
+ sprintf( buf, "%d of type ", argn-1 );
+ str = rb_str_cat2( str, buf );
+ str = rb_str_cat2( str, type );
+ str = rb_str_cat2( str, ", but got " );
+ str = rb_str_cat2( str, rb_obj_classname(input) );
+ str = rb_str_cat2( str, " " );
+ asStr = rb_inspect(input);
+ if ( RSTRING_LEN(asStr) > 30 )
+ {
+ str = rb_str_cat( str, StringValuePtr(asStr), 30 );
+ str = rb_str_cat2( str, "..." );
+ }
+ else
+ {
+ str = rb_str_append( str, asStr );
+ }
+
+ if ( name )
+ {
+ str = rb_str_cat2( str, "\n\tin SWIG method '" );
+ str = rb_str_cat2( str, name );
+ str = rb_str_cat2( str, "'" );
+ }
+
+ return StringValuePtr( str );
+}
+
+/* This function is called when an overloaded method fails */
+SWIGINTERN
+void Ruby_Format_OverloadedError(
+ const int argc,
+ const int maxargs,
+ const char* method,
+ const char* prototypes
+ )
+{
+ const char* msg = "Wrong # of arguments";
+ if ( argc <= maxargs ) msg = "Wrong arguments";
+ rb_raise(rb_eArgError,"%s for overloaded method '%s'.\n"
+ "Possible C/C++ prototypes are:\n%s",
+ msg, method, prototypes);
+}
+
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * rubytracking.swg
+ *
+ * This file contains support for tracking mappings from
+ * Ruby objects to C++ objects. This functionality is needed
+ * to implement mark functions for Ruby's mark and sweep
+ * garbage collector.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Ruby 1.8 actually assumes the first case. */
+#if SIZEOF_VOIDP == SIZEOF_LONG
+# define SWIG2NUM(v) LONG2NUM((unsigned long)v)
+# define NUM2SWIG(x) (unsigned long)NUM2LONG(x)
+#elif SIZEOF_VOIDP == SIZEOF_LONG_LONG
+# define SWIG2NUM(v) LL2NUM((unsigned long long)v)
+# define NUM2SWIG(x) (unsigned long long)NUM2LL(x)
+#else
+# error sizeof(void*) is not the same as long or long long
+#endif
+
+
+/* Global Ruby hash table to store Trackings from C/C++
+ structs to Ruby Objects.
+*/
+static VALUE swig_ruby_trackings = Qnil;
+
+/* Global variable that stores a reference to the ruby
+ hash table delete function. */
+static ID swig_ruby_hash_delete;
+
+/* Setup a Ruby hash table to store Trackings */
+SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
+ /* Create a ruby hash table to store Trackings from C++
+ objects to Ruby objects. */
+
+ /* Try to see if some other .so has already created a
+ tracking hash table, which we keep hidden in an instance var
+ in the SWIG module.
+ This is done to allow multiple DSOs to share the same
+ tracking table.
+ */
+ ID trackings_id = rb_intern( "@__trackings__" );
+ VALUE verbose = rb_gv_get("VERBOSE");
+ rb_gv_set("VERBOSE", Qfalse);
+ swig_ruby_trackings = rb_ivar_get( _mSWIG, trackings_id );
+ rb_gv_set("VERBOSE", verbose);
+
+ /* No, it hasn't. Create one ourselves */
+ if ( swig_ruby_trackings == Qnil )
+ {
+ swig_ruby_trackings = rb_hash_new();
+ rb_ivar_set( _mSWIG, trackings_id, swig_ruby_trackings );
+ }
+
+ /* Now store a reference to the hash table delete function
+ so that we only have to look it up once.*/
+ swig_ruby_hash_delete = rb_intern("delete");
+}
+
+/* Get a Ruby number to reference a pointer */
+SWIGRUNTIME VALUE SWIG_RubyPtrToReference(void* ptr) {
+ /* We cast the pointer to an unsigned long
+ and then store a reference to it using
+ a Ruby number object. */
+
+ /* Convert the pointer to a Ruby number */
+ return SWIG2NUM(ptr);
+}
+
+/* Get a Ruby number to reference an object */
+SWIGRUNTIME VALUE SWIG_RubyObjectToReference(VALUE object) {
+ /* We cast the object to an unsigned long
+ and then store a reference to it using
+ a Ruby number object. */
+
+ /* Convert the Object to a Ruby number */
+ return SWIG2NUM(object);
+}
+
+/* Get a Ruby object from a previously stored reference */
+SWIGRUNTIME VALUE SWIG_RubyReferenceToObject(VALUE reference) {
+ /* The provided Ruby number object is a reference
+ to the Ruby object we want.*/
+
+ /* Convert the Ruby number to a Ruby object */
+ return NUM2SWIG(reference);
+}
+
+/* Add a Tracking from a C/C++ struct to a Ruby object */
+SWIGRUNTIME void SWIG_RubyAddTracking(void* ptr, VALUE object) {
+ /* In a Ruby hash table we store the pointer and
+ the associated Ruby object. The trick here is
+ that we cannot store the Ruby object directly - if
+ we do then it cannot be garbage collected. So
+ instead we typecast it as a unsigned long and
+ convert it to a Ruby number object.*/
+
+ /* Get a reference to the pointer as a Ruby number */
+ VALUE key = SWIG_RubyPtrToReference(ptr);
+
+ /* Get a reference to the Ruby object as a Ruby number */
+ VALUE value = SWIG_RubyObjectToReference(object);
+
+ /* Store the mapping to the global hash table. */
+ rb_hash_aset(swig_ruby_trackings, key, value);
+}
+
+/* Get the Ruby object that owns the specified C/C++ struct */
+SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
+ /* Get a reference to the pointer as a Ruby number */
+ VALUE key = SWIG_RubyPtrToReference(ptr);
+
+ /* Now lookup the value stored in the global hash table */
+ VALUE value = rb_hash_aref(swig_ruby_trackings, key);
+
+ if (value == Qnil) {
+ /* No object exists - return nil. */
+ return Qnil;
+ }
+ else {
+ /* Convert this value to Ruby object */
+ return SWIG_RubyReferenceToObject(value);
+ }
+}
+
+/* Remove a Tracking from a C/C++ struct to a Ruby object. It
+ is very important to remove objects once they are destroyed
+ since the same memory address may be reused later to create
+ a new object. */
+SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
+ /* Get a reference to the pointer as a Ruby number */
+ VALUE key = SWIG_RubyPtrToReference(ptr);
+
+ /* Delete the object from the hash table by calling Ruby's
+ do this we need to call the Hash.delete method.*/
+ rb_funcall(swig_ruby_trackings, swig_ruby_hash_delete, 1, key);
+}
+
+/* This is a helper method that unlinks a Ruby object from its
+ underlying C++ object. This is needed if the lifetime of the
+ Ruby object is longer than the C++ object */
+SWIGRUNTIME void SWIG_RubyUnlinkObjects(void* ptr) {
+ VALUE object = SWIG_RubyInstanceFor(ptr);
+
+ if (object != Qnil) {
+ DATA_PTR(object) = 0;
+ }
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/* -----------------------------------------------------------------------------
+ * Ruby API portion that goes into the runtime
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+SWIGINTERN VALUE
+SWIG_Ruby_AppendOutput(VALUE target, VALUE o) {
+ if (NIL_P(target)) {
+ target = o;
+ } else {
+ if (TYPE(target) != T_ARRAY) {
+ VALUE o2 = target;
+ target = rb_ary_new();
+ rb_ary_push(target, o2);
+ }
+ rb_ary_push(target, o);
+ }
+ return target;
+}
+
+/* For ruby1.8.4 and earlier. */
+#ifndef RUBY_INIT_STACK
+ RUBY_EXTERN void Init_stack(VALUE* addr);
+# define RUBY_INIT_STACK \
+ VALUE variable_in_this_stack_frame; \
+ Init_stack(&variable_in_this_stack_frame);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * rubyrun.swg
+ *
+ * This file contains the runtime support for Ruby modules
+ * and includes code for managing global variables and pointer
+ * type checking.
+ * ----------------------------------------------------------------------------- */
+
+/* For backward compatibility only */
+#define SWIG_POINTER_EXCEPTION 0
+
+/* for raw pointers */
+#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Ruby_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Ruby_ConvertPtrAndOwn(obj, pptr, type, flags, own)
+#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Ruby_NewPointerObj(ptr, type, flags)
+#define SWIG_AcquirePtr(ptr, own) SWIG_Ruby_AcquirePtr(ptr, own)
+#define swig_owntype ruby_owntype
+
+/* for raw packed data */
+#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty, flags)
+#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Ruby_NewPackedObj(ptr, sz, type)
+
+/* for class or struct pointers */
+#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags)
+
+/* for C or C++ function pointers */
+#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_ConvertPtr(obj, pptr, type, 0)
+#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_NewPointerObj(ptr, type, 0)
+
+/* for C++ member pointers, ie, member methods */
+#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Ruby_NewPackedObj(ptr, sz, type)
+
+
+/* Runtime API */
+
+#define SWIG_GetModule(clientdata) SWIG_Ruby_GetModule()
+#define SWIG_SetModule(clientdata, pointer) SWIG_Ruby_SetModule(pointer)
+
+
+/* Error manipulation */
+
+#define SWIG_ErrorType(code) SWIG_Ruby_ErrorType(code)
+#define SWIG_Error(code, msg) rb_raise(SWIG_Ruby_ErrorType(code), msg)
+#define SWIG_fail goto fail
+
+
+/* Ruby-specific SWIG API */
+
+#define SWIG_InitRuntime() SWIG_Ruby_InitRuntime()
+#define SWIG_define_class(ty) SWIG_Ruby_define_class(ty)
+#define SWIG_NewClassInstance(value, ty) SWIG_Ruby_NewClassInstance(value, ty)
+#define SWIG_MangleStr(value) SWIG_Ruby_MangleStr(value)
+#define SWIG_CheckConvert(value, ty) SWIG_Ruby_CheckConvert(value, ty)
+
+#include "assert.h"
+
+/* -----------------------------------------------------------------------------
+ * pointers/data manipulation
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ VALUE klass;
+ VALUE mImpl;
+ void (*mark)(void *);
+ void (*destroy)(void *);
+ int trackObjects;
+} swig_class;
+
+
+/* Global pointer used to keep some internal SWIG stuff */
+static VALUE _cSWIG_Pointer = Qnil;
+static VALUE swig_runtime_data_type_pointer = Qnil;
+
+/* Global IDs used to keep some internal SWIG stuff */
+static ID swig_arity_id = 0;
+static ID swig_call_id = 0;
+
+/*
+ If your swig extension is to be run within an embedded ruby and has
+ director callbacks, you should set -DRUBY_EMBEDDED during compilation.
+ This will reset ruby's stack frame on each entry point from the main
+ program the first time a virtual director function is invoked (in a
+ non-recursive way).
+ If this is not done, you run the risk of Ruby trashing the stack.
+*/
+
+#ifdef RUBY_EMBEDDED
+
+# define SWIG_INIT_STACK \
+ if ( !swig_virtual_calls ) { RUBY_INIT_STACK } \
+ ++swig_virtual_calls;
+# define SWIG_RELEASE_STACK --swig_virtual_calls;
+# define Ruby_DirectorTypeMismatchException(x) \
+ rb_raise( rb_eTypeError, x ); return c_result;
+
+ static unsigned int swig_virtual_calls = 0;
+
+#else /* normal non-embedded extension */
+
+# define SWIG_INIT_STACK
+# define SWIG_RELEASE_STACK
+# define Ruby_DirectorTypeMismatchException(x) \
+ throw Swig::DirectorTypeMismatchException( x );
+
+#endif /* RUBY_EMBEDDED */
+
+
+SWIGRUNTIME VALUE
+getExceptionClass(void) {
+ static int init = 0;
+ static VALUE rubyExceptionClass ;
+ if (!init) {
+ init = 1;
+ rubyExceptionClass = rb_const_get(_mSWIG, rb_intern("Exception"));
+ }
+ return rubyExceptionClass;
+}
+
+/* This code checks to see if the Ruby object being raised as part
+ of an exception inherits from the Ruby class Exception. If so,
+ the object is simply returned. If not, then a new Ruby exception
+ object is created and that will be returned to Ruby.*/
+SWIGRUNTIME VALUE
+SWIG_Ruby_ExceptionType(swig_type_info *desc, VALUE obj) {
+ VALUE exceptionClass = getExceptionClass();
+ if (rb_obj_is_kind_of(obj, exceptionClass)) {
+ return obj;
+ } else {
+ return rb_exc_new3(rb_eRuntimeError, rb_obj_as_string(obj));
+ }
+}
+
+/* Initialize Ruby runtime support */
+SWIGRUNTIME void
+SWIG_Ruby_InitRuntime(void)
+{
+ if (_mSWIG == Qnil) {
+ _mSWIG = rb_define_module("SWIG");
+ swig_call_id = rb_intern("call");
+ swig_arity_id = rb_intern("arity");
+ }
+}
+
+/* Define Ruby class for C type */
+SWIGRUNTIME void
+SWIG_Ruby_define_class(swig_type_info *type)
+{
+ VALUE klass;
+ char *klass_name = (char *) malloc(4 + strlen(type->name) + 1);
+ sprintf(klass_name, "TYPE%s", type->name);
+ if (NIL_P(_cSWIG_Pointer)) {
+ _cSWIG_Pointer = rb_define_class_under(_mSWIG, "Pointer", rb_cObject);
+ rb_undef_method(CLASS_OF(_cSWIG_Pointer), "new");
+ }
+ klass = rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer);
+ free((void *) klass_name);
+}
+
+/* Create a new pointer object */
+SWIGRUNTIME VALUE
+SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int flags)
+{
+ int own = flags & SWIG_POINTER_OWN;
+ int track;
+ char *klass_name;
+ swig_class *sklass;
+ VALUE klass;
+ VALUE obj;
+
+ if (!ptr)
+ return Qnil;
+
+ if (type->clientdata) {
+ sklass = (swig_class *) type->clientdata;
+
+ /* Are we tracking this class and have we already returned this Ruby object? */
+ track = sklass->trackObjects;
+ if (track) {
+ obj = SWIG_RubyInstanceFor(ptr);
+
+ /* Check the object's type and make sure it has the correct type.
+ It might not in cases where methods do things like
+ downcast methods. */
+ if (obj != Qnil) {
+ VALUE value = rb_iv_get(obj, "@__swigtype__");
+ char* type_name = RSTRING_PTR(value);
+
+ if (strcmp(type->name, type_name) == 0) {
+ return obj;
+ }
+ }
+ }
+
+ /* Create a new Ruby object */
+ obj = Data_Wrap_Struct(sklass->klass, VOIDFUNC(sklass->mark),
+ ( own ? VOIDFUNC(sklass->destroy) :
+ (track ? VOIDFUNC(SWIG_RubyRemoveTracking) : 0 )
+ ), ptr);
+
+ /* If tracking is on for this class then track this object. */
+ if (track) {
+ SWIG_RubyAddTracking(ptr, obj);
+ }
+ } else {
+ klass_name = (char *) malloc(4 + strlen(type->name) + 1);
+ sprintf(klass_name, "TYPE%s", type->name);
+ klass = rb_const_get(_mSWIG, rb_intern(klass_name));
+ free((void *) klass_name);
+ obj = Data_Wrap_Struct(klass, 0, 0, ptr);
+ }
+ rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name));
+
+ return obj;
+}
+
+/* Create a new class instance (always owned) */
+SWIGRUNTIME VALUE
+SWIG_Ruby_NewClassInstance(VALUE klass, swig_type_info *type)
+{
+ VALUE obj;
+ swig_class *sklass = (swig_class *) type->clientdata;
+ obj = Data_Wrap_Struct(klass, VOIDFUNC(sklass->mark), VOIDFUNC(sklass->destroy), 0);
+ rb_iv_set(obj, "@__swigtype__", rb_str_new2(type->name));
+ return obj;
+}
+
+/* Get type mangle from class name */
+SWIGRUNTIMEINLINE char *
+SWIG_Ruby_MangleStr(VALUE obj)
+{
+ VALUE stype = rb_iv_get(obj, "@__swigtype__");
+ return StringValuePtr(stype);
+}
+
+/* Acquire a pointer value */
+typedef void (*ruby_owntype)(void*);
+
+SWIGRUNTIME ruby_owntype
+SWIG_Ruby_AcquirePtr(VALUE obj, ruby_owntype own) {
+ if (obj) {
+ ruby_owntype oldown = RDATA(obj)->dfree;
+ RDATA(obj)->dfree = own;
+ return oldown;
+ } else {
+ return 0;
+ }
+}
+
+/* Convert a pointer value */
+SWIGRUNTIME int
+SWIG_Ruby_ConvertPtrAndOwn(VALUE obj, void **ptr, swig_type_info *ty, int flags, ruby_owntype *own)
+{
+ char *c;
+ swig_cast_info *tc;
+ void *vptr = 0;
+
+ /* Grab the pointer */
+ if (NIL_P(obj)) {
+ *ptr = 0;
+ return SWIG_OK;
+ } else {
+ if (TYPE(obj) != T_DATA) {
+ return SWIG_ERROR;
+ }
+ Data_Get_Struct(obj, void, vptr);
+ }
+
+ if (own) *own = RDATA(obj)->dfree;
+
+ /* Check to see if the input object is giving up ownership
+ of the underlying C struct or C++ object. If so then we
+ need to reset the destructor since the Ruby object no
+ longer owns the underlying C++ object.*/
+ if (flags & SWIG_POINTER_DISOWN) {
+ /* Is tracking on for this class? */
+ int track = 0;
+ if (ty && ty->clientdata) {
+ swig_class *sklass = (swig_class *) ty->clientdata;
+ track = sklass->trackObjects;
+ }
+
+ if (track) {
+ /* We are tracking objects for this class. Thus we change the destructor
+ * to SWIG_RubyRemoveTracking. This allows us to
+ * remove the mapping from the C++ to Ruby object
+ * when the Ruby object is garbage collected. If we don't
+ * do this, then it is possible we will return a reference
+ * to a Ruby object that no longer exists thereby crashing Ruby. */
+ RDATA(obj)->dfree = SWIG_RubyRemoveTracking;
+ } else {
+ RDATA(obj)->dfree = 0;
+ }
+ }
+
+ /* Do type-checking if type info was provided */
+ if (ty) {
+ if (ty->clientdata) {
+ if (rb_obj_is_kind_of(obj, ((swig_class *) (ty->clientdata))->klass)) {
+ if (vptr == 0) {
+ /* The object has already been deleted */
+ return SWIG_ObjectPreviouslyDeletedError;
+ }
+ *ptr = vptr;
+ return SWIG_OK;
+ }
+ }
+ if ((c = SWIG_MangleStr(obj)) == NULL) {
+ return SWIG_ERROR;
+ }
+ tc = SWIG_TypeCheck(c, ty);
+ if (!tc) {
+ return SWIG_ERROR;
+ } else {
+ int newmemory = 0;
+ *ptr = SWIG_TypeCast(tc, vptr, &newmemory);
+ assert(!newmemory); /* newmemory handling not yet implemented */
+ }
+ } else {
+ *ptr = vptr;
+ }
+
+ return SWIG_OK;
+}
+
+/* Check convert */
+SWIGRUNTIMEINLINE int
+SWIG_Ruby_CheckConvert(VALUE obj, swig_type_info *ty)
+{
+ char *c = SWIG_MangleStr(obj);
+ if (!c) return 0;
+ return SWIG_TypeCheck(c,ty) != 0;
+}
+
+SWIGRUNTIME VALUE
+SWIG_Ruby_NewPackedObj(void *ptr, int sz, swig_type_info *type) {
+ char result[1024];
+ char *r = result;
+ if ((2*sz + 1 + strlen(type->name)) > 1000) return 0;
+ *(r++) = '_';
+ r = SWIG_PackData(r, ptr, sz);
+ strcpy(r, type->name);
+ return rb_str_new2(result);
+}
+
+/* Convert a packed value value */
+SWIGRUNTIME int
+SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty) {
+ swig_cast_info *tc;
+ const char *c;
+
+ if (TYPE(obj) != T_STRING) goto type_error;
+ c = StringValuePtr(obj);
+ /* Pointer values must start with leading underscore */
+ if (*c != '_') goto type_error;
+ c++;
+ c = SWIG_UnpackData(c, ptr, sz);
+ if (ty) {
+ tc = SWIG_TypeCheck(c, ty);
+ if (!tc) goto type_error;
+ }
+ return SWIG_OK;
+
+ type_error:
+ return SWIG_ERROR;
+}
+
+SWIGRUNTIME swig_module_info *
+SWIG_Ruby_GetModule(void)
+{
+ VALUE pointer;
+ swig_module_info *ret = 0;
+ VALUE verbose = rb_gv_get("VERBOSE");
+
+ /* temporarily disable warnings, since the pointer check causes warnings with 'ruby -w' */
+ rb_gv_set("VERBOSE", Qfalse);
+
+ /* first check if pointer already created */
+ pointer = rb_gv_get("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
+ if (pointer != Qnil) {
+ Data_Get_Struct(pointer, swig_module_info, ret);
+ }
+
+ /* reinstate warnings */
+ rb_gv_set("VERBOSE", verbose);
+ return ret;
+}
+
+SWIGRUNTIME void
+SWIG_Ruby_SetModule(swig_module_info *pointer)
+{
+ /* register a new class */
+ VALUE cl = rb_define_class("swig_runtime_data", rb_cObject);
+ /* create and store the structure pointer to a global variable */
+ swig_runtime_data_type_pointer = Data_Wrap_Struct(cl, 0, 0, pointer);
+ rb_define_readonly_variable("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, &swig_runtime_data_type_pointer);
+}
+
+/* This function can be used to check whether a proc or method or similarly
+ callable function has been passed. Usually used in a %typecheck, like:
+
+ %typecheck(c_callback_t, precedence=SWIG_TYPECHECK_POINTER) {
+ $result = SWIG_Ruby_isCallable( $input );
+ }
+ */
+SWIGINTERN
+int SWIG_Ruby_isCallable( VALUE proc )
+{
+ if ( rb_respond_to( proc, swig_call_id ) == Qtrue )
+ return 1;
+ return 0;
+}
+
+/* This function can be used to check the arity (number of arguments)
+ a proc or method can take. Usually used in a %typecheck.
+ Valid arities will be that equal to minimal or those < 0
+ which indicate a variable number of parameters at the end.
+ */
+SWIGINTERN
+int SWIG_Ruby_arity( VALUE proc, int minimal )
+{
+ if ( rb_respond_to( proc, swig_arity_id ) == Qtrue )
+ {
+ VALUE num = rb_funcall( proc, swig_arity_id, 0 );
+ int arity = NUM2INT(num);
+ if ( arity < 0 && (arity+1) < -minimal ) return 1;
+ if ( arity == minimal ) return 1;
+ return 1;
+ }
+ return 0;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0)
+
+#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else
+
+
+
+ #define SWIG_exception(code, msg) do { SWIG_Error(code, msg);; } while(0)
+
+
+/* -------- TYPES TABLE (BEGIN) -------- */
+
+#define SWIGTYPE_p_char swig_types[0]
+#define SWIGTYPE_p_marisa__Key swig_types[1]
+#define SWIGTYPE_p_marisa_swig__Agent swig_types[2]
+#define SWIGTYPE_p_marisa_swig__Key swig_types[3]
+#define SWIGTYPE_p_marisa_swig__Keyset swig_types[4]
+#define SWIGTYPE_p_marisa_swig__Query swig_types[5]
+#define SWIGTYPE_p_marisa_swig__Trie swig_types[6]
+#define SWIGTYPE_p_p_char swig_types[7]
+#define SWIGTYPE_p_std__size_t swig_types[8]
+static swig_type_info *swig_types[10];
+static swig_module_info swig_module = {swig_types, 9, 0, 0, 0, 0};
+#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name)
+#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name)
+
+/* -------- TYPES TABLE (END) -------- */
+
+#define SWIG_init Init_marisa
+#define SWIG_name "Marisa"
+
+static VALUE mMarisa;
+
+#define SWIG_RUBY_THREAD_BEGIN_BLOCK
+#define SWIG_RUBY_THREAD_END_BLOCK
+
+
+#define SWIGVERSION 0x010340
+#define SWIG_VERSION SWIGVERSION
+
+
+#define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a))
+#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),reinterpret_cast< void** >(a))
+
+
+#include <stdexcept>
+
+
+#include "marisa-swig.h"
+
+
+#include <limits.h>
+#if !defined(SWIG_NO_LLONG_MAX)
+# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__)
+# define LLONG_MAX __LONG_LONG_MAX__
+# define LLONG_MIN (-LLONG_MAX - 1LL)
+# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+# endif
+#endif
+
+
+ #define SWIG_From_long LONG2NUM
+
+
+SWIGINTERNINLINE VALUE
+SWIG_From_int (int value)
+{
+ return SWIG_From_long (value);
+}
+
+
+SWIGINTERN swig_type_info*
+SWIG_pchar_descriptor(void)
+{
+ static int init = 0;
+ static swig_type_info* info = 0;
+ if (!init) {
+ info = SWIG_TypeQuery("_p_char");
+ init = 1;
+ }
+ return info;
+}
+
+
+SWIGINTERNINLINE VALUE
+SWIG_FromCharPtrAndSize(const char* carray, size_t size)
+{
+ if (carray) {
+ if (size > LONG_MAX) {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ return pchar_descriptor ?
+ SWIG_NewPointerObj(const_cast< char * >(carray), pchar_descriptor, 0) : Qnil;
+ } else {
+ return rb_str_new(carray, static_cast< long >(size));
+ }
+ } else {
+ return Qnil;
+ }
+}
+
+
+SWIGINTERNINLINE VALUE
+SWIG_From_unsigned_SS_long (unsigned long value)
+{
+ return ULONG2NUM(value);
+}
+
+
+SWIGINTERNINLINE VALUE
+SWIG_From_size_t (size_t value)
+{
+ return SWIG_From_unsigned_SS_long (static_cast< unsigned long >(value));
+}
+
+
+ #define SWIG_From_double rb_float_new
+
+
+SWIGINTERNINLINE VALUE
+SWIG_From_float (float value)
+{
+ return SWIG_From_double (value);
+}
+
+
+SWIGINTERN int
+SWIG_AsCharPtrAndSize(VALUE obj, char** cptr, size_t* psize, int *alloc)
+{
+ if (TYPE(obj) == T_STRING) {
+ #if defined(StringValuePtr)
+ char *cstr = StringValuePtr(obj);
+ #else
+ char *cstr = STR2CSTR(obj);
+ #endif
+ size_t size = RSTRING_LEN(obj) + 1;
+ if (cptr) {
+ if (alloc) {
+ if (*alloc == SWIG_NEWOBJ) {
+ *cptr = reinterpret_cast< char* >(memcpy((new char[size]), cstr, sizeof(char)*(size)));
+ } else {
+ *cptr = cstr;
+ *alloc = SWIG_OLDOBJ;
+ }
+ }
+ }
+ if (psize) *psize = size;
+ return SWIG_OK;
+ } else {
+ swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+ if (pchar_descriptor) {
+ void* vptr = 0;
+ if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
+ if (cptr) *cptr = (char *)vptr;
+ if (psize) *psize = vptr ? (strlen((char*)vptr) + 1) : 0;
+ if (alloc) *alloc = SWIG_OLDOBJ;
+ return SWIG_OK;
+ }
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+#include <float.h>
+
+
+SWIGINTERN VALUE
+SWIG_ruby_failed(void)
+{
+ return Qnil;
+}
+
+
+/*@SWIG:/usr/share/swig1.3/ruby/rubyprimtypes.swg,23,%ruby_aux_method@*/
+SWIGINTERN VALUE SWIG_AUX_NUM2DBL(VALUE *args)
+{
+ VALUE obj = args[0];
+ VALUE type = TYPE(obj);
+ double *res = (double *)(args[1]);
+ *res = NUM2DBL(obj);
+ return obj;
+}
+/*@SWIG@*/
+
+SWIGINTERN int
+SWIG_AsVal_double (VALUE obj, double *val)
+{
+ VALUE type = TYPE(obj);
+ if ((type == T_FLOAT) || (type == T_FIXNUM) || (type == T_BIGNUM)) {
+ double v;
+ VALUE a[2];
+ a[0] = obj;
+ a[1] = (VALUE)(&v);
+ if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2DBL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+ if (val) *val = v;
+ return SWIG_OK;
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_float (VALUE obj, float *val)
+{
+ double v;
+ int res = SWIG_AsVal_double (obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < -FLT_MAX || v > FLT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = static_cast< float >(v);
+ }
+ }
+ return res;
+}
+
+
+
+
+
+/*@SWIG:/usr/share/swig1.3/ruby/rubyprimtypes.swg,23,%ruby_aux_method@*/
+SWIGINTERN VALUE SWIG_AUX_NUM2ULONG(VALUE *args)
+{
+ VALUE obj = args[0];
+ VALUE type = TYPE(obj);
+ unsigned long *res = (unsigned long *)(args[1]);
+ *res = type == T_FIXNUM ? NUM2ULONG(obj) : rb_big2ulong(obj);
+ return obj;
+}
+/*@SWIG@*/
+
+SWIGINTERN int
+SWIG_AsVal_unsigned_SS_long (VALUE obj, unsigned long *val)
+{
+ VALUE type = TYPE(obj);
+ if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
+ unsigned long v;
+ VALUE a[2];
+ a[0] = obj;
+ a[1] = (VALUE)(&v);
+ if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+ if (val) *val = v;
+ return SWIG_OK;
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERNINLINE int
+SWIG_AsVal_size_t (VALUE obj, size_t *val)
+{
+ unsigned long v;
+ int res = SWIG_AsVal_unsigned_SS_long (obj, val ? &v : 0);
+ if (SWIG_IsOK(res) && val) *val = static_cast< size_t >(v);
+ return res;
+}
+
+
+SWIGINTERNINLINE VALUE
+SWIG_From_bool (bool value)
+{
+ return value ? Qtrue : Qfalse;
+}
+
+
+/*@SWIG:/usr/share/swig1.3/ruby/rubyprimtypes.swg,23,%ruby_aux_method@*/
+SWIGINTERN VALUE SWIG_AUX_NUM2LONG(VALUE *args)
+{
+ VALUE obj = args[0];
+ VALUE type = TYPE(obj);
+ long *res = (long *)(args[1]);
+ *res = type == T_FIXNUM ? NUM2LONG(obj) : rb_big2long(obj);
+ return obj;
+}
+/*@SWIG@*/
+
+SWIGINTERN int
+SWIG_AsVal_long (VALUE obj, long* val)
+{
+ VALUE type = TYPE(obj);
+ if ((type == T_FIXNUM) || (type == T_BIGNUM)) {
+ long v;
+ VALUE a[2];
+ a[0] = obj;
+ a[1] = (VALUE)(&v);
+ if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+ if (val) *val = v;
+ return SWIG_OK;
+ }
+ }
+ return SWIG_TypeError;
+}
+
+
+SWIGINTERN int
+SWIG_AsVal_int (VALUE obj, int *val)
+{
+ long v;
+ int res = SWIG_AsVal_long (obj, &v);
+ if (SWIG_IsOK(res)) {
+ if ((v < INT_MIN || v > INT_MAX)) {
+ return SWIG_OverflowError;
+ } else {
+ if (val) *val = static_cast< int >(v);
+ }
+ }
+ return res;
+}
+
+swig_class SwigClassKey;
+
+SWIGINTERN VALUE
+_wrap_Key_str(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ VALUE vresult = Qnil;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Key const *","str", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ ((marisa_swig::Key const *)arg1)->str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (*arg2) {
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Key_id(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Key const *","id", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Key const *)arg1)->id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Key_weight(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Key *arg1 = (marisa_swig::Key *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ float result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Key const *","weight", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Key * >(argp1);
+ {
+ try {
+ result = (float)((marisa_swig::Key const *)arg1)->weight();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_float(static_cast< float >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN void
+free_marisa_swig_Key(marisa_swig::Key *arg1) {
+ delete arg1;
+}
+
+swig_class SwigClassQuery;
+
+SWIGINTERN VALUE
+_wrap_Query_str(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ VALUE vresult = Qnil;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Query const *","str", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ ((marisa_swig::Query const *)arg1)->str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (*arg2) {
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Query_id(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Query *arg1 = (marisa_swig::Query *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Query const *","id", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Query * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Query const *)arg1)->id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN void
+free_marisa_swig_Query(marisa_swig::Query *arg1) {
+ delete arg1;
+}
+
+swig_class SwigClassKeyset;
+
+#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
+SWIGINTERN VALUE
+_wrap_Keyset_allocate(VALUE self) {
+#else
+ SWIGINTERN VALUE
+ _wrap_Keyset_allocate(int argc, VALUE *argv, VALUE self) {
+#endif
+
+
+ VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE_p_marisa_swig__Keyset);
+#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
+ rb_obj_call_init(vresult, argc, argv);
+#endif
+ return vresult;
+ }
+
+
+SWIGINTERN VALUE
+_wrap_new_Keyset(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *result = 0 ;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ {
+ try {
+ result = (marisa_swig::Keyset *)new marisa_swig::Keyset();
+ DATA_PTR(self) = result;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return self;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN void
+free_marisa_swig_Keyset(marisa_swig::Keyset *arg1) {
+ delete arg1;
+}
+
+SWIGINTERN VALUE
+_wrap_Keyset_push_back__SWIG_0(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ marisa::Key *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 ;
+ int res2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset *","push_back", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa__Key, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa::Key const &","push_back", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa::Key const &","push_back", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa::Key * >(argp2);
+ {
+ try {
+ (arg1)->push_back((marisa::Key const &)*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_push_back__SWIG_1(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ float arg4 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ float val4 ;
+ int ecode4 = 0 ;
+
+ if ((argc < 2) || (argc > 2)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset *","push_back", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","push_back", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ ecode4 = SWIG_AsVal_float(argv[1], &val4);
+ if (!SWIG_IsOK(ecode4)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode4), Ruby_Format_TypeError( "", "float","push_back", 4, argv[1] ));
+ }
+ arg4 = static_cast< float >(val4);
+ {
+ try {
+ (arg1)->push_back((char const *)arg2,arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_push_back__SWIG_2(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset *","push_back", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","push_back", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ (arg1)->push_back((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE _wrap_Keyset_push_back(int nargs, VALUE *args, VALUE self) {
+ int argc;
+ VALUE argv[4];
+ int ii;
+
+ argc = nargs + 1;
+ argv[0] = self;
+ if (argc > 4) SWIG_fail;
+ for (ii = 1; (ii < argc); ++ii) {
+ argv[ii] = args[ii-1];
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa__Key, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Keyset_push_back__SWIG_0(nargs, args, self);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ if (argc <= 2) {
+ return _wrap_Keyset_push_back__SWIG_2(nargs, args, self);
+ }
+ {
+ int res = SWIG_AsVal_size_t(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Keyset_push_back__SWIG_2(nargs, args, self);
+ }
+ }
+ }
+ }
+ if (argc == 3) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_float(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Keyset_push_back__SWIG_1(nargs, args, self);
+ }
+ }
+ }
+ }
+
+fail:
+ Ruby_Format_OverloadedError( argc, 4, "Keyset.push_back",
+ " void Keyset.push_back(marisa::Key const &key)\n"
+ " void Keyset.push_back(char const *ptr, std::size_t length, float weight)\n"
+ " void Keyset.push_back(char const *ptr, std::size_t length)\n");
+
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_key(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ marisa_swig::Key *result = 0 ;
+ VALUE vresult = Qnil;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","key", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(argv[0], &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "std::size_t","key", 2, argv[0] ));
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ result = (marisa_swig::Key *) &((marisa_swig::Keyset const *)arg1)->key(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_key_str(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ char **arg3 = (char **) 0 ;
+ std::size_t *arg4 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ char *temp3 = 0 ;
+ std::size_t tempn3 ;
+ VALUE vresult = Qnil;
+
+ arg3 = &temp3; arg4 = &tempn3;
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","key_str", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(argv[0], &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "std::size_t","key_str", 2, argv[0] ));
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ ((marisa_swig::Keyset const *)arg1)->key_str(arg2,(char const **)arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (*arg3) {
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_FromCharPtrAndSize(*arg3,*arg4));
+ ;
+ }
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_key_id(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","key_id", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(argv[0], &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "std::size_t","key_id", 2, argv[0] ));
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->key_id(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_num_keys(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","num_keys", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->num_keys();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+
+/*
+ Document-method: Marisa::Keyset.empty
+
+ call-seq:
+ empty -> bool
+
+Check if Keyset is empty.
+*/
+SWIGINTERN VALUE
+_wrap_Keyset_empty(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ bool result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","empty", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = (bool)((marisa_swig::Keyset const *)arg1)->empty();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_bool(static_cast< bool >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+
+/*
+ Document-method: Marisa::Keyset.size
+
+ call-seq:
+ size -> std::size_t
+
+Size or Length of the Keyset.
+*/
+SWIGINTERN VALUE
+_wrap_Keyset_size(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","size", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_total_length(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset const *","total_length", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Keyset const *)arg1)->total_length();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_reset(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset *","reset", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ (arg1)->reset();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Keyset_clear(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Keyset *arg1 = (marisa_swig::Keyset *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Keyset, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Keyset *","clear", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Keyset * >(argp1);
+ {
+ try {
+ (arg1)->clear();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+swig_class SwigClassAgent;
+
+#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
+SWIGINTERN VALUE
+_wrap_Agent_allocate(VALUE self) {
+#else
+ SWIGINTERN VALUE
+ _wrap_Agent_allocate(int argc, VALUE *argv, VALUE self) {
+#endif
+
+
+ VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE_p_marisa_swig__Agent);
+#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
+ rb_obj_call_init(vresult, argc, argv);
+#endif
+ return vresult;
+ }
+
+
+SWIGINTERN VALUE
+_wrap_new_Agent(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *result = 0 ;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ {
+ try {
+ result = (marisa_swig::Agent *)new marisa_swig::Agent();
+ DATA_PTR(self) = result;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return self;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN void
+free_marisa_swig_Agent(marisa_swig::Agent *arg1) {
+ delete arg1;
+}
+
+SWIGINTERN VALUE
+_wrap_Agent_set_query__SWIG_0(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent *","set_query", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","set_query", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ (arg1)->set_query((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_set_query__SWIG_1(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ std::size_t arg2 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent *","set_query", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(argv[0], &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "std::size_t","set_query", 2, argv[0] ));
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ (arg1)->set_query(arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE _wrap_Agent_set_query(int nargs, VALUE *args, VALUE self) {
+ int argc;
+ VALUE argv[3];
+ int ii;
+
+ argc = nargs + 1;
+ argv[0] = self;
+ if (argc > 3) SWIG_fail;
+ for (ii = 1; (ii < argc); ++ii) {
+ argv[ii] = args[ii-1];
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_size_t(argv[1], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Agent_set_query__SWIG_1(nargs, args, self);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ if (argc <= 2) {
+ return _wrap_Agent_set_query__SWIG_0(nargs, args, self);
+ }
+ {
+ int res = SWIG_AsVal_size_t(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Agent_set_query__SWIG_0(nargs, args, self);
+ }
+ }
+ }
+ }
+
+fail:
+ Ruby_Format_OverloadedError( argc, 3, "Agent.set_query",
+ " void Agent.set_query(char const *ptr, std::size_t length)\n"
+ " void Agent.set_query(std::size_t id)\n");
+
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_key(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ marisa_swig::Key *result = 0 ;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent const *","key", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = (marisa_swig::Key *) &((marisa_swig::Agent const *)arg1)->key();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Key, 0 | 0 );
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_query(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ marisa_swig::Query *result = 0 ;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent const *","query", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = (marisa_swig::Query *) &((marisa_swig::Agent const *)arg1)->query();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_marisa_swig__Query, 0 | 0 );
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_key_str(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ VALUE vresult = Qnil;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent const *","key_str", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ ((marisa_swig::Agent const *)arg1)->key_str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (*arg2) {
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_key_id(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent const *","key_id", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Agent const *)arg1)->key_id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_query_str(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ char **arg2 = (char **) 0 ;
+ std::size_t *arg3 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ char *temp2 = 0 ;
+ std::size_t tempn2 ;
+ VALUE vresult = Qnil;
+
+ arg2 = &temp2; arg3 = &tempn2;
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent const *","query_str", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ ((marisa_swig::Agent const *)arg1)->query_str((char const **)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (*arg2) {
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_FromCharPtrAndSize(*arg2,*arg3));
+ ;
+ }
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Agent_query_id(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Agent *arg1 = (marisa_swig::Agent *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Agent, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Agent const *","query_id", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Agent * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Agent const *)arg1)->query_id();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+swig_class SwigClassTrie;
+
+#ifdef HAVE_RB_DEFINE_ALLOC_FUNC
+SWIGINTERN VALUE
+_wrap_Trie_allocate(VALUE self) {
+#else
+ SWIGINTERN VALUE
+ _wrap_Trie_allocate(int argc, VALUE *argv, VALUE self) {
+#endif
+
+
+ VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE_p_marisa_swig__Trie);
+#ifndef HAVE_RB_DEFINE_ALLOC_FUNC
+ rb_obj_call_init(vresult, argc, argv);
+#endif
+ return vresult;
+ }
+
+
+SWIGINTERN VALUE
+_wrap_new_Trie(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *result = 0 ;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ {
+ try {
+ result = (marisa_swig::Trie *)new marisa_swig::Trie();
+ DATA_PTR(self) = result;
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return self;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN void
+free_marisa_swig_Trie(marisa_swig::Trie *arg1) {
+ delete arg1;
+}
+
+SWIGINTERN VALUE
+_wrap_Trie_build__SWIG_0(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Keyset *arg2 = 0 ;
+ int arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ int val3 ;
+ int ecode3 = 0 ;
+
+ if ((argc < 2) || (argc > 2)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie *","build", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa_swig__Keyset, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa_swig::Keyset &","build", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa_swig::Keyset &","build", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa_swig::Keyset * >(argp2);
+ ecode3 = SWIG_AsVal_int(argv[1], &val3);
+ if (!SWIG_IsOK(ecode3)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode3), Ruby_Format_TypeError( "", "int","build", 3, argv[1] ));
+ }
+ arg3 = static_cast< int >(val3);
+ {
+ try {
+ (arg1)->build(*arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_build__SWIG_1(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Keyset *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie *","build", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa_swig__Keyset, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa_swig::Keyset &","build", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa_swig::Keyset &","build", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa_swig::Keyset * >(argp2);
+ {
+ try {
+ (arg1)->build(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE _wrap_Trie_build(int nargs, VALUE *args, VALUE self) {
+ int argc;
+ VALUE argv[4];
+ int ii;
+
+ argc = nargs + 1;
+ argv[0] = self;
+ if (argc > 4) SWIG_fail;
+ for (ii = 1; (ii < argc); ++ii) {
+ argv[ii] = args[ii-1];
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Trie_build__SWIG_1(nargs, args, self);
+ }
+ }
+ }
+ if (argc == 3) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Keyset, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_int(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Trie_build__SWIG_0(nargs, args, self);
+ }
+ }
+ }
+ }
+
+fail:
+ Ruby_Format_OverloadedError( argc, 4, "Trie.build",
+ " void Trie.build(marisa_swig::Keyset &keyset, int config_flags)\n"
+ " void Trie.build(marisa_swig::Keyset &keyset)\n");
+
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_mmap(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie *","mmap", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","mmap", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ (arg1)->mmap((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_load(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie *","load", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","load", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ (arg1)->load((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_save(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ int alloc2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","save", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, NULL, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","save", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->save((char const *)arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_lookup__SWIG_0(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ bool result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","lookup", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa_swig::Agent &","lookup", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa_swig::Agent &","lookup", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->lookup(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_bool(static_cast< bool >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_reverse_lookup__SWIG_0(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","reverse_lookup", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa_swig::Agent &","reverse_lookup", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa_swig::Agent &","reverse_lookup", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->reverse_lookup(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_common_prefix_search(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ bool result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","common_prefix_search", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa_swig::Agent &","common_prefix_search", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa_swig::Agent &","common_prefix_search", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->common_prefix_search(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_bool(static_cast< bool >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_predictive_search(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ marisa_swig::Agent *arg2 = 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ void *argp2 = 0 ;
+ int res2 = 0 ;
+ bool result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","predictive_search", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_ConvertPtr(argv[0], &argp2, SWIGTYPE_p_marisa_swig__Agent, 0 );
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "marisa_swig::Agent &","predictive_search", 2, argv[0] ));
+ }
+ if (!argp2) {
+ SWIG_exception_fail(SWIG_ValueError, Ruby_Format_TypeError("invalid null reference ", "marisa_swig::Agent &","predictive_search", 2, argv[0]));
+ }
+ arg2 = reinterpret_cast< marisa_swig::Agent * >(argp2);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->predictive_search(*arg2);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_bool(static_cast< bool >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_lookup__SWIG_1(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ char *arg2 = (char *) 0 ;
+ std::size_t arg3 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ int res2 ;
+ char *buf2 = 0 ;
+ size_t size2 = 0 ;
+ int alloc2 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","lookup", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ res2 = SWIG_AsCharPtrAndSize(argv[0], &buf2, &size2, &alloc2);
+ if (!SWIG_IsOK(res2)) {
+ SWIG_exception_fail(SWIG_ArgError(res2), Ruby_Format_TypeError( "", "char const *","lookup", 2, argv[0] ));
+ }
+ arg2 = reinterpret_cast< char * >(buf2);
+ arg3 = static_cast< std::size_t >(size2 - 1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->lookup((char const *)arg2,arg3);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return vresult;
+fail:
+ if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE _wrap_Trie_lookup(int nargs, VALUE *args, VALUE self) {
+ int argc;
+ VALUE argv[3];
+ int ii;
+
+ argc = nargs + 1;
+ argv[0] = self;
+ if (argc > 3) SWIG_fail;
+ for (ii = 1; (ii < argc); ++ii) {
+ argv[ii] = args[ii-1];
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Trie_lookup__SWIG_0(nargs, args, self);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ int res = SWIG_AsCharPtrAndSize(argv[1], 0, NULL, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ if (argc <= 2) {
+ return _wrap_Trie_lookup__SWIG_1(nargs, args, self);
+ }
+ {
+ int res = SWIG_AsVal_size_t(argv[2], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Trie_lookup__SWIG_1(nargs, args, self);
+ }
+ }
+ }
+ }
+
+fail:
+ Ruby_Format_OverloadedError( argc, 3, "Trie.lookup",
+ " std::size_t Trie.lookup(marisa_swig::Agent &agent)\n"
+ " std::size_t Trie.lookup(char const *ptr, std::size_t length)\n");
+
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_reverse_lookup__SWIG_1(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ std::size_t arg2 ;
+ char **arg3 = (char **) 0 ;
+ std::size_t *arg4 = (std::size_t *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ size_t val2 ;
+ int ecode2 = 0 ;
+ char *temp3 = 0 ;
+ std::size_t tempn3 ;
+ VALUE vresult = Qnil;
+
+ arg3 = &temp3; arg4 = &tempn3;
+ if ((argc < 1) || (argc > 1)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","reverse_lookup", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ ecode2 = SWIG_AsVal_size_t(argv[0], &val2);
+ if (!SWIG_IsOK(ecode2)) {
+ SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "std::size_t","reverse_lookup", 2, argv[0] ));
+ }
+ arg2 = static_cast< std::size_t >(val2);
+ {
+ try {
+ ((marisa_swig::Trie const *)arg1)->reverse_lookup(arg2,(char const **)arg3,arg4);
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ if (*arg3) {
+ vresult = SWIG_Ruby_AppendOutput(vresult, SWIG_FromCharPtrAndSize(*arg3,*arg4));
+ delete [] (*arg3);
+ }
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE _wrap_Trie_reverse_lookup(int nargs, VALUE *args, VALUE self) {
+ int argc;
+ VALUE argv[3];
+ int ii;
+
+ argc = nargs + 1;
+ argv[0] = self;
+ if (argc > 3) SWIG_fail;
+ for (ii = 1; (ii < argc); ++ii) {
+ argv[ii] = args[ii-1];
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_marisa_swig__Agent, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ return _wrap_Trie_reverse_lookup__SWIG_0(nargs, args, self);
+ }
+ }
+ }
+ if (argc == 2) {
+ int _v;
+ void *vptr = 0;
+ int res = SWIG_ConvertPtr(argv[0], &vptr, SWIGTYPE_p_marisa_swig__Trie, 0);
+ _v = SWIG_CheckState(res);
+ if (_v) {
+ {
+ int res = SWIG_AsVal_size_t(argv[1], NULL);
+ _v = SWIG_CheckState(res);
+ }
+ if (_v) {
+ return _wrap_Trie_reverse_lookup__SWIG_1(nargs, args, self);
+ }
+ }
+ }
+
+fail:
+ Ruby_Format_OverloadedError( argc, 3, "Trie.reverse_lookup",
+ " void Trie.reverse_lookup(marisa_swig::Agent &agent)\n"
+ " void Trie.reverse_lookup(std::size_t id, char const **ptr_out_to_be_deleted, std::size_t *length_out)\n");
+
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_num_tries(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","num_tries", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_tries();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_num_keys(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","num_keys", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_keys();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_num_nodes(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","num_nodes", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->num_nodes();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_tail_mode(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ marisa_swig::TailMode result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","tail_mode", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (marisa_swig::TailMode)((marisa_swig::Trie const *)arg1)->tail_mode();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_int(static_cast< int >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_node_order(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ marisa_swig::NodeOrder result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","node_order", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (marisa_swig::NodeOrder)((marisa_swig::Trie const *)arg1)->node_order();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_int(static_cast< int >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+
+/*
+ Document-method: Marisa::Trie.empty
+
+ call-seq:
+ empty -> bool
+
+Check if Trie is empty.
+*/
+SWIGINTERN VALUE
+_wrap_Trie_empty(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ bool result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","empty", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = (bool)((marisa_swig::Trie const *)arg1)->empty();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_bool(static_cast< bool >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+
+/*
+ Document-method: Marisa::Trie.size
+
+ call-seq:
+ size -> std::size_t
+
+Size or Length of the Trie.
+*/
+SWIGINTERN VALUE
+_wrap_Trie_size(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","size", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_total_size(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","total_size", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->total_size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_io_size(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+ std::size_t result;
+ VALUE vresult = Qnil;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie const *","io_size", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ result = ((marisa_swig::Trie const *)arg1)->io_size();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
+ return vresult;
+fail:
+ return Qnil;
+}
+
+
+SWIGINTERN VALUE
+_wrap_Trie_clear(int argc, VALUE *argv, VALUE self) {
+ marisa_swig::Trie *arg1 = (marisa_swig::Trie *) 0 ;
+ void *argp1 = 0 ;
+ int res1 = 0 ;
+
+ if ((argc < 0) || (argc > 0)) {
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
+ }
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_marisa_swig__Trie, 0 | 0 );
+ if (!SWIG_IsOK(res1)) {
+ SWIG_exception_fail(SWIG_ArgError(res1), Ruby_Format_TypeError( "", "marisa_swig::Trie *","clear", 1, self ));
+ }
+ arg1 = reinterpret_cast< marisa_swig::Trie * >(argp1);
+ {
+ try {
+ (arg1)->clear();
+ } catch (const marisa::Exception &ex) {
+ SWIG_exception(SWIG_RuntimeError, ex.what());
+ } catch (...) {
+ SWIG_exception(SWIG_UnknownError,"Unknown exception");
+ }
+ }
+ return Qnil;
+fail:
+ return Qnil;
+}
+
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */
+
+static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa__Key = {"_p_marisa__Key", "marisa::Key *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Agent = {"_p_marisa_swig__Agent", "marisa_swig::Agent *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Key = {"_p_marisa_swig__Key", "marisa_swig::Key *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Keyset = {"_p_marisa_swig__Keyset", "marisa_swig::Keyset *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Query = {"_p_marisa_swig__Query", "marisa_swig::Query *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_marisa_swig__Trie = {"_p_marisa_swig__Trie", "marisa_swig::Trie *", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_p_char = {"_p_p_char", "char **", 0, 0, (void*)0, 0};
+static swig_type_info _swigt__p_std__size_t = {"_p_std__size_t", "std::size_t *", 0, 0, (void*)0, 0};
+
+static swig_type_info *swig_type_initial[] = {
+ &_swigt__p_char,
+ &_swigt__p_marisa__Key,
+ &_swigt__p_marisa_swig__Agent,
+ &_swigt__p_marisa_swig__Key,
+ &_swigt__p_marisa_swig__Keyset,
+ &_swigt__p_marisa_swig__Query,
+ &_swigt__p_marisa_swig__Trie,
+ &_swigt__p_p_char,
+ &_swigt__p_std__size_t,
+};
+
+static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa__Key[] = { {&_swigt__p_marisa__Key, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Agent[] = { {&_swigt__p_marisa_swig__Agent, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Key[] = { {&_swigt__p_marisa_swig__Key, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Keyset[] = { {&_swigt__p_marisa_swig__Keyset, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Query[] = { {&_swigt__p_marisa_swig__Query, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_marisa_swig__Trie[] = { {&_swigt__p_marisa_swig__Trie, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_p_char[] = { {&_swigt__p_p_char, 0, 0, 0},{0, 0, 0, 0}};
+static swig_cast_info _swigc__p_std__size_t[] = { {&_swigt__p_std__size_t, 0, 0, 0},{0, 0, 0, 0}};
+
+static swig_cast_info *swig_cast_initial[] = {
+ _swigc__p_char,
+ _swigc__p_marisa__Key,
+ _swigc__p_marisa_swig__Agent,
+ _swigc__p_marisa_swig__Key,
+ _swigc__p_marisa_swig__Keyset,
+ _swigc__p_marisa_swig__Query,
+ _swigc__p_marisa_swig__Trie,
+ _swigc__p_p_char,
+ _swigc__p_std__size_t,
+};
+
+
+/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
+
+/* -----------------------------------------------------------------------------
+ * Type initialization:
+ * This problem is tough by the requirement that no dynamic
+ * memory is used. Also, since swig_type_info structures store pointers to
+ * swig_cast_info structures and swig_cast_info structures store pointers back
+ * to swig_type_info structures, we need some lookup code at initialization.
+ * The idea is that swig generates all the structures that are needed.
+ * The runtime then collects these partially filled structures.
+ * The SWIG_InitializeModule function takes these initial arrays out of
+ * swig_module, and does all the lookup, filling in the swig_module.types
+ * array with the correct data and linking the correct swig_cast_info
+ * structures together.
+ *
+ * The generated swig_type_info structures are assigned staticly to an initial
+ * array. We just loop through that array, and handle each type individually.
+ * First we lookup if this type has been already loaded, and if so, use the
+ * loaded structure instead of the generated one. Then we have to fill in the
+ * cast linked list. The cast data is initially stored in something like a
+ * two-dimensional array. Each row corresponds to a type (there are the same
+ * number of rows as there are in the swig_type_initial array). Each entry in
+ * a column is one of the swig_cast_info structures for that type.
+ * The cast_initial array is actually an array of arrays, because each row has
+ * a variable number of columns. So to actually build the cast linked list,
+ * we find the array of casts associated with the type, and loop through it
+ * adding the casts to the list. The one last trick we need to do is making
+ * sure the type pointer in the swig_cast_info struct is correct.
+ *
+ * First off, we lookup the cast->type name to see if it is already loaded.
+ * There are three cases to handle:
+ * 1) If the cast->type has already been loaded AND the type we are adding
+ * casting info to has not been loaded (it is in this module), THEN we
+ * replace the cast->type pointer with the type pointer that has already
+ * been loaded.
+ * 2) If BOTH types (the one we are adding casting info to, and the
+ * cast->type) are loaded, THEN the cast info has already been loaded by
+ * the previous module so we just ignore it.
+ * 3) Finally, if cast->type has not already been loaded, then we add that
+ * swig_cast_info to the linked list (because the cast->type) pointer will
+ * be correct.
+ * ----------------------------------------------------------------------------- */
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+} /* c-mode */
+#endif
+#endif
+
+#if 0
+#define SWIGRUNTIME_DEBUG
+#endif
+
+
+SWIGRUNTIME void
+SWIG_InitializeModule(void *clientdata) {
+ size_t i;
+ swig_module_info *module_head, *iter;
+ int found, init;
+
+ clientdata = clientdata;
+
+ /* check to see if the circular list has been setup, if not, set it up */
+ if (swig_module.next==0) {
+ /* Initialize the swig_module */
+ swig_module.type_initial = swig_type_initial;
+ swig_module.cast_initial = swig_cast_initial;
+ swig_module.next = &swig_module;
+ init = 1;
+ } else {
+ init = 0;
+ }
+
+ /* Try and load any already created modules */
+ module_head = SWIG_GetModule(clientdata);
+ if (!module_head) {
+ /* This is the first module loaded for this interpreter */
+ /* so set the swig module into the interpreter */
+ SWIG_SetModule(clientdata, &swig_module);
+ module_head = &swig_module;
+ } else {
+ /* the interpreter has loaded a SWIG module, but has it loaded this one? */
+ found=0;
+ iter=module_head;
+ do {
+ if (iter==&swig_module) {
+ found=1;
+ break;
+ }
+ iter=iter->next;
+ } while (iter!= module_head);
+
+ /* if the is found in the list, then all is done and we may leave */
+ if (found) return;
+ /* otherwise we must add out module into the list */
+ swig_module.next = module_head->next;
+ module_head->next = &swig_module;
+ }
+
+ /* When multiple interpeters are used, a module could have already been initialized in
+ a different interpreter, but not yet have a pointer in this interpreter.
+ In this case, we do not want to continue adding types... everything should be
+ set up already */
+ if (init == 0) return;
+
+ /* Now work on filling in swig_module.types */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: size %d\n", swig_module.size);
+#endif
+ for (i = 0; i < swig_module.size; ++i) {
+ swig_type_info *type = 0;
+ swig_type_info *ret;
+ swig_cast_info *cast;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+#endif
+
+ /* if there is another module already loaded */
+ if (swig_module.next != &swig_module) {
+ type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name);
+ }
+ if (type) {
+ /* Overwrite clientdata field */
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found type %s\n", type->name);
+#endif
+ if (swig_module.type_initial[i]->clientdata) {
+ type->clientdata = swig_module.type_initial[i]->clientdata;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name);
+#endif
+ }
+ } else {
+ type = swig_module.type_initial[i];
+ }
+
+ /* Insert casting types */
+ cast = swig_module.cast_initial[i];
+ while (cast->type) {
+
+ /* Don't need to add information already in the list */
+ ret = 0;
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: look cast %s\n", cast->type->name);
+#endif
+ if (swig_module.next != &swig_module) {
+ ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name);
+#endif
+ }
+ if (ret) {
+ if (type == swig_module.type_initial[i]) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: skip old type %s\n", ret->name);
+#endif
+ cast->type = ret;
+ ret = 0;
+ } else {
+ /* Check for casting already in the list */
+ swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type);
+#ifdef SWIGRUNTIME_DEBUG
+ if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name);
+#endif
+ if (!ocast) ret = 0;
+ }
+ }
+
+ if (!ret) {
+#ifdef SWIGRUNTIME_DEBUG
+ printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name);
+#endif
+ if (type->cast) {
+ type->cast->prev = cast;
+ cast->next = type->cast;
+ }
+ type->cast = cast;
+ }
+ cast++;
+ }
+ /* Set entry in modules->types array equal to the type */
+ swig_module.types[i] = type;
+ }
+ swig_module.types[i] = 0;
+
+#ifdef SWIGRUNTIME_DEBUG
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+ for (i = 0; i < swig_module.size; ++i) {
+ int j = 0;
+ swig_cast_info *cast = swig_module.cast_initial[i];
+ printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name);
+ while (cast->type) {
+ printf("SWIG_InitializeModule: cast type %s\n", cast->type->name);
+ cast++;
+ ++j;
+ }
+ printf("---- Total casts: %d\n",j);
+ }
+ printf("**** SWIG_InitializeModule: Cast List ******\n");
+#endif
+}
+
+/* This function will propagate the clientdata field of type to
+* any new swig_type_info structures that have been added into the list
+* of equivalent types. It is like calling
+* SWIG_TypeClientData(type, clientdata) a second time.
+*/
+SWIGRUNTIME void
+SWIG_PropagateClientData(void) {
+ size_t i;
+ swig_cast_info *equiv;
+ static int init_run = 0;
+
+ if (init_run) return;
+ init_run = 1;
+
+ for (i = 0; i < swig_module.size; i++) {
+ if (swig_module.types[i]->clientdata) {
+ equiv = swig_module.types[i]->cast;
+ while (equiv) {
+ if (!equiv->converter) {
+ if (equiv->type && !equiv->type->clientdata)
+ SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata);
+ }
+ equiv = equiv->next;
+ }
+ }
+ }
+}
+
+#ifdef __cplusplus
+#if 0
+{ /* c-mode */
+#endif
+}
+#endif
+
+/*
+
+*/
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void Init_marisa(void) {
+ size_t i;
+
+ SWIG_InitRuntime();
+ mMarisa = rb_define_module("Marisa");
+
+ SWIG_InitializeModule(0);
+ for (i = 0; i < swig_module.size; i++) {
+ SWIG_define_class(swig_module.types[i]);
+ }
+
+ SWIG_RubyInitializeTrackings();
+ rb_define_const(mMarisa, "OK", SWIG_From_int(static_cast< int >(marisa_swig::OK)));
+ rb_define_const(mMarisa, "STATE_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::STATE_ERROR)));
+ rb_define_const(mMarisa, "NULL_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::NULL_ERROR)));
+ rb_define_const(mMarisa, "BOUND_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::BOUND_ERROR)));
+ rb_define_const(mMarisa, "RANGE_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::RANGE_ERROR)));
+ rb_define_const(mMarisa, "CODE_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::CODE_ERROR)));
+ rb_define_const(mMarisa, "RESET_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::RESET_ERROR)));
+ rb_define_const(mMarisa, "SIZE_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::SIZE_ERROR)));
+ rb_define_const(mMarisa, "MEMORY_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::MEMORY_ERROR)));
+ rb_define_const(mMarisa, "IO_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::IO_ERROR)));
+ rb_define_const(mMarisa, "FORMAT_ERROR", SWIG_From_int(static_cast< int >(marisa_swig::FORMAT_ERROR)));
+ rb_define_const(mMarisa, "MIN_NUM_TRIES", SWIG_From_int(static_cast< int >(marisa_swig::MIN_NUM_TRIES)));
+ rb_define_const(mMarisa, "MAX_NUM_TRIES", SWIG_From_int(static_cast< int >(marisa_swig::MAX_NUM_TRIES)));
+ rb_define_const(mMarisa, "DEFAULT_NUM_TRIES", SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_NUM_TRIES)));
+ rb_define_const(mMarisa, "HUGE_CACHE", SWIG_From_int(static_cast< int >(marisa_swig::HUGE_CACHE)));
+ rb_define_const(mMarisa, "LARGE_CACHE", SWIG_From_int(static_cast< int >(marisa_swig::LARGE_CACHE)));
+ rb_define_const(mMarisa, "NORMAL_CACHE", SWIG_From_int(static_cast< int >(marisa_swig::NORMAL_CACHE)));
+ rb_define_const(mMarisa, "SMALL_CACHE", SWIG_From_int(static_cast< int >(marisa_swig::SMALL_CACHE)));
+ rb_define_const(mMarisa, "TINY_CACHE", SWIG_From_int(static_cast< int >(marisa_swig::TINY_CACHE)));
+ rb_define_const(mMarisa, "DEFAULT_CACHE", SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_CACHE)));
+ rb_define_const(mMarisa, "TEXT_TAIL", SWIG_From_int(static_cast< int >(marisa_swig::TEXT_TAIL)));
+ rb_define_const(mMarisa, "BINARY_TAIL", SWIG_From_int(static_cast< int >(marisa_swig::BINARY_TAIL)));
+ rb_define_const(mMarisa, "DEFAULT_TAIL", SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_TAIL)));
+ rb_define_const(mMarisa, "LABEL_ORDER", SWIG_From_int(static_cast< int >(marisa_swig::LABEL_ORDER)));
+ rb_define_const(mMarisa, "WEIGHT_ORDER", SWIG_From_int(static_cast< int >(marisa_swig::WEIGHT_ORDER)));
+ rb_define_const(mMarisa, "DEFAULT_ORDER", SWIG_From_int(static_cast< int >(marisa_swig::DEFAULT_ORDER)));
+
+ SwigClassKey.klass = rb_define_class_under(mMarisa, "Key", rb_cObject);
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Key, (void *) &SwigClassKey);
+ rb_undef_alloc_func(SwigClassKey.klass);
+ rb_define_method(SwigClassKey.klass, "str", VALUEFUNC(_wrap_Key_str), -1);
+ rb_define_method(SwigClassKey.klass, "id", VALUEFUNC(_wrap_Key_id), -1);
+ rb_define_method(SwigClassKey.klass, "weight", VALUEFUNC(_wrap_Key_weight), -1);
+ SwigClassKey.mark = 0;
+ SwigClassKey.destroy = (void (*)(void *)) free_marisa_swig_Key;
+ SwigClassKey.trackObjects = 0;
+
+ SwigClassQuery.klass = rb_define_class_under(mMarisa, "Query", rb_cObject);
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Query, (void *) &SwigClassQuery);
+ rb_undef_alloc_func(SwigClassQuery.klass);
+ rb_define_method(SwigClassQuery.klass, "str", VALUEFUNC(_wrap_Query_str), -1);
+ rb_define_method(SwigClassQuery.klass, "id", VALUEFUNC(_wrap_Query_id), -1);
+ SwigClassQuery.mark = 0;
+ SwigClassQuery.destroy = (void (*)(void *)) free_marisa_swig_Query;
+ SwigClassQuery.trackObjects = 0;
+
+ SwigClassKeyset.klass = rb_define_class_under(mMarisa, "Keyset", rb_cObject);
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Keyset, (void *) &SwigClassKeyset);
+ rb_define_alloc_func(SwigClassKeyset.klass, _wrap_Keyset_allocate);
+ rb_define_method(SwigClassKeyset.klass, "initialize", VALUEFUNC(_wrap_new_Keyset), -1);
+ rb_define_method(SwigClassKeyset.klass, "push_back", VALUEFUNC(_wrap_Keyset_push_back), -1);
+ rb_define_method(SwigClassKeyset.klass, "key", VALUEFUNC(_wrap_Keyset_key), -1);
+ rb_define_method(SwigClassKeyset.klass, "key_str", VALUEFUNC(_wrap_Keyset_key_str), -1);
+ rb_define_method(SwigClassKeyset.klass, "key_id", VALUEFUNC(_wrap_Keyset_key_id), -1);
+ rb_define_method(SwigClassKeyset.klass, "num_keys", VALUEFUNC(_wrap_Keyset_num_keys), -1);
+ rb_define_method(SwigClassKeyset.klass, "empty", VALUEFUNC(_wrap_Keyset_empty), -1);
+ rb_define_method(SwigClassKeyset.klass, "size", VALUEFUNC(_wrap_Keyset_size), -1);
+ rb_define_method(SwigClassKeyset.klass, "total_length", VALUEFUNC(_wrap_Keyset_total_length), -1);
+ rb_define_method(SwigClassKeyset.klass, "reset", VALUEFUNC(_wrap_Keyset_reset), -1);
+ rb_define_method(SwigClassKeyset.klass, "clear", VALUEFUNC(_wrap_Keyset_clear), -1);
+ SwigClassKeyset.mark = 0;
+ SwigClassKeyset.destroy = (void (*)(void *)) free_marisa_swig_Keyset;
+ SwigClassKeyset.trackObjects = 0;
+
+ SwigClassAgent.klass = rb_define_class_under(mMarisa, "Agent", rb_cObject);
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Agent, (void *) &SwigClassAgent);
+ rb_define_alloc_func(SwigClassAgent.klass, _wrap_Agent_allocate);
+ rb_define_method(SwigClassAgent.klass, "initialize", VALUEFUNC(_wrap_new_Agent), -1);
+ rb_define_method(SwigClassAgent.klass, "set_query", VALUEFUNC(_wrap_Agent_set_query), -1);
+ rb_define_method(SwigClassAgent.klass, "key", VALUEFUNC(_wrap_Agent_key), -1);
+ rb_define_method(SwigClassAgent.klass, "query", VALUEFUNC(_wrap_Agent_query), -1);
+ rb_define_method(SwigClassAgent.klass, "key_str", VALUEFUNC(_wrap_Agent_key_str), -1);
+ rb_define_method(SwigClassAgent.klass, "key_id", VALUEFUNC(_wrap_Agent_key_id), -1);
+ rb_define_method(SwigClassAgent.klass, "query_str", VALUEFUNC(_wrap_Agent_query_str), -1);
+ rb_define_method(SwigClassAgent.klass, "query_id", VALUEFUNC(_wrap_Agent_query_id), -1);
+ SwigClassAgent.mark = 0;
+ SwigClassAgent.destroy = (void (*)(void *)) free_marisa_swig_Agent;
+ SwigClassAgent.trackObjects = 0;
+
+ SwigClassTrie.klass = rb_define_class_under(mMarisa, "Trie", rb_cObject);
+ SWIG_TypeClientData(SWIGTYPE_p_marisa_swig__Trie, (void *) &SwigClassTrie);
+ rb_define_alloc_func(SwigClassTrie.klass, _wrap_Trie_allocate);
+ rb_define_method(SwigClassTrie.klass, "initialize", VALUEFUNC(_wrap_new_Trie), -1);
+ rb_define_method(SwigClassTrie.klass, "build", VALUEFUNC(_wrap_Trie_build), -1);
+ rb_define_method(SwigClassTrie.klass, "mmap", VALUEFUNC(_wrap_Trie_mmap), -1);
+ rb_define_method(SwigClassTrie.klass, "load", VALUEFUNC(_wrap_Trie_load), -1);
+ rb_define_method(SwigClassTrie.klass, "save", VALUEFUNC(_wrap_Trie_save), -1);
+ rb_define_method(SwigClassTrie.klass, "common_prefix_search", VALUEFUNC(_wrap_Trie_common_prefix_search), -1);
+ rb_define_method(SwigClassTrie.klass, "predictive_search", VALUEFUNC(_wrap_Trie_predictive_search), -1);
+ rb_define_method(SwigClassTrie.klass, "lookup", VALUEFUNC(_wrap_Trie_lookup), -1);
+ rb_define_method(SwigClassTrie.klass, "reverse_lookup", VALUEFUNC(_wrap_Trie_reverse_lookup), -1);
+ rb_define_method(SwigClassTrie.klass, "num_tries", VALUEFUNC(_wrap_Trie_num_tries), -1);
+ rb_define_method(SwigClassTrie.klass, "num_keys", VALUEFUNC(_wrap_Trie_num_keys), -1);
+ rb_define_method(SwigClassTrie.klass, "num_nodes", VALUEFUNC(_wrap_Trie_num_nodes), -1);
+ rb_define_method(SwigClassTrie.klass, "tail_mode", VALUEFUNC(_wrap_Trie_tail_mode), -1);
+ rb_define_method(SwigClassTrie.klass, "node_order", VALUEFUNC(_wrap_Trie_node_order), -1);
+ rb_define_method(SwigClassTrie.klass, "empty", VALUEFUNC(_wrap_Trie_empty), -1);
+ rb_define_method(SwigClassTrie.klass, "size", VALUEFUNC(_wrap_Trie_size), -1);
+ rb_define_method(SwigClassTrie.klass, "total_size", VALUEFUNC(_wrap_Trie_total_size), -1);
+ rb_define_method(SwigClassTrie.klass, "io_size", VALUEFUNC(_wrap_Trie_io_size), -1);
+ rb_define_method(SwigClassTrie.klass, "clear", VALUEFUNC(_wrap_Trie_clear), -1);
+ SwigClassTrie.mark = 0;
+ SwigClassTrie.destroy = (void (*)(void *)) free_marisa_swig_Trie;
+ SwigClassTrie.trackObjects = 0;
+ rb_define_const(mMarisa, "INVALID_KEY_ID", SWIG_From_size_t(static_cast< size_t >(MARISA_INVALID_KEY_ID)));
+}
+
diff --git a/bindings/ruby/sample.rb b/bindings/ruby/sample.rb
new file mode 100644
index 0000000..1c8cc7a
--- /dev/null
+++ b/bindings/ruby/sample.rb
@@ -0,0 +1,61 @@
+require "marisa"
+
+keyset = Marisa::Keyset.new
+keyset.push_back("cake")
+keyset.push_back("cookie")
+keyset.push_back("ice")
+keyset.push_back("ice-cream")
+
+trie = Marisa::Trie.new
+trie.build(keyset)
+print("no. keys: ", trie.num_keys(), "\n")
+print("no. tries: ", trie.num_tries(), "\n")
+print("no. nodes: ", trie.num_nodes(), "\n")
+print("size: ", trie.io_size(), "\n")
+
+agent = Marisa::Agent.new
+
+agent.set_query("cake")
+trie.lookup(agent)
+print(agent.query_str(), ": ", agent.key_id(), "\n")
+
+agent.set_query("cookie")
+trie.lookup(agent)
+print(agent.query_str(), ": ", agent.key_id(), "\n")
+
+agent.set_query("cockoo")
+if not trie.lookup(agent)
+ print(agent.query_str(), ": not found\n")
+end
+
+print("ice: ", trie.lookup("ice"), "\n")
+print("ice-cream: ", trie.lookup("ice-cream"), "\n")
+if trie.lookup("ice-age") == Marisa::INVALID_KEY_ID
+ print("ice-age: not found\n")
+end
+
+trie.save("sample.dic")
+trie.load("sample.dic")
+
+agent.set_query(0)
+trie.reverse_lookup(agent)
+print(agent.query_id(), ": ", agent.key_str(), "\n")
+
+agent.set_query(1)
+trie.reverse_lookup(agent)
+print(agent.query_id(), ": ", agent.key_str(), "\n")
+
+print("2: ", trie.reverse_lookup(2), "\n")
+print("3: ", trie.reverse_lookup(3), "\n")
+
+trie.mmap("sample.dic")
+
+agent.set_query("ice-cream soda")
+while trie.common_prefix_search(agent)
+ print(agent.query_str(), ": ", agent.key_str(), " (", agent.key_id(), ")\n")
+end
+
+agent.set_query("ic")
+while trie.predictive_search(agent)
+ print(agent.query_str(), ": ", agent.key_str(), " (", agent.key_id(), ")\n")
+end
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..118a677
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,278 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.67])
+AC_INIT([marisa], [0.2.6], [susumu.yata@gmail.com])
+AC_CONFIG_SRCDIR([include/marisa.h])
+AM_INIT_AUTOMAKE([foreign])
+
+# Checks for programs.
+LT_INIT
+AC_PROG_CXX
+AC_PROG_INSTALL
+
+AC_CONFIG_MACRO_DIR([m4])
+
+# Macros for SSE availability check.
+AC_DEFUN([MARISA_ENABLE_SSE2],
+ [AC_EGREP_CPP([yes], [
+#ifdef __SSE2__
+yes
+#endif
+ ], [enable_sse2="yes"], [enable_sse2="no"])])
+AC_DEFUN([MARISA_ENABLE_SSE3],
+ [AC_EGREP_CPP([yes], [
+#ifdef __SSE3__
+yes
+#endif
+ ], [enable_sse3="yes"], [enable_sse3="no"])])
+AC_DEFUN([MARISA_ENABLE_SSSE3],
+ [AC_EGREP_CPP([yes], [
+#ifdef __SSSE3__
+yes
+#endif
+ ], [enable_ssse3="yes"], [enable_ssse3="no"])])
+AC_DEFUN([MARISA_ENABLE_SSE4_1],
+ [AC_EGREP_CPP([yes], [
+#ifdef __SSE4_1__
+yes
+#endif
+ ], [enable_sse4_1="yes"], [enable_sse4_1="no"])])
+AC_DEFUN([MARISA_ENABLE_SSE4_2],
+ [AC_EGREP_CPP([yes], [
+#ifdef __SSE4_2__
+yes
+#endif
+ ], [enable_sse4_2="yes"], [enable_sse4_2="no"])])
+AC_DEFUN([MARISA_ENABLE_SSE4],
+ [AC_EGREP_CPP([yes], [
+#if defined(__POPCNT__) && defined(__SSE4_2__)
+yes
+#endif
+ ], [enable_sse4="yes"], [enable_sse4="no"])])
+AC_DEFUN([MARISA_ENABLE_SSE4A],
+ [AC_EGREP_CPP([yes], [
+#ifdef __SSE4A__
+yes
+#endif
+ ], [enable_sse4a="yes"], [enable_sse4a="no"])])
+AC_DEFUN([MARISA_ENABLE_POPCNT],
+ [AC_EGREP_CPP([yes], [
+#ifdef __POPCNT__
+yes
+#endif
+ ], [enable_popcnt="yes"], [enable_popcnt="no"])])
+AC_DEFUN([MARISA_ENABLE_BMI],
+ [AC_EGREP_CPP([yes], [
+#ifdef __BMI__
+yes
+#endif
+ ], [enable_bmi="yes"], [enable_bmi="no"])])
+AC_DEFUN([MARISA_ENABLE_BMI2],
+ [AC_EGREP_CPP([yes], [
+#ifdef __BMI2__
+yes
+#endif
+ ], [enable_bmi2="yes"], [enable_bmi2="no"])])
+
+# Enable native cpu instructions.
+AC_MSG_CHECKING([whether to enable optimization for native cpu])
+AC_ARG_ENABLE([native-code],
+ [AS_HELP_STRING([--enable-native-code],
+ [generate instructions for native cpu [default=no]])],
+ [],
+ [enable_native_code="no"])
+AS_IF([test "x${enable_native_code}" != "xno"], [
+ CPPFLAGS="$CPPFLAGS -march=native"
+ MARISA_ENABLE_SSE2
+ MARISA_ENABLE_SSE3
+ MARISA_ENABLE_SSE4_1
+ MARISA_ENABLE_SSE4_2
+ MARISA_ENABLE_SSE4
+ MARISA_ENABLE_SSE4A
+ MARISA_ENABLE_POPCNT
+ MARISA_ENABLE_BMI
+ MARISA_ENABLE_BMI2
+])
+AC_MSG_RESULT([${enable_native_code}])
+
+# Checks for SSE availability.
+AC_MSG_CHECKING([whether to use SSE2])
+AC_ARG_ENABLE([sse2],
+ [AS_HELP_STRING([--enable-sse2],
+ [use SSE2 [default=no]])],
+ [],
+ [enable_sse2="no"])
+AS_IF([test "x${enable_sse2}" != "xno"], [enable_sse2="yes"])
+AC_MSG_RESULT([${enable_sse2}])
+
+AC_MSG_CHECKING([whether to use SSE3])
+AC_ARG_ENABLE([sse3],
+ [AS_HELP_STRING([--enable-sse3],
+ [use SSE3 [default=no]])],
+ [],
+ [enable_sse3="no"])
+AS_IF([test "x${enable_sse3}" != "xno"], [enable_sse3="yes"])
+AC_MSG_RESULT([${enable_sse3}])
+
+AC_MSG_CHECKING([whether to use SSSE3])
+AC_ARG_ENABLE([ssse3],
+ [AS_HELP_STRING([--enable-ssse3],
+ [use SSSE3 [default=no]])],
+ [],
+ [enable_ssse3="no"])
+AS_IF([test "x${enable_ssse3}" != "xno"], [enable_ssse3="yes"])
+AC_MSG_RESULT([${enable_ssse3}])
+
+AC_MSG_CHECKING([whether to use SSE4.1])
+AC_ARG_ENABLE([sse4.1],
+ [AS_HELP_STRING([--enable-sse4.1],
+ [use SSE4.1 [default=no]])],
+ [],
+ [enable_sse4_1="no"])
+AS_IF([test "x${enable_sse4_1}" != "xno"], [enable_sse4_1="yes"])
+AC_MSG_RESULT([${enable_sse4_1}])
+
+AC_MSG_CHECKING([whether to use SSE4.2])
+AC_ARG_ENABLE([sse4.2],
+ [AS_HELP_STRING([--enable-sse4.2],
+ [use SSE4.2 [default=no]])],
+ [],
+ [enable_sse4_2="no"])
+AS_IF([test "x${enable_sse4_2}" != "xno"], [enable_sse4_2="yes"])
+AC_MSG_RESULT([${enable_sse4_2}])
+
+AC_MSG_CHECKING([whether to use SSE4])
+AC_ARG_ENABLE([sse4],
+ [AS_HELP_STRING([--enable-sse4],
+ [use SSE4 [default=no]])],
+ [],
+ [enable_sse4="no"])
+AS_IF([test "x${enable_sse4}" != "xno"], [enable_sse4="yes"])
+AC_MSG_RESULT([${enable_sse4}])
+
+AC_MSG_CHECKING([whether to use SSE4a])
+AC_ARG_ENABLE([sse4a],
+ [AS_HELP_STRING([--enable-sse4a],
+ [use SSE4a [default=no]])],
+ [],
+ [enable_sse4a="no"])
+AS_IF([test "x${enable_sse4a}" != "xno"], [enable_sse4a="yes"])
+AC_MSG_RESULT([${enable_sse4a}])
+
+AC_MSG_CHECKING([whether to use popcnt])
+AC_ARG_ENABLE([popcnt],
+ [AS_HELP_STRING([--enable-popcnt],
+ [use POPCNT [default=no]])],
+ [],
+ [enable_popcnt="no"])
+AS_IF([test "x${enable_popcnt}" != "xno"], [enable_popcnt="yes"])
+AC_MSG_RESULT([${enable_popcnt}])
+
+AC_MSG_CHECKING([whether to use BMI])
+AC_ARG_ENABLE([bmi],
+ [AS_HELP_STRING([--enable-bmi],
+ [use BMI [default=no]])],
+ [],
+ [enable_bmi="no"])
+AS_IF([test "x${enable_bmi}" != "xno"], [enable_bmi="yes"])
+AC_MSG_RESULT([${enable_bmi}])
+
+AC_MSG_CHECKING([whether to use BMI2])
+AC_ARG_ENABLE([bmi2],
+ [AS_HELP_STRING([--enable-bmi2],
+ [use BMI2 [default=no]])],
+ [],
+ [enable_bmi2="no"])
+AS_IF([test "x${enable_bmi2}" != "xno"], [enable_bmi2="yes"])
+AC_MSG_RESULT([${enable_bmi2}])
+
+AS_IF([test "x${enable_bmi2}" != "xno"], [
+ enable_bmi="yes"
+])
+AS_IF([test "x${enable_bmi}" != "xno"], [
+ enable_sse4="yes"
+])
+AS_IF([test "x${enable_popcnt}" != "xno"], [
+ enable_sse3="yes"
+])
+AS_IF([test "x${enable_sse4a}" != "xno"], [
+ enable_popcnt="yes"
+ enable_sse3="yes"
+])
+AS_IF([test "x${enable_sse4}" != "xno"], [
+ enable_popcnt="yes"
+ enable_sse4_2="yes"
+])
+AS_IF([test "x${enable_sse4_2}" != "xno"], [
+ enable_popcnt="yes"
+ enable_sse4_1="yes"
+])
+AS_IF([test "x${enable_sse4_1}" != "xno"], [
+ enable_ssse3="yes"
+])
+AS_IF([test "x${enable_ssse3}" != "xno"], [
+ enable_sse3="yes"
+])
+AS_IF([test "x${enable_sse3}" != "xno"], [
+ enable_sse2="yes"
+])
+
+AS_IF([test "x${enable_popcnt}" != "xno"], [
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_POPCNT -mpopcnt"
+])
+if test "x${enable_bmi2}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_BMI2 -mbmi2 -msse4"
+elif test "x${enable_bmi}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_BMI -mbmi -msse4"
+elif test "x${enable_sse4a}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSE4A -msse4a"
+elif test "x${enable_sse4}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSE4 -msse4"
+elif test "x${enable_sse4_2}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSE4_2 -msse4.2"
+elif test "x${enable_sse4_1}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSE4_1 -msse4.1"
+elif test "x${enable_ssse3}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSSE3 -mssse3"
+elif test "x${enable_sse3}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSE3 -msse3"
+elif test "x${enable_sse2}" != "xno"; then
+ CXXFLAGS="$CXXFLAGS -DMARISA_USE_SSE2 -msse2"
+fi
+
+AC_CONFIG_FILES([Makefile
+ marisa.pc
+ include/Makefile
+ include/marisa/Makefile
+ lib/Makefile
+ lib/marisa/Makefile
+ lib/marisa/grimoire/Makefile
+ lib/marisa/grimoire/algorithm/Makefile
+ lib/marisa/grimoire/io/Makefile
+ lib/marisa/grimoire/trie/Makefile
+ lib/marisa/grimoire/vector/Makefile
+ tests/Makefile
+ tools/Makefile])
+AC_OUTPUT
+
+AS_ECHO([])
+AS_ECHO(["${PACKAGE_NAME} ${PACKAGE_VERSION} configuration:"])
+AS_ECHO(["-------------------------------"])
+AS_ECHO([" HOST: ${host}"])
+AS_ECHO([" CXX: ${CXX}"])
+AS_ECHO([" CXXFLAGS: ${CXXFLAGS}"])
+AS_ECHO([" LDFLAGS: ${LDFLAGS}"])
+AS_ECHO([" PREFIX: ${prefix}"])
+AS_ECHO([])
+AS_ECHO([" NATIVE: ${enable_native_code}"])
+AS_ECHO([" SSE2: ${enable_sse2}"])
+AS_ECHO([" SSE3: ${enable_sse3}"])
+AS_ECHO([" SSSE3: ${enable_ssse3}"])
+AS_ECHO([" SSE4.1: ${enable_sse4_1}"])
+AS_ECHO([" SSE4.2: ${enable_sse4_2}"])
+AS_ECHO([" SSE4a: ${enable_sse4a}"])
+AS_ECHO([" POPCNT: ${enable_popcnt}"])
+AS_ECHO([" BMI: ${enable_bmi}"])
+AS_ECHO([" BMI2: ${enable_bmi2}"])
+AS_ECHO([])
diff --git a/docs/readme.en.html b/docs/readme.en.html
new file mode 100644
index 0000000..2ab260a
--- /dev/null
+++ b/docs/readme.en.html
@@ -0,0 +1,752 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>MARISA: Matching Algorithm with Recursively Implemented StorAge</title>
+ <link rel="stylesheet" type="text/css" href="./style.css">
+ </head>
+ <body>
+ <div id="header">
+ <div class="left">MARISA: Matching Algorithm with Recursively Implemented StorAge</div>
+ <div class="right">Last modified: 14 Jun 2020</div>
+ <div class="end"></div>
+ </div><!-- header -->
+ <div id="body" style="text-align: justify">
+ <h1>MARISA: Matching Algorithm with Recursively Implemented StorAge</h1>
+ <p id="abstract">
+ <span id="heading">Abstract: </span>
+ Matching Algorithm with Recursively Implemented StorAge (MARISA) is a space-efficient trie data structure. libmarisa is a C++ library for an implementation of MARISA. Users can build dictionaries and search keys from the dictionaries. The package also provides command line tools to test basic operations of libmarisa, and the tools are useful to test the performance.
+ </p><!-- abstract -->
+
+ <div class="section">
+ <h2><a name="introduction">Introduction</a></h2>
+ <div class="subsection">
+ <h3><a name="overview">Overview</a></h3>
+ <p>
+ Matching Algorithm with Recursively Implemented StorAge (MARISA) is a space-efficient, fairly fast, and static trie data structure. MARISA serves as a dictionary structure, and by definition, it supports exact match lookup, which is the basic operation of dictionary. In addition, MARISA supports reverse lookup, common prefix search, and predictive search.
+ </p>
+ <p>
+ In most cases, MARISA is much more compact than a plain text which consists of the registered keys. This means that the traditional dictionary implementations, a binary tree (<code>std::map&lt;std::string, T&gt;</code>) and a hash table (<code>std::unordered_map&lt;std::string, T&gt;</code>), require more and more and more spaces than MARISA. Bloom Filter, a probabilistic data structure, is more space-efficient than MARISA but causes false positives and does not support reverse lookup, common prefix search, and predictive search.
+ </p>
+ <p>
+ libmarisa is a C++ library for an implementation of MARISA. Users can build dictionaries and search keys from the dictionaries. The package also provides command line tools to test basic operations of libmarisa, and the tools are useful to test the performance.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="ability">Functionality</a></h3>
+ <p>
+ libmarisa associates string keys with unique IDs, from <var>0</var> to <var>(n - 1)</var>, where <var>n</var> is the number of keys. Note that users cannot specify the IDs because the mapping is automatically generated by MARISA. Every search function takes a string or an ID and returns the search result which is represented by a pair of the key and its ID.
+ </p>
+ <ul>
+ <li>Lookup
+ <ul>
+ <li>checks whether or not a query string is registered.</li>
+ </ul>
+ </li>
+ <li>Reverse lookup
+ <ul>
+ <li>restores a key from its ID.</li>
+ </ul>
+ </li>
+ <li>Common prefix search
+ <ul>
+ <li>searches keys from the possible prefixes of a query string.</li>
+ </ul>
+ </li>
+ <li>Predictive search
+ <ul>
+ <li>searches keys starting with a query string.</li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- subsection -->
+ </div><!-- section -->
+ <div class="section">
+ <h2><a name="source">Source</a></h2>
+ <div class="subsection">
+ <h3><a name="license">License</a></h3>
+ <p>
+ libmarisa and its command line tools are dual-licensed under the BSD 2-clause license and the LGPL.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="download">Download</a></h3>
+ <p>
+ The project is hosted on <a href="https://github.com/">GitHub</a>.
+ </p>
+ <ul>
+ <li>Project
+ <ul>
+ <li><a href="https://github.com/s-yata/marisa-trie">https://github.com/s-yata/marisa-trie</a></li>
+ </ul>
+ </li>
+ <li>Source
+ <ul>
+ <li><a href="https://github.com/s-yata/marisa-trie/archive/v0.2.6.tar.gz">marisa-0.2.6.tar.gz</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="install">Installation</a></h2>
+ <div class="subsection">
+ <h3><a name="gcc">GCC &amp; Clang</a></h3>
+ <div class="float">
+ <pre class="console">$ tar zxf marisa-0.2.6.tar.gz
+$ cd marisa-0.2.6
+$ ./configure
+$ make
+$ make check
+$ make install</pre>
+ </div><!-- float -->
+ <p>
+ Users can install libmarisa by using <kbd>configure</kbd> and <kbd>make</kbd>. <kbd>make install</kbd> might require <kbd>sudo</kbd> to install libmarisa as the root user. Additionally, <kbd>ldconfig</kbd> might be required because libmarisa is installed as a shared library in default settings.
+ </p>
+ <p>
+ If a POPCNT instruction is available on your environment, you can specify <kbd>--enable-popcnt</kbd>, when you run <kbd>configure</kbd>, to improve the performance of libmarisa. Likewise, <kbd>--enable-sse2</kbd>, <kbd>--enable-sse3</kbd>, <kbd>--enable-ssse3</kbd>, <kbd>--enable-sse4.1</kbd>, <kbd>--enable-sse4.2</kbd>, <kbd>--enable-sse4</kbd>, <kbd>--enable-sse4a</kbd>, <kbd>--enable-bmi</kbd>, <kbd>--enable-bmi2</kbd> are available. Note that <kbd>--enable-native-code</kbd> enables instructions available on the compilation environment. Also, if you need a static library, specify <kbd>--enable-static</kbd> to <kbd>configure</kbd>. For other options, see <kbd>./configure --help</kbd>.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Visual C++ 2008</a></h3>
+ <p>
+ There are project files for Visual C++ 2008 in <kbd>vs2008/</kbd>. Users can build a static library <kbd>libmarisa.lib</kbd> and the command line tools by using <kbd>vs2008/vs2008.sln</kbd>. If your Visual C++ is older than 2008. New projects are required to build libmarisa.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Perl Bindings</a></h3>
+ <div class="float">
+ <pre class="console">$ cd bindings/perl
+$ perl Makefile.PL
+$ make
+$ make install</pre>
+ </div><!-- float -->
+ <p>
+ Users can find a Perl bindings in <kbd>bindings/perl/</kbd>, in which the wrapper was generated by <a href="http://www.swig.org/">SWIG</a>. To install the Perl bindings, run <kbd>perl Makefile.PL</kbd> and then <kbd>make install</kbd>. See also <kbd>bindings/perl/sample.pl</kbd>.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Python Bindings</a></h3>
+ <div class="float">
+ <pre class="console">$ cd bindings/python
+$ python setup.py build
+$ python setup.py install</pre>
+ </div><!-- float -->
+ <p>
+ Users can find a Python bindings in <kbd>bindings/python/</kbd>, in which the wrapper was generated by <a href="http://www.swig.org/">SWIG</a>. To install the Python bindings, run <kbd>python setup.py install</kbd>. See also <kbd>bindings/python/sample.py</kbd>.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Ruby Bindings</a></h3>
+ <div class="float">
+ <pre class="console">$ cd bindings/ruby
+$ ruby extconf.rb
+$ make
+$ make install</pre>
+ </div><!-- float -->
+ <p>
+ Users can find a Ruby bindings in <kbd>bindings/ruby/</kbd>, in which the wrapper was generated by <a href="http://www.swig.org/">SWIG</a>. To install the Ruby bindings, run <kbd>ruby extconf.rb</kbd> and then <kbd>make install</kbd>. See also <kbd>bindings/ruby/sample.rb</kbd>.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Others</a></h3>
+ <p>
+ There are some other bindings.
+ </p>
+ <ul>
+ <li>Python
+ <ul>
+ <li><a href="https://github.com/kmike/marisa-trie/">https://github.com/kmike/marisa-trie/</a> an alternative Cython-based pip-installable Python bindings which is faster than the above Python bindings.</li>
+ </ul>
+ </li>
+ <li>Node.js</li>
+ <ul>
+ <li><a href="https://github.com/jakwings/iojs-marisa-trie">https://github.com/jakwings/iojs-marisa-trie</a> a wrapper of marisa-trie</li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="tools">Command Line Tools</a></h2>
+ <div class="subsection">
+ <h3><a name="marisa-build">marisa-build</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-build &lt; keyset.txt &gt; keyset.dic
+#keys: 9864459
+#nodes: 13473881
+size: 51044424</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-build</kbd> is a tool to build a dictionary from a set of keys. This tool takes as input newline-delimited keys and writes the dictionary to the standard output.
+ </p>
+ <p>
+ Users can specify parameters through command line options. See <kbd>marisa-build -h</kbd> for the list of options.
+ </p>
+ <p>
+ If an input line contains horizontal tabs, the last one serves as the delimiter between a key and its weight which is used to optimize the order of nodes. Estimated frequency of each key, given as the weight, may improve the search performance.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-lookup">marisa-lookup</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-lookup keyset.dic
+Marisa
+915465 Marisa
+What's_uuup
+-1 What's_uuup</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-lookup</kbd> is a tool to test exact match lookup. If a query string is registered, this tool prints the key and its ID. Otherwise, this tool prints the query with <var>-1</var>.
+ </p>
+ <p>
+ See <kbd>marisa-lookup -h</kbd> for the list of options.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-reverse-lookup">marisa-reverse-lookup</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-reverse-lookup keyset.dic
+1234567
+1234567 Goma_International_Airport</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-reverse-lookup</kbd> is a tool to test reverse lookup. If a given ID is not out-of-range, this tool restores the associated key and prints it. The available ID is <var>0</var> to <var>(n - 1)</var>, where <var>n</var> is the number of keys. Note that an out-of-range ID causes an error.
+ </p>
+ <p>
+ See <kbd>marisa-reverse-lookup -h</kbd> for the list of options.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-common-prefix-search">marisa-common-prefix-search</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-common-prefix-search keyset.dic
+USA
+3 found
+20 U USA
+1526 US USA
+37471 USA USA</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-common-prefix-search</kbd> is a tool to test common prefix search. This tool searches keys from the possible prefixes of a query string and then prints the first <var>m</var> keys, where <var>m</var> is one of the parameters.
+ </p>
+ <p>
+ See <kbd>marisa-common-prefix-search -h</kbd> for the list of options.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-predictive-search">marisa-predictive-search</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-predictive-search keyset.dic -n 2
+Touhou
+15 found
+975378 Touhou Touhou
+5508004 Touhou_Hisotensoku Touhou</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-predictive-search</kbd> is a tool to test predictive search. This tool searches keys starting with a query string and then prints the first <var>m</var> keys, where <var>m</var> is one of the parameters.
+ </p>
+ <p>
+ See <kbd>marisa-predictive-search -h</kbd> for the list of options.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-benchmark">marisa-benchmark</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-benchmark keyset.txt
+Number of tries: 1 - 5
+TAIL mode: Text mode
+Node order: Descending weight order
+Cache level: Normal cache
+Number of keys: 9864459
+Total length: 191858227
+------+----------+--------+--------+--------+--------+--------
+#tries size build lookup reverse prefix predict
+ lookup search search
+ [bytes] [K/s] [K/s] [K/s] [K/s] [K/s]
+------+----------+--------+--------+--------+--------+--------
+ 1 69905816 334.84 1368.16 1304.82 1080.44 605.92
+ 2 53635744 284.03 762.91 773.68 662.04 244.35
+ 3 51044424 278.89 688.86 703.60 604.44 212.00
+ 4 50309000 277.01 669.23 680.78 588.57 204.23
+ 5 50042232 275.93 636.83 674.26 562.08 199.48
+------+----------+--------+--------+--------+--------+--------</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-benchmark</kbd> is a tool to benchmark libmarisa. This tool takes the same input as <kbd>marisa-build</kbd> and measures the performance of libmarisa for the given set of keys. This tool is useful to fix dictionary settings.
+ </p>
+ <p>
+ For the search performance, <kbd>marisa-benchmark</kbd> measures the time to lookup or search keys in input order. When the keys are given in lexicographic order, few cache misses will occur in the benchmark. In contrast, when the keys are given in random order, many cache misses will occur in the benchmark.
+ </p>
+ <p>
+ See <kbd>marisa-benchmark -h</kbd> for the list of options.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-dump">marisa-dump</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-dump keyset.dic | head -3
+input: keyset.dic
+S
+St
+Sta</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-build</kbd> is a tool to dump a dictionary. This tool prints all the keys in a given dictionary.
+ </p>
+ <p>
+ Users can specify the delimiter through command line options. See <kbd>marisa-dump -h</kbd> for the list of options.
+ </p>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="library">Library</a></h2>
+ <div class="subsection">
+ <h3><a name="howto">How to Use</a></h3>
+ <div class="float">
+ <pre class="code">// sample.cc
+#include &lt;iostream&gt;
+#include &lt;marisa.h&gt;
+
+int main() {
+ marisa::Keyset keyset;
+ keyset.push_back("a");
+ keyset.push_back("app");
+ keyset.push_back("apple");
+
+ marisa::Trie trie;
+ trie.build(keyset);
+
+ marisa::Agent agent;
+ agent.set_query("apple");
+ while (trie.common_prefix_search(agent)) {
+ std::cout.write(agent.key().ptr(), agent.key().length());
+ std::cout &lt;&lt; ": " &lt;&lt; agent.key().id() &lt;&lt; std::endl;
+ }
+ return 0;
+}</pre>
+ </div><!-- float -->
+ <div class="float">
+ <pre class="console">$ g++ sample.cc -lmarisa
+$ ./a.out
+a: 0
+app: 1
+apple: 2</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa provides <kbd>marisa.h</kbd> in which all the headers are <code>#include</code>d. Also, libmarisa uses <code>namespace marisa</code>. All the classes and functions except enumeration types are given as members of this namespace. Note that <code>using namespace marisa</code> may cause a critical error. Finally, <kbd>gcc</kbd> and <kbd>clang</kbd> require an option, <kbd>-lmarisa</kbd>, to link libmarisa with an application.
+ </p>
+ <p>
+ The core components of libmarisa are <a href="#keyset">Keyset</a>, <a href="#agent">Agent</a>, and <a href="#trie">Trie</a>. In addition, libmarisa provides an exception class, <a href="#exception">Exception</a>, and two more classes, <a href="#key">Key</a> and <a href="#query">Query</a>, as members of <code>Keyset</code> and <code>Agent</code>.
+ </p>
+ <ul>
+ <li><code>Keyset</code>: A class to store a set of keys. This class is used to build a set of keys for building a dictionary. Also, this class is useful to store search results.</li>
+ <li><code>Agent</code>: A class to store a query and a result of search operations. Every search function takes a reference to this class.</li>
+ <li><code>Trie</code>: A dictionary class.</li>
+ </ul>
+ <p>
+ For more examples, you can find the source code of the command line tools in <kbd>tools/</kbd>. The source code is useful as an example of error handling, predicive search, etc.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="enum">Enumeration Constants</a></h3>
+ <div class="subsubsection">
+ <h4>Error Codes</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_error_code_ {
+ MARISA_OK = 0,
+ MARISA_STATE_ERROR = 1,
+ MARISA_NULL_ERROR = 2,
+ MARISA_BOUND_ERROR = 3,
+ MARISA_RANGE_ERROR = 4,
+ MARISA_CODE_ERROR = 5,
+ MARISA_RESET_ERROR = 6,
+ MARISA_SIZE_ERROR = 7,
+ MARISA_MEMORY_ERROR = 8,
+ MARISA_IO_ERROR = 9,
+ MARISA_FORMAT_ERROR = 10,
+} marisa_error_code;</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa throws an instance of <code>Exception</code> when an error occurs, such as a file I/O error (<var>MARISA_IO_ERROR</var>), a size limitation error (<var>MARISA_SIZE_ERROR</var>), etc. For details, see <kbd>marisa/base.h</kbd>.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Number of Tries</h4>
+ <div class="float">
+ <pre class="code">
+typedef enum marisa_num_tries_ {
+ MARISA_MIN_NUM_TRIES = 0x00001,
+ MARISA_MAX_NUM_TRIES = 0x0007F,
+ MARISA_DEFAULT_NUM_TRIES = 0x00003,
+} marisa_num_tries;</pre>
+ </div><!-- float -->
+ <p>
+ MARISA is a recursive data structure in which a patricia trie is used to represent another patricia trie. A deeper recursion makes a dictionary more compact but degrades the search performance. For this time-space tradeoff, libmarisa provides a parameter to limit the recursion depth, which is equivalent to the number of tries. <code>marisa_num_tries</code> gives the range and the default setting of this parameter.
+ </p>
+ <p>
+ The best setting depends on the set of keys and the applications. In most cases, libmarisa works well with the default setting, <var>MARISA_DEFAULT_NUM_TRIES</var>, but if the application requires better search performance, <var>MARISA_MIN_NUM_TRIES</var> may be a better choice. Also, if the application uses long and complicated keys, a deeper recursion may achieve much higher spece-efficiency. <kbd>marisa-benchmark</kbd> is useful to find the best setting.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Cache Size</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_cache_level_ {
+ MARISA_HUGE_CACHE = 0x00080,
+ MARISA_LARGE_CACHE = 0x00100,
+ MARISA_NORMAL_CACHE = 0x00200,
+ MARISA_SMALL_CACHE = 0x00400,
+ MARISA_TINY_CACHE = 0x00800,
+ MARISA_DEFAULT_CACHE = MARISA_NORMAL_CACHE
+} marisa_cache_level;</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa embeds a precomputed table to a dictionary. The table serves as transition cache which improves the search performance but increases the dictionary size. Cache size is the parameter of this time-space tradeoff.
+ </p>
+ <p>
+ <code>marisa_cache_level</code> gives a list of available cache size. Compared with <var>MARISA_NORMAL_CACHE</var>, <var>MARISA_LARGE_CACHE</var> is 2 times larger, <var>MARISA_HUGE_CACHE</var> is 4 times larger, <var>MARISA_SMALL_CACHE</var> is 2 times smaller, and <var>MARISA_TINY_CACHE</var> is 4 times smaller.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>TAIL Mode</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_tail_mode_ {
+ MARISA_TEXT_TAIL = 0x01000,
+ MARISA_BINARY_TAIL = 0x02000,
+ MARISA_DEFAULT_TAIL = MARISA_TEXT_TAIL,
+} marisa_tail_mode;</pre>
+ </div><!-- float -->
+ <p>
+ The last patricia trie of MARISA stores its multi-byte labels as strings and <code>marisa_tail_mode</code> gives a list of TAIL implementations.
+ </p>
+ <p>
+ <var>MARISA_TEXT_TAIL</var> stores labels as zero-terminated strings. If the labels contain <var>'\0'</var>, the TAIL mode is automatically switched to <var>MARISA_BINARY_TAIL</var>.
+ </p>
+ <p>
+ On the other hand, <var>MARISA_BINARY_TAIL</var> uses a bit vector, instead of <var>'\0'</var>, to detect the end of labels. This means that <var>MARISA_TEXT_TAIL</var> is more space-efficient than <var>MARISA_BINARY_TAIL</var> when the average length of multi-byte labels is longer than <var>8 bytes</var>.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Node Order</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_node_order_ {
+ MARISA_LABEL_ORDER = 0x10000,
+ MARISA_WEIGHT_ORDER = 0x20000,
+ MARISA_DEFAULT_ORDER = MARISA_WEIGHT_ORDER,
+} marisa_node_order;</pre>
+ </div><!-- float -->
+ <p>
+ A dictionary has one more parameter, which is the order of nodes. There are two choices, <var>MARISA_LABEL_ORDER</var> and <var>MARISA_WEIGHT_ORDER</var>. The former arranges nodes in ascending order of the label and the latter arranges nodes in descending order of the weight. Many trie implementations arrange nodes in the label order but libmarisa uses <var>MARISA_WEIGHT_ORDER</var> as the default setting.
+ </p>
+ <p>
+ <var>MARISA_WEIGHT_ORDER</var> optimizes the node order for linear search performed in exact match lookup, common prefix search, and predictive search. In practice, experiments for English words/phrases showed that <var>MARISA_WEIGHT_ORDER</var> halved the average search time. On the other hand, <var>MARISA_LABEL_ORDER</var> enables predictive search to restore keys in lexicographic order.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Aliases</h4>
+ <div class="float">
+ <pre class="code">namespace marisa {
+ typedef ::marisa_error_code ErrorCode;
+ typedef ::marisa_cache_level CacheLevel;
+ typedef ::marisa_tail_mode TailMode;
+ typedef ::marisa_node_order NodeOrder;
+} // namespace marisa</pre>
+ </div><!-- float -->
+ <p>
+ The above enumeration types are defined in the global namespace to avoid collisions of the enumeration constants with macros provided by other modules. libmarisa provides type aliases and users can choose the familiar one.
+ </p>
+ </div><!-- subsubsection -->
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="exception">class Exception</a></h3>
+ <div class="float">
+ <pre class="code">class Exception {
+ public:
+ const char *filename() const;
+ int line() const;
+ ErrorCode error_code() const;
+ const char *error_message() const;
+
+ const char *what() const;
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Exception</code> is an exception class. libmarisa throws an instance of <code>Exception</code> with the file name (<code>__FILE__</code>), the line number (<code>__LINE__</code>), and an error code (<code>ErrorCode</code>) when an error is detected. The instance also has an error message formatted <var>__FILE__:__LINE__: error_code: error_message</var>.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="key">class Key</a></h3>
+ <div class="float">
+ <pre class="code">class Key {
+ public:
+ char operator[](std::size_t i) const;
+ const char *ptr() const;
+ std::size_t length() const;
+ std::size_t id() const;
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Key</code> is a member of <a href="#keyset">Keyset</a> and <a href="#agent">Agent</a>. Each key of <code>Keyset</code> is represented by this class. Also, the search result of <code>Agent</code> is represented by this class.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="query">class Query</a></h3>
+ <div class="float">
+ <pre class="code">class Query {
+ public:
+ char operator[](std::size_t i) const;
+ const char *ptr() const;
+ std::size_t length() const;
+ std::size_t id() const;
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Query</code> is a member of <a href="#agent">Agent</a>. This class stores a query string and an ID as input for search functions. Users cannot make changes directly to <code>Query</code> because <code>Agent</code> provides a special interface to update its query.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="keyset">class Keyset</a></h3>
+ <div class="float">
+ <pre class="code">class Keyset {
+ public:
+ Keyset();
+
+ void push_back(const Key &amp;key);
+ void push_back(const Key &amp;key, char end_marker);
+
+ void push_back(const char *str);
+ void push_back(const char *ptr,
+ std::size_t length,
+ float weight = 1.0);
+
+ const Key &amp;operator[](std::size_t i) const;
+ Key &amp;operator[](std::size_t i);
+
+ std::size_t num_keys();
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_length() const;
+
+ void reset();
+
+ void clear();
+ void swap(Keyset &amp;rhs);
+};</pre>
+ </div><!-- float -->
+ <div class="subsubsection">
+ <h4>Overview</h4>
+ <p>
+ <code>Keyset</code> is used to store a set of keys for dictionary construction or to save the results of search functions.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Dictionary Source</h4>
+ <p>
+ For dictionary construction, users append keys to <code>Keyset</code> by using <code>push_back()</code> and then pass the keyset to <code>build()</code> of <a href="#trie">Trie</a>. <var>weight</var> is an argument to receive the frequency or possibility of each key. If there are same keys, the weights are accumulated in dictionary construction.
+ </p>
+ <p>
+ After dictionary construction, users can read the associated IDs through <code>operator[]()</code>. Instead, the weights are overwritten by the IDs because <code>Key</code> uses a <code>union</code> to store a weight or an ID.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Search Result</h4>
+ <p>
+ Users can save a search result to <code>Keyset</code> by using <code>push_back()</code>. When <code>key()</code> of <a href="#agent">Agent</a> is given, a copy of the search result is stored in <code>Keyset</code>. If you want to append an end marker, such as <code>'\0'</code>, use <var>end_marker</var> of <code>push_back()</code>.
+ </p>
+ <p>
+ If you want to reuse an instance of <code>Keyset</code>, <code>reset()</code> may be a better choice than <code>clear()</code> because <code>reset()</code> keeps allocated memory in order to reduce memory allocation overhead.
+ </p>
+ <p>
+ <code>num_keys()</code> and <code>size()</code> return the number of keys. <code>empty()</code> checks whether the number of keys is <var>0</var> or not. <code>total_length()</code> returns the total length in byte.
+ </p>
+ </div><!-- subsubsection -->
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="agent">class Agent</a></h3>
+ <div class="float">
+ <pre class="code">class Agent {
+ public:
+ Agent();
+
+ const Query &amp;query() const;
+ const Key &amp;key() const;
+
+ void set_query(const char *str);
+ void set_query(const char *ptr,
+ std::size_t length);
+ void set_query(std::size_t key_id);
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Agent</code> is actually a tuple of <code>Query</code>, <code>Key</code>, and <code>State</code>. This class is used as I/O of search functions. Also, <code>State</code> is an incomplete type to keep the internal state of search operation.
+ </p>
+ <p>
+ A lookup operation requires 3 steps as follows: 1. sets a query string by <code>set_query()</code> of <code>Agent</code>, 2. passes the agent to <code>lookup()</code> of <code>Trie</code>, and 3. gets the search result by <code>key()</code> of <code>Agent</code>. The other operations proceed in the same way.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="trie">class Trie</a></h3>
+ <div class="float">
+ <pre class="code">class Trie {
+ public:
+ Trie();
+
+ void build(Keyset &amp;keyset,
+ int config_flags = 0);
+
+ void mmap(const char *filename);
+ void map(const void *ptr,
+ std::size_t size);
+
+ void load(const char *filename);
+ void read(int fd);
+
+ void save(const char *filename) const;
+ void write(int fd) const;
+
+ bool lookup(Agent &amp;agent) const;
+ void reverse_lookup(Agent &amp;agent) const;
+ bool common_prefix_search(Agent &amp;agent) const;
+ bool predictive_search(Agent &amp;agent) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t io_size() const;
+
+ void clear();
+ void swap(Trie &amp;rhs);
+};</pre>
+ </div><!-- float -->
+ <div class="subsubsection">
+ <h4>Overview</h4>
+ <p>
+ <code>Trie</code> is a dictionary class, which is the most important component of libmarisa. All the operations are performed through this class.
+ </p>
+ <p>
+ In fact, <code>Trie</code> is a dictionary handle, and if the handle is invalid, functions other than <code>build()</code>, <code>mmap()</code>, <code>map()</code>, <code>load()</code>, <code>read()</code>, <code>clear()</code>, <code>swap()</code> throw an exception.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Construction</h4>
+ <p>
+ You can build a dictionary by using <code>build()</code>. The arguments are the above mentioned <a href="#keyset">Keyset</a> and a dictionary setting, <var>config_flags</var>, which is represented by a combination of flags. For example, <var>2 | MARISA_BINARY_TAIL</var> specifies the maximum number of tries (<var>2</var>) and a TAIL mode (<var>MARISA_BINARY_TAIL</var>). Also, in this case, the default settings, <var>MARISA_DEFAULT_ORDER</var> and <var>MARISA_DEFAULT_CACHE</var>, are used for the node order and the cache size.
+ </p>
+ <p>
+ The IDs associated with the keys are available through <code>operator[]()</code> of <var>keyset</var>, and the IDs are useful to associate the keys with any data types.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>File I/O</h4>
+ <p>
+ <code>mmap()</code> is an interface for memory mapped I/O. If an application performs a few search operations, it is unnecessary to read the whole dictionary, and in such a case, <code>mmap()</code> is useful. Also, memory mapped I/O is an easy way to share dictionary data among processes. On the other hand, if an application performs a lot of search operations, a memory mapped dictionary might cause a lot of random disk accesses which considerably increase the search time.
+ </p>
+ <p>
+ <code>map()</code> restores an instance of <code>Trie</code> from dictionary data on memory. <code>load()</code> and <code>read()</code> read a dictionary from a file or a file descriptor. <code>save()</code> and <code>write()</code> write a dictionary to a file or a file descriptor.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>Search</h4>
+ <p>
+ <code>Trie</code> provides 4 search functions <code>lookup()</code>, <code>reverse_lookup()</code>, <code>common_prefix_search()</code>, and <code>predictive_search()</code> as follows:
+ </p>
+ <ul>
+ <li>
+ <code>lookup()</code> checks whether a query string is registered or not, and if it is registered, <code>lookup()</code> returns <var>true</var>. In this case, the search result is available through <code>agent.key()</code>. Note that <code>lookup()</code> does not restore a key and <code>agent.key().ptr()</code> points to the query string because the two strings are the same.
+ </li>
+ <li>
+ <code>reverse_lookup()</code> restores a key from its ID. This function has no return value and the key is available through <var>agent.key()</var>. The key is actually stored in <var>agent</var> and it is lost when <var>agent</var> is reset or used for another search operation. If a given ID is out-of-range, <code>reverse_lookup()</code> throws an exception.
+ </li>
+ <li>
+ <code>common_prefix_search()</code> searches keys from the possible prefixes of a query string. If there are matching keys, this function returns <var>true</var>. In this case, the first key is available through <code>agent.key()</code>, and if there are more than one matching keys, the next key will be available after the next <code>common_prefix_search()</code> which returns <var>true</var> until there are no more matching keys. Note that <code>agent.key().ptr() == agent.query().ptr()</code> is always <var>true</var> when <code>common_prefix_search()</code> has returned <var>true</var>.
+ </li>
+ <li>
+ <code>predictive_search()</code> searches keys starting with a query string, and similar to <code>common_prefix_search()</code>, this function returns <var>true</var> until there are no more matching keys.
+ </li>
+ </ul>
+ <p>
+ Note that <code>agent</code> keeps the internal state of <code>common_prefix_search()</code> and <code>predictive_search()</code> until <code>agent</code> is passed to another search function or <code>agent.set_query()</code> is called.
+ </p>
+ <p>
+ <code>num_keys()</code> and <code>size()</code> return the number of keys. <code>empty()</code> checks whether the number of keys is <var>0</var> or not. <code>io_size()</code> returns the dictionary size in byte.
+ </p>
+ </div><!-- subsubsection -->
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="stdio">stdio</a></h3>
+ <div class="float">
+ <pre class="code">void fread(std::FILE *file, Trie *trie);
+void fwrite(std::FILE *file, const Trie &amp;trie);</pre>
+ </div><!-- float -->
+ <p>
+ The functions for I/O using <code>std::FILE</code> are declared in <kbd>marisa/stdio.h</kbd>. If you don't want to <code>#include &lt;cstdio&gt;</code>, use <kbd>marisa/trie.h</kbd> instead of <kbd>marisa.h</kbd>.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="iostream">iostream</a></h3>
+ <div class="float">
+ <pre class="code">std::istream &amp;read(std::istream &amp;stream, Trie *trie);
+std::ostream &amp;write(std::ostream &amp;stream, const Trie &amp;trie);
+
+std::istream &amp;operator>>(std::istream &amp;stream, Trie &amp;trie);
+std::ostream &amp;operator<<(std::ostream &amp;stream, const Trie &amp;trie);</pre>
+ </div><!-- float -->
+ <p>
+ The functions for I/O using <code>std::iostream</code> are declared in <kbd>marisa/iostream.h</kbd>. If you don't want to <code>#include &lt;iosfwd&gt;</code>, use <kbd>marisa/trie.h</kbd> instead of <kbd>marisa.h</kbd>.
+ </p>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="compatibility">Cross-architecture compatibility</a></h2>
+ <p>
+ The dictionary format of libmarisa depends on the architecture. Dictionaries built on a little endian architecture don't work on a big endian architecture. Also, on a big endian architecture, dictionaries built on a 32-bit machine don't work on a 64-bit machine and vise versa. On a little endian architecture, dictionaries are compatible on 32/64-bit machines.
+ </p>
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="references">References</a></h2>
+ <ul>
+ <li><a href="https://www.slideshare.net/s5yata/x86opti-05-s5yata">Remove Branches in BitVector Select Operations - marisa 0.2.2 -</a>
+ <ul>
+ <li>This PowerPoint presentation describes improvements in marisa 0.2.2.</li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="conclusion">Last Spell</a></h2>
+ <p>
+ Feel free to contact me for any questions.
+ </p>
+ </div><!-- section -->
+ </div><!-- body -->
+ <div id="footer">
+ <div class="left">MARISA: Matching Algorithm with Recursively Implemented StorAge</div>
+ <div class="right">
+ ‮moc.liamg@atay.umusus‭
+ </div>
+ <div class="end"></div>
+ </div><!-- footer -->
+ </body>
+</html>
diff --git a/docs/readme.ja.html b/docs/readme.ja.html
new file mode 100644
index 0000000..3ee616e
--- /dev/null
+++ b/docs/readme.ja.html
@@ -0,0 +1,762 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="ja">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <title>MARISA: Matching Algorithm with Recursively Implemented StorAge</title>
+ <link rel="stylesheet" type="text/css" href="./style.css">
+ </head>
+ <body>
+ <div id="header">
+ <div class="left">MARISA: Matching Algorithm with Recursively Implemented StorAge</div>
+ <div class="right">Last modified: 14 Jun 2020</div>
+ <div class="end"></div>
+ </div><!-- header -->
+ <div id="body">
+ <h1>MARISA: Matching Algorithm with Recursively Implemented StorAge</h1>
+ <p id="abstract">
+ <span id="heading">Abstract: </span>
+ Matching Algorithm with Recursively Implemented StorAge (MARISA) は Trie をコンパクトに表現する程度の能力を持つデータ構造です.libmarisa は MARISA を C++ で実装したライブラリであり,MARISA による辞書を構築したり,辞書からの検索をおこなったりできます.libmarisa の基本的な機能に対応するコマンドラインツールを用意しているので,辞書のサイズがどのくらいになるのか,検索にどのくらい時間がかかるのか,などを手軽に試すことができます.
+ </p><!-- abstract -->
+
+ <div class="section">
+ <h2><a name="introduction">はじめに</a></h2>
+ <div class="subsection">
+ <h3><a name="overview">概要</a></h3>
+ <p>
+ Matching Algorithm with Recursively Implemented StorAge (MARISA) は Trie に対するコンパクトなデータ構造であり,動的な更新には対応していないものの,高い空間効率とそれなりの時間効率を実現できます.また,Trie の特徴を引き継いでいるため,MARISA による辞書は,単純な辞書引きだけでなく,逆引き,Common Prefix Search や Predictive Search を効率良く実現できます.
+ </p>
+ <p>
+ ほとんどの場合,MARISA による辞書は,登録文字列の集合を連結してできるテキストと比べて,ずっとコンパクトになります.そのため,登録文字列をそのまま保持する標準的な二分探索木やハッシュ表と比べると,ずーっとコンパクトです.一方で,確率的なデータ構造である Bloom Filter と比べてみると,空間効率の面では劣りますが,False Positive がなく,逆引きに加えて Common Prefix Search や Predictive Search を効率良く実現できることが特徴になります.
+ </p>
+ <p>
+ libmarisa は MARISA を C++ で実装したライブラリであり,MARISA による辞書を構築したり,辞書からの検索をおこなったりできます.libmarisa の基本的な機能に対応するコマンドラインツールを用意しているので,辞書のサイズがどのくらいになるのか,検索にどのくらい時間がかかるのか,などを手軽に試すことができます.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="ability">できること</a></h3>
+ <p>
+ libmarisa による辞書の構築では,登録文字列に <var>0</var> から順に固有の ID を割り当てるようになっています.ID は自動的に割り当てられるので,登録文字列に任意の ID を割り当てることはできません.検索においては,文字列あるいは ID をクエリとして受け取り,適合する登録文字列と ID の組を検索結果として返すようになっています.
+ </p>
+ <ul>
+ <li>辞書引き(Lookup)
+ <ul>
+ <li>入力文字列が登録されているかどうかを確認します.</li>
+ </ul>
+ </li>
+ <li>逆引き(Reverse Lookup)
+ <ul>
+ <li>入力された ID から登録文字列を復元します.</li>
+ </ul>
+ </li>
+ <li>Common Prefix Search
+ <ul>
+ <li>入力文字列の前半部分に一致する登録文字列を検索します.</li>
+ </ul>
+ </li>
+ <li>Predictive Search
+ <ul>
+ <li>入力文字列で始まる登録文字列を検索します.</li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- subsection -->
+ </div><!-- section -->
+ <div class="section">
+ <h2><a name="source">ソースコード</a></h2>
+ <div class="subsection">
+ <h3><a name="license">ライセンス</a></h3>
+ <p>
+ libmarisa および付属のコマンドラインツールはフリーソフトウェアです.使用・再配布については,二条項 BSD ライセンスと LGPL のデュアルライセンスを採用しています.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="download">ダウンロード</a></h3>
+ <p>
+ プロジェクトの管理やソースコードの配布には <a href="https://github.com/">GitHub</a> を利用しています.
+ </p>
+ <ul>
+ <li>プロジェクト
+ <ul>
+ <li><a href="https://github.com/s-yata/marisa-trie">https://github.com/s-yata/marisa-trie</a></li>
+ </ul>
+ </li>
+ <li>ソースコード
+ <ul>
+ <li><a href="https://github.com/s-yata/marisa-trie/archive/v0.2.6.tar.gz">marisa-0.2.6.tar.gz</a></li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="install">インストール</a></h2>
+ <div class="subsection">
+ <h3><a name="gcc">GCC &amp; Clang</a></h3>
+ <div class="float">
+ <pre class="console">$ tar zxf marisa-0.2.6.tar.gz
+$ cd marisa-0.2.6
+$ ./configure
+$ make
+$ make check
+$ make install</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>configure</kbd> と <kbd>make</kbd> によりインストールできるようになっています.<kbd>make install</kbd> については,必要に応じて <kbd>sudo</kbd> を付けてご利用ください.また,特に指定がなければ libmarisa は共有ライブラリとしてインストールされるので,<kbd>ldconfig</kbd> が必要になるかもしれません.
+ </p>
+ <p>
+ POPCNT 命令が使える環境では,<kbd>configure</kbd> に <kbd>--enable-popcnt</kbd> を渡すことで,少し高速化することができます.同様に,<kbd>--enable-sse2</kbd>, <kbd>--enable-sse3</kbd>, <kbd>--enable-ssse3</kbd>, <kbd>--enable-sse4.1</kbd>, <kbd>--enable-sse4.2</kbd>, <kbd>--enable-sse4</kbd>, <kbd>--enable-sse4a</kbd>, <kbd>--enable-bmi</kbd>, <kbd>--enable-bmi2</kbd> というオプションがあります.<kbd>--enable-native-code</kbd> を渡せば,コンパイル環境で使える命令がすべて有効になります.また,スタティックライブラリが必要なときは,<kbd>configure</kbd> に <kbd>--enable-static</kbd> を渡すようにしてください.その他,<kbd>configure</kbd> のオプションについては <kbd>./configure --help</kbd> をご覧ください.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Visual C++ 2008</a></h3>
+ <p>
+ Visual C++ 2008 にて作成したファイルを <kbd>vs2008/</kbd> 以下に配置しています.Visual C++ 2008 以降であれば,<kbd>vs2008/vs2008.sln</kbd> を開くだけでスタティックライブラリ <kbd>libmarisa.lib</kbd> とコマンドラインツールをビルドできます.
+ </p>
+ <p>
+ Visual C++ 2008 より古い環境では,新しくプロジェクトを作る必要があります.プロジェクトを作成すれば問題なくビルドできると思いますが,試していないので断言はできません.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Perl バインディング</a></h3>
+ <div class="float">
+ <pre class="console">$ cd bindings/perl
+$ perl Makefile.PL
+$ make
+$ make install</pre>
+ </div><!-- float -->
+ <p>
+ <a href="http://www.swig.org/">SWIG</a> による Perl バインディングが <kbd>bindings/perl/</kbd> にあります.<kbd>perl Makefile.PL</kbd> により <kbd>Makefile</kbd> を作成し,<kbd>make install</kbd> を実行することでインストールできます.使い方については,<kbd>bindings/perl/sample.pl</kbd> を参考にしてください.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Python バインディング</a></h3>
+ <div class="float">
+ <pre class="console">$ cd bindings/python
+$ python setup.py build
+$ python setup.py install</pre>
+ </div><!-- float -->
+ <p>
+ <a href="http://www.swig.org/">SWIG</a> による Python バインディングが <kbd>bindings/python/</kbd> にあります.<kbd>python setup.py install</kbd> により インストールできます.使い方については,<kbd>bindings/python/sample.py</kbd> を参考にしてください.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">Ruby バインディング</a></h3>
+ <div class="float">
+ <pre class="console">$ cd bindings/ruby
+$ ruby extconf.rb
+$ make
+$ make install</pre>
+ </div><!-- float -->
+ <p>
+ <a href="http://www.swig.org/">SWIG</a> による Ruby バインディングが <kbd>bindings/ruby/</kbd> にあります.<kbd>ruby extconf.rb</kbd> により <kbd>Makefile</kbd> を作成し,<kbd>make install</kbd> を実行することでインストールできます.使い方については,<kbd>bindings/ruby/sample.rb</kbd> を参考にしてください.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="vc">その他</a></h3>
+ <p>
+ 上記のバインディング以外にも,いくつかのバインディングがあります.
+ </p>
+ <ul>
+ <li>Python
+ <ul>
+ <li><a href="https://github.com/kmike/marisa-trie/">"https://github.com/kmike/marisa-trie/</a>高速・高機能な Python バインディング</li>
+ </ul>
+ </li>
+ <li>Node.js
+ <ul>
+ <li><a href="https://github.com/komiya-atsushi/node-marisa-trie">https://github.com/komiya-atsushi/node-marisa-trie</a>Node.js から使うためのモジュール</li>
+ </ul>
+ </li>
+ </p>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="tools">コマンドラインツール</a></h2>
+ <div class="subsection">
+ <h3><a name="marisa-build">marisa-build</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-build &lt; keyset.txt &gt; keyset.dic
+#keys: 1342099
+#nodes: 1832373
+size: 7841664</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-build</kbd> は辞書を構築するツールです.改行を区切りとして文字列を受け取り,構築した辞書を標準出力に書き出すようになっています.
+ </p>
+ <p>
+ 構築する辞書のパラメータについては,オプションを使って指定できます.オプションの一覧は <kbd>marisa-build -h</kbd> により確認できます.
+ </p>
+ <p>
+ 入力は改行区切りとなっていますが,水平タブが存在する行については,最後の水平タブ以降を文字列の重みとして扱うようになっています.文字列の出現頻度や出現確率を与えることにより,検索時間を短縮できる可能性があります.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-lookup">marisa-lookup</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-lookup keyset.dic
+東方
+174385 東方
+とうほう
+-1 とうほう</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-lookup</kbd> は単純な辞書引きをおこなうツールです.入力された文字列が登録されていれば ID とともに出力し,登録されていなければ <var>-1</var> とともに出力します.
+ </p>
+ <p>
+ オプションの一覧は <kbd>marisa-lookup -h</kbd> により確認できます.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-reverse-lookup">marisa-reverse-lookup</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-reverse-lookup keyset.dic
+800000
+800000 紀元前475年</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-reverse-lookup</kbd> は辞書に登録されている文字列を ID から復元するツールです.登録文字列には <var>0</var> から順に固有の ID が割り当てられるので,指定できる値は <var>0</var> 以上で<var>登録文字列数</var>より小さい整数となります.範囲外の値を入力するとエラーになるので注意してください.
+ </p>
+ <p>
+ オプションの一覧は <kbd>marisa-reverse-lookup -h</kbd> により確認できます.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-common-prefix-search">marisa-common-prefix-search</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-common-prefix-search keyset.dic
+東方
+2 found
+3542 東 東方
+174385 東方 東方</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-common-prefix-search</kbd> は Common Prefix Search をおこなうツールです.入力された文字列の前半部分に一致する登録文字列を ID とともに出力します.
+ </p>
+ <p>
+ オプションの一覧は <kbd>marisa-common-prefix-search -h</kbd> により確認できます.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-predictive-search">marisa-predictive-search</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-predictive-search keyset.dic -n 2
+東方
+200 found
+174385 東方 東方
+639679 東方文花帖 東方</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-predictive-search</kbd> は Predictive Search をおこなうツールです.入力された文字列で始まる登録文字列を ID とともに出力します.
+ </p>
+ <p>
+ オプションの一覧は <kbd>marisa-predictive-search -h</kbd> により確認できます.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-benchmark">marisa-benchmark</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-benchmark keyset.txt
+Number of tries: 1 - 5
+TAIL mode: Text mode
+Node order: Descending weight order
+Cache level: Normal cache
+Number of keys: 1342099
+Total length: 28308027
+------+----------+--------+--------+--------+--------+--------
+#tries size build lookup reverse prefix predict
+ lookup search search
+ [bytes] [K/s] [K/s] [K/s] [K/s] [K/s]
+------+----------+--------+--------+--------+--------+--------
+ 1 11588904 506.45 1187.70 1109.17 1040.39 596.49
+ 2 8467920 424.71 699.01 677.83 636.07 300.25
+ 3 7841664 405.47 615.64 601.84 563.91 254.67
+ 4 7633584 399.43 593.85 583.52 545.57 242.69
+ 5 7548584 395.90 526.31 563.91 504.55 236.70
+------+----------+--------+--------+--------+--------+--------</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-benchmark</kbd> は,<kbd>marisa-build</kbd> と同様の入力を受け取り,辞書のサイズや構築・検索にかかる時間を調べるツールです.辞書を構成する Trie の数を選択するのに有用です.
+ </p>
+ <p>
+ 検索時間については,入力された文字列を一通り検索するのに要した時間を <code>std::clock()</code> で計測した結果を出力します.文字列を整列してから入力とした場合はキャッシュが効きやすい状況での検索時間になり,文字列をランダムに並べ替えてから入力とした場合はキャッシュが効きにくい状況での検索時間になります.
+ </p>
+ <p>
+ オプションの一覧は <kbd>marisa-benchmark -h</kbd> により確認できます.
+ </p>
+ </div><!-- subsection -->
+ <div class="subsection">
+ <h3><a name="marisa-dump">marisa-dump</a></h3>
+ <div class="float">
+ <pre class="console">$ marisa-dump keyset.dic | head -3
+input: keyset.dic
+フ
+ファ
+ファン</pre>
+ </div><!-- float -->
+ <p>
+ <kbd>marisa-dump</kbd> は辞書に登録されている文字列をすべて出力するツールです.デフォルトの区切り文字は改行(LF)ですが,オプションにより変更することができます.
+ </p>
+ <p>
+ オプションの一覧は <kbd>marisa-dump -h</kbd> により確認できます.
+ </p>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="library">ライブラリ</a></h2>
+ <div class="subsection">
+ <h3><a name="howto">使い方</a></h3>
+ <div class="float">
+ <pre class="code">// sample.cc
+#include &lt;iostream&gt;
+#include &lt;marisa.h&gt;
+
+int main() {
+ marisa::Keyset keyset;
+ keyset.push_back("a");
+ keyset.push_back("app");
+ keyset.push_back("apple");
+
+ marisa::Trie trie;
+ trie.build(keyset);
+
+ marisa::Agent agent;
+ agent.set_query("apple");
+ while (trie.common_prefix_search(agent)) {
+ std::cout.write(agent.key().ptr(), agent.key().length());
+ std::cout &lt;&lt; ": " &lt;&lt; agent.key().id() &lt;&lt; std::endl;
+ }
+ return 0;
+}</pre>
+ </div><!-- float -->
+ <div class="float">
+ <pre class="console">$ g++ sample.cc -lmarisa
+$ ./a.out
+a: 0
+app: 1
+apple: 2</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa のヘッダは <kbd>marisa.h</kbd> です.名前空間には <code>marisa</code> を使っています.危険なので,<code>using namespace marisa</code> とするのは避けてください.最後に,<kbd>gcc</kbd> や <kbd>clang</kbd> によるリンクでは <kbd>-lmarisa</kbd> が必要となることに注意してください.
+ </p>
+ <p>
+ libmarisa の主要なクラスは <a href="#keyset">Keyset</a>, <a href="#agent">Agent</a>, <a href="#trie">Trie</a> の 3 つです.サンプルコードでは明示的に使っていませんが,例外のクラスとして <a href="#exception">Exception</a> があるほか,<code>Keyset</code>, <code>Agent</code> のメンバとして <a href="#key">Key</a> や <a href="#query">Query</a> が存在します.
+ </p>
+ <ul>
+ <li><code>Keyset</code>: 文字列の集合を格納するクラスです.辞書を構築するときの入力として使うほか,検索結果の保存にも利用できます.</li>
+ <li><code>Agent</code>: 検索の入出力と途中経過を格納するクラスです.検索用の関数はすべて Agent への参照を引数とします.</li>
+ <li><code>Trie</code>: 辞書のクラスです.</li>
+ </ul>
+ <p>
+ コマンドラインツールのソースコードが <kbd>tools/</kbd> にあり,例外処理やファイル入出力,Predictive Search などのサンプルとして利用できます.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="enum">定数</a></h3>
+ <div class="subsubsection">
+ <h4>エラーコード</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_error_code_ {
+ MARISA_OK = 0,
+ MARISA_STATE_ERROR = 1,
+ MARISA_NULL_ERROR = 2,
+ MARISA_BOUND_ERROR = 3,
+ MARISA_RANGE_ERROR = 4,
+ MARISA_CODE_ERROR = 5,
+ MARISA_RESET_ERROR = 6,
+ MARISA_SIZE_ERROR = 7,
+ MARISA_MEMORY_ERROR = 8,
+ MARISA_IO_ERROR = 9,
+ MARISA_FORMAT_ERROR = 10,
+} marisa_error_code;</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa では,ファイル入出力に失敗したときや辞書のサイズが上限に到達したときなどに,<code>Exception</code> を送出します.そして,<code>Exception</code> に格納される情報の 1 つが <code>marisa_error_code</code> です.
+ </p>
+ <p>
+ 辞書の入出力に関するエラーコードである <var>MARISA_IO_ERROR</var> と <var>MARISA_FORMAT_ERROR</var> 以外については,バグによる可能性が高いと思います.各エラーコードの詳細については,<kbd>marisa/base.h</kbd> をご覧ください.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>トライの数</h4>
+ <div class="float">
+ <pre class="code">
+typedef enum marisa_num_tries_ {
+ MARISA_MIN_NUM_TRIES = 0x00001,
+ MARISA_MAX_NUM_TRIES = 0x0007F,
+ MARISA_DEFAULT_NUM_TRIES = 0x00003,
+} marisa_num_tries;</pre>
+ </div><!-- float -->
+ <p>
+ MARISA は複数の Patricia Trie を組み合わせて 1 つの Trie を構成することが特徴の 1 つであり,Patricia Trie の数を増やすほど,辞書はコンパクトになるものの,検索が遅くなるという傾向があります.<code>marisa_num_tries</code> では,辞書を構成する Patricia Trie の数について,最小値・最大値とデフォルトの値を提供します.
+ </p>
+ <p>
+ 適切な設定は登録文字列やアプリケーションによって異なります.ほとんどの場合はデフォルトの設定で問題ないと思いますが,検索時間が問題になるときは,思い切って <var>1</var> にしてください.また,登録文字列が長くて少し複雑な構成になる場合,デフォルトより大きな値にすることで,辞書のサイズをさらに小さくできることがあります.設定が気になるときは,<kbd>marisa-benchmark</kbd> をお試しください.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>キャッシュのサイズ</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_cache_level_ {
+ MARISA_HUGE_CACHE = 0x00080,
+ MARISA_LARGE_CACHE = 0x00100,
+ MARISA_NORMAL_CACHE = 0x00200,
+ MARISA_SMALL_CACHE = 0x00400,
+ MARISA_TINY_CACHE = 0x00800,
+ MARISA_DEFAULT_CACHE = MARISA_NORMAL_CACHE
+} marisa_cache_level;</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa では,検索時間の短縮を目的として,辞書にキャッシュを埋め込むようになっています.キャッシュの内容は通過する確率の高い遷移に関する情報であり,キャッシュを大きくすることによって,辞書は大きくなるものの,検索時間を短縮できます.
+ </p>
+ <p>
+ <code>marisa_cache_level</code> は,キャッシュのサイズを制御するための定数を提供します.<var>MARISA_NORMAL_CACHE</var> を基準として,<var>MARISA_LARGE_CACHE</var> は 2 倍,<var>MARISA_HUGE_CACHE</var> は 4 倍になり,<var>MARISA_SMALL_CACHE</var> は 1/2,<var>MARISA_TINY_CACHE</var> は 1/4 になります.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>TAIL の種類</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_tail_mode_ {
+ MARISA_TEXT_TAIL = 0x01000,
+ MARISA_BINARY_TAIL = 0x02000,
+ MARISA_DEFAULT_TAIL = MARISA_TEXT_TAIL,
+} marisa_tail_mode;</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa による辞書では,最後の Patiricia Trie について,ラベルをそのまま保存するようになっています.<code>marisa_tail_mode</code> はラベルの保存方法を選ぶためのパラメータです.
+ </p>
+ <p>
+ <var>MARISA_TEXT_TAIL</var> はラベルを <var>'\0'</var> を終端とする文字列として保存します.そのため,ラベルに <var>'\0'</var> が含まれるときは,自動的に <var>MARISA_BINARY_TAIL</var> へと切り替わるようになっています.明示的に <var>MARISA_BINARY_TAIL</var> を選ぶ理由はほとんどありません.
+ </p>
+ <p>
+ 一方,<var>MARISA_BINARY_TAIL</var> では,ラベルの終端を検出するために,<var>'\0'</var> の代わりにビット列を使用します.そのため,ラベルの平均長が <var>8 bytes</var> を超えるときは <var>MARISA_TEXT_TAIL</var> の方がコンパクトになります.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>ノードの順序</h4>
+ <div class="float">
+ <pre class="code">typedef enum marisa_node_order_ {
+ MARISA_LABEL_ORDER = 0x10000,
+ MARISA_WEIGHT_ORDER = 0x20000,
+ MARISA_DEFAULT_ORDER = MARISA_WEIGHT_ORDER,
+} marisa_node_order;</pre>
+ </div><!-- float -->
+ <p>
+ libmarisa では,ノードの順序が辞書のパラメータになっています.選択肢は <var>MARISA_LABEL_ORDER</var> と <var>MARISA_WEIGHT_ORDER</var> の 2 つであり,前者はラベルが昇順になるようにノードを配列し,後者は重み(出現しやすさ)が降順になるようにノードを配列します.一般的な Trie の実装では <var>MARISA_LABEL_ORDER</var> の順序を用いますが,libmarisa では <var>MARISA_WEIGHT_ORDER</var> がデフォルトになっています.
+ </p>
+ <p>
+ <var>MARISA_WEIGHT_ORDER</var> の目的は,出現しやすいノードから順に並べておくことにより,線形探索の効率を高め,検索時間を短縮することにあります.日本語の単語やフレーズを用いた実験においては,辞書引きにかかる時間を 1/2 程度に短縮できることが確認されています.一方,<var>MARISA_LABEL_ORDER</var> については,検索時間は長くなるものの,Predictive Search の検索結果が文字列昇順になるという特徴があります.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>別名</h4>
+ <div class="float">
+ <pre class="code">namespace marisa {
+ typedef ::marisa_error_code ErrorCode;
+ typedef ::marisa_cache_level CacheLevel;
+ typedef ::marisa_tail_mode TailMode;
+ typedef ::marisa_node_order NodeOrder;
+} // namespace marisa</pre>
+ </div><!-- float -->
+ <p>
+ 以上の列挙型については,マクロとの衝突を避けるために,グローバル名前空間にて定義しています.<code>namespace marisa</code> に別名を用意しているので,お好きな方をご利用ください.
+ </p>
+ </div><!-- subsubsection -->
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="exception">class Exception</a></h3>
+ <div class="float">
+ <pre class="code">class Exception {
+ public:
+ const char *filename() const;
+ int line() const;
+ ErrorCode error_code() const;
+ const char *error_message() const;
+
+ const char *what() const;
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Exception</code> は libmarisa が例外として送出するクラスです.エラーが検出されたファイルの名前(<code>__FILE__</code>)と行番号(<code>__LINE__</code>),さらにエラーコードを取り出せるようになっています.<code>what()</code> は使いやすさのために用意した関数であり,<code>error_message()</code> と同じく,<var>__FILE__:__LINE__: error_code: error_message</var> という書式の文字列を返します.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="key">class Key</a></h3>
+ <div class="float">
+ <pre class="code">class Key {
+ public:
+ char operator[](std::size_t i) const;
+ const char *ptr() const;
+ std::size_t length() const;
+ std::size_t id() const;
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Key</code> は後述する <a href="#keyset">Keyset</a> および <a href="#agent">Agent</a> のメンバになっているクラスです.登録しようとしている文字列や,検索で見つけた登録文字列の情報を格納するために使われています.基本的な使い方では,既に情報が格納されたインスタンスのみを目にすることになります.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="query">class Query</a></h3>
+ <div class="float">
+ <pre class="code">class Query {
+ public:
+ char operator[](std::size_t i) const;
+ const char *ptr() const;
+ std::size_t length() const;
+ std::size_t id() const;
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Query</code> は後述する <a href="#agent">Agent</a> のメンバになっているクラスです.検索しようとしている文字列や参照したい登録文字列の ID を格納するようになっています.<code>Query</code> に対する文字列や ID の設定は <code>Agent</code> を介しておこなうため,基本的な使い方では,意識する必要はありません.内容を確認したいときに参照する程度です.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="keyset">class Keyset</a></h3>
+ <div class="float">
+ <pre class="code">class Keyset {
+ public:
+ Keyset();
+
+ void push_back(const Key &amp;key);
+ void push_back(const Key &amp;key, char end_marker);
+
+ void push_back(const char *str);
+ void push_back(const char *ptr,
+ std::size_t length,
+ float weight = 1.0);
+
+ const Key &amp;operator[](std::size_t i) const;
+ Key &amp;operator[](std::size_t i);
+
+ std::size_t num_keys();
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_length() const;
+
+ void reset();
+
+ void clear();
+ void swap(Keyset &amp;rhs);
+};</pre>
+ </div><!-- float -->
+ <div class="subsubsection">
+ <h4>概要</h4>
+ <p>
+ <code>Keyset</code> は辞書に登録しようとしている文字列もしくは登録されている文字列を詰め込むためのクラスです.辞書を構築するときの入力として,あるいは検索結果を保存しておくために使います.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>辞書の構築</h4>
+ <p>
+ 辞書の構築に使う場合,<code>push_back()</code> で登録したい文字列を追加してから,後述する <a href="#trie">Trie</a> の <code>build()</code> に渡します.<var>weight</var> は文字列の出現しやすさを示す重みであり,同じ文字列を繰り返し追加した場合,辞書を構築する段階で加算されるようになっています.
+ </p>
+ <p>
+ 辞書を構築した後は,<code>operator[]()</code> により登録文字列の ID を確認できます.その代わり,<code>Key</code> は重みと ID を共用体のメンバとして持つため,辞書の構築に使用した重みを参照できなくなります.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>検索結果の保存</h4>
+ <p>
+ 検索結果の保存に使う場合,後述する <a href="#agent">Agent</a> に格納されている検索結果を <code>push_back()</code> に渡すことで,文字列を複製し,ID を残しておくことができます.検索結果の文字列に終端記号を加えたいときは <var>end_marker</var> を利用してください.文字列の長さには影響を与えず,<var>end_marker</var> を終端文字として加えることができます.
+ </p>
+ <p>
+ 検索結果を破棄して別の検索結果を保存するために再利用するという場合,<code>clear()</code> の代わりに <code>reset()</code> を使うことで,既に確保している領域を再利用できます.メモリの確保・解放にかかるオーバーヘッドが気になるときにご利用ください.
+ </p>
+ <p>
+ <code>empty()</code> は文字列が格納されていないかどうかを返す関数です.<code>size()</code> は <code>num_keys()</code> と同じく格納されている文字列の数を返す関数であり,<code>total_length()</code> は格納されている文字列の合計長を byte 単位で返す関数です.
+ </p>
+ </div><!-- subsubsection -->
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="agent">class Agent</a></h3>
+ <div class="float">
+ <pre class="code">class Agent {
+ public:
+ Agent();
+
+ const Query &amp;query() const;
+ const Key &amp;key() const;
+
+ void set_query(const char *str);
+ void set_query(const char *ptr,
+ std::size_t length);
+ void set_query(std::size_t key_id);
+};</pre>
+ </div><!-- float -->
+ <p>
+ <code>Agent</code> は <code>Query</code> と <code>Key</code> をメンバとして持つクラスです.検索における入出力の受け渡し,および途中経過の保存に使います.後述する <a href="#trie">Trie</a> の検索関数は,例外なく <code>Agent</code> への参照を引数として受け取るようになっています.
+ </p>
+ <p>
+ 検索の手順は,<code>set_query()</code> を使って検索したい文字列もしくは参照したい登録文字列の ID を設定し,<code>Trie</code> の関数に渡した後,<code>key()</code> により検索結果を取り出すという流れになります.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="trie">class Trie</a></h3>
+ <div class="float">
+ <pre class="code">class Trie {
+ public:
+ Trie();
+
+ void build(Keyset &amp;keyset,
+ int config_flags = 0);
+
+ void mmap(const char *filename);
+ void map(const void *ptr,
+ std::size_t size);
+
+ void load(const char *filename);
+ void read(int fd);
+
+ void save(const char *filename) const;
+ void write(int fd) const;
+
+ bool lookup(Agent &amp;agent) const;
+ void reverse_lookup(Agent &amp;agent) const;
+ bool common_prefix_search(Agent &amp;agent) const;
+ bool predictive_search(Agent &amp;agent) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t io_size() const;
+
+ void clear();
+ void swap(Trie &amp;rhs);
+};</pre>
+ </div><!-- float -->
+ <div class="subsubsection">
+ <h4>概要</h4>
+ <p>
+ <code>Trie</code> は辞書のクラスです.libmarisa において最も重要なクラスであり,辞書の構築・検索からファイル入出力にいたるまで,あらゆる操作に必要となります.
+ </p>
+ <p>
+ 実際には,辞書のハンドルに相当するクラスであり,辞書の実体がない状況では,<code>build()</code>, <code>mmap()</code>, <code>map()</code>, <code>load()</code>, <code>read()</code>, <code>clear()</code>, <code>swap()</code> 以外の関数を呼び出すと例外が送出されます.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>辞書の構築</h4>
+ <p>
+ 辞書の構築には <code>build()</code> を使います.引数は,前述の <a href="#keyset">Keyset</a> と,辞書の設定を XOR(<code>|</code>) で組み合わせた <var>config_flags</var> です.<var>config_flags</var> については,<var>2 | MARISA_BINARY_TAIL</var> のように指定します.この例では,辞書を構成する Patricia Trie の数を <var>2</var> つに制限し,ラベルの保存方法を <var>MARISA_BINARY_TAIL</var> に固定します.省略されているノードの順序とキャッシュのサイズについては,デフォルトの設定である <var>MARISA_DEFAULT_ORDER</var> と <var>MARISA_DEFAULT_CACHE</var> が採用されます.
+ </p>
+ <p>
+ 辞書の構築において登録文字列に割り当てられた ID は,<var>keyset</var> の <code>operator[]()</code> を使って確認できます.登録文字列に対して関連付ける情報がある場合にご利用ください.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>ファイル入出力</h4>
+ <p>
+ <code>mmap()</code> は,Memory Mapped I/O により,辞書全体をファイルから読み込むことなく検索できる状態にする関数です.少ししか検索しないのに辞書全体を読み込むのは勿体ないという状況や,異なるプロセスで同じ辞書を共有したいという状況で使うと効果的です.逆に,たくさんの文字列を検索する場合,あらかじめ辞書全体を読み込んでおかないと,外部記憶に対するランダムアクセスにより検索時間が極端に長くなる可能性があります.
+ </p>
+ <p>
+ <code>map()</code> はメモリ上に展開されている辞書のバイナリを使って検索できる状態にする関数です.<code>load()</code> と <code>read()</code> は辞書を入力する関数であり,<code>save()</code> と <code>write()</code> は辞書を出力する関数です.
+ </p>
+ </div><!-- subsubsection -->
+ <div class="subsubsection">
+ <h4>辞書からの検索</h4>
+ <p>
+ 検索をおこなう関数は <code>lookup()</code>, <code>reverse_lookup()</code>, <code>common_prefix_search()</code>, <code>predictive_search()</code> の 4 種類です.
+ </p>
+ <ul>
+ <li>
+ <code>lookup()</code>: 文字列が登録されているかどうかを確認します.登録されていれば <var>true</var> を返します.このとき,<code>agent.key()</code> により検索結果を取り出すことができます.ただし,<code>agent.key().ptr()</code> については,入力として渡された文字列を指しているだけであり,文字列の複製を持っているわけではないことに注意してください.登録されていなければ <var>false</var> を返して終了です.
+ </li>
+ <li>
+ <code>reverse_lookup()</code>: ID から登録文字列を復元します.返り値はなく,復元された文字列は <var>agent.key()</var> を介してアクセスできます.文字列の実体は <var>agent</var> 内部に保持されています.<var>agent</var> を使って次の検索をおこなった段階で失われるものと考えてください.ID が範囲外であれば例外を送出して終了です.
+ </li>
+ <li>
+ <code>common_prefix_search()</code>: 入力文字列の前半部分に一致する登録文字列を検索します.該当する登録文字列があれば <var>true</var> を返します.このとき,<code>agent.key()</code> には検索結果が格納されています.<code>agent.key().ptr() == agent.query().ptr()</code> が成立することに注意してください.該当する登録文字列が複数ある場合,返り値が <var>false</var> になるまで繰り返し <code>common_prefix_search()</code> を呼び出すことにより,すべての検索結果を取得できます.
+ </li>
+ <li>
+ <code>predictive_search()</code>: 入力文字列で始まる登録文字列を検索します.該当する登録文字列があれば <var>true</var> を返します.検索によって復元された文字列には,<code>agent.key()</code> を介してアクセスできます.文字列の実体は,<var>agent</var> 内部に検索の途中経過として保持されているので,<var>agent</var> を使って次の検索をおこなった段階で失われるものと考えてください.該当する登録文字列が複数ある場合,返り値が <var>false</var> になるまで繰り返し <code>predictive_search()</code> を呼び出すことにより,すべての検索結果を取得できます.
+ </li>
+ </ul>
+ <p>
+ 繰り返しにより検索が進行する <code>common_prefix_search()</code> と <code>predictive_search()</code> については,<code>agent</code> が検索の途中経過を保持するようになっています.そのため,<code>agent</code> を別の関数に渡したり,<code>agent.set_query()</code> を呼び出したりした時点で,検索の進行はリセットされます.
+ </p>
+ <p>
+ <code>empty()</code> は登録文字列が存在するかどうかを返す関数です.<code>size()</code> は <code>num_keys()</code> と同じく登録文字列の数を返す関数であり,<code>io_size()</code> は辞書をファイルに出力した場合のサイズを返す関数です.
+ </p>
+ </div><!-- subsubsection -->
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="stdio">stdio</a></h3>
+ <div class="float">
+ <pre class="code">void fread(std::FILE *file, Trie *trie);
+void fwrite(std::FILE *file, const Trie &amp;trie);</pre>
+ </div><!-- float -->
+ <p>
+ <code>std::FILE</code> を用いる関数は <kbd>marisa/stdio.h</kbd> で宣言されています.<code>#include &lt;cstdio&gt;</code> を入れたくないときは,<kbd>marisa.h</kbd> の代わりに <kbd>marisa/trie.h</kbd> を使ってください.
+ </p>
+ </div><!-- subsection -->
+
+ <div class="subsection">
+ <h3><a name="iostream">iostream</a></h3>
+ <div class="float">
+ <pre class="code">std::istream &amp;read(std::istream &amp;stream, Trie *trie);
+std::ostream &amp;write(std::ostream &amp;stream, const Trie &amp;trie);
+
+std::istream &amp;operator>>(std::istream &amp;stream, Trie &amp;trie);
+std::ostream &amp;operator<<(std::ostream &amp;stream, const Trie &amp;trie);</pre>
+ </div><!-- float -->
+ <p>
+ <code>std::iostream</code> を用いる関数は <kbd>marisa/iostream.h</kbd> で宣言されています.<code>#include &lt;iosfwd&gt;</code> を入れたくないときは,<kbd>marisa.h</kbd> の代わりに <kbd>marisa/trie.h</kbd> を使ってください.
+ </p>
+ </div><!-- subsection -->
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="compatibility">辞書の互換性</a></h2>
+ <p>
+ libmarisa により構築される辞書の書式はアーキテクチャに依存します.Little Endian な環境で構築した辞書は,Big Endian な環境では使えません.あらためて構築しなおす必要があります.また,Little Endian 形式の辞書は 32/64-bit 環境における互換性があるのに対し,Big Endian 形式の辞書は 32/64-bit 環境における互換性がありません.
+ </p>
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="references">参考資料</a></h2>
+ <ul>
+ <li><a href="http://www.anlp.jp/proceedings/annual_meeting/2011/html/program.html">言語処理学会第 17 回年次大会(NLP2011)</a>
+ <ul>
+ <li>言語処理学会年次大会の予稿集が公開されていて,MARISA に関する論文(<a href="http://www.anlp.jp/proceedings/annual_meeting/2011/pdf_dir/F2-6.pdf">F2-6.pdf</a>)をダウンロードできます.</li>
+ </ul>
+ </li>
+ <li><a href="http://d.hatena.ne.jp/s-yata/20110310/1299777228">発表資料(Prefix/Patricia Trie の入れ子による辞書圧縮)</a>
+ <ul>
+ <li>MARISA に関する発表資料(<a href="https://sites.google.com/site/headdythehero/cabine/2011/0311/NLP2011-F2-6.pptx?attredirects=0&amp;d=1">NLP2011-F2-6.pptx</a>, <a href="https://sites.google.com/site/headdythehero/cabine/2011/0311/NLP2011-F2-6.pdf?attredirects=0&amp;d=1">NLP2011-F2-6.pdf</a>, <a href="https://sites.google.com/site/headdythehero/cabine/2011/0311/NLP2011-F2-6-notes.pdf?attredirects=0&amp;d=1">NLP2011-F2-6-notes.pdf</a>)をダウンロードできます.</li>
+ </ul>
+ </li>
+ </ul>
+ </div><!-- section -->
+
+ <div class="section">
+ <h2><a name="conclusion">おわりに</a></h2>
+ <p>
+ 質問などありましたら,欄外のメールアドレス宛てに,お気軽にご連絡ください.
+ </p>
+ </div><!-- section -->
+ </div><!-- body -->
+ <div id="footer">
+ <div class="left">MARISA: Matching Algorithm with Recursively Implemented StorAge</div>
+ <div class="right">
+ ‮moc.liamg@atay.umusus‭
+ </div>
+ <div class="end"></div>
+ </div><!-- footer -->
+ </body>
+</html>
diff --git a/docs/style.css b/docs/style.css
new file mode 100644
index 0000000..04684ff
--- /dev/null
+++ b/docs/style.css
@@ -0,0 +1,245 @@
+@charset "utf-8";
+
+* {
+ line-height: 140%;
+ margin: 0px;
+ padding: 0px;
+}
+
+body {
+ background: lightgray;
+ color: #222;
+ margin: 10px 20px;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+}
+a:link {
+ color: #066;
+ padding: 0px 2px;
+}
+a:link:after {
+ content: "†";
+}
+a:visited {
+ color: #057;
+ padding: 0px 2px;
+}
+a:visited:after {
+ content: "†";
+}
+a:hover {
+ text-decoration: underline;
+}
+a[name]:hover {
+ color: inherit;
+ text-decoration: none;
+}
+a:active {
+}
+a[name]:active {
+ color: inherit;
+ padding: 0px;
+}
+
+ol {
+ list-style-position: outside;
+ margin-left: 2em;
+}
+ol ol {
+ list-style-position: outside;
+ margin-left: 1em;
+}
+ul {
+ list-style-position: outside;
+ margin-left: 2em;
+}
+ul ul {
+ list-style-position: outside;
+ margin-left: 1em;
+}
+li {
+ margin: 5px 0px;
+}
+
+code {
+ color: darkblue;
+ font-family: sans-serif;
+ font-style: normal;
+ padding: 0px 2px;
+}
+kbd {
+ color: darkgreen;
+ font-family: sans-serif;
+ font-style: normal;
+ padding: 0px 2px;
+}
+var {
+ color: darkred;
+ font-family: sans-serif;
+ font-style: normal;
+ padding: 0px 2px;
+}
+sup {
+ font-size: 75%;
+}
+
+div#header {
+ font-family: "Times New Roman";
+ padding: 5px 10px;
+}
+div#header div.left {
+ float: left;
+}
+div#header div.right {
+ float: right;
+}
+div#header div.end {
+ clear: both;
+}
+
+div#body {
+ background: white;
+ border: 1px solid black;
+ box-shadow: 1px 1px 5px gray;
+ -webkit-box-shadow: 1px 1px 5px gray;
+ -moz-box-shadow: 1px 1px 5px gray;
+ padding: 20px;
+}
+
+div#body h1 {
+ font-size: 150%;
+ margin: 10px;
+ text-align: center;
+}
+
+div#body p#authors {
+ font-weight: bold;
+ margin: 10px;
+ text-align: center;
+}
+div#body p#authors span.author {
+ margin: 0px 1em;
+}
+
+div#body p#abstract {
+ margin: 15px auto;
+ text-align: auto;
+ width: 75%;
+}
+div#body p#abstract span#heading {
+ font-family: "Times New Roman";
+ font-style: italic;
+ font-weight: bold;
+ margin-right: 0.5em;
+}
+
+div#body div.section {
+ clear: both;
+ margin: 5px 0px;
+}
+div#body div.section h2 {
+ background: honeydew;
+ border-bottom: 1px dashed darkgray;
+ color: #353;
+ font-size: 125%;
+ margin-top: 15px;
+ padding: 5px;
+}
+
+div#body div.section p {
+ margin: 5px 0px;
+ text-indent: 1em;
+}
+
+div#body div.section div.float {
+ box-shadow: 1px 1px 5px gray;
+ -webkit-box-shadow: 1px 1px 5px gray;
+ -moz-box-shadow: 1px 1px 5px gray;
+ clear: both;
+ float: right;
+ margin: 5px 0px 5px 10px;
+ max-width: 75%;
+}
+div#body div.section pre.code {
+ background: whitesmoke;
+ color: darkblue;
+ line-height: 125%;
+ overflow: auto;
+ padding: 5px 10px;
+}
+div#body div.section pre.console {
+ background: darkslategray;
+ color: white;
+ line-height: 125%;
+ overflow: auto;
+ padding: 5px 10px;
+}
+
+div#body div.section table {
+ background: whitesmoke;
+ border-collapse: separate;
+ border-spacing: 5px;
+ empty-cells: hide;
+ padding: 5px 10px;
+}
+div#body div.section table caption {
+ background: inherit;
+ padding-top: 5px;
+}
+div#body div.section table th {
+ background: white;
+ box-shadow: 1px 1px 3px gray;
+ -webkit-box-shadow: 1px 1px 3px gray;
+ -moz-box-shadow: 1px 1px 3px gray;
+ font-weight: normal;
+ padding: 0px 5px;
+}
+div#body div.section table td {
+ background: white;
+ box-shadow: 1px 1px 2px gray;
+ -webkit-box-shadow: 1px 1px 2px gray;
+ -moz-box-shadow: 1px 1px 2px gray;
+ padding: 0px 3px;
+}
+
+div#body div.section div.subsection {
+ clear: both;
+ margin: 5px 0px;
+}
+div#body div.section div.subsection h3 {
+ background: aliceblue;
+ border-bottom: 1px dashed lightgray;
+ color: #336;
+ font-size: 100%;
+ margin-top: 10px;
+ padding: 3px 5px;
+}
+
+div#body div.section div.subsubsection {
+ margin: 5px;
+}
+div#body div.section div.subsubsection h4 {
+ background: lavenderblush;
+ border-bottom: 1px dashed lightgray;
+ color: #336;
+ font-size: 100%;
+ margin-top: 10px;
+ padding: 3px 5px;
+}
+
+div#footer {
+ font-family: "Times New Roman";
+ padding: 5px 10px;
+}
+div#footer div.left {
+ float: left;
+}
+div#footer div.right {
+ float: right;
+}
+div#footer div.end {
+ clear: both;
+}
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100644
index 0000000..b4b25e2
--- /dev/null
+++ b/include/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = marisa
+
+include_HEADERS = marisa.h
diff --git a/include/marisa.h b/include/marisa.h
new file mode 100644
index 0000000..52e1ef0
--- /dev/null
+++ b/include/marisa.h
@@ -0,0 +1,14 @@
+#ifndef MARISA_H_
+#define MARISA_H_
+
+// "marisa/stdio.h" includes <cstdio> for I/O using std::FILE.
+#include "marisa/stdio.h"
+
+// "marisa/iostream.h" includes <iosfwd> for I/O using std::iostream.
+#include "marisa/iostream.h"
+
+// You can use <marisa/trie.h> instead of <marisa.h> if you don't need the
+// above I/O interfaces and don't want to include the above I/O headers.
+#include "marisa/trie.h"
+
+#endif // MARISA_H_
diff --git a/include/marisa/Makefile.am b/include/marisa/Makefile.am
new file mode 100644
index 0000000..ce3a987
--- /dev/null
+++ b/include/marisa/Makefile.am
@@ -0,0 +1,13 @@
+libmarisa_includedir = ${includedir}/marisa
+libmarisa_include_HEADERS = \
+ base.h \
+ exception.h \
+ scoped-ptr.h \
+ scoped-array.h \
+ key.h \
+ keyset.h \
+ query.h \
+ agent.h \
+ stdio.h \
+ iostream.h \
+ trie.h
diff --git a/include/marisa/agent.h b/include/marisa/agent.h
new file mode 100644
index 0000000..c72dea7
--- /dev/null
+++ b/include/marisa/agent.h
@@ -0,0 +1,73 @@
+#ifndef MARISA_AGENT_H_
+#define MARISA_AGENT_H_
+
+#include "marisa/key.h"
+#include "marisa/query.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class State;
+
+} // namespace trie
+} // namespace grimoire
+
+class Agent {
+ public:
+ Agent();
+ ~Agent();
+
+ const Query &query() const {
+ return query_;
+ }
+ const Key &key() const {
+ return key_;
+ }
+
+ void set_query(const char *str);
+ void set_query(const char *ptr, std::size_t length);
+ void set_query(std::size_t key_id);
+
+ const grimoire::trie::State &state() const {
+ return *state_;
+ }
+ grimoire::trie::State &state() {
+ return *state_;
+ }
+
+ void set_key(const char *str) {
+ MARISA_DEBUG_IF(str == NULL, MARISA_NULL_ERROR);
+ key_.set_str(str);
+ }
+ void set_key(const char *ptr, std::size_t length) {
+ MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ key_.set_str(ptr, length);
+ }
+ void set_key(std::size_t id) {
+ MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ key_.set_id(id);
+ }
+
+ bool has_state() const {
+ return state_.get() != NULL;
+ }
+ void init_state();
+
+ void clear();
+ void swap(Agent &rhs);
+
+ private:
+ Query query_;
+ Key key_;
+ scoped_ptr<grimoire::trie::State> state_;
+
+ // Disallows copy and assignment.
+ Agent(const Agent &);
+ Agent &operator=(const Agent &);
+};
+
+} // namespace marisa
+
+#endif // MARISA_AGENT_H_
diff --git a/include/marisa/base.h b/include/marisa/base.h
new file mode 100644
index 0000000..ffcdc5b
--- /dev/null
+++ b/include/marisa/base.h
@@ -0,0 +1,196 @@
+#ifndef MARISA_BASE_H_
+#define MARISA_BASE_H_
+
+// Old Visual C++ does not provide stdint.h.
+#ifndef _MSC_VER
+ #include <stdint.h>
+#endif // _MSC_VER
+
+#ifdef __cplusplus
+ #include <cstddef>
+#else // __cplusplus
+ #include <stddef.h>
+#endif // __cplusplus
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+#ifdef _MSC_VER
+typedef unsigned __int8 marisa_uint8;
+typedef unsigned __int16 marisa_uint16;
+typedef unsigned __int32 marisa_uint32;
+typedef unsigned __int64 marisa_uint64;
+#else // _MSC_VER
+typedef uint8_t marisa_uint8;
+typedef uint16_t marisa_uint16;
+typedef uint32_t marisa_uint32;
+typedef uint64_t marisa_uint64;
+#endif // _MSC_VER
+
+#if defined(_WIN64) || defined(__amd64__) || defined(__x86_64__) || \
+ defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__) || \
+ defined(__sparc64__) || defined(__mips64__) || defined(__aarch64__) || \
+ defined(__s390x__)
+ #define MARISA_WORD_SIZE 64
+#else // defined(_WIN64), etc.
+ #define MARISA_WORD_SIZE 32
+#endif // defined(_WIN64), etc.
+
+//#define MARISA_WORD_SIZE (sizeof(void *) * 8)
+
+#define MARISA_UINT8_MAX ((marisa_uint8)~(marisa_uint8)0)
+#define MARISA_UINT16_MAX ((marisa_uint16)~(marisa_uint16)0)
+#define MARISA_UINT32_MAX ((marisa_uint32)~(marisa_uint32)0)
+#define MARISA_UINT64_MAX ((marisa_uint64)~(marisa_uint64)0)
+#define MARISA_SIZE_MAX ((size_t)~(size_t)0)
+
+#define MARISA_INVALID_LINK_ID MARISA_UINT32_MAX
+#define MARISA_INVALID_KEY_ID MARISA_UINT32_MAX
+#define MARISA_INVALID_EXTRA (MARISA_UINT32_MAX >> 8)
+
+// Error codes are defined as members of marisa_error_code. This library throws
+// an exception with one of the error codes when an error occurs.
+typedef enum marisa_error_code_ {
+ // MARISA_OK means that a requested operation has succeeded. In practice, an
+ // exception never has MARISA_OK because it is not an error.
+ MARISA_OK = 0,
+
+ // MARISA_STATE_ERROR means that an object was not ready for a requested
+ // operation. For example, an operation to modify a fixed vector throws an
+ // exception with MARISA_STATE_ERROR.
+ MARISA_STATE_ERROR = 1,
+
+ // MARISA_NULL_ERROR means that an invalid NULL pointer has been given.
+ MARISA_NULL_ERROR = 2,
+
+ // MARISA_BOUND_ERROR means that an operation has tried to access an out of
+ // range address.
+ MARISA_BOUND_ERROR = 3,
+
+ // MARISA_RANGE_ERROR means that an out of range value has appeared in
+ // operation.
+ MARISA_RANGE_ERROR = 4,
+
+ // MARISA_CODE_ERROR means that an undefined code has appeared in operation.
+ MARISA_CODE_ERROR = 5,
+
+ // MARISA_RESET_ERROR means that a smart pointer has tried to reset itself.
+ MARISA_RESET_ERROR = 6,
+
+ // MARISA_SIZE_ERROR means that a size has exceeded a library limitation.
+ MARISA_SIZE_ERROR = 7,
+
+ // MARISA_MEMORY_ERROR means that a memory allocation has failed.
+ MARISA_MEMORY_ERROR = 8,
+
+ // MARISA_IO_ERROR means that an I/O operation has failed.
+ MARISA_IO_ERROR = 9,
+
+ // MARISA_FORMAT_ERROR means that input was in invalid format.
+ MARISA_FORMAT_ERROR = 10,
+} marisa_error_code;
+
+// Min/max values, flags and masks for dictionary settings are defined below.
+// Please note that unspecified settings will be replaced with the default
+// settings. For example, 0 is equivalent to (MARISA_DEFAULT_NUM_TRIES |
+// MARISA_DEFAULT_TRIE | MARISA_DEFAULT_TAIL | MARISA_DEFAULT_ORDER).
+
+// A dictionary consists of 3 tries in default. Usually more tries make a
+// dictionary space-efficient but time-inefficient.
+typedef enum marisa_num_tries_ {
+ MARISA_MIN_NUM_TRIES = 0x00001,
+ MARISA_MAX_NUM_TRIES = 0x0007F,
+ MARISA_DEFAULT_NUM_TRIES = 0x00003,
+} marisa_num_tries;
+
+// This library uses a cache technique to accelerate search functions. The
+// following enumerated type marisa_cache_level gives a list of available cache
+// size options. A larger cache enables faster search but takes a more space.
+typedef enum marisa_cache_level_ {
+ MARISA_HUGE_CACHE = 0x00080,
+ MARISA_LARGE_CACHE = 0x00100,
+ MARISA_NORMAL_CACHE = 0x00200,
+ MARISA_SMALL_CACHE = 0x00400,
+ MARISA_TINY_CACHE = 0x00800,
+ MARISA_DEFAULT_CACHE = MARISA_NORMAL_CACHE
+} marisa_cache_level;
+
+// This library provides 2 kinds of TAIL implementations.
+typedef enum marisa_tail_mode_ {
+ // MARISA_TEXT_TAIL merges last labels as zero-terminated strings. So, it is
+ // available if and only if the last labels do not contain a NULL character.
+ // If MARISA_TEXT_TAIL is specified and a NULL character exists in the last
+ // labels, the setting is automatically switched to MARISA_BINARY_TAIL.
+ MARISA_TEXT_TAIL = 0x01000,
+
+ // MARISA_BINARY_TAIL also merges last labels but as byte sequences. It uses
+ // a bit vector to detect the end of a sequence, instead of NULL characters.
+ // So, MARISA_BINARY_TAIL requires a larger space if the average length of
+ // labels is greater than 8.
+ MARISA_BINARY_TAIL = 0x02000,
+
+ MARISA_DEFAULT_TAIL = MARISA_TEXT_TAIL,
+} marisa_tail_mode;
+
+// The arrangement of nodes affects the time cost of matching and the order of
+// predictive search.
+typedef enum marisa_node_order_ {
+ // MARISA_LABEL_ORDER arranges nodes in ascending label order.
+ // MARISA_LABEL_ORDER is useful if an application needs to predict keys in
+ // label order.
+ MARISA_LABEL_ORDER = 0x10000,
+
+ // MARISA_WEIGHT_ORDER arranges nodes in descending weight order.
+ // MARISA_WEIGHT_ORDER is generally a better choice because it enables faster
+ // matching.
+ MARISA_WEIGHT_ORDER = 0x20000,
+
+ MARISA_DEFAULT_ORDER = MARISA_WEIGHT_ORDER,
+} marisa_node_order;
+
+typedef enum marisa_config_mask_ {
+ MARISA_NUM_TRIES_MASK = 0x0007F,
+ MARISA_CACHE_LEVEL_MASK = 0x00F80,
+ MARISA_TAIL_MODE_MASK = 0x0F000,
+ MARISA_NODE_ORDER_MASK = 0xF0000,
+ MARISA_CONFIG_MASK = 0xFFFFF
+} marisa_config_mask;
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
+
+#ifdef __cplusplus
+
+// `std::swap` is in <utility> since C++ 11 but in <algorithm> in C++ 98:
+#if __cplusplus >= 201103L
+ #include <utility>
+#else
+ #include <algorithm>
+#endif
+namespace marisa {
+
+typedef ::marisa_uint8 UInt8;
+typedef ::marisa_uint16 UInt16;
+typedef ::marisa_uint32 UInt32;
+typedef ::marisa_uint64 UInt64;
+
+typedef ::marisa_error_code ErrorCode;
+
+typedef ::marisa_cache_level CacheLevel;
+typedef ::marisa_tail_mode TailMode;
+typedef ::marisa_node_order NodeOrder;
+
+using std::swap;
+
+} // namespace marisa
+#endif // __cplusplus
+
+#ifdef __cplusplus
+ #include "marisa/exception.h"
+ #include "marisa/scoped-ptr.h"
+ #include "marisa/scoped-array.h"
+#endif // __cplusplus
+
+#endif // MARISA_BASE_H_
diff --git a/include/marisa/exception.h b/include/marisa/exception.h
new file mode 100644
index 0000000..508c6b8
--- /dev/null
+++ b/include/marisa/exception.h
@@ -0,0 +1,82 @@
+#ifndef MARISA_EXCEPTION_H_
+#define MARISA_EXCEPTION_H_
+
+#include <exception>
+
+#include "marisa/base.h"
+
+namespace marisa {
+
+// An exception object keeps a filename, a line number, an error code and an
+// error message. The message format is as follows:
+// "__FILE__:__LINE__: error_code: error_message"
+class Exception : public std::exception {
+ public:
+ Exception(const char *filename, int line,
+ ErrorCode error_code, const char *error_message)
+ : std::exception(), filename_(filename), line_(line),
+ error_code_(error_code), error_message_(error_message) {}
+ Exception(const Exception &ex)
+ : std::exception(), filename_(ex.filename_), line_(ex.line_),
+ error_code_(ex.error_code_), error_message_(ex.error_message_) {}
+ virtual ~Exception() throw() {}
+
+ Exception &operator=(const Exception &rhs) {
+ filename_ = rhs.filename_;
+ line_ = rhs.line_;
+ error_code_ = rhs.error_code_;
+ error_message_ = rhs.error_message_;
+ return *this;
+ }
+
+ const char *filename() const {
+ return filename_;
+ }
+ int line() const {
+ return line_;
+ }
+ ErrorCode error_code() const {
+ return error_code_;
+ }
+ const char *error_message() const {
+ return error_message_;
+ }
+
+ virtual const char *what() const throw() {
+ return error_message_;
+ }
+
+ private:
+ const char *filename_;
+ int line_;
+ ErrorCode error_code_;
+ const char *error_message_;
+};
+
+// These macros are used to convert a line number to a string constant.
+#define MARISA_INT_TO_STR(value) #value
+#define MARISA_LINE_TO_STR(line) MARISA_INT_TO_STR(line)
+#define MARISA_LINE_STR MARISA_LINE_TO_STR(__LINE__)
+
+// MARISA_THROW throws an exception with a filename, a line number, an error
+// code and an error message. The message format is as follows:
+// "__FILE__:__LINE__: error_code: error_message"
+#define MARISA_THROW(error_code, error_message) \
+ (throw marisa::Exception(__FILE__, __LINE__, error_code, \
+ __FILE__ ":" MARISA_LINE_STR ": " #error_code ": " error_message))
+
+// MARISA_THROW_IF throws an exception if `condition' is true.
+#define MARISA_THROW_IF(condition, error_code) \
+ (void)((!(condition)) || (MARISA_THROW(error_code, #condition), 0))
+
+// MARISA_DEBUG_IF is ignored if _DEBUG is undefined. So, it is useful for
+// debugging time-critical codes.
+#ifdef _DEBUG
+ #define MARISA_DEBUG_IF(cond, error_code) MARISA_THROW_IF(cond, error_code)
+#else
+ #define MARISA_DEBUG_IF(cond, error_code)
+#endif
+
+} // namespace marisa
+
+#endif // MARISA_EXCEPTION_H_
diff --git a/include/marisa/iostream.h b/include/marisa/iostream.h
new file mode 100644
index 0000000..05d139a
--- /dev/null
+++ b/include/marisa/iostream.h
@@ -0,0 +1,18 @@
+#ifndef MARISA_IOSTREAM_H_
+#define MARISA_IOSTREAM_H_
+
+#include <iosfwd>
+
+namespace marisa {
+
+class Trie;
+
+std::istream &read(std::istream &stream, Trie *trie);
+std::ostream &write(std::ostream &stream, const Trie &trie);
+
+std::istream &operator>>(std::istream &stream, Trie &trie);
+std::ostream &operator<<(std::ostream &stream, const Trie &trie);
+
+} // namespace marisa
+
+#endif // MARISA_IOSTREAM_H_
diff --git a/include/marisa/key.h b/include/marisa/key.h
new file mode 100644
index 0000000..8b2cf8f
--- /dev/null
+++ b/include/marisa/key.h
@@ -0,0 +1,85 @@
+#ifndef MARISA_KEY_H_
+#define MARISA_KEY_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+
+class Key {
+ public:
+ Key() : ptr_(NULL), length_(0), union_() {
+ union_.id = 0;
+ }
+ Key(const Key &key)
+ : ptr_(key.ptr_), length_(key.length_), union_(key.union_) {}
+
+ Key &operator=(const Key &key) {
+ ptr_ = key.ptr_;
+ length_ = key.length_;
+ union_ = key.union_;
+ return *this;
+ }
+
+ char operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR);
+ return ptr_[i];
+ }
+
+ void set_str(const char *str) {
+ MARISA_DEBUG_IF(str == NULL, MARISA_NULL_ERROR);
+ std::size_t length = 0;
+ while (str[length] != '\0') {
+ ++length;
+ }
+ MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ ptr_ = str;
+ length_ = (UInt32)length;
+ }
+ void set_str(const char *ptr, std::size_t length) {
+ MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ ptr_ = ptr;
+ length_ = (UInt32)length;
+ }
+ void set_id(std::size_t id) {
+ MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ union_.id = (UInt32)id;
+ }
+ void set_weight(float weight) {
+ union_.weight = weight;
+ }
+
+ const char *ptr() const {
+ return ptr_;
+ }
+ std::size_t length() const {
+ return length_;
+ }
+ std::size_t id() const {
+ return union_.id;
+ }
+ float weight() const {
+ return union_.weight;
+ }
+
+ void clear() {
+ Key().swap(*this);
+ }
+ void swap(Key &rhs) {
+ marisa::swap(ptr_, rhs.ptr_);
+ marisa::swap(length_, rhs.length_);
+ marisa::swap(union_.id, rhs.union_.id);
+ }
+
+ private:
+ const char *ptr_;
+ UInt32 length_;
+ union Union {
+ UInt32 id;
+ float weight;
+ } union_;
+};
+
+} // namespace marisa
+
+#endif // MARISA_KEY_H_
diff --git a/include/marisa/keyset.h b/include/marisa/keyset.h
new file mode 100644
index 0000000..e575015
--- /dev/null
+++ b/include/marisa/keyset.h
@@ -0,0 +1,80 @@
+#ifndef MARISA_KEYSET_H_
+#define MARISA_KEYSET_H_
+
+#include "marisa/key.h"
+
+namespace marisa {
+
+class Keyset {
+ public:
+ enum {
+ BASE_BLOCK_SIZE = 4096,
+ EXTRA_BLOCK_SIZE = 1024,
+ KEY_BLOCK_SIZE = 256
+ };
+
+ Keyset();
+
+ void push_back(const Key &key);
+ void push_back(const Key &key, char end_marker);
+
+ void push_back(const char *str);
+ void push_back(const char *ptr, std::size_t length, float weight = 1.0);
+
+ const Key &operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+ return key_blocks_[i / KEY_BLOCK_SIZE][i % KEY_BLOCK_SIZE];
+ }
+ Key &operator[](std::size_t i) {
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+ return key_blocks_[i / KEY_BLOCK_SIZE][i % KEY_BLOCK_SIZE];
+ }
+
+ std::size_t num_keys() const {
+ return size_;
+ }
+
+ bool empty() const {
+ return size_ == 0;
+ }
+ std::size_t size() const {
+ return size_;
+ }
+ std::size_t total_length() const {
+ return total_length_;
+ }
+
+ void reset();
+
+ void clear();
+ void swap(Keyset &rhs);
+
+ private:
+ scoped_array<scoped_array<char> > base_blocks_;
+ std::size_t base_blocks_size_;
+ std::size_t base_blocks_capacity_;
+ scoped_array<scoped_array<char> > extra_blocks_;
+ std::size_t extra_blocks_size_;
+ std::size_t extra_blocks_capacity_;
+ scoped_array<scoped_array<Key> > key_blocks_;
+ std::size_t key_blocks_size_;
+ std::size_t key_blocks_capacity_;
+ char *ptr_;
+ std::size_t avail_;
+ std::size_t size_;
+ std::size_t total_length_;
+
+ char *reserve(std::size_t size);
+
+ void append_base_block();
+ void append_extra_block(std::size_t size);
+ void append_key_block();
+
+ // Disallows copy and assignment.
+ Keyset(const Keyset &);
+ Keyset &operator=(const Keyset &);
+};
+
+} // namespace marisa
+
+#endif // MARISA_KEYSET_H_
diff --git a/include/marisa/query.h b/include/marisa/query.h
new file mode 100644
index 0000000..316e741
--- /dev/null
+++ b/include/marisa/query.h
@@ -0,0 +1,71 @@
+#ifndef MARISA_QUERY_H_
+#define MARISA_QUERY_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+
+class Query {
+ public:
+ Query() : ptr_(NULL), length_(0), id_(0) {}
+ Query(const Query &query)
+ : ptr_(query.ptr_), length_(query.length_), id_(query.id_) {}
+
+ Query &operator=(const Query &query) {
+ ptr_ = query.ptr_;
+ length_ = query.length_;
+ id_ = query.id_;
+ return *this;
+ }
+
+ char operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR);
+ return ptr_[i];
+ }
+
+ void set_str(const char *str) {
+ MARISA_DEBUG_IF(str == NULL, MARISA_NULL_ERROR);
+ std::size_t length = 0;
+ while (str[length] != '\0') {
+ ++length;
+ }
+ ptr_ = str;
+ length_ = length;
+ }
+ void set_str(const char *ptr, std::size_t length) {
+ MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ ptr_ = ptr;
+ length_ = length;
+ }
+ void set_id(std::size_t id) {
+ id_ = id;
+ }
+
+ const char *ptr() const {
+ return ptr_;
+ }
+ std::size_t length() const {
+ return length_;
+ }
+ std::size_t id() const {
+ return id_;
+ }
+
+ void clear() {
+ Query().swap(*this);
+ }
+ void swap(Query &rhs) {
+ marisa::swap(ptr_, rhs.ptr_);
+ marisa::swap(length_, rhs.length_);
+ marisa::swap(id_, rhs.id_);
+ }
+
+ private:
+ const char *ptr_;
+ std::size_t length_;
+ std::size_t id_;
+};
+
+} // namespace marisa
+
+#endif // MARISA_QUERY_H_
diff --git a/include/marisa/scoped-array.h b/include/marisa/scoped-array.h
new file mode 100644
index 0000000..12b5b9e
--- /dev/null
+++ b/include/marisa/scoped-array.h
@@ -0,0 +1,48 @@
+#ifndef MARISA_SCOPED_ARRAY_H_
+#define MARISA_SCOPED_ARRAY_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+
+template <typename T>
+class scoped_array {
+ public:
+ scoped_array() : array_(NULL) {}
+ explicit scoped_array(T *array) : array_(array) {}
+
+ ~scoped_array() {
+ delete [] array_;
+ }
+
+ void reset(T *array = NULL) {
+ MARISA_THROW_IF((array != NULL) && (array == array_), MARISA_RESET_ERROR);
+ scoped_array(array).swap(*this);
+ }
+
+ T &operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(array_ == NULL, MARISA_STATE_ERROR);
+ return array_[i];
+ }
+ T *get() const {
+ return array_;
+ }
+
+ void clear() {
+ scoped_array().swap(*this);
+ }
+ void swap(scoped_array &rhs) {
+ marisa::swap(array_, rhs.array_);
+ }
+
+ private:
+ T *array_;
+
+ // Disallows copy and assignment.
+ scoped_array(const scoped_array &);
+ scoped_array &operator=(const scoped_array &);
+};
+
+} // namespace marisa
+
+#endif // MARISA_SCOPED_ARRAY_H_
diff --git a/include/marisa/scoped-ptr.h b/include/marisa/scoped-ptr.h
new file mode 100644
index 0000000..63d7a3d
--- /dev/null
+++ b/include/marisa/scoped-ptr.h
@@ -0,0 +1,52 @@
+#ifndef MARISA_SCOPED_PTR_H_
+#define MARISA_SCOPED_PTR_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+
+template <typename T>
+class scoped_ptr {
+ public:
+ scoped_ptr() : ptr_(NULL) {}
+ explicit scoped_ptr(T *ptr) : ptr_(ptr) {}
+
+ ~scoped_ptr() {
+ delete ptr_;
+ }
+
+ void reset(T *ptr = NULL) {
+ MARISA_THROW_IF((ptr != NULL) && (ptr == ptr_), MARISA_RESET_ERROR);
+ scoped_ptr(ptr).swap(*this);
+ }
+
+ T &operator*() const {
+ MARISA_DEBUG_IF(ptr_ == NULL, MARISA_STATE_ERROR);
+ return *ptr_;
+ }
+ T *operator->() const {
+ MARISA_DEBUG_IF(ptr_ == NULL, MARISA_STATE_ERROR);
+ return ptr_;
+ }
+ T *get() const {
+ return ptr_;
+ }
+
+ void clear() {
+ scoped_ptr().swap(*this);
+ }
+ void swap(scoped_ptr &rhs) {
+ marisa::swap(ptr_, rhs.ptr_);
+ }
+
+ private:
+ T *ptr_;
+
+ // Disallows copy and assignment.
+ scoped_ptr(const scoped_ptr &);
+ scoped_ptr &operator=(const scoped_ptr &);
+};
+
+} // namespace marisa
+
+#endif // MARISA_SCOPED_PTR_H_
diff --git a/include/marisa/stdio.h b/include/marisa/stdio.h
new file mode 100644
index 0000000..ee9a7b7
--- /dev/null
+++ b/include/marisa/stdio.h
@@ -0,0 +1,15 @@
+#ifndef MARISA_MYSTDIO_H_
+#define MARISA_MYSTDIO_H_
+
+#include <cstdio>
+
+namespace marisa {
+
+class Trie;
+
+void fread(std::FILE *file, Trie *trie);
+void fwrite(std::FILE *file, const Trie &trie);
+
+} // namespace marisa
+
+#endif // MARISA_MYSTDIO_H_
diff --git a/include/marisa/trie.h b/include/marisa/trie.h
new file mode 100644
index 0000000..30f3c68
--- /dev/null
+++ b/include/marisa/trie.h
@@ -0,0 +1,64 @@
+#ifndef MARISA_TRIE_H_
+#define MARISA_TRIE_H_
+
+#include "marisa/keyset.h"
+#include "marisa/agent.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class LoudsTrie;
+
+} // namespace trie
+} // namespace grimoire
+
+class Trie {
+ friend class TrieIO;
+
+ public:
+ Trie();
+ ~Trie();
+
+ void build(Keyset &keyset, int config_flags = 0);
+
+ void mmap(const char *filename);
+ void map(const void *ptr, std::size_t size);
+
+ void load(const char *filename);
+ void read(int fd);
+
+ void save(const char *filename) const;
+ void write(int fd) const;
+
+ bool lookup(Agent &agent) const;
+ void reverse_lookup(Agent &agent) const;
+ bool common_prefix_search(Agent &agent) const;
+ bool predictive_search(Agent &agent) const;
+
+ std::size_t num_tries() const;
+ std::size_t num_keys() const;
+ std::size_t num_nodes() const;
+
+ TailMode tail_mode() const;
+ NodeOrder node_order() const;
+
+ bool empty() const;
+ std::size_t size() const;
+ std::size_t total_size() const;
+ std::size_t io_size() const;
+
+ void clear();
+ void swap(Trie &rhs);
+
+ private:
+ scoped_ptr<grimoire::trie::LoudsTrie> trie_;
+
+ // Disallows copy and assignment.
+ Trie(const Trie &);
+ Trie &operator=(const Trie &);
+};
+
+} // namespace marisa
+
+#endif // MARISA_TRIE_H_
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 0000000..2cfe33a
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = marisa
diff --git a/lib/marisa/Makefile.am b/lib/marisa/Makefile.am
new file mode 100644
index 0000000..e42408b
--- /dev/null
+++ b/lib/marisa/Makefile.am
@@ -0,0 +1,19 @@
+SUBDIRS = grimoire
+
+MY_INCLUDE = -I$(top_srcdir)/include -I$(top_srcdir)/lib
+
+AM_CXXFLAGS = -Wall -Weffc++ -Wextra -Wconversion $(MY_INCLUDE)
+
+lib_LTLIBRARIES = libmarisa.la
+
+libmarisa_la_LDFLAGS = -no-undefined
+
+libmarisa_la_LIBADD = \
+ grimoire/io/libio.la \
+ grimoire/trie/libtrie.la \
+ grimoire/vector/libvector.la
+
+libmarisa_la_SOURCES = \
+ keyset.cc \
+ agent.cc \
+ trie.cc
diff --git a/lib/marisa/agent.cc b/lib/marisa/agent.cc
new file mode 100644
index 0000000..7fa7cb1
--- /dev/null
+++ b/lib/marisa/agent.cc
@@ -0,0 +1,51 @@
+#include <new>
+
+#include "marisa/agent.h"
+#include "marisa/grimoire/trie.h"
+
+namespace marisa {
+
+Agent::Agent() : query_(), key_(), state_() {}
+
+Agent::~Agent() {}
+
+void Agent::set_query(const char *str) {
+ MARISA_THROW_IF(str == NULL, MARISA_NULL_ERROR);
+ if (state_.get() != NULL) {
+ state_->reset();
+ }
+ query_.set_str(str);
+}
+
+void Agent::set_query(const char *ptr, std::size_t length) {
+ MARISA_THROW_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ if (state_.get() != NULL) {
+ state_->reset();
+ }
+ query_.set_str(ptr, length);
+}
+
+void Agent::set_query(std::size_t key_id) {
+ if (state_.get() != NULL) {
+ state_->reset();
+ }
+ query_.set_id(key_id);
+}
+
+void Agent::init_state() {
+ MARISA_THROW_IF(state_.get() != NULL, MARISA_STATE_ERROR);
+ state_.reset(new (std::nothrow) grimoire::State);
+ MARISA_THROW_IF(state_.get() == NULL, MARISA_MEMORY_ERROR);
+}
+
+void Agent::clear() {
+ Agent().swap(*this);
+}
+
+void Agent::swap(Agent &rhs) {
+ query_.swap(rhs.query_);
+ key_.swap(rhs.key_);
+ state_.swap(rhs.state_);
+}
+
+} // namespace marisa
diff --git a/lib/marisa/grimoire/Makefile.am b/lib/marisa/grimoire/Makefile.am
new file mode 100644
index 0000000..8306e32
--- /dev/null
+++ b/lib/marisa/grimoire/Makefile.am
@@ -0,0 +1,8 @@
+SUBDIRS = algorithm io trie vector
+
+noinst_HEADERS = \
+ intrin.h \
+ io.h \
+ vector.h \
+ algorithm.h \
+ trie.h
diff --git a/lib/marisa/grimoire/algorithm.h b/lib/marisa/grimoire/algorithm.h
new file mode 100644
index 0000000..970c09f
--- /dev/null
+++ b/lib/marisa/grimoire/algorithm.h
@@ -0,0 +1,26 @@
+#ifndef MARISA_GRIMOIRE_ALGORITHM_H_
+#define MARISA_GRIMOIRE_ALGORITHM_H_
+
+#include "marisa/grimoire/algorithm/sort.h"
+
+namespace marisa {
+namespace grimoire {
+
+class Algorithm {
+ public:
+ Algorithm() {}
+
+ template <typename Iterator>
+ std::size_t sort(Iterator begin, Iterator end) const {
+ return algorithm::sort(begin, end);
+ }
+
+ private:
+ Algorithm(const Algorithm &);
+ Algorithm &operator=(const Algorithm &);
+};
+
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_ALGORITHM_H_
diff --git a/lib/marisa/grimoire/algorithm/Makefile.am b/lib/marisa/grimoire/algorithm/Makefile.am
new file mode 100644
index 0000000..df5167d
--- /dev/null
+++ b/lib/marisa/grimoire/algorithm/Makefile.am
@@ -0,0 +1,2 @@
+noinst_HEADERS = \
+ sort.h
diff --git a/lib/marisa/grimoire/algorithm/sort.h b/lib/marisa/grimoire/algorithm/sort.h
new file mode 100644
index 0000000..5f3b652
--- /dev/null
+++ b/lib/marisa/grimoire/algorithm/sort.h
@@ -0,0 +1,196 @@
+#ifndef MARISA_GRIMOIRE_ALGORITHM_SORT_H_
+#define MARISA_GRIMOIRE_ALGORITHM_SORT_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace algorithm {
+namespace details {
+
+enum {
+ MARISA_INSERTION_SORT_THRESHOLD = 10
+};
+
+template <typename T>
+int get_label(const T &unit, std::size_t depth) {
+ MARISA_DEBUG_IF(depth > unit.length(), MARISA_BOUND_ERROR);
+
+ return (depth < unit.length()) ? (int)(UInt8)unit[depth] : -1;
+}
+
+template <typename T>
+int median(const T &a, const T &b, const T &c, std::size_t depth) {
+ const int x = get_label(a, depth);
+ const int y = get_label(b, depth);
+ const int z = get_label(c, depth);
+ if (x < y) {
+ if (y < z) {
+ return y;
+ } else if (x < z) {
+ return z;
+ }
+ return x;
+ } else if (x < z) {
+ return x;
+ } else if (y < z) {
+ return z;
+ }
+ return y;
+}
+
+template <typename T>
+int compare(const T &lhs, const T &rhs, std::size_t depth) {
+ for (std::size_t i = depth; i < lhs.length(); ++i) {
+ if (i == rhs.length()) {
+ return 1;
+ }
+ if (lhs[i] != rhs[i]) {
+ return (UInt8)lhs[i] - (UInt8)rhs[i];
+ }
+ }
+ if (lhs.length() == rhs.length()) {
+ return 0;
+ }
+ return (lhs.length() < rhs.length()) ? -1 : 1;
+}
+
+template <typename Iterator>
+std::size_t insertion_sort(Iterator l, Iterator r, std::size_t depth) {
+ MARISA_DEBUG_IF(l > r, MARISA_BOUND_ERROR);
+
+ std::size_t count = 1;
+ for (Iterator i = l + 1; i < r; ++i) {
+ int result = 0;
+ for (Iterator j = i; j > l; --j) {
+ result = compare(*(j - 1), *j, depth);
+ if (result <= 0) {
+ break;
+ }
+ marisa::swap(*(j - 1), *j);
+ }
+ if (result != 0) {
+ ++count;
+ }
+ }
+ return count;
+}
+
+template <typename Iterator>
+std::size_t sort(Iterator l, Iterator r, std::size_t depth) {
+ MARISA_DEBUG_IF(l > r, MARISA_BOUND_ERROR);
+
+ std::size_t count = 0;
+ while ((r - l) > MARISA_INSERTION_SORT_THRESHOLD) {
+ Iterator pl = l;
+ Iterator pr = r;
+ Iterator pivot_l = l;
+ Iterator pivot_r = r;
+
+ const int pivot = median(*l, *(l + (r - l) / 2), *(r - 1), depth);
+ for ( ; ; ) {
+ while (pl < pr) {
+ const int label = get_label(*pl, depth);
+ if (label > pivot) {
+ break;
+ } else if (label == pivot) {
+ marisa::swap(*pl, *pivot_l);
+ ++pivot_l;
+ }
+ ++pl;
+ }
+ while (pl < pr) {
+ const int label = get_label(*--pr, depth);
+ if (label < pivot) {
+ break;
+ } else if (label == pivot) {
+ marisa::swap(*pr, *--pivot_r);
+ }
+ }
+ if (pl >= pr) {
+ break;
+ }
+ marisa::swap(*pl, *pr);
+ ++pl;
+ }
+ while (pivot_l > l) {
+ marisa::swap(*--pivot_l, *--pl);
+ }
+ while (pivot_r < r) {
+ marisa::swap(*pivot_r, *pr);
+ ++pivot_r;
+ ++pr;
+ }
+
+ if (((pl - l) > (pr - pl)) || ((r - pr) > (pr - pl))) {
+ if ((pr - pl) == 1) {
+ ++count;
+ } else if ((pr - pl) > 1) {
+ if (pivot == -1) {
+ ++count;
+ } else {
+ count += sort(pl, pr, depth + 1);
+ }
+ }
+
+ if ((pl - l) < (r - pr)) {
+ if ((pl - l) == 1) {
+ ++count;
+ } else if ((pl - l) > 1) {
+ count += sort(l, pl, depth);
+ }
+ l = pr;
+ } else {
+ if ((r - pr) == 1) {
+ ++count;
+ } else if ((r - pr) > 1) {
+ count += sort(pr, r, depth);
+ }
+ r = pl;
+ }
+ } else {
+ if ((pl - l) == 1) {
+ ++count;
+ } else if ((pl - l) > 1) {
+ count += sort(l, pl, depth);
+ }
+
+ if ((r - pr) == 1) {
+ ++count;
+ } else if ((r - pr) > 1) {
+ count += sort(pr, r, depth);
+ }
+
+ l = pl, r = pr;
+ if ((pr - pl) == 1) {
+ ++count;
+ } else if ((pr - pl) > 1) {
+ if (pivot == -1) {
+ l = r;
+ ++count;
+ } else {
+ ++depth;
+ }
+ }
+ }
+ }
+
+ if ((r - l) > 1) {
+ count += insertion_sort(l, r, depth);
+ }
+ return count;
+}
+
+} // namespace details
+
+template <typename Iterator>
+std::size_t sort(Iterator begin, Iterator end) {
+ MARISA_DEBUG_IF(begin > end, MARISA_BOUND_ERROR);
+ return details::sort(begin, end, 0);
+};
+
+} // namespace algorithm
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_ALGORITHM_SORT_H_
diff --git a/lib/marisa/grimoire/intrin.h b/lib/marisa/grimoire/intrin.h
new file mode 100644
index 0000000..77b4e99
--- /dev/null
+++ b/lib/marisa/grimoire/intrin.h
@@ -0,0 +1,138 @@
+#ifndef MARISA_GRIMOIRE_INTRIN_H_
+#define MARISA_GRIMOIRE_INTRIN_H_
+
+#include "marisa/base.h"
+
+#if defined(__x86_64__) || defined(_M_X64)
+ #define MARISA_X64
+#elif defined(__i386__) || defined(_M_IX86)
+ #define MARISA_X86
+#else // defined(__i386__) || defined(_M_IX86)
+ #ifdef MARISA_USE_BMI2
+ #undef MARISA_USE_BMI2
+ #endif // MARISA_USE_BMI2
+ #ifdef MARISA_USE_BMI
+ #undef MARISA_USE_BMI
+ #endif // MARISA_USE_BMI
+ #ifdef MARISA_USE_POPCNT
+ #undef MARISA_USE_POPCNT
+ #endif // MARISA_USE_POPCNT
+ #ifdef MARISA_USE_SSE4A
+ #undef MARISA_USE_SSE4A
+ #endif // MARISA_USE_SSE4A
+ #ifdef MARISA_USE_SSE4
+ #undef MARISA_USE_SSE4
+ #endif // MARISA_USE_SSE4
+ #ifdef MARISA_USE_SSE4_2
+ #undef MARISA_USE_SSE4_2
+ #endif // MARISA_USE_SSE4_2
+ #ifdef MARISA_USE_SSE4_1
+ #undef MARISA_USE_SSE4_1
+ #endif // MARISA_USE_SSE4_1
+ #ifdef MARISA_USE_SSSE3
+ #undef MARISA_USE_SSSE3
+ #endif // MARISA_USE_SSSE3
+ #ifdef MARISA_USE_SSE3
+ #undef MARISA_USE_SSE3
+ #endif // MARISA_USE_SSE3
+ #ifdef MARISA_USE_SSE2
+ #undef MARISA_USE_SSE2
+ #endif // MARISA_USE_SSE2
+#endif // defined(__i386__) || defined(_M_IX86)
+
+#ifdef MARISA_USE_BMI2
+ #ifndef MARISA_USE_BMI
+ #define MARISA_USE_BMI
+ #endif // MARISA_USE_BMI
+ #ifdef _MSC_VER
+ #include <immintrin.h>
+ #else // _MSC_VER
+ #include <x86intrin.h>
+ #endif // _MSC_VER
+#endif // MARISA_USE_BMI2
+
+#ifdef MARISA_USE_BMI
+ #ifndef MARISA_USE_SSE4
+ #define MARISA_USE_SSE4
+ #endif // MARISA_USE_SSE4
+#endif // MARISA_USE_BMI
+
+#ifdef MARISA_USE_SSE4A
+ #ifndef MARISA_USE_SSE3
+ #define MARISA_USE_SSE3
+ #endif // MARISA_USE_SSE3
+ #ifndef MARISA_USE_POPCNT
+ #define MARISA_USE_POPCNT
+ #endif // MARISA_USE_POPCNT
+#endif // MARISA_USE_SSE4A
+
+#ifdef MARISA_USE_SSE4
+ #ifndef MARISA_USE_SSE4_2
+ #define MARISA_USE_SSE4_2
+ #endif // MARISA_USE_SSE4_2
+#endif // MARISA_USE_SSE4
+
+#ifdef MARISA_USE_SSE4_2
+ #ifndef MARISA_USE_SSE4_1
+ #define MARISA_USE_SSE4_1
+ #endif // MARISA_USE_SSE4_1
+ #ifndef MARISA_USE_POPCNT
+ #define MARISA_USE_POPCNT
+ #endif // MARISA_USE_POPCNT
+#endif // MARISA_USE_SSE4_2
+
+#ifdef MARISA_USE_SSE4_1
+ #ifndef MARISA_USE_SSSE3
+ #define MARISA_USE_SSSE3
+ #endif // MARISA_USE_SSSE3
+#endif // MARISA_USE_SSE4_1
+
+#ifdef MARISA_USE_POPCNT
+ #ifndef MARISA_USE_SSE3
+ #define MARISA_USE_SSE3
+ #endif // MARISA_USE_SSE3
+ #ifdef _MSC_VER
+ #include <intrin.h>
+ #else // _MSC_VER
+ #include <popcntintrin.h>
+ #endif // _MSC_VER
+#endif // MARISA_USE_POPCNT
+
+#ifdef MARISA_USE_SSSE3
+ #ifndef MARISA_USE_SSE3
+ #define MARISA_USE_SSE3
+ #endif // MARISA_USE_SSE3
+ #ifdef MARISA_X64
+ #define MARISA_X64_SSSE3
+ #else // MARISA_X64
+ #define MARISA_X86_SSSE3
+ #endif // MAIRSA_X64
+ #include <tmmintrin.h>
+#endif // MARISA_USE_SSSE3
+
+#ifdef MARISA_USE_SSE3
+ #ifndef MARISA_USE_SSE2
+ #define MARISA_USE_SSE2
+ #endif // MARISA_USE_SSE2
+#endif // MARISA_USE_SSE3
+
+#ifdef MARISA_USE_SSE2
+ #ifdef MARISA_X64
+ #define MARISA_X64_SSE2
+ #else // MARISA_X64
+ #define MARISA_X86_SSE2
+ #endif // MAIRSA_X64
+ #include <emmintrin.h>
+#endif // MARISA_USE_SSE2
+
+#ifdef _MSC_VER
+ #if MARISA_WORD_SIZE == 64
+ #include <intrin.h>
+ #pragma intrinsic(_BitScanForward64)
+ #else // MARISA_WORD_SIZE == 64
+ #include <intrin.h>
+ #pragma intrinsic(_BitScanForward)
+ #endif // MARISA_WORD_SIZE == 64
+#endif // _MSC_VER
+
+#endif // MARISA_GRIMOIRE_INTRIN_H_
diff --git a/lib/marisa/grimoire/io.h b/lib/marisa/grimoire/io.h
new file mode 100644
index 0000000..43ff8c9
--- /dev/null
+++ b/lib/marisa/grimoire/io.h
@@ -0,0 +1,18 @@
+#ifndef MARISA_GRIMOIRE_IO_H_
+#define MARISA_GRIMOIRE_IO_H_
+
+#include "marisa/grimoire/io/mapper.h"
+#include "marisa/grimoire/io/reader.h"
+#include "marisa/grimoire/io/writer.h"
+
+namespace marisa {
+namespace grimoire {
+
+using io::Mapper;
+using io::Reader;
+using io::Writer;
+
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_IO_H_
diff --git a/lib/marisa/grimoire/io/Makefile.am b/lib/marisa/grimoire/io/Makefile.am
new file mode 100644
index 0000000..772c370
--- /dev/null
+++ b/lib/marisa/grimoire/io/Makefile.am
@@ -0,0 +1,17 @@
+MY_INCLUDE = -I$(top_srcdir)/include -I$(top_srcdir)/lib
+
+AM_CXXFLAGS = -Wall -Weffc++ -Wextra -Wconversion $(MY_INCLUDE)
+
+noinst_LTLIBRARIES = libio.la
+
+libio_la_LDFLAGS = -no-undefined
+
+libio_la_SOURCES = \
+ mapper.cc \
+ reader.cc \
+ writer.cc
+
+noinst_HEADERS = \
+ mapper.h \
+ reader.h \
+ writer.h
diff --git a/lib/marisa/grimoire/io/mapper.cc b/lib/marisa/grimoire/io/mapper.cc
new file mode 100644
index 0000000..6ae0ee3
--- /dev/null
+++ b/lib/marisa/grimoire/io/mapper.cc
@@ -0,0 +1,163 @@
+#if (defined _WIN32) || (defined _WIN64)
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <windows.h>
+#else // (defined _WIN32) || (defined _WIN64)
+ #include <sys/mman.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+#endif // (defined _WIN32) || (defined _WIN64)
+
+#include "marisa/grimoire/io/mapper.h"
+
+namespace marisa {
+namespace grimoire {
+namespace io {
+
+#if (defined _WIN32) || (defined _WIN64)
+Mapper::Mapper()
+ : ptr_(NULL), origin_(NULL), avail_(0), size_(0),
+ file_(NULL), map_(NULL) {}
+#else // (defined _WIN32) || (defined _WIN64)
+Mapper::Mapper()
+ : ptr_(NULL), origin_(MAP_FAILED), avail_(0), size_(0), fd_(-1) {}
+#endif // (defined _WIN32) || (defined _WIN64)
+
+#if (defined _WIN32) || (defined _WIN64)
+Mapper::~Mapper() {
+ if (origin_ != NULL) {
+ ::UnmapViewOfFile(origin_);
+ }
+
+ if (map_ != NULL) {
+ ::CloseHandle(map_);
+ }
+
+ if (file_ != NULL) {
+ ::CloseHandle(file_);
+ }
+}
+#else // (defined _WIN32) || (defined _WIN64)
+Mapper::~Mapper() {
+ if (origin_ != MAP_FAILED) {
+ ::munmap(origin_, size_);
+ }
+
+ if (fd_ != -1) {
+ ::close(fd_);
+ }
+}
+#endif // (defined _WIN32) || (defined _WIN64)
+
+void Mapper::open(const char *filename) {
+ MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
+
+ Mapper temp;
+ temp.open_(filename);
+ swap(temp);
+}
+
+void Mapper::open(const void *ptr, std::size_t size) {
+ MARISA_THROW_IF((ptr == NULL) && (size != 0), MARISA_NULL_ERROR);
+
+ Mapper temp;
+ temp.open_(ptr, size);
+ swap(temp);
+}
+
+void Mapper::seek(std::size_t size) {
+ MARISA_THROW_IF(!is_open(), MARISA_STATE_ERROR);
+ MARISA_THROW_IF(size > avail_, MARISA_IO_ERROR);
+
+ map_data(size);
+}
+
+bool Mapper::is_open() const {
+ return ptr_ != NULL;
+}
+
+void Mapper::clear() {
+ Mapper().swap(*this);
+}
+
+void Mapper::swap(Mapper &rhs) {
+ marisa::swap(ptr_, rhs.ptr_);
+ marisa::swap(avail_, rhs.avail_);
+ marisa::swap(origin_, rhs.origin_);
+ marisa::swap(size_, rhs.size_);
+#if (defined _WIN32) || (defined _WIN64)
+ marisa::swap(file_, rhs.file_);
+ marisa::swap(map_, rhs.map_);
+#else // (defined _WIN32) || (defined _WIN64)
+ marisa::swap(fd_, rhs.fd_);
+#endif // (defined _WIN32) || (defined _WIN64)
+}
+
+const void *Mapper::map_data(std::size_t size) {
+ MARISA_THROW_IF(!is_open(), MARISA_STATE_ERROR);
+ MARISA_THROW_IF(size > avail_, MARISA_IO_ERROR);
+
+ const char * const data = static_cast<const char *>(ptr_);
+ ptr_ = data + size;
+ avail_ -= size;
+ return data;
+}
+
+#if (defined _WIN32) || (defined _WIN64)
+ #ifdef __MSVCRT_VERSION__
+ #if __MSVCRT_VERSION__ >= 0x0601
+ #define MARISA_HAS_STAT64
+ #endif // __MSVCRT_VERSION__ >= 0x0601
+ #endif // __MSVCRT_VERSION__
+void Mapper::open_(const char *filename) {
+ #ifdef MARISA_HAS_STAT64
+ struct __stat64 st;
+ MARISA_THROW_IF(::_stat64(filename, &st) != 0, MARISA_IO_ERROR);
+ #else // MARISA_HAS_STAT64
+ struct _stat st;
+ MARISA_THROW_IF(::_stat(filename, &st) != 0, MARISA_IO_ERROR);
+ #endif // MARISA_HAS_STAT64
+ MARISA_THROW_IF((UInt64)st.st_size > MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ size_ = (std::size_t)st.st_size;
+
+ file_ = ::CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ MARISA_THROW_IF(file_ == INVALID_HANDLE_VALUE, MARISA_IO_ERROR);
+
+ map_ = ::CreateFileMapping(file_, NULL, PAGE_READONLY, 0, 0, NULL);
+ MARISA_THROW_IF(map_ == NULL, MARISA_IO_ERROR);
+
+ origin_ = ::MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0);
+ MARISA_THROW_IF(origin_ == NULL, MARISA_IO_ERROR);
+
+ ptr_ = static_cast<const char *>(origin_);
+ avail_ = size_;
+}
+#else // (defined _WIN32) || (defined _WIN64)
+void Mapper::open_(const char *filename) {
+ struct stat st;
+ MARISA_THROW_IF(::stat(filename, &st) != 0, MARISA_IO_ERROR);
+ MARISA_THROW_IF((UInt64)st.st_size > MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ size_ = (std::size_t)st.st_size;
+
+ fd_ = ::open(filename, O_RDONLY);
+ MARISA_THROW_IF(fd_ == -1, MARISA_IO_ERROR);
+
+ origin_ = ::mmap(NULL, size_, PROT_READ, MAP_SHARED, fd_, 0);
+ MARISA_THROW_IF(origin_ == MAP_FAILED, MARISA_IO_ERROR);
+
+ ptr_ = static_cast<const char *>(origin_);
+ avail_ = size_;
+}
+#endif // (defined _WIN32) || (defined _WIN64)
+
+void Mapper::open_(const void *ptr, std::size_t size) {
+ ptr_ = ptr;
+ avail_ = size;
+}
+
+} // namespace io
+} // namespace grimoire
+} // namespace marisa
diff --git a/lib/marisa/grimoire/io/mapper.h b/lib/marisa/grimoire/io/mapper.h
new file mode 100644
index 0000000..f701c94
--- /dev/null
+++ b/lib/marisa/grimoire/io/mapper.h
@@ -0,0 +1,67 @@
+#ifndef MARISA_GRIMOIRE_IO_MAPPER_H_
+#define MARISA_GRIMOIRE_IO_MAPPER_H_
+
+#include <cstdio>
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace io {
+
+class Mapper {
+ public:
+ Mapper();
+ ~Mapper();
+
+ void open(const char *filename);
+ void open(const void *ptr, std::size_t size);
+
+ template <typename T>
+ void map(T *obj) {
+ MARISA_THROW_IF(obj == NULL, MARISA_NULL_ERROR);
+ *obj = *static_cast<const T *>(map_data(sizeof(T)));
+ }
+
+ template <typename T>
+ void map(const T **objs, std::size_t num_objs) {
+ MARISA_THROW_IF((objs == NULL) && (num_objs != 0), MARISA_NULL_ERROR);
+ MARISA_THROW_IF(num_objs > (MARISA_SIZE_MAX / sizeof(T)),
+ MARISA_SIZE_ERROR);
+ *objs = static_cast<const T *>(map_data(sizeof(T) * num_objs));
+ }
+
+ void seek(std::size_t size);
+
+ bool is_open() const;
+
+ void clear();
+ void swap(Mapper &rhs);
+
+ private:
+ const void *ptr_;
+ void *origin_;
+ std::size_t avail_;
+ std::size_t size_;
+#if (defined _WIN32) || (defined _WIN64)
+ void *file_;
+ void *map_;
+#else // (defined _WIN32) || (defined _WIN64)
+ int fd_;
+#endif // (defined _WIN32) || (defined _WIN64)
+
+ void open_(const char *filename);
+ void open_(const void *ptr, std::size_t size);
+
+ const void *map_data(std::size_t size);
+
+ // Disallows copy and assignment.
+ Mapper(const Mapper &);
+ Mapper &operator=(const Mapper &);
+};
+
+} // namespace io
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_IO_MAPPER_H_
diff --git a/lib/marisa/grimoire/io/reader.cc b/lib/marisa/grimoire/io/reader.cc
new file mode 100644
index 0000000..b9c0809
--- /dev/null
+++ b/lib/marisa/grimoire/io/reader.cc
@@ -0,0 +1,147 @@
+#include <stdio.h>
+
+#ifdef _WIN32
+ #include <io.h>
+#else // _WIN32
+ #include <unistd.h>
+#endif // _WIN32
+
+#include <limits>
+
+#include "marisa/grimoire/io/reader.h"
+
+namespace marisa {
+namespace grimoire {
+namespace io {
+
+Reader::Reader()
+ : file_(NULL), fd_(-1), stream_(NULL), needs_fclose_(false) {}
+
+Reader::~Reader() {
+ if (needs_fclose_) {
+ ::fclose(file_);
+ }
+}
+
+void Reader::open(const char *filename) {
+ MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
+
+ Reader temp;
+ temp.open_(filename);
+ swap(temp);
+}
+
+void Reader::open(std::FILE *file) {
+ MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
+
+ Reader temp;
+ temp.open_(file);
+ swap(temp);
+}
+
+void Reader::open(int fd) {
+ MARISA_THROW_IF(fd == -1, MARISA_CODE_ERROR);
+
+ Reader temp;
+ temp.open_(fd);
+ swap(temp);
+}
+
+void Reader::open(std::istream &stream) {
+ Reader temp;
+ temp.open_(stream);
+ swap(temp);
+}
+
+void Reader::clear() {
+ Reader().swap(*this);
+}
+
+void Reader::swap(Reader &rhs) {
+ marisa::swap(file_, rhs.file_);
+ marisa::swap(fd_, rhs.fd_);
+ marisa::swap(stream_, rhs.stream_);
+ marisa::swap(needs_fclose_, rhs.needs_fclose_);
+}
+
+void Reader::seek(std::size_t size) {
+ MARISA_THROW_IF(!is_open(), MARISA_STATE_ERROR);
+ if (size == 0) {
+ return;
+ } else if (size <= 16) {
+ char buf[16];
+ read_data(buf, size);
+ } else {
+ char buf[1024];
+ while (size != 0) {
+ const std::size_t count = (size < sizeof(buf)) ? size : sizeof(buf);
+ read_data(buf, count);
+ size -= count;
+ }
+ }
+}
+
+bool Reader::is_open() const {
+ return (file_ != NULL) || (fd_ != -1) || (stream_ != NULL);
+}
+
+void Reader::open_(const char *filename) {
+ std::FILE *file = NULL;
+#ifdef _MSC_VER
+ MARISA_THROW_IF(::fopen_s(&file, filename, "rb") != 0, MARISA_IO_ERROR);
+#else // _MSC_VER
+ file = ::fopen(filename, "rb");
+ MARISA_THROW_IF(file == NULL, MARISA_IO_ERROR);
+#endif // _MSC_VER
+ file_ = file;
+ needs_fclose_ = true;
+}
+
+void Reader::open_(std::FILE *file) {
+ file_ = file;
+}
+
+void Reader::open_(int fd) {
+ fd_ = fd;
+}
+
+void Reader::open_(std::istream &stream) {
+ stream_ = &stream;
+}
+
+void Reader::read_data(void *buf, std::size_t size) {
+ MARISA_THROW_IF(!is_open(), MARISA_STATE_ERROR);
+ if (size == 0) {
+ return;
+ } else if (fd_ != -1) {
+ while (size != 0) {
+#ifdef _WIN32
+ static const std::size_t CHUNK_SIZE =
+ std::numeric_limits<int>::max();
+ const unsigned int count = (size < CHUNK_SIZE) ? size : CHUNK_SIZE;
+ const int size_read = ::_read(fd_, buf, count);
+#else // _WIN32
+ static const std::size_t CHUNK_SIZE =
+ std::numeric_limits< ::ssize_t>::max();
+ const ::size_t count = (size < CHUNK_SIZE) ? size : CHUNK_SIZE;
+ const ::ssize_t size_read = ::read(fd_, buf, count);
+#endif // _WIN32
+ MARISA_THROW_IF(size_read <= 0, MARISA_IO_ERROR);
+ buf = static_cast<char *>(buf) + size_read;
+ size -= static_cast<std::size_t>(size_read);
+ }
+ } else if (file_ != NULL) {
+ MARISA_THROW_IF(::fread(buf, 1, size, file_) != size, MARISA_IO_ERROR);
+ } else if (stream_ != NULL) {
+ try {
+ MARISA_THROW_IF(!stream_->read(static_cast<char *>(buf),
+ static_cast<std::streamsize>(size)), MARISA_IO_ERROR);
+ } catch (const std::ios_base::failure &) {
+ MARISA_THROW(MARISA_IO_ERROR, "std::ios_base::failure");
+ }
+ }
+}
+
+} // namespace io
+} // namespace grimoire
+} // namespace marisa
diff --git a/lib/marisa/grimoire/io/reader.h b/lib/marisa/grimoire/io/reader.h
new file mode 100644
index 0000000..fa4ce36
--- /dev/null
+++ b/lib/marisa/grimoire/io/reader.h
@@ -0,0 +1,66 @@
+#ifndef MARISA_GRIMOIRE_IO_READER_H_
+#define MARISA_GRIMOIRE_IO_READER_H_
+
+#include <cstdio>
+#include <iostream>
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace io {
+
+class Reader {
+ public:
+ Reader();
+ ~Reader();
+
+ void open(const char *filename);
+ void open(std::FILE *file);
+ void open(int fd);
+ void open(std::istream &stream);
+
+ template <typename T>
+ void read(T *obj) {
+ MARISA_THROW_IF(obj == NULL, MARISA_NULL_ERROR);
+ read_data(obj, sizeof(T));
+ }
+
+ template <typename T>
+ void read(T *objs, std::size_t num_objs) {
+ MARISA_THROW_IF((objs == NULL) && (num_objs != 0), MARISA_NULL_ERROR);
+ MARISA_THROW_IF(num_objs > (MARISA_SIZE_MAX / sizeof(T)),
+ MARISA_SIZE_ERROR);
+ read_data(objs, sizeof(T) * num_objs);
+ }
+
+ void seek(std::size_t size);
+
+ bool is_open() const;
+
+ void clear();
+ void swap(Reader &rhs);
+
+ private:
+ std::FILE *file_;
+ int fd_;
+ std::istream *stream_;
+ bool needs_fclose_;
+
+ void open_(const char *filename);
+ void open_(std::FILE *file);
+ void open_(int fd);
+ void open_(std::istream &stream);
+
+ void read_data(void *buf, std::size_t size);
+
+ // Disallows copy and assignment.
+ Reader(const Reader &);
+ Reader &operator=(const Reader &);
+};
+
+} // namespace io
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_IO_READER_H_
diff --git a/lib/marisa/grimoire/io/writer.cc b/lib/marisa/grimoire/io/writer.cc
new file mode 100644
index 0000000..fb3d2d0
--- /dev/null
+++ b/lib/marisa/grimoire/io/writer.cc
@@ -0,0 +1,148 @@
+#include <stdio.h>
+
+#ifdef _WIN32
+ #include <io.h>
+#else // _WIN32
+ #include <unistd.h>
+#endif // _WIN32
+
+#include <limits>
+
+#include "marisa/grimoire/io/writer.h"
+
+namespace marisa {
+namespace grimoire {
+namespace io {
+
+Writer::Writer()
+ : file_(NULL), fd_(-1), stream_(NULL), needs_fclose_(false) {}
+
+Writer::~Writer() {
+ if (needs_fclose_) {
+ ::fclose(file_);
+ }
+}
+
+void Writer::open(const char *filename) {
+ MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
+
+ Writer temp;
+ temp.open_(filename);
+ swap(temp);
+}
+
+void Writer::open(std::FILE *file) {
+ MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
+
+ Writer temp;
+ temp.open_(file);
+ swap(temp);
+}
+
+void Writer::open(int fd) {
+ MARISA_THROW_IF(fd == -1, MARISA_CODE_ERROR);
+
+ Writer temp;
+ temp.open_(fd);
+ swap(temp);
+}
+
+void Writer::open(std::ostream &stream) {
+ Writer temp;
+ temp.open_(stream);
+ swap(temp);
+}
+
+void Writer::clear() {
+ Writer().swap(*this);
+}
+
+void Writer::swap(Writer &rhs) {
+ marisa::swap(file_, rhs.file_);
+ marisa::swap(fd_, rhs.fd_);
+ marisa::swap(stream_, rhs.stream_);
+ marisa::swap(needs_fclose_, rhs.needs_fclose_);
+}
+
+void Writer::seek(std::size_t size) {
+ MARISA_THROW_IF(!is_open(), MARISA_STATE_ERROR);
+ if (size == 0) {
+ return;
+ } else if (size <= 16) {
+ const char buf[16] = {};
+ write_data(buf, size);
+ } else {
+ const char buf[1024] = {};
+ do {
+ const std::size_t count = (size < sizeof(buf)) ? size : sizeof(buf);
+ write_data(buf, count);
+ size -= count;
+ } while (size != 0);
+ }
+}
+
+bool Writer::is_open() const {
+ return (file_ != NULL) || (fd_ != -1) || (stream_ != NULL);
+}
+
+void Writer::open_(const char *filename) {
+ std::FILE *file = NULL;
+#ifdef _MSC_VER
+ MARISA_THROW_IF(::fopen_s(&file, filename, "wb") != 0, MARISA_IO_ERROR);
+#else // _MSC_VER
+ file = ::fopen(filename, "wb");
+ MARISA_THROW_IF(file == NULL, MARISA_IO_ERROR);
+#endif // _MSC_VER
+ file_ = file;
+ needs_fclose_ = true;
+}
+
+void Writer::open_(std::FILE *file) {
+ file_ = file;
+}
+
+void Writer::open_(int fd) {
+ fd_ = fd;
+}
+
+void Writer::open_(std::ostream &stream) {
+ stream_ = &stream;
+}
+
+void Writer::write_data(const void *data, std::size_t size) {
+ MARISA_THROW_IF(!is_open(), MARISA_STATE_ERROR);
+ if (size == 0) {
+ return;
+ } else if (fd_ != -1) {
+ while (size != 0) {
+#ifdef _WIN32
+ static const std::size_t CHUNK_SIZE =
+ std::numeric_limits<int>::max();
+ const unsigned int count = (size < CHUNK_SIZE) ? size : CHUNK_SIZE;
+ const int size_written = ::_write(fd_, data, count);
+#else // _WIN32
+ static const std::size_t CHUNK_SIZE =
+ std::numeric_limits< ::ssize_t>::max();
+ const ::size_t count = (size < CHUNK_SIZE) ? size : CHUNK_SIZE;
+ const ::ssize_t size_written = ::write(fd_, data, count);
+#endif // _WIN32
+ MARISA_THROW_IF(size_written <= 0, MARISA_IO_ERROR);
+ data = static_cast<const char *>(data) + size_written;
+ size -= static_cast<std::size_t>(size_written);
+ }
+ } else if (file_ != NULL) {
+ MARISA_THROW_IF(::fwrite(data, 1, size, file_) != size, MARISA_IO_ERROR);
+ MARISA_THROW_IF(::fflush(file_) != 0, MARISA_IO_ERROR);
+ } else if (stream_ != NULL) {
+ try {
+ MARISA_THROW_IF(!stream_->write(static_cast<const char *>(data),
+ static_cast<std::streamsize>(size)), MARISA_IO_ERROR);
+ } catch (const std::ios_base::failure &) {
+ MARISA_THROW(MARISA_IO_ERROR, "std::ios_base::failure");
+ }
+ }
+}
+
+} // namespace io
+} // namespace grimoire
+} // namespace marisa
diff --git a/lib/marisa/grimoire/io/writer.h b/lib/marisa/grimoire/io/writer.h
new file mode 100644
index 0000000..d49761b
--- /dev/null
+++ b/lib/marisa/grimoire/io/writer.h
@@ -0,0 +1,65 @@
+#ifndef MARISA_GRIMOIRE_IO_WRITER_H_
+#define MARISA_GRIMOIRE_IO_WRITER_H_
+
+#include <cstdio>
+#include <iostream>
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace io {
+
+class Writer {
+ public:
+ Writer();
+ ~Writer();
+
+ void open(const char *filename);
+ void open(std::FILE *file);
+ void open(int fd);
+ void open(std::ostream &stream);
+
+ template <typename T>
+ void write(const T &obj) {
+ write_data(&obj, sizeof(T));
+ }
+
+ template <typename T>
+ void write(const T *objs, std::size_t num_objs) {
+ MARISA_THROW_IF((objs == NULL) && (num_objs != 0), MARISA_NULL_ERROR);
+ MARISA_THROW_IF(num_objs > (MARISA_SIZE_MAX / sizeof(T)),
+ MARISA_SIZE_ERROR);
+ write_data(objs, sizeof(T) * num_objs);
+ }
+
+ void seek(std::size_t size);
+
+ bool is_open() const;
+
+ void clear();
+ void swap(Writer &rhs);
+
+ private:
+ std::FILE *file_;
+ int fd_;
+ std::ostream *stream_;
+ bool needs_fclose_;
+
+ void open_(const char *filename);
+ void open_(std::FILE *file);
+ void open_(int fd);
+ void open_(std::ostream &stream);
+
+ void write_data(const void *data, std::size_t size);
+
+ // Disallows copy and assignment.
+ Writer(const Writer &);
+ Writer &operator=(const Writer &);
+};
+
+} // namespace io
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_IO_WRITER_H_
diff --git a/lib/marisa/grimoire/trie.h b/lib/marisa/grimoire/trie.h
new file mode 100644
index 0000000..73a0c2b
--- /dev/null
+++ b/lib/marisa/grimoire/trie.h
@@ -0,0 +1,16 @@
+#ifndef MARISA_GRIMOIRE_TRIE_H_
+#define MARISA_GRIMOIRE_TRIE_H_
+
+#include "marisa/grimoire/trie/state.h"
+#include "marisa/grimoire/trie/louds-trie.h"
+
+namespace marisa {
+namespace grimoire {
+
+using trie::State;
+using trie::LoudsTrie;
+
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_H_
diff --git a/lib/marisa/grimoire/trie/Makefile.am b/lib/marisa/grimoire/trie/Makefile.am
new file mode 100644
index 0000000..0bb4ffa
--- /dev/null
+++ b/lib/marisa/grimoire/trie/Makefile.am
@@ -0,0 +1,23 @@
+MY_INCLUDE = -I$(top_srcdir)/include -I$(top_srcdir)/lib
+
+AM_CXXFLAGS = -Wall -Weffc++ -Wextra -Wconversion $(MY_INCLUDE)
+
+noinst_LTLIBRARIES = libtrie.la
+
+libtrie_la_LDFLAGS = -no-undefined
+
+libtrie_la_SOURCES = \
+ tail.cc \
+ louds-trie.cc
+
+noinst_HEADERS = \
+ config.h \
+ header.h \
+ key.h \
+ range.h \
+ entry.h \
+ tail.h \
+ cache.h \
+ history.h \
+ state.h \
+ louds-trie.h
diff --git a/lib/marisa/grimoire/trie/cache.h b/lib/marisa/grimoire/trie/cache.h
new file mode 100644
index 0000000..19ce021
--- /dev/null
+++ b/lib/marisa/grimoire/trie/cache.h
@@ -0,0 +1,81 @@
+#ifndef MARISA_GRIMOIRE_TRIE_CACHE_H_
+#define MARISA_GRIMOIRE_TRIE_CACHE_H_
+
+#include <cfloat>
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Cache {
+ public:
+ Cache() : parent_(0), child_(0), union_() {
+ union_.weight = FLT_MIN;
+ }
+ Cache(const Cache &cache)
+ : parent_(cache.parent_), child_(cache.child_), union_(cache.union_) {}
+
+ Cache &operator=(const Cache &cache) {
+ parent_ = cache.parent_;
+ child_ = cache.child_;
+ union_ = cache.union_;
+ return *this;
+ }
+
+ void set_parent(std::size_t parent) {
+ MARISA_DEBUG_IF(parent > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ parent_ = (UInt32)parent;
+ }
+ void set_child(std::size_t child) {
+ MARISA_DEBUG_IF(child > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ child_ = (UInt32)child;
+ }
+ void set_base(UInt8 base) {
+ union_.link = (union_.link & ~0xFFU) | base;
+ }
+ void set_extra(std::size_t extra) {
+ MARISA_DEBUG_IF(extra > (MARISA_UINT32_MAX >> 8), MARISA_SIZE_ERROR);
+ union_.link = (UInt32)((union_.link & 0xFFU) | (extra << 8));
+ }
+ void set_weight(float weight) {
+ union_.weight = weight;
+ }
+
+ std::size_t parent() const {
+ return parent_;
+ }
+ std::size_t child() const {
+ return child_;
+ }
+ UInt8 base() const {
+ return (UInt8)(union_.link & 0xFFU);
+ }
+ std::size_t extra() const {
+ return union_.link >> 8;
+ }
+ char label() const {
+ return (char)base();
+ }
+ std::size_t link() const {
+ return union_.link;
+ }
+ float weight() const {
+ return union_.weight;
+ }
+
+ private:
+ UInt32 parent_;
+ UInt32 child_;
+ union Union {
+ UInt32 link;
+ float weight;
+ } union_;
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_CACHE_H_
diff --git a/lib/marisa/grimoire/trie/config.h b/lib/marisa/grimoire/trie/config.h
new file mode 100644
index 0000000..2f1e17a
--- /dev/null
+++ b/lib/marisa/grimoire/trie/config.h
@@ -0,0 +1,155 @@
+#ifndef MARISA_GRIMOIRE_TRIE_CONFIG_H_
+#define MARISA_GRIMOIRE_TRIE_CONFIG_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Config {
+ public:
+ Config()
+ : num_tries_(MARISA_DEFAULT_NUM_TRIES),
+ cache_level_(MARISA_DEFAULT_CACHE),
+ tail_mode_(MARISA_DEFAULT_TAIL),
+ node_order_(MARISA_DEFAULT_ORDER) {}
+
+ void parse(int config_flags) {
+ Config temp;
+ temp.parse_(config_flags);
+ swap(temp);
+ }
+
+ int flags() const {
+ return (int)num_tries_ | tail_mode_ | node_order_;
+ }
+
+ std::size_t num_tries() const {
+ return num_tries_;
+ }
+ CacheLevel cache_level() const {
+ return cache_level_;
+ }
+ TailMode tail_mode() const {
+ return tail_mode_;
+ }
+ NodeOrder node_order() const {
+ return node_order_;
+ }
+
+ void clear() {
+ Config().swap(*this);
+ }
+ void swap(Config &rhs) {
+ marisa::swap(num_tries_, rhs.num_tries_);
+ marisa::swap(cache_level_, rhs.cache_level_);
+ marisa::swap(tail_mode_, rhs.tail_mode_);
+ marisa::swap(node_order_, rhs.node_order_);
+ }
+
+ private:
+ std::size_t num_tries_;
+ CacheLevel cache_level_;
+ TailMode tail_mode_;
+ NodeOrder node_order_;
+
+ void parse_(int config_flags) {
+ MARISA_THROW_IF((config_flags & ~MARISA_CONFIG_MASK) != 0,
+ MARISA_CODE_ERROR);
+
+ parse_num_tries(config_flags);
+ parse_cache_level(config_flags);
+ parse_tail_mode(config_flags);
+ parse_node_order(config_flags);
+ }
+
+ void parse_num_tries(int config_flags) {
+ const int num_tries = config_flags & MARISA_NUM_TRIES_MASK;
+ if (num_tries != 0) {
+ num_tries_ = static_cast<std::size_t>(num_tries);
+ }
+ }
+
+ void parse_cache_level(int config_flags) {
+ switch (config_flags & MARISA_CACHE_LEVEL_MASK) {
+ case 0: {
+ cache_level_ = MARISA_DEFAULT_CACHE;
+ break;
+ }
+ case MARISA_HUGE_CACHE: {
+ cache_level_ = MARISA_HUGE_CACHE;
+ break;
+ }
+ case MARISA_LARGE_CACHE: {
+ cache_level_ = MARISA_LARGE_CACHE;
+ break;
+ }
+ case MARISA_NORMAL_CACHE: {
+ cache_level_ = MARISA_NORMAL_CACHE;
+ break;
+ }
+ case MARISA_SMALL_CACHE: {
+ cache_level_ = MARISA_SMALL_CACHE;
+ break;
+ }
+ case MARISA_TINY_CACHE: {
+ cache_level_ = MARISA_TINY_CACHE;
+ break;
+ }
+ default: {
+ MARISA_THROW(MARISA_CODE_ERROR, "undefined cache level");
+ }
+ }
+ }
+
+ void parse_tail_mode(int config_flags) {
+ switch (config_flags & MARISA_TAIL_MODE_MASK) {
+ case 0: {
+ tail_mode_ = MARISA_DEFAULT_TAIL;
+ break;
+ }
+ case MARISA_TEXT_TAIL: {
+ tail_mode_ = MARISA_TEXT_TAIL;
+ break;
+ }
+ case MARISA_BINARY_TAIL: {
+ tail_mode_ = MARISA_BINARY_TAIL;
+ break;
+ }
+ default: {
+ MARISA_THROW(MARISA_CODE_ERROR, "undefined tail mode");
+ }
+ }
+ }
+
+ void parse_node_order(int config_flags) {
+ switch (config_flags & MARISA_NODE_ORDER_MASK) {
+ case 0: {
+ node_order_ = MARISA_DEFAULT_ORDER;
+ break;
+ }
+ case MARISA_LABEL_ORDER: {
+ node_order_ = MARISA_LABEL_ORDER;
+ break;
+ }
+ case MARISA_WEIGHT_ORDER: {
+ node_order_ = MARISA_WEIGHT_ORDER;
+ break;
+ }
+ default: {
+ MARISA_THROW(MARISA_CODE_ERROR, "undefined node order");
+ }
+ }
+ }
+
+ // Disallows copy and assignment.
+ Config(const Config &);
+ Config &operator=(const Config &);
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_CONFIG_H_
diff --git a/lib/marisa/grimoire/trie/entry.h b/lib/marisa/grimoire/trie/entry.h
new file mode 100644
index 0000000..2c754a8
--- /dev/null
+++ b/lib/marisa/grimoire/trie/entry.h
@@ -0,0 +1,81 @@
+#ifndef MARISA_GRIMOIRE_TRIE_ENTRY_H_
+#define MARISA_GRIMOIRE_TRIE_ENTRY_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Entry {
+ public:
+ Entry() : ptr_(NULL), length_(0), id_(0) {}
+ Entry(const Entry &entry)
+ : ptr_(entry.ptr_), length_(entry.length_), id_(entry.id_) {}
+
+ Entry &operator=(const Entry &entry) {
+ ptr_ = entry.ptr_;
+ length_ = entry.length_;
+ id_ = entry.id_;
+ return *this;
+ }
+
+ char operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR);
+ return *(ptr_ - i);
+ }
+
+ void set_str(const char *ptr, std::size_t length) {
+ MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ ptr_ = ptr + length - 1;
+ length_ = (UInt32)length;
+ }
+ void set_id(std::size_t id) {
+ MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ id_ = (UInt32)id;
+ }
+
+ const char *ptr() const {
+ return ptr_ - length_ + 1;
+ }
+ std::size_t length() const {
+ return length_;
+ }
+ std::size_t id() const {
+ return id_;
+ }
+
+ class StringComparer {
+ public:
+ bool operator()(const Entry &lhs, const Entry &rhs) const {
+ for (std::size_t i = 0; i < lhs.length(); ++i) {
+ if (i == rhs.length()) {
+ return true;
+ }
+ if (lhs[i] != rhs[i]) {
+ return (UInt8)lhs[i] > (UInt8)rhs[i];
+ }
+ }
+ return lhs.length() > rhs.length();
+ }
+ };
+
+ class IDComparer {
+ public:
+ bool operator()(const Entry &lhs, const Entry &rhs) const {
+ return lhs.id_ < rhs.id_;
+ }
+ };
+
+ private:
+ const char *ptr_;
+ UInt32 length_;
+ UInt32 id_;
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_ENTRY_H_
diff --git a/lib/marisa/grimoire/trie/header.h b/lib/marisa/grimoire/trie/header.h
new file mode 100644
index 0000000..e13220c
--- /dev/null
+++ b/lib/marisa/grimoire/trie/header.h
@@ -0,0 +1,61 @@
+#ifndef MARISA_GRIMOIRE_TRIE_HEADER_H_
+#define MARISA_GRIMOIRE_TRIE_HEADER_H_
+
+#include "marisa/grimoire/io.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Header {
+ public:
+ enum {
+ HEADER_SIZE = 16
+ };
+
+ Header() {}
+
+ void map(Mapper &mapper) {
+ const char *ptr;
+ mapper.map(&ptr, HEADER_SIZE);
+ MARISA_THROW_IF(!test_header(ptr), MARISA_FORMAT_ERROR);
+ }
+ void read(Reader &reader) {
+ char buf[HEADER_SIZE];
+ reader.read(buf, HEADER_SIZE);
+ MARISA_THROW_IF(!test_header(buf), MARISA_FORMAT_ERROR);
+ }
+ void write(Writer &writer) const {
+ writer.write(get_header(), HEADER_SIZE);
+ }
+
+ std::size_t io_size() const {
+ return HEADER_SIZE;
+ }
+
+ private:
+
+ static const char *get_header() {
+ static const char buf[HEADER_SIZE] = "We love Marisa.";
+ return buf;
+ }
+
+ static bool test_header(const char *ptr) {
+ for (std::size_t i = 0; i < HEADER_SIZE; ++i) {
+ if (ptr[i] != get_header()[i]) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Disallows copy and assignment.
+ Header(const Header &);
+ Header &operator=(const Header &);
+};
+
+} // namespace trie
+} // namespace marisa
+} // namespace grimoire
+
+#endif // MARISA_GRIMOIRE_TRIE_HEADER_H_
diff --git a/lib/marisa/grimoire/trie/history.h b/lib/marisa/grimoire/trie/history.h
new file mode 100644
index 0000000..84d10df
--- /dev/null
+++ b/lib/marisa/grimoire/trie/history.h
@@ -0,0 +1,65 @@
+#ifndef MARISA_GRIMOIRE_TRIE_STATE_HISTORY_H_
+#define MARISA_GRIMOIRE_TRIE_STATE_HISTORY_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class History {
+ public:
+ History()
+ : node_id_(0), louds_pos_(0), key_pos_(0),
+ link_id_(MARISA_INVALID_LINK_ID), key_id_(MARISA_INVALID_KEY_ID) {}
+
+ void set_node_id(std::size_t node_id) {
+ MARISA_DEBUG_IF(node_id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ node_id_ = (UInt32)node_id;
+ }
+ void set_louds_pos(std::size_t louds_pos) {
+ MARISA_DEBUG_IF(louds_pos > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ louds_pos_ = (UInt32)louds_pos;
+ }
+ void set_key_pos(std::size_t key_pos) {
+ MARISA_DEBUG_IF(key_pos > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ key_pos_ = (UInt32)key_pos;
+ }
+ void set_link_id(std::size_t link_id) {
+ MARISA_DEBUG_IF(link_id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ link_id_ = (UInt32)link_id;
+ }
+ void set_key_id(std::size_t key_id) {
+ MARISA_DEBUG_IF(key_id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ key_id_ = (UInt32)key_id;
+ }
+
+ std::size_t node_id() const {
+ return node_id_;
+ }
+ std::size_t louds_pos() const {
+ return louds_pos_;
+ }
+ std::size_t key_pos() const {
+ return key_pos_;
+ }
+ std::size_t link_id() const {
+ return link_id_;
+ }
+ std::size_t key_id() const {
+ return key_id_;
+ }
+
+ private:
+ UInt32 node_id_;
+ UInt32 louds_pos_;
+ UInt32 key_pos_;
+ UInt32 link_id_;
+ UInt32 key_id_;
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_STATE_HISTORY_H_
diff --git a/lib/marisa/grimoire/trie/key.h b/lib/marisa/grimoire/trie/key.h
new file mode 100644
index 0000000..8555cc7
--- /dev/null
+++ b/lib/marisa/grimoire/trie/key.h
@@ -0,0 +1,226 @@
+#ifndef MARISA_GRIMOIRE_TRIE_KEY_H_
+#define MARISA_GRIMOIRE_TRIE_KEY_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Key {
+ public:
+ Key() : ptr_(NULL), length_(0), union_(), id_(0) {
+ union_.terminal = 0;
+ }
+ Key(const Key &entry)
+ : ptr_(entry.ptr_), length_(entry.length_),
+ union_(entry.union_), id_(entry.id_) {}
+
+ Key &operator=(const Key &entry) {
+ ptr_ = entry.ptr_;
+ length_ = entry.length_;
+ union_ = entry.union_;
+ id_ = entry.id_;
+ return *this;
+ }
+
+ char operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR);
+ return ptr_[i];
+ }
+
+ void substr(std::size_t pos, std::size_t length) {
+ MARISA_DEBUG_IF(pos > length_, MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(length > length_, MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(pos > (length_ - length), MARISA_BOUND_ERROR);
+ ptr_ += pos;
+ length_ = (UInt32)length;
+ }
+
+ void set_str(const char *ptr, std::size_t length) {
+ MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ ptr_ = ptr;
+ length_ = (UInt32)length;
+ }
+ void set_weight(float weight) {
+ union_.weight = weight;
+ }
+ void set_terminal(std::size_t terminal) {
+ MARISA_DEBUG_IF(terminal > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ union_.terminal = (UInt32)terminal;
+ }
+ void set_id(std::size_t id) {
+ MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ id_ = (UInt32)id;
+ }
+
+ const char *ptr() const {
+ return ptr_;
+ }
+ std::size_t length() const {
+ return length_;
+ }
+ float weight() const {
+ return union_.weight;
+ }
+ std::size_t terminal() const {
+ return union_.terminal;
+ }
+ std::size_t id() const {
+ return id_;
+ }
+
+ private:
+ const char *ptr_;
+ UInt32 length_;
+ union Union {
+ float weight;
+ UInt32 terminal;
+ } union_;
+ UInt32 id_;
+};
+
+inline bool operator==(const Key &lhs, const Key &rhs) {
+ if (lhs.length() != rhs.length()) {
+ return false;
+ }
+ for (std::size_t i = 0; i < lhs.length(); ++i) {
+ if (lhs[i] != rhs[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline bool operator!=(const Key &lhs, const Key &rhs) {
+ return !(lhs == rhs);
+}
+
+inline bool operator<(const Key &lhs, const Key &rhs) {
+ for (std::size_t i = 0; i < lhs.length(); ++i) {
+ if (i == rhs.length()) {
+ return false;
+ }
+ if (lhs[i] != rhs[i]) {
+ return (UInt8)lhs[i] < (UInt8)rhs[i];
+ }
+ }
+ return lhs.length() < rhs.length();
+}
+
+inline bool operator>(const Key &lhs, const Key &rhs) {
+ return rhs < lhs;
+}
+
+class ReverseKey {
+ public:
+ ReverseKey() : ptr_(NULL), length_(0), union_(), id_(0) {
+ union_.terminal = 0;
+ }
+ ReverseKey(const ReverseKey &entry)
+ : ptr_(entry.ptr_), length_(entry.length_),
+ union_(entry.union_), id_(entry.id_) {}
+
+ ReverseKey &operator=(const ReverseKey &entry) {
+ ptr_ = entry.ptr_;
+ length_ = entry.length_;
+ union_ = entry.union_;
+ id_ = entry.id_;
+ return *this;
+ }
+
+ char operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= length_, MARISA_BOUND_ERROR);
+ return *(ptr_ - i - 1);
+ }
+
+ void substr(std::size_t pos, std::size_t length) {
+ MARISA_DEBUG_IF(pos > length_, MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(length > length_, MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(pos > (length_ - length), MARISA_BOUND_ERROR);
+ ptr_ -= pos;
+ length_ = (UInt32)length;
+ }
+
+ void set_str(const char *ptr, std::size_t length) {
+ MARISA_DEBUG_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ MARISA_DEBUG_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ ptr_ = ptr + length;
+ length_ = (UInt32)length;
+ }
+ void set_weight(float weight) {
+ union_.weight = weight;
+ }
+ void set_terminal(std::size_t terminal) {
+ MARISA_DEBUG_IF(terminal > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ union_.terminal = (UInt32)terminal;
+ }
+ void set_id(std::size_t id) {
+ MARISA_DEBUG_IF(id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ id_ = (UInt32)id;
+ }
+
+ const char *ptr() const {
+ return ptr_ - length_;
+ }
+ std::size_t length() const {
+ return length_;
+ }
+ float weight() const {
+ return union_.weight;
+ }
+ std::size_t terminal() const {
+ return union_.terminal;
+ }
+ std::size_t id() const {
+ return id_;
+ }
+
+ private:
+ const char *ptr_;
+ UInt32 length_;
+ union Union {
+ float weight;
+ UInt32 terminal;
+ } union_;
+ UInt32 id_;
+};
+
+inline bool operator==(const ReverseKey &lhs, const ReverseKey &rhs) {
+ if (lhs.length() != rhs.length()) {
+ return false;
+ }
+ for (std::size_t i = 0; i < lhs.length(); ++i) {
+ if (lhs[i] != rhs[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+inline bool operator!=(const ReverseKey &lhs, const ReverseKey &rhs) {
+ return !(lhs == rhs);
+}
+
+inline bool operator<(const ReverseKey &lhs, const ReverseKey &rhs) {
+ for (std::size_t i = 0; i < lhs.length(); ++i) {
+ if (i == rhs.length()) {
+ return false;
+ }
+ if (lhs[i] != rhs[i]) {
+ return (UInt8)lhs[i] < (UInt8)rhs[i];
+ }
+ }
+ return lhs.length() < rhs.length();
+}
+
+inline bool operator>(const ReverseKey &lhs, const ReverseKey &rhs) {
+ return rhs < lhs;
+}
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_KEY_H_
diff --git a/lib/marisa/grimoire/trie/louds-trie.cc b/lib/marisa/grimoire/trie/louds-trie.cc
new file mode 100644
index 0000000..df191f5
--- /dev/null
+++ b/lib/marisa/grimoire/trie/louds-trie.cc
@@ -0,0 +1,878 @@
+#include <algorithm>
+#include <functional>
+#include <queue>
+
+#include "marisa/grimoire/algorithm.h"
+#include "marisa/grimoire/trie/header.h"
+#include "marisa/grimoire/trie/range.h"
+#include "marisa/grimoire/trie/state.h"
+#include "marisa/grimoire/trie/louds-trie.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+LoudsTrie::LoudsTrie()
+ : louds_(), terminal_flags_(), link_flags_(), bases_(), extras_(),
+ tail_(), next_trie_(), cache_(), cache_mask_(0), num_l1_nodes_(0),
+ config_(), mapper_() {}
+
+LoudsTrie::~LoudsTrie() {}
+
+void LoudsTrie::build(Keyset &keyset, int flags) {
+ Config config;
+ config.parse(flags);
+
+ LoudsTrie temp;
+ temp.build_(keyset, config);
+ swap(temp);
+}
+
+void LoudsTrie::map(Mapper &mapper) {
+ Header().map(mapper);
+
+ LoudsTrie temp;
+ temp.map_(mapper);
+ temp.mapper_.swap(mapper);
+ swap(temp);
+}
+
+void LoudsTrie::read(Reader &reader) {
+ Header().read(reader);
+
+ LoudsTrie temp;
+ temp.read_(reader);
+ swap(temp);
+}
+
+void LoudsTrie::write(Writer &writer) const {
+ Header().write(writer);
+
+ write_(writer);
+}
+
+bool LoudsTrie::lookup(Agent &agent) const {
+ MARISA_DEBUG_IF(!agent.has_state(), MARISA_STATE_ERROR);
+
+ State &state = agent.state();
+ state.lookup_init();
+ while (state.query_pos() < agent.query().length()) {
+ if (!find_child(agent)) {
+ return false;
+ }
+ }
+ if (!terminal_flags_[state.node_id()]) {
+ return false;
+ }
+ agent.set_key(agent.query().ptr(), agent.query().length());
+ agent.set_key(terminal_flags_.rank1(state.node_id()));
+ return true;
+}
+
+void LoudsTrie::reverse_lookup(Agent &agent) const {
+ MARISA_DEBUG_IF(!agent.has_state(), MARISA_STATE_ERROR);
+ MARISA_THROW_IF(agent.query().id() >= size(), MARISA_BOUND_ERROR);
+
+ State &state = agent.state();
+ state.reverse_lookup_init();
+
+ state.set_node_id(terminal_flags_.select1(agent.query().id()));
+ if (state.node_id() == 0) {
+ agent.set_key(state.key_buf().begin(), state.key_buf().size());
+ agent.set_key(agent.query().id());
+ return;
+ }
+ for ( ; ; ) {
+ if (link_flags_[state.node_id()]) {
+ const std::size_t prev_key_pos = state.key_buf().size();
+ restore(agent, get_link(state.node_id()));
+ std::reverse(state.key_buf().begin() + prev_key_pos,
+ state.key_buf().end());
+ } else {
+ state.key_buf().push_back((char)bases_[state.node_id()]);
+ }
+
+ if (state.node_id() <= num_l1_nodes_) {
+ std::reverse(state.key_buf().begin(), state.key_buf().end());
+ agent.set_key(state.key_buf().begin(), state.key_buf().size());
+ agent.set_key(agent.query().id());
+ return;
+ }
+ state.set_node_id(louds_.select1(state.node_id()) - state.node_id() - 1);
+ }
+}
+
+bool LoudsTrie::common_prefix_search(Agent &agent) const {
+ MARISA_DEBUG_IF(!agent.has_state(), MARISA_STATE_ERROR);
+
+ State &state = agent.state();
+ if (state.status_code() == MARISA_END_OF_COMMON_PREFIX_SEARCH) {
+ return false;
+ }
+
+ if (state.status_code() != MARISA_READY_TO_COMMON_PREFIX_SEARCH) {
+ state.common_prefix_search_init();
+ if (terminal_flags_[state.node_id()]) {
+ agent.set_key(agent.query().ptr(), state.query_pos());
+ agent.set_key(terminal_flags_.rank1(state.node_id()));
+ return true;
+ }
+ }
+
+ while (state.query_pos() < agent.query().length()) {
+ if (!find_child(agent)) {
+ state.set_status_code(MARISA_END_OF_COMMON_PREFIX_SEARCH);
+ return false;
+ } else if (terminal_flags_[state.node_id()]) {
+ agent.set_key(agent.query().ptr(), state.query_pos());
+ agent.set_key(terminal_flags_.rank1(state.node_id()));
+ return true;
+ }
+ }
+ state.set_status_code(MARISA_END_OF_COMMON_PREFIX_SEARCH);
+ return false;
+}
+
+bool LoudsTrie::predictive_search(Agent &agent) const {
+ MARISA_DEBUG_IF(!agent.has_state(), MARISA_STATE_ERROR);
+
+ State &state = agent.state();
+ if (state.status_code() == MARISA_END_OF_PREDICTIVE_SEARCH) {
+ return false;
+ }
+
+ if (state.status_code() != MARISA_READY_TO_PREDICTIVE_SEARCH) {
+ state.predictive_search_init();
+ while (state.query_pos() < agent.query().length()) {
+ if (!predictive_find_child(agent)) {
+ state.set_status_code(MARISA_END_OF_PREDICTIVE_SEARCH);
+ return false;
+ }
+ }
+
+ History history;
+ history.set_node_id(state.node_id());
+ history.set_key_pos(state.key_buf().size());
+ state.history().push_back(history);
+ state.set_history_pos(1);
+
+ if (terminal_flags_[state.node_id()]) {
+ agent.set_key(state.key_buf().begin(), state.key_buf().size());
+ agent.set_key(terminal_flags_.rank1(state.node_id()));
+ return true;
+ }
+ }
+
+ for ( ; ; ) {
+ if (state.history_pos() == state.history().size()) {
+ const History &current = state.history().back();
+ History next;
+ next.set_louds_pos(louds_.select0(current.node_id()) + 1);
+ next.set_node_id(next.louds_pos() - current.node_id() - 1);
+ state.history().push_back(next);
+ }
+
+ History &next = state.history()[state.history_pos()];
+ const bool link_flag = louds_[next.louds_pos()];
+ next.set_louds_pos(next.louds_pos() + 1);
+ if (link_flag) {
+ state.set_history_pos(state.history_pos() + 1);
+ if (link_flags_[next.node_id()]) {
+ next.set_link_id(update_link_id(next.link_id(), next.node_id()));
+ restore(agent, get_link(next.node_id(), next.link_id()));
+ } else {
+ state.key_buf().push_back((char)bases_[next.node_id()]);
+ }
+ next.set_key_pos(state.key_buf().size());
+
+ if (terminal_flags_[next.node_id()]) {
+ if (next.key_id() == MARISA_INVALID_KEY_ID) {
+ next.set_key_id(terminal_flags_.rank1(next.node_id()));
+ } else {
+ next.set_key_id(next.key_id() + 1);
+ }
+ agent.set_key(state.key_buf().begin(), state.key_buf().size());
+ agent.set_key(next.key_id());
+ return true;
+ }
+ } else if (state.history_pos() != 1) {
+ History &current = state.history()[state.history_pos() - 1];
+ current.set_node_id(current.node_id() + 1);
+ const History &prev =
+ state.history()[state.history_pos() - 2];
+ state.key_buf().resize(prev.key_pos());
+ state.set_history_pos(state.history_pos() - 1);
+ } else {
+ state.set_status_code(MARISA_END_OF_PREDICTIVE_SEARCH);
+ return false;
+ }
+ }
+}
+
+std::size_t LoudsTrie::total_size() const {
+ return louds_.total_size() + terminal_flags_.total_size()
+ + link_flags_.total_size() + bases_.total_size()
+ + extras_.total_size() + tail_.total_size()
+ + ((next_trie_.get() != NULL) ? next_trie_->total_size() : 0)
+ + cache_.total_size();
+}
+
+std::size_t LoudsTrie::io_size() const {
+ return Header().io_size() + louds_.io_size()
+ + terminal_flags_.io_size() + link_flags_.io_size()
+ + bases_.io_size() + extras_.io_size() + tail_.io_size()
+ + ((next_trie_.get() != NULL) ?
+ (next_trie_->io_size() - Header().io_size()) : 0)
+ + cache_.io_size() + (sizeof(UInt32) * 2);
+}
+
+void LoudsTrie::clear() {
+ LoudsTrie().swap(*this);
+}
+
+void LoudsTrie::swap(LoudsTrie &rhs) {
+ louds_.swap(rhs.louds_);
+ terminal_flags_.swap(rhs.terminal_flags_);
+ link_flags_.swap(rhs.link_flags_);
+ bases_.swap(rhs.bases_);
+ extras_.swap(rhs.extras_);
+ tail_.swap(rhs.tail_);
+ next_trie_.swap(rhs.next_trie_);
+ cache_.swap(rhs.cache_);
+ marisa::swap(cache_mask_, rhs.cache_mask_);
+ marisa::swap(num_l1_nodes_, rhs.num_l1_nodes_);
+ config_.swap(rhs.config_);
+ mapper_.swap(rhs.mapper_);
+}
+
+void LoudsTrie::build_(Keyset &keyset, const Config &config) {
+ Vector<Key> keys;
+ keys.resize(keyset.size());
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ keys[i].set_str(keyset[i].ptr(), keyset[i].length());
+ keys[i].set_weight(keyset[i].weight());
+ }
+
+ Vector<UInt32> terminals;
+ build_trie(keys, &terminals, config, 1);
+
+ typedef std::pair<UInt32, UInt32> TerminalIdPair;
+
+ Vector<TerminalIdPair> pairs;
+ pairs.resize(terminals.size());
+ for (std::size_t i = 0; i < pairs.size(); ++i) {
+ pairs[i].first = terminals[i];
+ pairs[i].second = (UInt32)i;
+ }
+ terminals.clear();
+ std::sort(pairs.begin(), pairs.end());
+
+ std::size_t node_id = 0;
+ for (std::size_t i = 0; i < pairs.size(); ++i) {
+ while (node_id < pairs[i].first) {
+ terminal_flags_.push_back(false);
+ ++node_id;
+ }
+ if (node_id == pairs[i].first) {
+ terminal_flags_.push_back(true);
+ ++node_id;
+ }
+ }
+ while (node_id < bases_.size()) {
+ terminal_flags_.push_back(false);
+ ++node_id;
+ }
+ terminal_flags_.push_back(false);
+ terminal_flags_.build(false, true);
+
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ keyset[pairs[i].second].set_id(terminal_flags_.rank1(pairs[i].first));
+ }
+}
+
+template <typename T>
+void LoudsTrie::build_trie(Vector<T> &keys,
+ Vector<UInt32> *terminals, const Config &config, std::size_t trie_id) {
+ build_current_trie(keys, terminals, config, trie_id);
+
+ Vector<UInt32> next_terminals;
+ if (!keys.empty()) {
+ build_next_trie(keys, &next_terminals, config, trie_id);
+ }
+
+ if (next_trie_.get() != NULL) {
+ config_.parse(static_cast<int>((next_trie_->num_tries() + 1)) |
+ next_trie_->tail_mode() | next_trie_->node_order());
+ } else {
+ config_.parse(1 | tail_.mode() | config.node_order() |
+ config.cache_level());
+ }
+
+ link_flags_.build(false, false);
+ std::size_t node_id = 0;
+ for (std::size_t i = 0; i < next_terminals.size(); ++i) {
+ while (!link_flags_[node_id]) {
+ ++node_id;
+ }
+ bases_[node_id] = (UInt8)(next_terminals[i] % 256);
+ next_terminals[i] /= 256;
+ ++node_id;
+ }
+ extras_.build(next_terminals);
+ fill_cache();
+}
+
+template <typename T>
+void LoudsTrie::build_current_trie(Vector<T> &keys,
+ Vector<UInt32> *terminals, const Config &config,
+ std::size_t trie_id) try {
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ keys[i].set_id(i);
+ }
+ const std::size_t num_keys = Algorithm().sort(keys.begin(), keys.end());
+ reserve_cache(config, trie_id, num_keys);
+
+ louds_.push_back(true);
+ louds_.push_back(false);
+ bases_.push_back('\0');
+ link_flags_.push_back(false);
+
+ Vector<T> next_keys;
+ std::queue<Range> queue;
+ Vector<WeightedRange> w_ranges;
+
+ queue.push(make_range(0, keys.size(), 0));
+ while (!queue.empty()) {
+ const std::size_t node_id = link_flags_.size() - queue.size();
+
+ Range range = queue.front();
+ queue.pop();
+
+ while ((range.begin() < range.end()) &&
+ (keys[range.begin()].length() == range.key_pos())) {
+ keys[range.begin()].set_terminal(node_id);
+ range.set_begin(range.begin() + 1);
+ }
+
+ if (range.begin() == range.end()) {
+ louds_.push_back(false);
+ continue;
+ }
+
+ w_ranges.clear();
+ double weight = keys[range.begin()].weight();
+ for (std::size_t i = range.begin() + 1; i < range.end(); ++i) {
+ if (keys[i - 1][range.key_pos()] != keys[i][range.key_pos()]) {
+ w_ranges.push_back(make_weighted_range(
+ range.begin(), i, range.key_pos(), (float)weight));
+ range.set_begin(i);
+ weight = 0.0;
+ }
+ weight += keys[i].weight();
+ }
+ w_ranges.push_back(make_weighted_range(
+ range.begin(), range.end(), range.key_pos(), (float)weight));
+ if (config.node_order() == MARISA_WEIGHT_ORDER) {
+ std::stable_sort(w_ranges.begin(), w_ranges.end(),
+ std::greater<WeightedRange>());
+ }
+
+ if (node_id == 0) {
+ num_l1_nodes_ = w_ranges.size();
+ }
+
+ for (std::size_t i = 0; i < w_ranges.size(); ++i) {
+ WeightedRange &w_range = w_ranges[i];
+ std::size_t key_pos = w_range.key_pos() + 1;
+ while (key_pos < keys[w_range.begin()].length()) {
+ std::size_t j;
+ for (j = w_range.begin() + 1; j < w_range.end(); ++j) {
+ if (keys[j - 1][key_pos] != keys[j][key_pos]) {
+ break;
+ }
+ }
+ if (j < w_range.end()) {
+ break;
+ }
+ ++key_pos;
+ }
+ cache<T>(node_id, bases_.size(), w_range.weight(),
+ keys[w_range.begin()][w_range.key_pos()]);
+
+ if (key_pos == w_range.key_pos() + 1) {
+ bases_.push_back(static_cast<unsigned char>(
+ keys[w_range.begin()][w_range.key_pos()]));
+ link_flags_.push_back(false);
+ } else {
+ bases_.push_back('\0');
+ link_flags_.push_back(true);
+ T next_key;
+ next_key.set_str(keys[w_range.begin()].ptr(),
+ keys[w_range.begin()].length());
+ next_key.substr(w_range.key_pos(), key_pos - w_range.key_pos());
+ next_key.set_weight(w_range.weight());
+ next_keys.push_back(next_key);
+ }
+ w_range.set_key_pos(key_pos);
+ queue.push(w_range.range());
+ louds_.push_back(true);
+ }
+ louds_.push_back(false);
+ }
+
+ louds_.push_back(false);
+ louds_.build(trie_id == 1, true);
+ bases_.shrink();
+
+ build_terminals(keys, terminals);
+ keys.swap(next_keys);
+} catch (const std::bad_alloc &) {
+ MARISA_THROW(MARISA_MEMORY_ERROR, "std::bad_alloc");
+}
+
+template <>
+void LoudsTrie::build_next_trie(Vector<Key> &keys,
+ Vector<UInt32> *terminals, const Config &config, std::size_t trie_id) {
+ if (trie_id == config.num_tries()) {
+ Vector<Entry> entries;
+ entries.resize(keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ entries[i].set_str(keys[i].ptr(), keys[i].length());
+ }
+ tail_.build(entries, terminals, config.tail_mode());
+ return;
+ }
+ Vector<ReverseKey> reverse_keys;
+ reverse_keys.resize(keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ reverse_keys[i].set_str(keys[i].ptr(), keys[i].length());
+ reverse_keys[i].set_weight(keys[i].weight());
+ }
+ keys.clear();
+ next_trie_.reset(new (std::nothrow) LoudsTrie);
+ MARISA_THROW_IF(next_trie_.get() == NULL, MARISA_MEMORY_ERROR);
+ next_trie_->build_trie(reverse_keys, terminals, config, trie_id + 1);
+}
+
+template <>
+void LoudsTrie::build_next_trie(Vector<ReverseKey> &keys,
+ Vector<UInt32> *terminals, const Config &config, std::size_t trie_id) {
+ if (trie_id == config.num_tries()) {
+ Vector<Entry> entries;
+ entries.resize(keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ entries[i].set_str(keys[i].ptr(), keys[i].length());
+ }
+ tail_.build(entries, terminals, config.tail_mode());
+ return;
+ }
+ next_trie_.reset(new (std::nothrow) LoudsTrie);
+ MARISA_THROW_IF(next_trie_.get() == NULL, MARISA_MEMORY_ERROR);
+ next_trie_->build_trie(keys, terminals, config, trie_id + 1);
+}
+
+template <typename T>
+void LoudsTrie::build_terminals(const Vector<T> &keys,
+ Vector<UInt32> *terminals) const {
+ Vector<UInt32> temp;
+ temp.resize(keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ temp[keys[i].id()] = (UInt32)keys[i].terminal();
+ }
+ terminals->swap(temp);
+}
+
+template <>
+void LoudsTrie::cache<Key>(std::size_t parent, std::size_t child,
+ float weight, char label) {
+ MARISA_DEBUG_IF(parent >= child, MARISA_RANGE_ERROR);
+
+ const std::size_t cache_id = get_cache_id(parent, label);
+ if (weight > cache_[cache_id].weight()) {
+ cache_[cache_id].set_parent(parent);
+ cache_[cache_id].set_child(child);
+ cache_[cache_id].set_weight(weight);
+ }
+}
+
+void LoudsTrie::reserve_cache(const Config &config, std::size_t trie_id,
+ std::size_t num_keys) {
+ std::size_t cache_size = (trie_id == 1) ? 256 : 1;
+ while (cache_size < (num_keys / config.cache_level())) {
+ cache_size *= 2;
+ }
+ cache_.resize(cache_size);
+ cache_mask_ = cache_size - 1;
+}
+
+template <>
+void LoudsTrie::cache<ReverseKey>(std::size_t parent, std::size_t child,
+ float weight, char) {
+ MARISA_DEBUG_IF(parent >= child, MARISA_RANGE_ERROR);
+
+ const std::size_t cache_id = get_cache_id(child);
+ if (weight > cache_[cache_id].weight()) {
+ cache_[cache_id].set_parent(parent);
+ cache_[cache_id].set_child(child);
+ cache_[cache_id].set_weight(weight);
+ }
+}
+
+void LoudsTrie::fill_cache() {
+ for (std::size_t i = 0; i < cache_.size(); ++i) {
+ const std::size_t node_id = cache_[i].child();
+ if (node_id != 0) {
+ cache_[i].set_base(bases_[node_id]);
+ cache_[i].set_extra(!link_flags_[node_id] ?
+ MARISA_INVALID_EXTRA : extras_[link_flags_.rank1(node_id)]);
+ } else {
+ cache_[i].set_parent(MARISA_UINT32_MAX);
+ cache_[i].set_child(MARISA_UINT32_MAX);
+ }
+ }
+}
+
+void LoudsTrie::map_(Mapper &mapper) {
+ louds_.map(mapper);
+ terminal_flags_.map(mapper);
+ link_flags_.map(mapper);
+ bases_.map(mapper);
+ extras_.map(mapper);
+ tail_.map(mapper);
+ if ((link_flags_.num_1s() != 0) && tail_.empty()) {
+ next_trie_.reset(new (std::nothrow) LoudsTrie);
+ MARISA_THROW_IF(next_trie_.get() == NULL, MARISA_MEMORY_ERROR);
+ next_trie_->map_(mapper);
+ }
+ cache_.map(mapper);
+ cache_mask_ = cache_.size() - 1;
+ {
+ UInt32 temp_num_l1_nodes;
+ mapper.map(&temp_num_l1_nodes);
+ num_l1_nodes_ = temp_num_l1_nodes;
+ }
+ {
+ UInt32 temp_config_flags;
+ mapper.map(&temp_config_flags);
+ config_.parse((int)temp_config_flags);
+ }
+}
+
+void LoudsTrie::read_(Reader &reader) {
+ louds_.read(reader);
+ terminal_flags_.read(reader);
+ link_flags_.read(reader);
+ bases_.read(reader);
+ extras_.read(reader);
+ tail_.read(reader);
+ if ((link_flags_.num_1s() != 0) && tail_.empty()) {
+ next_trie_.reset(new (std::nothrow) LoudsTrie);
+ MARISA_THROW_IF(next_trie_.get() == NULL, MARISA_MEMORY_ERROR);
+ next_trie_->read_(reader);
+ }
+ cache_.read(reader);
+ cache_mask_ = cache_.size() - 1;
+ {
+ UInt32 temp_num_l1_nodes;
+ reader.read(&temp_num_l1_nodes);
+ num_l1_nodes_ = temp_num_l1_nodes;
+ }
+ {
+ UInt32 temp_config_flags;
+ reader.read(&temp_config_flags);
+ config_.parse((int)temp_config_flags);
+ }
+}
+
+void LoudsTrie::write_(Writer &writer) const {
+ louds_.write(writer);
+ terminal_flags_.write(writer);
+ link_flags_.write(writer);
+ bases_.write(writer);
+ extras_.write(writer);
+ tail_.write(writer);
+ if (next_trie_.get() != NULL) {
+ next_trie_->write_(writer);
+ }
+ cache_.write(writer);
+ writer.write((UInt32)num_l1_nodes_);
+ writer.write((UInt32)config_.flags());
+}
+
+bool LoudsTrie::find_child(Agent &agent) const {
+ MARISA_DEBUG_IF(agent.state().query_pos() >= agent.query().length(),
+ MARISA_BOUND_ERROR);
+
+ State &state = agent.state();
+ const std::size_t cache_id = get_cache_id(state.node_id(),
+ agent.query()[state.query_pos()]);
+ if (state.node_id() == cache_[cache_id].parent()) {
+ if (cache_[cache_id].extra() != MARISA_INVALID_EXTRA) {
+ if (!match(agent, cache_[cache_id].link())) {
+ return false;
+ }
+ } else {
+ state.set_query_pos(state.query_pos() + 1);
+ }
+ state.set_node_id(cache_[cache_id].child());
+ return true;
+ }
+
+ std::size_t louds_pos = louds_.select0(state.node_id()) + 1;
+ if (!louds_[louds_pos]) {
+ return false;
+ }
+ state.set_node_id(louds_pos - state.node_id() - 1);
+ std::size_t link_id = MARISA_INVALID_LINK_ID;
+ do {
+ if (link_flags_[state.node_id()]) {
+ link_id = update_link_id(link_id, state.node_id());
+ const std::size_t prev_query_pos = state.query_pos();
+ if (match(agent, get_link(state.node_id(), link_id))) {
+ return true;
+ } else if (state.query_pos() != prev_query_pos) {
+ return false;
+ }
+ } else if (bases_[state.node_id()] ==
+ (UInt8)agent.query()[state.query_pos()]) {
+ state.set_query_pos(state.query_pos() + 1);
+ return true;
+ }
+ state.set_node_id(state.node_id() + 1);
+ ++louds_pos;
+ } while (louds_[louds_pos]);
+ return false;
+}
+
+bool LoudsTrie::predictive_find_child(Agent &agent) const {
+ MARISA_DEBUG_IF(agent.state().query_pos() >= agent.query().length(),
+ MARISA_BOUND_ERROR);
+
+ State &state = agent.state();
+ const std::size_t cache_id = get_cache_id(state.node_id(),
+ agent.query()[state.query_pos()]);
+ if (state.node_id() == cache_[cache_id].parent()) {
+ if (cache_[cache_id].extra() != MARISA_INVALID_EXTRA) {
+ if (!prefix_match(agent, cache_[cache_id].link())) {
+ return false;
+ }
+ } else {
+ state.key_buf().push_back(cache_[cache_id].label());
+ state.set_query_pos(state.query_pos() + 1);
+ }
+ state.set_node_id(cache_[cache_id].child());
+ return true;
+ }
+
+ std::size_t louds_pos = louds_.select0(state.node_id()) + 1;
+ if (!louds_[louds_pos]) {
+ return false;
+ }
+ state.set_node_id(louds_pos - state.node_id() - 1);
+ std::size_t link_id = MARISA_INVALID_LINK_ID;
+ do {
+ if (link_flags_[state.node_id()]) {
+ link_id = update_link_id(link_id, state.node_id());
+ const std::size_t prev_query_pos = state.query_pos();
+ if (prefix_match(agent, get_link(state.node_id(), link_id))) {
+ return true;
+ } else if (state.query_pos() != prev_query_pos) {
+ return false;
+ }
+ } else if (bases_[state.node_id()] ==
+ (UInt8)agent.query()[state.query_pos()]) {
+ state.key_buf().push_back((char)bases_[state.node_id()]);
+ state.set_query_pos(state.query_pos() + 1);
+ return true;
+ }
+ state.set_node_id(state.node_id() + 1);
+ ++louds_pos;
+ } while (louds_[louds_pos]);
+ return false;
+}
+
+void LoudsTrie::restore(Agent &agent, std::size_t link) const {
+ if (next_trie_.get() != NULL) {
+ next_trie_->restore_(agent, link);
+ } else {
+ tail_.restore(agent, link);
+ }
+}
+
+bool LoudsTrie::match(Agent &agent, std::size_t link) const {
+ if (next_trie_.get() != NULL) {
+ return next_trie_->match_(agent, link);
+ } else {
+ return tail_.match(agent, link);
+ }
+}
+
+bool LoudsTrie::prefix_match(Agent &agent, std::size_t link) const {
+ if (next_trie_.get() != NULL) {
+ return next_trie_->prefix_match_(agent, link);
+ } else {
+ return tail_.prefix_match(agent, link);
+ }
+}
+
+void LoudsTrie::restore_(Agent &agent, std::size_t node_id) const {
+ MARISA_DEBUG_IF(node_id == 0, MARISA_RANGE_ERROR);
+
+ State &state = agent.state();
+ for ( ; ; ) {
+ const std::size_t cache_id = get_cache_id(node_id);
+ if (node_id == cache_[cache_id].child()) {
+ if (cache_[cache_id].extra() != MARISA_INVALID_EXTRA) {
+ restore(agent, cache_[cache_id].link());
+ } else {
+ state.key_buf().push_back(cache_[cache_id].label());
+ }
+
+ node_id = cache_[cache_id].parent();
+ if (node_id == 0) {
+ return;
+ }
+ continue;
+ }
+
+ if (link_flags_[node_id]) {
+ restore(agent, get_link(node_id));
+ } else {
+ state.key_buf().push_back((char)bases_[node_id]);
+ }
+
+ if (node_id <= num_l1_nodes_) {
+ return;
+ }
+ node_id = louds_.select1(node_id) - node_id - 1;
+ }
+}
+
+bool LoudsTrie::match_(Agent &agent, std::size_t node_id) const {
+ MARISA_DEBUG_IF(agent.state().query_pos() >= agent.query().length(),
+ MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(node_id == 0, MARISA_RANGE_ERROR);
+
+ State &state = agent.state();
+ for ( ; ; ) {
+ const std::size_t cache_id = get_cache_id(node_id);
+ if (node_id == cache_[cache_id].child()) {
+ if (cache_[cache_id].extra() != MARISA_INVALID_EXTRA) {
+ if (!match(agent, cache_[cache_id].link())) {
+ return false;
+ }
+ } else if (cache_[cache_id].label() ==
+ agent.query()[state.query_pos()]) {
+ state.set_query_pos(state.query_pos() + 1);
+ } else {
+ return false;
+ }
+
+ node_id = cache_[cache_id].parent();
+ if (node_id == 0) {
+ return true;
+ } else if (state.query_pos() >= agent.query().length()) {
+ return false;
+ }
+ continue;
+ }
+
+ if (link_flags_[node_id]) {
+ if (next_trie_.get() != NULL) {
+ if (!match(agent, get_link(node_id))) {
+ return false;
+ }
+ } else if (!tail_.match(agent, get_link(node_id))) {
+ return false;
+ }
+ } else if (bases_[node_id] == (UInt8)agent.query()[state.query_pos()]) {
+ state.set_query_pos(state.query_pos() + 1);
+ } else {
+ return false;
+ }
+
+ if (node_id <= num_l1_nodes_) {
+ return true;
+ } else if (state.query_pos() >= agent.query().length()) {
+ return false;
+ }
+ node_id = louds_.select1(node_id) - node_id - 1;
+ }
+}
+
+bool LoudsTrie::prefix_match_(Agent &agent, std::size_t node_id) const {
+ MARISA_DEBUG_IF(agent.state().query_pos() >= agent.query().length(),
+ MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(node_id == 0, MARISA_RANGE_ERROR);
+
+ State &state = agent.state();
+ for ( ; ; ) {
+ const std::size_t cache_id = get_cache_id(node_id);
+ if (node_id == cache_[cache_id].child()) {
+ if (cache_[cache_id].extra() != MARISA_INVALID_EXTRA) {
+ if (!prefix_match(agent, cache_[cache_id].link())) {
+ return false;
+ }
+ } else if (cache_[cache_id].label() ==
+ agent.query()[state.query_pos()]) {
+ state.key_buf().push_back(cache_[cache_id].label());
+ state.set_query_pos(state.query_pos() + 1);
+ } else {
+ return false;
+ }
+
+ node_id = cache_[cache_id].parent();
+ if (node_id == 0) {
+ return true;
+ }
+ } else {
+ if (link_flags_[node_id]) {
+ if (!prefix_match(agent, get_link(node_id))) {
+ return false;
+ }
+ } else if (bases_[node_id] == (UInt8)agent.query()[state.query_pos()]) {
+ state.key_buf().push_back((char)bases_[node_id]);
+ state.set_query_pos(state.query_pos() + 1);
+ } else {
+ return false;
+ }
+
+ if (node_id <= num_l1_nodes_) {
+ return true;
+ }
+ node_id = louds_.select1(node_id) - node_id - 1;
+ }
+
+ if (state.query_pos() >= agent.query().length()) {
+ restore_(agent, node_id);
+ return true;
+ }
+ }
+}
+
+std::size_t LoudsTrie::get_cache_id(std::size_t node_id, char label) const {
+ return (node_id ^ (node_id << 5) ^ (UInt8)label) & cache_mask_;
+}
+
+std::size_t LoudsTrie::get_cache_id(std::size_t node_id) const {
+ return node_id & cache_mask_;
+}
+
+std::size_t LoudsTrie::get_link(std::size_t node_id) const {
+ return bases_[node_id] | (extras_[link_flags_.rank1(node_id)] * 256);
+}
+
+std::size_t LoudsTrie::get_link(std::size_t node_id,
+ std::size_t link_id) const {
+ return bases_[node_id] | (extras_[link_id] * 256);
+}
+
+std::size_t LoudsTrie::update_link_id(std::size_t link_id,
+ std::size_t node_id) const {
+ return (link_id == MARISA_INVALID_LINK_ID) ?
+ link_flags_.rank1(node_id) : (link_id + 1);
+}
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
diff --git a/lib/marisa/grimoire/trie/louds-trie.h b/lib/marisa/grimoire/trie/louds-trie.h
new file mode 100644
index 0000000..24ae013
--- /dev/null
+++ b/lib/marisa/grimoire/trie/louds-trie.h
@@ -0,0 +1,134 @@
+#ifndef MARISA_GRIMOIRE_TRIE_LOUDS_TRIE_H_
+#define MARISA_GRIMOIRE_TRIE_LOUDS_TRIE_H_
+
+#include "marisa/keyset.h"
+#include "marisa/agent.h"
+#include "marisa/grimoire/vector.h"
+#include "marisa/grimoire/trie/config.h"
+#include "marisa/grimoire/trie/key.h"
+#include "marisa/grimoire/trie/tail.h"
+#include "marisa/grimoire/trie/cache.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class LoudsTrie {
+ public:
+ LoudsTrie();
+ ~LoudsTrie();
+
+ void build(Keyset &keyset, int flags);
+
+ void map(Mapper &mapper);
+ void read(Reader &reader);
+ void write(Writer &writer) const;
+
+ bool lookup(Agent &agent) const;
+ void reverse_lookup(Agent &agent) const;
+ bool common_prefix_search(Agent &agent) const;
+ bool predictive_search(Agent &agent) const;
+
+ std::size_t num_tries() const {
+ return config_.num_tries();
+ }
+ std::size_t num_keys() const {
+ return size();
+ }
+ std::size_t num_nodes() const {
+ return (louds_.size() / 2) - 1;
+ }
+
+ CacheLevel cache_level() const {
+ return config_.cache_level();
+ }
+ TailMode tail_mode() const {
+ return config_.tail_mode();
+ }
+ NodeOrder node_order() const {
+ return config_.node_order();
+ }
+
+ bool empty() const {
+ return size() == 0;
+ }
+ std::size_t size() const {
+ return terminal_flags_.num_1s();
+ }
+ std::size_t total_size() const;
+ std::size_t io_size() const;
+
+ void clear();
+ void swap(LoudsTrie &rhs);
+
+ private:
+ BitVector louds_;
+ BitVector terminal_flags_;
+ BitVector link_flags_;
+ Vector<UInt8> bases_;
+ FlatVector extras_;
+ Tail tail_;
+ scoped_ptr<LoudsTrie> next_trie_;
+ Vector<Cache> cache_;
+ std::size_t cache_mask_;
+ std::size_t num_l1_nodes_;
+ Config config_;
+ Mapper mapper_;
+
+ void build_(Keyset &keyset, const Config &config);
+
+ template <typename T>
+ void build_trie(Vector<T> &keys,
+ Vector<UInt32> *terminals, const Config &config, std::size_t trie_id);
+ template <typename T>
+ void build_current_trie(Vector<T> &keys,
+ Vector<UInt32> *terminals, const Config &config, std::size_t trie_id);
+ template <typename T>
+ void build_next_trie(Vector<T> &keys,
+ Vector<UInt32> *terminals, const Config &config, std::size_t trie_id);
+ template <typename T>
+ void build_terminals(const Vector<T> &keys,
+ Vector<UInt32> *terminals) const;
+
+ void reserve_cache(const Config &config, std::size_t trie_id,
+ std::size_t num_keys);
+ template <typename T>
+ void cache(std::size_t parent, std::size_t child,
+ float weight, char label);
+ void fill_cache();
+
+ void map_(Mapper &mapper);
+ void read_(Reader &reader);
+ void write_(Writer &writer) const;
+
+ inline bool find_child(Agent &agent) const;
+ inline bool predictive_find_child(Agent &agent) const;
+
+ inline void restore(Agent &agent, std::size_t node_id) const;
+ inline bool match(Agent &agent, std::size_t node_id) const;
+ inline bool prefix_match(Agent &agent, std::size_t node_id) const;
+
+ void restore_(Agent &agent, std::size_t node_id) const;
+ bool match_(Agent &agent, std::size_t node_id) const;
+ bool prefix_match_(Agent &agent, std::size_t node_id) const;
+
+ inline std::size_t get_cache_id(std::size_t node_id, char label) const;
+ inline std::size_t get_cache_id(std::size_t node_id) const;
+
+ inline std::size_t get_link(std::size_t node_id) const;
+ inline std::size_t get_link(std::size_t node_id,
+ std::size_t link_id) const;
+
+ inline std::size_t update_link_id(std::size_t link_id,
+ std::size_t node_id) const;
+
+ // Disallows copy and assignment.
+ LoudsTrie(const LoudsTrie &);
+ LoudsTrie &operator=(const LoudsTrie &);
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_LOUDS_TRIE_H_
diff --git a/lib/marisa/grimoire/trie/range.h b/lib/marisa/grimoire/trie/range.h
new file mode 100644
index 0000000..6c78ddb
--- /dev/null
+++ b/lib/marisa/grimoire/trie/range.h
@@ -0,0 +1,115 @@
+#ifndef MARISA_GRIMOIRE_TRIE_RANGE_H_
+#define MARISA_GRIMOIRE_TRIE_RANGE_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Range {
+ public:
+ Range() : begin_(0), end_(0), key_pos_(0) {}
+
+ void set_begin(std::size_t begin) {
+ MARISA_DEBUG_IF(begin > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ begin_ = static_cast<UInt32>(begin);
+ }
+ void set_end(std::size_t end) {
+ MARISA_DEBUG_IF(end > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ end_ = static_cast<UInt32>(end);
+ }
+ void set_key_pos(std::size_t key_pos) {
+ MARISA_DEBUG_IF(key_pos > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ key_pos_ = static_cast<UInt32>(key_pos);
+ }
+
+ std::size_t begin() const {
+ return begin_;
+ }
+ std::size_t end() const {
+ return end_;
+ }
+ std::size_t key_pos() const {
+ return key_pos_;
+ }
+
+ private:
+ UInt32 begin_;
+ UInt32 end_;
+ UInt32 key_pos_;
+};
+
+inline Range make_range(std::size_t begin, std::size_t end,
+ std::size_t key_pos) {
+ Range range;
+ range.set_begin(begin);
+ range.set_end(end);
+ range.set_key_pos(key_pos);
+ return range;
+}
+
+class WeightedRange {
+ public:
+ WeightedRange() : range_(), weight_(0.0F) {}
+
+ void set_range(const Range &range) {
+ range_ = range;
+ }
+ void set_begin(std::size_t begin) {
+ range_.set_begin(begin);
+ }
+ void set_end(std::size_t end) {
+ range_.set_end(end);
+ }
+ void set_key_pos(std::size_t key_pos) {
+ range_.set_key_pos(key_pos);
+ }
+ void set_weight(float weight) {
+ weight_ = weight;
+ }
+
+ const Range &range() const {
+ return range_;
+ }
+ std::size_t begin() const {
+ return range_.begin();
+ }
+ std::size_t end() const {
+ return range_.end();
+ }
+ std::size_t key_pos() const {
+ return range_.key_pos();
+ }
+ float weight() const {
+ return weight_;
+ }
+
+ private:
+ Range range_;
+ float weight_;
+};
+
+inline bool operator<(const WeightedRange &lhs, const WeightedRange &rhs) {
+ return lhs.weight() < rhs.weight();
+}
+
+inline bool operator>(const WeightedRange &lhs, const WeightedRange &rhs) {
+ return lhs.weight() > rhs.weight();
+}
+
+inline WeightedRange make_weighted_range(std::size_t begin, std::size_t end,
+ std::size_t key_pos, float weight) {
+ WeightedRange range;
+ range.set_begin(begin);
+ range.set_end(end);
+ range.set_key_pos(key_pos);
+ range.set_weight(weight);
+ return range;
+}
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_RANGE_H_
diff --git a/lib/marisa/grimoire/trie/state.h b/lib/marisa/grimoire/trie/state.h
new file mode 100644
index 0000000..df605a6
--- /dev/null
+++ b/lib/marisa/grimoire/trie/state.h
@@ -0,0 +1,117 @@
+#ifndef MARISA_GRIMOIRE_TRIE_STATE_H_
+#define MARISA_GRIMOIRE_TRIE_STATE_H_
+
+#include "marisa/grimoire/vector.h"
+#include "marisa/grimoire/trie/history.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+// A search agent has its internal state and the status codes are defined
+// below.
+typedef enum StatusCode {
+ MARISA_READY_TO_ALL,
+ MARISA_READY_TO_COMMON_PREFIX_SEARCH,
+ MARISA_READY_TO_PREDICTIVE_SEARCH,
+ MARISA_END_OF_COMMON_PREFIX_SEARCH,
+ MARISA_END_OF_PREDICTIVE_SEARCH,
+} StatusCode;
+
+class State {
+ public:
+ State()
+ : key_buf_(), history_(), node_id_(0), query_pos_(0),
+ history_pos_(0), status_code_(MARISA_READY_TO_ALL) {}
+
+ void set_node_id(std::size_t node_id) {
+ MARISA_DEBUG_IF(node_id > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ node_id_ = (UInt32)node_id;
+ }
+ void set_query_pos(std::size_t query_pos) {
+ MARISA_DEBUG_IF(query_pos > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ query_pos_ = (UInt32)query_pos;
+ }
+ void set_history_pos(std::size_t history_pos) {
+ MARISA_DEBUG_IF(history_pos > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ history_pos_ = (UInt32)history_pos;
+ }
+ void set_status_code(StatusCode status_code) {
+ status_code_ = status_code;
+ }
+
+ std::size_t node_id() const {
+ return node_id_;
+ }
+ std::size_t query_pos() const {
+ return query_pos_;
+ }
+ std::size_t history_pos() const {
+ return history_pos_;
+ }
+ StatusCode status_code() const {
+ return status_code_;
+ }
+
+ const Vector<char> &key_buf() const {
+ return key_buf_;
+ }
+ const Vector<History> &history() const {
+ return history_;
+ }
+
+ Vector<char> &key_buf() {
+ return key_buf_;
+ }
+ Vector<History> &history() {
+ return history_;
+ }
+
+ void reset() {
+ status_code_ = MARISA_READY_TO_ALL;
+ }
+
+ void lookup_init() {
+ node_id_ = 0;
+ query_pos_ = 0;
+ status_code_ = MARISA_READY_TO_ALL;
+ }
+ void reverse_lookup_init() {
+ key_buf_.resize(0);
+ key_buf_.reserve(32);
+ status_code_ = MARISA_READY_TO_ALL;
+ }
+ void common_prefix_search_init() {
+ node_id_ = 0;
+ query_pos_ = 0;
+ status_code_ = MARISA_READY_TO_COMMON_PREFIX_SEARCH;
+ }
+ void predictive_search_init() {
+ key_buf_.resize(0);
+ key_buf_.reserve(64);
+ history_.resize(0);
+ history_.reserve(4);
+ node_id_ = 0;
+ query_pos_ = 0;
+ history_pos_ = 0;
+ status_code_ = MARISA_READY_TO_PREDICTIVE_SEARCH;
+ }
+
+ private:
+ Vector<char> key_buf_;
+ Vector<History> history_;
+ UInt32 node_id_;
+ UInt32 query_pos_;
+ UInt32 history_pos_;
+ StatusCode status_code_;
+
+ // Disallows copy and assignment.
+ State(const State &);
+ State &operator=(const State &);
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_STATE_H_
diff --git a/lib/marisa/grimoire/trie/tail.cc b/lib/marisa/grimoire/trie/tail.cc
new file mode 100644
index 0000000..bd9bd01
--- /dev/null
+++ b/lib/marisa/grimoire/trie/tail.cc
@@ -0,0 +1,218 @@
+#include "marisa/grimoire/algorithm.h"
+#include "marisa/grimoire/trie/state.h"
+#include "marisa/grimoire/trie/tail.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+Tail::Tail() : buf_(), end_flags_() {}
+
+void Tail::build(Vector<Entry> &entries, Vector<UInt32> *offsets,
+ TailMode mode) {
+ MARISA_THROW_IF(offsets == NULL, MARISA_NULL_ERROR);
+
+ switch (mode) {
+ case MARISA_TEXT_TAIL: {
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ const char * const ptr = entries[i].ptr();
+ const std::size_t length = entries[i].length();
+ for (std::size_t j = 0; j < length; ++j) {
+ if (ptr[j] == '\0') {
+ mode = MARISA_BINARY_TAIL;
+ break;
+ }
+ }
+ if (mode == MARISA_BINARY_TAIL) {
+ break;
+ }
+ }
+ break;
+ }
+ case MARISA_BINARY_TAIL: {
+ break;
+ }
+ default: {
+ MARISA_THROW(MARISA_CODE_ERROR, "undefined tail mode");
+ }
+ }
+
+ Tail temp;
+ temp.build_(entries, offsets, mode);
+ swap(temp);
+}
+
+void Tail::map(Mapper &mapper) {
+ Tail temp;
+ temp.map_(mapper);
+ swap(temp);
+}
+
+void Tail::read(Reader &reader) {
+ Tail temp;
+ temp.read_(reader);
+ swap(temp);
+}
+
+void Tail::write(Writer &writer) const {
+ write_(writer);
+}
+
+void Tail::restore(Agent &agent, std::size_t offset) const {
+ MARISA_DEBUG_IF(buf_.empty(), MARISA_STATE_ERROR);
+
+ State &state = agent.state();
+ if (end_flags_.empty()) {
+ for (const char *ptr = &buf_[offset]; *ptr != '\0'; ++ptr) {
+ state.key_buf().push_back(*ptr);
+ }
+ } else {
+ do {
+ state.key_buf().push_back(buf_[offset]);
+ } while (!end_flags_[offset++]);
+ }
+}
+
+bool Tail::match(Agent &agent, std::size_t offset) const {
+ MARISA_DEBUG_IF(buf_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(agent.state().query_pos() >= agent.query().length(),
+ MARISA_BOUND_ERROR);
+
+ State &state = agent.state();
+ if (end_flags_.empty()) {
+ const char * const ptr = &buf_[offset] - state.query_pos();
+ do {
+ if (ptr[state.query_pos()] != agent.query()[state.query_pos()]) {
+ return false;
+ }
+ state.set_query_pos(state.query_pos() + 1);
+ if (ptr[state.query_pos()] == '\0') {
+ return true;
+ }
+ } while (state.query_pos() < agent.query().length());
+ return false;
+ } else {
+ do {
+ if (buf_[offset] != agent.query()[state.query_pos()]) {
+ return false;
+ }
+ state.set_query_pos(state.query_pos() + 1);
+ if (end_flags_[offset++]) {
+ return true;
+ }
+ } while (state.query_pos() < agent.query().length());
+ return false;
+ }
+}
+
+bool Tail::prefix_match(Agent &agent, std::size_t offset) const {
+ MARISA_DEBUG_IF(buf_.empty(), MARISA_STATE_ERROR);
+
+ State &state = agent.state();
+ if (end_flags_.empty()) {
+ const char *ptr = &buf_[offset] - state.query_pos();
+ do {
+ if (ptr[state.query_pos()] != agent.query()[state.query_pos()]) {
+ return false;
+ }
+ state.key_buf().push_back(ptr[state.query_pos()]);
+ state.set_query_pos(state.query_pos() + 1);
+ if (ptr[state.query_pos()] == '\0') {
+ return true;
+ }
+ } while (state.query_pos() < agent.query().length());
+ ptr += state.query_pos();
+ do {
+ state.key_buf().push_back(*ptr);
+ } while (*++ptr != '\0');
+ return true;
+ } else {
+ do {
+ if (buf_[offset] != agent.query()[state.query_pos()]) {
+ return false;
+ }
+ state.key_buf().push_back(buf_[offset]);
+ state.set_query_pos(state.query_pos() + 1);
+ if (end_flags_[offset++]) {
+ return true;
+ }
+ } while (state.query_pos() < agent.query().length());
+ do {
+ state.key_buf().push_back(buf_[offset]);
+ } while (!end_flags_[offset++]);
+ return true;
+ }
+}
+
+void Tail::clear() {
+ Tail().swap(*this);
+}
+
+void Tail::swap(Tail &rhs) {
+ buf_.swap(rhs.buf_);
+ end_flags_.swap(rhs.end_flags_);
+}
+
+void Tail::build_(Vector<Entry> &entries, Vector<UInt32> *offsets,
+ TailMode mode) {
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ entries[i].set_id(i);
+ }
+ Algorithm().sort(entries.begin(), entries.end());
+
+ Vector<UInt32> temp_offsets;
+ temp_offsets.resize(entries.size(), 0);
+
+ const Entry dummy;
+ const Entry *last = &dummy;
+ for (std::size_t i = entries.size(); i > 0; --i) {
+ const Entry &current = entries[i - 1];
+ MARISA_THROW_IF(current.length() == 0, MARISA_RANGE_ERROR);
+ std::size_t match = 0;
+ while ((match < current.length()) && (match < last->length()) &&
+ ((*last)[match] == current[match])) {
+ ++match;
+ }
+ if ((match == current.length()) && (last->length() != 0)) {
+ temp_offsets[current.id()] = (UInt32)(
+ temp_offsets[last->id()] + (last->length() - match));
+ } else {
+ temp_offsets[current.id()] = (UInt32)buf_.size();
+ for (std::size_t j = 1; j <= current.length(); ++j) {
+ buf_.push_back(current[current.length() - j]);
+ }
+ if (mode == MARISA_TEXT_TAIL) {
+ buf_.push_back('\0');
+ } else {
+ for (std::size_t j = 1; j < current.length(); ++j) {
+ end_flags_.push_back(false);
+ }
+ end_flags_.push_back(true);
+ }
+ MARISA_THROW_IF(buf_.size() > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ }
+ last = &current;
+ }
+ buf_.shrink();
+
+ offsets->swap(temp_offsets);
+}
+
+void Tail::map_(Mapper &mapper) {
+ buf_.map(mapper);
+ end_flags_.map(mapper);
+}
+
+void Tail::read_(Reader &reader) {
+ buf_.read(reader);
+ end_flags_.read(reader);
+}
+
+void Tail::write_(Writer &writer) const {
+ buf_.write(writer);
+ end_flags_.write(writer);
+}
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
diff --git a/lib/marisa/grimoire/trie/tail.h b/lib/marisa/grimoire/trie/tail.h
new file mode 100644
index 0000000..dd24f3e
--- /dev/null
+++ b/lib/marisa/grimoire/trie/tail.h
@@ -0,0 +1,72 @@
+#ifndef MARISA_GRIMOIRE_TRIE_TAIL_H_
+#define MARISA_GRIMOIRE_TRIE_TAIL_H_
+
+#include "marisa/agent.h"
+#include "marisa/grimoire/vector.h"
+#include "marisa/grimoire/trie/entry.h"
+
+namespace marisa {
+namespace grimoire {
+namespace trie {
+
+class Tail {
+ public:
+ Tail();
+
+ void build(Vector<Entry> &entries, Vector<UInt32> *offsets,
+ TailMode mode);
+
+ void map(Mapper &mapper);
+ void read(Reader &reader);
+ void write(Writer &writer) const;
+
+ void restore(Agent &agent, std::size_t offset) const;
+ bool match(Agent &agent, std::size_t offset) const;
+ bool prefix_match(Agent &agent, std::size_t offset) const;
+
+ const char &operator[](std::size_t offset) const {
+ MARISA_DEBUG_IF(offset >= buf_.size(), MARISA_BOUND_ERROR);
+ return buf_[offset];
+ }
+
+ TailMode mode() const {
+ return end_flags_.empty() ? MARISA_TEXT_TAIL : MARISA_BINARY_TAIL;
+ }
+
+ bool empty() const {
+ return buf_.empty();
+ }
+ std::size_t size() const {
+ return buf_.size();
+ }
+ std::size_t total_size() const {
+ return buf_.total_size() + end_flags_.total_size();
+ }
+ std::size_t io_size() const {
+ return buf_.io_size() + end_flags_.io_size();
+ }
+
+ void clear();
+ void swap(Tail &rhs);
+
+ private:
+ Vector<char> buf_;
+ BitVector end_flags_;
+
+ void build_(Vector<Entry> &entries, Vector<UInt32> *offsets,
+ TailMode mode);
+
+ void map_(Mapper &mapper);
+ void read_(Reader &reader);
+ void write_(Writer &writer) const;
+
+ // Disallows copy and assignment.
+ Tail(const Tail &);
+ Tail &operator=(const Tail &);
+};
+
+} // namespace trie
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_TRIE_TAIL_H_
diff --git a/lib/marisa/grimoire/vector.h b/lib/marisa/grimoire/vector.h
new file mode 100644
index 0000000..582160b
--- /dev/null
+++ b/lib/marisa/grimoire/vector.h
@@ -0,0 +1,18 @@
+#ifndef MARISA_GRIMOIRE_VECTOR_H_
+#define MARISA_GRIMOIRE_VECTOR_H_
+
+#include "marisa/grimoire/vector/vector.h"
+#include "marisa/grimoire/vector/flat-vector.h"
+#include "marisa/grimoire/vector/bit-vector.h"
+
+namespace marisa {
+namespace grimoire {
+
+using vector::Vector;
+typedef vector::FlatVector FlatVector;
+typedef vector::BitVector BitVector;
+
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_VECTOR_H_
diff --git a/lib/marisa/grimoire/vector/Makefile.am b/lib/marisa/grimoire/vector/Makefile.am
new file mode 100644
index 0000000..a447d98
--- /dev/null
+++ b/lib/marisa/grimoire/vector/Makefile.am
@@ -0,0 +1,17 @@
+MY_INCLUDE = -I$(top_srcdir)/include -I$(top_srcdir)/lib
+
+AM_CXXFLAGS = -Wall -Weffc++ -Wextra -Wconversion $(MY_INCLUDE)
+
+noinst_LTLIBRARIES = libvector.la
+
+libvector_la_LDFLAGS = -no-undefined
+
+libvector_la_SOURCES = \
+ bit-vector.cc
+
+noinst_HEADERS = \
+ pop-count.h \
+ rank-index.h \
+ vector.h \
+ flat-vector.h \
+ bit-vector.h
diff --git a/lib/marisa/grimoire/vector/bit-vector.cc b/lib/marisa/grimoire/vector/bit-vector.cc
new file mode 100644
index 0000000..60ded67
--- /dev/null
+++ b/lib/marisa/grimoire/vector/bit-vector.cc
@@ -0,0 +1,844 @@
+#include "marisa/grimoire/vector/pop-count.h"
+#include "marisa/grimoire/vector/bit-vector.h"
+
+namespace marisa {
+namespace grimoire {
+namespace vector {
+namespace {
+
+#ifdef MARISA_USE_BMI2
+std::size_t select_bit(std::size_t i, std::size_t bit_id, UInt64 unit) {
+ #ifdef _MSC_VER
+ unsigned long pos;
+ ::_BitScanForward64(&pos, _pdep_u64(1ULL << i, unit));
+ return bit_id + pos;
+ #else // _MSC_VER
+ return bit_id + ::__builtin_ctzll(_pdep_u64(1ULL << i, unit));
+ #endif // _MSC_VER
+}
+#else // MARISA_USE_BMI2
+const UInt8 SELECT_TABLE[8][256] = {
+ {
+ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
+ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+ },
+ {
+ 7, 7, 7, 1, 7, 2, 2, 1, 7, 3, 3, 1, 3, 2, 2, 1,
+ 7, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 7, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
+ 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 7, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1,
+ 6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
+ 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 7, 7, 7, 1, 7, 2, 2, 1, 7, 3, 3, 1, 3, 2, 2, 1,
+ 7, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 7, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
+ 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 7, 6, 6, 1, 6, 2, 2, 1, 6, 3, 3, 1, 3, 2, 2, 1,
+ 6, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1,
+ 6, 5, 5, 1, 5, 2, 2, 1, 5, 3, 3, 1, 3, 2, 2, 1,
+ 5, 4, 4, 1, 4, 2, 2, 1, 4, 3, 3, 1, 3, 2, 2, 1
+ },
+ {
+ 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 3, 7, 3, 3, 2,
+ 7, 7, 7, 4, 7, 4, 4, 2, 7, 4, 4, 3, 4, 3, 3, 2,
+ 7, 7, 7, 5, 7, 5, 5, 2, 7, 5, 5, 3, 5, 3, 3, 2,
+ 7, 5, 5, 4, 5, 4, 4, 2, 5, 4, 4, 3, 4, 3, 3, 2,
+ 7, 7, 7, 6, 7, 6, 6, 2, 7, 6, 6, 3, 6, 3, 3, 2,
+ 7, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 3, 4, 3, 3, 2,
+ 7, 6, 6, 5, 6, 5, 5, 2, 6, 5, 5, 3, 5, 3, 3, 2,
+ 6, 5, 5, 4, 5, 4, 4, 2, 5, 4, 4, 3, 4, 3, 3, 2,
+ 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 3, 7, 3, 3, 2,
+ 7, 7, 7, 4, 7, 4, 4, 2, 7, 4, 4, 3, 4, 3, 3, 2,
+ 7, 7, 7, 5, 7, 5, 5, 2, 7, 5, 5, 3, 5, 3, 3, 2,
+ 7, 5, 5, 4, 5, 4, 4, 2, 5, 4, 4, 3, 4, 3, 3, 2,
+ 7, 7, 7, 6, 7, 6, 6, 2, 7, 6, 6, 3, 6, 3, 3, 2,
+ 7, 6, 6, 4, 6, 4, 4, 2, 6, 4, 4, 3, 4, 3, 3, 2,
+ 7, 6, 6, 5, 6, 5, 5, 2, 6, 5, 5, 3, 5, 3, 3, 2,
+ 6, 5, 5, 4, 5, 4, 4, 2, 5, 4, 4, 3, 4, 3, 3, 2
+ },
+ {
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3,
+ 7, 7, 7, 7, 7, 7, 7, 4, 7, 7, 7, 4, 7, 4, 4, 3,
+ 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 5, 7, 5, 5, 3,
+ 7, 7, 7, 5, 7, 5, 5, 4, 7, 5, 5, 4, 5, 4, 4, 3,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 3,
+ 7, 7, 7, 6, 7, 6, 6, 4, 7, 6, 6, 4, 6, 4, 4, 3,
+ 7, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 3,
+ 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3,
+ 7, 7, 7, 7, 7, 7, 7, 4, 7, 7, 7, 4, 7, 4, 4, 3,
+ 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 5, 7, 5, 5, 3,
+ 7, 7, 7, 5, 7, 5, 5, 4, 7, 5, 5, 4, 5, 4, 4, 3,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 3,
+ 7, 7, 7, 6, 7, 6, 6, 4, 7, 6, 6, 4, 6, 4, 4, 3,
+ 7, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 3,
+ 7, 6, 6, 5, 6, 5, 5, 4, 6, 5, 5, 4, 5, 4, 4, 3
+ },
+ {
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5,
+ 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 5, 7, 5, 5, 4,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 4,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 5,
+ 7, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5,
+ 7, 7, 7, 7, 7, 7, 7, 5, 7, 7, 7, 5, 7, 5, 5, 4,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 4,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 5,
+ 7, 7, 7, 6, 7, 6, 6, 5, 7, 6, 6, 5, 6, 5, 5, 4
+ },
+ {
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 6, 7, 6, 6, 5
+ },
+ {
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6
+ },
+ {
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
+ }
+};
+
+ #if MARISA_WORD_SIZE == 64
+const UInt64 MASK_01 = 0x0101010101010101ULL;
+ #if !defined(MARISA_X64) || !defined(MARISA_USE_SSSE3)
+const UInt64 MASK_0F = 0x0F0F0F0F0F0F0F0FULL;
+const UInt64 MASK_33 = 0x3333333333333333ULL;
+const UInt64 MASK_55 = 0x5555555555555555ULL;
+ #endif // !defined(MARISA_X64) || !defined(MARISA_USE_SSSE3)
+ #if !defined(MARISA_X64) || !defined(MARISA_USE_POPCNT)
+const UInt64 MASK_80 = 0x8080808080808080ULL;
+ #endif // !defined(MARISA_X64) || !defined(MARISA_USE_POPCNT)
+
+std::size_t select_bit(std::size_t i, std::size_t bit_id, UInt64 unit) {
+ UInt64 counts;
+ {
+ #if defined(MARISA_X64) && defined(MARISA_USE_SSSE3)
+ __m128i lower_nibbles = _mm_cvtsi64_si128(
+ static_cast<long long>(unit & 0x0F0F0F0F0F0F0F0FULL));
+ __m128i upper_nibbles = _mm_cvtsi64_si128(
+ static_cast<long long>(unit & 0xF0F0F0F0F0F0F0F0ULL));
+ upper_nibbles = _mm_srli_epi32(upper_nibbles, 4);
+
+ __m128i lower_counts =
+ _mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0);
+ lower_counts = _mm_shuffle_epi8(lower_counts, lower_nibbles);
+ __m128i upper_counts =
+ _mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0);
+ upper_counts = _mm_shuffle_epi8(upper_counts, upper_nibbles);
+
+ counts = static_cast<UInt64>(_mm_cvtsi128_si64(
+ _mm_add_epi8(lower_counts, upper_counts)));
+ #else // defined(MARISA_X64) && defined(MARISA_USE_SSSE3)
+ counts = unit - ((unit >> 1) & MASK_55);
+ counts = (counts & MASK_33) + ((counts >> 2) & MASK_33);
+ counts = (counts + (counts >> 4)) & MASK_0F;
+ #endif // defined(MARISA_X64) && defined(MARISA_USE_SSSE3)
+ counts *= MASK_01;
+ }
+
+ #if defined(MARISA_X64) && defined(MARISA_USE_POPCNT)
+ UInt8 skip;
+ {
+ __m128i x = _mm_cvtsi64_si128(static_cast<long long>((i + 1) * MASK_01));
+ __m128i y = _mm_cvtsi64_si128(static_cast<long long>(counts));
+ x = _mm_cmpgt_epi8(x, y);
+ skip = (UInt8)PopCount::count(static_cast<UInt64>(_mm_cvtsi128_si64(x)));
+ }
+ #else // defined(MARISA_X64) && defined(MARISA_USE_POPCNT)
+ const UInt64 x = (counts | MASK_80) - ((i + 1) * MASK_01);
+ #ifdef _MSC_VER
+ unsigned long skip;
+ ::_BitScanForward64(&skip, (x & MASK_80) >> 7);
+ #else // _MSC_VER
+ const int skip = ::__builtin_ctzll((x & MASK_80) >> 7);
+ #endif // _MSC_VER
+ #endif // defined(MARISA_X64) && defined(MARISA_USE_POPCNT)
+
+ bit_id += static_cast<std::size_t>(skip);
+ unit >>= skip;
+ i -= ((counts << 8) >> skip) & 0xFF;
+
+ return bit_id + SELECT_TABLE[i][unit & 0xFF];
+}
+ #else // MARISA_WORD_SIZE == 64
+ #ifdef MARISA_USE_SSE2
+const UInt8 POPCNT_TABLE[256] = {
+ 0, 8, 8, 16, 8, 16, 16, 24, 8, 16, 16, 24, 16, 24, 24, 32,
+ 8, 16, 16, 24, 16, 24, 24, 32, 16, 24, 24, 32, 24, 32, 32, 40,
+ 8, 16, 16, 24, 16, 24, 24, 32, 16, 24, 24, 32, 24, 32, 32, 40,
+ 16, 24, 24, 32, 24, 32, 32, 40, 24, 32, 32, 40, 32, 40, 40, 48,
+ 8, 16, 16, 24, 16, 24, 24, 32, 16, 24, 24, 32, 24, 32, 32, 40,
+ 16, 24, 24, 32, 24, 32, 32, 40, 24, 32, 32, 40, 32, 40, 40, 48,
+ 16, 24, 24, 32, 24, 32, 32, 40, 24, 32, 32, 40, 32, 40, 40, 48,
+ 24, 32, 32, 40, 32, 40, 40, 48, 32, 40, 40, 48, 40, 48, 48, 56,
+ 8, 16, 16, 24, 16, 24, 24, 32, 16, 24, 24, 32, 24, 32, 32, 40,
+ 16, 24, 24, 32, 24, 32, 32, 40, 24, 32, 32, 40, 32, 40, 40, 48,
+ 16, 24, 24, 32, 24, 32, 32, 40, 24, 32, 32, 40, 32, 40, 40, 48,
+ 24, 32, 32, 40, 32, 40, 40, 48, 32, 40, 40, 48, 40, 48, 48, 56,
+ 16, 24, 24, 32, 24, 32, 32, 40, 24, 32, 32, 40, 32, 40, 40, 48,
+ 24, 32, 32, 40, 32, 40, 40, 48, 32, 40, 40, 48, 40, 48, 48, 56,
+ 24, 32, 32, 40, 32, 40, 40, 48, 32, 40, 40, 48, 40, 48, 48, 56,
+ 32, 40, 40, 48, 40, 48, 48, 56, 40, 48, 48, 56, 48, 56, 56, 64
+};
+
+std::size_t select_bit(std::size_t i, std::size_t bit_id,
+ UInt32 unit_lo, UInt32 unit_hi) {
+ __m128i unit;
+ {
+ __m128i lower_dword = _mm_cvtsi32_si128(unit_lo);
+ __m128i upper_dword = _mm_cvtsi32_si128(unit_hi);
+ upper_dword = _mm_slli_si128(upper_dword, 4);
+ unit = _mm_or_si128(lower_dword, upper_dword);
+ }
+
+ __m128i counts;
+ {
+ #ifdef MARISA_USE_SSSE3
+ __m128i lower_nibbles = _mm_set1_epi8(0x0F);
+ lower_nibbles = _mm_and_si128(lower_nibbles, unit);
+ __m128i upper_nibbles = _mm_set1_epi8((UInt8)0xF0);
+ upper_nibbles = _mm_and_si128(upper_nibbles, unit);
+ upper_nibbles = _mm_srli_epi32(upper_nibbles, 4);
+
+ __m128i lower_counts =
+ _mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0);
+ lower_counts = _mm_shuffle_epi8(lower_counts, lower_nibbles);
+ __m128i upper_counts =
+ _mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0);
+ upper_counts = _mm_shuffle_epi8(upper_counts, upper_nibbles);
+
+ counts = _mm_add_epi8(lower_counts, upper_counts);
+ #else // MARISA_USE_SSSE3
+ __m128i x = _mm_srli_epi32(unit, 1);
+ x = _mm_and_si128(x, _mm_set1_epi8(0x55));
+ x = _mm_sub_epi8(unit, x);
+
+ __m128i y = _mm_srli_epi32(x, 2);
+ y = _mm_and_si128(y, _mm_set1_epi8(0x33));
+ x = _mm_and_si128(x, _mm_set1_epi8(0x33));
+ x = _mm_add_epi8(x, y);
+
+ y = _mm_srli_epi32(x, 4);
+ x = _mm_add_epi8(x, y);
+ counts = _mm_and_si128(x, _mm_set1_epi8(0x0F));
+ #endif // MARISA_USE_SSSE3
+ }
+
+ __m128i accumulated_counts;
+ {
+ __m128i x = counts;
+ x = _mm_slli_si128(x, 1);
+ __m128i y = counts;
+ y = _mm_add_epi32(y, x);
+
+ x = y;
+ y = _mm_slli_si128(y, 2);
+ x = _mm_add_epi32(x, y);
+
+ y = x;
+ x = _mm_slli_si128(x, 4);
+ y = _mm_add_epi32(y, x);
+
+ accumulated_counts = _mm_set_epi32(0x7F7F7F7FU, 0x7F7F7F7FU, 0, 0);
+ accumulated_counts = _mm_or_si128(accumulated_counts, y);
+ }
+
+ UInt8 skip;
+ {
+ __m128i x = _mm_set1_epi8((UInt8)(i + 1));
+ x = _mm_cmpgt_epi8(x, accumulated_counts);
+ skip = POPCNT_TABLE[_mm_movemask_epi8(x)];
+ }
+
+ UInt8 byte;
+ {
+ #ifdef _MSC_VER
+ __declspec(align(16)) UInt8 unit_bytes[16];
+ __declspec(align(16)) UInt8 accumulated_counts_bytes[16];
+ #else // _MSC_VER
+ UInt8 unit_bytes[16] __attribute__ ((aligned (16)));
+ UInt8 accumulated_counts_bytes[16] __attribute__ ((aligned (16)));
+ #endif // _MSC_VER
+ accumulated_counts = _mm_slli_si128(accumulated_counts, 1);
+ _mm_store_si128(reinterpret_cast<__m128i *>(unit_bytes), unit);
+ _mm_store_si128(reinterpret_cast<__m128i *>(accumulated_counts_bytes),
+ accumulated_counts);
+
+ bit_id += skip;
+ byte = unit_bytes[skip / 8];
+ i -= accumulated_counts_bytes[skip / 8];
+ }
+
+ return bit_id + SELECT_TABLE[i][byte];
+}
+ #endif // MARISA_USE_SSE2
+ #endif // MARISA_WORD_SIZE == 64
+#endif // MARISA_USE_BMI2
+
+} // namespace
+
+#if MARISA_WORD_SIZE == 64
+
+std::size_t BitVector::rank1(std::size_t i) const {
+ MARISA_DEBUG_IF(ranks_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i > size_, MARISA_BOUND_ERROR);
+
+ const RankIndex &rank = ranks_[i / 512];
+ std::size_t offset = rank.abs();
+ switch ((i / 64) % 8) {
+ case 1: {
+ offset += rank.rel1();
+ break;
+ }
+ case 2: {
+ offset += rank.rel2();
+ break;
+ }
+ case 3: {
+ offset += rank.rel3();
+ break;
+ }
+ case 4: {
+ offset += rank.rel4();
+ break;
+ }
+ case 5: {
+ offset += rank.rel5();
+ break;
+ }
+ case 6: {
+ offset += rank.rel6();
+ break;
+ }
+ case 7: {
+ offset += rank.rel7();
+ break;
+ }
+ }
+ offset += PopCount::count(units_[i / 64] & ((1ULL << (i % 64)) - 1));
+ return offset;
+}
+
+std::size_t BitVector::select0(std::size_t i) const {
+ MARISA_DEBUG_IF(select0s_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i >= num_0s(), MARISA_BOUND_ERROR);
+
+ const std::size_t select_id = i / 512;
+ MARISA_DEBUG_IF((select_id + 1) >= select0s_.size(), MARISA_BOUND_ERROR);
+ if ((i % 512) == 0) {
+ return select0s_[select_id];
+ }
+ std::size_t begin = select0s_[select_id] / 512;
+ std::size_t end = (select0s_[select_id + 1] + 511) / 512;
+ if (begin + 10 >= end) {
+ while (i >= ((begin + 1) * 512) - ranks_[begin + 1].abs()) {
+ ++begin;
+ }
+ } else {
+ while (begin + 1 < end) {
+ const std::size_t middle = (begin + end) / 2;
+ if (i < (middle * 512) - ranks_[middle].abs()) {
+ end = middle;
+ } else {
+ begin = middle;
+ }
+ }
+ }
+ const std::size_t rank_id = begin;
+ i -= (rank_id * 512) - ranks_[rank_id].abs();
+
+ const RankIndex &rank = ranks_[rank_id];
+ std::size_t unit_id = rank_id * 8;
+ if (i < (256U - rank.rel4())) {
+ if (i < (128U - rank.rel2())) {
+ if (i >= (64U - rank.rel1())) {
+ unit_id += 1;
+ i -= 64 - rank.rel1();
+ }
+ } else if (i < (192U - rank.rel3())) {
+ unit_id += 2;
+ i -= 128 - rank.rel2();
+ } else {
+ unit_id += 3;
+ i -= 192 - rank.rel3();
+ }
+ } else if (i < (384U - rank.rel6())) {
+ if (i < (320U - rank.rel5())) {
+ unit_id += 4;
+ i -= 256 - rank.rel4();
+ } else {
+ unit_id += 5;
+ i -= 320 - rank.rel5();
+ }
+ } else if (i < (448U - rank.rel7())) {
+ unit_id += 6;
+ i -= 384 - rank.rel6();
+ } else {
+ unit_id += 7;
+ i -= 448 - rank.rel7();
+ }
+
+ return select_bit(i, unit_id * 64, ~units_[unit_id]);
+}
+
+std::size_t BitVector::select1(std::size_t i) const {
+ MARISA_DEBUG_IF(select1s_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i >= num_1s(), MARISA_BOUND_ERROR);
+
+ const std::size_t select_id = i / 512;
+ MARISA_DEBUG_IF((select_id + 1) >= select1s_.size(), MARISA_BOUND_ERROR);
+ if ((i % 512) == 0) {
+ return select1s_[select_id];
+ }
+ std::size_t begin = select1s_[select_id] / 512;
+ std::size_t end = (select1s_[select_id + 1] + 511) / 512;
+ if (begin + 10 >= end) {
+ while (i >= ranks_[begin + 1].abs()) {
+ ++begin;
+ }
+ } else {
+ while (begin + 1 < end) {
+ const std::size_t middle = (begin + end) / 2;
+ if (i < ranks_[middle].abs()) {
+ end = middle;
+ } else {
+ begin = middle;
+ }
+ }
+ }
+ const std::size_t rank_id = begin;
+ i -= ranks_[rank_id].abs();
+
+ const RankIndex &rank = ranks_[rank_id];
+ std::size_t unit_id = rank_id * 8;
+ if (i < rank.rel4()) {
+ if (i < rank.rel2()) {
+ if (i >= rank.rel1()) {
+ unit_id += 1;
+ i -= rank.rel1();
+ }
+ } else if (i < rank.rel3()) {
+ unit_id += 2;
+ i -= rank.rel2();
+ } else {
+ unit_id += 3;
+ i -= rank.rel3();
+ }
+ } else if (i < rank.rel6()) {
+ if (i < rank.rel5()) {
+ unit_id += 4;
+ i -= rank.rel4();
+ } else {
+ unit_id += 5;
+ i -= rank.rel5();
+ }
+ } else if (i < rank.rel7()) {
+ unit_id += 6;
+ i -= rank.rel6();
+ } else {
+ unit_id += 7;
+ i -= rank.rel7();
+ }
+
+ return select_bit(i, unit_id * 64, units_[unit_id]);
+}
+
+#else // MARISA_WORD_SIZE == 64
+
+std::size_t BitVector::rank1(std::size_t i) const {
+ MARISA_DEBUG_IF(ranks_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i > size_, MARISA_BOUND_ERROR);
+
+ const RankIndex &rank = ranks_[i / 512];
+ std::size_t offset = rank.abs();
+ switch ((i / 64) % 8) {
+ case 1: {
+ offset += rank.rel1();
+ break;
+ }
+ case 2: {
+ offset += rank.rel2();
+ break;
+ }
+ case 3: {
+ offset += rank.rel3();
+ break;
+ }
+ case 4: {
+ offset += rank.rel4();
+ break;
+ }
+ case 5: {
+ offset += rank.rel5();
+ break;
+ }
+ case 6: {
+ offset += rank.rel6();
+ break;
+ }
+ case 7: {
+ offset += rank.rel7();
+ break;
+ }
+ }
+ if (((i / 32) & 1) == 1) {
+ offset += PopCount::count(units_[(i / 32) - 1]);
+ }
+ offset += PopCount::count(units_[i / 32] & ((1U << (i % 32)) - 1));
+ return offset;
+}
+
+std::size_t BitVector::select0(std::size_t i) const {
+ MARISA_DEBUG_IF(select0s_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i >= num_0s(), MARISA_BOUND_ERROR);
+
+ const std::size_t select_id = i / 512;
+ MARISA_DEBUG_IF((select_id + 1) >= select0s_.size(), MARISA_BOUND_ERROR);
+ if ((i % 512) == 0) {
+ return select0s_[select_id];
+ }
+ std::size_t begin = select0s_[select_id] / 512;
+ std::size_t end = (select0s_[select_id + 1] + 511) / 512;
+ if (begin + 10 >= end) {
+ while (i >= ((begin + 1) * 512) - ranks_[begin + 1].abs()) {
+ ++begin;
+ }
+ } else {
+ while (begin + 1 < end) {
+ const std::size_t middle = (begin + end) / 2;
+ if (i < (middle * 512) - ranks_[middle].abs()) {
+ end = middle;
+ } else {
+ begin = middle;
+ }
+ }
+ }
+ const std::size_t rank_id = begin;
+ i -= (rank_id * 512) - ranks_[rank_id].abs();
+
+ const RankIndex &rank = ranks_[rank_id];
+ std::size_t unit_id = rank_id * 16;
+ if (i < (256U - rank.rel4())) {
+ if (i < (128U - rank.rel2())) {
+ if (i >= (64U - rank.rel1())) {
+ unit_id += 2;
+ i -= 64 - rank.rel1();
+ }
+ } else if (i < (192U - rank.rel3())) {
+ unit_id += 4;
+ i -= 128 - rank.rel2();
+ } else {
+ unit_id += 6;
+ i -= 192 - rank.rel3();
+ }
+ } else if (i < (384U - rank.rel6())) {
+ if (i < (320U - rank.rel5())) {
+ unit_id += 8;
+ i -= 256 - rank.rel4();
+ } else {
+ unit_id += 10;
+ i -= 320 - rank.rel5();
+ }
+ } else if (i < (448U - rank.rel7())) {
+ unit_id += 12;
+ i -= 384 - rank.rel6();
+ } else {
+ unit_id += 14;
+ i -= 448 - rank.rel7();
+ }
+
+#ifdef MARISA_USE_SSE2
+ return select_bit(i, unit_id * 32, ~units_[unit_id], ~units_[unit_id + 1]);
+#else // MARISA_USE_SSE2
+ UInt32 unit = ~units_[unit_id];
+ PopCount count(unit);
+ if (i >= count.lo32()) {
+ ++unit_id;
+ i -= count.lo32();
+ unit = ~units_[unit_id];
+ count = PopCount(unit);
+ }
+
+ std::size_t bit_id = unit_id * 32;
+ if (i < count.lo16()) {
+ if (i >= count.lo8()) {
+ bit_id += 8;
+ unit >>= 8;
+ i -= count.lo8();
+ }
+ } else if (i < count.lo24()) {
+ bit_id += 16;
+ unit >>= 16;
+ i -= count.lo16();
+ } else {
+ bit_id += 24;
+ unit >>= 24;
+ i -= count.lo24();
+ }
+ return bit_id + SELECT_TABLE[i][unit & 0xFF];
+#endif // MARISA_USE_SSE2
+}
+
+std::size_t BitVector::select1(std::size_t i) const {
+ MARISA_DEBUG_IF(select1s_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i >= num_1s(), MARISA_BOUND_ERROR);
+
+ const std::size_t select_id = i / 512;
+ MARISA_DEBUG_IF((select_id + 1) >= select1s_.size(), MARISA_BOUND_ERROR);
+ if ((i % 512) == 0) {
+ return select1s_[select_id];
+ }
+ std::size_t begin = select1s_[select_id] / 512;
+ std::size_t end = (select1s_[select_id + 1] + 511) / 512;
+ if (begin + 10 >= end) {
+ while (i >= ranks_[begin + 1].abs()) {
+ ++begin;
+ }
+ } else {
+ while (begin + 1 < end) {
+ const std::size_t middle = (begin + end) / 2;
+ if (i < ranks_[middle].abs()) {
+ end = middle;
+ } else {
+ begin = middle;
+ }
+ }
+ }
+ const std::size_t rank_id = begin;
+ i -= ranks_[rank_id].abs();
+
+ const RankIndex &rank = ranks_[rank_id];
+ std::size_t unit_id = rank_id * 16;
+ if (i < rank.rel4()) {
+ if (i < rank.rel2()) {
+ if (i >= rank.rel1()) {
+ unit_id += 2;
+ i -= rank.rel1();
+ }
+ } else if (i < rank.rel3()) {
+ unit_id += 4;
+ i -= rank.rel2();
+ } else {
+ unit_id += 6;
+ i -= rank.rel3();
+ }
+ } else if (i < rank.rel6()) {
+ if (i < rank.rel5()) {
+ unit_id += 8;
+ i -= rank.rel4();
+ } else {
+ unit_id += 10;
+ i -= rank.rel5();
+ }
+ } else if (i < rank.rel7()) {
+ unit_id += 12;
+ i -= rank.rel6();
+ } else {
+ unit_id += 14;
+ i -= rank.rel7();
+ }
+
+#ifdef MARISA_USE_SSE2
+ return select_bit(i, unit_id * 32, units_[unit_id], units_[unit_id + 1]);
+#else // MARISA_USE_SSE2
+ UInt32 unit = units_[unit_id];
+ PopCount count(unit);
+ if (i >= count.lo32()) {
+ ++unit_id;
+ i -= count.lo32();
+ unit = units_[unit_id];
+ count = PopCount(unit);
+ }
+
+ std::size_t bit_id = unit_id * 32;
+ if (i < count.lo16()) {
+ if (i >= count.lo8()) {
+ bit_id += 8;
+ unit >>= 8;
+ i -= count.lo8();
+ }
+ } else if (i < count.lo24()) {
+ bit_id += 16;
+ unit >>= 16;
+ i -= count.lo16();
+ } else {
+ bit_id += 24;
+ unit >>= 24;
+ i -= count.lo24();
+ }
+ return bit_id + SELECT_TABLE[i][unit & 0xFF];
+#endif // MARISA_USE_SSE2
+}
+
+#endif // MARISA_WORD_SIZE == 64
+
+void BitVector::build_index(const BitVector &bv,
+ bool enables_select0, bool enables_select1) {
+ ranks_.resize((bv.size() / 512) + (((bv.size() % 512) != 0) ? 1 : 0) + 1);
+
+ std::size_t num_0s = 0;
+ std::size_t num_1s = 0;
+
+ for (std::size_t i = 0; i < bv.size(); ++i) {
+ if ((i % 64) == 0) {
+ const std::size_t rank_id = i / 512;
+ switch ((i / 64) % 8) {
+ case 0: {
+ ranks_[rank_id].set_abs(num_1s);
+ break;
+ }
+ case 1: {
+ ranks_[rank_id].set_rel1(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ case 2: {
+ ranks_[rank_id].set_rel2(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ case 3: {
+ ranks_[rank_id].set_rel3(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ case 4: {
+ ranks_[rank_id].set_rel4(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ case 5: {
+ ranks_[rank_id].set_rel5(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ case 6: {
+ ranks_[rank_id].set_rel6(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ case 7: {
+ ranks_[rank_id].set_rel7(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ }
+ }
+
+ if (bv[i]) {
+ if (enables_select1 && ((num_1s % 512) == 0)) {
+ select1s_.push_back(static_cast<UInt32>(i));
+ }
+ ++num_1s;
+ } else {
+ if (enables_select0 && ((num_0s % 512) == 0)) {
+ select0s_.push_back(static_cast<UInt32>(i));
+ }
+ ++num_0s;
+ }
+ }
+
+ if ((bv.size() % 512) != 0) {
+ const std::size_t rank_id = (bv.size() - 1) / 512;
+ switch (((bv.size() - 1) / 64) % 8) {
+ case 0: {
+ ranks_[rank_id].set_rel1(num_1s - ranks_[rank_id].abs());
+ } // fall through
+ case 1: {
+ ranks_[rank_id].set_rel2(num_1s - ranks_[rank_id].abs());
+ } // fall through
+ case 2: {
+ ranks_[rank_id].set_rel3(num_1s - ranks_[rank_id].abs());
+ } // fall through
+ case 3: {
+ ranks_[rank_id].set_rel4(num_1s - ranks_[rank_id].abs());
+ } // fall through
+ case 4: {
+ ranks_[rank_id].set_rel5(num_1s - ranks_[rank_id].abs());
+ } // fall through
+ case 5: {
+ ranks_[rank_id].set_rel6(num_1s - ranks_[rank_id].abs());
+ } // fall through
+ case 6: {
+ ranks_[rank_id].set_rel7(num_1s - ranks_[rank_id].abs());
+ break;
+ }
+ }
+ }
+
+ size_ = bv.size();
+ num_1s_ = bv.num_1s();
+
+ ranks_.back().set_abs(num_1s);
+ if (enables_select0) {
+ select0s_.push_back(static_cast<UInt32>(bv.size()));
+ select0s_.shrink();
+ }
+ if (enables_select1) {
+ select1s_.push_back(static_cast<UInt32>(bv.size()));
+ select1s_.shrink();
+ }
+}
+
+} // namespace vector
+} // namespace grimoire
+} // namespace marisa
diff --git a/lib/marisa/grimoire/vector/bit-vector.h b/lib/marisa/grimoire/vector/bit-vector.h
new file mode 100644
index 0000000..ea698f1
--- /dev/null
+++ b/lib/marisa/grimoire/vector/bit-vector.h
@@ -0,0 +1,179 @@
+#ifndef MARISA_GRIMOIRE_VECTOR_BIT_VECTOR_H_
+#define MARISA_GRIMOIRE_VECTOR_BIT_VECTOR_H_
+
+#include "marisa/grimoire/vector/rank-index.h"
+#include "marisa/grimoire/vector/vector.h"
+
+namespace marisa {
+namespace grimoire {
+namespace vector {
+
+class BitVector {
+ public:
+#if MARISA_WORD_SIZE == 64
+ typedef UInt64 Unit;
+#else // MARISA_WORD_SIZE == 64
+ typedef UInt32 Unit;
+#endif // MARISA_WORD_SIZE == 64
+
+ BitVector()
+ : units_(), size_(0), num_1s_(0), ranks_(), select0s_(), select1s_() {}
+
+ void build(bool enables_select0, bool enables_select1) {
+ BitVector temp;
+ temp.build_index(*this, enables_select0, enables_select1);
+ units_.shrink();
+ temp.units_.swap(units_);
+ swap(temp);
+ }
+
+ void map(Mapper &mapper) {
+ BitVector temp;
+ temp.map_(mapper);
+ swap(temp);
+ }
+ void read(Reader &reader) {
+ BitVector temp;
+ temp.read_(reader);
+ swap(temp);
+ }
+ void write(Writer &writer) const {
+ write_(writer);
+ }
+
+ void disable_select0() {
+ select0s_.clear();
+ }
+ void disable_select1() {
+ select1s_.clear();
+ }
+
+ void push_back(bool bit) {
+ MARISA_THROW_IF(size_ == MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ if (size_ == (MARISA_WORD_SIZE * units_.size())) {
+ units_.resize(units_.size() + (64 / MARISA_WORD_SIZE), 0);
+ }
+ if (bit) {
+ units_[size_ / MARISA_WORD_SIZE] |=
+ (Unit)1 << (size_ % MARISA_WORD_SIZE);
+ ++num_1s_;
+ }
+ ++size_;
+ }
+
+ bool operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+ return (units_[i / MARISA_WORD_SIZE]
+ & ((Unit)1 << (i % MARISA_WORD_SIZE))) != 0;
+ }
+
+ std::size_t rank0(std::size_t i) const {
+ MARISA_DEBUG_IF(ranks_.empty(), MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i > size_, MARISA_BOUND_ERROR);
+ return i - rank1(i);
+ }
+ std::size_t rank1(std::size_t i) const;
+
+ std::size_t select0(std::size_t i) const;
+ std::size_t select1(std::size_t i) const;
+
+ std::size_t num_0s() const {
+ return size_ - num_1s_;
+ }
+ std::size_t num_1s() const {
+ return num_1s_;
+ }
+
+ bool empty() const {
+ return size_ == 0;
+ }
+ std::size_t size() const {
+ return size_;
+ }
+ std::size_t total_size() const {
+ return units_.total_size() + ranks_.total_size()
+ + select0s_.total_size() + select1s_.total_size();
+ }
+ std::size_t io_size() const {
+ return units_.io_size() + (sizeof(UInt32) * 2) + ranks_.io_size()
+ + select0s_.io_size() + select1s_.io_size();
+ }
+
+ void clear() {
+ BitVector().swap(*this);
+ }
+ void swap(BitVector &rhs) {
+ units_.swap(rhs.units_);
+ marisa::swap(size_, rhs.size_);
+ marisa::swap(num_1s_, rhs.num_1s_);
+ ranks_.swap(rhs.ranks_);
+ select0s_.swap(rhs.select0s_);
+ select1s_.swap(rhs.select1s_);
+ }
+
+ private:
+ Vector<Unit> units_;
+ std::size_t size_;
+ std::size_t num_1s_;
+ Vector<RankIndex> ranks_;
+ Vector<UInt32> select0s_;
+ Vector<UInt32> select1s_;
+
+ void build_index(const BitVector &bv,
+ bool enables_select0, bool enables_select1);
+
+ void map_(Mapper &mapper) {
+ units_.map(mapper);
+ {
+ UInt32 temp_size;
+ mapper.map(&temp_size);
+ size_ = temp_size;
+ }
+ {
+ UInt32 temp_num_1s;
+ mapper.map(&temp_num_1s);
+ MARISA_THROW_IF(temp_num_1s > size_, MARISA_FORMAT_ERROR);
+ num_1s_ = temp_num_1s;
+ }
+ ranks_.map(mapper);
+ select0s_.map(mapper);
+ select1s_.map(mapper);
+ }
+
+ void read_(Reader &reader) {
+ units_.read(reader);
+ {
+ UInt32 temp_size;
+ reader.read(&temp_size);
+ size_ = temp_size;
+ }
+ {
+ UInt32 temp_num_1s;
+ reader.read(&temp_num_1s);
+ MARISA_THROW_IF(temp_num_1s > size_, MARISA_FORMAT_ERROR);
+ num_1s_ = temp_num_1s;
+ }
+ ranks_.read(reader);
+ select0s_.read(reader);
+ select1s_.read(reader);
+ }
+
+ void write_(Writer &writer) const {
+ units_.write(writer);
+ writer.write((UInt32)size_);
+ writer.write((UInt32)num_1s_);
+ ranks_.write(writer);
+ select0s_.write(writer);
+ select1s_.write(writer);
+ }
+
+ // Disallows copy and assignment.
+ BitVector(const BitVector &);
+ BitVector &operator=(const BitVector &);
+};
+
+} // namespace vector
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_VECTOR_BIT_VECTOR_H_
diff --git a/lib/marisa/grimoire/vector/flat-vector.h b/lib/marisa/grimoire/vector/flat-vector.h
new file mode 100644
index 0000000..eeae719
--- /dev/null
+++ b/lib/marisa/grimoire/vector/flat-vector.h
@@ -0,0 +1,205 @@
+#ifndef MARISA_GRIMOIRE_VECTOR_FLAT_VECTOR_H_
+#define MARISA_GRIMOIRE_VECTOR_FLAT_VECTOR_H_
+
+#include "marisa/grimoire/vector/vector.h"
+
+namespace marisa {
+namespace grimoire {
+namespace vector {
+
+class FlatVector {
+ public:
+#if MARISA_WORD_SIZE == 64
+ typedef UInt64 Unit;
+#else // MARISA_WORD_SIZE == 64
+ typedef UInt32 Unit;
+#endif // MARISA_WORD_SIZE == 64
+
+ FlatVector() : units_(), value_size_(0), mask_(0), size_(0) {}
+
+ void build(const Vector<UInt32> &values) {
+ FlatVector temp;
+ temp.build_(values);
+ swap(temp);
+ }
+
+ void map(Mapper &mapper) {
+ FlatVector temp;
+ temp.map_(mapper);
+ swap(temp);
+ }
+ void read(Reader &reader) {
+ FlatVector temp;
+ temp.read_(reader);
+ swap(temp);
+ }
+ void write(Writer &writer) const {
+ write_(writer);
+ }
+
+ UInt32 operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+
+ const std::size_t pos = i * value_size_;
+ const std::size_t unit_id = pos / MARISA_WORD_SIZE;
+ const std::size_t unit_offset = pos % MARISA_WORD_SIZE;
+
+ if ((unit_offset + value_size_) <= MARISA_WORD_SIZE) {
+ return (UInt32)(units_[unit_id] >> unit_offset) & mask_;
+ } else {
+ return (UInt32)((units_[unit_id] >> unit_offset)
+ | (units_[unit_id + 1] << (MARISA_WORD_SIZE - unit_offset))) & mask_;
+ }
+ }
+
+ std::size_t value_size() const {
+ return value_size_;
+ }
+ UInt32 mask() const {
+ return mask_;
+ }
+
+ bool empty() const {
+ return size_ == 0;
+ }
+ std::size_t size() const {
+ return size_;
+ }
+ std::size_t total_size() const {
+ return units_.total_size();
+ }
+ std::size_t io_size() const {
+ return units_.io_size() + (sizeof(UInt32) * 2) + sizeof(UInt64);
+ }
+
+ void clear() {
+ FlatVector().swap(*this);
+ }
+ void swap(FlatVector &rhs) {
+ units_.swap(rhs.units_);
+ marisa::swap(value_size_, rhs.value_size_);
+ marisa::swap(mask_, rhs.mask_);
+ marisa::swap(size_, rhs.size_);
+ }
+
+ private:
+ Vector<Unit> units_;
+ std::size_t value_size_;
+ UInt32 mask_;
+ std::size_t size_;
+
+ void build_(const Vector<UInt32> &values) {
+ UInt32 max_value = 0;
+ for (std::size_t i = 0; i < values.size(); ++i) {
+ if (values[i] > max_value) {
+ max_value = values[i];
+ }
+ }
+
+ std::size_t value_size = 0;
+ while (max_value != 0) {
+ ++value_size;
+ max_value >>= 1;
+ }
+
+ std::size_t num_units = values.empty() ? 0 : (64 / MARISA_WORD_SIZE);
+ if (value_size != 0) {
+ num_units = (std::size_t)(
+ (((UInt64)value_size * values.size()) + (MARISA_WORD_SIZE - 1))
+ / MARISA_WORD_SIZE);
+ num_units += num_units % (64 / MARISA_WORD_SIZE);
+ }
+
+ units_.resize(num_units);
+ if (num_units > 0) {
+ units_.back() = 0;
+ }
+
+ value_size_ = value_size;
+ if (value_size != 0) {
+ mask_ = MARISA_UINT32_MAX >> (32 - value_size);
+ }
+ size_ = values.size();
+
+ for (std::size_t i = 0; i < values.size(); ++i) {
+ set(i, values[i]);
+ }
+ }
+
+ void map_(Mapper &mapper) {
+ units_.map(mapper);
+ {
+ UInt32 temp_value_size;
+ mapper.map(&temp_value_size);
+ MARISA_THROW_IF(temp_value_size > 32, MARISA_FORMAT_ERROR);
+ value_size_ = temp_value_size;
+ }
+ {
+ UInt32 temp_mask;
+ mapper.map(&temp_mask);
+ mask_ = temp_mask;
+ }
+ {
+ UInt64 temp_size;
+ mapper.map(&temp_size);
+ MARISA_THROW_IF(temp_size > MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ size_ = (std::size_t)temp_size;
+ }
+ }
+
+ void read_(Reader &reader) {
+ units_.read(reader);
+ {
+ UInt32 temp_value_size;
+ reader.read(&temp_value_size);
+ MARISA_THROW_IF(temp_value_size > 32, MARISA_FORMAT_ERROR);
+ value_size_ = temp_value_size;
+ }
+ {
+ UInt32 temp_mask;
+ reader.read(&temp_mask);
+ mask_ = temp_mask;
+ }
+ {
+ UInt64 temp_size;
+ reader.read(&temp_size);
+ MARISA_THROW_IF(temp_size > MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ size_ = (std::size_t)temp_size;
+ }
+ }
+
+ void write_(Writer &writer) const {
+ units_.write(writer);
+ writer.write((UInt32)value_size_);
+ writer.write((UInt32)mask_);
+ writer.write((UInt64)size_);
+ }
+
+ void set(std::size_t i, UInt32 value) {
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+ MARISA_DEBUG_IF(value > mask_, MARISA_RANGE_ERROR);
+
+ const std::size_t pos = i * value_size_;
+ const std::size_t unit_id = pos / MARISA_WORD_SIZE;
+ const std::size_t unit_offset = pos % MARISA_WORD_SIZE;
+
+ units_[unit_id] &= ~((Unit)mask_ << unit_offset);
+ units_[unit_id] |= (Unit)(value & mask_) << unit_offset;
+ if ((unit_offset + value_size_) > MARISA_WORD_SIZE) {
+ units_[unit_id + 1] &=
+ ~((Unit)mask_ >> (MARISA_WORD_SIZE - unit_offset));
+ units_[unit_id + 1] |=
+ (Unit)(value & mask_) >> (MARISA_WORD_SIZE - unit_offset);
+ }
+ }
+
+ // Disallows copy and assignment.
+ FlatVector(const FlatVector &);
+ FlatVector &operator=(const FlatVector &);
+};
+
+} // namespace vector
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_VECTOR_FLAT_VECTOR_H_
diff --git a/lib/marisa/grimoire/vector/pop-count.h b/lib/marisa/grimoire/vector/pop-count.h
new file mode 100644
index 0000000..47f4b5d
--- /dev/null
+++ b/lib/marisa/grimoire/vector/pop-count.h
@@ -0,0 +1,110 @@
+#ifndef MARISA_GRIMOIRE_VECTOR_POP_COUNT_H_
+#define MARISA_GRIMOIRE_VECTOR_POP_COUNT_H_
+
+#include "marisa/grimoire/intrin.h"
+
+namespace marisa {
+namespace grimoire {
+namespace vector {
+
+#if MARISA_WORD_SIZE == 64
+
+class PopCount {
+ public:
+ explicit PopCount(UInt64 x) : value_() {
+ x = (x & 0x5555555555555555ULL) + ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1);
+ x = (x & 0x3333333333333333ULL) + ((x & 0xCCCCCCCCCCCCCCCCULL) >> 2);
+ x = (x & 0x0F0F0F0F0F0F0F0FULL) + ((x & 0xF0F0F0F0F0F0F0F0ULL) >> 4);
+ x *= 0x0101010101010101ULL;
+ value_ = x;
+ }
+
+ std::size_t lo8() const {
+ return (std::size_t)(value_ & 0xFFU);
+ }
+ std::size_t lo16() const {
+ return (std::size_t)((value_ >> 8) & 0xFFU);
+ }
+ std::size_t lo24() const {
+ return (std::size_t)((value_ >> 16) & 0xFFU);
+ }
+ std::size_t lo32() const {
+ return (std::size_t)((value_ >> 24) & 0xFFU);
+ }
+ std::size_t lo40() const {
+ return (std::size_t)((value_ >> 32) & 0xFFU);
+ }
+ std::size_t lo48() const {
+ return (std::size_t)((value_ >> 40) & 0xFFU);
+ }
+ std::size_t lo56() const {
+ return (std::size_t)((value_ >> 48) & 0xFFU);
+ }
+ std::size_t lo64() const {
+ return (std::size_t)((value_ >> 56) & 0xFFU);
+ }
+
+ static std::size_t count(UInt64 x) {
+#if defined(MARISA_X64) && defined(MARISA_USE_POPCNT)
+ #ifdef _MSC_VER
+ return __popcnt64(x);
+ #else // _MSC_VER
+ return static_cast<std::size_t>(_mm_popcnt_u64(x));
+ #endif // _MSC_VER
+#else // defined(MARISA_X64) && defined(MARISA_USE_POPCNT)
+ return PopCount(x).lo64();
+#endif // defined(MARISA_X64) && defined(MARISA_USE_POPCNT)
+ }
+
+ private:
+ UInt64 value_;
+};
+
+#else // MARISA_WORD_SIZE == 64
+
+class PopCount {
+ public:
+ explicit PopCount(UInt32 x) : value_() {
+ x = (x & 0x55555555U) + ((x & 0xAAAAAAAAU) >> 1);
+ x = (x & 0x33333333U) + ((x & 0xCCCCCCCCU) >> 2);
+ x = (x & 0x0F0F0F0FU) + ((x & 0xF0F0F0F0U) >> 4);
+ x *= 0x01010101U;
+ value_ = x;
+ }
+
+ std::size_t lo8() const {
+ return value_ & 0xFFU;
+ }
+ std::size_t lo16() const {
+ return (value_ >> 8) & 0xFFU;
+ }
+ std::size_t lo24() const {
+ return (value_ >> 16) & 0xFFU;
+ }
+ std::size_t lo32() const {
+ return (value_ >> 24) & 0xFFU;
+ }
+
+ static std::size_t count(UInt32 x) {
+#ifdef MARISA_USE_POPCNT
+ #ifdef _MSC_VER
+ return __popcnt(x);
+ #else // _MSC_VER
+ return _mm_popcnt_u32(x);
+ #endif // _MSC_VER
+#else // MARISA_USE_POPCNT
+ return PopCount(x).lo32();
+#endif // MARISA_USE_POPCNT
+ }
+
+ private:
+ UInt32 value_;
+};
+
+#endif // MARISA_WORD_SIZE == 64
+
+} // namespace vector
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_VECTOR_POP_COUNT_H_
diff --git a/lib/marisa/grimoire/vector/rank-index.h b/lib/marisa/grimoire/vector/rank-index.h
new file mode 100644
index 0000000..c1ce476
--- /dev/null
+++ b/lib/marisa/grimoire/vector/rank-index.h
@@ -0,0 +1,82 @@
+#ifndef MARISA_GRIMOIRE_VECTOR_RANK_INDEX_H_
+#define MARISA_GRIMOIRE_VECTOR_RANK_INDEX_H_
+
+#include "marisa/base.h"
+
+namespace marisa {
+namespace grimoire {
+namespace vector {
+
+class RankIndex {
+ public:
+ RankIndex() : abs_(0), rel_lo_(0), rel_hi_(0) {}
+
+ void set_abs(std::size_t value) {
+ MARISA_DEBUG_IF(value > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+ abs_ = (UInt32)value;
+ }
+ void set_rel1(std::size_t value) {
+ MARISA_DEBUG_IF(value > 64, MARISA_RANGE_ERROR);
+ rel_lo_ = (UInt32)((rel_lo_ & ~0x7FU) | (value & 0x7FU));
+ }
+ void set_rel2(std::size_t value) {
+ MARISA_DEBUG_IF(value > 128, MARISA_RANGE_ERROR);
+ rel_lo_ = (UInt32)((rel_lo_ & ~(0xFFU << 7)) | ((value & 0xFFU) << 7));
+ }
+ void set_rel3(std::size_t value) {
+ MARISA_DEBUG_IF(value > 192, MARISA_RANGE_ERROR);
+ rel_lo_ = (UInt32)((rel_lo_ & ~(0xFFU << 15)) | ((value & 0xFFU) << 15));
+ }
+ void set_rel4(std::size_t value) {
+ MARISA_DEBUG_IF(value > 256, MARISA_RANGE_ERROR);
+ rel_lo_ = (UInt32)((rel_lo_ & ~(0x1FFU << 23)) | ((value & 0x1FFU) << 23));
+ }
+ void set_rel5(std::size_t value) {
+ MARISA_DEBUG_IF(value > 320, MARISA_RANGE_ERROR);
+ rel_hi_ = (UInt32)((rel_hi_ & ~0x1FFU) | (value & 0x1FFU));
+ }
+ void set_rel6(std::size_t value) {
+ MARISA_DEBUG_IF(value > 384, MARISA_RANGE_ERROR);
+ rel_hi_ = (UInt32)((rel_hi_ & ~(0x1FFU << 9)) | ((value & 0x1FFU) << 9));
+ }
+ void set_rel7(std::size_t value) {
+ MARISA_DEBUG_IF(value > 448, MARISA_RANGE_ERROR);
+ rel_hi_ = (UInt32)((rel_hi_ & ~(0x1FFU << 18)) | ((value & 0x1FFU) << 18));
+ }
+
+ std::size_t abs() const {
+ return abs_;
+ }
+ std::size_t rel1() const {
+ return rel_lo_ & 0x7FU;
+ }
+ std::size_t rel2() const {
+ return (rel_lo_ >> 7) & 0xFFU;
+ }
+ std::size_t rel3() const {
+ return (rel_lo_ >> 15) & 0xFFU;
+ }
+ std::size_t rel4() const {
+ return (rel_lo_ >> 23) & 0x1FFU;
+ }
+ std::size_t rel5() const {
+ return rel_hi_ & 0x1FFU;
+ }
+ std::size_t rel6() const {
+ return (rel_hi_ >> 9) & 0x1FFU;
+ }
+ std::size_t rel7() const {
+ return (rel_hi_ >> 18) & 0x1FFU;
+ }
+
+ private:
+ UInt32 abs_;
+ UInt32 rel_lo_;
+ UInt32 rel_hi_;
+};
+
+} // namespace vector
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_VECTOR_RANK_INDEX_H_
diff --git a/lib/marisa/grimoire/vector/vector.h b/lib/marisa/grimoire/vector/vector.h
new file mode 100644
index 0000000..2bfccdb
--- /dev/null
+++ b/lib/marisa/grimoire/vector/vector.h
@@ -0,0 +1,256 @@
+#ifndef MARISA_GRIMOIRE_VECTOR_VECTOR_H_
+#define MARISA_GRIMOIRE_VECTOR_VECTOR_H_
+
+#include <new>
+
+#include "marisa/grimoire/io.h"
+
+namespace marisa {
+namespace grimoire {
+namespace vector {
+
+template <typename T>
+class Vector {
+ public:
+ Vector()
+ : buf_(), objs_(NULL), const_objs_(NULL),
+ size_(0), capacity_(0), fixed_(false) {}
+ ~Vector() {
+ if (objs_ != NULL) {
+ for (std::size_t i = 0; i < size_; ++i) {
+ objs_[i].~T();
+ }
+ }
+ }
+
+ void map(Mapper &mapper) {
+ Vector temp;
+ temp.map_(mapper);
+ swap(temp);
+ }
+
+ void read(Reader &reader) {
+ Vector temp;
+ temp.read_(reader);
+ swap(temp);
+ }
+
+ void write(Writer &writer) const {
+ write_(writer);
+ }
+
+ void push_back(const T &x) {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(size_ == max_size(), MARISA_SIZE_ERROR);
+ reserve(size_ + 1);
+ new (&objs_[size_]) T(x);
+ ++size_;
+ }
+
+ void pop_back() {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(size_ == 0, MARISA_STATE_ERROR);
+ objs_[--size_].~T();
+ }
+
+ // resize() assumes that T's placement new does not throw an exception.
+ void resize(std::size_t size) {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ reserve(size);
+ for (std::size_t i = size_; i < size; ++i) {
+ new (&objs_[i]) T;
+ }
+ for (std::size_t i = size; i < size_; ++i) {
+ objs_[i].~T();
+ }
+ size_ = size;
+ }
+
+ // resize() assumes that T's placement new does not throw an exception.
+ void resize(std::size_t size, const T &x) {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ reserve(size);
+ for (std::size_t i = size_; i < size; ++i) {
+ new (&objs_[i]) T(x);
+ }
+ for (std::size_t i = size; i < size_; ++i) {
+ objs_[i].~T();
+ }
+ size_ = size;
+ }
+
+ void reserve(std::size_t capacity) {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ if (capacity <= capacity_) {
+ return;
+ }
+ MARISA_DEBUG_IF(capacity > max_size(), MARISA_SIZE_ERROR);
+ std::size_t new_capacity = capacity;
+ if (capacity_ > (capacity / 2)) {
+ if (capacity_ > (max_size() / 2)) {
+ new_capacity = max_size();
+ } else {
+ new_capacity = capacity_ * 2;
+ }
+ }
+ realloc(new_capacity);
+ }
+
+ void shrink() {
+ MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR);
+ if (size_ != capacity_) {
+ realloc(size_);
+ }
+ }
+
+ void fix() {
+ MARISA_THROW_IF(fixed_, MARISA_STATE_ERROR);
+ fixed_ = true;
+ }
+
+ const T *begin() const {
+ return const_objs_;
+ }
+ const T *end() const {
+ return const_objs_ + size_;
+ }
+ const T &operator[](std::size_t i) const {
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+ return const_objs_[i];
+ }
+ const T &front() const {
+ MARISA_DEBUG_IF(size_ == 0, MARISA_STATE_ERROR);
+ return const_objs_[0];
+ }
+ const T &back() const {
+ MARISA_DEBUG_IF(size_ == 0, MARISA_STATE_ERROR);
+ return const_objs_[size_ - 1];
+ }
+
+ T *begin() {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ return objs_;
+ }
+ T *end() {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ return objs_ + size_;
+ }
+ T &operator[](std::size_t i) {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(i >= size_, MARISA_BOUND_ERROR);
+ return objs_[i];
+ }
+ T &front() {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(size_ == 0, MARISA_STATE_ERROR);
+ return objs_[0];
+ }
+ T &back() {
+ MARISA_DEBUG_IF(fixed_, MARISA_STATE_ERROR);
+ MARISA_DEBUG_IF(size_ == 0, MARISA_STATE_ERROR);
+ return objs_[size_ - 1];
+ }
+
+ std::size_t size() const {
+ return size_;
+ }
+ std::size_t capacity() const {
+ return capacity_;
+ }
+ bool fixed() const {
+ return fixed_;
+ }
+
+ bool empty() const {
+ return size_ == 0;
+ }
+ std::size_t total_size() const {
+ return sizeof(T) * size_;
+ }
+ std::size_t io_size() const {
+ return sizeof(UInt64) + ((total_size() + 7) & ~(std::size_t)0x07);
+ }
+
+ void clear() {
+ Vector().swap(*this);
+ }
+ void swap(Vector &rhs) {
+ buf_.swap(rhs.buf_);
+ marisa::swap(objs_, rhs.objs_);
+ marisa::swap(const_objs_, rhs.const_objs_);
+ marisa::swap(size_, rhs.size_);
+ marisa::swap(capacity_, rhs.capacity_);
+ marisa::swap(fixed_, rhs.fixed_);
+ }
+
+ static std::size_t max_size() {
+ return MARISA_SIZE_MAX / sizeof(T);
+ }
+
+ private:
+ scoped_array<char> buf_;
+ T *objs_;
+ const T *const_objs_;
+ std::size_t size_;
+ std::size_t capacity_;
+ bool fixed_;
+
+ void map_(Mapper &mapper) {
+ UInt64 total_size;
+ mapper.map(&total_size);
+ MARISA_THROW_IF(total_size > MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ MARISA_THROW_IF((total_size % sizeof(T)) != 0, MARISA_FORMAT_ERROR);
+ const std::size_t size = (std::size_t)(total_size / sizeof(T));
+ mapper.map(&const_objs_, size);
+ mapper.seek((std::size_t)((8 - (total_size % 8)) % 8));
+ size_ = size;
+ fix();
+ }
+ void read_(Reader &reader) {
+ UInt64 total_size;
+ reader.read(&total_size);
+ MARISA_THROW_IF(total_size > MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ MARISA_THROW_IF((total_size % sizeof(T)) != 0, MARISA_FORMAT_ERROR);
+ const std::size_t size = (std::size_t)(total_size / sizeof(T));
+ resize(size);
+ reader.read(objs_, size);
+ reader.seek((std::size_t)((8 - (total_size % 8)) % 8));
+ }
+ void write_(Writer &writer) const {
+ writer.write((UInt64)total_size());
+ writer.write(const_objs_, size_);
+ writer.seek((8 - (total_size() % 8)) % 8);
+ }
+
+ // realloc() assumes that T's placement new does not throw an exception.
+ void realloc(std::size_t new_capacity) {
+ MARISA_DEBUG_IF(new_capacity > max_size(), MARISA_SIZE_ERROR);
+
+ scoped_array<char> new_buf(
+ new (std::nothrow) char[sizeof(T) * new_capacity]);
+ MARISA_DEBUG_IF(new_buf.get() == NULL, MARISA_MEMORY_ERROR);
+ T *new_objs = reinterpret_cast<T *>(new_buf.get());
+
+ for (std::size_t i = 0; i < size_; ++i) {
+ new (&new_objs[i]) T(objs_[i]);
+ }
+ for (std::size_t i = 0; i < size_; ++i) {
+ objs_[i].~T();
+ }
+
+ buf_.swap(new_buf);
+ objs_ = new_objs;
+ const_objs_ = new_objs;
+ capacity_ = new_capacity;
+ }
+
+ // Disallows copy and assignment.
+ Vector(const Vector &);
+ Vector &operator=(const Vector &);
+};
+
+} // namespace vector
+} // namespace grimoire
+} // namespace marisa
+
+#endif // MARISA_GRIMOIRE_VECTOR_VECTOR_H_
diff --git a/lib/marisa/keyset.cc b/lib/marisa/keyset.cc
new file mode 100644
index 0000000..41354f7
--- /dev/null
+++ b/lib/marisa/keyset.cc
@@ -0,0 +1,181 @@
+#include <new>
+
+#include "marisa/keyset.h"
+
+namespace marisa {
+
+Keyset::Keyset()
+ : base_blocks_(), base_blocks_size_(0), base_blocks_capacity_(0),
+ extra_blocks_(), extra_blocks_size_(0), extra_blocks_capacity_(0),
+ key_blocks_(), key_blocks_size_(0), key_blocks_capacity_(0),
+ ptr_(NULL), avail_(0), size_(0), total_length_(0) {}
+
+void Keyset::push_back(const Key &key) {
+ MARISA_DEBUG_IF(size_ == MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+
+ char * const key_ptr = reserve(key.length());
+ for (std::size_t i = 0; i < key.length(); ++i) {
+ key_ptr[i] = key[i];
+ }
+
+ Key &new_key = key_blocks_[size_ / KEY_BLOCK_SIZE][size_ % KEY_BLOCK_SIZE];
+ new_key.set_str(key_ptr, key.length());
+ new_key.set_id(key.id());
+ ++size_;
+ total_length_ += new_key.length();
+}
+
+void Keyset::push_back(const Key &key, char end_marker) {
+ MARISA_DEBUG_IF(size_ == MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+
+ if ((size_ / KEY_BLOCK_SIZE) == key_blocks_size_) {
+ append_key_block();
+ }
+
+ char * const key_ptr = reserve(key.length() + 1);
+ for (std::size_t i = 0; i < key.length(); ++i) {
+ key_ptr[i] = key[i];
+ }
+ key_ptr[key.length()] = end_marker;
+
+ Key &new_key = key_blocks_[size_ / KEY_BLOCK_SIZE][size_ % KEY_BLOCK_SIZE];
+ new_key.set_str(key_ptr, key.length());
+ new_key.set_id(key.id());
+ ++size_;
+ total_length_ += new_key.length();
+}
+
+void Keyset::push_back(const char *str) {
+ MARISA_DEBUG_IF(size_ == MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ MARISA_THROW_IF(str == NULL, MARISA_NULL_ERROR);
+
+ std::size_t length = 0;
+ while (str[length] != '\0') {
+ ++length;
+ }
+ push_back(str, length);
+}
+
+void Keyset::push_back(const char *ptr, std::size_t length, float weight) {
+ MARISA_DEBUG_IF(size_ == MARISA_SIZE_MAX, MARISA_SIZE_ERROR);
+ MARISA_THROW_IF((ptr == NULL) && (length != 0), MARISA_NULL_ERROR);
+ MARISA_THROW_IF(length > MARISA_UINT32_MAX, MARISA_SIZE_ERROR);
+
+ char * const key_ptr = reserve(length);
+ for (std::size_t i = 0; i < length; ++i) {
+ key_ptr[i] = ptr[i];
+ }
+
+ Key &key = key_blocks_[size_ / KEY_BLOCK_SIZE][size_ % KEY_BLOCK_SIZE];
+ key.set_str(key_ptr, length);
+ key.set_weight(weight);
+ ++size_;
+ total_length_ += length;
+}
+
+void Keyset::reset() {
+ base_blocks_size_ = 0;
+ extra_blocks_size_ = 0;
+ ptr_ = NULL;
+ avail_ = 0;
+ size_ = 0;
+ total_length_ = 0;
+}
+
+void Keyset::clear() {
+ Keyset().swap(*this);
+}
+
+void Keyset::swap(Keyset &rhs) {
+ base_blocks_.swap(rhs.base_blocks_);
+ marisa::swap(base_blocks_size_, rhs.base_blocks_size_);
+ marisa::swap(base_blocks_capacity_, rhs.base_blocks_capacity_);
+ extra_blocks_.swap(rhs.extra_blocks_);
+ marisa::swap(extra_blocks_size_, rhs.extra_blocks_size_);
+ marisa::swap(extra_blocks_capacity_, rhs.extra_blocks_capacity_);
+ key_blocks_.swap(rhs.key_blocks_);
+ marisa::swap(key_blocks_size_, rhs.key_blocks_size_);
+ marisa::swap(key_blocks_capacity_, rhs.key_blocks_capacity_);
+ marisa::swap(ptr_, rhs.ptr_);
+ marisa::swap(avail_, rhs.avail_);
+ marisa::swap(size_, rhs.size_);
+ marisa::swap(total_length_, rhs.total_length_);
+}
+
+char *Keyset::reserve(std::size_t size) {
+ if ((size_ / KEY_BLOCK_SIZE) == key_blocks_size_) {
+ append_key_block();
+ }
+
+ if (size > EXTRA_BLOCK_SIZE) {
+ append_extra_block(size);
+ return extra_blocks_[extra_blocks_size_ - 1].get();
+ } else {
+ if (size > avail_) {
+ append_base_block();
+ }
+ ptr_ += size;
+ avail_ -= size;
+ return ptr_ - size;
+ }
+}
+
+void Keyset::append_base_block() {
+ if (base_blocks_size_ == base_blocks_capacity_) {
+ const std::size_t new_capacity =
+ (base_blocks_size_ != 0) ? (base_blocks_size_ * 2) : 1;
+ scoped_array<scoped_array<char> > new_blocks(
+ new (std::nothrow) scoped_array<char>[new_capacity]);
+ MARISA_THROW_IF(new_blocks.get() == NULL, MARISA_MEMORY_ERROR);
+ for (std::size_t i = 0; i < base_blocks_size_; ++i) {
+ base_blocks_[i].swap(new_blocks[i]);
+ }
+ base_blocks_.swap(new_blocks);
+ base_blocks_capacity_ = new_capacity;
+ }
+ if (base_blocks_[base_blocks_size_].get() == NULL) {
+ scoped_array<char> new_block(new (std::nothrow) char[BASE_BLOCK_SIZE]);
+ MARISA_THROW_IF(new_block.get() == NULL, MARISA_MEMORY_ERROR);
+ base_blocks_[base_blocks_size_].swap(new_block);
+ }
+ ptr_ = base_blocks_[base_blocks_size_++].get();
+ avail_ = BASE_BLOCK_SIZE;
+}
+
+void Keyset::append_extra_block(std::size_t size) {
+ if (extra_blocks_size_ == extra_blocks_capacity_) {
+ const std::size_t new_capacity =
+ (extra_blocks_size_ != 0) ? (extra_blocks_size_ * 2) : 1;
+ scoped_array<scoped_array<char> > new_blocks(
+ new (std::nothrow) scoped_array<char>[new_capacity]);
+ MARISA_THROW_IF(new_blocks.get() == NULL, MARISA_MEMORY_ERROR);
+ for (std::size_t i = 0; i < extra_blocks_size_; ++i) {
+ extra_blocks_[i].swap(new_blocks[i]);
+ }
+ extra_blocks_.swap(new_blocks);
+ extra_blocks_capacity_ = new_capacity;
+ }
+ scoped_array<char> new_block(new (std::nothrow) char[size]);
+ MARISA_THROW_IF(new_block.get() == NULL, MARISA_MEMORY_ERROR);
+ extra_blocks_[extra_blocks_size_++].swap(new_block);
+}
+
+void Keyset::append_key_block() {
+ if (key_blocks_size_ == key_blocks_capacity_) {
+ const std::size_t new_capacity =
+ (key_blocks_size_ != 0) ? (key_blocks_size_ * 2) : 1;
+ scoped_array<scoped_array<Key> > new_blocks(
+ new (std::nothrow) scoped_array<Key>[new_capacity]);
+ MARISA_THROW_IF(new_blocks.get() == NULL, MARISA_MEMORY_ERROR);
+ for (std::size_t i = 0; i < key_blocks_size_; ++i) {
+ key_blocks_[i].swap(new_blocks[i]);
+ }
+ key_blocks_.swap(new_blocks);
+ key_blocks_capacity_ = new_capacity;
+ }
+ scoped_array<Key> new_block(new (std::nothrow) Key[KEY_BLOCK_SIZE]);
+ MARISA_THROW_IF(new_block.get() == NULL, MARISA_MEMORY_ERROR);
+ key_blocks_[key_blocks_size_++].swap(new_block);
+}
+
+} // namespace marisa
diff --git a/lib/marisa/trie.cc b/lib/marisa/trie.cc
new file mode 100644
index 0000000..6805001
--- /dev/null
+++ b/lib/marisa/trie.cc
@@ -0,0 +1,249 @@
+#include "marisa/stdio.h"
+#include "marisa/iostream.h"
+#include "marisa/trie.h"
+#include "marisa/grimoire/trie.h"
+
+namespace marisa {
+
+Trie::Trie() : trie_() {}
+
+Trie::~Trie() {}
+
+void Trie::build(Keyset &keyset, int config_flags) {
+ scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ temp->build(keyset, config_flags);
+ trie_.swap(temp);
+}
+
+void Trie::mmap(const char *filename) {
+ MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
+
+ scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ grimoire::Mapper mapper;
+ mapper.open(filename);
+ temp->map(mapper);
+ trie_.swap(temp);
+}
+
+void Trie::map(const void *ptr, std::size_t size) {
+ MARISA_THROW_IF((ptr == NULL) && (size != 0), MARISA_NULL_ERROR);
+
+ scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ grimoire::Mapper mapper;
+ mapper.open(ptr, size);
+ temp->map(mapper);
+ trie_.swap(temp);
+}
+
+void Trie::load(const char *filename) {
+ MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
+
+ scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ grimoire::Reader reader;
+ reader.open(filename);
+ temp->read(reader);
+ trie_.swap(temp);
+}
+
+void Trie::read(int fd) {
+ MARISA_THROW_IF(fd == -1, MARISA_CODE_ERROR);
+
+ scoped_ptr<grimoire::LoudsTrie> temp(new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ grimoire::Reader reader;
+ reader.open(fd);
+ temp->read(reader);
+ trie_.swap(temp);
+}
+
+void Trie::save(const char *filename) const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ MARISA_THROW_IF(filename == NULL, MARISA_NULL_ERROR);
+
+ grimoire::Writer writer;
+ writer.open(filename);
+ trie_->write(writer);
+}
+
+void Trie::write(int fd) const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ MARISA_THROW_IF(fd == -1, MARISA_CODE_ERROR);
+
+ grimoire::Writer writer;
+ writer.open(fd);
+ trie_->write(writer);
+}
+
+bool Trie::lookup(Agent &agent) const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ if (!agent.has_state()) {
+ agent.init_state();
+ }
+ return trie_->lookup(agent);
+}
+
+void Trie::reverse_lookup(Agent &agent) const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ if (!agent.has_state()) {
+ agent.init_state();
+ }
+ trie_->reverse_lookup(agent);
+}
+
+bool Trie::common_prefix_search(Agent &agent) const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ if (!agent.has_state()) {
+ agent.init_state();
+ }
+ return trie_->common_prefix_search(agent);
+}
+
+bool Trie::predictive_search(Agent &agent) const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ if (!agent.has_state()) {
+ agent.init_state();
+ }
+ return trie_->predictive_search(agent);
+}
+
+std::size_t Trie::num_tries() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->num_tries();
+}
+
+std::size_t Trie::num_keys() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->num_keys();
+}
+
+std::size_t Trie::num_nodes() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->num_nodes();
+}
+
+TailMode Trie::tail_mode() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->tail_mode();
+}
+
+NodeOrder Trie::node_order() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->node_order();
+}
+
+bool Trie::empty() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->empty();
+}
+
+std::size_t Trie::size() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->size();
+}
+
+std::size_t Trie::total_size() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->total_size();
+}
+
+std::size_t Trie::io_size() const {
+ MARISA_THROW_IF(trie_.get() == NULL, MARISA_STATE_ERROR);
+ return trie_->io_size();
+}
+
+void Trie::clear() {
+ Trie().swap(*this);
+}
+
+void Trie::swap(Trie &rhs) {
+ trie_.swap(rhs.trie_);
+}
+
+} // namespace marisa
+
+#include <iostream>
+
+namespace marisa {
+
+class TrieIO {
+ public:
+ static void fread(std::FILE *file, Trie *trie) {
+ MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
+
+ scoped_ptr<grimoire::LoudsTrie> temp(
+ new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ grimoire::Reader reader;
+ reader.open(file);
+ temp->read(reader);
+ trie->trie_.swap(temp);
+ }
+ static void fwrite(std::FILE *file, const Trie &trie) {
+ MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
+ MARISA_THROW_IF(trie.trie_.get() == NULL, MARISA_STATE_ERROR);
+ grimoire::Writer writer;
+ writer.open(file);
+ trie.trie_->write(writer);
+ }
+
+ static std::istream &read(std::istream &stream, Trie *trie) {
+ MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
+
+ scoped_ptr<grimoire::LoudsTrie> temp(
+ new (std::nothrow) grimoire::LoudsTrie);
+ MARISA_THROW_IF(temp.get() == NULL, MARISA_MEMORY_ERROR);
+
+ grimoire::Reader reader;
+ reader.open(stream);
+ temp->read(reader);
+ trie->trie_.swap(temp);
+ return stream;
+ }
+ static std::ostream &write(std::ostream &stream, const Trie &trie) {
+ MARISA_THROW_IF(trie.trie_.get() == NULL, MARISA_STATE_ERROR);
+ grimoire::Writer writer;
+ writer.open(stream);
+ trie.trie_->write(writer);
+ return stream;
+ }
+};
+
+void fread(std::FILE *file, Trie *trie) {
+ MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
+ MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
+ TrieIO::fread(file, trie);
+}
+
+void fwrite(std::FILE *file, const Trie &trie) {
+ MARISA_THROW_IF(file == NULL, MARISA_NULL_ERROR);
+ TrieIO::fwrite(file, trie);
+}
+
+std::istream &read(std::istream &stream, Trie *trie) {
+ MARISA_THROW_IF(trie == NULL, MARISA_NULL_ERROR);
+ return TrieIO::read(stream, trie);
+}
+
+std::ostream &write(std::ostream &stream, const Trie &trie) {
+ return TrieIO::write(stream, trie);
+}
+
+std::istream &operator>>(std::istream &stream, Trie &trie) {
+ return read(stream, &trie);
+}
+
+std::ostream &operator<<(std::ostream &stream, const Trie &trie) {
+ return write(stream, trie);
+}
+
+} // namespace marisa
diff --git a/m4/.gitkeep b/m4/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/m4/.gitkeep
diff --git a/marisa.pc.in b/marisa.pc.in
new file mode 100644
index 0000000..444e73d
--- /dev/null
+++ b/marisa.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+bindir=@bindir@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Marisa
+Description: Matching Algorithm with Recursively Implemented StorAge
+Version: @VERSION@
+Cflags: -I${includedir}
+Libs: -L${libdir} -lmarisa
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..4d73823
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,30 @@
+MY_INCLUDE = -I$(top_srcdir)/include -I$(top_srcdir)/lib
+MY_LIBS = $(top_srcdir)/lib/marisa/libmarisa.la
+
+AM_CXXFLAGS = -Wall -Weffc++ -Wextra -Wconversion -D_DEBUG $(MY_INCLUDE)
+
+TESTS = \
+ base-test \
+ io-test \
+ vector-test \
+ trie-test \
+ marisa-test
+
+check_PROGRAMS = $(TESTS)
+
+noinst_HEADERS = marisa-assert.h
+
+base_test_SOURCES = base-test.cc
+base_test_LDADD = $(MY_LIBS)
+
+io_test_SOURCES = io-test.cc
+io_test_LDADD = $(MY_LIBS)
+
+vector_test_SOURCES = vector-test.cc
+vector_test_LDADD = $(MY_LIBS)
+
+trie_test_SOURCES = trie-test.cc
+trie_test_LDADD = $(MY_LIBS)
+
+marisa_test_SOURCES = marisa-test.cc
+marisa_test_LDADD = $(MY_LIBS)
diff --git a/tests/base-test.cc b/tests/base-test.cc
new file mode 100644
index 0000000..4b4629d
--- /dev/null
+++ b/tests/base-test.cc
@@ -0,0 +1,313 @@
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <string>
+#include <vector>
+
+#include <marisa.h>
+
+#include "marisa-assert.h"
+
+namespace {
+
+void TestTypes() {
+ TEST_START();
+
+ ASSERT(sizeof(marisa_uint8) == 1);
+ ASSERT(sizeof(marisa_uint16) == 2);
+ ASSERT(sizeof(marisa_uint32) == 4);
+ ASSERT(sizeof(marisa_uint64) == 8);
+
+ ASSERT(MARISA_WORD_SIZE == (sizeof(std::size_t) * 8));
+
+ ASSERT(MARISA_UINT8_MAX == 0xFFU);
+ ASSERT(MARISA_UINT16_MAX == 0xFFFFU);
+ ASSERT(MARISA_UINT32_MAX == 0xFFFFFFFFU);
+ ASSERT(MARISA_UINT64_MAX == 0xFFFFFFFFFFFFFFFFULL);
+
+ ASSERT(sizeof(marisa::UInt8) == 1);
+ ASSERT(sizeof(marisa::UInt16) == 2);
+ ASSERT(sizeof(marisa::UInt32) == 4);
+ ASSERT(sizeof(marisa::UInt64) == 8);
+
+ TEST_END();
+}
+
+void TestSwap() {
+ TEST_START();
+
+ int x = 100, y = 200;
+ marisa::swap(x, y);
+ ASSERT(x == 200);
+ ASSERT(y == 100);
+
+ double a = 1.23, b = 2.34;
+ marisa::swap(a, b);
+ ASSERT(a == 2.34);
+ ASSERT(b == 1.23);
+
+ TEST_END();
+}
+
+void TestException() {
+ TEST_START();
+
+ try {
+ MARISA_THROW(MARISA_OK, "Message");
+ } catch (const marisa::Exception &ex) {
+ ASSERT(std::strcmp(ex.filename(), __FILE__) == 0);
+ ASSERT(ex.line() == (__LINE__ - 3));
+ ASSERT(ex.error_code() == MARISA_OK);
+ ASSERT(std::strstr(ex.error_message(), "Message") != NULL);
+ }
+
+ EXCEPT(MARISA_THROW(MARISA_OK, "OK"), MARISA_OK);
+ EXCEPT(MARISA_THROW(MARISA_NULL_ERROR, "NULL"), MARISA_NULL_ERROR);
+
+ TEST_END();
+}
+
+void TestKey() {
+ TEST_START();
+
+ const char * const str = "apple";
+
+ marisa::Key key;
+
+ ASSERT(key.ptr() == NULL);
+ ASSERT(key.length() == 0);
+
+ key.set_str(str);
+
+ ASSERT(key.ptr() == str);
+ ASSERT(key.length() == std::strlen(str));
+
+ key.set_str(str, 4);
+
+ ASSERT(key.ptr() == str);
+ ASSERT(key.length() == 4);
+
+ key.set_weight(1.0);
+
+ ASSERT(key.weight() == 1.0);
+
+ key.set_id(100);
+
+ ASSERT(key.id() == 100);
+
+ TEST_END();
+}
+
+void TestKeyset() {
+ TEST_START();
+
+ marisa::Keyset keyset;
+
+ ASSERT(keyset.size() == 0);
+ ASSERT(keyset.empty());
+ ASSERT(keyset.total_length() == 0);
+
+ std::vector<std::string> keys;
+ keys.push_back("apple");
+ keys.push_back("orange");
+ keys.push_back("banana");
+
+ std::size_t total_length = 0;
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ keyset.push_back(keys[i].c_str());
+ ASSERT(keyset.size() == (i + 1));
+ ASSERT(!keyset.empty());
+
+ total_length += keys[i].length();
+ ASSERT(keyset.total_length() == total_length);
+
+ ASSERT(keyset[i].length() == keys[i].length());
+ ASSERT(std::memcmp(keyset[i].ptr(), keys[i].c_str(),
+ keyset[i].length()) == 0);
+ ASSERT(keyset[i].weight() == 1.0);
+ }
+
+ keyset.clear();
+
+ marisa::Key key;
+
+ key.set_str("123");
+ keyset.push_back(key);
+ ASSERT(keyset[0].length() == 3);
+ ASSERT(std::memcmp(keyset[0].ptr(), "123", 3) == 0);
+
+ key.set_str("456");
+ keyset.push_back(key, '\0');
+ ASSERT(keyset[1].length() == 3);
+ ASSERT(std::memcmp(keyset[1].ptr(), "456", 3) == 0);
+ ASSERT(std::strcmp(keyset[1].ptr(), "456") == 0);
+
+ key.set_str("789");
+ keyset.push_back(key, '0');
+ ASSERT(keyset[2].length() == 3);
+ ASSERT(std::memcmp(keyset[2].ptr(), "789", 3) == 0);
+ ASSERT(std::memcmp(keyset[2].ptr(), "7890", 4) == 0);
+
+ ASSERT(keyset.size() == 3);
+
+ keyset.clear();
+
+ ASSERT(keyset.size() == 0);
+ ASSERT(keyset.total_length() == 0);
+
+ keys.resize(1000);
+ std::vector<float> weights(keys.size());
+
+ total_length = 0;
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ keys[i].resize(std::rand() % (marisa::Keyset::EXTRA_BLOCK_SIZE * 2));
+ for (std::size_t j = 0; j < keys[i].length(); ++j) {
+ keys[i][j] = (char)(std::rand() & 0xFF);
+ }
+ double weight = 100.0 * static_cast<double>(std::rand()) /
+ static_cast<double>(RAND_MAX);
+ weights[i] = static_cast<float>(weight);
+
+ keyset.push_back(keys[i].c_str(), keys[i].length(), weights[i]);
+ total_length += keys[i].length();
+ ASSERT(keyset.total_length() == total_length);
+ }
+
+ ASSERT(keyset.size() == keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ ASSERT(keyset[i].length() == keys[i].length());
+ ASSERT(std::memcmp(keyset[i].ptr(), keys[i].c_str(),
+ keyset[i].length()) == 0);
+ ASSERT(keyset[i].weight() == weights[i]);
+ }
+
+ keyset.reset();
+
+ ASSERT(keyset.size() == 0);
+ ASSERT(keyset.total_length() == 0);
+
+ total_length = 0;
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ keys[i].resize(std::rand() % (marisa::Keyset::EXTRA_BLOCK_SIZE * 2));
+ for (std::size_t j = 0; j < keys[i].length(); ++j) {
+ keys[i][j] = (char)(std::rand() & 0xFF);
+ }
+ double weight = 100.0 * static_cast<double>(std::rand()) /
+ static_cast<double>(RAND_MAX);
+ weights[i] = static_cast<float>(weight);
+
+ keyset.push_back(keys[i].c_str(), keys[i].length(), weights[i]);
+ total_length += keys[i].length();
+ ASSERT(keyset.total_length() == total_length);
+ }
+
+ ASSERT(keyset.size() == keys.size());
+ for (std::size_t i = 0; i < keys.size(); ++i) {
+ ASSERT(keyset[i].length() == keys[i].length());
+ ASSERT(std::memcmp(keyset[i].ptr(), keys[i].c_str(),
+ keyset[i].length()) == 0);
+ ASSERT(keyset[i].weight() == weights[i]);
+ }
+
+ TEST_END();
+}
+
+void TestQuery() {
+ TEST_START();
+
+ marisa::Query query;
+
+ ASSERT(query.ptr() == NULL);
+ ASSERT(query.length() == 0);
+ ASSERT(query.id() == 0);
+
+ const char *str = "apple";
+ query.set_str(str);
+
+ ASSERT(query.ptr() == str);
+ ASSERT(query.length() == std::strlen(str));
+
+ query.set_str(str, 3);
+
+ ASSERT(query.ptr() == str);
+ ASSERT(query.length() == 3);
+
+ query.set_id(100);
+
+ ASSERT(query.id() == 100);
+
+ query.clear();
+
+ ASSERT(query.ptr() == NULL);
+ ASSERT(query.length() == 0);
+ ASSERT(query.id() == 0);
+
+ TEST_END();
+}
+
+void TestAgent() {
+ TEST_START();
+
+ marisa::Agent agent;
+
+ ASSERT(agent.query().ptr() == NULL);
+ ASSERT(agent.query().length() == 0);
+ ASSERT(agent.query().id() == 0);
+
+ ASSERT(agent.key().ptr() == NULL);
+ ASSERT(agent.key().length() == 0);
+
+ ASSERT(!agent.has_state());
+
+ const char *query_str = "query";
+ const char *key_str = "key";
+
+ agent.set_query(query_str);
+ agent.set_query(123);
+ agent.set_key(key_str);
+ agent.set_key(234);
+
+ ASSERT(agent.query().ptr() == query_str);
+ ASSERT(agent.query().length() == std::strlen(query_str));
+ ASSERT(agent.query().id() == 123);
+
+ ASSERT(agent.key().ptr() == key_str);
+ ASSERT(agent.key().length() == std::strlen(key_str));
+ ASSERT(agent.key().id() == 234);
+
+ agent.init_state();
+
+ ASSERT(agent.has_state());
+
+ EXCEPT(agent.init_state(), MARISA_STATE_ERROR);
+
+ agent.clear();
+
+ ASSERT(agent.query().ptr() == NULL);
+ ASSERT(agent.query().length() == 0);
+ ASSERT(agent.query().id() == 0);
+
+ ASSERT(agent.key().ptr() == NULL);
+ ASSERT(agent.key().length() == 0);
+
+ ASSERT(!agent.has_state());
+
+ TEST_END();
+}
+
+} // namespace
+
+int main() try {
+ TestTypes();
+ TestSwap();
+ TestException();
+ TestKey();
+ TestKeyset();
+ TestQuery();
+ TestAgent();
+
+ return 0;
+} catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << std::endl;
+ throw;
+}
diff --git a/tests/io-test.cc b/tests/io-test.cc
new file mode 100644
index 0000000..07b6e87
--- /dev/null
+++ b/tests/io-test.cc
@@ -0,0 +1,252 @@
+#ifdef _MSC_VER
+#include <io.h>
+#else
+#include <unistd.h>
+#endif // _MSC_VER
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sstream>
+
+#include <marisa/grimoire/io.h>
+
+#include "marisa-assert.h"
+
+namespace {
+
+void TestFilename() {
+ TEST_START();
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open("io-test.dat");
+
+ writer.write((marisa::UInt32)123);
+ writer.write((marisa::UInt32)234);
+
+ double values[] = { 3.45, 4.56 };
+ writer.write(values, 2);
+
+ EXCEPT(writer.write(values, MARISA_SIZE_MAX), MARISA_SIZE_ERROR);
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open("io-test.dat");
+
+ marisa::UInt32 value;
+ reader.read(&value);
+ ASSERT(value == 123);
+ reader.read(&value);
+ ASSERT(value == 234);
+
+ double values[2];
+ reader.read(values, 2);
+ ASSERT(values[0] == 3.45);
+ ASSERT(values[1] == 4.56);
+
+ char byte;
+ EXCEPT(reader.read(&byte), MARISA_IO_ERROR);
+ }
+
+ {
+ marisa::grimoire::Mapper mapper;
+ mapper.open("io-test.dat");
+
+ marisa::UInt32 value;
+ mapper.map(&value);
+ ASSERT(value == 123);
+ mapper.map(&value);
+ ASSERT(value == 234);
+
+ const double *values;
+ mapper.map(&values, 2);
+ ASSERT(values[0] == 3.45);
+ ASSERT(values[1] == 4.56);
+
+ char byte;
+ EXCEPT(mapper.map(&byte), MARISA_IO_ERROR);
+ }
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open("io-test.dat");
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open("io-test.dat");
+
+ char byte;
+ EXCEPT(reader.read(&byte), MARISA_IO_ERROR);
+ }
+
+ TEST_END();
+}
+
+void TestFd() {
+ TEST_START();
+
+ {
+#ifdef _MSC_VER
+ int fd = -1;
+ ASSERT(::_sopen_s(&fd, "io-test.dat",
+ _O_BINARY | _O_CREAT | _O_WRONLY | _O_TRUNC,
+ _SH_DENYRW, _S_IREAD | _S_IWRITE) == 0);
+#else // _MSC_VER
+ int fd = ::creat("io-test.dat", 0644);
+ ASSERT(fd != -1);
+#endif // _MSC_VER
+ marisa::grimoire::Writer writer;
+ writer.open(fd);
+
+ marisa::UInt32 value = 234;
+ writer.write(value);
+
+ double values[] = { 34.5, 67.8 };
+ writer.write(values, 2);
+
+#ifdef _MSC_VER
+ ASSERT(::_close(fd) == 0);
+#else // _MSC_VER
+ ASSERT(::close(fd) == 0);
+#endif // _MSC_VER
+ }
+
+ {
+#ifdef _MSC_VER
+ int fd = -1;
+ ASSERT(::_sopen_s(&fd, "io-test.dat", _O_BINARY | _O_RDONLY,
+ _SH_DENYRW, _S_IREAD) == 0);
+#else // _MSC_VER
+ int fd = ::open("io-test.dat", O_RDONLY);
+ ASSERT(fd != -1);
+#endif // _MSC_VER
+ marisa::grimoire::Reader reader;
+ reader.open(fd);
+
+ marisa::UInt32 value;
+ reader.read(&value);
+ ASSERT(value == 234);
+
+ double values[2];
+ reader.read(values, 2);
+ ASSERT(values[0] == 34.5);
+ ASSERT(values[1] == 67.8);
+
+ char byte;
+ EXCEPT(reader.read(&byte), MARISA_IO_ERROR);
+
+#ifdef _MSC_VER
+ ASSERT(::_close(fd) == 0);
+#else // _MSC_VER
+ ASSERT(::close(fd) == 0);
+#endif // _MSC_VER
+ }
+
+ TEST_END();
+}
+
+void TestFile() {
+ TEST_START();
+
+ {
+#ifdef _MSC_VER
+ FILE *file = NULL;
+ ASSERT(::fopen_s(&file, "io-test.dat", "wb") == 0);
+#else // _MSC_VER
+ FILE *file = std::fopen("io-test.dat", "wb");
+ ASSERT(file != NULL);
+#endif // _MSC_VER
+ marisa::grimoire::Writer writer;
+ writer.open(file);
+
+ marisa::UInt32 value = 10;
+ writer.write(value);
+
+ double values[2] = { 0.1, 0.2 };
+ writer.write(values, 2);
+
+ ASSERT(std::fclose(file) == 0);
+ }
+
+ {
+#ifdef _MSC_VER
+ FILE *file = NULL;
+ ASSERT(::fopen_s(&file, "io-test.dat", "rb") == 0);
+#else // _MSC_VER
+ FILE *file = std::fopen("io-test.dat", "rb");
+ ASSERT(file != NULL);
+#endif // _MSC_VER
+ marisa::grimoire::Reader reader;
+ reader.open(file);
+
+ marisa::UInt32 value;
+ reader.read(&value);
+ ASSERT(value == 10);
+
+ double values[2];
+ reader.read(values, 2);
+ ASSERT(values[0] == 0.1);
+ ASSERT(values[1] == 0.2);
+
+ char byte;
+ EXCEPT(reader.read(&byte), MARISA_IO_ERROR);
+
+ ASSERT(std::fclose(file) == 0);
+ }
+
+ TEST_END();
+}
+
+void TestStream() {
+ TEST_START();
+
+ std::stringstream stream;
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open(stream);
+
+ marisa::UInt32 value = 12;
+ writer.write(value);
+
+ double values[2] = { 3.4, 5.6 };
+ writer.write(values, 2);
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open(stream);
+
+ marisa::UInt32 value;
+ reader.read(&value);
+ ASSERT(value == 12);
+
+ double values[2];
+ reader.read(values, 2);
+ ASSERT(values[0] == 3.4);
+ ASSERT(values[1] == 5.6);
+
+ char byte;
+ EXCEPT(reader.read(&byte), MARISA_IO_ERROR);
+ }
+
+ TEST_END();
+}
+
+} // namespace
+
+int main() try {
+ TestFilename();
+ TestFd();
+ TestFile();
+ TestStream();
+
+ return 0;
+} catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << std::endl;
+ throw;
+}
diff --git a/tests/marisa-assert.h b/tests/marisa-assert.h
new file mode 100644
index 0000000..aa2403d
--- /dev/null
+++ b/tests/marisa-assert.h
@@ -0,0 +1,26 @@
+#ifndef MARISA_ASSERT_H_
+#define MARISA_ASSERT_H_
+
+#include <iostream>
+#include <cstdlib>
+
+#define ASSERT(cond) (void)((!!(cond)) || \
+ ((std::cout << __LINE__ << ": Assertion `" << #cond << "' failed." \
+ << std::endl), std::exit(-1), 0))
+
+#define EXCEPT(code, expected_error_code) try { \
+ code; \
+ std::cout << __LINE__ << ": Exception `" << #code << "' failed." \
+ << std::endl; \
+ std::exit(-1); \
+} catch (const marisa::Exception &ex) { \
+ ASSERT(ex.error_code() == expected_error_code); \
+}
+
+#define TEST_START() \
+ (std::cout << __FILE__ << ":" << __LINE__ << ": " << __FUNCTION__ << "(): ")
+
+#define TEST_END() \
+ (std::cout << "ok" << std::endl)
+
+#endif // MARISA_ASSERT_H_
diff --git a/tests/marisa-test.cc b/tests/marisa-test.cc
new file mode 100644
index 0000000..36e4258
--- /dev/null
+++ b/tests/marisa-test.cc
@@ -0,0 +1,389 @@
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <sstream>
+
+#include <marisa.h>
+
+#include "marisa-assert.h"
+
+namespace {
+
+void TestEmptyTrie() {
+ TEST_START();
+
+ marisa::Trie trie;
+
+ EXCEPT(trie.save("marisa-test.dat"), MARISA_STATE_ERROR);
+#ifdef _MSC_VER
+ EXCEPT(trie.write(::_fileno(stdout)), MARISA_STATE_ERROR);
+#else // _MSC_VER
+ EXCEPT(trie.write(::fileno(stdout)), MARISA_STATE_ERROR);
+#endif // _MSC_VER
+ EXCEPT(std::cout << trie, MARISA_STATE_ERROR);
+ EXCEPT(marisa::fwrite(stdout, trie), MARISA_STATE_ERROR);
+
+ marisa::Agent agent;
+
+ EXCEPT(trie.lookup(agent), MARISA_STATE_ERROR);
+ EXCEPT(trie.reverse_lookup(agent), MARISA_STATE_ERROR);
+ EXCEPT(trie.common_prefix_search(agent), MARISA_STATE_ERROR);
+ EXCEPT(trie.predictive_search(agent), MARISA_STATE_ERROR);
+
+ EXCEPT(trie.num_tries(), MARISA_STATE_ERROR);
+ EXCEPT(trie.num_keys(), MARISA_STATE_ERROR);
+ EXCEPT(trie.num_nodes(), MARISA_STATE_ERROR);
+
+ EXCEPT(trie.tail_mode(), MARISA_STATE_ERROR);
+ EXCEPT(trie.node_order(), MARISA_STATE_ERROR);
+
+ EXCEPT(trie.empty(), MARISA_STATE_ERROR);
+ EXCEPT(trie.size(), MARISA_STATE_ERROR);
+ EXCEPT(trie.total_size(), MARISA_STATE_ERROR);
+ EXCEPT(trie.io_size(), MARISA_STATE_ERROR);
+
+ marisa::Keyset keyset;
+ trie.build(keyset);
+
+ ASSERT(!trie.lookup(agent));
+ EXCEPT(trie.reverse_lookup(agent), MARISA_BOUND_ERROR);
+ ASSERT(!trie.common_prefix_search(agent));
+ ASSERT(!trie.predictive_search(agent));
+
+ ASSERT(trie.num_tries() == 1);
+ ASSERT(trie.num_keys() == 0);
+ ASSERT(trie.num_nodes() == 1);
+
+ ASSERT(trie.tail_mode() == MARISA_DEFAULT_TAIL);
+ ASSERT(trie.node_order() == MARISA_DEFAULT_ORDER);
+
+ ASSERT(trie.empty());
+ ASSERT(trie.size() == 0);
+ ASSERT(trie.total_size() != 0);
+ ASSERT(trie.io_size() != 0);
+
+ keyset.push_back("");
+ trie.build(keyset);
+
+ ASSERT(trie.lookup(agent));
+ trie.reverse_lookup(agent);
+ ASSERT(trie.common_prefix_search(agent));
+ ASSERT(!trie.common_prefix_search(agent));
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(!trie.predictive_search(agent));
+
+ ASSERT(trie.num_keys() == 1);
+ ASSERT(trie.num_nodes() == 1);
+
+ ASSERT(!trie.empty());
+ ASSERT(trie.size() == 1);
+ ASSERT(trie.total_size() != 0);
+ ASSERT(trie.io_size() != 0);
+
+ TEST_END();
+}
+
+void TestTinyTrie() {
+ TEST_START();
+
+ marisa::Keyset keyset;
+ keyset.push_back("bach");
+ keyset.push_back("bet");
+ keyset.push_back("chat");
+ keyset.push_back("check");
+ keyset.push_back("check");
+
+ marisa::Trie trie;
+ trie.build(keyset, 1);
+
+ ASSERT(trie.num_tries() == 1);
+ ASSERT(trie.num_keys() == 4);
+ ASSERT(trie.num_nodes() == 7);
+
+ ASSERT(trie.tail_mode() == MARISA_DEFAULT_TAIL);
+ ASSERT(trie.node_order() == MARISA_DEFAULT_ORDER);
+
+ ASSERT(keyset[0].id() == 2);
+ ASSERT(keyset[1].id() == 3);
+ ASSERT(keyset[2].id() == 1);
+ ASSERT(keyset[3].id() == 0);
+ ASSERT(keyset[4].id() == 0);
+
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ ASSERT(trie.lookup(agent));
+ ASSERT(agent.key().id() == keyset[i].id());
+
+ agent.set_query(keyset[i].id());
+ trie.reverse_lookup(agent);
+ ASSERT(agent.key().length() == keyset[i].length());
+ ASSERT(std::memcmp(agent.key().ptr(), keyset[i].ptr(),
+ agent.key().length()) == 0);
+ }
+
+ agent.set_query("be");
+ ASSERT(!trie.common_prefix_search(agent));
+ agent.set_query("beX");
+ ASSERT(!trie.common_prefix_search(agent));
+ agent.set_query("bet");
+ ASSERT(trie.common_prefix_search(agent));
+ ASSERT(!trie.common_prefix_search(agent));
+ agent.set_query("betX");
+ ASSERT(trie.common_prefix_search(agent));
+ ASSERT(!trie.common_prefix_search(agent));
+
+ agent.set_query("chatX");
+ ASSERT(!trie.predictive_search(agent));
+ agent.set_query("chat");
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().length() == 4);
+ ASSERT(!trie.predictive_search(agent));
+
+ agent.set_query("cha");
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().length() == 4);
+ ASSERT(!trie.predictive_search(agent));
+
+ agent.set_query("c");
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().length() == 5);
+ ASSERT(std::memcmp(agent.key().ptr(), "check", 5) == 0);
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().length() == 4);
+ ASSERT(std::memcmp(agent.key().ptr(), "chat", 4) == 0);
+ ASSERT(!trie.predictive_search(agent));
+
+ agent.set_query("ch");
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().length() == 5);
+ ASSERT(std::memcmp(agent.key().ptr(), "check", 5) == 0);
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().length() == 4);
+ ASSERT(std::memcmp(agent.key().ptr(), "chat", 4) == 0);
+ ASSERT(!trie.predictive_search(agent));
+
+ trie.build(keyset, 1 | MARISA_LABEL_ORDER);
+
+ ASSERT(trie.num_tries() == 1);
+ ASSERT(trie.num_keys() == 4);
+ ASSERT(trie.num_nodes() == 7);
+
+ ASSERT(trie.tail_mode() == MARISA_DEFAULT_TAIL);
+ ASSERT(trie.node_order() == MARISA_LABEL_ORDER);
+
+ ASSERT(keyset[0].id() == 0);
+ ASSERT(keyset[1].id() == 1);
+ ASSERT(keyset[2].id() == 2);
+ ASSERT(keyset[3].id() == 3);
+ ASSERT(keyset[4].id() == 3);
+
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ ASSERT(trie.lookup(agent));
+ ASSERT(agent.key().id() == keyset[i].id());
+
+ agent.set_query(keyset[i].id());
+ trie.reverse_lookup(agent);
+ ASSERT(agent.key().length() == keyset[i].length());
+ ASSERT(std::memcmp(agent.key().ptr(), keyset[i].ptr(),
+ agent.key().length()) == 0);
+ }
+
+ agent.set_query("");
+ for (std::size_t i = 0; i < trie.size(); ++i) {
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().id() == i);
+ }
+ ASSERT(!trie.predictive_search(agent));
+
+ TEST_END();
+}
+
+void MakeKeyset(std::size_t num_keys, marisa::TailMode tail_mode,
+ marisa::Keyset *keyset) {
+ char key_buf[16];
+ for (std::size_t i = 0; i < num_keys; ++i) {
+ const std::size_t length =
+ static_cast<std::size_t>(std::rand()) % sizeof(key_buf);
+ for (std::size_t j = 0; j < length; ++j) {
+ key_buf[j] = (char)(std::rand() % 10);
+ if (tail_mode == MARISA_TEXT_TAIL) {
+ key_buf[j] = static_cast<char>(key_buf[j] + '0');
+ }
+ }
+ keyset->push_back(key_buf, length);
+ }
+}
+
+void TestLookup(const marisa::Trie &trie, const marisa::Keyset &keyset) {
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ ASSERT(trie.lookup(agent));
+ ASSERT(agent.key().id() == keyset[i].id());
+
+ agent.set_query(keyset[i].id());
+ trie.reverse_lookup(agent);
+ ASSERT(agent.key().length() == keyset[i].length());
+ ASSERT(std::memcmp(agent.key().ptr(), keyset[i].ptr(),
+ agent.key().length()) == 0);
+ }
+}
+
+void TestCommonPrefixSearch(const marisa::Trie &trie,
+ const marisa::Keyset &keyset) {
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ ASSERT(trie.common_prefix_search(agent));
+ ASSERT(agent.key().id() <= keyset[i].id());
+ while (trie.common_prefix_search(agent)) {
+ ASSERT(agent.key().id() <= keyset[i].id());
+ }
+ ASSERT(agent.key().id() == keyset[i].id());
+ }
+}
+
+void TestPredictiveSearch(const marisa::Trie &trie,
+ const marisa::Keyset &keyset) {
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ ASSERT(trie.predictive_search(agent));
+ ASSERT(agent.key().id() == keyset[i].id());
+ while (trie.predictive_search(agent)) {
+ ASSERT(agent.key().id() > keyset[i].id());
+ }
+ }
+}
+
+void TestTrie(int num_tries, marisa::TailMode tail_mode,
+ marisa::NodeOrder node_order, marisa::Keyset &keyset) {
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ keyset[i].set_weight(1.0F);
+ }
+
+ marisa::Trie trie;
+ trie.build(keyset, num_tries | tail_mode | node_order);
+
+ ASSERT(trie.num_tries() == (std::size_t)num_tries);
+ ASSERT(trie.num_keys() <= keyset.size());
+
+ ASSERT(trie.tail_mode() == tail_mode);
+ ASSERT(trie.node_order() == node_order);
+
+ TestLookup(trie, keyset);
+ TestCommonPrefixSearch(trie, keyset);
+ TestPredictiveSearch(trie, keyset);
+
+ trie.save("marisa-test.dat");
+
+ trie.clear();
+ trie.load("marisa-test.dat");
+
+ ASSERT(trie.num_tries() == (std::size_t)num_tries);
+ ASSERT(trie.num_keys() <= keyset.size());
+
+ ASSERT(trie.tail_mode() == tail_mode);
+ ASSERT(trie.node_order() == node_order);
+
+ TestLookup(trie, keyset);
+
+ {
+ std::FILE *file;
+#ifdef _MSC_VER
+ ASSERT(::fopen_s(&file, "marisa-test.dat", "wb") == 0);
+#else // _MSC_VER
+ file = std::fopen("marisa-test.dat", "wb");
+ ASSERT(file != NULL);
+#endif // _MSC_VER
+ marisa::fwrite(file, trie);
+ std::fclose(file);
+ trie.clear();
+#ifdef _MSC_VER
+ ASSERT(::fopen_s(&file, "marisa-test.dat", "rb") == 0);
+#else // _MSC_VER
+ file = std::fopen("marisa-test.dat", "rb");
+ ASSERT(file != NULL);
+#endif // _MSC_VER
+ marisa::fread(file, &trie);
+ std::fclose(file);
+ }
+
+ ASSERT(trie.num_tries() == (std::size_t)num_tries);
+ ASSERT(trie.num_keys() <= keyset.size());
+
+ ASSERT(trie.tail_mode() == tail_mode);
+ ASSERT(trie.node_order() == node_order);
+
+ TestLookup(trie, keyset);
+
+ trie.clear();
+ trie.mmap("marisa-test.dat");
+
+ ASSERT(trie.num_tries() == (std::size_t)num_tries);
+ ASSERT(trie.num_keys() <= keyset.size());
+
+ ASSERT(trie.tail_mode() == tail_mode);
+ ASSERT(trie.node_order() == node_order);
+
+ TestLookup(trie, keyset);
+
+ {
+ std::stringstream stream;
+ stream << trie;
+ trie.clear();
+ stream >> trie;
+ }
+
+ ASSERT(trie.num_tries() == (std::size_t)num_tries);
+ ASSERT(trie.num_keys() <= keyset.size());
+
+ ASSERT(trie.tail_mode() == tail_mode);
+ ASSERT(trie.node_order() == node_order);
+
+ TestLookup(trie, keyset);
+}
+
+void TestTrie(marisa::TailMode tail_mode, marisa::NodeOrder node_order,
+ marisa::Keyset &keyset) {
+ TEST_START();
+ std::cout << ((tail_mode == MARISA_TEXT_TAIL) ? "TEXT" : "BINARY") << ", ";
+ std::cout << ((node_order == MARISA_WEIGHT_ORDER) ?
+ "WEIGHT" : "LABEL") << ": ";
+
+ for (int i = 1; i < 5; ++i) {
+ TestTrie(i, tail_mode, node_order, keyset);
+ }
+
+ TEST_END();
+}
+
+void TestTrie(marisa::TailMode tail_mode) {
+ marisa::Keyset keyset;
+ MakeKeyset(1000, tail_mode, &keyset);
+
+ TestTrie(tail_mode, MARISA_WEIGHT_ORDER, keyset);
+ TestTrie(tail_mode, MARISA_LABEL_ORDER, keyset);
+}
+
+void TestTrie() {
+ TestTrie(MARISA_TEXT_TAIL);
+ TestTrie(MARISA_BINARY_TAIL);
+}
+
+} // namespace
+
+int main() try {
+ std::srand((unsigned int)std::time(NULL));
+
+ TestEmptyTrie();
+ TestTinyTrie();
+ TestTrie();
+
+ return 0;
+} catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << std::endl;
+ throw;
+}
diff --git a/tests/trie-test.cc b/tests/trie-test.cc
new file mode 100644
index 0000000..2ca1a74
--- /dev/null
+++ b/tests/trie-test.cc
@@ -0,0 +1,506 @@
+#include <algorithm>
+#include <cstring>
+#include <sstream>
+
+#include <marisa/grimoire/trie/config.h>
+#include <marisa/grimoire/trie/header.h>
+#include <marisa/grimoire/trie/key.h>
+#include <marisa/grimoire/trie/range.h>
+#include <marisa/grimoire/trie/tail.h>
+#include <marisa/grimoire/trie/state.h>
+
+#include "marisa-assert.h"
+
+namespace {
+
+void TestConfig() {
+ TEST_START();
+
+ marisa::grimoire::trie::Config config;
+
+ ASSERT(config.num_tries() == MARISA_DEFAULT_NUM_TRIES);
+ ASSERT(config.tail_mode() == MARISA_DEFAULT_TAIL);
+ ASSERT(config.node_order() == MARISA_DEFAULT_ORDER);
+ ASSERT(config.cache_level() == MARISA_DEFAULT_CACHE);
+
+ config.parse(10 | MARISA_BINARY_TAIL | MARISA_LABEL_ORDER |
+ MARISA_TINY_CACHE);
+
+ ASSERT(config.num_tries() == 10);
+ ASSERT(config.tail_mode() == MARISA_BINARY_TAIL);
+ ASSERT(config.node_order() == MARISA_LABEL_ORDER);
+ ASSERT(config.cache_level() == MARISA_TINY_CACHE);
+
+ config.parse(0);
+
+ ASSERT(config.num_tries() == MARISA_DEFAULT_NUM_TRIES);
+ ASSERT(config.tail_mode() == MARISA_DEFAULT_TAIL);
+ ASSERT(config.node_order() == MARISA_DEFAULT_ORDER);
+ ASSERT(config.cache_level() == MARISA_DEFAULT_CACHE);
+
+ TEST_END();
+}
+
+void TestHeader() {
+ TEST_START();
+
+ marisa::grimoire::trie::Header header;
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open("trie-test.dat");
+ header.write(writer);
+ }
+
+ {
+ marisa::grimoire::Mapper mapper;
+ mapper.open("trie-test.dat");
+ header.map(mapper);
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open("trie-test.dat");
+ header.read(reader);
+ }
+
+ TEST_END();
+}
+
+void TestKey() {
+ TEST_START();
+
+ marisa::grimoire::trie::Key key;
+
+ ASSERT(key.ptr() == NULL);
+ ASSERT(key.length() == 0);
+ ASSERT(key.id() == 0);
+ ASSERT(key.terminal() == 0);
+
+ const char *str = "xyz";
+
+ key.set_str(str, 3);
+ key.set_weight(10.0F);
+ key.set_id(20);
+
+
+ ASSERT(key.ptr() == str);
+ ASSERT(key.length() == 3);
+ ASSERT(key[0] == 'x');
+ ASSERT(key[1] == 'y');
+ ASSERT(key[2] == 'z');
+ ASSERT(key.weight() == 10.0F);
+ ASSERT(key.id() == 20);
+
+ key.set_terminal(30);
+ ASSERT(key.terminal() == 30);
+
+ key.substr(1, 2);
+
+ ASSERT(key.ptr() == str + 1);
+ ASSERT(key.length() == 2);
+ ASSERT(key[0] == 'y');
+ ASSERT(key[1] == 'z');
+
+ marisa::grimoire::trie::Key key2;
+ key2.set_str("abc", 3);
+
+ ASSERT(key == key);
+ ASSERT(key != key2);
+ ASSERT(key > key2);
+ ASSERT(key2 < key);
+
+ marisa::grimoire::trie::ReverseKey r_key;
+
+ ASSERT(r_key.ptr() == NULL);
+ ASSERT(r_key.length() == 0);
+ ASSERT(r_key.id() == 0);
+ ASSERT(r_key.terminal() == 0);
+
+ r_key.set_str(str, 3);
+ r_key.set_weight(100.0F);
+ r_key.set_id(200);
+
+ ASSERT(r_key.ptr() == str);
+ ASSERT(r_key.length() == 3);
+ ASSERT(r_key[0] == 'z');
+ ASSERT(r_key[1] == 'y');
+ ASSERT(r_key[2] == 'x');
+ ASSERT(r_key.weight() == 100.0F);
+ ASSERT(r_key.id() == 200);
+
+ r_key.set_terminal(300);
+ ASSERT(r_key.terminal() == 300);
+
+ r_key.substr(1, 2);
+
+ ASSERT(r_key.ptr() == str);
+ ASSERT(r_key.length() == 2);
+ ASSERT(r_key[0] == 'y');
+ ASSERT(r_key[1] == 'x');
+
+ marisa::grimoire::trie::ReverseKey r_key2;
+ r_key2.set_str("abc", 3);
+
+ ASSERT(r_key == r_key);
+ ASSERT(r_key != r_key2);
+ ASSERT(r_key > r_key2);
+ ASSERT(r_key2 < r_key);
+
+ TEST_END();
+}
+
+void TestRange() {
+ TEST_START();
+
+ marisa::grimoire::trie::Range range;
+
+ ASSERT(range.begin() == 0);
+ ASSERT(range.end() == 0);
+ ASSERT(range.key_pos() == 0);
+
+ range.set_begin(1);
+ range.set_end(2);
+ range.set_key_pos(3);
+
+ ASSERT(range.begin() == 1);
+ ASSERT(range.end() == 2);
+ ASSERT(range.key_pos() == 3);
+
+ range = marisa::grimoire::trie::make_range(10, 20, 30);
+
+ ASSERT(range.begin() == 10);
+ ASSERT(range.end() == 20);
+ ASSERT(range.key_pos() == 30);
+
+ marisa::grimoire::trie::WeightedRange w_range;
+
+ ASSERT(w_range.begin() == 0);
+ ASSERT(w_range.end() == 0);
+ ASSERT(w_range.key_pos() == 0);
+ ASSERT(w_range.weight() == 0.0F);
+
+ w_range.set_begin(10);
+ w_range.set_end(20);
+ w_range.set_key_pos(30);
+ w_range.set_weight(40.0F);
+
+ ASSERT(w_range.begin() == 10);
+ ASSERT(w_range.end() == 20);
+ ASSERT(w_range.key_pos() == 30);
+ ASSERT(w_range.weight() == 40.0F);
+
+ marisa::grimoire::trie::WeightedRange w_range2 =
+ marisa::grimoire::trie::make_weighted_range(100, 200, 300, 400.0F);
+
+ ASSERT(w_range2.begin() == 100);
+ ASSERT(w_range2.end() == 200);
+ ASSERT(w_range2.key_pos() == 300);
+ ASSERT(w_range2.weight() == 400.0F);
+
+ ASSERT(w_range < w_range2);
+ ASSERT(w_range2 > w_range);
+
+ TEST_END();
+}
+
+void TestEntry() {
+ TEST_START();
+
+ marisa::grimoire::trie::Entry entry;
+
+ ASSERT(entry.length() == 0);
+ ASSERT(entry.id() == 0);
+
+ const char *str = "XYZ";
+
+ entry.set_str(str, 3);
+ entry.set_id(123);
+
+ ASSERT(entry.ptr() == str);
+ ASSERT(entry.length() == 3);
+ ASSERT(entry[0] == 'Z');
+ ASSERT(entry[1] == 'Y');
+ ASSERT(entry[2] == 'X');
+ ASSERT(entry.id() == 123);
+
+ TEST_END();
+}
+
+void TestTextTail() {
+ TEST_START();
+
+ marisa::grimoire::trie::Tail tail;
+ marisa::grimoire::Vector<marisa::grimoire::trie::Entry> entries;
+ marisa::grimoire::Vector<marisa::UInt32> offsets;
+ tail.build(entries, &offsets, MARISA_TEXT_TAIL);
+
+ ASSERT(tail.mode() == MARISA_TEXT_TAIL);
+ ASSERT(tail.size() == 0);
+ ASSERT(tail.empty());
+ ASSERT(tail.total_size() == tail.size());
+ ASSERT(tail.io_size() == (sizeof(marisa::UInt64) * 6));
+
+ ASSERT(offsets.empty());
+
+ marisa::grimoire::trie::Entry entry;
+ entry.set_str("X", 1);
+ entries.push_back(entry);
+
+ tail.build(entries, &offsets, MARISA_TEXT_TAIL);
+
+ ASSERT(tail.mode() == MARISA_TEXT_TAIL);
+ ASSERT(tail.size() == 2);
+ ASSERT(!tail.empty());
+ ASSERT(tail.total_size() == tail.size());
+ ASSERT(tail.io_size() == (sizeof(marisa::UInt64) * 7));
+
+ ASSERT(offsets.size() == entries.size());
+ ASSERT(offsets[0] == 0);
+ ASSERT(tail[offsets[0]] == 'X');
+ ASSERT(tail[offsets[0] + 1] == '\0');
+
+ entries.clear();
+ entry.set_str("abc", 3);
+ entries.push_back(entry);
+ entry.set_str("bc", 2);
+ entries.push_back(entry);
+ entry.set_str("abc", 3);
+ entries.push_back(entry);
+ entry.set_str("c", 1);
+ entries.push_back(entry);
+ entry.set_str("ABC", 3);
+ entries.push_back(entry);
+ entry.set_str("AB", 2);
+ entries.push_back(entry);
+
+ tail.build(entries, &offsets, MARISA_TEXT_TAIL);
+ std::sort(entries.begin(), entries.end(),
+ marisa::grimoire::trie::Entry::IDComparer());
+
+ ASSERT(tail.size() == 11);
+ ASSERT(offsets.size() == entries.size());
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ const char * const ptr = &tail[offsets[i]];
+ ASSERT(std::strlen(ptr) == entries[i].length());
+ ASSERT(std::strcmp(ptr, entries[i].ptr()) == 0);
+ }
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open("trie-test.dat");
+ tail.write(writer);
+ }
+
+ tail.clear();
+
+ ASSERT(tail.size() == 0);
+ ASSERT(tail.total_size() == tail.size());
+
+ {
+ marisa::grimoire::Mapper mapper;
+ mapper.open("trie-test.dat");
+ tail.map(mapper);
+
+ ASSERT(tail.mode() == MARISA_TEXT_TAIL);
+ ASSERT(tail.size() == 11);
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ const char * const ptr = &tail[offsets[i]];
+ ASSERT(std::strlen(ptr) == entries[i].length());
+ ASSERT(std::strcmp(ptr, entries[i].ptr()) == 0);
+ }
+ tail.clear();
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open("trie-test.dat");
+ tail.read(reader);
+ }
+
+ ASSERT(tail.size() == 11);
+ ASSERT(offsets.size() == entries.size());
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ const char * const ptr = &tail[offsets[i]];
+ ASSERT(std::strlen(ptr) == entries[i].length());
+ ASSERT(std::strcmp(ptr, entries[i].ptr()) == 0);
+ }
+
+ {
+ std::stringstream stream;
+ marisa::grimoire::Writer writer;
+ writer.open(stream);
+ tail.write(writer);
+ tail.clear();
+ marisa::grimoire::Reader reader;
+ reader.open(stream);
+ tail.read(reader);
+ }
+
+ ASSERT(tail.size() == 11);
+ ASSERT(offsets.size() == entries.size());
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ const char * const ptr = &tail[offsets[i]];
+ ASSERT(std::strlen(ptr) == entries[i].length());
+ ASSERT(std::strcmp(ptr, entries[i].ptr()) == 0);
+ }
+
+ TEST_END();
+}
+
+void TestBinaryTail() {
+ TEST_START();
+
+ marisa::grimoire::trie::Tail tail;
+ marisa::grimoire::Vector<marisa::grimoire::trie::Entry> entries;
+ marisa::grimoire::Vector<marisa::UInt32> offsets;
+ tail.build(entries, &offsets, MARISA_BINARY_TAIL);
+
+ ASSERT(tail.mode() == MARISA_TEXT_TAIL);
+ ASSERT(tail.size() == 0);
+ ASSERT(tail.empty());
+ ASSERT(tail.total_size() == tail.size());
+ ASSERT(tail.io_size() == (sizeof(marisa::UInt64) * 6));
+
+ ASSERT(offsets.empty());
+
+ marisa::grimoire::trie::Entry entry;
+ entry.set_str("X", 1);
+ entries.push_back(entry);
+
+ tail.build(entries, &offsets, MARISA_BINARY_TAIL);
+
+ ASSERT(tail.mode() == MARISA_BINARY_TAIL);
+ ASSERT(tail.size() == 1);
+ ASSERT(!tail.empty());
+ ASSERT(tail.total_size() == (tail.size() + sizeof(marisa::UInt64)));
+ ASSERT(tail.io_size() == (sizeof(marisa::UInt64) * 8));
+
+ ASSERT(offsets.size() == entries.size());
+ ASSERT(offsets[0] == 0);
+
+ const char binary_entry[] = { 'N', 'P', '\0', 'T', 'r', 'i', 'e' };
+ entries[0].set_str(binary_entry, sizeof(binary_entry));
+
+ tail.build(entries, &offsets, MARISA_TEXT_TAIL);
+
+ ASSERT(tail.mode() == MARISA_BINARY_TAIL);
+ ASSERT(tail.size() == entries[0].length());
+
+ ASSERT(offsets.size() == entries.size());
+ ASSERT(offsets[0] == 0);
+
+ entries.clear();
+ entry.set_str("abc", 3);
+ entries.push_back(entry);
+ entry.set_str("bc", 2);
+ entries.push_back(entry);
+ entry.set_str("abc", 3);
+ entries.push_back(entry);
+ entry.set_str("c", 1);
+ entries.push_back(entry);
+ entry.set_str("ABC", 3);
+ entries.push_back(entry);
+ entry.set_str("AB", 2);
+ entries.push_back(entry);
+
+ tail.build(entries, &offsets, MARISA_BINARY_TAIL);
+ std::sort(entries.begin(), entries.end(),
+ marisa::grimoire::trie::Entry::IDComparer());
+
+ ASSERT(tail.mode() == MARISA_BINARY_TAIL);
+ ASSERT(tail.size() == 8);
+ ASSERT(offsets.size() == entries.size());
+ for (std::size_t i = 0; i < entries.size(); ++i) {
+ const char * const ptr = &tail[offsets[i]];
+ ASSERT(std::memcmp(ptr, entries[i].ptr(), entries[i].length()) == 0);
+ }
+
+ TEST_END();
+}
+
+void TestHistory() {
+ TEST_START();
+
+ marisa::grimoire::trie::History history;
+
+ ASSERT(history.node_id() == 0);
+ ASSERT(history.louds_pos() == 0);
+ ASSERT(history.key_pos() == 0);
+ ASSERT(history.link_id() == MARISA_INVALID_LINK_ID);
+ ASSERT(history.key_id() == MARISA_INVALID_KEY_ID);
+
+ history.set_node_id(100);
+ history.set_louds_pos(200);
+ history.set_key_pos(300);
+ history.set_link_id(400);
+ history.set_key_id(500);
+
+ ASSERT(history.node_id() == 100);
+ ASSERT(history.louds_pos() == 200);
+ ASSERT(history.key_pos() == 300);
+ ASSERT(history.link_id() == 400);
+ ASSERT(history.key_id() == 500);
+
+ TEST_END();
+}
+
+void TestState() {
+ TEST_START();
+
+ marisa::grimoire::trie::State state;
+
+ ASSERT(state.key_buf().empty());
+ ASSERT(state.history().empty());
+ ASSERT(state.node_id() == 0);
+ ASSERT(state.query_pos() == 0);
+ ASSERT(state.history_pos() == 0);
+ ASSERT(state.status_code() == marisa::grimoire::trie::MARISA_READY_TO_ALL);
+
+ state.set_node_id(10);
+ state.set_query_pos(100);
+ state.set_history_pos(1000);
+ state.set_status_code(
+ marisa::grimoire::trie::MARISA_END_OF_PREDICTIVE_SEARCH);
+
+ ASSERT(state.node_id() == 10);
+ ASSERT(state.query_pos() == 100);
+ ASSERT(state.history_pos() == 1000);
+ ASSERT(state.status_code() ==
+ marisa::grimoire::trie::MARISA_END_OF_PREDICTIVE_SEARCH);
+
+ state.lookup_init();
+ ASSERT(state.status_code() == marisa::grimoire::trie::MARISA_READY_TO_ALL);
+
+ state.reverse_lookup_init();
+ ASSERT(state.status_code() == marisa::grimoire::trie::MARISA_READY_TO_ALL);
+
+ state.common_prefix_search_init();
+ ASSERT(state.status_code() ==
+ marisa::grimoire::trie::MARISA_READY_TO_COMMON_PREFIX_SEARCH);
+
+ state.predictive_search_init();
+ ASSERT(state.status_code() ==
+ marisa::grimoire::trie::MARISA_READY_TO_PREDICTIVE_SEARCH);
+
+ TEST_END();
+}
+
+} // namespace
+
+int main() try {
+ TestConfig();
+ TestHeader();
+ TestKey();
+ TestRange();
+ TestEntry();
+ TestTextTail();
+ TestBinaryTail();
+ TestHistory();
+ TestState();
+
+ return 0;
+} catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << std::endl;
+ throw;
+}
diff --git a/tests/vector-test.cc b/tests/vector-test.cc
new file mode 100644
index 0000000..a11cd12
--- /dev/null
+++ b/tests/vector-test.cc
@@ -0,0 +1,466 @@
+#include <cstdlib>
+#include <ctime>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include <marisa/grimoire/vector/pop-count.h>
+#include <marisa/grimoire/vector/rank-index.h>
+#include <marisa/grimoire/vector.h>
+
+#include "marisa-assert.h"
+
+namespace {
+
+#if MARISA_WORD_SIZE == 64
+void TestPopCount() {
+ TEST_START();
+
+ {
+ marisa::grimoire::vector::PopCount count(0);
+ ASSERT(count.lo8() == 0);
+ ASSERT(count.lo16() == 0);
+ ASSERT(count.lo24() == 0);
+ ASSERT(count.lo32() == 0);
+ ASSERT(count.lo40() == 0);
+ ASSERT(count.lo48() == 0);
+ ASSERT(count.lo56() == 0);
+ ASSERT(count.lo64() == 0);
+ }
+
+ {
+ marisa::grimoire::vector::PopCount count(0xFFFFFFFFFFFFFFFFULL);
+ ASSERT(count.lo8() == 8);
+ ASSERT(count.lo16() == 16);
+ ASSERT(count.lo24() == 24);
+ ASSERT(count.lo32() == 32);
+ ASSERT(count.lo40() == 40);
+ ASSERT(count.lo48() == 48);
+ ASSERT(count.lo56() == 56);
+ ASSERT(count.lo64() == 64);
+ }
+
+ {
+ marisa::grimoire::vector::PopCount count(0xFF7F3F1F0F070301ULL);
+ ASSERT(count.lo8() == 1);
+ ASSERT(count.lo16() == 3);
+ ASSERT(count.lo24() == 6);
+ ASSERT(count.lo32() == 10);
+ ASSERT(count.lo40() == 15);
+ ASSERT(count.lo48() == 21);
+ ASSERT(count.lo56() == 28);
+ ASSERT(count.lo64() == 36);
+ }
+
+ TEST_END();
+}
+#else // MARISA_WORD_SIZE == 64
+void TestPopCount() {
+ TEST_START();
+
+ {
+ marisa::grimoire::vector::PopCount count(0);
+ ASSERT(count.lo8() == 0);
+ ASSERT(count.lo16() == 0);
+ ASSERT(count.lo24() == 0);
+ ASSERT(count.lo32() == 0);
+ }
+
+ {
+ marisa::grimoire::vector::PopCount count(0xFFFFFFFFU);
+ ASSERT(count.lo8() == 8);
+ ASSERT(count.lo16() == 16);
+ ASSERT(count.lo24() == 24);
+ ASSERT(count.lo32() == 32);
+ }
+
+ {
+ marisa::grimoire::vector::PopCount count(0xFF3F0F03U);
+ ASSERT(count.lo8() == 2);
+ ASSERT(count.lo16() == 6);
+ ASSERT(count.lo24() == 12);
+ ASSERT(count.lo32() == 20);
+ }
+
+ TEST_END();
+}
+#endif // MARISA_WORD_SIZE == 64
+
+void TestRankIndex() {
+ TEST_START();
+
+ marisa::grimoire::vector::RankIndex rank;
+
+ ASSERT(rank.abs() == 0);
+ ASSERT(rank.rel1() == 0);
+ ASSERT(rank.rel2() == 0);
+ ASSERT(rank.rel3() == 0);
+ ASSERT(rank.rel4() == 0);
+ ASSERT(rank.rel5() == 0);
+ ASSERT(rank.rel6() == 0);
+ ASSERT(rank.rel7() == 0);
+
+ rank.set_abs(10000);
+ rank.set_rel1(64);
+ rank.set_rel2(128);
+ rank.set_rel3(192);
+ rank.set_rel4(256);
+ rank.set_rel5(320);
+ rank.set_rel6(384);
+ rank.set_rel7(448);
+
+ ASSERT(rank.abs() == 10000);
+ ASSERT(rank.rel1() == 64);
+ ASSERT(rank.rel2() == 128);
+ ASSERT(rank.rel3() == 192);
+ ASSERT(rank.rel4() == 256);
+ ASSERT(rank.rel5() == 320);
+ ASSERT(rank.rel6() == 384);
+ ASSERT(rank.rel7() == 448);
+
+ TEST_END();
+}
+
+void TestVector() {
+ TEST_START();
+
+ std::vector<int> values;
+ for (std::size_t i = 0; i < 10000; ++i) {
+ values.push_back(std::rand());
+ }
+
+ marisa::grimoire::Vector<int> vec;
+
+ ASSERT(vec.max_size() == (MARISA_SIZE_MAX / sizeof(int)));
+ ASSERT(vec.size() == 0);
+ ASSERT(vec.capacity() == 0);
+ ASSERT(!vec.fixed());
+ ASSERT(vec.empty());
+ ASSERT(vec.total_size() == 0);
+ ASSERT(vec.io_size() == sizeof(marisa::UInt64));
+
+ for (std::size_t i = 0; i < values.size(); ++i) {
+ vec.push_back(values[i]);
+ ASSERT(vec[i] == values[i]);
+ ASSERT(static_cast<const marisa::grimoire::Vector<int> &>(vec)[i]
+ == values[i]);
+ }
+
+ ASSERT(vec.size() == values.size());
+ ASSERT(vec.capacity() >= vec.size());
+ ASSERT(!vec.empty());
+ ASSERT(vec.total_size() == (sizeof(int) * values.size()));
+ ASSERT(vec.io_size() == sizeof(marisa::UInt64)
+ + ((sizeof(int) * values.size())));
+
+ ASSERT(static_cast<const marisa::grimoire::Vector<int> &>(vec).front()
+ == values.front());
+ ASSERT(static_cast<const marisa::grimoire::Vector<int> &>(vec).back()
+ == values.back());
+ ASSERT(vec.front() == values.front());
+ ASSERT(vec.back() == values.back());
+
+ vec.shrink();
+
+ ASSERT(vec.size() == values.size());
+ ASSERT(vec.capacity() == vec.size());
+ for (std::size_t i = 0; i < values.size(); ++i) {
+ ASSERT(vec[i] == values[i]);
+ ASSERT(static_cast<const marisa::grimoire::Vector<int> &>(vec)[i]
+ == values[i]);
+ }
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open("vector-test.dat");
+ vec.write(writer);
+ }
+ vec.clear();
+
+ ASSERT(vec.empty());
+ ASSERT(vec.capacity() == 0);
+
+ {
+ marisa::grimoire::Mapper mapper;
+ mapper.open("vector-test.dat");
+ vec.map(mapper);
+
+ ASSERT(vec.size() == values.size());
+ ASSERT(vec.capacity() == 0);
+ ASSERT(vec.fixed());
+ ASSERT(!vec.empty());
+ ASSERT(vec.total_size() == (sizeof(int) * values.size()));
+ ASSERT(vec.io_size() == sizeof(marisa::UInt64)
+ + ((sizeof(int) * values.size())));
+
+ for (std::size_t i = 0; i < values.size(); ++i) {
+ ASSERT(static_cast<const marisa::grimoire::Vector<int> &>(vec)[i]
+ == values[i]);
+ }
+
+ vec.clear();
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open("vector-test.dat");
+ vec.read(reader);
+ }
+
+ ASSERT(vec.size() == values.size());
+ ASSERT(vec.capacity() == vec.size());
+ ASSERT(!vec.fixed());
+ ASSERT(!vec.empty());
+ ASSERT(vec.total_size() == (sizeof(int) * values.size()));
+ ASSERT(vec.io_size() == sizeof(marisa::UInt64)
+ + ((sizeof(int) * values.size())));
+
+ for (std::size_t i = 0; i < values.size(); ++i) {
+ ASSERT(vec[i] == values[i]);
+ ASSERT(static_cast<const marisa::grimoire::Vector<int> &>(vec)[i]
+ == values[i]);
+ }
+
+ vec.clear();
+
+ vec.push_back(0);
+ ASSERT(vec.capacity() == 1);
+ vec.push_back(1);
+ ASSERT(vec.capacity() == 2);
+ vec.push_back(2);
+ ASSERT(vec.capacity() == 4);
+ vec.resize(5);
+ ASSERT(vec.capacity() == 8);
+ vec.resize(100);
+ ASSERT(vec.capacity() == 100);
+
+ EXCEPT(vec.resize(MARISA_SIZE_MAX), MARISA_SIZE_ERROR);
+
+ vec.fix();
+ ASSERT(vec.fixed());
+ EXCEPT(vec.fix(), MARISA_STATE_ERROR);
+ EXCEPT(vec.push_back(0), MARISA_STATE_ERROR);
+ EXCEPT(vec.resize(0), MARISA_STATE_ERROR);
+ EXCEPT(vec.reserve(0), MARISA_STATE_ERROR);
+
+ TEST_END();
+}
+
+void TestFlatVector() {
+ TEST_START();
+
+ marisa::grimoire::FlatVector vec;
+
+ ASSERT(vec.value_size() == 0);
+ ASSERT(vec.mask() == 0);
+ ASSERT(vec.size() == 0);
+ ASSERT(vec.empty());
+ ASSERT(vec.total_size() == 0);
+ ASSERT(vec.io_size() == (sizeof(marisa::UInt64) * 3));
+
+ marisa::grimoire::Vector<marisa::UInt32> values;
+ vec.build(values);
+
+ ASSERT(vec.value_size() == 0);
+ ASSERT(vec.mask() == 0);
+ ASSERT(vec.size() == 0);
+ ASSERT(vec.empty());
+ ASSERT(vec.total_size() == 0);
+ ASSERT(vec.io_size() == (sizeof(marisa::UInt64) * 3));
+
+ values.push_back(0);
+ vec.build(values);
+
+ ASSERT(vec.value_size() == 0);
+ ASSERT(vec.mask() == 0);
+ ASSERT(vec.size() == 1);
+ ASSERT(!vec.empty());
+ ASSERT(vec.total_size() == 8);
+ ASSERT(vec.io_size() == (sizeof(marisa::UInt64) * 4));
+ ASSERT(vec[0] == 0);
+
+ values.push_back(255);
+ vec.build(values);
+
+ ASSERT(vec.value_size() == 8);
+ ASSERT(vec.mask() == 0xFF);
+ ASSERT(vec.size() == 2);
+ ASSERT(vec[0] == 0);
+ ASSERT(vec[1] == 255);
+
+ values.push_back(65536);
+ vec.build(values);
+
+ ASSERT(vec.value_size() == 17);
+ ASSERT(vec.mask() == 0x1FFFF);
+ ASSERT(vec.size() == 3);
+ ASSERT(vec[0] == 0);
+ ASSERT(vec[1] == 255);
+ ASSERT(vec[2] == 65536);
+
+ {
+ marisa::grimoire::Writer writer;
+ writer.open("vector-test.dat");
+ vec.write(writer);
+ }
+
+ vec.clear();
+
+ ASSERT(vec.value_size() == 0);
+ ASSERT(vec.mask() == 0);
+ ASSERT(vec.size() == 0);
+
+ {
+ marisa::grimoire::Mapper mapper;
+ mapper.open("vector-test.dat");
+ vec.map(mapper);
+
+ ASSERT(vec.value_size() == 17);
+ ASSERT(vec.mask() == 0x1FFFF);
+ ASSERT(vec.size() == 3);
+ ASSERT(vec[0] == 0);
+ ASSERT(vec[1] == 255);
+ ASSERT(vec[2] == 65536);
+
+ vec.clear();
+ }
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open("vector-test.dat");
+ vec.read(reader);
+ }
+
+ ASSERT(vec.value_size() == 17);
+ ASSERT(vec.mask() == 0x1FFFF);
+ ASSERT(vec.size() == 3);
+ ASSERT(vec[0] == 0);
+ ASSERT(vec[1] == 255);
+ ASSERT(vec[2] == 65536);
+
+ values.clear();
+ for (std::size_t i = 0; i < 10000; ++i) {
+ values.push_back(static_cast<marisa::UInt32>(std::rand()));
+ }
+ vec.build(values);
+
+ ASSERT(vec.size() == values.size());
+ for (std::size_t i = 0; i < vec.size(); ++i) {
+ ASSERT(vec[i] == values[i]);
+ }
+
+ TEST_END();
+}
+
+void TestBitVector(std::size_t size) {
+ marisa::grimoire::BitVector bv;
+
+ ASSERT(bv.size() == 0);
+ ASSERT(bv.empty());
+ ASSERT(bv.total_size() == 0);
+ ASSERT(bv.io_size() == sizeof(marisa::UInt64) * 5);
+
+ std::vector<bool> bits(size);
+ std::vector<std::size_t> zeros, ones;
+ for (std::size_t i = 0; i < size; ++i) {
+ const bool bit = (std::rand() % 2) == 0;
+ bits[i] = bit;
+ bv.push_back(bit);
+ (bit ? ones : zeros).push_back(i);
+ ASSERT(bv[i] == bits[i]);
+ }
+
+ ASSERT(bv.size() == bits.size());
+ ASSERT((size == 0) || !bv.empty());
+
+ bv.build(true, true);
+
+ std::size_t num_zeros = 0, num_ones = 0;
+ for (std::size_t i = 0; i < bits.size(); ++i) {
+ ASSERT(bv[i] == bits[i]);
+ ASSERT(bv.rank0(i) == num_zeros);
+ ASSERT(bv.rank1(i) == num_ones);
+ ++(bv[i] ? num_ones : num_zeros);
+ }
+ for (std::size_t i = 0; i < zeros.size(); ++i) {
+ ASSERT(bv.select0(i) == zeros[i]);
+ }
+ for (std::size_t i = 0; i < ones.size(); ++i) {
+ ASSERT(bv.select1(i) == ones[i]);
+ }
+ ASSERT(bv.num_0s() == num_zeros);
+ ASSERT(bv.num_1s() == num_ones);
+
+ std::stringstream stream;
+ {
+ marisa::grimoire::Writer writer;
+ writer.open(stream);
+ bv.write(writer);
+ }
+
+ bv.clear();
+
+ ASSERT(bv.size() == 0);
+ ASSERT(bv.empty());
+ ASSERT(bv.total_size() == 0);
+ ASSERT(bv.io_size() == sizeof(marisa::UInt64) * 5);
+
+ {
+ marisa::grimoire::Reader reader;
+ reader.open(stream);
+ bv.read(reader);
+ }
+
+ ASSERT(bv.size() == bits.size());
+
+ num_zeros = 0, num_ones = 0;
+ for (std::size_t i = 0; i < bits.size(); ++i) {
+ ASSERT(bv[i] == bits[i]);
+ ASSERT(bv.rank0(i) == num_zeros);
+ ASSERT(bv.rank1(i) == num_ones);
+ ++(bv[i] ? num_ones : num_zeros);
+ }
+ for (std::size_t i = 0; i < zeros.size(); ++i) {
+ ASSERT(bv.select0(i) == zeros[i]);
+ }
+ for (std::size_t i = 0; i < ones.size(); ++i) {
+ ASSERT(bv.select1(i) == ones[i]);
+ }
+ ASSERT(bv.num_0s() == num_zeros);
+ ASSERT(bv.num_1s() == num_ones);
+}
+
+void TestBitVector() {
+ TEST_START();
+
+ TestBitVector(0);
+ TestBitVector(1);
+ TestBitVector(511);
+ TestBitVector(512);
+ TestBitVector(513);
+
+ for (int i = 0; i < 100; ++i) {
+ TestBitVector(std::rand() % 4096);
+ }
+
+ TEST_END();
+}
+
+} // namespace
+
+int main() try {
+ std::srand((unsigned int)std::time(NULL));
+
+ TestPopCount();
+ TestPopCount();
+ TestRankIndex();
+
+ TestVector();
+ TestFlatVector();
+ TestBitVector();
+
+ return 0;
+} catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << std::endl;
+ throw;
+}
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 0000000..2da7f98
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,40 @@
+MY_INCLUDE = -I$(top_srcdir)/include -I$(top_srcdir)/lib
+MY_LIBS = $(top_srcdir)/lib/marisa/libmarisa.la libcmdopt.la
+
+AM_CXXFLAGS = -Wall -Weffc++ -Wextra -Wconversion $(MY_INCLUDE)
+
+noinst_LTLIBRARIES = libcmdopt.la
+
+libcmdopt_la_SOURCES = cmdopt.cc
+
+noinst_HEADERS = cmdopt.h
+
+bin_PROGRAMS = \
+ marisa-build \
+ marisa-lookup \
+ marisa-reverse-lookup \
+ marisa-common-prefix-search \
+ marisa-predictive-search \
+ marisa-dump \
+ marisa-benchmark
+
+marisa_build_SOURCES = marisa-build.cc
+marisa_build_LDADD = $(MY_LIBS)
+
+marisa_lookup_SOURCES = marisa-lookup.cc
+marisa_lookup_LDADD = $(MY_LIBS)
+
+marisa_reverse_lookup_SOURCES = marisa-reverse-lookup.cc
+marisa_reverse_lookup_LDADD = $(MY_LIBS)
+
+marisa_common_prefix_search_SOURCES = marisa-common-prefix-search.cc
+marisa_common_prefix_search_LDADD = $(MY_LIBS)
+
+marisa_predictive_search_SOURCES = marisa-predictive-search.cc
+marisa_predictive_search_LDADD = $(MY_LIBS)
+
+marisa_dump_SOURCES = marisa-dump.cc
+marisa_dump_LDADD = $(MY_LIBS)
+
+marisa_benchmark_SOURCES = marisa-benchmark.cc
+marisa_benchmark_LDADD = $(MY_LIBS)
diff --git a/tools/cmdopt.cc b/tools/cmdopt.cc
new file mode 100644
index 0000000..468d0fe
--- /dev/null
+++ b/tools/cmdopt.cc
@@ -0,0 +1,298 @@
+#include <stdio.h>
+
+#include "cmdopt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
+
+// Moves `optind' to the end and shifts other arguments.
+static void cmdopt_shift(cmdopt_t *h) {
+ int i;
+ char *tmp;
+
+ tmp = h->argv[h->optind];
+ for (i = h->optind; i < h->argc - 1; i++) {
+ h->argv[i] = h->argv[i + 1];
+ }
+ h->argv[i] = tmp;
+
+ h->nextchar = NULL;
+ h->optnum--;
+}
+
+// Moves to the next argument.
+static void cmdopt_next(cmdopt_t *h) {
+ h->optind++;
+ h->nextchar = NULL;
+}
+
+// Checks if the current argument is an option or not.
+static int cmdopt_check(cmdopt_t *h) {
+ int ret = 1;
+ const char *arg = h->argv[h->optind];
+
+ if (*arg++ != '-') {
+ return 0;
+ }
+
+ if (*arg == '-') {
+ arg++;
+ ret++;
+ }
+
+ return ret - (*arg == '\0');
+}
+
+// Gets an argument of the current option.
+static void cmdopt_getopt(cmdopt_t *h) {
+ // Moves to the next argument if the current argument has no more characters.
+ if (*h->nextchar == '\0') {
+ cmdopt_next(h);
+ h->nextchar = h->argv[h->optind];
+ }
+
+ // Checks whether the current option has an argument or not.
+ if (h->optind < h->optnum) {
+ h->optarg = h->nextchar;
+ cmdopt_next(h);
+ } else {
+ h->optarg = NULL;
+ }
+}
+
+// Searches an option.
+static int cmdopt_search(cmdopt_t *h) {
+ const char *ptr;
+
+ // Updates an option character.
+ h->optopt = *h->nextchar++;
+
+ for (ptr = h->optstring; *ptr != '\0'; ptr++) {
+ if (*ptr == h->optopt) {
+ // Gets an option argument if required.
+ if (ptr[1] == ':') {
+ cmdopt_getopt(h);
+
+ // Returns ':' if there is no argument.
+ if (h->optarg == NULL && ptr[2] != ':') {
+ return ':';
+ }
+ }
+ return h->optopt;
+ }
+ }
+
+ if (h->optopt == '-') {
+ cmdopt_next(h);
+ while (h->optind < h->optnum) {
+ cmdopt_shift(h);
+ }
+ return -1;
+ }
+
+ // Returns '?' if the option character is undefined.
+ return '?';
+}
+
+// Compares a long option with an argument and returns the length of the
+// matched prefix.
+static int cmdopt_match_len(const char *opt, const char *arg) {
+ int len = 0;
+
+ // Returns 0 if there is a mismatch.
+ while ((*arg != '\0') && (*arg != '=')) {
+ if (*arg++ != *opt++) {
+ return 0;
+ }
+ len++;
+ }
+
+ // Returns a negative value in case of a perfect match.
+ if ((*arg == '\0') || (*arg == '=')) {
+ return -len;
+ }
+
+ return len;
+}
+
+// Checks long options.
+static int cmdopt_match(cmdopt_t *h) {
+ int i, len;
+ int max = 0, max_optind = -1;
+
+ // Returns -1 if there are no long options.
+ if (h->longopts == NULL) {
+ return max_optind;
+ }
+
+ for (i = 0; h->longopts[i].name != NULL; i++) {
+ len = cmdopt_match_len(h->longopts[i].name, h->nextchar);
+ if (len < 0) {
+ // In case of a perfect match.
+ h->nextchar -= len;
+ return i;
+ } else if (len > max) {
+ // In case of a prefix match.
+ max = len;
+ max_optind = i;
+ } else if (len == max) {
+ // There are other candidates.
+ max_optind = -1;
+ }
+ }
+
+ // If there is no perfect match, adopts the longest one.
+ h->nextchar += max;
+ return max_optind;
+}
+
+// Gets an argument of a long option.
+static void cmdopt_getopt_long(cmdopt_t *h) {
+ if (*h->nextchar == '=') {
+ h->optarg = h->nextchar + 1;
+ cmdopt_next(h);
+ } else {
+ cmdopt_next(h);
+
+ // Checks whether there are more options or not.
+ if (h->optind < h->optnum) {
+ h->optarg = h->argv[h->optind];
+ cmdopt_next(h);
+ } else {
+ h->optarg = NULL;
+ }
+ }
+}
+
+// Searches long options.
+static int cmdopt_search_long(cmdopt_t *h) {
+ const cmdopt_option *option;
+
+ // Keeps the long option.
+ h->optlong = h->argv[h->optind];
+
+ // Gets the next option.
+ h->longindex = cmdopt_match(h);
+ if (h->longindex < 0) {
+ cmdopt_next(h);
+ return '?';
+ }
+
+ // Gets an argument if required.
+ option = h->longopts + h->longindex;
+ if (option->has_arg) {
+ cmdopt_getopt_long(h);
+
+ // Return ':' if there are no more arguments.
+ if (h->optarg == NULL) {
+ return ':';
+ }
+ } else if (*h->nextchar == '=') {
+ // Returns '?' for an extra option argument.
+ cmdopt_getopt_long(h);
+ return '?';
+ }
+
+ // Overwrites a variable if specified in settings.
+ if (option->flag != NULL) {
+ *option->flag = option->val;
+ return 0;
+ }
+
+ return option->val;
+}
+
+// Analyze command line option.
+static int cmdopt_main(cmdopt_t *h) {
+ int type;
+
+ // Initializes the internal state.
+ h->optopt = 0;
+ h->optlong = NULL;
+ h->optarg = NULL;
+ h->longindex = 0;
+
+ while (h->optind < h->optnum) {
+ if (h->nextchar == NULL) {
+ // Checks whether the next argument is an option or not.
+ type = cmdopt_check(h);
+ if (type == 0) {
+ cmdopt_shift(h);
+ } else {
+ h->nextchar = h->argv[h->optind] + type;
+ if (type == 2) {
+ return cmdopt_search_long(h);
+ }
+ }
+ } else {
+ if (*h->nextchar == '\0') {
+ cmdopt_next(h);
+ continue;
+ }
+ // Searches an option string.
+ return cmdopt_search(h);
+ }
+ }
+
+ return -1;
+}
+
+// cmdopt_init() initializes a cmdopt_t for successive cmdopt_get()s.
+void cmdopt_init(cmdopt_t *h, int argc, char **argv,
+ const char *optstring, const cmdopt_option *longopts) {
+ static const char empty_optstring[] = "";
+
+ h->argc = argc;
+ h->argv = argv;
+ h->optnum = h->argc;
+
+ h->longopts = longopts;
+ h->optstring = (optstring != NULL) ? optstring : empty_optstring;
+
+ h->optind = 1;
+ h->nextchar = NULL;
+ h->optarg = NULL;
+ h->optopt = 0;
+ h->optlong = NULL;
+ h->opterr = 1;
+ h->longindex = 0;
+}
+
+// cmdopt_get() analyzes command line arguments and gets the next option.
+int cmdopt_get(cmdopt_t *h) {
+ int value = cmdopt_main(h);
+
+ // Prints a warning to the standard error stream if enabled.
+ if (h->opterr) {
+ if (value == ':') {
+ // Warning for a lack of an option argument.
+ if (h->optlong == NULL) {
+ fprintf(stderr, "option requires an argument -- %c\n", h->optopt);
+ } else {
+ fprintf(stderr, "option `--%s' requires an argument\n",
+ h->longopts[h->longindex].name);
+ }
+ } else if (value == '?') {
+ // Warning for an invalid option.
+ if (h->optlong == NULL) {
+ fprintf(stderr, "invalid option -- %c\n", h->optopt);
+ } else {
+ fprintf(stderr, "unrecognized option `%s'\n", h->optlong);
+ }
+ } else if ((value != -1) && (h->opterr == 2)) {
+ // Actually this is not for warning, but for debugging.
+ if (h->optlong == NULL) {
+ fprintf(stderr, "option with `%s' -- %c\n", h->optarg, h->optopt);
+ } else {
+ fprintf(stderr, "option `--%s' with `%s'\n",
+ h->longopts[h->longindex].name, h->optarg);
+ }
+ }
+ }
+ return value;
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif // __cplusplus
diff --git a/tools/cmdopt.h b/tools/cmdopt.h
new file mode 100644
index 0000000..1c611d6
--- /dev/null
+++ b/tools/cmdopt.h
@@ -0,0 +1,58 @@
+#ifndef MARISA_CMDOPT_H_
+#define MARISA_CMDOPT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct cmdopt_option_ {
+ // `name' specifies the name of this option.
+ // An array of options must be terminated with an option whose name == NULL.
+ const char *name;
+
+ // `has_name' specifies whether an option takes an argument or not.
+ // 0 specifies that this option does not have any argument.
+ // 1 specifies that this option has an argument.
+ // 2 specifies that this option may have an argument.
+ int has_arg;
+
+ // `flag' specifies an integer variable which is overwritten by cmdopt_next()
+ // with its return value.
+ int *flag;
+
+ // `val' specifies a return value of cmdopt_next(). This value is returned
+ // when cmdopt_next() finds this option.
+ int val;
+} cmdopt_option;
+
+typedef struct cmdopt_t_ {
+ // Command line arguments.
+ int argc;
+ char **argv;
+
+ // Option settings.
+ const cmdopt_option *longopts;
+ const char *optstring;
+
+ int optind; // Index of the next argument.
+ char *nextchar; // Next character.
+ char *optarg; // Argument of the last option.
+ int optopt; // Label of the last option.
+ char *optlong; // Long option.
+ int opterr; // Warning level (0: nothing, 1: warning, 2: all).
+ int longindex; // Index of the last long option.
+ int optnum; // Number of options.
+} cmdopt_t;
+
+// cmdopt_init() initializes a cmdopt_t for successive cmdopt_next()s.
+void cmdopt_init(cmdopt_t *h, int argc, char **argv,
+ const char *optstring, const cmdopt_option *longopts);
+
+// cmdopt_get() analyzes command line arguments and gets the next option.
+int cmdopt_get(cmdopt_t *h);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // MARISA_CMDOPT_H_
diff --git a/tools/marisa-benchmark.cc b/tools/marisa-benchmark.cc
new file mode 100644
index 0000000..122073c
--- /dev/null
+++ b/tools/marisa-benchmark.cc
@@ -0,0 +1,420 @@
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+#include <fstream>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+int param_min_num_tries = 1;
+int param_max_num_tries = 5;
+marisa::TailMode param_tail_mode = MARISA_DEFAULT_TAIL;
+marisa::NodeOrder param_node_order = MARISA_DEFAULT_ORDER;
+marisa::CacheLevel param_cache_level = MARISA_DEFAULT_CACHE;
+bool param_with_predict = true;
+bool param_print_speed = true;
+
+class Clock {
+ public:
+ Clock() : cl_(std::clock()) {}
+
+ void reset() {
+ cl_ = std::clock();
+ }
+
+ double elasped() const {
+ std::clock_t cur = std::clock();
+ return static_cast<double>(cur - cl_) / static_cast<double>(CLOCKS_PER_SEC);
+ }
+
+ private:
+ std::clock_t cl_;
+};
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... [FILE]...\n\n"
+ "Options:\n"
+ " -N, --min-num-tries=[N] limit the number of tries"
+ " [" << MARISA_MIN_NUM_TRIES << ", " << MARISA_MAX_NUM_TRIES
+ << "] (default: 1)\n"
+ " -n, --max-num-tries=[N] limit the number of tries"
+ " [" << MARISA_MIN_NUM_TRIES << ", " << MARISA_MAX_NUM_TRIES
+ << "] (default: 5)\n"
+ " -t, --text-tail build a dictionary with text TAIL (default)\n"
+ " -b, --binary-tail build a dictionary with binary TAIL\n"
+ " -w, --weight-order arrange siblings in weight order (default)\n"
+ " -l, --label-order arrange siblings in label order\n"
+ " -c, --cache-level=[N] specify the cache size"
+ " [1, 5] (default: 3)\n"
+ " -P, --with-predict include predictive search (default)\n"
+ " -p, --without-predict skip predictive search\n"
+ " -S, --print-speed print speed [1000 keys/s] (default)\n"
+ " -s, --print-time print time [ns/key]\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+void print_config() {
+ std::cout << "Number of tries: " << param_min_num_tries
+ << " - " << param_max_num_tries << std::endl;
+
+ std::cout << "TAIL mode: ";
+ switch (param_tail_mode) {
+ case MARISA_TEXT_TAIL: {
+ std::cout << "Text mode" << std::endl;
+ break;
+ }
+ case MARISA_BINARY_TAIL: {
+ std::cout << "Binary mode" << std::endl;
+ break;
+ }
+ }
+
+ std::cout << "Node order: ";
+ switch (param_node_order) {
+ case MARISA_LABEL_ORDER: {
+ std::cout << "Ascending label order" << std::endl;
+ break;
+ }
+ case MARISA_WEIGHT_ORDER: {
+ std::cout << "Descending weight order" << std::endl;
+ break;
+ }
+ }
+
+ std::cout << "Cache level: ";
+ switch (param_cache_level) {
+ case MARISA_HUGE_CACHE: {
+ std::cout << "Huge cache" << std::endl;
+ break;
+ }
+ case MARISA_LARGE_CACHE: {
+ std::cout << "Large cache" << std::endl;
+ break;
+ }
+ case MARISA_NORMAL_CACHE: {
+ std::cout << "Normal cache" << std::endl;
+ break;
+ }
+ case MARISA_SMALL_CACHE: {
+ std::cout << "Small cache" << std::endl;
+ break;
+ }
+ case MARISA_TINY_CACHE: {
+ std::cout << "Tiny cache" << std::endl;
+ break;
+ }
+ }
+}
+
+void print_time_info(std::size_t num_keys, double elasped) {
+ if (param_print_speed) {
+ if (elasped == 0.0) {
+ std::printf(" %8s", "-");
+ } else {
+ std::printf(" %8.2f", static_cast<double>(num_keys) / elasped / 1000.0);
+ }
+ } else {
+ if ((elasped == 0.0) || (num_keys == 0)) {
+ std::printf(" %8s", "-");
+ } else {
+ std::printf(" %8.1f",
+ 1000000000.0 * elasped / static_cast<double>(num_keys));
+ }
+ }
+}
+
+void read_keys(std::istream &input, marisa::Keyset *keyset,
+ std::vector<float> *weights) {
+ std::string line;
+ while (std::getline(input, line)) {
+ const std::string::size_type delim_pos = line.find_last_of('\t');
+ float weight = 1.0F;
+ if (delim_pos != line.npos) {
+ char *end_of_value;
+ weight = (float)std::strtod(&line[delim_pos + 1], &end_of_value);
+ if (*end_of_value == '\0') {
+ line.resize(delim_pos);
+ }
+ }
+ keyset->push_back(line.c_str(), line.length());
+ weights->push_back(weight);
+ }
+}
+
+int read_keys(const char * const *args, std::size_t num_args,
+ marisa::Keyset *keyset, std::vector<float> *weights) {
+ if (num_args == 0) {
+ read_keys(std::cin, keyset, weights);
+ }
+ for (std::size_t i = 0; i < num_args; ++i) {
+ std::ifstream input_file(args[i], std::ios::binary);
+ if (!input_file) {
+ std::cerr << "error: failed to open: " << args[i] << std::endl;
+ return 10;
+ }
+ read_keys(input_file, keyset, weights);
+ }
+ std::cout << "Number of keys: " << keyset->size() << std::endl;
+ std::cout << "Total length: " << keyset->total_length() << std::endl;
+ return 0;
+}
+
+void benchmark_build(marisa::Keyset &keyset,
+ const std::vector<float> &weights, int num_tries, marisa::Trie *trie) {
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ keyset[i].set_weight(weights[i]);
+ }
+ Clock cl;
+ trie->build(keyset, num_tries | param_tail_mode | param_node_order |
+ param_cache_level);
+ std::printf(" %10lu", (unsigned long)trie->io_size());
+ print_time_info(keyset.size(), cl.elasped());
+}
+
+void benchmark_lookup(const marisa::Trie &trie,
+ const marisa::Keyset &keyset) {
+ Clock cl;
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ if (!trie.lookup(agent) || (agent.key().id() != keyset[i].id())) {
+ std::cerr << "error: lookup() failed" << std::endl;
+ return;
+ }
+ }
+ print_time_info(keyset.size(), cl.elasped());
+}
+
+void benchmark_reverse_lookup(const marisa::Trie &trie,
+ const marisa::Keyset &keyset) {
+ Clock cl;
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].id());
+ trie.reverse_lookup(agent);
+ if ((agent.key().id() != keyset[i].id()) ||
+ (agent.key().length() != keyset[i].length()) ||
+ (std::memcmp(agent.key().ptr(), keyset[i].ptr(),
+ agent.key().length()) != 0)) {
+ std::cerr << "error: reverse_lookup() failed" << std::endl;
+ return;
+ }
+ }
+ print_time_info(keyset.size(), cl.elasped());
+}
+
+void benchmark_common_prefix_search(const marisa::Trie &trie,
+ const marisa::Keyset &keyset) {
+ Clock cl;
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ while (trie.common_prefix_search(agent)) {
+ if (agent.key().id() > keyset[i].id()) {
+ std::cerr << "error: common_prefix_search() failed" << std::endl;
+ return;
+ }
+ }
+ if (agent.key().id() != keyset[i].id()) {
+ std::cerr << "error: common_prefix_search() failed" << std::endl;
+ return;
+ }
+ }
+ print_time_info(keyset.size(), cl.elasped());
+}
+
+void benchmark_predictive_search(const marisa::Trie &trie,
+ const marisa::Keyset &keyset) {
+ if (!param_with_predict) {
+ print_time_info(keyset.size(), 0.0);
+ return;
+ }
+
+ Clock cl;
+ marisa::Agent agent;
+ for (std::size_t i = 0; i < keyset.size(); ++i) {
+ agent.set_query(keyset[i].ptr(), keyset[i].length());
+ if (!trie.predictive_search(agent) ||
+ (agent.key().id() != keyset[i].id())) {
+ std::cerr << "error: predictive_search() failed" << std::endl;
+ return;
+ }
+ while (trie.predictive_search(agent)) {
+ if (agent.key().id() <= keyset[i].id()) {
+ std::cerr << "error: predictive_search() failed" << std::endl;
+ return;
+ }
+ }
+ }
+ print_time_info(keyset.size(), cl.elasped());
+}
+
+void benchmark(marisa::Keyset &keyset, const std::vector<float> &weights,
+ int num_tries) {
+ std::printf("%6d", num_tries);
+ marisa::Trie trie;
+ benchmark_build(keyset, weights, num_tries, &trie);
+ if (!trie.empty()) {
+ benchmark_lookup(trie, keyset);
+ benchmark_reverse_lookup(trie, keyset);
+ benchmark_common_prefix_search(trie, keyset);
+ benchmark_predictive_search(trie, keyset);
+ }
+ std::printf("\n");
+}
+
+int benchmark(const char * const *args, std::size_t num_args) try {
+ marisa::Keyset keyset;
+ std::vector<float> weights;
+ const int ret = read_keys(args, num_args, &keyset, &weights);
+ if (ret != 0) {
+ return ret;
+ }
+ std::printf("------+----------+--------+--------+"
+ "--------+--------+--------\n");
+ std::printf("%6s %10s %8s %8s %8s %8s %8s\n",
+ "#tries", "size", "build", "lookup", "reverse", "prefix", "predict");
+ std::printf("%6s %10s %8s %8s %8s %8s %8s\n",
+ "", "", "", "", "lookup", "search", "search");
+ if (param_print_speed) {
+ std::printf("%6s %10s %8s %8s %8s %8s %8s\n",
+ "", "[bytes]",
+ "[K/s]", "[K/s]", "[K/s]", "[K/s]", "[K/s]");
+ } else {
+ std::printf("%6s %10s %8s %8s %8s %8s %8s\n",
+ "", "[bytes]", "[ns]", "[ns]", "[ns]", "[ns]", "[ns]");
+ }
+ std::printf("------+----------+--------+--------+"
+ "--------+--------+--------\n");
+ for (int i = param_min_num_tries; i <= param_max_num_tries; ++i) {
+ benchmark(keyset, weights, i);
+ }
+ std::printf("------+----------+--------+--------+"
+ "--------+--------+--------\n");
+ return 0;
+} catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << std::endl;
+ return -1;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "min-num-tries", 1, NULL, 'N' },
+ { "max-num-tries", 1, NULL, 'n' },
+ { "text-tail", 0, NULL, 't' },
+ { "binary-tail", 0, NULL, 'b' },
+ { "weight-order", 0, NULL, 'w' },
+ { "label-order", 0, NULL, 'l' },
+ { "cache-level", 1, NULL, 'c' },
+ { "predict-on", 0, NULL, 'P' },
+ { "predict-off", 0, NULL, 'p' },
+ { "print-speed", 0, NULL, 'S' },
+ { "print-time", 0, NULL, 's' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "N:n:tbwlc:PpSsh", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'N': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value <= 0) ||
+ (value > MARISA_MAX_NUM_TRIES)) {
+ std::cerr << "error: option `-n' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ return 1;
+ }
+ param_min_num_tries = (int)value;
+ break;
+ }
+ case 'n': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value <= 0) ||
+ (value > MARISA_MAX_NUM_TRIES)) {
+ std::cerr << "error: option `-n' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ return 2;
+ }
+ param_max_num_tries = (int)value;
+ break;
+ }
+ case 't': {
+ param_tail_mode = MARISA_TEXT_TAIL;
+ break;
+ }
+ case 'b': {
+ param_tail_mode = MARISA_BINARY_TAIL;
+ break;
+ }
+ case 'w': {
+ param_node_order = MARISA_WEIGHT_ORDER;
+ break;
+ }
+ case 'l': {
+ param_node_order = MARISA_LABEL_ORDER;
+ break;
+ }
+ case 'c': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value < 1) || (value > 5)) {
+ std::cerr << "error: option `-c' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ return 3;
+ } else if (value == 1) {
+ param_cache_level = MARISA_TINY_CACHE;
+ } else if (value == 2) {
+ param_cache_level = MARISA_SMALL_CACHE;
+ } else if (value == 3) {
+ param_cache_level = MARISA_NORMAL_CACHE;
+ } else if (value == 4) {
+ param_cache_level = MARISA_LARGE_CACHE;
+ } else if (value == 5) {
+ param_cache_level = MARISA_HUGE_CACHE;
+ }
+ break;
+ }
+ case 'P': {
+ param_with_predict = true;
+ break;
+ }
+ case 'p': {
+ param_with_predict = false;
+ break;
+ }
+ case 'S': {
+ param_print_speed = true;
+ break;
+ }
+ case 's': {
+ param_print_speed = false;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ print_config();
+ return benchmark(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/tools/marisa-build.cc b/tools/marisa-build.cc
new file mode 100644
index 0000000..bffddb1
--- /dev/null
+++ b/tools/marisa-build.cc
@@ -0,0 +1,207 @@
+#ifdef _WIN32
+ #include <fcntl.h>
+ #include <io.h>
+ #include <stdio.h>
+#endif // _WIN32
+
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <string>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+int param_num_tries = MARISA_DEFAULT_NUM_TRIES;
+marisa::TailMode param_tail_mode = MARISA_DEFAULT_TAIL;
+marisa::NodeOrder param_node_order = MARISA_DEFAULT_ORDER;
+marisa::CacheLevel param_cache_level = MARISA_DEFAULT_CACHE;
+const char *output_filename = NULL;
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... [FILE]...\n\n"
+ "Options:\n"
+ " -n, --num-tries=[N] limit the number of tries"
+ " [" << MARISA_MIN_NUM_TRIES << ", " << MARISA_MAX_NUM_TRIES
+ << "] (default: 3)\n"
+ " -t, --text-tail build a dictionary with text TAIL (default)\n"
+ " -b, --binary-tail build a dictionary with binary TAIL\n"
+ " -w, --weight-order arrange siblings in weight order (default)\n"
+ " -l, --label-order arrange siblings in label order\n"
+ " -c, --cache-level=[N] specify the cache size"
+ " [1, 5] (default: 3)\n"
+ " -o, --output=[FILE] write tries to FILE (default: stdout)\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+void read_keys(std::istream &input, marisa::Keyset *keyset) {
+ std::string line;
+ while (std::getline(input, line)) {
+ const std::string::size_type delim_pos = line.find_last_of('\t');
+ float weight = 1.0F;
+ if (delim_pos != line.npos) {
+ char *end_of_value;
+ weight = (float)std::strtod(&line[delim_pos + 1], &end_of_value);
+ if (*end_of_value == '\0') {
+ line.resize(delim_pos);
+ }
+ }
+ keyset->push_back(line.c_str(), line.length(), weight);
+ }
+}
+
+int build(const char * const *args, std::size_t num_args) {
+ marisa::Keyset keyset;
+ if (num_args == 0) try {
+ read_keys(std::cin, &keyset);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to read keys" << std::endl;
+ return 10;
+ }
+
+ for (std::size_t i = 0; i < num_args; ++i) try {
+ std::ifstream input_file(args[i], std::ios::binary);
+ if (!input_file) {
+ std::cerr << "error: failed to open: " << args[i] << std::endl;
+ return 11;
+ }
+ read_keys(input_file, &keyset);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to read keys" << std::endl;
+ return 12;
+ }
+
+ marisa::Trie trie;
+ try {
+ trie.build(keyset, param_num_tries | param_tail_mode | param_node_order |
+ param_cache_level);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to build a dictionary" << std::endl;
+ return 20;
+ }
+
+ std::cerr << "#keys: " << trie.num_keys() << std::endl;
+ std::cerr << "#nodes: " << trie.num_nodes() << std::endl;
+ std::cerr << "size: " << trie.io_size() << std::endl;
+
+ if (output_filename != NULL) {
+ try {
+ trie.save(output_filename);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to write a dictionary to file: "
+ << output_filename << std::endl;
+ return 30;
+ }
+ } else {
+#ifdef _WIN32
+ const int stdout_fileno = ::_fileno(stdout);
+ if (stdout_fileno < 0) {
+ std::cerr << "error: failed to get the file descriptor of "
+ "standard output" << std::endl;
+ return 31;
+ }
+ if (::_setmode(stdout_fileno, _O_BINARY) == -1) {
+ std::cerr << "error: failed to set binary mode" << std::endl;
+ return 32;
+ }
+#endif // _WIN32
+ try {
+ std::cout << trie;
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what()
+ << ": failed to write a dictionary to standard output" << std::endl;
+ return 33;
+ }
+ }
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "max-num-tries", 1, NULL, 'n' },
+ { "text-tail", 0, NULL, 't' },
+ { "binary-tail", 0, NULL, 'b' },
+ { "weight-order", 0, NULL, 'w' },
+ { "label-order", 0, NULL, 'l' },
+ { "cache-level", 1, NULL, 'c' },
+ { "output", 1, NULL, 'o' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "n:tbwlc:o:h", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'n': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value <= 0) ||
+ (value > MARISA_MAX_NUM_TRIES)) {
+ std::cerr << "error: option `-n' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ return 1;
+ }
+ param_num_tries = (int)value;
+ break;
+ }
+ case 't': {
+ param_tail_mode = MARISA_TEXT_TAIL;
+ break;
+ }
+ case 'b': {
+ param_tail_mode = MARISA_BINARY_TAIL;
+ break;
+ }
+ case 'w': {
+ param_node_order = MARISA_WEIGHT_ORDER;
+ break;
+ }
+ case 'l': {
+ param_node_order = MARISA_LABEL_ORDER;
+ break;
+ }
+ case 'c': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value < 1) || (value > 5)) {
+ std::cerr << "error: option `-c' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ return 2;
+ } else if (value == 1) {
+ param_cache_level = MARISA_TINY_CACHE;
+ } else if (value == 2) {
+ param_cache_level = MARISA_SMALL_CACHE;
+ } else if (value == 3) {
+ param_cache_level = MARISA_NORMAL_CACHE;
+ } else if (value == 4) {
+ param_cache_level = MARISA_LARGE_CACHE;
+ } else if (value == 5) {
+ param_cache_level = MARISA_HUGE_CACHE;
+ }
+ break;
+ }
+ case 'o': {
+ output_filename = cmdopt.optarg;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ return build(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/tools/marisa-common-prefix-search.cc b/tools/marisa-common-prefix-search.cc
new file mode 100644
index 0000000..55a1f86
--- /dev/null
+++ b/tools/marisa-common-prefix-search.cc
@@ -0,0 +1,144 @@
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+std::size_t max_num_results = 10;
+bool mmap_flag = true;
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... DIC\n\n"
+ "Options:\n"
+ " -n, --max-num-results=[N] limit the number of results to N"
+ " (default: 10)\n"
+ " 0: no limit\n"
+ " -m, --mmap-dictionary use memory-mapped I/O to load a dictionary"
+ " (default)\n"
+ " -r, --read-dictionary read an entire dictionary into memory\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+int common_prefix_search(const char * const *args, std::size_t num_args) {
+ if (num_args == 0) {
+ std::cerr << "error: dictionary is not specified" << std::endl;
+ return 10;
+ } else if (num_args > 1) {
+ std::cerr << "error: more than one dictionaries are specified"
+ << std::endl;
+ return 11;
+ }
+
+ marisa::Trie trie;
+ if (mmap_flag) {
+ try {
+ trie.mmap(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to mmap a dictionary file: "
+ << args[0] << std::endl;
+ return 20;
+ }
+ } else {
+ try {
+ trie.load(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to load a dictionary file: "
+ << args[0] << std::endl;
+ return 21;
+ }
+ }
+
+ marisa::Agent agent;
+ marisa::Keyset keyset;
+ std::string str;
+ while (std::getline(std::cin, str)) {
+ try {
+ agent.set_query(str.c_str(), str.length());
+ while (trie.common_prefix_search(agent)) {
+ keyset.push_back(agent.key());
+ }
+ if (keyset.empty()) {
+ std::cout << "not found" << std::endl;
+ } else {
+ std::cout << keyset.size() << " found" << std::endl;
+ const std::size_t end = std::min(max_num_results, keyset.size());
+ for (std::size_t i = 0; i < end; ++i) {
+ std::cout << keyset[i].id() << '\t';
+ std::cout.write(keyset[i].ptr(),
+ static_cast<std::streamsize>(keyset[i].length())) << '\t';
+ std::cout << str << '\n';
+ }
+ }
+ keyset.reset();
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": common_prefix_search() failed: "
+ << str << std::endl;
+ return 30;
+ }
+
+ if (!std::cout) {
+ std::cerr << "error: failed to write results to standard output"
+ << std::endl;
+ return 31;
+ }
+ }
+
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "max-num-results", 1, NULL, 'n' },
+ { "mmap-dictionary", 0, NULL, 'm' },
+ { "read-dictionary", 0, NULL, 'r' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "n:mrh", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'n': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value < 0)) {
+ std::cerr << "error: option `-n' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ }
+ if ((value == 0) || ((unsigned long long)value > MARISA_SIZE_MAX)) {
+ max_num_results = MARISA_SIZE_MAX;
+ } else {
+ max_num_results = (std::size_t)value;
+ }
+ break;
+ }
+ case 'm': {
+ mmap_flag = true;
+ break;
+ }
+ case 'r': {
+ mmap_flag = false;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ return common_prefix_search(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/tools/marisa-dump.cc b/tools/marisa-dump.cc
new file mode 100644
index 0000000..1b086d8
--- /dev/null
+++ b/tools/marisa-dump.cc
@@ -0,0 +1,153 @@
+#ifdef _WIN32
+ #include <fcntl.h>
+ #include <io.h>
+ #include <stdio.h>
+#endif // _WIN32
+
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+const char *delimiter = "\n";
+bool mmap_flag = true;
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... DIC...\n\n"
+ "Options:\n"
+ " -d, --delimiter=[S] specify the delimier (default: \"\\n\")\n"
+ " -m, --mmap-dictionary use memory-mapped I/O to load a dictionary"
+ " (default)\n"
+ " -r, --read-dictionary read an entire dictionary into memory\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+int dump(const marisa::Trie &trie) {
+ std::size_t num_keys = 0;
+ marisa::Agent agent;
+ agent.set_query("");
+ try {
+ while (trie.predictive_search(agent)) {
+ std::cout.write(agent.key().ptr(),
+ static_cast<std::streamsize>(agent.key().length())) << delimiter;
+ if (!std::cout) {
+ std::cerr << "error: failed to write results to standard output"
+ << std::endl;
+ return 20;
+ }
+ ++num_keys;
+ }
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": predictive_search() failed" << std::endl;
+ return 21;
+ }
+ std::cerr << "#keys: " << num_keys << std::endl;
+ return 0;
+}
+
+int dump(const char *filename) {
+ marisa::Trie trie;
+ if (filename != NULL) {
+ std::cerr << "input: " << filename << std::endl;
+ if (mmap_flag) {
+ try {
+ trie.mmap(filename);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to mmap a dictionary file: "
+ << filename << std::endl;
+ return 10;
+ }
+ } else {
+ try {
+ trie.load(filename);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to load a dictionary file: "
+ << filename << std::endl;
+ return 11;
+ }
+ }
+ } else {
+ std::cerr << "input: <stdin>" << std::endl;
+#ifdef _WIN32
+ const int stdin_fileno = ::_fileno(stdin);
+ if (stdin_fileno < 0) {
+ std::cerr << "error: failed to get the file descriptor of "
+ "standard input" << std::endl;
+ return 20;
+ }
+ if (::_setmode(stdin_fileno, _O_BINARY) == -1) {
+ std::cerr << "error: failed to set binary mode" << std::endl;
+ return 21;
+ }
+#endif // _WIN32
+ try {
+ std::cin >> trie;
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what()
+ << ": failed to read a dictionary from standard input" << std::endl;
+ return 22;
+ }
+ }
+ return dump(trie);
+}
+
+int dump(const char * const *args, std::size_t num_args) {
+ if (num_args == 0) {
+ return dump(NULL);
+ }
+ for (std::size_t i = 0; i < num_args; ++i) {
+ const int result = dump(args[i]);
+ if (result != 0) {
+ return result;
+ }
+ }
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "delimiter", 1, NULL, 'd' },
+ { "mmap-dictionary", 0, NULL, 'm' },
+ { "read-dictionary", 0, NULL, 'r' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "d:mrh", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'd': {
+ delimiter = cmdopt.optarg;
+ break;
+ }
+ case 'm': {
+ mmap_flag = true;
+ break;
+ }
+ case 'r': {
+ mmap_flag = false;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ return dump(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/tools/marisa-lookup.cc b/tools/marisa-lookup.cc
new file mode 100644
index 0000000..f9f2466
--- /dev/null
+++ b/tools/marisa-lookup.cc
@@ -0,0 +1,111 @@
+#include <iostream>
+#include <string>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+bool mmap_flag = true;
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... DIC\n\n"
+ "Options:\n"
+ " -m, --mmap-dictionary use memory-mapped I/O to load a dictionary"
+ " (default)\n"
+ " -r, --read-dictionary read an entire dictionary into memory\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+int lookup(const char * const *args, std::size_t num_args) {
+ if (num_args == 0) {
+ std::cerr << "error: dictionary is not specified" << std::endl;
+ return 10;
+ } else if (num_args > 1) {
+ std::cerr << "error: more than one dictionaries are specified"
+ << std::endl;
+ return 11;
+ }
+
+ marisa::Trie trie;
+ if (mmap_flag) {
+ try {
+ trie.mmap(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to mmap a dictionary file: "
+ << args[0] << std::endl;
+ return 20;
+ }
+ } else {
+ try {
+ trie.load(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to load a dictionary file: "
+ << args[0] << std::endl;
+ return 21;
+ }
+ }
+
+ marisa::Agent agent;
+ std::string str;
+ while (std::getline(std::cin, str)) {
+ try {
+ agent.set_query(str.c_str(), str.length());
+ if (trie.lookup(agent)) {
+ std::cout << agent.key().id() << '\t' << str << '\n';
+ } else {
+ std::cout << "-1\t" << str << '\n';
+ }
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": lookup() failed: " << str << std::endl;
+ return 30;
+ }
+
+ if (!std::cout) {
+ std::cerr << "error: failed to write results to standard output"
+ << std::endl;
+ return 30;
+ }
+ }
+
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "mmap-dictionary", 0, NULL, 'm' },
+ { "read-dictionary", 0, NULL, 'r' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "mrh", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'm': {
+ mmap_flag = true;
+ break;
+ }
+ case 'r': {
+ mmap_flag = false;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ return lookup(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/tools/marisa-predictive-search.cc b/tools/marisa-predictive-search.cc
new file mode 100644
index 0000000..af5069d
--- /dev/null
+++ b/tools/marisa-predictive-search.cc
@@ -0,0 +1,144 @@
+#include <cstdlib>
+#include <iostream>
+#include <string>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+std::size_t max_num_results = 10;
+bool mmap_flag = true;
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... DIC\n\n"
+ "Options:\n"
+ " -n, --max-num-results=[N] limit the number of outputs to N"
+ " (default: 10)\n"
+ " 0: no limit\n"
+ " -m, --mmap-dictionary use memory-mapped I/O to load a dictionary"
+ " (default)\n"
+ " -r, --read-dictionary read an entire dictionary into memory\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+int predictive_search(const char * const *args, std::size_t num_args) {
+ if (num_args == 0) {
+ std::cerr << "error: dictionary is not specified" << std::endl;
+ return 10;
+ } else if (num_args > 1) {
+ std::cerr << "error: more than one dictionaries are specified"
+ << std::endl;
+ return 11;
+ }
+
+ marisa::Trie trie;
+ if (mmap_flag) {
+ try {
+ trie.mmap(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to mmap a dictionary file: "
+ << args[0] << std::endl;
+ return 20;
+ }
+ } else {
+ try {
+ trie.load(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to load a dictionary file: "
+ << args[0] << std::endl;
+ return 21;
+ }
+ }
+
+ marisa::Agent agent;
+ marisa::Keyset keyset;
+ std::string str;
+ while (std::getline(std::cin, str)) {
+ try {
+ agent.set_query(str.c_str(), str.length());
+ while (trie.predictive_search(agent)) {
+ keyset.push_back(agent.key());
+ }
+ if (keyset.empty()) {
+ std::cout << "not found" << std::endl;
+ } else {
+ std::cout << keyset.size() << " found" << std::endl;
+ const std::size_t end = std::min(max_num_results, keyset.size());
+ for (std::size_t i = 0; i < end; ++i) {
+ std::cout << keyset[i].id() << '\t';
+ std::cout.write(keyset[i].ptr(),
+ static_cast<std::streamsize>(keyset[i].length())) << '\t';
+ std::cout << str << '\n';
+ }
+ }
+ keyset.reset();
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": predictive_search() failed: "
+ << str << std::endl;
+ return 30;
+ }
+
+ if (!std::cout) {
+ std::cerr << "error: failed to write results to standard output"
+ << std::endl;
+ return 31;
+ }
+ }
+
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "max-num-results", 1, NULL, 'n' },
+ { "mmap-dictionary", 0, NULL, 'm' },
+ { "read-dictionary", 0, NULL, 'r' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "n:mrh", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'n': {
+ char *end_of_value;
+ const long value = std::strtol(cmdopt.optarg, &end_of_value, 10);
+ if ((*end_of_value != '\0') || (value < 0)) {
+ std::cerr << "error: option `-n' with an invalid argument: "
+ << cmdopt.optarg << std::endl;
+ }
+ if ((value == 0) || ((unsigned long long)value > MARISA_SIZE_MAX)) {
+ max_num_results = MARISA_SIZE_MAX;
+ } else {
+ max_num_results = (std::size_t)value;
+ }
+ break;
+ }
+ case 'm': {
+ mmap_flag = true;
+ break;
+ }
+ case 'r': {
+ mmap_flag = false;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ return predictive_search(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/tools/marisa-reverse-lookup.cc b/tools/marisa-reverse-lookup.cc
new file mode 100644
index 0000000..c101a97
--- /dev/null
+++ b/tools/marisa-reverse-lookup.cc
@@ -0,0 +1,111 @@
+#include <iostream>
+#include <string>
+
+#include <marisa.h>
+
+#include "cmdopt.h"
+
+namespace {
+
+bool mmap_flag = true;
+
+void print_help(const char *cmd) {
+ std::cerr << "Usage: " << cmd << " [OPTION]... DIC\n\n"
+ "Options:\n"
+ " -m, --mmap-dictionary use memory-mapped I/O to load a dictionary"
+ " (default)\n"
+ " -r, --read-dictionary read an entire dictionary into memory\n"
+ " -h, --help print this help\n"
+ << std::endl;
+}
+
+int reverse_lookup(const char * const *args, std::size_t num_args) {
+ if (num_args == 0) {
+ std::cerr << "error: dictionary is not specified" << std::endl;
+ return 10;
+ } else if (num_args > 1) {
+ std::cerr << "error: more than one dictionaries are specified"
+ << std::endl;
+ return 11;
+ }
+
+ marisa::Trie trie;
+ if (mmap_flag) {
+ try {
+ trie.mmap(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to mmap a dictionary file: "
+ << args[0] << std::endl;
+ return 20;
+ }
+ } else {
+ try {
+ trie.load(args[0]);
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": failed to load a dictionary file: "
+ << args[0] << std::endl;
+ return 21;
+ }
+ }
+
+ marisa::Agent agent;
+ std::size_t key_id;
+ while (std::cin >> key_id) {
+ try {
+ agent.set_query(key_id);
+ trie.reverse_lookup(agent);
+ std::cout << agent.key().id() << '\t';
+ std::cout.write(agent.key().ptr(),
+ static_cast<std::streamsize>(agent.key().length())) << '\n';
+ } catch (const marisa::Exception &ex) {
+ std::cerr << ex.what() << ": reverse_lookup() failed: "
+ << key_id << std::endl;
+ return 30;
+ }
+
+ if (!std::cout) {
+ std::cerr << "error: failed to write results to standard output"
+ << std::endl;
+ return 30;
+ }
+ }
+
+ return 0;
+}
+
+} // namespace
+
+int main(int argc, char *argv[]) {
+ std::ios::sync_with_stdio(false);
+
+ ::cmdopt_option long_options[] = {
+ { "mmap-dictionary", 0, NULL, 'm' },
+ { "read-dictionary", 0, NULL, 'r' },
+ { "help", 0, NULL, 'h' },
+ { NULL, 0, NULL, 0 }
+ };
+ ::cmdopt_t cmdopt;
+ ::cmdopt_init(&cmdopt, argc, argv, "mrh", long_options);
+ int label;
+ while ((label = ::cmdopt_get(&cmdopt)) != -1) {
+ switch (label) {
+ case 'm': {
+ mmap_flag = true;
+ break;
+ }
+ case 'r': {
+ mmap_flag = false;
+ break;
+ }
+ case 'h': {
+ print_help(argv[0]);
+ return 0;
+ }
+ default: {
+ return 1;
+ }
+ }
+ }
+ return reverse_lookup(cmdopt.argv + cmdopt.optind,
+ static_cast<std::size_t>(cmdopt.argc - cmdopt.optind));
+}
diff --git a/vs2008/base-test/base-test.vcproj b/vs2008/base-test/base-test.vcproj
new file mode 100644
index 0000000..f52f742
--- /dev/null
+++ b/vs2008/base-test/base-test.vcproj
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="base-test"
+ ProjectGUID="{27D9F340-49F7-4715-B77D-B44CE57B7CBD}"
+ RootNamespace="basetest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories=""
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\base-test.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tests\assert.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/io-test/io-test.vcproj b/vs2008/io-test/io-test.vcproj
new file mode 100644
index 0000000..70a07d2
--- /dev/null
+++ b/vs2008/io-test/io-test.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="io-test"
+ ProjectGUID="{24807515-7B42-4E76-B630-E82BDA83845C}"
+ RootNamespace="iotest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\io-test.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tests\assert.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/libmarisa/libmarisa.vcproj b/vs2008/libmarisa/libmarisa.vcproj
new file mode 100644
index 0000000..34c5d63
--- /dev/null
+++ b/vs2008/libmarisa/libmarisa.vcproj
@@ -0,0 +1,349 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="libmarisa"
+ ProjectGUID="{3BE97421-D962-4330-815B-AC9B7B799F15}"
+ RootNamespace="libmarisa"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MARISA_EXPORTS"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MARISA_EXPORTS"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\lib\marisa\agent.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector\bit-vector.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\keyset.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\louds-trie.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io\mapper.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io\reader.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\tail.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\trie.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io\writer.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\lib\marisa\agent.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\algorithm.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\base.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector\bit-vector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\cache.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\entry.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\exception.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector\flat-vector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\header.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\history.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\intrin.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\iostream.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\key.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\key.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\keyset.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\louds-trie.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io\mapper.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector\pop-count.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\query.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\range.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector\rank-index.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io\reader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\scoped-array.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\scoped-ptr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\algorithm\sort.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\state.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\stdio.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie\tail.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\trie.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\trie.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\vector\vector.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\lib\marisa\grimoire\io\writer.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-benchmark/marisa-benchmark.vcproj b/vs2008/marisa-benchmark/marisa-benchmark.vcproj
new file mode 100644
index 0000000..e825735
--- /dev/null
+++ b/vs2008/marisa-benchmark/marisa-benchmark.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-benchmark"
+ ProjectGUID="{85E7F33D-2053-47AD-AEA4-4DB8B754BCD7}"
+ RootNamespace="marisabenchmark"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-benchmark.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-build/marisa-build.vcproj b/vs2008/marisa-build/marisa-build.vcproj
new file mode 100644
index 0000000..3857c9c
--- /dev/null
+++ b/vs2008/marisa-build/marisa-build.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-build"
+ ProjectGUID="{104CFCC9-11DF-4894-894B-BFE5F5C13DCA}"
+ RootNamespace="marisabuild"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-build.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-common-prefix-search/marisa-common-prefix-search.vcproj b/vs2008/marisa-common-prefix-search/marisa-common-prefix-search.vcproj
new file mode 100644
index 0000000..ec2d829
--- /dev/null
+++ b/vs2008/marisa-common-prefix-search/marisa-common-prefix-search.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-common-prefix-search"
+ ProjectGUID="{C4C7BA27-B713-47C0-92B1-FF70EAC9A373}"
+ RootNamespace="marisacommonprefixsearch"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-common-prefix-search.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-dump/marisa-dump.vcproj b/vs2008/marisa-dump/marisa-dump.vcproj
new file mode 100644
index 0000000..9099746
--- /dev/null
+++ b/vs2008/marisa-dump/marisa-dump.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-dump"
+ ProjectGUID="{2B7CDB51-C796-4CD2-82ED-F782C7952204}"
+ RootNamespace="marisadump"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-dump.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-lookup/marisa-lookup.vcproj b/vs2008/marisa-lookup/marisa-lookup.vcproj
new file mode 100644
index 0000000..0bcaa9d
--- /dev/null
+++ b/vs2008/marisa-lookup/marisa-lookup.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-lookup"
+ ProjectGUID="{98C25734-1D4B-48A7-B8B2-D6559410FF3F}"
+ RootNamespace="marisalookup"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-lookup.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-predictive-search/marisa-predictive-search.vcproj b/vs2008/marisa-predictive-search/marisa-predictive-search.vcproj
new file mode 100644
index 0000000..fec7503
--- /dev/null
+++ b/vs2008/marisa-predictive-search/marisa-predictive-search.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-predictive-search"
+ ProjectGUID="{B4B56EF0-681D-4B32-AD14-F855D67CB01B}"
+ RootNamespace="marisapredictivesearch"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-predictive-search.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-reverse-lookup/marisa-reverse-lookup.vcproj b/vs2008/marisa-reverse-lookup/marisa-reverse-lookup.vcproj
new file mode 100644
index 0000000..e013bd9
--- /dev/null
+++ b/vs2008/marisa-reverse-lookup/marisa-reverse-lookup.vcproj
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-reverse-lookup"
+ ProjectGUID="{EC73A2FE-5D85-45C3-A223-37737C823476}"
+ RootNamespace="marisareverselookup"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.cc"
+ >
+ </File>
+ <File
+ RelativePath="..\..\tools\marisa-reverse-lookup.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tools\cmdopt.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/marisa-test/marisa-test.vcproj b/vs2008/marisa-test/marisa-test.vcproj
new file mode 100644
index 0000000..9d2f899
--- /dev/null
+++ b/vs2008/marisa-test/marisa-test.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="marisa-test"
+ ProjectGUID="{594A9352-4170-4F5D-AEB3-E6C96DA2E87F}"
+ RootNamespace="marisatest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\marisa-test.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tests\assert.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/trie-test/trie-test.vcproj b/vs2008/trie-test/trie-test.vcproj
new file mode 100644
index 0000000..7295779
--- /dev/null
+++ b/vs2008/trie-test/trie-test.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="trie-test"
+ ProjectGUID="{F1876AD7-43C2-4D95-BB45-E1EAED974C75}"
+ RootNamespace="trietest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\trie-test.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tests\assert.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/vector-test/vector-test.vcproj b/vs2008/vector-test/vector-test.vcproj
new file mode 100644
index 0000000..5762836
--- /dev/null
+++ b/vs2008/vector-test/vector-test.vcproj
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="shift_jis"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="vector-test"
+ ProjectGUID="{B20AE738-2F4F-4E96-A673-F5A02591D50E}"
+ RootNamespace="vectortest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="../../lib"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\tests\vector-test.cc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\tests\assert.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/vs2008/vs2008.sln b/vs2008/vs2008.sln
new file mode 100644
index 0000000..38c7113
--- /dev/null
+++ b/vs2008/vs2008.sln
@@ -0,0 +1,123 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-benchmark", "marisa-benchmark\marisa-benchmark.vcproj", "{85E7F33D-2053-47AD-AEA4-4DB8B754BCD7}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-build", "marisa-build\marisa-build.vcproj", "{104CFCC9-11DF-4894-894B-BFE5F5C13DCA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-lookup", "marisa-lookup\marisa-lookup.vcproj", "{98C25734-1D4B-48A7-B8B2-D6559410FF3F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "io-test", "io-test\io-test.vcproj", "{24807515-7B42-4E76-B630-E82BDA83845C}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "trie-test", "trie-test\trie-test.vcproj", "{F1876AD7-43C2-4D95-BB45-E1EAED974C75}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vector-test", "vector-test\vector-test.vcproj", "{B20AE738-2F4F-4E96-A673-F5A02591D50E}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-test", "marisa-test\marisa-test.vcproj", "{594A9352-4170-4F5D-AEB3-E6C96DA2E87F}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base-test", "base-test\base-test.vcproj", "{27D9F340-49F7-4715-B77D-B44CE57B7CBD}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-reverse-lookup", "marisa-reverse-lookup\marisa-reverse-lookup.vcproj", "{EC73A2FE-5D85-45C3-A223-37737C823476}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-common-prefix-search", "marisa-common-prefix-search\marisa-common-prefix-search.vcproj", "{C4C7BA27-B713-47C0-92B1-FF70EAC9A373}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-predictive-search", "marisa-predictive-search\marisa-predictive-search.vcproj", "{B4B56EF0-681D-4B32-AD14-F855D67CB01B}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmarisa", "libmarisa\libmarisa.vcproj", "{3BE97421-D962-4330-815B-AC9B7B799F15}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "marisa-dump", "marisa-dump\marisa-dump.vcproj", "{2B7CDB51-C796-4CD2-82ED-F782C7952204}"
+ ProjectSection(ProjectDependencies) = postProject
+ {3BE97421-D962-4330-815B-AC9B7B799F15} = {3BE97421-D962-4330-815B-AC9B7B799F15}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {85E7F33D-2053-47AD-AEA4-4DB8B754BCD7}.Debug|Win32.ActiveCfg = Debug|Win32
+ {85E7F33D-2053-47AD-AEA4-4DB8B754BCD7}.Debug|Win32.Build.0 = Debug|Win32
+ {85E7F33D-2053-47AD-AEA4-4DB8B754BCD7}.Release|Win32.ActiveCfg = Release|Win32
+ {85E7F33D-2053-47AD-AEA4-4DB8B754BCD7}.Release|Win32.Build.0 = Release|Win32
+ {104CFCC9-11DF-4894-894B-BFE5F5C13DCA}.Debug|Win32.ActiveCfg = Debug|Win32
+ {104CFCC9-11DF-4894-894B-BFE5F5C13DCA}.Debug|Win32.Build.0 = Debug|Win32
+ {104CFCC9-11DF-4894-894B-BFE5F5C13DCA}.Release|Win32.ActiveCfg = Release|Win32
+ {104CFCC9-11DF-4894-894B-BFE5F5C13DCA}.Release|Win32.Build.0 = Release|Win32
+ {98C25734-1D4B-48A7-B8B2-D6559410FF3F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {98C25734-1D4B-48A7-B8B2-D6559410FF3F}.Debug|Win32.Build.0 = Debug|Win32
+ {98C25734-1D4B-48A7-B8B2-D6559410FF3F}.Release|Win32.ActiveCfg = Release|Win32
+ {98C25734-1D4B-48A7-B8B2-D6559410FF3F}.Release|Win32.Build.0 = Release|Win32
+ {24807515-7B42-4E76-B630-E82BDA83845C}.Debug|Win32.ActiveCfg = Debug|Win32
+ {24807515-7B42-4E76-B630-E82BDA83845C}.Debug|Win32.Build.0 = Debug|Win32
+ {24807515-7B42-4E76-B630-E82BDA83845C}.Release|Win32.ActiveCfg = Release|Win32
+ {F1876AD7-43C2-4D95-BB45-E1EAED974C75}.Debug|Win32.ActiveCfg = Debug|Win32
+ {F1876AD7-43C2-4D95-BB45-E1EAED974C75}.Debug|Win32.Build.0 = Debug|Win32
+ {F1876AD7-43C2-4D95-BB45-E1EAED974C75}.Release|Win32.ActiveCfg = Release|Win32
+ {B20AE738-2F4F-4E96-A673-F5A02591D50E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B20AE738-2F4F-4E96-A673-F5A02591D50E}.Debug|Win32.Build.0 = Debug|Win32
+ {B20AE738-2F4F-4E96-A673-F5A02591D50E}.Release|Win32.ActiveCfg = Release|Win32
+ {594A9352-4170-4F5D-AEB3-E6C96DA2E87F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {594A9352-4170-4F5D-AEB3-E6C96DA2E87F}.Debug|Win32.Build.0 = Debug|Win32
+ {594A9352-4170-4F5D-AEB3-E6C96DA2E87F}.Release|Win32.ActiveCfg = Release|Win32
+ {27D9F340-49F7-4715-B77D-B44CE57B7CBD}.Debug|Win32.ActiveCfg = Debug|Win32
+ {27D9F340-49F7-4715-B77D-B44CE57B7CBD}.Debug|Win32.Build.0 = Debug|Win32
+ {27D9F340-49F7-4715-B77D-B44CE57B7CBD}.Release|Win32.ActiveCfg = Release|Win32
+ {EC73A2FE-5D85-45C3-A223-37737C823476}.Debug|Win32.ActiveCfg = Debug|Win32
+ {EC73A2FE-5D85-45C3-A223-37737C823476}.Debug|Win32.Build.0 = Debug|Win32
+ {EC73A2FE-5D85-45C3-A223-37737C823476}.Release|Win32.ActiveCfg = Release|Win32
+ {EC73A2FE-5D85-45C3-A223-37737C823476}.Release|Win32.Build.0 = Release|Win32
+ {C4C7BA27-B713-47C0-92B1-FF70EAC9A373}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C4C7BA27-B713-47C0-92B1-FF70EAC9A373}.Debug|Win32.Build.0 = Debug|Win32
+ {C4C7BA27-B713-47C0-92B1-FF70EAC9A373}.Release|Win32.ActiveCfg = Release|Win32
+ {C4C7BA27-B713-47C0-92B1-FF70EAC9A373}.Release|Win32.Build.0 = Release|Win32
+ {B4B56EF0-681D-4B32-AD14-F855D67CB01B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B4B56EF0-681D-4B32-AD14-F855D67CB01B}.Debug|Win32.Build.0 = Debug|Win32
+ {B4B56EF0-681D-4B32-AD14-F855D67CB01B}.Release|Win32.ActiveCfg = Release|Win32
+ {B4B56EF0-681D-4B32-AD14-F855D67CB01B}.Release|Win32.Build.0 = Release|Win32
+ {3BE97421-D962-4330-815B-AC9B7B799F15}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3BE97421-D962-4330-815B-AC9B7B799F15}.Debug|Win32.Build.0 = Debug|Win32
+ {3BE97421-D962-4330-815B-AC9B7B799F15}.Release|Win32.ActiveCfg = Release|Win32
+ {3BE97421-D962-4330-815B-AC9B7B799F15}.Release|Win32.Build.0 = Release|Win32
+ {2B7CDB51-C796-4CD2-82ED-F782C7952204}.Debug|Win32.ActiveCfg = Debug|Win32
+ {2B7CDB51-C796-4CD2-82ED-F782C7952204}.Debug|Win32.Build.0 = Debug|Win32
+ {2B7CDB51-C796-4CD2-82ED-F782C7952204}.Release|Win32.ActiveCfg = Release|Win32
+ {2B7CDB51-C796-4CD2-82ED-F782C7952204}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/vs2008/vs2008.suo b/vs2008/vs2008.suo
new file mode 100644
index 0000000..8fb4b3f
--- /dev/null
+++ b/vs2008/vs2008.suo
Binary files differ