nlib
|
Windows, Linux, FreeBSD, OS X, Cygwin及び任天堂の開発環境に対応したライブラリの集合です。
nlib
はWindows, Linux, FreeBSD, OS X, Cygwin及び任天堂の開発環境に対して同一のI/Fを利用したプログラミングが可能な、ユーザーランド上で動作するライブラリ群を提供することを目的として開発されています。 開発はsoftware centricに行われ、適切で現実的なコーディングルール(nlibのコーディングルール)と個別の開発環境からの独立性が確保されたI/Fと実装によって、複数の開発環境に対して同時並行的に高い品質と性能及び信頼性を維持しつつ行われることにフォーカスしています。nlib
のアップデートによるトラブルを回避するためにも役に立ちます。 そのような受け入れテストの作成にtesting
ライブラリを利用するのはよい考えです。 nn::nlib::testing
形式のテストコードとして記述してそれを報告に含めると迅速に修正されるかもしれません。├── bin │ └── cmake # Command-line tools ├── cmake # Common Cmake scripts ├── documents-ja(documents-en) │ └── API # Reference Manual │ ├── html # HTML version of the Reference Manual │ ├── nlib.chm # HTML Help version of the Reference Manual │ └── searchdata.xml # Search index ├── include # Include files (in `system/include` for Cafe) │ ├── nn │ │ └── nlib │ │ ├── exi │ │ ├── heap │ │ ├── msgpack │ │ │ └── jsonrpc │ │ ├── oss │ │ ├── simd │ │ ├── succinct │ │ ├── testing │ │ ├── threading │ │ └── unicode │ ├── lz4.h │ ├── lz4hc.h │ ├── lz4frame.h │ ├── sqlite3.h │ └── sqlite3ext.h ├── lib # Platform-specific library files (`system/lib` for Cafe, `libraries` for CTR) └── samples # Source code for samples ├── cmake └── sources ├── exi ├── heap ├── misc ├── msgpack ├── oss ├── succinct └── testing
nn/nlib/Platform.h
に宣言されている) pthread_once
相当) printf
系関数の環境毎の挙動の違いを抑制したprintf
系関数の実装 InputStream
, OutputStream
を基底とする各種ストリームを扱うためのクラス群 MemoryInputStream
, MemoryOutputStream
) FileInputStream
, FileOutputStream
) Base64InputStream
, Base64OutputStream
) zlib
で圧縮されたデータの読み書き(ZlibInputStream
, ZlibOutputStream
) TextReader
, TextWriter
) BinaryReader
, BinaryWriter
) unicode::UnicodeNormalizer
) unicode::StringPrep
) std::thread
に相当するクラス(threading::Thread
) std::future
, std::async
等に相当するクラスや関数(threading::Future
, threading::Async
) threading::Barrier
) threading::SharedCriticalSection
) threading::ThreadPool
) Uri
) UriTemplate
) NativePathMapper
) threading::AsyncFileIo
) nn::nlib
, nn::nlib::unicode
, nn::nlib::threading
です。nn::nlib::exi
です。misc
ライブラリに依存します。nmalloc()
/nfree()
(とそれらを実装するheap::CachedHeap
, heap::CentralHeap
)は、多段のフリーリストを利用することでフラグメンテーションの抑制を行い、性能の劣化を抑えています。 また、小さいサイズのメモリの場合は各スレッド毎にキャッシュを保持することにより、ロックをかけずにメモリの割り当てと解放が可能になっていてマルチスレッドでの性能劣化を抑制しています。 フリーリスト内のポインタはマングルされているか割り当て状態がチェックされていて、外部からのメモリの書き換えによる不正利用が行いにくいように実装されています。nn::nlib::heap
及びグローバル名前空間(Cリンケージの関数)です。 misc
ライブラリに依存します。succinct
ライブラリは以下のものを含みます。 nn::nlib::succinct
です。misc
ライブラリに依存します。msgpack
ライブラリは以下のものを含みます。 nn::nlib::msgpack
です。misc
ライブラリに依存します。nn::nlib::testing
(googletestとの互換性のためtesting
名前空間にエイリアスされている)です。misc
ライブラリに依存します。nn::nlib::oss
及びグローバル名前空間(Cリンケージの関数)です。 heap
ライブラリとmisc
ライブラリに依存します。simd
ライブラリは、SSE4.1とNEONに両対応したコードを記述するためのライブラリです。nn::nlib::simd
です。nlib
ではコンパイラの種類やバージョンによって、C++11の機能を利用してコンパイルされています。 以下にC++11の機能とnlib
で利用できる互換用マクロ等、及びC++11を利用してコンパイルされる コンパイラについて表にまとめておきます。 なお、clangについてはバージョンではなく__has_feature()
マクロ及び__has_include()
マクロによって判定されます。 C++11の機能 | 識別用マクロ | C++03互換用マクロやtypedef等 | Visual Studio | gcc |
---|---|---|---|---|
Rvalue references | NLIB_CXX11_RVALUE_REFERENCES | なし | 2010 | 4.3 |
Variadic templates | NLIB_CXX11_VARIADIC_TEMPLATES | なし | 2013 | 4.7 |
Static assertions | NLIB_CXX11_STATIC_ASSERTIONS | NLIB_STATIC_ASSERT() | 2010 | 4.3 |
Null pointer constant | NLIB_CXX11_NULL_POINTER_CONSTANT | nn::nlib::nullptr, nn::nlib::nullptr_t | 2010 | 4.6 |
Deleted functions | NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS | NLIB_DISALLOW_COPY_AND_ASSIGN() | 2015 | 4.4 |
Explicit conversion operators | NLIB_CXX11_EXPLICIT_CONVERSION_OPERATORS | NLIB_SAFE_BOOL() | 2013 | 4.6 |
Alias templates | NLIB_CXX11_TEMPLATE_ALIAS | なし | 2013 | 4.7 |
constexpr | NLIB_CXX11_CONSTEXPR | NLIB_CEXPR | 2015 | 4.7 |
char16_t, char32_t | NLIB_CXX11_NEW_CHARACTER_TYPES | nlib_utf16_t, nlib_utf32_t | 2015 | 4.4 |
alignas | NLIB_CXX11_ALIGNMENT_SUPPORT | NLIB_ALIGNAS() | 2015 | 4.8 |
Explicit virtual overrides | NLIB_CXX11_EXPLICIT_VIRTUAL_OVERRIDES | NLIB_OVERRIDE | 2012 | 4.7 |
final | NLIB_CXX11_EXPLICIT_VIRTUAL_OVERRIDES | NLIB_FINAL | 2012 | 4.7 |
noexcept | NLIB_CXX11_NOEXCEPT | NLIB_NOEXCEPT | 2015 | 4.6 |
Range-based for | NLIB_CXX11_RANGE_BASED_FOR | なし | 2012 | 4.6 |
lambda | NLIB_CXX11_LAMBDAS | なし | 2012 | 4.7 |
Delegating constructors | NLIB_CXX11_DELEGATING_CONSTRUCTORS | なし | 2013 | 4.7 |
std::unique_ptr | NLIB_CXX11_UNIQUEPTR | nn::nlib::UniquePtr | 2013 | 4.7 |
#include <random> | NLIB_CXX11_STDLIB_RANDOM | なし | 2013 | 4.8 |
#include <chrono> | NLIB_CXX11_STDLIB_CHRONO | nn::nlib::DateTime との変換 | 2012 | 4.7 |
#include <atomic> | NLIB_CXX11_STDLIB_ATOMIC | NLIB_MEMORY_ORDER_RELEASE 等 | 2012 | 4.8 |
#include <array> | NLIB_CXX11_STDLIB_ARRAY | なし | 2012 | 4.5 |
#include <unordered_map> #include <unordered_set> | NLIB_CXX11_STDLIB_UNORDERED | なし | 2012 | 4.5 |
#include <tuple> | NLIB_CXX11_STDLIB_TUPLE | なし | 2012 | 4.5 |
nlib
のコーディングルールは、(最新の)Google C++ Style Guide(若干古いが日本語訳)に若干の変更と緩和を行ったものになっています。 .cc
ではなく .cpp
とする FileName.cpp
のように大文字と小文字を混ぜる file_name.cpp
のようにする #pragma once
をつける(Visual Studioのコンパイル高速化のため) nlib
ではm_XXXX
のような名前がついているが、これは規則ではない。 nlib
のライブラリ本体ではBoostライブラリを利用しないが、テスト等において使うことは自由である nlib
では以下については例外的に非const参照を利用可能にしている std::swap()
の特殊化を行う場合 ScopedLock
クラスのようにロックを保持するだけの機能を持っているクラス。 nn::nlib::UniquePtr
を引数で渡す場合(値渡しは非効率だし、UniquePtr
へのポインタを渡すというのも変である) nullptr_t
やnullptr
を使わないこと nullptr
を実現するためのnullptr
イディオムは、複数のライブラリで定義されている場合にエラーとなるので、グローバル名前空間で定義できない nlib
では、C++03の場合は nn::nlib::nullptr_t
, nn::nlib::nullptr
として定義されている nullptr
が必要となる状況の殆どは回避できるはずである constexpr
の利用は自明なケース以外では見合わせること constexpr
を積極的に利用したコードは、コンパイラ毎の挙動の違いによりコンパイルエラーを多発させる要因になるという移植性におけるデメリットが存在する。 constexpr
をサポートするどのコンパイラでもコンパイルが通ることを期待できる場合のことである。 legal/copyright
, build/include_alpha
, whitespace/newline
による警告は抑制されている。 std::swap()
の利用に際してヘッダalgorithm
のインクルードは要求されないよう緩和している。 nlib
はclang-check
によるソースコードの検査にも対応しています。 cmakeでMakefileを生成すると、compile_commands.jsonというファイルが一緒に作成され、clang-checkはこれを利用して動作します。 nlib
で用いている設定が .clang-format
ファイル(clang3.5用です)としてnlib
のパッケージに含まれていて利用することが可能です。 まず、clang-format
で一括してソースコードの大まかな変換を行い、cpplint.py
でより細かい日常的なチェックを行うことをおすすめします。_MSC_FULL_VER
をチェックすること。 -Wstack-usage=65536
を利用し、スタックを使い過ぎないようにすること。 -fstack-protector
を利用すること。 cpplint.py
の警告をゼロにし、各種環境でのコンパイルとテストを通すことがnlib
の基本的なリリース基準になっています。Platform.h
で定義される関数の宣言や実装以外のコードは利用する可能性のある全環境でコンパイルできるコードで記述されている必要がある。ただしSIMD命令等によって機種別に最適化されたコードが含まれることは容認される。 NLIB_FINAL
, NLIB_OVERRIDE
等のマクロやtypedef
を利用してC++11の機能を安全に導入し、C++11やC++14以降への連続的な移行を可能にすること。 errno_t
とすること(https://www.jpcert.or.jp/sc-rules/c-dcl09-c.html)。nlib
を利用する側のコードがこれらを利用する場合を想定したコードを記述すること(例外安全性等)。 malloc()
, free()
等はnlib_malloc()
, nlib_free()
等を利用すること。 new
は、new (std::nothrow)
を利用すること。 nlib_printf()
に渡す文字列はnlib
内部でUTF-16に変換された上でWin32 APIに渡されている。 Nflags
)は例外 char
型が符号付きでも符号無しでも正常に動作するようにしておくこと。 signed
char
を用いれば明示的に符号付きの値として扱うことができる。 wchar_t
に関してはwchar_t
が16bitの場合はUTF-16として、32bitの場合はUTF-32としてサポートすること。 NLIB_WCHAR_SIZE
が2か4のいずれかに定義されるのでそれで判断することができる。 nlib_utf16_t
, UTF-32文字の型には nlib_utf32_t
を利用すること。 char16_t
, char32_t
のtypedef
となる。 nlib_strcplen_ex()
を使うことにより、validationを行いつつコードポイント数とバイト長を同時に求めることができる。更にSIMDがサポートされている場合にはこの動作をより高速に行うことができる。 NLIB_CXX11_RVALUE_REFERENCES
で切り分けられたコード内での定義の他に、C++03でも同等の機能を実現できるよう、以下のようなメンバ関数を定義しなければならない。 boost::move
のような素晴らしい手法も存在するが、結局完全な互換性は達成できないのでこの手法は利用しない。 type_traits
の利用は慎重に行うこと。C++11のこの機能はコンパイラやそのバージョンによってバグがあったり実装が抜けていたり、といったことがある。 nn/nlib/TypeTraits.h に一応のラップが行われているが、やむを得ない場合にのみ利用すること。 NLIB_DISALLOW_COPY_AND_ASSIGN()
を使うこと。 .h
形式のものをインクルードすること。理由は以下の2つ。 nn/nlib/Platform.h
はCコンパイラでコンパイル可能である必要があることから、xxx.h
形式のヘッダをインクルードする必要があるため、nlib内部でxxx.h
形式とcxxx
形式の両方の形式でインクルードすることに起因するコード上の混乱を抑制するため。 testing
ライブラリを利用することが可能である。 manual.h
というファイルを配置して、そこに記述すること。英語版のマニュアルの場合はmanual_en.h
である。こうすることで複数言語版を同じレポジトリで管理することができる。 CMakeLists.txt
というファイルが含まれていることに気づいた方も多いと思います。 cmakeを利用すると、このCMakefiles.txt
というスクリプトファイルを記述することで、GNU makeのMakefileやVisual Studio及びXcodeのプロジェクト等を生成することが可能です。 nlib
ではcmakeを利用することで、Visual Studioの各バージョンに対応したソリューションファイル,Unix, Cygwin用のMakefile等を生成しプログラムをビルドすることが可能となります。 ./cmake/toolchain-cafe.cmake
, ./cmake/toolchain-ctr.cmake
ファイルにクロスコンパイル用の各種設定がされていて、CAFE/CTR版のサンプルプログラムもcmakeを利用してMakefileを生成し、ビルドすることが可能です。 なお、nlib
のCAFE版及びCTR版には標準のmake, omake用のスクリプトも用意されています。nlib
を利用する際によく遭遇する状況と対処法について説明します。nlib
はメモリの確保にはnew (std::nothrow)
を利用しています。 アプリケーション、又は他のライブラリでnew/delete
をオーバーロードする場合には、operator new(size_t, const std::nothrow_t&)
もオーバーロードする必要があります。 nlib
はmalloc, free
を直接使うことはしていません。代わりにnlib_malloc()
, nlib_free()
等を利用します。 これらの関数はweak関数として定義されていてユーザーが定義することで置き換え可能です。 cmake/common.cmake.win32
等のファイルにプラットフォーム毎のスイッチ等の定義が記述されています。 参考にしてください。nlib
を利用するプロジェクトの判断に委ねられます。 受け入れテストを記述しておくことで、そういった判断をより容易にすることができます。 ただし、サポートの対象となるのは最新版のみです。ご了承ください。nlib
を利用するプロジェクト側においてnlib
のパッケージを再構成、再パッケージを行いプロジェクト内においてのみ再配布することが認められています。nlib_printf()
の入力文字列はUTF-8である必要があります。misc
ライブラリにDynamicAlignedStorage
クラスを追加しました。 misc
ライブラリにLockFreeUnitHeap
クラスを追加しました。 misc
ライブラリにLockFreePipe
クラスを追加しました。 misc
ライブラリにLockFreeStack
クラスを追加しました。 misc
ライブラリにLockFreeQueue
クラスを追加しました。 misc
ライブラリにLockFreeInit()
関数を追加しました。 misc
ライブラリにLockFreePriorityQueue
クラスを追加しました。 misc
ライブラリにLockFreeBroadcastQueue
クラスを追加しました。 nmalloc_aligned()
で4096より大きいアライメントを指定できるようになりました。 nmalloc()
, nrealloc()
で大きすぎるサイズを指定した場合にNULL
以外を返すことがある問題を修正しました。 Crc32
クラスの計算速度の改善を行いました。 nlib_mq_open()
, nlib_mq_send()
, nlib_mq_receive()
等の関数が追加されていて、ブロッキングキュー、ノンブロッキングキュー、ロックフリーキューに対応しています。 nlib_condrwlock
型と関数群を追加しました。リードロック、ライトロックのどちらか一方をアンロックして待つことができます。C++用のクラスはnn::nlib::threading::CondVarForSharedCriticalSection
となります。 nlib_atomic_compare_exchange32()
, nlib_atomic_compare_exchange64()
, nlib_atomic_compare_exchangeptr()
等のアトミック操作関数を追加しました。メモリオーダーの指定に対応しています。 nlib_atomic32_xxxxx()
, nlib_atomic64_xxxxx()
等のアトミック操作関数をdeprecatedとしました。 nlib_ns
を名前空間nn::nlib
のエイリアスとして定義しました。 oss
ライブラリに含まれるLZ4をバージョン1.7.0にアップデートしました。 oss
ライブラリにnn::nlib::oss::Lz4InputStream
及びnn::nlib::oss::Lz4OutputStream
を追加しました。 lz4_nlib
を追加しました。 misc
ライブラリにHandleMaker
クラスを追加しました。ハンドル(32bit整数値)と何らかのオブジェクトの関連付けの実装をサポートするためのクラスです。 misc
ライブラリにnlib_spinlock_init()
, nlib_spinlock_lock()
, nlib_spinlock_trylock()
, nlib_spinlock_unlock()
関数を追加しました。 misc
ライブラリにnlib_thread_exit()
, nlib_thread_exit_cpp()
関数を追加しました。 misc
ライブラリにnlib_thread_attr_setstack()
, nlib_thread_attr_getstack()
関数を追加しました。それに伴い、NLIB_THREAD_ATTR_KEY_STACKADDR
マクロは削除されています。 misc
ライブラリにnlib_error_string()
関数を追加しました。 misc
ライブラリのthreading::ThreadSettings
クラスの仕様が変更になり、nlib_thread_attr
をラップするようになりました。ソースコードレベルの互換性が失われるので関連するコードの修正が必要となります。 NLIB_NMALLOC_DISABLE_TLSCACHE
, NLIB_NMALLOC_HEAPSIZE
, NLIB_NMALLOC_MODE
でカスタマイズできるようになりました。 nmalloc_aligned()
が指定されたアライメントのメモリを割り当てないことがある問題を修正しました。 nmalloc_heaphash()
のハッシュの品質を改善しました。 testing
ライブラリのサンプルがXMLをファイルに出力しなくなった問題を修正しました。 nlib_strerror()
がdeprecatedとなりました。 threading::CondVar::Init()
がdeprecatedとなりました。 oss
ライブラリに含まれるLZ4をバージョン1.6.0にアップデートしました。 testing
ライブラリにASSERT_STRCASEEQ()
, ASSERT_STRCASENE()
, EXPECT_STRCASEEQ()
, EXPECT_STRCASENE()
マクロを追加しました。 testing
ライブラリがGoogle Testがサポートしている環境変数のうちのいくつかを読むようになりました。 misc
ライブラリにnlib_disk_freespace()
関数を追加しました。 misc
ライブラリにnlib_fd_readv()
関数及びnlib_fd_writev()
関数を追加しました。 misc
ライブラリにnlib_fd_preadv()
関数及びnlib_fd_pwritev()
関数を追加しました。 misc
ライブラリのOutputStream
クラスにOutputStream::WriteGather()
メンバ関数を追加しました。 misc
ライブラリのNflags
クラスにNflags::GetBoolFromEnv()
, Nflags::GetInt32FromEnv()
, Nflags::GetInt64FromEnv()
, Nflags::GetDoubleFromEnv()
, Nflags::GetStringFromEnv()
メンバ関数を追加しました。 StringInputStream
がdeprecatedとなりました。 oss
ライブラリのライブラリファイルがOSS毎に分割されました。 スタティックライブラリではなく、DLLやシェアードライブラリではリンク時のデッドコードストリップという手段では該当OSSのバイナリを取り除くことができないことが理由となります。 _d
'がつくようになりました。意図しないDLLやシェアードライブラリをダイナミックリンクしてしまう間違いを避けるための措置です。 msvc
というディレクトリに統一されます。 nx_misc-vc120.lib
, nx_misc-vc120_d.lib
のように命名されます。 LD_LIBRARY_PATH
の設定が不要になります。 DateTime
クラスがasctime
形式の読み書きに対応しました。 array
, unordered_map
, tuple
の読み書きに対応しました。 -fvisiblity=hidden
, -fvisibility-inlines-hidden
オプションを追加しました。 これによりライブラリが公開するシンボルの数が減少しています。 oss
ライブラリに高速な圧縮展開ライブラリLZ4(https://github.com/Cyan4973/lz4)を追加しました。多くの場合、圧縮はzlib
の約20倍、展開はzlib
の約5倍程度(CAFEでは約3倍)で動作します。 OutputDebugString()
での出力, syslog(Linux/FreeBSD)又はイベントログ(Windows), ファイル を指定することが可能です。 errno.h
で定義される)がnlibによって独自に定義される場合、その値をboost
ライブラリ(http://www.boost.org/)のcerrno.hpp(http://www.boost.org/doc/libs/1_57_0/boost/cerrno.hpp)で定義される値と同一の値を定義するように変更しました。nlibをboost
ライブラリと共用する場合の動作が改善されます。 heap
ライブラリ(DLL/shared libraryの場合)の終了(アンロード)処理を改善しました。 heap
ライブラリにおいて、特定の状況でメタデータが破壊されることがあるバグを修正しました。 heap
ライブラリの性能を改善しました。 oss
ライブラリに収録されているSQLiteをバージョン3.8.7にアップデートしました。 heap
ライブラリのサンプルにgameheapサンプルを追加しました。 heap
ライブラリのヒープを用いて実装しています。 heap
ライブラリのnmalloc
のスレッドキャッシュの領域がリークすることがあるバグを修正しました。 exi
ライブラリのテキストのXMLパーサー利用時に、テキストノードの文字列がアロケータの削除以前に無効となる動作を修正しました。 exi
ライブラリのXmlStreamEventLogger を削除しました。 nlib_sock
のtypedefをSOCKET型からint型に変更しました。 simd
ライブラリのNEON用コードを実際のARMアーキテクチャ用クロスコンパイラ(gcc 4.9)でビルドできるようにしました。 simd
ライブラリのコードにAArch64向けのコードを追加しました。 nlib
のセットアップについての説明を改善しました。 nn::nlib::unicode
名前空間内のいくつかの関数をdeprecatedにしました。将来のリリースで削除されます。 misc
ライブラリからnn/nlib/threading/SimpleRingBuffer.hを削除しました。 misc
ライブラリからnn/nlib/threading/Interlocked.hを削除しました。今後はnlib_atomic32_increment()等のCリンケージの関数を直接ご利用ください。 misc
ライブラリからnn/nlib/threading/CallOnce.hを削除しました。 SimpleRingBuffer
クラスの定義をライブラリ本体から misc/threading/simpleringbuffer/simpleringbuffer.cpp サンプルへ移動させました。 simd
ライブラリがCAFEのpaired singleに対応しました。単精度浮動小数点数を用いる計算にpaired singleが用いられるようになりました。 simd
ライブラリにクラスと関数が追加されました。 Frustum
クラスの追加。 exi
ライブラリ(Text xml parser)のトークナイザがXML属性用に確保するバッファの初期サイズを調整しました。 © 2013, 2014, 2015 Nintendo Co., Ltd. All rights reserved.