text_ux 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +25 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +51 -0
  7. data/Rakefile +18 -0
  8. data/ext/text_ux/extconf.rb +5 -0
  9. data/ext/text_ux/text_ux.cpp +252 -0
  10. data/lib/text_ux.rb +5 -0
  11. data/lib/text_ux/version.rb +3 -0
  12. data/spec/fixtures/test.ux +0 -0
  13. data/spec/spec_helper.rb +19 -0
  14. data/spec/text_ux_spec.rb +137 -0
  15. data/text_ux.gemspec +26 -0
  16. data/vendor/ux-trie/ux-0.1.9/.lock-waf_darwin_build +8 -0
  17. data/vendor/ux-trie/ux-0.1.9/.unittest-gtest/gtest-1.6.0/fused-src/gtest/gtest-all.cc +9118 -0
  18. data/vendor/ux-trie/ux-0.1.9/.unittest-gtest/gtest-1.6.0/fused-src/gtest/gtest.h +19537 -0
  19. data/vendor/ux-trie/ux-0.1.9/.unittest-gtest/gtest-1.6.0/fused-src/gtest/gtest_main.cc +39 -0
  20. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Build.py +733 -0
  21. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Build.pyc +0 -0
  22. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/ConfigSet.py +147 -0
  23. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/ConfigSet.pyc +0 -0
  24. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Configure.py +314 -0
  25. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Configure.pyc +0 -0
  26. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Context.py +298 -0
  27. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Context.pyc +0 -0
  28. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Errors.py +37 -0
  29. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Errors.pyc +0 -0
  30. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Logs.py +149 -0
  31. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Logs.pyc +0 -0
  32. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Node.py +500 -0
  33. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Node.pyc +0 -0
  34. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Options.py +130 -0
  35. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Options.pyc +0 -0
  36. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Runner.py +191 -0
  37. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Runner.pyc +0 -0
  38. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Scripting.py +358 -0
  39. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Scripting.pyc +0 -0
  40. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Task.py +669 -0
  41. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Task.pyc +0 -0
  42. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/TaskGen.py +341 -0
  43. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/TaskGen.pyc +0 -0
  44. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/__init__.py +4 -0
  45. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/__init__.pyc +0 -0
  46. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/ar.py +12 -0
  47. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/ar.pyc +0 -0
  48. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/asm.py +25 -0
  49. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/bison.py +29 -0
  50. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c.py +27 -0
  51. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_aliases.py +56 -0
  52. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_aliases.pyc +0 -0
  53. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_config.py +708 -0
  54. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_config.pyc +0 -0
  55. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_osx.py +121 -0
  56. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_osx.pyc +0 -0
  57. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_preproc.py +606 -0
  58. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_preproc.pyc +0 -0
  59. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_tests.py +110 -0
  60. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/c_tests.pyc +0 -0
  61. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/ccroot.py +372 -0
  62. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/ccroot.pyc +0 -0
  63. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/compiler_c.py +39 -0
  64. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/compiler_cxx.py +39 -0
  65. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/compiler_cxx.pyc +0 -0
  66. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/compiler_d.py +30 -0
  67. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/compiler_fc.py +45 -0
  68. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/cs.py +98 -0
  69. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/cxx.py +27 -0
  70. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/cxx.pyc +0 -0
  71. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/d.py +51 -0
  72. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/d_config.py +47 -0
  73. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/d_scan.py +133 -0
  74. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/dbus.py +30 -0
  75. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/dmd.py +43 -0
  76. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/errcheck.py +153 -0
  77. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/fc.py +123 -0
  78. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/fc_config.py +271 -0
  79. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/fc_scan.py +68 -0
  80. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/flex.py +27 -0
  81. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/g95.py +55 -0
  82. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gas.py +10 -0
  83. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gcc.py +98 -0
  84. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gdc.py +34 -0
  85. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gfortran.py +69 -0
  86. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/glib2.py +174 -0
  87. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gnu_dirs.py +65 -0
  88. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gxx.py +98 -0
  89. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/gxx.pyc +0 -0
  90. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/icc.py +31 -0
  91. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/icpc.py +30 -0
  92. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/ifort.py +42 -0
  93. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/intltool.py +78 -0
  94. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/irixcc.py +49 -0
  95. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/javaw.py +272 -0
  96. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/kde4.py +49 -0
  97. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/lua.py +19 -0
  98. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/msvc.py +650 -0
  99. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/nasm.py +13 -0
  100. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/perl.py +78 -0
  101. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/python.py +303 -0
  102. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/qt4.py +424 -0
  103. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/ruby.py +104 -0
  104. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/suncc.py +54 -0
  105. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/suncxx.py +55 -0
  106. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/tex.py +222 -0
  107. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/vala.py +215 -0
  108. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/waf_unit_test.py +79 -0
  109. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/winres.py +34 -0
  110. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/xlc.py +46 -0
  111. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Tools/xlcxx.py +46 -0
  112. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Utils.py +334 -0
  113. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/Utils.pyc +0 -0
  114. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/__init__.py +4 -0
  115. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/__init__.pyc +0 -0
  116. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/ansiterm.py +173 -0
  117. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/ansiterm.pyc +0 -0
  118. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/extras/__init__.py +4 -0
  119. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/extras/__init__.pyc +0 -0
  120. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/extras/compat15.py +223 -0
  121. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/extras/compat15.pyc +0 -0
  122. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/fixpy2.py +50 -0
  123. data/vendor/ux-trie/ux-0.1.9/.waf-1.6.8-3e3391c5f23fbabad81e6d17c63a1b1e/waflib/fixpy2.pyc +0 -0
  124. data/vendor/ux-trie/ux-0.1.9/src/bitVec.cpp +119 -0
  125. data/vendor/ux-trie/ux-0.1.9/src/bitVec.hpp +64 -0
  126. data/vendor/ux-trie/ux-0.1.9/src/bitVecTest.cpp +143 -0
  127. data/vendor/ux-trie/ux-0.1.9/src/cmdline.h +809 -0
  128. data/vendor/ux-trie/ux-0.1.9/src/rsDic.cpp +121 -0
  129. data/vendor/ux-trie/ux-0.1.9/src/rsDic.hpp +57 -0
  130. data/vendor/ux-trie/ux-0.1.9/src/ux.hpp +26 -0
  131. data/vendor/ux-trie/ux-0.1.9/src/uxMain.cpp +206 -0
  132. data/vendor/ux-trie/ux-0.1.9/src/uxMap.cpp +0 -0
  133. data/vendor/ux-trie/ux-0.1.9/src/uxMap.hpp +248 -0
  134. data/vendor/ux-trie/ux-0.1.9/src/uxMapTest.cpp +139 -0
  135. data/vendor/ux-trie/ux-0.1.9/src/uxTest.cpp +229 -0
  136. data/vendor/ux-trie/ux-0.1.9/src/uxTrie.cpp +529 -0
  137. data/vendor/ux-trie/ux-0.1.9/src/uxTrie.hpp +220 -0
  138. data/vendor/ux-trie/ux-0.1.9/src/uxUtil.cpp +92 -0
  139. data/vendor/ux-trie/ux-0.1.9/src/uxUtil.hpp +35 -0
  140. data/vendor/ux-trie/ux-0.1.9/src/wscript +43 -0
  141. data/vendor/ux-trie/ux-0.1.9/unittest_gtest.py +0 -0
  142. data/vendor/ux-trie/ux-0.1.9/unittest_gtest.pyc +0 -0
  143. data/vendor/ux-trie/ux-0.1.9/unittestt.py +166 -0
  144. data/vendor/ux-trie/ux-0.1.9/ux.pc.in +10 -0
  145. data/vendor/ux-trie/ux-0.1.9/waf +0 -0
  146. data/vendor/ux-trie/ux-0.1.9/wscript +32 -0
  147. metadata +249 -0
@@ -0,0 +1,119 @@
1
+ /*
2
+ * Copyright (c) 2010 Daisuke Okanohara
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions
6
+ * are met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above Copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above Copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * 3. Neither the name of the authors nor the names of its contributors
16
+ * may be used to endorse or promote products derived from this
17
+ * software without specific prior written permission.
18
+ */
19
+
20
+ #include <iostream>
21
+ #include <cassert>
22
+ #include "bitVec.hpp"
23
+
24
+ using namespace std;
25
+
26
+ namespace ux {
27
+
28
+ BitVec::BitVec() : size_(0){
29
+ }
30
+
31
+ BitVec::~BitVec(){
32
+ }
33
+
34
+
35
+ void BitVec::push_back(const uint8_t b){
36
+ if (size_ / S_BLOCK >= B_.size()) {
37
+ B_.push_back(0);
38
+ }
39
+
40
+ if (b) {
41
+ B_[size_ / S_BLOCK] |= (1ULL << (size_ % S_BLOCK));
42
+ }
43
+ ++size_;
44
+ }
45
+
46
+ void BitVec::push_back_with_len(const uint64_t x, const uint64_t len){
47
+ size_t offset = size_ % S_BLOCK;
48
+ if ((size_ + len - 1) / S_BLOCK >= B_.size()){
49
+ B_.push_back(0);
50
+ }
51
+
52
+ B_[size_ / S_BLOCK] |= (x << offset);
53
+ if (offset + len - 1 >= S_BLOCK){
54
+ B_[size_ / S_BLOCK + 1] |= (x >> (S_BLOCK - offset));
55
+ }
56
+ size_ += len;
57
+ }
58
+
59
+ void BitVec::setBit(const uint64_t pos, const uint8_t b){
60
+ if (b == 0) return;
61
+ B_[pos / S_BLOCK] = 1LLU << (pos % S_BLOCK);
62
+ }
63
+
64
+ uint8_t BitVec::getBit(const uint64_t pos) const{
65
+ return (B_[pos/S_BLOCK] >> (pos % S_BLOCK)) & 1;
66
+ }
67
+
68
+ uint64_t BitVec::getBits(const uint64_t pos, const uint64_t len) const{
69
+ uint64_t blockInd1 = pos / S_BLOCK;
70
+ uint64_t blockOffset1 = pos % S_BLOCK;
71
+ if (blockOffset1 + len <= S_BLOCK){
72
+ return mask(B_[blockInd1] >> blockOffset1, len);
73
+ } else {
74
+ uint64_t blockInd2 = ((pos + len - 1) / S_BLOCK);
75
+ return mask((B_[blockInd1] >> blockOffset1) + (B_[blockInd2] << (S_BLOCK - blockOffset1)), len);
76
+ }
77
+ }
78
+
79
+ void BitVec::save(ostream& os) const {
80
+ os.write((const char*)&size_, sizeof(size_));
81
+ os.write((const char*)&B_[0], sizeof(B_[0])*B_.size());
82
+ }
83
+
84
+ void BitVec::load(istream& ifs) {
85
+ ifs.read((char*)&size_, sizeof(size_));
86
+ B_.resize((size_ + S_BLOCK - 1) / S_BLOCK);
87
+ ifs.read((char*)&B_[0], sizeof(B_[0])*B_.size());
88
+ }
89
+
90
+ size_t BitVec::size() const {
91
+ return size_;
92
+ }
93
+
94
+ void BitVec::clear() {
95
+ B_.clear();
96
+ size_ = 0;
97
+ }
98
+
99
+ void BitVec::print() const {
100
+ for (size_t i = 0; i < size_; ++i){
101
+ if (getBit(i)) cout << "1";
102
+ else cout << "0";
103
+ if ((i+1)%8 == 0){
104
+ cout << " ";
105
+ if ((i+1)%64 == 0) cout << endl;
106
+ }
107
+ }
108
+ }
109
+
110
+ size_t BitVec::getAllocSize() const {
111
+ return B_.size() * sizeof(B_[0]);
112
+ }
113
+
114
+ uint64_t BitVec::lookupBlock(const size_t ind) const{
115
+ return B_[ind];
116
+ }
117
+
118
+
119
+ }
@@ -0,0 +1,64 @@
1
+ /*
2
+ * Copyright (c) 2010 Daisuke Okanohara
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions
6
+ * are met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above Copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above Copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * 3. Neither the name of the authors nor the names of its contributors
16
+ * may be used to endorse or promote products derived from this
17
+ * software without specific prior written permission.
18
+ */
19
+
20
+ #ifndef BIT_VEC_HPP__
21
+ #define BIT_VEC_HPP__
22
+
23
+ #include <stdint.h>
24
+ #include <vector>
25
+ #include <iostream>
26
+ #include "uxUtil.hpp"
27
+
28
+ namespace ux {
29
+
30
+ static const uint64_t L_SHIFT = 9;
31
+ static const uint64_t L_BLOCK = 1LLU << L_SHIFT;
32
+ static const uint64_t S_SHIFT = 6;
33
+ static const uint64_t S_BLOCK = 1LLU << S_SHIFT;
34
+ static const uint64_t S_RATIO = L_BLOCK / S_BLOCK;
35
+
36
+ class BitVec {
37
+ public:
38
+ BitVec();
39
+ ~BitVec();
40
+
41
+ void push_back(const uint8_t b);
42
+ void push_back_with_len(const uint64_t x, const uint64_t len);
43
+
44
+ void setBit(const uint64_t pos, const uint8_t b);
45
+ uint8_t getBit(const uint64_t pos) const;
46
+ uint64_t getBits(const uint64_t pos, const uint64_t len) const;
47
+ void save(std::ostream& os) const;
48
+ void load(std::istream& is);
49
+ size_t size() const;
50
+ void clear();
51
+ void print() const;
52
+ size_t getAllocSize() const;
53
+ uint64_t lookupBlock(const size_t ind) const;
54
+
55
+ private:
56
+ size_t size_;
57
+ std::vector<uint64_t> B_;
58
+ };
59
+
60
+ }
61
+
62
+
63
+
64
+ #endif // BIT_VEC_HPP__
@@ -0,0 +1,143 @@
1
+ /*
2
+ * Copyright (c) 2010 Daisuke Okanohara
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without
5
+ * modification, are permitted provided that the following conditions
6
+ * are met:
7
+ *
8
+ * 1. Redistributions of source code must retain the above Copyright
9
+ * notice, this list of conditions and the following disclaimer.
10
+ *
11
+ * 2. Redistributions in binary form must reproduce the above Copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * 3. Neither the name of the authors nor the names of its contributors
16
+ * may be used to endorse or promote products derived from this
17
+ * software without specific prior written permission.
18
+ */
19
+
20
+ #include <gtest/gtest.h>
21
+ #include <vector>
22
+ #include <string>
23
+ #include "bitVec.hpp"
24
+ #include "rsDic.hpp"
25
+ #include "uxUtil.hpp"
26
+
27
+ using namespace std;
28
+ using namespace ux;
29
+
30
+ TEST(bitvec, popcount){
31
+ uint64_t x = 0;
32
+ for (uint64_t i = 0; i < 64; ++i){
33
+ ASSERT_EQ(i, popCount(x));
34
+ x |= (1LLU << i);
35
+ }
36
+ }
37
+
38
+ TEST(bitvec, selectblock){
39
+ uint64_t x = 0;
40
+
41
+ for (uint64_t i = 0; i < 64; ++i){
42
+ ASSERT_EQ(i, selectBlock(i+1, x, 0));
43
+ }
44
+
45
+ for (uint64_t i = 0; i < 64; ++i){
46
+ x |= (1LLU << i);
47
+ }
48
+
49
+ for (uint64_t i = 0; i < 64; ++i){
50
+ ASSERT_EQ(i, selectBlock(i+1, x, 1));
51
+ }
52
+ }
53
+
54
+ TEST(bitvec, trivial_zero){
55
+ BitVec bv;
56
+ for (int i = 0; i < 1000; ++i){
57
+ bv.push_back(0);
58
+ }
59
+
60
+ RSDic rs;
61
+ rs.build(bv);
62
+ ASSERT_EQ(1000, rs.size());
63
+ for (size_t i = 0; i < rs.size(); ++i){
64
+ ASSERT_EQ(0 , bv.getBit(i));
65
+ ASSERT_EQ(i+1, rs.rank(i, 0));
66
+ ASSERT_EQ(i , rs.select(i+1, 0));
67
+ }
68
+ }
69
+
70
+ TEST(bitvec, trivial_one){
71
+ BitVec bv;
72
+ for (int i = 0; i < 1000; ++i){
73
+ bv.push_back(1);
74
+ }
75
+
76
+ RSDic rs;
77
+ rs.build(bv);
78
+ ASSERT_EQ(1000, rs.size());
79
+ for (size_t i = 0; i < rs.size(); ++i){
80
+ ASSERT_EQ(1 , rs.getBit(i));
81
+ ASSERT_EQ(i+1, rs.rank(i, 1));
82
+ ASSERT_EQ(i , rs.select(i+1, 1));
83
+ }
84
+ }
85
+
86
+ /*
87
+ TEST(bitvec, trivial_interleave){
88
+ RSDic bv;
89
+ for (int i = 0; i < 1000; ++i){
90
+ bv.push_back((i+1)%2);
91
+ }
92
+ bv.build();
93
+ ASSERT_EQ(1000, bv.size());
94
+ for (size_t i = 0; i < bv.size(); ++i){
95
+ ASSERT_EQ(i/2 + 1, bv.rank2(i));
96
+ }
97
+ }
98
+ */
99
+
100
+
101
+ TEST(bitvec, random){
102
+ BitVec bv;
103
+ vector<int> B;
104
+ for (int i = 0; i < 100000; ++i){
105
+ int b = rand() % 2;
106
+ bv.push_back(b);
107
+ B.push_back(b);
108
+ }
109
+
110
+ RSDic rs;
111
+ rs.build(bv);
112
+ ASSERT_EQ(100000, rs.size());
113
+ int sum = 0;
114
+ for (size_t i = 0; i < rs.size(); ++i){
115
+ ASSERT_EQ(B[i] , bv.getBit(i));
116
+ sum += B[i];
117
+ if (B[i]){
118
+ ASSERT_EQ(sum, rs.rank(i, 1));
119
+ ASSERT_EQ(i, rs.select(sum, 1));
120
+ } else {
121
+ ASSERT_EQ(i - sum + 1, rs.rank(i, 0));
122
+ ASSERT_EQ(i, rs.select(i-sum+1, 0));
123
+ }
124
+ }
125
+ }
126
+
127
+ TEST(bitvec, vacuum){
128
+ BitVec bv;
129
+ vector<int> B;
130
+ for (int i = 0; i < 100000; ++i){
131
+ int b = rand() % 2;
132
+ bv.push_back(b);
133
+ B.push_back(b);
134
+ }
135
+
136
+ RSDic rs;
137
+ rs.build(bv);
138
+ }
139
+
140
+
141
+
142
+
143
+
@@ -0,0 +1,809 @@
1
+ /*
2
+ Copyright (c) 2009, Hideyuki Tanaka
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+ * Redistributions of source code must retain the above copyright
8
+ notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright
10
+ notice, this list of conditions and the following disclaimer in the
11
+ documentation and/or other materials provided with the distribution.
12
+ * Neither the name of the <organization> nor the
13
+ names of its contributors may be used to endorse or promote products
14
+ derived from this software without specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY <copyright holder> ''AS IS'' AND ANY
17
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ */
27
+
28
+ #pragma once
29
+
30
+ #include <iostream>
31
+ #include <sstream>
32
+ #include <vector>
33
+ #include <map>
34
+ #include <string>
35
+ #include <stdexcept>
36
+ #include <typeinfo>
37
+ #include <cstring>
38
+ #include <algorithm>
39
+ #include <cxxabi.h>
40
+ #include <cstdlib>
41
+
42
+ namespace cmdline{
43
+
44
+ namespace detail{
45
+
46
+ template <typename Target, typename Source, bool Same>
47
+ class lexical_cast_t{
48
+ public:
49
+ static Target cast(const Source &arg){
50
+ Target ret;
51
+ std::stringstream ss;
52
+ if (!(ss<<arg && ss>>ret && ss.eof()))
53
+ throw std::bad_cast();
54
+
55
+ return ret;
56
+ }
57
+ };
58
+
59
+ template <typename Target, typename Source>
60
+ class lexical_cast_t<Target, Source, true>{
61
+ public:
62
+ static Target cast(const Source &arg){
63
+ return arg;
64
+ }
65
+ };
66
+
67
+ template <typename Source>
68
+ class lexical_cast_t<std::string, Source, false>{
69
+ public:
70
+ static std::string cast(const Source &arg){
71
+ std::ostringstream ss;
72
+ ss<<arg;
73
+ return ss.str();
74
+ }
75
+ };
76
+
77
+ template <typename Target>
78
+ class lexical_cast_t<Target, std::string, false>{
79
+ public:
80
+ static Target cast(const std::string &arg){
81
+ Target ret;
82
+ std::istringstream ss(arg);
83
+ if (!(ss>>ret && ss.eof()))
84
+ throw std::bad_cast();
85
+ return ret;
86
+ }
87
+ };
88
+
89
+ template <typename T1, typename T2>
90
+ struct is_same {
91
+ static const bool value = false;
92
+ };
93
+
94
+ template <typename T>
95
+ struct is_same<T, T>{
96
+ static const bool value = true;
97
+ };
98
+
99
+ template<typename Target, typename Source>
100
+ Target lexical_cast(const Source &arg)
101
+ {
102
+ return lexical_cast_t<Target, Source, detail::is_same<Target, Source>::value>::cast(arg);
103
+ }
104
+
105
+ static inline std::string demangle(const std::string &name)
106
+ {
107
+ int status=0;
108
+ char *p=abi::__cxa_demangle(name.c_str(), 0, 0, &status);
109
+ std::string ret(p);
110
+ free(p);
111
+ return ret;
112
+ }
113
+
114
+ template <class T>
115
+ std::string readable_typename()
116
+ {
117
+ return demangle(typeid(T).name());
118
+ }
119
+
120
+ template <class T>
121
+ std::string default_value(T def)
122
+ {
123
+ return detail::lexical_cast<std::string>(def);
124
+ }
125
+
126
+ template <>
127
+ inline std::string readable_typename<std::string>()
128
+ {
129
+ return "string";
130
+ }
131
+
132
+ } // detail
133
+
134
+ //-----
135
+
136
+ class cmdline_error : public std::exception {
137
+ public:
138
+ cmdline_error(const std::string &msg): msg(msg){}
139
+ ~cmdline_error() throw() {}
140
+ const char *what() const throw() { return msg.c_str(); }
141
+ private:
142
+ std::string msg;
143
+ };
144
+
145
+ template <class T>
146
+ struct default_reader{
147
+ T operator()(const std::string &str){
148
+ return detail::lexical_cast<T>(str);
149
+ }
150
+ };
151
+
152
+ template <class T>
153
+ struct range_reader{
154
+ range_reader(const T &low, const T &high): low(low), high(high) {}
155
+ T operator()(const std::string &s) const {
156
+ T ret=default_reader<T>()(s);
157
+ if (!(ret>=low && ret<=high)) throw cmdline::cmdline_error("range_error");
158
+ return ret;
159
+ }
160
+ private:
161
+ T low, high;
162
+ };
163
+
164
+ template <class T>
165
+ range_reader<T> range(const T &low, const T &high)
166
+ {
167
+ return range_reader<T>(low, high);
168
+ }
169
+
170
+ template <class T>
171
+ struct oneof_reader{
172
+ T operator()(const std::string &s){
173
+ T ret=default_reader<T>()(s);
174
+ if (std::find(alt.begin(), alt.end(), ret)==alt.end())
175
+ throw cmdline_error("");
176
+ return ret;
177
+ }
178
+ void add(const T &v){ alt.push_back(v); }
179
+ private:
180
+ std::vector<T> alt;
181
+ };
182
+
183
+ template <class T>
184
+ oneof_reader<T> oneof(T a1)
185
+ {
186
+ oneof_reader<T> ret;
187
+ ret.add(a1);
188
+ return ret;
189
+ }
190
+
191
+ template <class T>
192
+ oneof_reader<T> oneof(T a1, T a2)
193
+ {
194
+ oneof_reader<T> ret;
195
+ ret.add(a1);
196
+ ret.add(a2);
197
+ return ret;
198
+ }
199
+
200
+ template <class T>
201
+ oneof_reader<T> oneof(T a1, T a2, T a3)
202
+ {
203
+ oneof_reader<T> ret;
204
+ ret.add(a1);
205
+ ret.add(a2);
206
+ ret.add(a3);
207
+ return ret;
208
+ }
209
+
210
+ template <class T>
211
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4)
212
+ {
213
+ oneof_reader<T> ret;
214
+ ret.add(a1);
215
+ ret.add(a2);
216
+ ret.add(a3);
217
+ ret.add(a4);
218
+ return ret;
219
+ }
220
+
221
+ template <class T>
222
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5)
223
+ {
224
+ oneof_reader<T> ret;
225
+ ret.add(a1);
226
+ ret.add(a2);
227
+ ret.add(a3);
228
+ ret.add(a4);
229
+ ret.add(a5);
230
+ return ret;
231
+ }
232
+
233
+ template <class T>
234
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6)
235
+ {
236
+ oneof_reader<T> ret;
237
+ ret.add(a1);
238
+ ret.add(a2);
239
+ ret.add(a3);
240
+ ret.add(a4);
241
+ ret.add(a5);
242
+ ret.add(a6);
243
+ return ret;
244
+ }
245
+
246
+ template <class T>
247
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7)
248
+ {
249
+ oneof_reader<T> ret;
250
+ ret.add(a1);
251
+ ret.add(a2);
252
+ ret.add(a3);
253
+ ret.add(a4);
254
+ ret.add(a5);
255
+ ret.add(a6);
256
+ ret.add(a7);
257
+ return ret;
258
+ }
259
+
260
+ template <class T>
261
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8)
262
+ {
263
+ oneof_reader<T> ret;
264
+ ret.add(a1);
265
+ ret.add(a2);
266
+ ret.add(a3);
267
+ ret.add(a4);
268
+ ret.add(a5);
269
+ ret.add(a6);
270
+ ret.add(a7);
271
+ ret.add(a8);
272
+ return ret;
273
+ }
274
+
275
+ template <class T>
276
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9)
277
+ {
278
+ oneof_reader<T> ret;
279
+ ret.add(a1);
280
+ ret.add(a2);
281
+ ret.add(a3);
282
+ ret.add(a4);
283
+ ret.add(a5);
284
+ ret.add(a6);
285
+ ret.add(a7);
286
+ ret.add(a8);
287
+ ret.add(a9);
288
+ return ret;
289
+ }
290
+
291
+ template <class T>
292
+ oneof_reader<T> oneof(T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10)
293
+ {
294
+ oneof_reader<T> ret;
295
+ ret.add(a1);
296
+ ret.add(a2);
297
+ ret.add(a3);
298
+ ret.add(a4);
299
+ ret.add(a5);
300
+ ret.add(a6);
301
+ ret.add(a7);
302
+ ret.add(a8);
303
+ ret.add(a9);
304
+ ret.add(a10);
305
+ return ret;
306
+ }
307
+
308
+ //-----
309
+
310
+ class parser{
311
+ public:
312
+ parser(){
313
+ }
314
+ ~parser(){
315
+ for (std::map<std::string, option_base*>::iterator p=options.begin();
316
+ p!=options.end(); p++)
317
+ delete p->second;
318
+ }
319
+
320
+ void add(const std::string &name,
321
+ char short_name=0,
322
+ const std::string &desc=""){
323
+ if (options.count(name)) throw cmdline_error("multiple definition: "+name);
324
+ options[name]=new option_without_value(name, short_name, desc);
325
+ ordered.push_back(options[name]);
326
+ }
327
+
328
+ template <class T>
329
+ void add(const std::string &name,
330
+ char short_name=0,
331
+ const std::string &desc="",
332
+ bool need=true,
333
+ const T def=T()){
334
+ add(name, short_name, desc, need, def, default_reader<T>());
335
+ }
336
+
337
+ template <class T, class F>
338
+ void add(const std::string &name,
339
+ char short_name=0,
340
+ const std::string &desc="",
341
+ bool need=true,
342
+ const T def=T(),
343
+ F reader=F()){
344
+ if (options.count(name)) throw cmdline_error("multiple definition: "+name);
345
+ options[name]=new option_with_value_with_reader<T, F>(name, short_name, need, def, desc, reader);
346
+ ordered.push_back(options[name]);
347
+ }
348
+
349
+ void footer(const std::string &f){
350
+ ftr=f;
351
+ }
352
+
353
+ void set_program_name(const std::string &name){
354
+ prog_name=name;
355
+ }
356
+
357
+ bool exist(const std::string &name) const {
358
+ if (options.count(name)==0) throw cmdline_error("there is no flag: --"+name);
359
+ return options.find(name)->second->has_set();
360
+ }
361
+
362
+ template <class T>
363
+ const T &get(const std::string &name) const {
364
+ if (options.count(name)==0) throw cmdline_error("there is no flag: --"+name);
365
+ const option_with_value<T> *p=dynamic_cast<const option_with_value<T>*>(options.find(name)->second);
366
+ if (p==NULL) throw cmdline_error("type mismatch flag '"+name+"'");
367
+ return p->get();
368
+ }
369
+
370
+ const std::vector<std::string> &rest() const {
371
+ return others;
372
+ }
373
+
374
+ bool parse(const std::string &arg){
375
+ std::vector<std::string> args;
376
+
377
+ std::string buf;
378
+ bool in_quote=false;
379
+ for (std::string::size_type i=0; i<arg.length(); i++){
380
+ if (arg[i]=='\"'){
381
+ in_quote=!in_quote;
382
+ continue;
383
+ }
384
+
385
+ if (arg[i]==' ' && !in_quote){
386
+ args.push_back(buf);
387
+ buf="";
388
+ continue;
389
+ }
390
+
391
+ if (arg[i]=='\\'){
392
+ i++;
393
+ if (i>=arg.length()){
394
+ errors.push_back("unexpected occurrence of '\\' at end of string");
395
+ return false;
396
+ }
397
+ }
398
+
399
+ buf+=arg[i];
400
+ }
401
+
402
+ if (in_quote){
403
+ errors.push_back("quote is not closed");
404
+ return false;
405
+ }
406
+
407
+ if (buf.length()>0)
408
+ args.push_back(buf);
409
+
410
+ for (size_t i=0; i<args.size(); i++)
411
+ std::cout<<"\""<<args[i]<<"\""<<std::endl;
412
+
413
+ return parse(args);
414
+ }
415
+
416
+ bool parse(const std::vector<std::string> &args){
417
+ int argc=static_cast<int>(args.size());
418
+ std::vector<const char*> argv(argc);
419
+
420
+ for (int i=0; i<argc; i++)
421
+ argv[i]=args[i].c_str();
422
+
423
+ return parse(argc, &argv[0]);
424
+ }
425
+
426
+ bool parse(int argc, const char * const argv[]){
427
+ errors.clear();
428
+ others.clear();
429
+
430
+ if (argc<1){
431
+ errors.push_back("argument number must be longer than 0");
432
+ return false;
433
+ }
434
+ if (prog_name=="")
435
+ prog_name=argv[0];
436
+
437
+ std::map<char, std::string> lookup;
438
+ for (std::map<std::string, option_base*>::iterator p=options.begin();
439
+ p!=options.end(); p++){
440
+ if (p->first.length()==0) continue;
441
+ char initial=p->second->short_name();
442
+ if (initial){
443
+ if (lookup.count(initial)>0){
444
+ lookup[initial]="";
445
+ errors.push_back(std::string("short option '")+initial+"' is ambiguous");
446
+ return false;
447
+ }
448
+ else lookup[initial]=p->first;
449
+ }
450
+ }
451
+
452
+ for (int i=1; i<argc; i++){
453
+ if (strncmp(argv[i], "--", 2)==0){
454
+ const char *p=strchr(argv[i]+2, '=');
455
+ if (p){
456
+ std::string name(argv[i]+2, p);
457
+ std::string val(p+1);
458
+ set_option(name, val);
459
+ }
460
+ else{
461
+ std::string name(argv[i]+2);
462
+ if (options.count(name)==0){
463
+ errors.push_back("undefined option: --"+name);
464
+ continue;
465
+ }
466
+ if (options[name]->has_value()){
467
+ if (i+1>=argc){
468
+ errors.push_back("option needs value: --"+name);
469
+ continue;
470
+ }
471
+ else{
472
+ i++;
473
+ set_option(name, argv[i]);
474
+ }
475
+ }
476
+ else{
477
+ set_option(name);
478
+ }
479
+ }
480
+ }
481
+ else if (strncmp(argv[i], "-", 1)==0){
482
+ if (!argv[i][1]) continue;
483
+ char last=argv[i][1];
484
+ for (int j=2; argv[i][j]; j++){
485
+ last=argv[i][j];
486
+ if (lookup.count(argv[i][j-1])==0){
487
+ errors.push_back(std::string("undefined short option: -")+argv[i][j-1]);
488
+ continue;
489
+ }
490
+ if (lookup[argv[i][j-1]]==""){
491
+ errors.push_back(std::string("ambiguous short option: -")+argv[i][j-1]);
492
+ continue;
493
+ }
494
+ set_option(lookup[argv[i][j-1]]);
495
+ }
496
+
497
+ if (lookup.count(last)==0){
498
+ errors.push_back(std::string("undefined short option: -")+last);
499
+ continue;
500
+ }
501
+ if (lookup[last]==""){
502
+ errors.push_back(std::string("ambiguous short option: -")+last);
503
+ continue;
504
+ }
505
+
506
+ if (i+1<argc && options[lookup[last]]->has_value()){
507
+ set_option(lookup[last], argv[i+1]);
508
+ i++;
509
+ }
510
+ else{
511
+ set_option(lookup[last]);
512
+ }
513
+ }
514
+ else{
515
+ others.push_back(argv[i]);
516
+ }
517
+ }
518
+
519
+ for (std::map<std::string, option_base*>::iterator p=options.begin();
520
+ p!=options.end(); p++)
521
+ if (!p->second->valid())
522
+ errors.push_back("need option: --"+std::string(p->first));
523
+
524
+ return errors.size()==0;
525
+ }
526
+
527
+ void parse_check(const std::string &arg){
528
+ if (!options.count("help"))
529
+ add("help", '?', "print this message");
530
+ check(0, parse(arg));
531
+ }
532
+
533
+ void parse_check(const std::vector<std::string> &args){
534
+ if (!options.count("help"))
535
+ add("help", '?', "print this message");
536
+ check(args.size(), parse(args));
537
+ }
538
+
539
+ void parse_check(int argc, char *argv[]){
540
+ if (!options.count("help"))
541
+ add("help", '?', "print this message");
542
+ check(argc, parse(argc, argv));
543
+ }
544
+
545
+ std::string error() const{
546
+ return errors.size()>0?errors[0]:"";
547
+ }
548
+
549
+ std::string error_full() const{
550
+ std::ostringstream oss;
551
+ for (size_t i=0; i<errors.size(); i++)
552
+ oss<<errors[i]<<std::endl;
553
+ return oss.str();
554
+ }
555
+
556
+ std::string usage() const {
557
+ std::ostringstream oss;
558
+ oss<<"usage: "<<prog_name<<" ";
559
+ for (size_t i=0; i<ordered.size(); i++){
560
+ if (ordered[i]->must())
561
+ oss<<ordered[i]->short_description()<<" ";
562
+ }
563
+
564
+ oss<<"[options] ... "<<ftr<<std::endl;
565
+ oss<<"options:"<<std::endl;
566
+
567
+ size_t max_width=0;
568
+ for (size_t i=0; i<ordered.size(); i++){
569
+ max_width=std::max(max_width, ordered[i]->name().length());
570
+ }
571
+ for (size_t i=0; i<ordered.size(); i++){
572
+ if (ordered[i]->short_name()){
573
+ oss<<" -"<<ordered[i]->short_name()<<", ";
574
+ }
575
+ else{
576
+ oss<<" ";
577
+ }
578
+
579
+ oss<<"--"<<ordered[i]->name();
580
+ for (size_t j=ordered[i]->name().length(); j<max_width+4; j++)
581
+ oss<<' ';
582
+ oss<<ordered[i]->description()<<std::endl;
583
+ }
584
+ return oss.str();
585
+ }
586
+
587
+ private:
588
+
589
+ void check(int argc, bool ok){
590
+ if ((argc==1 && !ok) || exist("help")){
591
+ std::cerr<<usage();
592
+ exit(0);
593
+ }
594
+
595
+ if (!ok){
596
+ std::cerr<<error()<<std::endl<<usage();
597
+ exit(1);
598
+ }
599
+ }
600
+
601
+ void set_option(const std::string &name){
602
+ if (options.count(name)==0){
603
+ errors.push_back("undefined option: --"+name);
604
+ return;
605
+ }
606
+ if (!options[name]->set()){
607
+ errors.push_back("option needs value: --"+name);
608
+ return;
609
+ }
610
+ }
611
+
612
+ void set_option(const std::string &name, const std::string &value){
613
+ if (options.count(name)==0){
614
+ errors.push_back("undefined option: --"+name);
615
+ return;
616
+ }
617
+ if (!options[name]->set(value)){
618
+ errors.push_back("option value is invalid: --"+name+"="+value);
619
+ return;
620
+ }
621
+ }
622
+
623
+ class option_base{
624
+ public:
625
+ virtual ~option_base(){}
626
+
627
+ virtual bool has_value() const=0;
628
+ virtual bool set()=0;
629
+ virtual bool set(const std::string &value)=0;
630
+ virtual bool has_set() const=0;
631
+ virtual bool valid() const=0;
632
+ virtual bool must() const=0;
633
+
634
+ virtual const std::string &name() const=0;
635
+ virtual char short_name() const=0;
636
+ virtual const std::string &description() const=0;
637
+ virtual std::string short_description() const=0;
638
+ };
639
+
640
+ class option_without_value : public option_base {
641
+ public:
642
+ option_without_value(const std::string &name,
643
+ char short_name,
644
+ const std::string &desc)
645
+ :nam(name), snam(short_name), desc(desc), has(false){
646
+ }
647
+ ~option_without_value(){}
648
+
649
+ bool has_value() const { return false; }
650
+
651
+ bool set(){
652
+ has=true;
653
+ return true;
654
+ }
655
+
656
+ bool set(const std::string &){
657
+ return false;
658
+ }
659
+
660
+ bool has_set() const {
661
+ return has;
662
+ }
663
+
664
+ bool valid() const{
665
+ return true;
666
+ }
667
+
668
+ bool must() const{
669
+ return false;
670
+ }
671
+
672
+ const std::string &name() const{
673
+ return nam;
674
+ }
675
+
676
+ char short_name() const{
677
+ return snam;
678
+ }
679
+
680
+ const std::string &description() const {
681
+ return desc;
682
+ }
683
+
684
+ std::string short_description() const{
685
+ return "--"+nam;
686
+ }
687
+
688
+ private:
689
+ std::string nam;
690
+ char snam;
691
+ std::string desc;
692
+ bool has;
693
+ };
694
+
695
+ template <class T>
696
+ class option_with_value : public option_base {
697
+ public:
698
+ option_with_value(const std::string &name,
699
+ char short_name,
700
+ bool need,
701
+ const T &def,
702
+ const std::string &desc)
703
+ : nam(name), snam(short_name), need(need), has(false)
704
+ , def(def), actual(def) {
705
+ this->desc=full_description(desc);
706
+ }
707
+ ~option_with_value(){}
708
+
709
+ const T &get() const {
710
+ return actual;
711
+ }
712
+
713
+ bool has_value() const { return true; }
714
+
715
+ bool set(){
716
+ return false;
717
+ }
718
+
719
+ bool set(const std::string &value){
720
+ try{
721
+ actual=read(value);
722
+ has=true;
723
+ }
724
+ catch(const std::exception &e){
725
+ return false;
726
+ }
727
+ return true;
728
+ }
729
+
730
+ bool has_set() const{
731
+ return has;
732
+ }
733
+
734
+ bool valid() const{
735
+ if (need && !has) return false;
736
+ return true;
737
+ }
738
+
739
+ bool must() const{
740
+ return need;
741
+ }
742
+
743
+ const std::string &name() const{
744
+ return nam;
745
+ }
746
+
747
+ char short_name() const{
748
+ return snam;
749
+ }
750
+
751
+ const std::string &description() const {
752
+ return desc;
753
+ }
754
+
755
+ std::string short_description() const{
756
+ return "--"+nam+"="+detail::readable_typename<T>();
757
+ }
758
+
759
+ protected:
760
+ std::string full_description(const std::string &desc){
761
+ return
762
+ desc+" ("+detail::readable_typename<T>()+
763
+ (need?"":" [="+detail::default_value<T>(def)+"]")
764
+ +")";
765
+ }
766
+
767
+ virtual T read(const std::string &s)=0;
768
+
769
+ std::string nam;
770
+ char snam;
771
+ bool need;
772
+ std::string desc;
773
+
774
+ bool has;
775
+ T def;
776
+ T actual;
777
+ };
778
+
779
+ template <class T, class F>
780
+ class option_with_value_with_reader : public option_with_value<T> {
781
+ public:
782
+ option_with_value_with_reader(const std::string &name,
783
+ char short_name,
784
+ bool need,
785
+ const T def,
786
+ const std::string &desc,
787
+ F reader)
788
+ : option_with_value<T>(name, short_name, need, def, desc), reader(reader){
789
+ }
790
+
791
+ private:
792
+ T read(const std::string &s){
793
+ return reader(s);
794
+ }
795
+
796
+ F reader;
797
+ };
798
+
799
+ std::map<std::string, option_base*> options;
800
+ std::vector<option_base*> ordered;
801
+ std::string ftr;
802
+
803
+ std::string prog_name;
804
+ std::vector<std::string> others;
805
+
806
+ std::vector<std::string> errors;
807
+ };
808
+
809
+ } // cmdline