├── .gitignore ├── LICENSE ├── README.md ├── build ├── build.js ├── clean.bat ├── codecheck.vcxproj ├── codecheck.vcxproj.filters ├── nixy.sln ├── nixycore.vcxproj └── nixycore.vcxproj.filters ├── codecheck ├── dummy.cpp ├── main.cpp ├── nedmalloc │ ├── malloc.c.h │ ├── nedmalloc.c │ └── nedmalloc.h ├── test_algorithm.h ├── test_bugfix.h ├── test_delegate.h ├── test_finalizer.h ├── test_head.h ├── test_memory.h ├── test_preprocessor.h ├── test_random.h ├── test_stream.h ├── test_string.h ├── test_thread.h ├── test_time.h ├── test_typemanip.h └── test_utility.h ├── nixycore ├── algorithm │ ├── algorithm.h │ ├── assign.h │ ├── container.h │ ├── foreach.h │ └── series.h ├── bugfix │ ├── assert.h │ ├── assert_detail.h │ ├── bugfix.h │ ├── noexcept.h │ ├── output.h │ └── trace.h ├── container │ ├── any.h │ ├── array.h │ ├── container.h │ ├── deque.h │ ├── forward_list.h │ ├── hash_map.h │ ├── hash_set.h │ ├── list.h │ ├── map.h │ ├── priority.h │ ├── queue.h │ ├── set.h │ ├── stack.h │ └── vector.h ├── delegate │ ├── bind.h │ ├── delegate.h │ ├── function_traits.h │ ├── functor.h │ └── signal.h ├── finalizer │ ├── finalizer.h │ ├── gc.h │ ├── holder.h │ ├── ref_counter.h │ └── scope_guard.h ├── general │ ├── detail │ │ ├── plat_detect_cc.hxx │ │ ├── plat_detect_os.hxx │ │ ├── plat_detect_pc.hxx │ │ └── plat_detect_sp.hxx │ ├── general.h │ ├── global_functions.h │ └── plat_detect.h ├── memory │ ├── alloc.h │ ├── alloc_model.h │ ├── cache_pool.h │ ├── center_heap.h │ ├── construct.h │ ├── default_alloc.h │ ├── detail │ │ └── skip_array.h │ ├── fixed_pool.h │ ├── mem_alloc.h │ ├── mem_guard.h │ ├── mem_leak.h │ ├── mem_pool.h │ ├── memory.h │ ├── object_pool.h │ ├── pointer.h │ ├── std_alloc.h │ └── unfixed_pool.h ├── pattern │ ├── iterator.h │ ├── pattern.h │ ├── prototype.h │ ├── singleton.h │ └── trackable.h ├── preprocessor │ ├── pp_arg.h │ ├── pp_count.h │ ├── pp_macros.h │ ├── pp_mult.h │ ├── pp_nest.h │ ├── pp_repeat.h │ └── preprocessor.h ├── random │ ├── rand_mt19937.h │ ├── rand_std.h │ └── random.h ├── stream │ ├── detail │ │ ├── stream_buffer_in.hxx │ │ └── stream_buffer_out.hxx │ ├── printf_format.h │ ├── stream.h │ ├── stream_buffer.h │ ├── stream_detail.h │ ├── stream_ops.h │ └── stream_wrap.h ├── string │ ├── detail │ │ └── string_ops_define.hxx │ ├── string.h │ ├── string_detail.h │ └── transform.h ├── thread │ ├── async.h │ ├── atomic.h │ ├── barrier.h │ ├── blocking_queue.h │ ├── condition.h │ ├── detail │ │ ├── barrier_gnuc.hxx │ │ ├── barrier_msvc.hxx │ │ ├── condition_linux.hxx │ │ ├── condition_win.hxx │ │ ├── interlocked_def_msvc.hxx │ │ ├── interlocked_gnuc.hxx │ │ ├── interlocked_msvc.hxx │ │ ├── mutex_linux.hxx │ │ ├── mutex_win.hxx │ │ ├── thread_ops_define.hxx │ │ ├── thread_ops_linux.hxx │ │ ├── thread_ops_std.hxx │ │ ├── thread_ops_win.hxx │ │ ├── tls_ptr_linux.hxx │ │ └── tls_ptr_win.hxx │ ├── future.h │ ├── interlocked.h │ ├── lock_guard.h │ ├── mutex.h │ ├── promise.h │ ├── semaphore.h │ ├── spin_lock.h │ ├── task.h │ ├── thread.h │ ├── thread_detail.h │ ├── thread_model.h │ ├── thread_ops.h │ ├── thread_pool.h │ ├── tls_ptr.h │ └── waiter.h ├── time │ ├── stopwatch.h │ ├── tickcount.h │ └── time.h ├── typemanip │ ├── detail │ │ └── typeof_msvc.hxx │ ├── typebehavior.h │ ├── typeconcept.h │ ├── typedecay.h │ ├── typedefs.h │ ├── typedetect.h │ ├── typelist.h │ ├── typemanip.h │ ├── typeof.h │ ├── typequalifier.h │ ├── typerelation.h │ ├── typetools.h │ └── typetraits.h └── utility │ ├── addressof.h │ ├── alignof.h │ ├── countof.h │ ├── final.h │ ├── forward.h │ ├── initialize.h │ ├── limit_of.h │ ├── max_min.h │ ├── noncopyable.h │ ├── operator.h │ ├── refer.h │ ├── rvalue.h │ ├── safe_bool.h │ ├── tuple.h │ ├── type_cast.h │ ├── utility.h │ └── valid.h └── nixyx ├── config.cpp ├── config.h ├── config_base.h ├── config_ini.h ├── config_js.h ├── main.cpp ├── nixyx.pro ├── platform.cpp ├── platform.h ├── platform_base.h ├── platform_gcc.h ├── platform_vc.h ├── policy_vc10.h ├── policy_vc11.h ├── policy_vc12.h ├── policy_vc8.h ├── policy_vc9.h ├── policy_vc_base.h ├── solution.h └── tools.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | 5 | # Libraries 6 | *.lib 7 | *.a 8 | 9 | # Shared objects (inc. Windows DLLs) 10 | *.dll 11 | *.so 12 | *.so.* 13 | *.dylib 14 | 15 | # Executables 16 | *.exe 17 | *.out 18 | *.app 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Nixy Library - A Lightweight C++ Library 2 | Copyright (c) 2013-2014, mutouyun (http://orzz.org). All rights reserved. 3 | https://code.google.com/p/nixy/ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The Nixy Library 2 | 3 | 这是一个小巧灵活的 跨平台/编译器的 C++基础库 4 | 5 | * 目前支持的OS: Windows(32/64/CE), Linux(Desktop/ARM) 6 | * 目前支持的CC: VC(8.0+), gcc, clang 7 | 8 | ## nixyx 9 | 10 | 1. Nixy的构建系统, 使用 Qt 编写 11 | 2. 脚本可以使用ini和js, 其中ini不支持条件判断和循环(当然了,这货只是个ini), 仅用于最简单的情况 12 | 3. 目前支持生成: Makefile, Visual Studio项目文件(Format Version 9.00 以上) 13 | 14 | ## nixycore 15 | 16 | 1. Nixy的核心部分, 基于泛型思想搭建的C++库 17 | 2. 目标: 代码轻巧, 功能灵活, 使用方便 18 | 19 | - [x] bugfix - 用于简化调试和排错 20 | - [x] container - 各种泛型容器 21 | - [x] delegate - 委托,包括泛化仿函数、绑定器等 22 | - [x] finalizer - 资源管理,包括通用rc和gc实现等 23 | - [x] memory - 内存管理,包括内存池、通用内存分配器、rc智能指针等 24 | - [x] preprocessor - 预处理器,用于对编译器的预处理阶段编程,一般用于自动代码生成 25 | - [x] stream - 输入输出流,包括简单的format功能 26 | - [x] string - 字符串相关,包括字符编码处理、字符串存储等 27 | - [x] typemanip - 类型操作,用于对编译器的编译期编程,实现各种泛型技巧 28 | - [x] thread - 线程管理,包括原子类、各种线程同步对象、线程类等 29 | - [x] utility - 各种实用小工具 30 | - [ ] general - 全库的通用部分 31 | - [ ] algorithm - 提供一些基本的算法 32 | - [ ] file - 文件处理 33 | - [ ] pattern - 模式,包括一部分可以通用化的设计模式 34 | - [ ] random - 随机数生成器 35 | - [ ] time - 时间管理 36 | -------------------------------------------------------------------------------- /build/clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | cd .. 4 | 5 | for /r %%a in (.) do ( 6 | set list=%%a 7 | setlocal enabledelayedexpansion 8 | if "!list:~-8,6!"=="-Debug" rd /q /s "!list:~0,-2!" 9 | if "!list:~-10,8!"=="-Release" rd /q /s "!list:~0,-2!" 10 | endlocal 11 | ) 12 | 13 | rd /q /s "build/!bin" 14 | rd /q /s "build/!tmp" 15 | rd /q /s "build/debug" 16 | rd /q /s "build/release" 17 | 18 | del /f /q /s /a *.user *.ncb *.suo *.sdf *.i -------------------------------------------------------------------------------- /build/codecheck.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /build/nixy.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 14 3 | VisualStudioVersion = 14.0.24720.0 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "codecheck", "codecheck.vcxproj", "{E7486F48-C460-4688-8BA9-6A9A39B26F94}" 6 | ProjectSection(ProjectDependencies) = postProject 7 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED} = {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED} 8 | EndProjectSection 9 | EndProject 10 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nixycore", "nixycore.vcxproj", "{23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|x64 = Debug|x64 15 | Debug|x86 = Debug|x86 16 | Release|x64 = Release|x64 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Debug|x64.ActiveCfg = Debug|x64 21 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Debug|x64.Build.0 = Debug|x64 22 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Debug|x86.ActiveCfg = Debug|Win32 23 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Debug|x86.Build.0 = Debug|Win32 24 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Release|x64.ActiveCfg = Release|x64 25 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Release|x64.Build.0 = Release|x64 26 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Release|x86.ActiveCfg = Release|Win32 27 | {E7486F48-C460-4688-8BA9-6A9A39B26F94}.Release|x86.Build.0 = Release|Win32 28 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Debug|x64.ActiveCfg = Debug|x64 29 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Debug|x64.Build.0 = Debug|x64 30 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Debug|x86.ActiveCfg = Debug|Win32 31 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Debug|x86.Build.0 = Debug|Win32 32 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Release|x64.ActiveCfg = Release|x64 33 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Release|x64.Build.0 = Release|x64 34 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Release|x86.ActiveCfg = Release|Win32 35 | {23C0BEBC-BB9D-4A10-86BF-1AA06909A1ED}.Release|x86.Build.0 = Release|Win32 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | EndGlobal 41 | -------------------------------------------------------------------------------- /codecheck/dummy.cpp: -------------------------------------------------------------------------------- 1 | //#include "nixycore/time/time.h" 2 | //#include "nixycore/typemanip/typemanip.h" 3 | //#include "nixycore/memory/memory.h" 4 | //#include "nixycore/thread/thread.h" 5 | #include "nixycore/container/container.h" 6 | #include "nixycore/delegate/delegate.h" 7 | 8 | void dummy(void) 9 | { 10 | } 11 | -------------------------------------------------------------------------------- /codecheck/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | ////////////////////////////////////////////////////////////////////////// 3 | //#define _WIN32_WINNT 0x0601 4 | #include "test_head.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | void dummy(void); 9 | 10 | int main(void) 11 | { 12 | cout << __cplusplus << endl; 13 | dummy(); 14 | testAll(); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /codecheck/test_bugfix.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/bugfix/bugfix.h" 4 | 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | void testAssert(void) nx_noexcept 8 | { 9 | TEST_CASE(); 10 | 11 | bool b = true; 12 | int i = 1, j = 2; 13 | char what[] = "What's up"; 14 | 15 | try 16 | { 17 | nx_assert(b = false)(i)(j)(what).msg("blabla").except(b); 18 | strout << b << endl; 19 | } 20 | catch(const nx::assert_context&) 21 | { 22 | strout << "catched assert_context!" << endl; 23 | } 24 | catch(bool b) 25 | { 26 | strout << "catched bool: " << b << endl; 27 | } 28 | catch(...) 29 | { 30 | strout << "What?!" << endl; 31 | } 32 | } 33 | 34 | ////////////////////////////////////////////////////////////////////////// 35 | 36 | void testTrace(void) 37 | { 38 | TEST_CASE(); 39 | 40 | nx_trace("I %x seiko")("love") << nx::endl; 41 | nx_trace()("seiko ") << 123 << nx::endl<2>; 42 | } 43 | 44 | ////////////////////////////////////////////////////////////////////////// 45 | 46 | void testBugFix(void) 47 | { 48 | TEST_FUNCTION(); 49 | 50 | testAssert(); 51 | testTrace(); 52 | } 53 | -------------------------------------------------------------------------------- /codecheck/test_finalizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/finalizer/finalizer.h" 4 | 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | namespace test_scopeguard 8 | { 9 | void onScopeExit(void) 10 | { 11 | strout << NX__FUNCTION__ << endl; 12 | } 13 | 14 | void onSoleExit(void) 15 | { 16 | strout << NX__FUNCTION__ << endl; 17 | } 18 | } 19 | 20 | void testScopeGuard(void) 21 | { 22 | TEST_CASE(); 23 | 24 | using namespace test_scopeguard; 25 | 26 | { 27 | nx_guard_scope(onScopeExit); 28 | static nx_guard_scope(onSoleExit); 29 | 30 | # ifdef NX_SP_CXX11_LAMBDA 31 | nx_guard_scope([]() 32 | { 33 | strout << NX__FUNCTION__ << endl; 34 | }); 35 | # endif 36 | } 37 | 38 | strout << __FUNCTION__ << " ending..." << endl; 39 | } 40 | 41 | ////////////////////////////////////////////////////////////////////////// 42 | 43 | namespace test_gc 44 | { 45 | template 46 | void new_dest(T* p) 47 | { 48 | if (!p) return; 49 | strout << NX__FUNCTION__ << " ->: "; 50 | delete p; 51 | } 52 | 53 | class A 54 | { 55 | public: 56 | int a_; 57 | 58 | public: 59 | A(int a = 0) : a_(a) 60 | { strout << "cont A " << a_ << endl; } 61 | ~A(void) 62 | { strout << "dest A " << a_ << endl; } 63 | }; 64 | 65 | class B 66 | { 67 | public: 68 | A* p_; 69 | 70 | public: 71 | B(int a = 0) : p_(nx::nulptr) 72 | { 73 | nx_gc_scope() = this; 74 | gc(p_)(new A(a), new_dest); 75 | strout << "cont B " << p_->a_ << endl; 76 | } 77 | ~B(void) 78 | { 79 | strout << "dest B " << p_->a_ << endl; 80 | } 81 | }; 82 | 83 | void func_scope(B*(& pd)) 84 | { 85 | nx_gc_scope(); 86 | gc(pd)(new B(4), new_dest); 87 | } 88 | } 89 | 90 | void testGC(void) 91 | { 92 | TEST_CASE(); 93 | 94 | using namespace test_gc; 95 | { 96 | nx_gc_scope(); 97 | 98 | A* pa = nx::nulptr; 99 | A* pb = nx::nulptr; 100 | 101 | gc(pa)(new A(1), new_dest); 102 | gc(pb) = nx::alloc(2); 103 | gc(pb) = pa; 104 | 105 | B* pd = nx::nulptr; 106 | gc(pd) = nx::alloc(3); 107 | 108 | strout << "...scope in..." << endl; 109 | func_scope(pd); 110 | strout << "...scope out..." << endl; 111 | 112 | gc(pd) = nx::alloc(5); 113 | 114 | strout << "...start dest..." << endl; 115 | } 116 | strout << endl << "Finish Scope" << endl << endl; 117 | { 118 | nx_gc_scope(); 119 | B* NX_UNUSED pb = gc(nx::alloc(2)); 120 | A* NX_UNUSED pa = gc(new A(1), new_dest); 121 | } 122 | } 123 | 124 | ////////////////////////////////////////////////////////////////////////// 125 | 126 | void testFinalizer(void) 127 | { 128 | TEST_FUNCTION(); 129 | 130 | //testScopeGuard(); 131 | testGC(); 132 | } 133 | -------------------------------------------------------------------------------- /codecheck/test_head.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | ////////////////////////////////////////////////////////////////////////// 4 | 5 | #ifndef CODECHECK_CUSTOM_STROUT 6 | 7 | #include 8 | 9 | using std::cout; 10 | using std::endl; 11 | 12 | #define strout cout 13 | 14 | #endif/*CODECHECK_CUSTOM_STROUT*/ 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | #define TEST_FUNCTION(...) \ 19 | strout << endl \ 20 | << "==================================" << endl \ 21 | << "\t" __VA_ARGS__ << __FUNCTION__ << endl \ 22 | << "==================================" << endl 23 | 24 | #define TEST_CASE(...) \ 25 | strout << endl \ 26 | << "----------------------------------" << endl \ 27 | << "\t" __VA_ARGS__ << __FUNCTION__ << " ->: " << endl \ 28 | << "----------------------------------" << endl 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | 32 | //#define NX_SINGLE_THREAD 33 | //#define NX_NO_CXX11_ATOMIC 34 | //#define NX_NO_CXX11_RVALUE_REF 35 | //#define NX_NO_CXX11_PERFECT_FWD 36 | //#define NX_NO_CXX11_AUTO 37 | 38 | #include "test_preprocessor.h" 39 | #include "test_bugfix.h" 40 | #include "test_typemanip.h" 41 | #include "test_algorithm.h" 42 | #include "test_utility.h" 43 | #include "test_time.h" 44 | #include "test_random.h" 45 | #include "test_delegate.h" 46 | #include "test_thread.h" 47 | #include "test_memory.h" 48 | #include "test_finalizer.h" 49 | #include "test_string.h" 50 | #include "test_stream.h" 51 | 52 | ////////////////////////////////////////////////////////////////////////// 53 | 54 | void testAll(void) 55 | { 56 | //testPreprocessor(); 57 | //testBugFix(); 58 | //testTypeManip(); 59 | //testAlgorithm(); 60 | testUtility(); 61 | //testTime(); 62 | //testRandom(); 63 | //testDelegate(); 64 | //testFinalizer(); 65 | //testThread(); 66 | //testMemory(); 67 | //testString(); 68 | //testStream(); 69 | 70 | TEST_FUNCTION(<< "Finished "); 71 | } 72 | -------------------------------------------------------------------------------- /codecheck/test_preprocessor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/general/general.h" 4 | #include "nixycore/preprocessor/preprocessor.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | void testPreprocessor(void) 9 | { 10 | TEST_FUNCTION(); 11 | 12 | strout << NX_PP_STR(NX_PP_REPEAT(5, f, d1, d2)) << endl; 13 | strout << NX_PP_STR(NX_PP_NEST(3, func, last, nest, xx)) << endl; 14 | 15 | strout << NX_PP_STR(NX_PP_CLONE(6, c, ,)) << endl; 16 | 17 | strout << NX_PP_STR(NX_PP_REV(1, 2, 3, 4, 5, 6, 7, 8, 9)) << endl; 18 | strout << NX_PP_STR(NX_PP_LIMIT(3, a, b, c, d, e, f)) << endl; 19 | 20 | strout << NX_PP_STR(NX_PP_INC(5)) << endl; 21 | strout << NX_PP_STR(NX_PP_DEC(5)) << endl; 22 | strout << NX_PP_STR(NX_PP_ADD(3, 4)) << endl; 23 | strout << NX_PP_STR(NX_PP_SUB(5, 3)) << endl; 24 | 25 | strout << NX_PP_STR(NX_PP_LESS(3, 4, Yes, No)) << endl; 26 | strout << NX_PP_STR(NX_PP_MORE(3, 4, Yes, No)) << endl; 27 | strout << NX_PP_STR(NX_PP_EQUA(4, 4, Yes, No)) << endl; 28 | 29 | strout << NX_PP_STR(NX_PP_RECUR(9, f, nul, c)) << endl; 30 | strout << NX_PP_STR(NX_PP_ORDER(f, 1, 2, 3, 4, 5, 6, 7, 8, 9)) << endl; 31 | strout << NX_PP_STR(NX_PP_CALL(func)) << endl; 32 | 33 | strout << NX_PP_STR(NX_PP_PARAM(par, int, char, long, double)) << endl; 34 | 35 | strout << NX_PP_STR(NX_PP_TYPE_1(3, T)) << endl; 36 | strout << NX_PP_STR(NX_PP_TYPE_2(3, P, * par, = NULL)) << endl; 37 | strout << NX_PP_STR(NX_PP_TYPE_1(1, typename P)) << endl; 38 | 39 | //#define NX_REPEAT_2(f1, f2, ...) f1(1, __VA_ARGS__) f2(2, __VA_ARGS__) 40 | //#define NX_MULT_2(f) f(1) f(2) 41 | // 42 | //#define NX_TYPE_1_1(n, t1, ...) NX_PP_VA(NX_PP_JOIN(t1, n) __VA_ARGS__) 43 | //#define NX_TYPE_1_2(n, t1, ...) NX_PP_VA(, NX_PP_JOIN(t1, n) __VA_ARGS__) 44 | // 45 | //#define NX_RP(n) NX_REPEAT_2(NX_TYPE_1_1, NX_TYPE_1_2, T) 46 | // 47 | // NX_MULT_2(NX_RP) 48 | } 49 | -------------------------------------------------------------------------------- /codecheck/test_random.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/random/random.h" 4 | #include "nixycore/utility/countof.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | void testRandMT19937(void) 9 | { 10 | TEST_CASE(); 11 | 12 | nx::random<> rdm(0, 10000); 13 | int save[10]; 14 | int save_index = 0, save_counter[nx_countof(save)] = {0}; 15 | char snm[6]; 16 | 17 | FILE* fp = fopen("test_rand_mt19937.txt", "wb"); 18 | for (int i = 0; i < 1000000; ++i) 19 | { 20 | int x = rdm.roll(); 21 | int n = 0; 22 | for (; n < save_index; ++n) 23 | { 24 | if (save[n] == x) 25 | { 26 | save_counter[n] += 1; 27 | break; 28 | } 29 | } 30 | if (n >= save_index && save_index < (int)nx_countof(save)) 31 | { 32 | save_counter[save_index] += 1; 33 | save[save_index++] = x; 34 | } 35 | 36 | sprintf(snm, "%d", x); 37 | for (unsigned int m = 0; (m < nx_countof(snm)) && snm[m]; ++m) 38 | fwrite(snm + m, sizeof(char), 1, fp); 39 | fwrite("\r\n", sizeof(char), 2, fp); 40 | } 41 | fclose(fp); 42 | 43 | for (unsigned int n = 0; n < nx_countof(save); ++n) 44 | strout << save[n] << "\t->: " << save_counter[n] << endl; 45 | } 46 | 47 | ////////////////////////////////////////////////////////////////////////// 48 | 49 | void testRandom(void) 50 | { 51 | TEST_FUNCTION(); 52 | 53 | testRandMT19937(); 54 | } 55 | -------------------------------------------------------------------------------- /codecheck/test_stream.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/string/string.h" 4 | #include "nixycore/stream/stream.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | void testStreamDetail(void) 9 | { 10 | TEST_CASE(); 11 | 12 | nx::string text; 13 | { 14 | nx::format(&text, L"pi: %x%x\ntest bool: %x and %x") << 3.1415 << "926" << true << false; 15 | } 16 | strout << text.to_local().c_str() << endl << endl; 17 | { 18 | nx::io(&text) << 3.1415 << L"926" << true << false; 19 | } 20 | strout << text.to_local().c_str() << endl << endl; 21 | { 22 | text = L"I think is true && -3.1415926 && I-love-Sego"; 23 | bool is_what = false; 24 | float pi = 0; 25 | nx::string tmp; 26 | nx::format(&text, L"I think is %x && %x && %x") >> is_what >> pi >> tmp; 27 | strout << is_what << " " << pi << " " << tmp.to_local().c_str() << endl; 28 | } 29 | } 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | 33 | void testStreamOps(void) 34 | { 35 | TEST_CASE(); 36 | 37 | nx::string text; 38 | nx::io(&text) << L"pi is about: " << nx::fmt("%.2f", 3.1415) << nx::endl<2>; 39 | strout << text.to_local().c_str() << endl; 40 | } 41 | 42 | ////////////////////////////////////////////////////////////////////////// 43 | 44 | void testStream(void) 45 | { 46 | TEST_FUNCTION(); 47 | 48 | testStreamDetail(); 49 | testStreamOps(); 50 | } 51 | -------------------------------------------------------------------------------- /codecheck/test_string.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/string/string.h" 4 | 5 | ////////////////////////////////////////////////////////////////////////// 6 | 7 | namespace test_string 8 | { 9 | const char* c = "Hello world 你好世界 こんにちわ、世界"; 10 | } 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | 14 | void testTransform(void) 15 | { 16 | TEST_CASE(); 17 | 18 | using namespace test_string; 19 | 20 | size_t n = nx::transform::local_to_utf(c); 21 | wchar_t* s = new wchar_t[n]; 22 | n = nx::transform::local_to_utf(c, s, n); 23 | FILE* fp = fopen("test_transform_s.txt", "wb"); 24 | fwrite(s, sizeof(wchar_t), n - 1, fp); 25 | fclose(fp); 26 | strout << "local_to_utf size: " << n << endl; 27 | 28 | n = nx::transform::utf_to_local(s); 29 | char* z = new char[n]; 30 | n = nx::transform::utf_to_local(s, z, n); 31 | fp = fopen("test_transform_z.txt", "wb"); 32 | fwrite(z, sizeof(char), n - 1, fp); 33 | fclose(fp); 34 | strout << "utf_to_local size: " << n << endl; 35 | 36 | //wchar_t* s = new wchar_t[n]; 37 | //size_t m = nx::transform::utf(c, s); 38 | //strout << n << " " << m << endl; 39 | /* 40 | wstring s; 41 | size_t n; nx::wchar w; 42 | while (!!(n = nx::transform::utf(c, w))) 43 | { 44 | s.push_back(w); 45 | c += n; 46 | }*/ 47 | } 48 | 49 | ////////////////////////////////////////////////////////////////////////// 50 | 51 | void testStringDetail(void) 52 | { 53 | TEST_CASE(); 54 | 55 | using namespace test_string; 56 | 57 | nx::string str('c'); 58 | 59 | str = c; 60 | str = str + "\r\ncstring: 123123\r\n" 61 | + L"wstring: 一二三一二三\r\n" 62 | + 'c' 63 | + "\r\n"; 64 | str += L'夏'; 65 | 66 | FILE* fp = fopen("test_string.txt", "wb"); 67 | fwrite(str.c_str(), sizeof(wchar_t), str.length(), fp); 68 | fclose(fp); 69 | 70 | nx::vector arr = str.split(); 71 | nx_foreach(s, arr) 72 | strout << s.to_local().c_str() << endl; 73 | } 74 | 75 | ////////////////////////////////////////////////////////////////////////// 76 | 77 | void testString(void) 78 | { 79 | TEST_FUNCTION(); 80 | 81 | //testTransform(); 82 | testStringDetail(); 83 | } 84 | -------------------------------------------------------------------------------- /codecheck/test_time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "nixycore/time/time.h" 4 | #include "nixycore/thread/thread_ops.h" 5 | 6 | #include 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | #ifndef STOPWATCH_CHECKER 11 | #define STOPWATCH_CHECKER(op) \ 12 | strout << "stopwatch ->: " << #op << endl; \ 13 | sw.op(); \ 14 | for(int i = 0; i < 5; ++i) \ 15 | { \ 16 | nx::thread_ops::sleep(100); \ 17 | strout << "stopwatch ->: " << sw.value() << endl; \ 18 | } 19 | #endif 20 | 21 | void testStopwatch(void) 22 | { 23 | TEST_CASE(); 24 | 25 | strout << std::setiosflags(std::ios_base::showpoint); 26 | nx::stopwatch<> sw; 27 | STOPWATCH_CHECKER(start) 28 | STOPWATCH_CHECKER(pause) 29 | STOPWATCH_CHECKER(start) 30 | STOPWATCH_CHECKER(stop) 31 | STOPWATCH_CHECKER(start) 32 | STOPWATCH_CHECKER(start) 33 | strout << std::resetiosflags(std::ios_base::showpoint); 34 | } 35 | 36 | #undef STOPWATCH_CHECKER 37 | #undef STOPWATCH_SLEEP 38 | 39 | ////////////////////////////////////////////////////////////////////////// 40 | 41 | void testTime(void) 42 | { 43 | TEST_FUNCTION(); 44 | 45 | testStopwatch(); 46 | } 47 | -------------------------------------------------------------------------------- /nixycore/algorithm/foreach.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/algorithm/container.h" 11 | 12 | #include "nixycore/typemanip/typetools.h" 13 | #include "nixycore/typemanip/typetraits.h" 14 | #include "nixycore/typemanip/typeof.h" 15 | 16 | #include "nixycore/general/general.h" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifdef NX_SP_CXX11_RANGEFOR 23 | #define nx_foreach(var, col, ...) \ 24 | for(auto var : col) \ 25 | for(bool once__ = true; once__; once__ = false,##__VA_ARGS__) 26 | #else 27 | namespace private_foreach 28 | { 29 | template struct storage { typedef const T & type_t; }; 30 | template struct storage { typedef T & type_t; }; 31 | 32 | template 33 | struct helper 34 | { 35 | typedef typename traits::type_t type_t; 36 | typedef typename container_traits::ite_t ite_t; 37 | typedef typename container_traits::val_t val_t; 38 | typedef typename traits::forward_t deref_t; 39 | typedef typename storage::type_t storage_t; 40 | 41 | T set_; ite_t cur_, end_; 42 | bool mark_; 43 | 44 | helper(storage_t s) 45 | : set_(s) 46 | , cur_(nx::begin(set_)) 47 | , end_(nx::end(set_)) 48 | , mark_(false) 49 | {} 50 | 51 | inline void next(void) { ++cur_; } 52 | inline bool is_inside(void) { return (cur_ != end_); } 53 | inline bool go_next(void) { return (mark_ = !mark_); } 54 | }; 55 | 56 | template 57 | inline helper contain(T & t) // lvalue 58 | { 59 | return helper(t); 60 | } 61 | 62 | template 63 | inline helper contain(T const & t) // rvalue 64 | { 65 | return helper(t); 66 | } 67 | 68 | template 69 | inline typename enable_if::ite_t>::value, 70 | typename helper::deref_t>::type_t deref(helper& hp) 71 | { 72 | return hp.cur_; 73 | } 74 | 75 | template 76 | inline typename enable_if::ite_t>::value, 77 | typename helper::deref_t>::type_t deref(helper& hp) 78 | { 79 | return *(hp.cur_); 80 | } 81 | } 82 | 83 | #define nx_foreach(var, col, ...) \ 84 | for(nx_auto(hp__, nx::private_foreach::contain(col)); hp__.is_inside(); hp__.next(),##__VA_ARGS__) \ 85 | for(nx_auto(var , nx::private_foreach::deref(hp__)) ; hp__.go_next();) 86 | 87 | #endif/*NX_SP_CXX11_RANGEFOR*/ 88 | 89 | #define nx_forever(...) \ 90 | for(__VA_ARGS__;;) 91 | 92 | ////////////////////////////////////////////////////////////////////////// 93 | NX_END 94 | ////////////////////////////////////////////////////////////////////////// 95 | -------------------------------------------------------------------------------- /nixycore/bugfix/bugfix.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/bugfix/noexcept.h" 13 | #include "nixycore/bugfix/output.h" 14 | #include "nixycore/bugfix/assert_detail.h" 15 | #include "nixycore/bugfix/assert.h" 16 | #include "nixycore/bugfix/trace.h" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | -------------------------------------------------------------------------------- /nixycore/bugfix/noexcept.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #include "nixycore/general/general.h" 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | NX_BEG 12 | ////////////////////////////////////////////////////////////////////////// 13 | 14 | #ifdef NX_SP_CXX11_NOEXCEPT 15 | #define nx_noexcept noexcept 16 | #else 17 | #define nx_noexcept throw() 18 | #endif 19 | 20 | ////////////////////////////////////////////////////////////////////////// 21 | NX_END 22 | ////////////////////////////////////////////////////////////////////////// 23 | -------------------------------------------------------------------------------- /nixycore/bugfix/output.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/string/transform.h" 11 | #include "nixycore/utility/countof.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | // std::cout, std::cerr, std::clog 16 | #include 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | namespace use 23 | { 24 | struct std_cout 25 | { 26 | static void out(const char* str) 27 | { 28 | std::cout << str; 29 | } 30 | }; 31 | 32 | struct std_cerr 33 | { 34 | static void out(const char* str) 35 | { 36 | # if defined(NX_OS_WINCE) 37 | nx::wchar wcs[MAX_PATH]; 38 | transform::local_to_utf(str, wcs, nx_countof(wcs)); 39 | ::OutputDebugStringW(wcs); 40 | # else 41 | # if defined(NX_OS_WIN) 42 | ::OutputDebugStringA(str); 43 | # endif 44 | std::cerr << str; 45 | # endif 46 | } 47 | }; 48 | 49 | struct std_clog 50 | { 51 | static void out(const char* str) 52 | { 53 | std::clog << str; 54 | } 55 | }; 56 | } 57 | 58 | template 59 | bool output(const char* fmt, ...) 60 | { 61 | if (!fmt) return false; 62 | bool ret = true; 63 | va_list args; 64 | va_start(args, fmt); 65 | #ifdef NX_OS_WINCE 66 | char buf[MAX_PATH]; 67 | if (::_vsnprintf(buf, nx_countof(buf), fmt, args) > 0) 68 | { 69 | PolicyT::out(buf); 70 | } 71 | else ret = false; 72 | #else 73 | char* buf = static_cast(::malloc(::vsnprintf(NULL, 0, fmt, args) + 1)); 74 | if (buf) 75 | { 76 | if (::vsprintf(buf, fmt, args) > 0) 77 | { 78 | PolicyT::out(buf); 79 | } 80 | else ret = false; 81 | ::free(buf); 82 | } 83 | else ret = false; 84 | #endif 85 | va_end(args); 86 | return ret; 87 | } 88 | 89 | ////////////////////////////////////////////////////////////////////////// 90 | NX_END 91 | ////////////////////////////////////////////////////////////////////////// 92 | -------------------------------------------------------------------------------- /nixycore/bugfix/trace.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/bugfix/output.h" 11 | 12 | #include "nixycore/general/general.h" 13 | #include "nixycore/stream/stream.h" 14 | #include "nixycore/string/string.h" 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | class trace : public nx::stream 21 | { 22 | typedef nx::stream base_t; 23 | 24 | nx::string str_; 25 | 26 | public: 27 | trace(void) 28 | : base_t(&str_) 29 | {} 30 | 31 | template 32 | trace(const S& fs) 33 | : base_t(&str_, fs) 34 | {} 35 | 36 | ~trace(void) 37 | { 38 | base_t::flush(); 39 | nx::output(str_.to_local().c_str()); 40 | } 41 | }; 42 | 43 | namespace private_trace 44 | { 45 | class maker 46 | { 47 | const nx::string::value_type* str_; 48 | 49 | public: 50 | maker(const nx::string::value_type* str) 51 | : str_(str) 52 | {} 53 | 54 | nx::trace operator()(void) 55 | { 56 | return nx::trace(str_); 57 | } 58 | 59 | template 60 | nx::trace operator()(const T& fmt) 61 | { 62 | return nx::trace(nx::string(str_) + fmt); 63 | } 64 | }; 65 | } 66 | 67 | #ifndef NX_ENABLE_TRACE 68 | #ifndef NDEBUG 69 | # define NX_ENABLE_TRACE 70 | #endif 71 | #endif/*NX_ENABLE_TRACE*/ 72 | 73 | #ifdef NX_ENABLE_TRACE 74 | # define nx_trace(...) \ 75 | (nx::private_trace::maker(L"%x\n%x, L: %x ->: ")(__VA_ARGS__) << __FILE__ << NX__FUNCTION__ << __LINE__) 76 | #else /*NX_ENABLE_TRACE*/ 77 | # define nx_trace(...) if (true) ; else nx::trace() 78 | #endif/*NX_ENABLE_TRACE*/ 79 | 80 | ////////////////////////////////////////////////////////////////////////// 81 | NX_END 82 | ////////////////////////////////////////////////////////////////////////// 83 | -------------------------------------------------------------------------------- /nixycore/container/container.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/container/any.h" 13 | #include "nixycore/container/array.h" 14 | #include "nixycore/container/deque.h" 15 | #include "nixycore/container/list.h" 16 | #include "nixycore/container/map.h" 17 | #include "nixycore/container/priority.h" 18 | #include "nixycore/container/queue.h" 19 | #include "nixycore/container/set.h" 20 | #include "nixycore/container/stack.h" 21 | #include "nixycore/container/vector.h" 22 | #include "nixycore/container/forward_list.h" 23 | #include "nixycore/container/hash_map.h" 24 | #include "nixycore/container/hash_set.h" 25 | 26 | ////////////////////////////////////////////////////////////////////////// 27 | -------------------------------------------------------------------------------- /nixycore/container/deque.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/default_alloc.h" 11 | #include "nixycore/utility/rvalue.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | #include // std::deque 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | #ifdef NX_SP_CXX11_ALIAS 22 | template 23 | using deque = std::deque::type_t>; 24 | #else /*NX_SP_CXX11_ALIAS*/ 25 | template 26 | class deque : public std::deque::type_t> 27 | { 28 | typedef std::deque::type_t> base_t; 29 | 30 | public: 31 | #ifdef NX_SP_CXX11_INHERITING 32 | using base_t::deque; 33 | #else /*NX_SP_CXX11_INHERITING*/ 34 | deque(void) 35 | : base_t() 36 | {} 37 | 38 | explicit deque(const typename base_t::allocator_type& a) 39 | : base_t(a) 40 | {} 41 | 42 | explicit deque(typename base_t::size_type n, 43 | const typename base_t::value_type& v = typename base_t::value_type(), 44 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 45 | : base_t(n, v, a) 46 | {} 47 | 48 | template 49 | deque(IteratorT f, IteratorT l, 50 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 51 | : base_t(f, l, a) 52 | {} 53 | 54 | deque(const deque& rhs) 55 | : base_t(rhs) 56 | {} 57 | 58 | deque(nx_rref(deque, true) rhs) 59 | : base_t() 60 | { 61 | base_t::swap(nx::moved(rhs)); 62 | } 63 | #endif/*NX_SP_CXX11_INHERITING*/ 64 | 65 | deque& operator=(deque rhs) 66 | { 67 | rhs.swap(*this); 68 | return (*this); 69 | } 70 | }; 71 | 72 | /* 73 | Special swap algorithm 74 | */ 75 | 76 | template 77 | inline void swap(deque& x, deque& y) 78 | { 79 | x.swap(y); 80 | } 81 | #endif/*NX_SP_CXX11_ALIAS*/ 82 | 83 | ////////////////////////////////////////////////////////////////////////// 84 | NX_END 85 | ////////////////////////////////////////////////////////////////////////// 86 | -------------------------------------------------------------------------------- /nixycore/container/forward_list.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | #ifdef NX_SP_CXX11_FORWARD_LIST 13 | 14 | #include "nixycore/memory/default_alloc.h" 15 | #include "nixycore/utility/rvalue.h" 16 | 17 | #include // std::forward_list 18 | 19 | ////////////////////////////////////////////////////////////////////////// 20 | NX_BEG 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | #ifdef NX_SP_CXX11_ALIAS 24 | template 25 | using forward_list = std::forward_list::type_t>; 26 | #else /*NX_SP_CXX11_ALIAS*/ 27 | template 28 | class forward_list : public std::forward_list::type_t> 29 | { 30 | typedef std::forward_list::type_t> base_t; 31 | 32 | public: 33 | #ifdef NX_SP_CXX11_INHERITING 34 | using base_t::forward_list; 35 | #else /*NX_SP_CXX11_INHERITING*/ 36 | forward_list(void) 37 | : base_t() 38 | {} 39 | 40 | explicit forward_list(typename base_t::size_type count) 41 | : base_t(count) 42 | {} 43 | 44 | forward_list(typename base_t::size_type count, const T& val, 45 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 46 | : base_t(count, val, a) 47 | {} 48 | 49 | explicit forward_list(const typename base_t::allocator_type& a) 50 | : base_t(a) 51 | {} 52 | 53 | template 54 | forward_list(IteratorT f, IteratorT l, 55 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 56 | : base_t(f, l, a) 57 | {} 58 | 59 | forward_list(const forward_list& rhs) 60 | : base_t(rhs) 61 | {} 62 | 63 | forward_list(nx_rref(forward_list, true) rhs) 64 | : base_t() 65 | { 66 | base_t::swap(nx::moved(rhs)); 67 | } 68 | #endif/*NX_SP_CXX11_INHERITING*/ 69 | 70 | forward_list& operator=(forward_list rhs) 71 | { 72 | rhs.swap(*this); 73 | return (*this); 74 | } 75 | }; 76 | 77 | /* 78 | Special swap algorithm 79 | */ 80 | 81 | template 82 | inline void swap(forward_list& x, forward_list& y) 83 | { 84 | x.swap(y); 85 | } 86 | #endif/*NX_SP_CXX11_ALIAS*/ 87 | 88 | ////////////////////////////////////////////////////////////////////////// 89 | NX_END 90 | ////////////////////////////////////////////////////////////////////////// 91 | 92 | #endif/*NX_SP_CXX11_FORWARD_LIST*/ 93 | -------------------------------------------------------------------------------- /nixycore/container/list.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/default_alloc.h" 11 | #include "nixycore/utility/rvalue.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | #include // std::list 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | #ifdef NX_SP_CXX11_ALIAS 22 | template 23 | using list = std::list::type_t>; 24 | #else /*NX_SP_CXX11_ALIAS*/ 25 | template 26 | class list : public std::list::type_t> 27 | { 28 | typedef std::list::type_t> base_t; 29 | 30 | public: 31 | #ifdef NX_SP_CXX11_INHERITING 32 | using base_t::list; 33 | #else /*NX_SP_CXX11_INHERITING*/ 34 | list(void) 35 | : base_t() 36 | {} 37 | 38 | explicit list(const typename base_t::allocator_type& a) 39 | : base_t(a) 40 | {} 41 | 42 | explicit list(typename base_t::size_type n, 43 | const typename base_t::value_type& v = typename base_t::value_type(), 44 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 45 | : base_t(n, v, a) 46 | {} 47 | 48 | template 49 | list(IteratorT f, IteratorT l, 50 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 51 | : base_t(f, l, a) 52 | {} 53 | 54 | list(const list& rhs) 55 | : base_t(rhs) 56 | {} 57 | 58 | list(nx_rref(list, true) rhs) 59 | : base_t() 60 | { 61 | base_t::swap(nx::moved(rhs)); 62 | } 63 | #endif/*NX_SP_CXX11_INHERITING*/ 64 | 65 | list& operator=(list rhs) 66 | { 67 | rhs.swap(*this); 68 | return (*this); 69 | } 70 | }; 71 | 72 | /* 73 | Special swap algorithm 74 | */ 75 | 76 | template 77 | inline void swap(list& x, list& y) 78 | { 79 | x.swap(y); 80 | } 81 | #endif/*NX_SP_CXX11_ALIAS*/ 82 | 83 | ////////////////////////////////////////////////////////////////////////// 84 | NX_END 85 | ////////////////////////////////////////////////////////////////////////// 86 | -------------------------------------------------------------------------------- /nixycore/container/priority.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/container/vector.h" 11 | 12 | #include "nixycore/utility/rvalue.h" 13 | 14 | #include "nixycore/general/general.h" 15 | 16 | #include // std::priority_queue 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifdef NX_SP_CXX11_ALIAS 23 | template 24 | < 25 | typename T, typename SeqT = nx::vector, 26 | typename CompT = std::less 27 | > 28 | using priority = std::priority_queue; 29 | #else /*NX_SP_CXX11_ALIAS*/ 30 | template 31 | < 32 | typename T, typename SeqT = nx::vector, 33 | typename CompT = std::less 34 | > 35 | class priority : public std::priority_queue 36 | { 37 | typedef std::priority_queue base_t; 38 | 39 | public: 40 | #ifdef NX_SP_CXX11_INHERITING 41 | using base_t::priority_queue; 42 | #else /*NX_SP_CXX11_INHERITING*/ 43 | explicit priority(const CompT& c = CompT(), const SeqT& s = SeqT()) 44 | : base_t(c, s) 45 | {} 46 | 47 | template 48 | priority(IteratorT f, IteratorT l, 49 | const CompT& c = CompT(), const SeqT& s = SeqT()) 50 | : base_t(f, l, c, s) 51 | {} 52 | 53 | priority(const priority& rhs) 54 | : base_t(rhs) 55 | {} 56 | 57 | #ifdef NX_SP_CXX11_STACK_SWAP 58 | priority(nx_rref(priority, true) rhs) 59 | : base_t() 60 | { 61 | base_t::swap(nx::moved(rhs)); 62 | } 63 | #endif 64 | #endif/*NX_SP_CXX11_INHERITING*/ 65 | 66 | priority& operator=(priority rhs) 67 | { 68 | rhs.swap(*this); 69 | return (*this); 70 | } 71 | }; 72 | 73 | /* 74 | Special swap algorithm 75 | */ 76 | 77 | template 78 | inline void swap(priority& x, priority& y) 79 | { 80 | x.swap(y); 81 | } 82 | #endif/*NX_SP_CXX11_ALIAS*/ 83 | 84 | /* 85 | Special assign algorithm 86 | */ 87 | 88 | template 89 | inline void insert(std::priority_queue& set, 90 | typename std::priority_queue::iterator /*ite*/, const V& val) 91 | { 92 | set.push(val); 93 | } 94 | 95 | template 96 | inline void erase(std::priority_queue& set, 97 | typename std::priority_queue::iterator /*ite*/) 98 | { 99 | set.pop(); 100 | } 101 | 102 | #ifndef NX_SP_CXX11_ALIAS 103 | template 104 | inline void insert(priority& set, typename priority::iterator /*ite*/, const V& val) 105 | { 106 | set.push(val); 107 | } 108 | 109 | template 110 | inline void erase(priority& set, typename priority::iterator /*ite*/) 111 | { 112 | set.pop(); 113 | } 114 | #endif/*NX_SP_CXX11_ALIAS*/ 115 | 116 | ////////////////////////////////////////////////////////////////////////// 117 | NX_END 118 | ////////////////////////////////////////////////////////////////////////// 119 | -------------------------------------------------------------------------------- /nixycore/container/queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/container/deque.h" 11 | 12 | #include "nixycore/utility/rvalue.h" 13 | 14 | #include "nixycore/general/general.h" 15 | 16 | #include // std::queue 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifdef NX_SP_CXX11_ALIAS 23 | template > 24 | using queue = std::queue; 25 | #else /*NX_SP_CXX11_ALIAS*/ 26 | template > 27 | class queue : public std::queue 28 | { 29 | typedef std::queue base_t; 30 | 31 | public: 32 | #ifdef NX_SP_CXX11_INHERITING 33 | using base_t::queue; 34 | #else /*NX_SP_CXX11_INHERITING*/ 35 | explicit queue(const SeqT& s = SeqT()) 36 | : base_t(s) 37 | {} 38 | 39 | queue(const queue& rhs) 40 | : base_t(rhs) 41 | {} 42 | 43 | #ifdef NX_SP_CXX11_STACK_SWAP 44 | queue(nx_rref(queue, true) rhs) 45 | : base_t() 46 | { 47 | base_t::swap(nx::moved(rhs)); 48 | } 49 | #endif 50 | #endif/*NX_SP_CXX11_INHERITING*/ 51 | 52 | queue& operator=(queue rhs) 53 | { 54 | rhs.swap(*this); 55 | return (*this); 56 | } 57 | }; 58 | 59 | /* 60 | Special swap algorithm 61 | */ 62 | 63 | template 64 | inline void swap(queue& x, queue& y) 65 | { 66 | x.swap(y); 67 | } 68 | #endif/*NX_SP_CXX11_ALIAS*/ 69 | 70 | /* 71 | Special assign algorithm 72 | */ 73 | 74 | template 75 | inline void insert(std::queue& set, typename std::queue::iterator /*ite*/, const V& val) 76 | { 77 | set.push(val); 78 | } 79 | 80 | template 81 | inline void erase(std::queue& set, typename std::queue::iterator /*ite*/) 82 | { 83 | set.pop(); 84 | } 85 | 86 | #ifndef NX_SP_CXX11_ALIAS 87 | template 88 | inline void insert(queue& set, typename queue::iterator /*ite*/, const V& val) 89 | { 90 | set.push(val); 91 | } 92 | 93 | template 94 | inline void erase(queue& set, typename queue::iterator /*ite*/) 95 | { 96 | set.pop(); 97 | } 98 | #endif/*NX_SP_CXX11_ALIAS*/ 99 | 100 | ////////////////////////////////////////////////////////////////////////// 101 | NX_END 102 | ////////////////////////////////////////////////////////////////////////// 103 | -------------------------------------------------------------------------------- /nixycore/container/stack.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/container/deque.h" 11 | 12 | #include "nixycore/utility/rvalue.h" 13 | 14 | #include "nixycore/general/general.h" 15 | 16 | #include // std::stack 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifdef NX_SP_CXX11_ALIAS 23 | template > 24 | using stack = std::stack; 25 | #else /*NX_SP_CXX11_ALIAS*/ 26 | template > 27 | class stack : public std::stack 28 | { 29 | typedef std::stack base_t; 30 | 31 | public: 32 | #ifdef NX_SP_CXX11_INHERITING 33 | using base_t::stack; 34 | #else /*NX_SP_CXX11_INHERITING*/ 35 | explicit stack(const SeqT& s = SeqT()) 36 | : base_t(s) 37 | {} 38 | 39 | stack(const stack& rhs) 40 | : base_t(rhs) 41 | {} 42 | 43 | #ifdef NX_SP_CXX11_STACK_SWAP 44 | stack(nx_rref(stack, true) rhs) 45 | : base_t() 46 | { 47 | base_t::swap(nx::moved(rhs)); 48 | } 49 | #endif 50 | #endif/*NX_SP_CXX11_INHERITING*/ 51 | 52 | stack& operator=(stack rhs) 53 | { 54 | rhs.swap(*this); 55 | return (*this); 56 | } 57 | }; 58 | 59 | /* 60 | Special swap algorithm 61 | */ 62 | 63 | template 64 | inline void swap(stack& x, stack& y) 65 | { 66 | x.swap(y); 67 | } 68 | #endif/*NX_SP_CXX11_ALIAS*/ 69 | 70 | /* 71 | Special assign algorithm 72 | */ 73 | 74 | template 75 | inline void insert(std::stack& set, typename std::stack::iterator /*ite*/, const V& val) 76 | { 77 | set.push(val); 78 | } 79 | 80 | template 81 | inline void erase(std::stack& set, typename std::stack::iterator /*ite*/) 82 | { 83 | set.pop(); 84 | } 85 | 86 | #ifndef NX_SP_CXX11_ALIAS 87 | template 88 | inline void insert(stack& set, typename stack::iterator /*ite*/, const V& val) 89 | { 90 | set.push(val); 91 | } 92 | 93 | template 94 | inline void erase(stack& set, typename stack::iterator /*ite*/) 95 | { 96 | set.pop(); 97 | } 98 | #endif/*NX_SP_CXX11_ALIAS*/ 99 | 100 | ////////////////////////////////////////////////////////////////////////// 101 | NX_END 102 | ////////////////////////////////////////////////////////////////////////// 103 | -------------------------------------------------------------------------------- /nixycore/container/vector.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/default_alloc.h" 11 | #include "nixycore/utility/rvalue.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | #include // std::vector 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | #ifdef NX_SP_CXX11_ALIAS 22 | template 23 | using vector = std::vector::type_t>; 24 | #else /*NX_SP_CXX11_ALIAS*/ 25 | template 26 | class vector : public std::vector::type_t> 27 | { 28 | typedef std::vector::type_t> base_t; 29 | 30 | public: 31 | #ifdef NX_SP_CXX11_INHERITING 32 | using base_t::vector; 33 | #else /*NX_SP_CXX11_INHERITING*/ 34 | vector(void) 35 | : base_t() 36 | {} 37 | 38 | explicit vector(const typename base_t::allocator_type& a) 39 | : base_t(a) 40 | {} 41 | 42 | explicit vector(typename base_t::size_type n, 43 | const typename base_t::value_type& v = typename base_t::value_type(), 44 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 45 | : base_t(n, v, a) 46 | {} 47 | 48 | template 49 | vector(IteratorT f, IteratorT l, 50 | const typename base_t::allocator_type& a = typename base_t::allocator_type()) 51 | : base_t(f, l, a) 52 | {} 53 | 54 | vector(const vector& rhs) 55 | : base_t(rhs) 56 | {} 57 | 58 | vector(nx_rref(vector, true) rhs) 59 | : base_t() 60 | { 61 | base_t::swap(nx::moved(rhs)); 62 | } 63 | #endif/*NX_SP_CXX11_INHERITING*/ 64 | 65 | vector& operator=(vector rhs) 66 | { 67 | rhs.swap(*this); 68 | return (*this); 69 | } 70 | }; 71 | 72 | /* 73 | Special swap algorithm 74 | */ 75 | 76 | template 77 | inline void swap(vector& x, vector& y) 78 | { 79 | x.swap(y); 80 | } 81 | #endif/*NX_SP_CXX11_ALIAS*/ 82 | 83 | ////////////////////////////////////////////////////////////////////////// 84 | NX_END 85 | ////////////////////////////////////////////////////////////////////////// 86 | -------------------------------------------------------------------------------- /nixycore/delegate/delegate.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/delegate/function_traits.h" 13 | #include "nixycore/delegate/functor.h" 14 | #include "nixycore/delegate/bind.h" 15 | #include "nixycore/delegate/signal.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | -------------------------------------------------------------------------------- /nixycore/finalizer/finalizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/finalizer/scope_guard.h" 13 | #include "nixycore/finalizer/ref_counter.h" 14 | #include "nixycore/finalizer/holder.h" 15 | #include "nixycore/finalizer/gc.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | -------------------------------------------------------------------------------- /nixycore/finalizer/scope_guard.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/delegate/functor.h" 11 | 12 | #include "nixycore/bugfix/noexcept.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/typemanip/typemanip.h" 16 | #include "nixycore/utility/utility.h" 17 | #include "nixycore/algorithm/algorithm.h" 18 | 19 | ////////////////////////////////////////////////////////////////////////// 20 | NX_BEG 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | /* 24 | Execute guard function when the enclosing scope exits 25 | */ 26 | 27 | template 28 | class scope_guard : noncopyable 29 | { 30 | F destructor_; 31 | mutable bool dismiss_; 32 | 33 | public: 34 | explicit scope_guard(const F& destructor) 35 | : destructor_(destructor) 36 | , dismiss_(false) 37 | {} 38 | 39 | explicit scope_guard(nx_rref(F) destructor) 40 | : destructor_(nx::move(destructor)) 41 | , dismiss_(false) 42 | {} 43 | 44 | scope_guard(nx_rref(scope_guard, true) rhs) 45 | : destructor_(nx::move(rhs.destructor_)) 46 | , dismiss_(true) // dismiss rhs 47 | { 48 | nx::swap(dismiss_, nx::moved(rhs).dismiss_); 49 | } 50 | 51 | ~scope_guard(void) 52 | { 53 | if (!dismiss_) try 54 | { 55 | destructor_(); 56 | } 57 | /* 58 | In the realm of exceptions, 59 | it is fundamental that you can do nothing 60 | if your "undo/recover" action fails. 61 | */ 62 | catch(...) 63 | { 64 | // Do nothing 65 | } 66 | } 67 | 68 | void dismiss() const nx_noexcept 69 | { 70 | dismiss_ = true; 71 | } 72 | 73 | nx_rval(functor, true) get(void) const 74 | { 75 | functor tmp(destructor_); 76 | return nx::move(tmp); 77 | } 78 | 79 | void swap(scope_guard& rhs) 80 | { 81 | nx::swap(destructor_, rhs.destructor_); 82 | nx::swap(dismiss_, rhs.dismiss_); 83 | } 84 | }; 85 | 86 | /* 87 | --> 88 | void func(void) 89 | { 90 | int* p = new int(2); 91 | nx_guard_scope(nx::bind(new_dest, p)); 92 | ... 93 | } 94 | */ 95 | 96 | template 97 | inline nx_rval(scope_guard::type_t>, true) 98 | make_scope_guard(nx_fref(F) f) 99 | { 100 | return scope_guard::type_t>(nx_forward(F, f)); 101 | } 102 | 103 | #define NX_GUARD_SCOPE_NAM_(nn) scope_guard_##nn##__ 104 | #define NX_GUARD_SCOPE_(nn, call) \ 105 | nx_auto(NX_UNUSED NX_GUARD_SCOPE_NAM_(nn), call) 106 | 107 | #define nx_guard_scope(...) NX_GUARD_SCOPE_(__LINE__, nx::make_scope_guard(__VA_ARGS__)) 108 | 109 | ////////////////////////////////////////////////////////////////////////// 110 | NX_END 111 | ////////////////////////////////////////////////////////////////////////// 112 | -------------------------------------------------------------------------------- /nixycore/general/detail/plat_detect_cc.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | /* 10 | The compiler, must be one of: (NX_CC_XX) 11 | 12 | MSVC - Microsoft Visual C++ 13 | GNUC - GNU C++ 14 | CLANG - C++ front-end for the LLVM compiler 15 | */ 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | #if defined(_MSC_VER) && (_MSC_VER >= 1400) /* >= 8.0 */ 19 | # define NX_CC_MSVC _MSC_VER 20 | #elif defined(__GNUC__) 21 | # define NX_CC_GNUC 22 | # if defined(__clang__) 23 | # define NX_CC_CLANG // Clang also masquerades as GCC 24 | # else 25 | # define NX_CC_GCC 26 | # endif 27 | #else 28 | # error "This CC is unsupported." 29 | #endif 30 | 31 | #if defined(NX_CC_MSVC) 32 | # pragma warning(disable:4996) // This function or variable may be unsafe 33 | # pragma warning(disable:4101) // The local variable is never used 34 | # define NX_UNUSED __pragma(warning(suppress:4100)) 35 | # ifndef NX__FUNCTION__ 36 | # define NX__FUNCTION__ __FUNCSIG__ 37 | # endif 38 | #elif defined(NX_CC_GNUC) 39 | # define NX_UNUSED __attribute__((__unused__)) 40 | # ifndef NX__FUNCTION__ 41 | # define NX__FUNCTION__ __PRETTY_FUNCTION__ 42 | # endif 43 | #endif 44 | 45 | ////////////////////////////////////////////////////////////////////////// 46 | -------------------------------------------------------------------------------- /nixycore/general/detail/plat_detect_pc.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | /* 10 | The processor, must be one of: (NX_PC_XX) 11 | 12 | X86_32 - x86 32-bit processors 13 | X86_64 - x86 64-bit processors 14 | IA_64 - Itanium Processor Family 64-bit processors 15 | ARM - ARM processors 16 | */ 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | #if defined(__i386__) || defined(_M_IX86) 20 | # define NX_PC_X86_32 21 | #elif defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) 22 | # define NX_PC_X86_64 23 | #elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) 24 | # define NX_PC_IA_64 25 | #elif defined(__arm__) || defined(_ARM_) || defined(_M_ARM) 26 | # define NX_PC_ARM 27 | #else 28 | # error "This processor is unsupported." 29 | #endif 30 | 31 | #if defined(NX_PC_X86_32) || defined(NX_PC_X86_64) 32 | # define NX_PC_X86 33 | #endif 34 | 35 | #if defined(NX_PC_X86_32) 36 | # define NX_PC_X32 37 | #endif 38 | 39 | #if defined(NX_PC_X86_64) || defined(NX_PC_IA_64) 40 | # define NX_PC_X64 41 | #endif 42 | 43 | #if defined(NX_CC_GNUC) 44 | # if defined(__MMX__) 45 | # define NX_PC_MMX 46 | # endif 47 | # if defined(__SSE__) 48 | # define NX_PC_SSE 49 | # endif 50 | # if defined(__SSE2__) 51 | # define NX_PC_SSE2 52 | # endif 53 | #elif defined(NX_CC_MSVC) && defined(NX_PC_X86) 54 | # if !defined(NX_PC_X86_64) 55 | # define NX_PC_MMX 56 | # endif 57 | # if defined(_M_IX86_FP) && (_M_IX86_FP >= 1) 58 | # define NX_PC_SSE 59 | # endif 60 | # if defined(_M_IX86_FP) && (_M_IX86_FP >= 2) 61 | # define NX_PC_SSE2 62 | # endif 63 | #endif 64 | 65 | ////////////////////////////////////////////////////////////////////////// 66 | -------------------------------------------------------------------------------- /nixycore/general/general.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | /* 13 | Standard Librarys 14 | */ 15 | 16 | // size_t, ptrdiff_t, ... 17 | #include 18 | // printf, vsnprintf, vsprintf, ... 19 | #include 20 | // wprintf, vswprintf, ... 21 | #include 22 | // abort, rand, srand, ... 23 | #include 24 | // va_list, va_start, va_end 25 | #include 26 | // memcpy, memset, ... 27 | #include 28 | 29 | /* 30 | Detect platforms 31 | */ 32 | 33 | // NX_OS, NX_CC, NDEBUG, ... 34 | #include "nixycore/general/plat_detect.h" 35 | 36 | ////////////////////////////////////////////////////////////////////////// 37 | 38 | // namespace define 39 | 40 | #define NX_BEG namespace nx { 41 | #define NX_END } 42 | 43 | ////////////////////////////////////////////////////////////////////////// 44 | NX_BEG 45 | ////////////////////////////////////////////////////////////////////////// 46 | 47 | // global types 48 | 49 | typedef unsigned char uchar; 50 | typedef unsigned short ushort; 51 | typedef unsigned int uint; 52 | typedef unsigned long ulong; 53 | typedef long long llong; 54 | typedef unsigned long long ullong; 55 | 56 | typedef wchar_t wchar; 57 | typedef long double ldouble; 58 | 59 | typedef char* pchar; 60 | typedef const char* cpchar; 61 | typedef wchar_t* pwchar; 62 | typedef const wchar_t* cpwchar; 63 | typedef void* pvoid; 64 | typedef const void* cpvoid; 65 | 66 | typedef unsigned char byte; 67 | 68 | typedef ::size_t size_t; 69 | typedef ::ptrdiff_t ptrdiff_t; 70 | 71 | typedef char sint8; 72 | typedef uchar uint8; 73 | typedef short sint16; 74 | typedef ushort uint16; 75 | typedef int sint32; 76 | typedef uint uint32; 77 | typedef llong sint64; 78 | typedef ullong uint64; 79 | 80 | ////////////////////////////////////////////////////////////////////////// 81 | NX_END 82 | ////////////////////////////////////////////////////////////////////////// 83 | -------------------------------------------------------------------------------- /nixycore/general/global_functions.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #if defined(NX_OS_LINUX) 9 | #include 10 | #endif 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | /* 17 | Detect the numbers of the CPU cores 18 | */ 19 | inline long detect_cpu_count(void) 20 | { 21 | static long cpu_count = 0; 22 | if (cpu_count > 0) return cpu_count; 23 | #if defined(NX_OS_WIN) 24 | SYSTEM_INFO si; 25 | GetSystemInfo(&si); 26 | cpu_count = static_cast(si.dwNumberOfProcessors); 27 | #elif defined(NX_OS_LINUX) 28 | cpu_count = static_cast(get_nprocs()); 29 | #endif 30 | if (cpu_count < 1) cpu_count = 1; // fail-safe 31 | return cpu_count; 32 | } 33 | 34 | ////////////////////////////////////////////////////////////////////////// 35 | NX_END 36 | ////////////////////////////////////////////////////////////////////////// 37 | -------------------------------------------------------------------------------- /nixycore/general/plat_detect.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | // The compiler, must be one of: (NX_CC_XX) 11 | #include "detail/plat_detect_cc.hxx" 12 | 13 | // C++ features support, must be one of: (NX_SP_XX) 14 | #include "detail/plat_detect_sp.hxx" 15 | 16 | // The processor, must be one of: (NX_PC_XX) 17 | #include "detail/plat_detect_pc.hxx" 18 | 19 | // The operating system, must be one of: (NX_OS_XX) 20 | #include "detail/plat_detect_os.hxx" 21 | 22 | // The other defines 23 | 24 | #ifndef NDEBUG 25 | # ifndef _DEBUG 26 | # define _DEBUG 27 | # endif 28 | # ifndef DEBUG 29 | # define DEBUG 30 | # endif 31 | #endif 32 | 33 | #ifndef CHAR_BIT 34 | # define CHAR_BIT 8 35 | #endif 36 | 37 | ////////////////////////////////////////////////////////////////////////// 38 | -------------------------------------------------------------------------------- /nixycore/memory/alloc_model.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/construct.h" 11 | #include "nixycore/memory/alloc.h" 12 | 13 | #include "nixycore/utility/limit_of.h" 14 | 15 | #include "nixycore/general/general.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | /* 22 | a adapter allocator for stl 23 | */ 24 | 25 | template 26 | struct std_allocator 27 | { 28 | public: 29 | // type definitions 30 | typedef T value_type; 31 | typedef T* pointer; 32 | typedef const T* const_pointer; 33 | typedef T& reference; 34 | typedef const T& const_reference; 35 | typedef size_t size_type; 36 | typedef ptrdiff_t difference_type; 37 | 38 | // the other type of std_allocator 39 | template 40 | struct rebind { typedef std_allocator other; }; 41 | 42 | public: 43 | pointer address(reference val) const 44 | { return &val; } 45 | const_pointer address(const_reference val) const 46 | { return &val; } 47 | 48 | size_type max_size() const 49 | { return (nx::limit_of::upper / sizeof(T)); } 50 | 51 | public: 52 | std_allocator(void) {} 53 | std_allocator(const std_allocator&) {} 54 | template 55 | std_allocator(const std_allocator&) {} 56 | 57 | std_allocator& operator=(const std_allocator&) { return (*this); } 58 | template 59 | std_allocator& operator=(const std_allocator&) { return (*this); } 60 | 61 | template 62 | bool operator==(const std_allocator&) const { return true; } 63 | /* vector(609): compiler error C2593 */ 64 | template 65 | bool operator!=(const std_allocator&) const { return false; } 66 | 67 | public: 68 | pointer allocate(size_type count, const pvoid = NULL) 69 | { 70 | if (count > this->max_size()) throw std::bad_alloc(); 71 | pvoid p = nx::alloc(count * sizeof(T)); 72 | if (!p) throw std::bad_alloc(); 73 | return static_cast(p); 74 | } 75 | 76 | void deallocate(pvoid p, size_type count) 77 | { 78 | nx::free(p, count * sizeof(T)); 79 | } 80 | 81 | static void construct(pointer p, const T& val) 82 | { 83 | nx_construct(p, value_type, (val)); 84 | } 85 | 86 | static void destroy(pointer p) 87 | { 88 | nx_destruct(p, value_type); 89 | } 90 | }; 91 | 92 | /* 93 | alloc policy base 94 | */ 95 | 96 | template 97 | struct alloc_model : ModelT 98 | { 99 | /* the stl allocator type */ 100 | template 101 | struct std_allocator { typedef nx::std_allocator type_t; }; 102 | }; 103 | 104 | /* 105 | check alloc policy 106 | */ 107 | 108 | template 109 | struct is_alloc 110 | : type_if 111 | {}; 112 | 113 | template 114 | struct is_alloc > 115 | : type_if 116 | {}; 117 | 118 | ////////////////////////////////////////////////////////////////////////// 119 | NX_END 120 | ////////////////////////////////////////////////////////////////////////// 121 | -------------------------------------------------------------------------------- /nixycore/memory/center_heap.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/alloc.h" 11 | #include "nixycore/memory/std_alloc.h" 12 | #include "nixycore/memory/cache_pool.h" 13 | #include "nixycore/memory/mem_pool.h" 14 | 15 | #include "nixycore/bugfix/assert.h" 16 | #include "nixycore/typemanip/typedefs.h" 17 | #include "nixycore/thread/thread_model.h" 18 | #include "nixycore/pattern/singleton.h" 19 | 20 | #include "nixycore/general/general.h" 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | NX_BEG 24 | ////////////////////////////////////////////////////////////////////////// 25 | 26 | /* 27 | center heap alloc policy model 28 | */ 29 | 30 | template 31 | struct center_heap_model 32 | { 33 | typedef cache_pool cache_pool_t; 34 | typedef mem_pool mem_pool_t; 35 | 36 | static mem_pool_t& instance(void) 37 | { 38 | static mem_pool_t& cache = nx::singleton(); 39 | return cache; 40 | } 41 | 42 | static pvoid alloc(size_t size) 43 | { 44 | return instance().alloc(size); 45 | } 46 | 47 | static void free(pvoid p, size_t size) 48 | { 49 | instance().free(p, size); 50 | } 51 | 52 | static pvoid realloc(pvoid p, size_t old_size, size_t new_size) 53 | { 54 | return instance().realloc(p, old_size, new_size); 55 | } 56 | }; 57 | 58 | namespace use 59 | { 60 | typedef alloc_model > alloc_center_heap; 61 | } 62 | 63 | ////////////////////////////////////////////////////////////////////////// 64 | NX_END 65 | ////////////////////////////////////////////////////////////////////////// 66 | -------------------------------------------------------------------------------- /nixycore/memory/construct.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | // placement new, std::bad_alloc 13 | #include 14 | 15 | ////////////////////////////////////////////////////////////////////////// 16 | NX_BEG 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | /* 20 | construct/destruct 21 | */ 22 | 23 | #define nx_construct(p, T, ...) \ 24 | (T*)::new ((void*)(p)) T __VA_ARGS__ 25 | 26 | #define nx_construct_arr(p, T, N, ...) \ 27 | do \ 28 | { \ 29 | for(size_t i = 0; i < N; ++i) \ 30 | nx_construct(&(((T*)(p))[i]), T, __VA_ARGS__); \ 31 | } while(false) 32 | 33 | #define nx_destruct(p, T) \ 34 | ((T*)(p))->~T() 35 | 36 | #define nx_destruct_arr(p, T, N) \ 37 | do \ 38 | { \ 39 | for(size_t i = 0; i < N; ++i) \ 40 | nx_destruct(&(((T*)(p))[i]), T); \ 41 | } while(false) 42 | 43 | ////////////////////////////////////////////////////////////////////////// 44 | NX_END 45 | ////////////////////////////////////////////////////////////////////////// 46 | -------------------------------------------------------------------------------- /nixycore/memory/default_alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/alloc.h" 11 | #include "nixycore/memory/std_alloc.h" 12 | #include "nixycore/memory/mem_alloc.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/preprocessor/preprocessor.h" 16 | #include "nixycore/utility/utility.h" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifndef NX_DEFAULT_ALLOC 23 | #define NX_DEFAULT_ALLOC nx::use::alloc_pool 24 | #endif 25 | 26 | /* 27 | construct alloc 28 | */ 29 | 30 | inline pvoid alloc(size_t size) 31 | { 32 | return nx::alloc(size); 33 | } 34 | 35 | #ifdef NX_SP_CXX11_TEMPLATES 36 | template 37 | inline typename nx::enable_if::value, 38 | T*>::type_t alloc(nx_fref(P)... par) 39 | { 40 | return nx::alloc(nx_forward(P, par)...); 41 | } 42 | #else /*NX_SP_CXX11_TEMPLATES*/ 43 | template 44 | inline T* alloc(void) 45 | { 46 | return nx::alloc(); 47 | } 48 | 49 | #define NX_ALLOC_(n) \ 50 | template \ 51 | inline typename nx::enable_if::value, \ 52 | T*>::type_t alloc(NX_PP_TYPE_2(n, P, NX_PP_FREF(par))) \ 53 | { \ 54 | return nx::alloc(NX_PP_FORWARD(n, P, par)); \ 55 | } 56 | NX_PP_MULT_MAX(NX_ALLOC_) 57 | #undef NX_ALLOC_ 58 | #endif/*NX_SP_CXX11_TEMPLATES*/ 59 | 60 | /* 61 | destruct free 62 | */ 63 | 64 | inline void free(pvoid p, size_t size) 65 | { 66 | nx::free(p, size); 67 | } 68 | 69 | template 70 | inline void free(T* p) 71 | { 72 | nx::free(p); 73 | } 74 | 75 | /* 76 | realloc 77 | */ 78 | 79 | inline pvoid realloc(pvoid p, size_t old_size, size_t new_size) 80 | { 81 | return nx::realloc(p, old_size, new_size); 82 | } 83 | 84 | template 85 | inline pvoid realloc(T* p, size_t size) 86 | { 87 | return nx::realloc(p, size); 88 | } 89 | 90 | ////////////////////////////////////////////////////////////////////////// 91 | NX_END 92 | ////////////////////////////////////////////////////////////////////////// 93 | -------------------------------------------------------------------------------- /nixycore/memory/mem_alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/alloc.h" 11 | #include "nixycore/memory/std_alloc.h" 12 | #include "nixycore/memory/cache_pool.h" 13 | #include "nixycore/memory/mem_pool.h" 14 | #include "nixycore/memory/center_heap.h" 15 | 16 | #include "nixycore/thread/tls_ptr.h" 17 | #include "nixycore/thread/thread_model.h" 18 | #include "nixycore/pattern/singleton.h" 19 | #include "nixycore/algorithm/series.h" 20 | 21 | #include "nixycore/general/general.h" 22 | #include "nixycore/preprocessor/preprocessor.h" 23 | #include "nixycore/utility/utility.h" 24 | 25 | ////////////////////////////////////////////////////////////////////////// 26 | NX_BEG 27 | ////////////////////////////////////////////////////////////////////////// 28 | 29 | /* 30 | The thread local storage singleton 31 | */ 32 | 33 | template 34 | class TLSSingleton 35 | { 36 | typedef tls_ptr tls_t; 37 | 38 | static void destroy(pvoid p) 39 | { 40 | nx::free(static_cast(p)); 41 | } 42 | 43 | public: 44 | #ifdef NX_SP_CXX11_TEMPLATES 45 | template 46 | static T& instance(nx_fref(P)... par) 47 | { 48 | T* p = singleton(destroy); 49 | if (p) return (*p); 50 | singleton() = p = nx::alloc(nx_forward(P, par)...); 51 | return (*p); 52 | } 53 | #else /*NX_SP_CXX11_TEMPLATES*/ 54 | static T& instance(void) 55 | { 56 | T* p = singleton(destroy); 57 | if (p) return (*p); 58 | singleton() = p = nx::alloc(); 59 | return (*p); 60 | } 61 | #define NX_INSTANCE_(n) \ 62 | template \ 63 | static T& instance(NX_PP_TYPE_2(n, P, NX_PP_FREF(par))) \ 64 | { \ 65 | T* p = singleton(destroy); \ 66 | if (p) return (*p); \ 67 | singleton() = p = nx::alloc(NX_PP_FORWARD(n, P, par)); \ 68 | return (*p); \ 69 | } 70 | NX_PP_MULT_MAX(NX_INSTANCE_) 71 | #undef NX_INSTANCE_ 72 | #endif/*NX_SP_CXX11_TEMPLATES*/ 73 | }; 74 | 75 | /* 76 | memory alloc policy model 77 | */ 78 | 79 | struct pool_alloc_model 80 | { 81 | typedef cache_pool 82 | < 83 | use::alloc_std, 84 | use::thread_single, 85 | use::alloc_center_heap 86 | > cache_pool_t; 87 | 88 | typedef mem_pool mem_pool_t; 89 | 90 | static mem_pool_t& instance(void) 91 | { 92 | use::alloc_center_heap::instance(); // Make center heap run first 93 | return TLSSingleton::instance(); 94 | } 95 | 96 | static pvoid alloc(size_t size) 97 | { 98 | return instance().alloc(size); 99 | } 100 | 101 | static void free(pvoid p, size_t size) 102 | { 103 | instance().free(p, size); 104 | } 105 | 106 | static pvoid realloc(pvoid p, size_t old_size, size_t new_size) 107 | { 108 | return instance().realloc(p, old_size, new_size); 109 | } 110 | }; 111 | 112 | namespace use 113 | { 114 | typedef alloc_model alloc_pool; 115 | } 116 | 117 | ////////////////////////////////////////////////////////////////////////// 118 | NX_END 119 | ////////////////////////////////////////////////////////////////////////// 120 | -------------------------------------------------------------------------------- /nixycore/memory/mem_guard.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/default_alloc.h" 11 | 12 | #include "nixycore/delegate/functor.h" 13 | #include "nixycore/finalizer/scope_guard.h" 14 | #include "nixycore/utility/rvalue.h" 15 | 16 | #include "nixycore/general/general.h" 17 | #include "nixycore/typemanip/typemanip.h" 18 | 19 | ////////////////////////////////////////////////////////////////////////// 20 | NX_BEG 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | /* 24 | memory scope guard 25 | */ 26 | 27 | namespace private_mem_guard 28 | { 29 | template 30 | struct free_fr 31 | { 32 | T p_; 33 | free_fr(T p) : p_(p) {} 34 | void operator()(void) { nx::free(p_); } 35 | }; 36 | 37 | template <> 38 | struct free_fr 39 | { 40 | pvoid p_; 41 | size_t s_; 42 | free_fr(pvoid p, size_t s) : p_(p), s_(s) {} 43 | void operator()(void) { nx::free(p_, s_); } 44 | }; 45 | } 46 | 47 | template 48 | inline private_mem_guard::free_fr make_destructor(T* r) 49 | { 50 | return private_mem_guard::free_fr(r); 51 | } 52 | 53 | template 54 | inline typename nx::enable_if::value, 55 | private_mem_guard::free_fr >::type_t make_destructor(pvoid r, SizeT s) 56 | { 57 | return private_mem_guard::free_fr(r, s); 58 | } 59 | 60 | #define nx_memory_scope(...) \ 61 | nx_guard_scope(nx::make_destructor(__VA_ARGS__)) 62 | 63 | ////////////////////////////////////////////////////////////////////////// 64 | NX_END 65 | ////////////////////////////////////////////////////////////////////////// 66 | -------------------------------------------------------------------------------- /nixycore/memory/memory.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/memory/construct.h" 13 | #include "nixycore/memory/alloc.h" 14 | #include "nixycore/memory/std_alloc.h" 15 | #include "nixycore/memory/fixed_pool.h" 16 | #include "nixycore/memory/cache_pool.h" 17 | #include "nixycore/memory/mem_pool.h" 18 | #include "nixycore/memory/center_heap.h" 19 | #include "nixycore/memory/mem_alloc.h" 20 | #include "nixycore/memory/default_alloc.h" 21 | #include "nixycore/memory/mem_leak.h" 22 | #include "nixycore/memory/unfixed_pool.h" 23 | #include "nixycore/memory/object_pool.h" 24 | #include "nixycore/memory/mem_guard.h" 25 | #include "nixycore/memory/pointer.h" 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | -------------------------------------------------------------------------------- /nixycore/memory/std_alloc.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/construct.h" 11 | #include "nixycore/memory/alloc_model.h" 12 | #include "nixycore/memory/alloc.h" 13 | 14 | #include "nixycore/general/general.h" 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | /* 21 | standard alloc policy model 22 | */ 23 | 24 | struct std_alloc_model 25 | { 26 | static pvoid alloc(size_t size) 27 | { return (size ? ::malloc(size) : NULL); } 28 | static void free(pvoid p, size_t /*size*/) 29 | { if (p) ::free(p); } 30 | static pvoid realloc(pvoid p, size_t old_size, size_t new_size) 31 | { return (((p && old_size) || new_size) ? ::realloc(p, new_size) : NULL); } 32 | }; 33 | 34 | namespace use 35 | { 36 | typedef alloc_model alloc_std; 37 | } 38 | 39 | ////////////////////////////////////////////////////////////////////////// 40 | NX_END 41 | ////////////////////////////////////////////////////////////////////////// 42 | -------------------------------------------------------------------------------- /nixycore/pattern/iterator.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | #include "nixycore/utility/utility.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | NX_BEG 15 | ////////////////////////////////////////////////////////////////////////// 16 | 17 | template 18 | struct iterator : public ModelT, nx_operator(iterator, unequal, operable) 19 | { 20 | typedef typename ModelT::type_t type_t; 21 | 22 | iterator(void) 23 | : ModelT(0) 24 | {} 25 | 26 | template 27 | iterator(T v) 28 | : ModelT(v) 29 | {} 30 | 31 | iterator& operator+=(int v) 32 | { 33 | ModelT::operator()(v); 34 | return (*this); 35 | } 36 | 37 | bool operator==(const iterator& y) const 38 | { 39 | return ModelT::operator==(y); 40 | } 41 | 42 | type_t value(void) const 43 | { 44 | return ModelT::value(); 45 | } 46 | 47 | type_t operator*(void) const { return value(); } 48 | }; 49 | 50 | ////////////////////////////////////////////////////////////////////////// 51 | NX_END 52 | ////////////////////////////////////////////////////////////////////////// 53 | -------------------------------------------------------------------------------- /nixycore/pattern/pattern.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/pattern/prototype.h" 13 | #include "nixycore/pattern/singleton.h" 14 | #include "nixycore/pattern/iterator.h" 15 | #include "nixycore/pattern/trackable.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | -------------------------------------------------------------------------------- /nixycore/pattern/prototype.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/memory/default_alloc.h" 11 | 12 | #include "nixycore/general/general.h" 13 | #include "nixycore/typemanip/typemanip.h" 14 | #include "nixycore/utility/utility.h" 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | NX_CONCEPT(clone, clone, C*(C::*)(void)) 21 | 22 | template 23 | inline typename enable_if::value, 24 | T*>::type_t clone(T* ob) 25 | { 26 | if (!ob) return nx::nulptr; 27 | return static_cast(ob->clone()); 28 | } 29 | 30 | template 31 | inline typename enable_if::value, 32 | T*>::type_t clone(T* ob) 33 | { 34 | if (!ob) return nx::nulptr; 35 | return nx::alloc(nx::ref(*ob)); 36 | } 37 | 38 | template 39 | T* clone(T* ob) 40 | { 41 | if (!ob) return nx::nulptr; 42 | return nx::alloc(nx::ref(*ob)); 43 | } 44 | 45 | ////////////////////////////////////////////////////////////////////////// 46 | NX_END 47 | ////////////////////////////////////////////////////////////////////////// 48 | -------------------------------------------------------------------------------- /nixycore/pattern/trackable.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/pattern/singleton.h" 11 | 12 | #include "nixycore/bugfix/assert.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/typemanip/typemanip.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | template class SingleT = Singleton> 22 | class trackable 23 | { 24 | public: 25 | T * prev_, * next_; 26 | 27 | private: 28 | static T *(& get_head_ptr(void)) 29 | { 30 | return SingleT::instance(nx::nulptr); 31 | } 32 | 33 | void init(void) 34 | { 35 | T*(& head) = get_head_ptr(); 36 | // check and push self to list 37 | if (head) 38 | { 39 | this->next_ = head; 40 | head->prev_ = static_cast(this); 41 | } 42 | head = static_cast(this); 43 | } 44 | 45 | void dest(void) 46 | { 47 | T*(& head) = get_head_ptr(); 48 | // check and pop self from list 49 | if (!head) return; 50 | if (this->prev_) 51 | { 52 | this->prev_->next_ = this->next_; 53 | if (this->next_) 54 | this->next_->prev_ = this->prev_; 55 | } 56 | else 57 | { 58 | nx_assert(this == head); 59 | head = head->next_; 60 | if (head) head->prev_ = nx::nulptr; 61 | } 62 | } 63 | 64 | public: 65 | trackable(void) 66 | : prev_(nx::nulptr) 67 | , next_(nx::nulptr) { init(); } 68 | 69 | trackable(const trackable&) 70 | : prev_(nx::nulptr) 71 | , next_(nx::nulptr) { init(); } 72 | 73 | ~trackable(void) { dest(); } 74 | 75 | trackable& operator=(const trackable&) { return (*this); } 76 | 77 | public: 78 | static T* track(void) { return get_head_ptr(); } 79 | }; 80 | 81 | ////////////////////////////////////////////////////////////////////////// 82 | NX_END 83 | ////////////////////////////////////////////////////////////////////////// 84 | -------------------------------------------------------------------------------- /nixycore/preprocessor/pp_arg.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | // preprocessor macros 11 | #include "nixycore/preprocessor/pp_macros.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | /* 16 | NX_PP_B2(a, b, c, d, e) 17 | --> 18 | c, d, e 19 | */ 20 | 21 | #define NX_PP_B_H(a, ...) __VA_ARGS__ 22 | 23 | #define NX_PP_B0(...) NX_PP_VA(__VA_ARGS__) 24 | #define NX_PP_B1(...) NX_PP_VA(NX_PP_B_H(__VA_ARGS__)) 25 | #define NX_PP_B2(...) NX_PP_B1(NX_PP_B1(__VA_ARGS__)) 26 | #define NX_PP_B3(...) NX_PP_B1(NX_PP_B2(__VA_ARGS__)) 27 | #define NX_PP_B4(...) NX_PP_B1(NX_PP_B3(__VA_ARGS__)) 28 | #define NX_PP_B5(...) NX_PP_B1(NX_PP_B4(__VA_ARGS__)) 29 | #define NX_PP_B6(...) NX_PP_B1(NX_PP_B5(__VA_ARGS__)) 30 | #define NX_PP_B7(...) NX_PP_B1(NX_PP_B6(__VA_ARGS__)) 31 | #define NX_PP_B8(...) NX_PP_B1(NX_PP_B7(__VA_ARGS__)) 32 | #define NX_PP_B9(...) NX_PP_B1(NX_PP_B8(__VA_ARGS__)) 33 | 34 | #define NX_PP_B10(...) NX_PP_B1(NX_PP_B9(__VA_ARGS__)) 35 | #define NX_PP_B11(...) NX_PP_B1(NX_PP_B10(__VA_ARGS__)) 36 | #define NX_PP_B12(...) NX_PP_B1(NX_PP_B11(__VA_ARGS__)) 37 | #define NX_PP_B13(...) NX_PP_B1(NX_PP_B12(__VA_ARGS__)) 38 | #define NX_PP_B14(...) NX_PP_B1(NX_PP_B13(__VA_ARGS__)) 39 | #define NX_PP_B15(...) NX_PP_B1(NX_PP_B14(__VA_ARGS__)) 40 | #define NX_PP_B16(...) NX_PP_B1(NX_PP_B15(__VA_ARGS__)) 41 | #define NX_PP_B17(...) NX_PP_B1(NX_PP_B16(__VA_ARGS__)) 42 | #define NX_PP_B18(...) NX_PP_B1(NX_PP_B17(__VA_ARGS__)) 43 | #define NX_PP_B19(...) NX_PP_B1(NX_PP_B18(__VA_ARGS__)) 44 | 45 | #define NX_PP_B20(...) NX_PP_B1(NX_PP_B19(__VA_ARGS__)) 46 | 47 | #define NX_PP_B_P(F, ...) NX_PP_VA(F(__VA_ARGS__)) 48 | #define NX_PP_B(n, ...) NX_PP_B_P(NX_PP_JOIN(NX_PP_B, n), __VA_ARGS__) 49 | 50 | ////////////////////////////////////////////////////////////////////////// 51 | 52 | /* 53 | NX_PP_A3(a, b, c, d, e) 54 | --> 55 | c 56 | */ 57 | 58 | #define NX_PP_A_H(a, ...) a 59 | 60 | #define NX_PP_A0(...) 61 | #define NX_PP_A1(...) NX_PP_VA(NX_PP_A_H(__VA_ARGS__)) 62 | #define NX_PP_A2(...) NX_PP_A1(NX_PP_B1(__VA_ARGS__)) 63 | #define NX_PP_A3(...) NX_PP_A1(NX_PP_B2(__VA_ARGS__)) 64 | #define NX_PP_A4(...) NX_PP_A1(NX_PP_B3(__VA_ARGS__)) 65 | #define NX_PP_A5(...) NX_PP_A1(NX_PP_B4(__VA_ARGS__)) 66 | #define NX_PP_A6(...) NX_PP_A1(NX_PP_B5(__VA_ARGS__)) 67 | #define NX_PP_A7(...) NX_PP_A1(NX_PP_B6(__VA_ARGS__)) 68 | #define NX_PP_A8(...) NX_PP_A1(NX_PP_B7(__VA_ARGS__)) 69 | #define NX_PP_A9(...) NX_PP_A1(NX_PP_B8(__VA_ARGS__)) 70 | 71 | #define NX_PP_A10(...) NX_PP_A1(NX_PP_B9(__VA_ARGS__)) 72 | #define NX_PP_A11(...) NX_PP_A1(NX_PP_B10(__VA_ARGS__)) 73 | #define NX_PP_A12(...) NX_PP_A1(NX_PP_B11(__VA_ARGS__)) 74 | #define NX_PP_A13(...) NX_PP_A1(NX_PP_B12(__VA_ARGS__)) 75 | #define NX_PP_A14(...) NX_PP_A1(NX_PP_B13(__VA_ARGS__)) 76 | #define NX_PP_A15(...) NX_PP_A1(NX_PP_B14(__VA_ARGS__)) 77 | #define NX_PP_A16(...) NX_PP_A1(NX_PP_B15(__VA_ARGS__)) 78 | #define NX_PP_A17(...) NX_PP_A1(NX_PP_B16(__VA_ARGS__)) 79 | #define NX_PP_A18(...) NX_PP_A1(NX_PP_B17(__VA_ARGS__)) 80 | #define NX_PP_A19(...) NX_PP_A1(NX_PP_B18(__VA_ARGS__)) 81 | 82 | #define NX_PP_A20(...) NX_PP_A1(NX_PP_B19(__VA_ARGS__)) 83 | 84 | #define NX_PP_A_P(F, ...) NX_PP_VA(F(__VA_ARGS__)) 85 | #define NX_PP_A(n, ...) NX_PP_A_P(NX_PP_JOIN(NX_PP_A, n), __VA_ARGS__) 86 | -------------------------------------------------------------------------------- /nixycore/preprocessor/pp_count.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | // preprocessor macros 11 | #include "nixycore/preprocessor/pp_macros.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | #define NX_PP_MAX 20 16 | 17 | #define NX_PP_FILTER_( _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \ 18 | _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ 19 | _N, ...) _N 20 | 21 | #define NX_PP_NUMBER_() 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \ 22 | 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 23 | 24 | /* 25 | Get count of args from __VA_ARGS__ 26 | 27 | NX_PP_COUNT(a, b, c, d) 28 | --> 29 | 4 30 | */ 31 | 32 | #define NX_PP_HELPER(...) NX_PP_VA(NX_PP_FILTER_(__VA_ARGS__)) 33 | #define NX_PP_COUNT(...) NX_PP_HELPER(__VA_ARGS__, NX_PP_NUMBER_()) 34 | -------------------------------------------------------------------------------- /nixycore/preprocessor/pp_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | /* 13 | Get a string of macro 14 | */ 15 | 16 | #define NX_PP_SOL(...) #__VA_ARGS__ 17 | #define NX_PP_STR_(...) NX_PP_SOL(__VA_ARGS__) 18 | #define NX_PP_STR(...) NX_PP_STR_(__VA_ARGS__) 19 | 20 | /* 21 | Connect two args together 22 | */ 23 | 24 | #define NX_PP_CAT(x, ...) x##__VA_ARGS__ 25 | #define NX_PP_JOIN_(x, ...) NX_PP_CAT(x, __VA_ARGS__) 26 | #define NX_PP_JOIN(x, ...) NX_PP_JOIN_(x, __VA_ARGS__) 27 | 28 | /* 29 | Circumvent MSVC __VA_ARGS__ BUG 30 | */ 31 | 32 | #define NX_PP_VA(...) __VA_ARGS__ /* Try to expand __VA_ARGS__ */ 33 | #define NX_PP_PROXY(F, ...) NX_PP_VA(F(__VA_ARGS__)) 34 | -------------------------------------------------------------------------------- /nixycore/preprocessor/pp_mult.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | // preprocessor macros 11 | #include "nixycore/preprocessor/pp_macros.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | #define NX_PP_MULT_0(f) 16 | 17 | #define NX_PP_MULT_1(f) f(1) 18 | #define NX_PP_MULT_2(f) NX_PP_MULT_1(f) f(2) 19 | #define NX_PP_MULT_3(f) NX_PP_MULT_2(f) f(3) 20 | #define NX_PP_MULT_4(f) NX_PP_MULT_3(f) f(4) 21 | #define NX_PP_MULT_5(f) NX_PP_MULT_4(f) f(5) 22 | #define NX_PP_MULT_6(f) NX_PP_MULT_5(f) f(6) 23 | #define NX_PP_MULT_7(f) NX_PP_MULT_6(f) f(7) 24 | #define NX_PP_MULT_8(f) NX_PP_MULT_7(f) f(8) 25 | #define NX_PP_MULT_9(f) NX_PP_MULT_8(f) f(9) 26 | #define NX_PP_MULT_10(f) NX_PP_MULT_9(f) f(10) 27 | 28 | #define NX_PP_MULT_11(f) NX_PP_MULT_10(f) f(11) 29 | #define NX_PP_MULT_12(f) NX_PP_MULT_11(f) f(12) 30 | #define NX_PP_MULT_13(f) NX_PP_MULT_12(f) f(13) 31 | #define NX_PP_MULT_14(f) NX_PP_MULT_13(f) f(14) 32 | #define NX_PP_MULT_15(f) NX_PP_MULT_14(f) f(15) 33 | #define NX_PP_MULT_16(f) NX_PP_MULT_15(f) f(16) 34 | #define NX_PP_MULT_17(f) NX_PP_MULT_16(f) f(17) 35 | #define NX_PP_MULT_18(f) NX_PP_MULT_17(f) f(18) 36 | #define NX_PP_MULT_19(f) NX_PP_MULT_18(f) f(19) 37 | #define NX_PP_MULT_20(f) NX_PP_MULT_19(f) f(20) 38 | 39 | /* 40 | NX_PP_MULT(10, f) 41 | --> 42 | f(1) f(2) f(3) f(4) f(5) f(6) f(7) f(8) f(9) f(10) 43 | */ 44 | 45 | #define NX_PP_MULT_P(F, ...) NX_PP_VA(F(__VA_ARGS__)) 46 | #define NX_PP_MULT(n, f) NX_PP_MULT_P(NX_PP_JOIN(NX_PP_MULT_, n), f) 47 | #define NX_PP_MULT_MAX(f) NX_PP_MULT(NX_PP_MAX, f) 48 | -------------------------------------------------------------------------------- /nixycore/preprocessor/pp_nest.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | // NX_PP_COUNT 11 | #include "nixycore/preprocessor/pp_count.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | #define NX_PP_NEST_0(f, l, n, ...) 16 | 17 | #define NX_PP_NEST_1(f, l, n, ...) NX_PP_VA(l(NX_PP_VA(__VA_ARGS__))) 18 | #define NX_PP_NEST_2(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_1(f, l, n, n(__VA_ARGS__)))) 19 | #define NX_PP_NEST_3(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_2(f, l, n, n(__VA_ARGS__)))) 20 | #define NX_PP_NEST_4(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_3(f, l, n, n(__VA_ARGS__)))) 21 | #define NX_PP_NEST_5(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_4(f, l, n, n(__VA_ARGS__)))) 22 | #define NX_PP_NEST_6(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_5(f, l, n, n(__VA_ARGS__)))) 23 | #define NX_PP_NEST_7(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_6(f, l, n, n(__VA_ARGS__)))) 24 | #define NX_PP_NEST_8(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_7(f, l, n, n(__VA_ARGS__)))) 25 | #define NX_PP_NEST_9(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_8(f, l, n, n(__VA_ARGS__)))) 26 | #define NX_PP_NEST_10(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_9(f, l, n, n(__VA_ARGS__)))) 27 | 28 | #define NX_PP_NEST_11(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_10(f, l, n, n(__VA_ARGS__)))) 29 | #define NX_PP_NEST_12(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_11(f, l, n, n(__VA_ARGS__)))) 30 | #define NX_PP_NEST_13(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_12(f, l, n, n(__VA_ARGS__)))) 31 | #define NX_PP_NEST_14(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_13(f, l, n, n(__VA_ARGS__)))) 32 | #define NX_PP_NEST_15(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_14(f, l, n, n(__VA_ARGS__)))) 33 | #define NX_PP_NEST_16(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_15(f, l, n, n(__VA_ARGS__)))) 34 | #define NX_PP_NEST_17(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_16(f, l, n, n(__VA_ARGS__)))) 35 | #define NX_PP_NEST_18(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_17(f, l, n, n(__VA_ARGS__)))) 36 | #define NX_PP_NEST_19(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_18(f, l, n, n(__VA_ARGS__)))) 37 | #define NX_PP_NEST_20(f, l, n, ...) NX_PP_VA(f(NX_PP_VA(__VA_ARGS__), NX_PP_NEST_19(f, l, n, n(__VA_ARGS__)))) 38 | 39 | /* 40 | NX_PP_NEST(3, func, last, nest, xx) 41 | --> 42 | func(xx, func(nest(xx), last(nest(nest(xx))))) 43 | */ 44 | 45 | #define NX_PP_NEST_P(F, ...) NX_PP_VA(F(__VA_ARGS__)) 46 | #define NX_PP_NEST(n, func, last, nest, ...) NX_PP_NEST_P(NX_PP_JOIN(NX_PP_NEST_, n), func, last, nest, __VA_ARGS__) 47 | #define NX_PP_NEST_MAX(func, last, nest, ...) NX_PP_NEST(NX_PP_MAX, func, last, nest, __VA_ARGS__) 48 | -------------------------------------------------------------------------------- /nixycore/preprocessor/pp_repeat.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | // preprocessor macros 11 | #include "nixycore/preprocessor/pp_macros.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | #define NX_PP_REPEAT_0(f1, f2, ...) 16 | 17 | #define NX_PP_REPEAT_1(f1, f2, ...) NX_PP_VA(f1(1, __VA_ARGS__)) 18 | #define NX_PP_REPEAT_2(f1, f2, ...) NX_PP_REPEAT_1(f1, f2, __VA_ARGS__) NX_PP_VA(f2(2, __VA_ARGS__)) 19 | #define NX_PP_REPEAT_3(f1, f2, ...) NX_PP_REPEAT_2(f1, f2, __VA_ARGS__) NX_PP_VA(f2(3, __VA_ARGS__)) 20 | #define NX_PP_REPEAT_4(f1, f2, ...) NX_PP_REPEAT_3(f1, f2, __VA_ARGS__) NX_PP_VA(f2(4, __VA_ARGS__)) 21 | #define NX_PP_REPEAT_5(f1, f2, ...) NX_PP_REPEAT_4(f1, f2, __VA_ARGS__) NX_PP_VA(f2(5, __VA_ARGS__)) 22 | #define NX_PP_REPEAT_6(f1, f2, ...) NX_PP_REPEAT_5(f1, f2, __VA_ARGS__) NX_PP_VA(f2(6, __VA_ARGS__)) 23 | #define NX_PP_REPEAT_7(f1, f2, ...) NX_PP_REPEAT_6(f1, f2, __VA_ARGS__) NX_PP_VA(f2(7, __VA_ARGS__)) 24 | #define NX_PP_REPEAT_8(f1, f2, ...) NX_PP_REPEAT_7(f1, f2, __VA_ARGS__) NX_PP_VA(f2(8, __VA_ARGS__)) 25 | #define NX_PP_REPEAT_9(f1, f2, ...) NX_PP_REPEAT_8(f1, f2, __VA_ARGS__) NX_PP_VA(f2(9, __VA_ARGS__)) 26 | #define NX_PP_REPEAT_10(f1, f2, ...) NX_PP_REPEAT_9(f1, f2, __VA_ARGS__) NX_PP_VA(f2(10, __VA_ARGS__)) 27 | 28 | #define NX_PP_REPEAT_11(f1, f2, ...) NX_PP_REPEAT_10(f1, f2, __VA_ARGS__) NX_PP_VA(f2(11, __VA_ARGS__)) 29 | #define NX_PP_REPEAT_12(f1, f2, ...) NX_PP_REPEAT_11(f1, f2, __VA_ARGS__) NX_PP_VA(f2(12, __VA_ARGS__)) 30 | #define NX_PP_REPEAT_13(f1, f2, ...) NX_PP_REPEAT_12(f1, f2, __VA_ARGS__) NX_PP_VA(f2(13, __VA_ARGS__)) 31 | #define NX_PP_REPEAT_14(f1, f2, ...) NX_PP_REPEAT_13(f1, f2, __VA_ARGS__) NX_PP_VA(f2(14, __VA_ARGS__)) 32 | #define NX_PP_REPEAT_15(f1, f2, ...) NX_PP_REPEAT_14(f1, f2, __VA_ARGS__) NX_PP_VA(f2(15, __VA_ARGS__)) 33 | #define NX_PP_REPEAT_16(f1, f2, ...) NX_PP_REPEAT_15(f1, f2, __VA_ARGS__) NX_PP_VA(f2(16, __VA_ARGS__)) 34 | #define NX_PP_REPEAT_17(f1, f2, ...) NX_PP_REPEAT_16(f1, f2, __VA_ARGS__) NX_PP_VA(f2(17, __VA_ARGS__)) 35 | #define NX_PP_REPEAT_18(f1, f2, ...) NX_PP_REPEAT_17(f1, f2, __VA_ARGS__) NX_PP_VA(f2(18, __VA_ARGS__)) 36 | #define NX_PP_REPEAT_19(f1, f2, ...) NX_PP_REPEAT_18(f1, f2, __VA_ARGS__) NX_PP_VA(f2(19, __VA_ARGS__)) 37 | #define NX_PP_REPEAT_20(f1, f2, ...) NX_PP_REPEAT_19(f1, f2, __VA_ARGS__) NX_PP_VA(f2(20, __VA_ARGS__)) 38 | 39 | /* 40 | NX_PP_REPEAT(5, f, data) 41 | --> 42 | f(1, data) f(2, data) f(3, data) f(4, data) f(5, data) 43 | */ 44 | 45 | #define NX_PP_REPEAT_P(F, ...) NX_PP_VA(F(__VA_ARGS__)) 46 | 47 | #define NX_PP_REPEATEX(n, f1, f2, ...) NX_PP_REPEAT_P(NX_PP_JOIN(NX_PP_REPEAT_, n), f1, f2, __VA_ARGS__) 48 | #define NX_PP_REPEATEX_MAX(f1, f2, ...) NX_PP_REPEATEX(NX_PP_MAX, f1, f2, __VA_ARGS__) 49 | 50 | #define NX_PP_REPEAT(n, f, ...) NX_PP_REPEATEX(n, f, f, __VA_ARGS__) 51 | #define NX_PP_REPEAT_MAX(f, ...) NX_PP_REPEATEX_MAX(f, f, __VA_ARGS__) 52 | -------------------------------------------------------------------------------- /nixycore/random/rand_std.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typedefs.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | NX_BEG namespace use { 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | /* 19 | Standard random policy 20 | */ 21 | 22 | struct rand_std 23 | { 24 | typedef int rand_t; 25 | 26 | NX_STATIC_PROPERTY(rand_t, MAX, RAND_MAX); 27 | 28 | void srand(nx::uint sd) 29 | { 30 | ::srand(sd); 31 | } 32 | 33 | rand_t rand(void) 34 | { 35 | return ::rand(); 36 | } 37 | }; 38 | 39 | ////////////////////////////////////////////////////////////////////////// 40 | } NX_END 41 | ////////////////////////////////////////////////////////////////////////// 42 | -------------------------------------------------------------------------------- /nixycore/random/random.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/random/rand_std.h" 11 | #include "nixycore/random/rand_mt19937.h" 12 | 13 | #include "nixycore/time/tickcount.h" 14 | 15 | #include "nixycore/general/general.h" 16 | #include "nixycore/typemanip/typemanip.h" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifndef NX_DEFAULT_RAND 23 | #define NX_DEFAULT_RAND nx::use::rand_mt19937 24 | #endif 25 | 26 | template 27 | class random : public ModelT 28 | { 29 | protected: 30 | int lower_, upper_; 31 | 32 | double roll(void) 33 | { 34 | return (ModelT::rand() + 0.5) / (ModelT::MAX + 1.0); 35 | } 36 | 37 | public: 38 | random(int lower = 0, int upper = ModelT::MAX) 39 | : lower_(0), upper_(0) 40 | { 41 | range(lower, upper); 42 | srand(); 43 | } 44 | 45 | void range(int lower = 0, int upper = ModelT::MAX) 46 | { 47 | lower_ = lower; 48 | upper_ = upper; 49 | } 50 | 51 | void srand(nx::uint seed = 0) 52 | { 53 | ModelT::srand(seed ? seed : static_cast(tickcount())); 54 | } 55 | 56 | template 57 | T roll(int lower, int upper) 58 | { 59 | return static_cast( lower + (upper - lower) * roll() ); 60 | } 61 | 62 | template 63 | T roll(void) 64 | { 65 | return roll(lower_, upper_); 66 | } 67 | 68 | template 69 | T roll(T& r_, int lower, int upper) 70 | { 71 | return r_ = roll(lower, upper); 72 | } 73 | 74 | template 75 | T roll(T& r_) 76 | { 77 | return r_ = roll(); 78 | } 79 | }; 80 | 81 | ////////////////////////////////////////////////////////////////////////// 82 | NX_END 83 | ////////////////////////////////////////////////////////////////////////// 84 | -------------------------------------------------------------------------------- /nixycore/stream/detail/stream_buffer_in.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | void make_finish(void) 11 | { 12 | index_ = fmt_.length(); // make finish 13 | ref_index_ = ref_->length(); // make read complete 14 | } 15 | 16 | void check_matching(wchar c, wchar r) 17 | { 18 | if (c == r) 19 | ref_index_ += 1; 20 | else 21 | make_finish(); 22 | } 23 | 24 | void put_buffer_and_wait(wchar r) 25 | { 26 | string tmp; 27 | bool end_state = false; 28 | do 29 | { 30 | if (string::default_check(r)) 31 | { 32 | if (end_state) break; 33 | } 34 | else 35 | { 36 | tmp.push_back(r); 37 | end_state = true; 38 | } 39 | ref_index_ += 1; 40 | if (is_read_complete()) break; 41 | r = ref_->at(ref_index_); 42 | } while (true); 43 | buf_.swap(tmp); 44 | } 45 | 46 | void do_assign_in(void) 47 | { 48 | nx_assert(ref_); 49 | while (!is_finished()) 50 | { 51 | wchar r = ref_->at(ref_index_); 52 | wchar c = fmt_[index_++]; 53 | if (c == '%') 54 | { 55 | c = fmt_[index_++]; 56 | if (c == '%') 57 | check_matching(c, r); 58 | else 59 | return put_buffer_and_wait(r); 60 | } 61 | else 62 | check_matching(c, r); 63 | } 64 | } 65 | 66 | template 67 | void swscanf_buf(V& val) const 68 | { 69 | nx::swscanf(buf_, printf_format::val(), val); 70 | } 71 | 72 | void parse_in(bool& val) const 73 | { 74 | val = (buf_ == L"true"); 75 | } 76 | 77 | template 78 | typename enable_if::value 79 | >::type_t parse_in(V& val) const 80 | { 81 | if (buf_.empty()) return; 82 | val = buf_[0]; 83 | } 84 | 85 | template 86 | typename enable_if::value && 87 | !is_character::value && 88 | is_numeric::value 89 | >::type_t parse_in(V& val) const 90 | { 91 | swscanf_buf(val); 92 | } 93 | 94 | void parse_in(char* val) const 95 | { 96 | strcpy(val, buf_.to_local().c_str()); 97 | } 98 | 99 | void parse_in(wchar* val) const 100 | { 101 | wcscpy(val, buf_.c_str()); 102 | } 103 | 104 | void parse_in(pvoid& val) const 105 | { 106 | swscanf_buf(val); 107 | } 108 | 109 | template 110 | typename enable_if::value && /* */ 111 | is_class::value 112 | >::type_t parse_in(V& val) const 113 | { 114 | buf_ >> val; 115 | } 116 | 117 | ////////////////////////////////////////////////////////////////////////// 118 | -------------------------------------------------------------------------------- /nixycore/stream/detail/stream_buffer_out.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | void do_assign_out(void) 11 | { 12 | while (!is_finished()) 13 | { 14 | wchar c = fmt_[index_++]; 15 | if (c == '%') 16 | { 17 | c = fmt_[index_++]; 18 | if (c == '%') 19 | buf_.push_back(c); 20 | else 21 | return; // and just wait 22 | } 23 | else 24 | buf_.push_back(c); 25 | } 26 | } 27 | 28 | template 29 | void swprintf_buf(const V& val) 30 | { 31 | nx::swprintf(buf_, printf_format::val(), val); 32 | } 33 | 34 | void parse_out(bool val) 35 | { 36 | static const wchar PARSE_T_[] = L"true"; 37 | static const wchar PARSE_F_[] = L"false"; 38 | if (val) 39 | buf_.append(PARSE_T_, nx_countof(PARSE_T_) - 1); 40 | else 41 | buf_.append(PARSE_F_, nx_countof(PARSE_F_) - 1); 42 | } 43 | 44 | template 45 | typename enable_if::value 46 | >::type_t parse_out(V val) 47 | { 48 | buf_.push_back(val); 49 | } 50 | 51 | template 52 | typename enable_if::value && 53 | !is_character::value && 54 | is_numeric::value 55 | >::type_t parse_out(V val) 56 | { 57 | swprintf_buf(val); 58 | } 59 | 60 | void parse_out(const char* val) 61 | { 62 | buf_ += val; 63 | } 64 | 65 | void parse_out(const wchar* val) 66 | { 67 | buf_ += val; 68 | } 69 | 70 | void parse_out(pvoid val) 71 | { 72 | swprintf_buf(val); 73 | } 74 | 75 | template 76 | typename enable_if::value && /* */ 77 | is_class::value 78 | >::type_t parse_out(const V& val) 79 | { 80 | buf_ << val; 81 | } 82 | 83 | ////////////////////////////////////////////////////////////////////////// 84 | -------------------------------------------------------------------------------- /nixycore/stream/printf_format.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | #include "nixycore/preprocessor/pp_macros.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | NX_BEG 15 | ////////////////////////////////////////////////////////////////////////// 16 | 17 | /* 18 | format string for printf 19 | */ 20 | 21 | template 22 | struct printf_format; 23 | 24 | #define NX_PRINTF_FORMAT_(R, ...) \ 25 | NX_PP_VA(template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%c" ; } }; \ 26 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%c" ; } }; \ 27 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%lc" ; } }; \ 28 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%d" ; } }; \ 29 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%u" ; } }; \ 30 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%d" ; } }; \ 31 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%u" ; } }; \ 32 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%ld" ; } }; \ 33 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%lu" ; } }; \ 34 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%lld"; } }; \ 35 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%llu"; } }; \ 36 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%f" ; } }; \ 37 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%g" ; } }; \ 38 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%Lg" ; } }; \ 39 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%s" ; } }; \ 40 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%ls" ; } }; \ 41 | template <> struct printf_format { static const R* val(void) { return __VA_ARGS__##"%p" ; } }; \ 42 | template <> struct printf_format : printf_format {}; \ 43 | template \ 44 | struct printf_format : printf_format {}; \ 45 | template \ 46 | struct printf_format : printf_format {}; \ 47 | template \ 48 | struct printf_format : printf_format {}; ) 49 | 50 | NX_PRINTF_FORMAT_(char) 51 | NX_PRINTF_FORMAT_(wchar, L) 52 | 53 | #undef NX_PRINTF_FORMAT_ 54 | 55 | ////////////////////////////////////////////////////////////////////////// 56 | NX_END 57 | ////////////////////////////////////////////////////////////////////////// 58 | -------------------------------------------------------------------------------- /nixycore/stream/stream.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/stream/printf_format.h" 13 | #include "nixycore/stream/stream_wrap.h" 14 | #include "nixycore/stream/stream_buffer.h" 15 | #include "nixycore/stream/stream_detail.h" 16 | #include "nixycore/stream/stream_ops.h" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | -------------------------------------------------------------------------------- /nixycore/stream/stream_detail.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/stream/stream_buffer.h" 11 | #include "nixycore/stream/stream_wrap.h" 12 | 13 | #include "nixycore/general/general.h" 14 | #include "nixycore/utility/utility.h" 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | template 21 | class stream : public stream_wrap > 22 | { 23 | typedef stream_wrap > base_t; 24 | 25 | public: 26 | template 27 | stream(T* tp, const S& fs) 28 | { 29 | base_t::set_format(tp, fs); 30 | } 31 | 32 | stream(T* tp) 33 | { 34 | base_t::set_format(tp, L""); 35 | } 36 | }; 37 | 38 | /* 39 | Make a stream for in or out 40 | */ 41 | 42 | template 43 | stream format(T* tp, const S& fs) 44 | { 45 | return stream(tp, fs); 46 | } 47 | 48 | template 49 | stream io(T* tp) 50 | { 51 | return stream(tp); 52 | } 53 | 54 | ////////////////////////////////////////////////////////////////////////// 55 | NX_END 56 | ////////////////////////////////////////////////////////////////////////// 57 | -------------------------------------------------------------------------------- /nixycore/stream/stream_ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/stream/stream_detail.h" 11 | 12 | #include "nixycore/general/general.h" 13 | #include "nixycore/utility/utility.h" 14 | #include "nixycore/string/string.h" 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | /* 21 | Print "\n" to the stream, just like std::endl 22 | */ 23 | 24 | template 25 | const stream_wrap

& endl(const stream_wrap

& ss) 26 | { 27 | return ss << L"\n"; 28 | } 29 | 30 | template 31 | const stream_wrap

& endl(const stream_wrap

& ss) 32 | { 33 | for(size_t i = 0; i < N; ++i) 34 | ss << L"\n"; 35 | return ss; 36 | } 37 | 38 | /* 39 | Custom format 40 | */ 41 | 42 | template 43 | class custom_format 44 | { 45 | nx::string fmt_; 46 | T ref_; 47 | 48 | public: 49 | template 50 | custom_format(const S& fmt, T r) 51 | : fmt_(fmt) 52 | , ref_(r) 53 | {} 54 | 55 | custom_format(nx_rref(custom_format, true) rhs) 56 | : ref_(nx::moved(rhs).ref_) 57 | { 58 | nx::moved(rhs).fmt_.swap(fmt_); 59 | } 60 | 61 | friend void operator<<(string& buf, const custom_format& val) // out 62 | { 63 | nx::swprintf(buf, val.fmt_.c_str(), val.ref_); 64 | } 65 | 66 | friend void operator>>(const string& buf, custom_format& val) // in 67 | { 68 | nx::swscanf(buf, val.fmt_.c_str(), val.ref_); 69 | } 70 | }; 71 | 72 | template 73 | custom_format fmt(const S& fmt, const T& val) 74 | { 75 | return custom_format(fmt, val); 76 | } 77 | 78 | template 79 | custom_format fmt(const S& fmt, T& val) 80 | { 81 | return custom_format(fmt, val); 82 | } 83 | 84 | ////////////////////////////////////////////////////////////////////////// 85 | NX_END 86 | ////////////////////////////////////////////////////////////////////////// 87 | -------------------------------------------------------------------------------- /nixycore/stream/stream_wrap.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | template 17 | class stream_wrap : public PolicyT 18 | { 19 | public: 20 | typedef PolicyT policy_t; 21 | typedef stream_wrap warp_t; 22 | typedef const warp_t& (*option_t)(const warp_t&); 23 | 24 | public: 25 | /* 26 | operator<< 27 | */ 28 | 29 | template 30 | friend const warp_t& operator<<(const warp_t& s, const T& data) 31 | { 32 | const_cast(s).policy_t::operator<<(data); 33 | return s; 34 | } 35 | 36 | template 37 | friend const warp_t& operator>>(const warp_t& s, T& data) 38 | { 39 | const_cast(s).policy_t::operator>>(data); 40 | return s; 41 | } 42 | 43 | friend const warp_t& operator<<(const warp_t& s, option_t opt) 44 | { 45 | return opt(s); 46 | } 47 | 48 | /* 49 | operator, 50 | */ 51 | 52 | template 53 | friend const warp_t& operator,(const warp_t& s, const T& data) 54 | { 55 | return s << data; 56 | } 57 | 58 | friend const warp_t& operator,(const warp_t& s, option_t opt) 59 | { 60 | return s << opt; 61 | } 62 | 63 | /* 64 | operator() 65 | */ 66 | 67 | template 68 | const warp_t& operator()(const T& data) const 69 | { 70 | return (*this) << data; 71 | } 72 | 73 | template 74 | const warp_t& operator()(option_t opt) const 75 | { 76 | return (*this) << opt; 77 | } 78 | }; 79 | 80 | ////////////////////////////////////////////////////////////////////////// 81 | NX_END 82 | ////////////////////////////////////////////////////////////////////////// 83 | -------------------------------------------------------------------------------- /nixycore/string/string.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/string/transform.h" 13 | #include "nixycore/string/string_detail.h" 14 | 15 | ////////////////////////////////////////////////////////////////////////// 16 | -------------------------------------------------------------------------------- /nixycore/thread/barrier.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | #ifdef NX_SP_CXX11_ATOMIC 13 | #include // std::atomic ... 14 | 15 | ////////////////////////////////////////////////////////////////////////// 16 | NX_BEG namespace thread_ops { 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | inline static void cc_barrier(void) 20 | { 21 | std::atomic_signal_fence(std::memory_order_seq_cst); 22 | } 23 | 24 | inline static void mm_barrier(void) 25 | { 26 | std::atomic_thread_fence(std::memory_order_seq_cst); 27 | } 28 | 29 | ////////////////////////////////////////////////////////////////////////// 30 | } NX_END 31 | ////////////////////////////////////////////////////////////////////////// 32 | #else /*NX_SP_CXX11_ATOMIC*/ 33 | 34 | #if defined(NX_CC_MSVC) 35 | # include "detail/barrier_msvc.hxx" 36 | #elif defined(NX_CC_GNUC) 37 | # include "detail/barrier_gnuc.hxx" 38 | #endif 39 | 40 | #endif/*NX_SP_CXX11_ATOMIC*/ 41 | -------------------------------------------------------------------------------- /nixycore/thread/blocking_queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/thread/lock_guard.h" 11 | #include "nixycore/thread/mutex.h" 12 | #include "nixycore/thread/condition.h" 13 | 14 | #include "nixycore/container/deque.h" 15 | 16 | #include "nixycore/bugfix/assert.h" 17 | 18 | #include "nixycore/general/general.h" 19 | #include "nixycore/utility/utility.h" 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | NX_BEG 23 | ////////////////////////////////////////////////////////////////////////// 24 | 25 | template 26 | class blocking_queue : noncopyable 27 | { 28 | mutable mutex lock_; 29 | condition task_coming_; 30 | condition until_empty_; 31 | nx::deque queue_; 32 | 33 | public: 34 | typedef T type_t; 35 | 36 | blocking_queue(void) 37 | : task_coming_(lock_) 38 | , until_empty_(lock_) 39 | {} 40 | 41 | void put(const type_t& v) 42 | { 43 | nx_lock_scope(lock_); 44 | queue_.push_back(v); 45 | task_coming_.notify(); 46 | } 47 | 48 | nx_rval(type_t) take(void) 49 | { 50 | nx_lock_scope(lock_); 51 | while (queue_.empty()) // used to avoid spurious wakeups 52 | task_coming_.wait(); 53 | nx_assert(!queue_.empty()); 54 | type_t ret(nx::move(queue_.front())); 55 | queue_.pop_front(); 56 | if (queue_.empty()) 57 | until_empty_.notify(); 58 | return nx::move(ret); 59 | } 60 | 61 | bool wait_empty(int tm_ms = -1) 62 | { 63 | nx_lock_scope(lock_); 64 | while (!queue_.empty()) // used to avoid spurious wakeups 65 | { 66 | bool ret = until_empty_.wait(tm_ms); 67 | if (!ret) return false; 68 | } 69 | return true; 70 | } 71 | 72 | size_t size(void) const 73 | { 74 | nx_lock_scope(lock_); 75 | return queue_.size(); 76 | } 77 | 78 | bool is_empty(void) const 79 | { 80 | nx_lock_scope(lock_); 81 | return queue_.empty(); 82 | } 83 | }; 84 | 85 | ////////////////////////////////////////////////////////////////////////// 86 | NX_END 87 | ////////////////////////////////////////////////////////////////////////// 88 | -------------------------------------------------------------------------------- /nixycore/thread/condition.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/thread/mutex.h" 11 | 12 | #include "nixycore/general/general.h" 13 | #include "nixycore/utility/utility.h" 14 | 15 | #ifdef NX_SP_CXX11_CONDITION 16 | #include 17 | #include // std::chrono::milliseconds 18 | #endif 19 | 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | #ifndef NX_SP_CXX11_CONDITION 23 | #if defined(NX_OS_WIN) 24 | # include "detail/condition_win.hxx" 25 | #elif defined(NX_OS_LINUX) 26 | # include "detail/condition_linux.hxx" 27 | #endif 28 | #endif/*NX_SP_CXX11_CONDITION*/ 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | NX_BEG 32 | ////////////////////////////////////////////////////////////////////////// 33 | 34 | #ifdef NX_SP_CXX11_CONDITION 35 | namespace private_condition 36 | { 37 | class detail : private std::condition_variable_any 38 | { 39 | typedef std::condition_variable_any base_t; 40 | 41 | mutex& cond_mutex_; 42 | 43 | public: 44 | detail(mutex& mx) 45 | : cond_mutex_(mx) 46 | {} 47 | 48 | ~detail(void) 49 | { 50 | broadcast(); 51 | } 52 | 53 | public: 54 | bool wait(int tm_ms = -1) 55 | { 56 | if (tm_ms < 0) 57 | { 58 | base_t::wait(cond_mutex_); 59 | return true; 60 | } 61 | else 62 | { 63 | return (base_t::wait_for(cond_mutex_, std::chrono::milliseconds(tm_ms)) 64 | == std::cv_status::no_timeout); 65 | } 66 | } 67 | 68 | void notify(void) 69 | { 70 | base_t::notify_one(); 71 | } 72 | 73 | void broadcast(void) 74 | { 75 | base_t::notify_all(); 76 | } 77 | }; 78 | } 79 | #endif/*NX_SP_CXX11_CONDITION*/ 80 | 81 | class condition 82 | : public private_condition::detail, nx::noncopyable 83 | { 84 | public: 85 | condition(mutex& mx) 86 | : private_condition::detail(mx) 87 | {} 88 | }; 89 | 90 | ////////////////////////////////////////////////////////////////////////// 91 | NX_END 92 | ////////////////////////////////////////////////////////////////////////// 93 | -------------------------------------------------------------------------------- /nixycore/thread/detail/barrier_gnuc.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | #define NX_CC_BARRIER() __asm__ __volatile__ ("" ::: "memory") 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG namespace thread_ops { 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | inline static void cc_barrier(void) 17 | { 18 | NX_CC_BARRIER(); 19 | } 20 | 21 | inline static void mm_barrier(void) 22 | { 23 | #if NX_CHECK_GNUC(4, 4, 0) 24 | /* 25 | Bug 36793 - x86-64 does not get __sync_synchronize right 26 | See: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36793 27 | */ 28 | __sync_synchronize(); 29 | #elif defined(NX_PC_X86_64) || defined(NX_PC_SSE2) 30 | __asm__ __volatile__ ("mfence" ::: "memory"); 31 | #elif defined(NX_PC_X86_32) 32 | __asm__ __volatile__ ("lock ; addl $0, (%%esp)" ::: "memory"); 33 | #elif defined(NX_PC_IA_64) 34 | __asm__ __volatile__ ("mf" ::: "memory"); 35 | #elif defined(NX_PC_ARM) 36 | ((void(*)(void))0xffff0fa0)(); 37 | NX_CC_BARRIER(); 38 | #endif 39 | } 40 | 41 | ////////////////////////////////////////////////////////////////////////// 42 | } NX_END 43 | ////////////////////////////////////////////////////////////////////////// 44 | -------------------------------------------------------------------------------- /nixycore/thread/detail/barrier_msvc.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | #include "interlocked_def_msvc.hxx" 11 | 12 | #if defined(NX_OS_WINCE) 13 | # define NX_CC_BARRIER() 14 | #else /*NX_OS_WINCE*/ 15 | # include 16 | # pragma intrinsic(_ReadWriteBarrier) 17 | # define NX_CC_BARRIER() _ReadWriteBarrier() 18 | #endif/*NX_OS_WINCE*/ 19 | 20 | ////////////////////////////////////////////////////////////////////////// 21 | NX_BEG namespace thread_ops { 22 | ////////////////////////////////////////////////////////////////////////// 23 | 24 | inline static void cc_barrier(void) 25 | { 26 | NX_CC_BARRIER(); 27 | } 28 | 29 | inline static void mm_barrier(void) 30 | { 31 | NX_CC_BARRIER(); 32 | #if defined(NX_OS_WINCE) 33 | long tmp; 34 | NX_INTERLOCKED_EXCHANGE(tmp, 0); 35 | #else 36 | MemoryBarrier(); 37 | #endif 38 | } 39 | 40 | ////////////////////////////////////////////////////////////////////////// 41 | } NX_END 42 | ////////////////////////////////////////////////////////////////////////// 43 | -------------------------------------------------------------------------------- /nixycore/thread/detail/condition_linux.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #include "nixycore/time/tickcount.h" 9 | 10 | #include 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG namespace private_condition { 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | class detail 17 | { 18 | pthread_cond_t cond_; 19 | mutex& cond_mutex_; 20 | 21 | public: 22 | detail(mutex& mx) 23 | : cond_mutex_(mx) 24 | { 25 | pthread_condattr_t attr; 26 | if (pthread_condattr_init(&attr) != 0) return; 27 | pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); 28 | pthread_cond_init(&cond_, &attr); 29 | pthread_condattr_destroy(&attr); 30 | } 31 | 32 | ~detail(void) 33 | { 34 | broadcast(); 35 | pthread_cond_destroy(&cond_); 36 | } 37 | 38 | public: 39 | bool wait(int tm_ms = -1) 40 | { 41 | int err; 42 | if (tm_ms < 0) 43 | { 44 | err = pthread_cond_wait(&cond_, &(*cond_mutex_)); 45 | } 46 | else 47 | { 48 | ulong tc = tickcount() + tm_ms; 49 | struct timespec tv; 50 | tv.tv_sec = (tc / 1000); 51 | tv.tv_nsec = (tc % 1000) * 1000000; 52 | // returns true if signal comes, false otherwise. 53 | err = pthread_cond_timedwait(&cond_, &(*cond_mutex_), &tv); 54 | } 55 | return (err == 0); 56 | } 57 | 58 | void notify(void) 59 | { 60 | pthread_cond_signal(&cond_); 61 | } 62 | 63 | void broadcast(void) 64 | { 65 | pthread_cond_broadcast(&cond_); 66 | } 67 | }; 68 | 69 | ////////////////////////////////////////////////////////////////////////// 70 | } NX_END 71 | ////////////////////////////////////////////////////////////////////////// 72 | -------------------------------------------------------------------------------- /nixycore/thread/detail/condition_win.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #if defined(NX_OS_WINCE) || (WINVER < 0x0600) 9 | #include "nixycore/thread/lock_guard.h" 10 | #endif 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG namespace private_condition { 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | /* 17 | wince, winxp, win2003, ... 18 | */ 19 | #if defined(NX_OS_WINCE) || (WINVER < 0x0600) 20 | 21 | class detail 22 | { 23 | mutex lock_; 24 | HANDLE sema_, handshake_; 25 | mutex& cond_mutex_; 26 | long counter_; 27 | 28 | public: 29 | detail(mutex& mx) 30 | : sema_ (CreateSemaphore(NULL, 0, LONG_MAX, NULL)) 31 | , handshake_(CreateSemaphore(NULL, 0, LONG_MAX, NULL)) 32 | , cond_mutex_(mx) 33 | , counter_(0) 34 | {} 35 | 36 | ~detail(void) 37 | { 38 | broadcast(); 39 | CloseHandle(handshake_); 40 | CloseHandle(sema_); 41 | } 42 | 43 | public: 44 | bool wait(int tm_ms = -1) 45 | { 46 | { 47 | nx_lock_scope(lock_); 48 | ++ counter_; 49 | } 50 | cond_mutex_.unlock(); 51 | bool ret_s = (WaitForSingleObject(sema_, (tm_ms < 0) ? INFINITE : tm_ms) == WAIT_OBJECT_0); 52 | bool ret_h = !!ReleaseSemaphore(handshake_, 1, NULL); 53 | cond_mutex_.lock(); 54 | return ret_s && ret_h; 55 | } 56 | 57 | void notify(void) 58 | { 59 | nx_lock_scope(lock_); 60 | if (counter_ > 0) 61 | { 62 | ReleaseSemaphore(sema_, 1, NULL); 63 | -- counter_; 64 | WaitForSingleObject(handshake_, INFINITE); 65 | } 66 | } 67 | 68 | void broadcast(void) 69 | { 70 | nx_lock_scope(lock_); 71 | if (counter_ > 0) 72 | { 73 | ReleaseSemaphore(sema_, counter_, NULL); 74 | do 75 | { 76 | -- counter_; 77 | WaitForSingleObject(handshake_, INFINITE); 78 | } while (counter_ > 0); 79 | } 80 | } 81 | }; 82 | 83 | /* 84 | vista, win7, ... 85 | */ 86 | #else // (WINVER >= 0x0600) 87 | 88 | class detail 89 | { 90 | CONDITION_VARIABLE cond_; 91 | mutex& cond_mutex_; 92 | 93 | public: 94 | detail(mutex& mx) 95 | : cond_mutex_(mx) 96 | { 97 | InitializeConditionVariable(&cond_); 98 | } 99 | 100 | ~detail(void) 101 | { 102 | broadcast(); 103 | } 104 | 105 | public: 106 | bool wait(int tm_ms = -1) 107 | { 108 | // returns true if signal comes, false otherwise. 109 | return !!SleepConditionVariableCS(&cond_, &(*cond_mutex_), (tm_ms < 0) ? INFINITE : tm_ms); 110 | } 111 | 112 | void notify(void) 113 | { 114 | WakeConditionVariable(&cond_); 115 | } 116 | 117 | void broadcast(void) 118 | { 119 | WakeAllConditionVariable(&cond_); 120 | } 121 | }; 122 | 123 | #endif /* vista, win7, ... */ 124 | 125 | ////////////////////////////////////////////////////////////////////////// 126 | } NX_END 127 | ////////////////////////////////////////////////////////////////////////// 128 | -------------------------------------------------------------------------------- /nixycore/thread/detail/mutex_linux.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #include 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | NX_BEG namespace private_mutex { 12 | ////////////////////////////////////////////////////////////////////////// 13 | 14 | class detail 15 | { 16 | protected: 17 | pthread_mutex_t mx_; 18 | 19 | public: 20 | detail(void) 21 | { pthread_mutex_init(&mx_, NULL); } 22 | 23 | ~detail(void) 24 | { pthread_mutex_destroy(&mx_); } 25 | 26 | typedef pthread_mutex_t handle_t; 27 | handle_t& operator*(void) { return mx_; } 28 | const handle_t& operator*(void) const { return mx_; } 29 | 30 | public: 31 | bool try_lock(void) 32 | { 33 | return (pthread_mutex_trylock(&mx_) == 0); 34 | } 35 | 36 | void lock(void) 37 | { 38 | pthread_mutex_lock(&mx_); 39 | } 40 | 41 | void unlock(void) 42 | { 43 | pthread_mutex_unlock(&mx_); 44 | } 45 | }; 46 | 47 | ////////////////////////////////////////////////////////////////////////// 48 | } NX_END 49 | ////////////////////////////////////////////////////////////////////////// 50 | -------------------------------------------------------------------------------- /nixycore/thread/detail/mutex_win.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | NX_BEG namespace private_mutex { 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | class detail 13 | { 14 | protected: 15 | CRITICAL_SECTION mx_; 16 | 17 | public: 18 | detail(void) 19 | { 20 | # if defined(NX_OS_WINCE) 21 | InitializeCriticalSection(&mx_); 22 | # else 23 | if(!InitializeCriticalSectionAndSpinCount(&mx_, 4000)) 24 | InitializeCriticalSection(&mx_); 25 | # endif 26 | } 27 | 28 | ~detail(void) 29 | { 30 | DeleteCriticalSection(&mx_); 31 | } 32 | 33 | typedef CRITICAL_SECTION handle_t; 34 | handle_t& operator*(void) { return mx_; } 35 | const handle_t& operator*(void) const { return mx_; } 36 | 37 | public: 38 | bool try_lock(void) 39 | { 40 | return (!!TryEnterCriticalSection(&mx_)); 41 | } 42 | 43 | void lock(void) 44 | { 45 | EnterCriticalSection(&mx_); 46 | } 47 | 48 | void unlock(void) 49 | { 50 | LeaveCriticalSection(&mx_); 51 | } 52 | }; 53 | 54 | ////////////////////////////////////////////////////////////////////////// 55 | } NX_END 56 | ////////////////////////////////////////////////////////////////////////// 57 | -------------------------------------------------------------------------------- /nixycore/thread/detail/thread_ops_define.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | typedef thread_ops::id_t id_t; 11 | typedef thread_ops::handle_t handle_t; 12 | typedef thread_ops::native_id_t native_id_t; 13 | typedef thread_ops::proc_t proc_t; 14 | 15 | static handle_t create(proc_t proc, pvoid arg = 0, id_t* thr_id = 0) 16 | { 17 | return thread_ops::create(proc, arg, thr_id); 18 | } 19 | 20 | static void exit(void) 21 | { 22 | thread_ops::exit(); 23 | } 24 | 25 | static native_id_t native_current_id(void) 26 | { 27 | return thread_ops::native_current_id(); 28 | } 29 | 30 | static id_t current_id(void) 31 | { 32 | return thread_ops::current_id(); 33 | } 34 | 35 | static id_t handle2id(handle_t hd) 36 | { 37 | return thread_ops::handle2id(hd); 38 | } 39 | 40 | static bool join(handle_t hd) 41 | { 42 | return thread_ops::join(hd); 43 | } 44 | 45 | static bool detach(handle_t hd) 46 | { 47 | return thread_ops::detach(hd); 48 | } 49 | 50 | static void sleep(unsigned ms) 51 | { 52 | thread_ops::sleep(ms); 53 | } 54 | 55 | static void yield(void) 56 | { 57 | thread_ops::yield(); 58 | } 59 | 60 | static void pause(unsigned k = 4) 61 | { 62 | thread_ops::pause(k); 63 | } 64 | 65 | static unsigned hardware_concurrency(void) 66 | { 67 | return thread_ops::hardware_concurrency(); 68 | } 69 | 70 | ////////////////////////////////////////////////////////////////////////// 71 | -------------------------------------------------------------------------------- /nixycore/thread/detail/thread_ops_linux.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #include 9 | #include 10 | #include // get_nprocs 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG namespace thread_ops { 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | typedef pthread_t id_t; 17 | typedef pthread_t handle_t; 18 | typedef pthread_t native_id_t; 19 | 20 | inline void clear_id(id_t& id) 21 | { 22 | id = 0; 23 | } 24 | 25 | inline void clear_hd(handle_t& hd) 26 | { 27 | hd = 0; 28 | } 29 | 30 | #define NX_THREAD_PROC(name, ...) void* (name)(void* __VA_ARGS__) 31 | typedef NX_THREAD_PROC(*proc_t); 32 | 33 | inline handle_t create(proc_t proc, pvoid arg = 0, id_t* thr_id = 0) 34 | { 35 | handle_t hd = 0; 36 | int err = pthread_create(&hd, NULL, proc, arg); 37 | if (err == 0) 38 | { 39 | if (thr_id) (*thr_id) = hd; 40 | } 41 | else 42 | hd = 0; 43 | return hd; 44 | } 45 | 46 | inline void exit(void) 47 | { 48 | pthread_exit(0); 49 | } 50 | 51 | inline native_id_t native_current_id(void) 52 | { 53 | return pthread_self(); 54 | } 55 | 56 | inline id_t current_id(void) 57 | { 58 | return pthread_self(); 59 | } 60 | 61 | inline id_t handle2id(handle_t hd) 62 | { 63 | return (id_t)hd; 64 | } 65 | 66 | inline bool join(handle_t hd) 67 | { 68 | return (pthread_join(hd, NULL) == 0); 69 | } 70 | 71 | inline bool detach(handle_t hd) 72 | { 73 | return (pthread_detach(hd) == 0); 74 | } 75 | 76 | inline void sleep(unsigned ms) 77 | { 78 | usleep(ms * 1000); 79 | } 80 | 81 | inline void yield(void) 82 | { 83 | pthread_yield(); 84 | } 85 | 86 | inline unsigned hardware_concurrency(void) 87 | { 88 | static unsigned cpu_count = 0; 89 | if (cpu_count > 0) return cpu_count; 90 | cpu_count = static_cast(get_nprocs()); 91 | if (cpu_count < 1) cpu_count = 1; // fail-safe 92 | return cpu_count; 93 | } 94 | 95 | ////////////////////////////////////////////////////////////////////////// 96 | } NX_END 97 | ////////////////////////////////////////////////////////////////////////// 98 | -------------------------------------------------------------------------------- /nixycore/thread/detail/tls_ptr_linux.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #include "nixycore/bugfix/assert.h" 9 | 10 | #include 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG namespace private_tls_ptr { 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | template 17 | class detail 18 | { 19 | pthread_key_t index_; 20 | void (*destructor_)(void*); 21 | 22 | public: 23 | detail(void (*destructor)(void*)) 24 | : destructor_(destructor) 25 | { 26 | pthread_key_create(&index_, destructor); 27 | } 28 | 29 | ~detail(void) 30 | { 31 | if (destructor_) 32 | { 33 | void* p = get(); 34 | if (p) destructor_(p); 35 | } 36 | pthread_key_delete(index_); 37 | } 38 | 39 | bool set(T* ptr) 40 | { 41 | return (pthread_setspecific(index_, (void*)ptr) == 0); 42 | } 43 | 44 | T* get(void) const 45 | { 46 | return (T*)pthread_getspecific(index_); 47 | } 48 | }; 49 | 50 | ////////////////////////////////////////////////////////////////////////// 51 | } NX_END 52 | ////////////////////////////////////////////////////////////////////////// 53 | -------------------------------------------------------------------------------- /nixycore/thread/detail/tls_ptr_win.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #include "nixycore/pattern/trackable.h" 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | NX_BEG namespace private_tls_ptr { 12 | ////////////////////////////////////////////////////////////////////////// 13 | 14 | #ifndef TLS_OUT_OF_INDEXES // wince does not define the TLS_OUT_OF_INDEXES constant 15 | #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) 16 | #endif/*TLS_OUT_OF_INDEXES*/ 17 | 18 | /* 19 | The list node for saving destructors 20 | */ 21 | 22 | class tls_data : public trackable 23 | { 24 | public: 25 | void (*destructor_)(void*); 26 | 27 | private: 28 | DWORD index_; 29 | 30 | public: 31 | tls_data(void (*destructor)(void*)) 32 | : destructor_(destructor) 33 | , index_(TlsAlloc()) 34 | {} 35 | 36 | ~tls_data(void) 37 | { 38 | if (destructor_) 39 | { 40 | void* p = get(); 41 | if (p) destructor_(p); 42 | } 43 | // free the tls index 44 | TlsFree(index_); 45 | } 46 | 47 | public: 48 | bool set(LPVOID ptr) 49 | { 50 | nx_assert(index_ != TLS_OUT_OF_INDEXES); 51 | return !!TlsSetValue(index_, ptr); 52 | } 53 | 54 | LPVOID get(void) const 55 | { 56 | nx_assert(index_ != TLS_OUT_OF_INDEXES); 57 | return TlsGetValue(index_); 58 | } 59 | }; 60 | 61 | /* 62 | Call destructor on thread exit 63 | */ 64 | 65 | inline void __cdecl onThreadExit(void) 66 | { 67 | tls_data* ite = tls_data::track(); 68 | while(ite) 69 | { 70 | if (ite->destructor_) 71 | { 72 | void* p = ite->get(); 73 | if (p) ite->destructor_(p); 74 | } 75 | ite = ite->next_; 76 | } 77 | } 78 | 79 | /* 80 | The detail of tls_ptr 81 | */ 82 | 83 | template 84 | class detail : tls_data 85 | { 86 | public: 87 | detail(void (*destructor)(void*)) 88 | : tls_data(destructor) 89 | {} 90 | 91 | public: 92 | bool set(T* ptr) 93 | { 94 | return tls_data::set((LPVOID)ptr); 95 | } 96 | 97 | T* get(void) const 98 | { 99 | return (T*)tls_data::get(); 100 | } 101 | }; 102 | 103 | ////////////////////////////////////////////////////////////////////////// 104 | } NX_END 105 | ////////////////////////////////////////////////////////////////////////// 106 | -------------------------------------------------------------------------------- /nixycore/thread/lock_guard.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/pattern/singleton.h" 11 | #include "nixycore/finalizer/scope_guard.h" 12 | #include "nixycore/delegate/bind.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/typemanip/typemanip.h" 16 | #include "nixycore/utility/utility.h" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | /* 23 | nx_lock_scope 24 | */ 25 | 26 | namespace private_lock_scope 27 | { 28 | template 29 | struct lock_fr 30 | { 31 | T& lc_; 32 | lock_fr(T& lc) : lc_(lc) { lc_.lock(); } 33 | void operator() (void) { lc_.unlock(); } 34 | }; 35 | } 36 | 37 | template 38 | inline private_lock_scope::lock_fr make_lock_fr(T& r) 39 | { 40 | return private_lock_scope::lock_fr(r); 41 | } 42 | 43 | #ifdef NX_SINGLE_THREAD 44 | 45 | #define nx_lock_scope(...) 46 | #define nx_lock_sole(Lock_) 47 | #define nx_lock_type(Lock_, ...) 48 | 49 | #else /*NX_SINGLE_THREAD*/ 50 | 51 | #define nx_lock_scope(...) \ 52 | nx_guard_scope(nx::make_lock_fr(__VA_ARGS__)) 53 | 54 | #define nx_lock_sole(Lock_) \ 55 | nx_lock_scope(nx::singleton()) 56 | 57 | #define nx_lock_type(Lock_, ...) \ 58 | nx_lock_scope(nx::singleton<__VA_ARGS__, Lock_>()) 59 | 60 | #endif/*NX_SINGLE_THREAD*/ 61 | 62 | ////////////////////////////////////////////////////////////////////////// 63 | NX_END 64 | ////////////////////////////////////////////////////////////////////////// 65 | -------------------------------------------------------------------------------- /nixycore/thread/mutex.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | #include "nixycore/utility/utility.h" 12 | 13 | #ifdef NX_SP_CXX11_MUTEX 14 | #include 15 | #endif 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | #ifndef NX_SP_CXX11_MUTEX 20 | #if defined(NX_OS_WIN) 21 | # include "detail/mutex_win.hxx" 22 | #elif defined(NX_OS_LINUX) 23 | # include "detail/mutex_linux.hxx" 24 | #endif 25 | #endif/*NX_SP_CXX11_MUTEX*/ 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | NX_BEG 29 | ////////////////////////////////////////////////////////////////////////// 30 | 31 | #ifdef NX_SP_CXX11_MUTEX 32 | namespace private_mutex 33 | { 34 | class detail : private std::mutex 35 | { 36 | typedef std::mutex base_t; 37 | 38 | public: 39 | typedef base_t::native_handle_type handle_t; 40 | handle_t operator*(void) { return base_t::native_handle(); } 41 | 42 | public: 43 | bool try_lock(void) 44 | { 45 | return base_t::try_lock(); 46 | } 47 | 48 | void lock(void) 49 | { 50 | base_t::lock(); 51 | } 52 | 53 | void unlock(void) 54 | { 55 | base_t::unlock(); 56 | } 57 | }; 58 | } 59 | #endif/*NX_SP_CXX11_MUTEX*/ 60 | 61 | class mutex 62 | : public private_mutex::detail, nx::noncopyable 63 | { 64 | public: 65 | typedef mutex lock_t; 66 | }; 67 | 68 | ////////////////////////////////////////////////////////////////////////// 69 | NX_END 70 | ////////////////////////////////////////////////////////////////////////// 71 | -------------------------------------------------------------------------------- /nixycore/thread/semaphore.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/thread/lock_guard.h" 11 | #include "nixycore/thread/mutex.h" 12 | #include "nixycore/thread/condition.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/utility/utility.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | class semaphore : nx::noncopyable 22 | { 23 | mutable mutex lock_; 24 | condition cond_; 25 | long counter_; 26 | 27 | public: 28 | semaphore(long init_count = 0) 29 | : cond_(lock_) 30 | , counter_(init_count) 31 | {} 32 | 33 | long count(void) const 34 | { 35 | nx_lock_scope(lock_); 36 | return counter_; 37 | } 38 | 39 | public: 40 | bool wait(int tm_ms = -1) 41 | { 42 | nx_lock_scope(lock_); 43 | while (counter_ < 1) 44 | { 45 | bool ret = cond_.wait(tm_ms); 46 | if (!ret) return false; 47 | } 48 | -- counter_; 49 | return true; 50 | } 51 | 52 | void post(long count = 1) 53 | { 54 | nx_lock_scope(lock_); 55 | counter_ += count; 56 | cond_.broadcast(); 57 | } 58 | }; 59 | 60 | ////////////////////////////////////////////////////////////////////////// 61 | NX_END 62 | ////////////////////////////////////////////////////////////////////////// 63 | -------------------------------------------------------------------------------- /nixycore/thread/spin_lock.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/thread/atomic.h" 11 | #include "nixycore/thread/thread_ops.h" 12 | 13 | #include "nixycore/bugfix/assert.h" 14 | 15 | #include "nixycore/general/general.h" 16 | #include "nixycore/utility/utility.h" 17 | 18 | #ifdef NX_SP_CXX11_ATOMIC 19 | #include // std::atomic ... 20 | #endif 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | NX_BEG 24 | ////////////////////////////////////////////////////////////////////////// 25 | 26 | class spin_lock : nx::noncopyable 27 | { 28 | protected: 29 | #ifdef NX_SP_CXX11_ATOMIC 30 | std::atomic_flag lc_; 31 | #else 32 | nx::atomic lc_; 33 | #endif 34 | 35 | public: 36 | typedef spin_lock lock_t; 37 | typedef lock_t handle_t; 38 | 39 | #ifdef NX_SP_CXX11_ATOMIC 40 | # if defined(NX_CC_MSVC) && (NX_CC_MSVC <= 1800) 41 | /* 42 | Atomic flag cannot be initialized in a constructor initializer. 43 | See: http://connect.microsoft.com/VisualStudio/feedback/details/800243/ 44 | */ 45 | spin_lock(void) 46 | { 47 | lc_.clear(std::memory_order_relaxed); 48 | } 49 | # else 50 | spin_lock(void) 51 | : lc_ ATOMIC_FLAG_INIT 52 | {} 53 | # endif 54 | ~spin_lock(void) 55 | { 56 | nx_assert(try_lock()); 57 | } 58 | #else 59 | ~spin_lock(void) 60 | { 61 | nx_assert(!lc_.load(memory_order::relaxed)); 62 | } 63 | #endif 64 | 65 | handle_t& operator*(void) { return (*this); } 66 | const handle_t& operator*(void) const { return (*this); } 67 | 68 | public: 69 | #ifdef NX_SP_CXX11_ATOMIC 70 | bool try_lock(void) 71 | { 72 | return !lc_.test_and_set(std::memory_order_acquire); 73 | } 74 | 75 | void lock(void) 76 | { 77 | for(unsigned k = 0; lc_.test_and_set(std::memory_order_acquire); ++k) 78 | thread_ops::pause(k); 79 | } 80 | 81 | void unlock(void) 82 | { 83 | lc_.clear(std::memory_order_release); 84 | } 85 | #else 86 | bool try_lock(void) 87 | { 88 | return !lc_.exchange(true, memory_order::acquire); 89 | } 90 | 91 | void lock(void) 92 | { 93 | for(unsigned k = 0; lc_.exchange(true, memory_order::acquire); ++k) 94 | thread_ops::pause(k); 95 | } 96 | 97 | void unlock(void) 98 | { 99 | lc_.store(false, memory_order::release); 100 | } 101 | #endif 102 | }; 103 | 104 | ////////////////////////////////////////////////////////////////////////// 105 | NX_END 106 | ////////////////////////////////////////////////////////////////////////// 107 | -------------------------------------------------------------------------------- /nixycore/thread/thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/thread/barrier.h" 13 | #include "nixycore/thread/interlocked.h" 14 | #include "nixycore/thread/atomic.h" 15 | #include "nixycore/thread/spin_lock.h" 16 | #include "nixycore/thread/lock_guard.h" 17 | #include "nixycore/thread/mutex.h" 18 | #include "nixycore/thread/condition.h" 19 | #include "nixycore/thread/semaphore.h" 20 | #include "nixycore/thread/waiter.h" 21 | #include "nixycore/thread/tls_ptr.h" 22 | #include "nixycore/thread/thread_ops.h" 23 | #include "nixycore/thread/thread_model.h" 24 | #include "nixycore/thread/thread_detail.h" 25 | #include "nixycore/thread/thread_pool.h" 26 | #include "nixycore/thread/future.h" 27 | #include "nixycore/thread/promise.h" 28 | #include "nixycore/thread/task.h" 29 | #include "nixycore/thread/async.h" 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | -------------------------------------------------------------------------------- /nixycore/thread/thread_model.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/thread/atomic.h" 11 | #include "nixycore/thread/spin_lock.h" 12 | #include "nixycore/thread/mutex.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/utility/utility.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | template 22 | struct thread_model : ModelT 23 | { 24 | template 25 | struct atomic { typedef nx::atomic type_t; }; 26 | }; 27 | 28 | /* 29 | non_lock, for single-thread model 30 | */ 31 | 32 | class non_lock : nx::noncopyable 33 | { 34 | public: 35 | typedef non_lock lock_t; 36 | typedef lock_t handle_t; 37 | handle_t& operator*(void) { return (*this); } 38 | const handle_t& operator*(void) const { return (*this); } 39 | 40 | public: 41 | bool try_lock(void) { return true; } 42 | void lock (void) {} 43 | void unlock (void) {} 44 | }; 45 | 46 | /* 47 | single-thread model 48 | */ 49 | 50 | struct single_thread_model 51 | { 52 | typedef use::interlocked_st interlocked; 53 | typedef non_lock lock_t; 54 | typedef non_lock mutex_t; 55 | }; 56 | 57 | /* 58 | multi-thread model 59 | */ 60 | 61 | struct multi_thread_model 62 | { 63 | typedef use::interlocked_mt interlocked; 64 | typedef spin_lock lock_t; 65 | typedef mutex mutex_t; 66 | }; 67 | 68 | /* 69 | default thread model 70 | */ 71 | 72 | namespace use 73 | { 74 | typedef thread_model thread_single; 75 | typedef thread_model thread_multi; 76 | } 77 | 78 | #ifndef NX_DEFAULT_THREAD_MODEL 79 | # ifdef NX_SINGLE_THREAD 80 | # define NX_DEFAULT_THREAD_MODEL nx::use::thread_single 81 | # else 82 | # define NX_DEFAULT_THREAD_MODEL nx::use::thread_multi 83 | # endif 84 | #endif 85 | 86 | ////////////////////////////////////////////////////////////////////////// 87 | NX_END 88 | ////////////////////////////////////////////////////////////////////////// 89 | -------------------------------------------------------------------------------- /nixycore/thread/thread_ops.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/bugfix/assert.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | #ifdef NX_SP_CXX11_THREAD 17 | # include "detail/thread_ops_std.hxx" 18 | #elif defined(NX_OS_WIN) 19 | # include "detail/thread_ops_win.hxx" 20 | #elif defined(NX_OS_LINUX) 21 | # include "detail/thread_ops_linux.hxx" 22 | #endif 23 | 24 | ////////////////////////////////////////////////////////////////////////// 25 | 26 | #if defined(NX_CC_MSVC) && defined(NX_PC_X86) 27 | 28 | extern "C" void _mm_pause(void); 29 | #pragma intrinsic(_mm_pause) 30 | #define NX_THREADOPS_PAUSE() _mm_pause() 31 | 32 | #elif defined(NX_CC_GNUC) && defined(NX_PC_X86) 33 | 34 | #define NX_THREADOPS_PAUSE() __asm__ __volatile__ ("pause") 35 | 36 | #endif/*defined(NX_CC_) && defined(NX_PC_)*/ 37 | 38 | ////////////////////////////////////////////////////////////////////////// 39 | NX_BEG namespace thread_ops { 40 | ////////////////////////////////////////////////////////////////////////// 41 | 42 | inline void pause(unsigned k = 4) 43 | { 44 | if (k < 4) {} 45 | #ifdef NX_THREADOPS_PAUSE 46 | else 47 | if (k < 16) { NX_THREADOPS_PAUSE(); } 48 | #endif/*NX_THREADOPS_PAUSE*/ 49 | else 50 | if (k < 32) { yield(); } 51 | else 52 | { 53 | sleep(1); 54 | } 55 | } 56 | 57 | ////////////////////////////////////////////////////////////////////////// 58 | } NX_END 59 | ////////////////////////////////////////////////////////////////////////// 60 | -------------------------------------------------------------------------------- /nixycore/thread/tls_ptr.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | #include "nixycore/typemanip/typemanip.h" 12 | #include "nixycore/utility/utility.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | #if defined(NX_OS_WIN) 17 | # include "detail/tls_ptr_win.hxx" 18 | #elif defined(NX_OS_LINUX) 19 | # include "detail/tls_ptr_linux.hxx" 20 | #endif 21 | 22 | ////////////////////////////////////////////////////////////////////////// 23 | NX_BEG 24 | ////////////////////////////////////////////////////////////////////////// 25 | 26 | template 27 | class tls_ptr 28 | : public private_tls_ptr::detail 29 | , public safe_bool > 30 | , nx::noncopyable 31 | { 32 | typedef private_tls_ptr::detail base_t; 33 | 34 | public: 35 | tls_ptr(void (*destructor)(void*) = nx::nulptr) 36 | : base_t(destructor) 37 | {} 38 | 39 | bool check_safe_bool(void) const 40 | { return !!base_t::get(); } 41 | 42 | tls_ptr& operator=(T* ptr) 43 | { 44 | base_t::set(ptr); 45 | return (*this); 46 | } 47 | 48 | operator T*(void) const 49 | { return base_t::get(); } 50 | 51 | T* operator->(void) const { return base_t::get(); } 52 | T& operator* (void) const { return *base_t::get(); } 53 | }; 54 | 55 | ////////////////////////////////////////////////////////////////////////// 56 | NX_END 57 | ////////////////////////////////////////////////////////////////////////// 58 | -------------------------------------------------------------------------------- /nixycore/thread/waiter.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/thread/lock_guard.h" 11 | #include "nixycore/thread/mutex.h" 12 | #include "nixycore/thread/condition.h" 13 | 14 | #include "nixycore/general/general.h" 15 | #include "nixycore/utility/utility.h" 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | NX_BEG 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | /* 22 | waiter status enum 23 | */ 24 | 25 | enum waiter_status_t 26 | { 27 | waiter_Resting, 28 | waiter_Excited, 29 | waiter_AutoRet 30 | }; 31 | 32 | /* 33 | wait for something is happen 34 | */ 35 | 36 | class waiter : nx::noncopyable 37 | { 38 | mutable mutex lock_; 39 | condition cond_; 40 | 41 | waiter_status_t signaled_; 42 | 43 | public: 44 | waiter(void) 45 | : cond_(lock_) 46 | , signaled_(waiter_Resting) 47 | {} 48 | 49 | waiter_status_t status(void) const 50 | { 51 | nx_lock_scope(lock_); 52 | return signaled_; 53 | } 54 | 55 | bool is_signaled(void) const 56 | { 57 | nx_lock_scope(lock_); 58 | return (signaled_ != waiter_Resting); 59 | } 60 | 61 | void reset(void) 62 | { 63 | nx_lock_scope(lock_); 64 | signaled_ = waiter_Resting; 65 | } 66 | 67 | public: 68 | bool wait(int tm_ms = -1) 69 | { 70 | nx_lock_scope(lock_); 71 | while (signaled_ == waiter_Resting) 72 | { 73 | bool ret = cond_.wait(tm_ms); 74 | if (!ret) return false; 75 | } 76 | if (signaled_ == waiter_AutoRet) 77 | signaled_ = waiter_Resting; 78 | return true; 79 | } 80 | 81 | void notify(void) 82 | { 83 | nx_lock_scope(lock_); 84 | signaled_ = waiter_AutoRet; 85 | cond_.broadcast(); 86 | } 87 | 88 | void broadcast(void) 89 | { 90 | nx_lock_scope(lock_); 91 | signaled_ = waiter_Excited; 92 | cond_.broadcast(); 93 | } 94 | }; 95 | 96 | ////////////////////////////////////////////////////////////////////////// 97 | NX_END 98 | ////////////////////////////////////////////////////////////////////////// 99 | -------------------------------------------------------------------------------- /nixycore/time/stopwatch.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/time/tickcount.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | NX_BEG 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | namespace use 19 | { 20 | struct clock_std // Standard clock policy 21 | { 22 | typedef ulong clock_t; 23 | clock_t clock(void) { return tickcount(); } 24 | static double second(const clock_t& cl) { return double(cl) / double(1000); } 25 | }; 26 | } 27 | 28 | ////////////////////////////////////////////////////////////////////////// 29 | 30 | #ifndef NX_DEFAULT_CLOCK 31 | #define NX_DEFAULT_CLOCK nx::use::clock_std 32 | #endif 33 | 34 | template 35 | class stopwatch : public ModelT 36 | { 37 | public: 38 | typedef typename ModelT::clock_t clock_t; 39 | 40 | protected: 41 | clock_t start_time_; 42 | clock_t pause_elap_; 43 | bool is_stopped_; 44 | 45 | public: 46 | stopwatch(bool start_watch = false) 47 | : ModelT() 48 | , start_time_(0) 49 | , pause_elap_(0) 50 | , is_stopped_(true) 51 | { 52 | if (start_watch) start(); 53 | } 54 | 55 | public: 56 | bool check(void) 57 | { 58 | return (start_time_ <= ModelT::clock()); 59 | } 60 | 61 | double value(void) 62 | { 63 | return ModelT::second(elapsed()); 64 | } 65 | 66 | clock_t elapsed(void) 67 | { 68 | if (isStopped()) 69 | return 0; 70 | else if (isPaused()) 71 | return pause_elap_; 72 | else 73 | { 74 | clock_t now = ModelT::clock(); 75 | if (start_time_ > now) 76 | { 77 | stop(); 78 | return 0; 79 | } 80 | return now - start_time_; 81 | } 82 | } 83 | 84 | void start(void) 85 | { 86 | elapsed(); // if (start_time_ > now), stopwatch will restart 87 | start_time_ = ModelT::clock(); 88 | start_time_ -= pause_elap_; 89 | pause_elap_ = 0; 90 | is_stopped_ = false; 91 | } 92 | 93 | void pause(void) 94 | { 95 | pause_elap_ = elapsed(); 96 | } 97 | 98 | void stop(void) 99 | { 100 | start_time_ = 0; 101 | pause_elap_ = 0; 102 | is_stopped_ = true; 103 | } 104 | 105 | bool isStopped(void) 106 | { 107 | return is_stopped_; 108 | } 109 | 110 | bool isPaused(void) 111 | { 112 | return (pause_elap_ != 0); 113 | } 114 | }; 115 | 116 | ////////////////////////////////////////////////////////////////////////// 117 | NX_END 118 | ////////////////////////////////////////////////////////////////////////// 119 | -------------------------------------------------------------------------------- /nixycore/time/tickcount.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | #if defined(NX_OS_LINUX) 13 | #include 14 | #endif 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | inline ulong tickcount(void) 21 | { 22 | #if defined(NX_OS_WIN) 23 | return static_cast(GetTickCount()); 24 | #elif defined(NX_OS_LINUX) 25 | /* need -lrt */ 26 | struct timespec tv; 27 | clock_gettime(CLOCK_MONOTONIC, &tv); 28 | return (tv.tv_sec * 1000) + (tv.tv_nsec / 1000000); 29 | #endif 30 | } 31 | 32 | ////////////////////////////////////////////////////////////////////////// 33 | NX_END 34 | ////////////////////////////////////////////////////////////////////////// 35 | -------------------------------------------------------------------------------- /nixycore/time/time.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/time/tickcount.h" 13 | #include "nixycore/time/stopwatch.h" 14 | 15 | ////////////////////////////////////////////////////////////////////////// 16 | -------------------------------------------------------------------------------- /nixycore/typemanip/detail/typeof_msvc.hxx: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | // std::type_info 9 | #include 10 | 11 | ////////////////////////////////////////////////////////////////////////// 12 | NX_BEG namespace private_typeof { 13 | ////////////////////////////////////////////////////////////////////////// 14 | 15 | /* 16 | Get a Type from a std::type_info 17 | */ 18 | 19 | template 20 | struct TypeID {}; 21 | 22 | #define NX_TYPE_ID_(...) nx::private_typeof::TypeID 23 | 24 | /* 25 | Extract a type from TypeID 26 | */ 27 | 28 | template 29 | struct type_extractor; 30 | 31 | template 32 | struct type_extractor 33 | { 34 | template 35 | struct id2type { typedef nx::null_t type_t; }; 36 | }; 37 | 38 | template 39 | struct type_extractor : type_extractor 40 | { 41 | template <> 42 | struct id2type { typedef T type_t; }; 43 | }; 44 | 45 | /* 46 | Register a type 47 | */ 48 | 49 | template 50 | struct type_register : type_extractor 51 | { 52 | typedef typename id2type::type_t type_t; 53 | }; 54 | 55 | /* 56 | Encode a expression 57 | */ 58 | 59 | template 60 | struct type_encoder 61 | { 62 | typedef T* enc_type; 63 | typedef type_register reg_type; 64 | typedef typename reg_type::type_t type_t; 65 | }; 66 | 67 | template 68 | typename type_encoder::type_t encode_type(const T&); 69 | 70 | /* 71 | Decode a type 72 | */ 73 | 74 | template 75 | struct type_decoder 76 | { 77 | typedef typename type_extractor::template id2type::type_t enc_type; 78 | typedef typename rm_pointer::type_t type_t; 79 | }; 80 | 81 | #define NX_TYPEOF_(...) \ 82 | nx::private_typeof::type_decoder::type_t 83 | 84 | ////////////////////////////////////////////////////////////////////////// 85 | } NX_END 86 | ////////////////////////////////////////////////////////////////////////// 87 | -------------------------------------------------------------------------------- /nixycore/typemanip/typeconcept.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typedefs.h" 11 | #include "nixycore/typemanip/typetools.h" 12 | 13 | #include "nixycore/general/general.h" 14 | #include "nixycore/preprocessor/preprocessor.h" 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | /* 21 | Check has member type 22 | */ 23 | 24 | #define NX_HAS_MEMBERTYPE_(name, InnerType) \ 25 | template \ 26 | struct has_##name \ 27 | { \ 28 | template \ 29 | static nx::yes_t check(typename U::InnerType*); \ 30 | template \ 31 | static nx::not_t check(...); \ 32 | NX_STATIC_VALUE( bool, nx_judge(check(0)) ); \ 33 | }; 34 | 35 | /* 36 | Check has member function 37 | */ 38 | 39 | #define NX_HAS_MEMBERFUNC_(name, InnerFunc, FuncTypePtr) \ 40 | template \ 41 | struct has_##name \ 42 | { \ 43 | template \ 44 | struct FuncTest; \ 45 | template \ 46 | static nx::yes_t check(FuncTest*); \ 47 | template \ 48 | static nx::not_t check(...); \ 49 | NX_STATIC_VALUE( bool, nx_judge(check(0)) ); \ 50 | }; 51 | 52 | /* 53 | Define a concept for member type or function 54 | */ 55 | 56 | #define NX_CONCEPT(...) \ 57 | NX_PP_JOIN(NX_, NX_PP_LESS(2, NX_PP_COUNT(__VA_ARGS__), HAS_MEMBERFUNC_, HAS_MEMBERTYPE_))(__VA_ARGS__) 58 | 59 | ////////////////////////////////////////////////////////////////////////// 60 | NX_END 61 | ////////////////////////////////////////////////////////////////////////// 62 | -------------------------------------------------------------------------------- /nixycore/typemanip/typedecay.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typetraits.h" 11 | 12 | #include "nixycore/utility/forward.h" 13 | #include "nixycore/utility/noncopyable.h" // for is_copyable 14 | 15 | #include "nixycore/general/general.h" 16 | 17 | #ifdef NX_SP_CXX11_TYPE_TRAITS 18 | #include 19 | #endif 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | NX_BEG 23 | ////////////////////////////////////////////////////////////////////////// 24 | 25 | /* 26 | Obtains the decay type of T 27 | */ 28 | 29 | #ifdef NX_SP_CXX11_TYPE_TRAITS 30 | template 31 | struct decay 32 | { 33 | private: 34 | typedef typename extract::type_t extract_type; 35 | 36 | public: 37 | typedef typename std::decay::type type_t; 38 | }; 39 | #else /*NX_SP_CXX11_TYPE_TRAITS*/ 40 | template 41 | struct decay 42 | { 43 | private: 44 | typedef typename extract::type_t extract_type; 45 | 46 | public: 47 | typedef typename select_if::value, 48 | typename rm_array::type_t*, 49 | typename select_if::value && !is_pointer::value, 50 | extract_type*, 51 | extract_type 52 | >::type_t 53 | >::type_t type_t; 54 | }; 55 | #endif/*NX_SP_CXX11_TYPE_TRAITS*/ 56 | 57 | /* 58 | The type_t is enabled as T is the same type as U. 59 | */ 60 | 61 | template 62 | struct enable_if_same 63 | : nx::enable_if::type_t, 65 | typename nx::decay::type_t 66 | >::value, TypeT> 67 | {}; 68 | 69 | /* 70 | The type_t is enabled as T is the different type as U. 71 | */ 72 | 73 | template 74 | struct enable_if_diff 75 | : nx::enable_if::type_t, 77 | typename nx::decay::type_t 78 | >::value, TypeT> 79 | {}; 80 | 81 | /* 82 | detect copyable 83 | */ 84 | 85 | #if defined(NX_SP_CXX11_TYPE_TRAITS) && \ 86 | /* 87 | std::is_copy_constructible doesn't work correctly. 88 | See: http://connect.microsoft.com/VisualStudio/feedback/details/799732/ 89 | http://connect.microsoft.com/VisualStudio/feedback/details/800328/ 90 | http://connect.microsoft.com/VisualStudio/feedback/details/802032/ 91 | */ \ 92 | !(defined(NX_CC_MSVC) && (NX_CC_MSVC <= 1800)) && \ 93 | /* 94 | 4.7 and later support -std=c++11 and -std=gnu++11 as well. 95 | See: http://gcc.gnu.org/projects/cxx0x.html 96 | */ \ 97 | (!defined(NX_CC_GCC) || NX_CHECK_GNUC(4, 7, 0)) 98 | template 99 | struct is_copyable 100 | : type_if::value> 101 | {}; 102 | #else /*NX_SP_CXX11_TYPE_TRAITS*/ 103 | template 104 | struct is_copyable 105 | : type_if::type_t>::value> 106 | {}; 107 | #endif/*NX_SP_CXX11_TYPE_TRAITS*/ 108 | 109 | ////////////////////////////////////////////////////////////////////////// 110 | NX_END 111 | ////////////////////////////////////////////////////////////////////////// 112 | -------------------------------------------------------------------------------- /nixycore/typemanip/typedefs.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/preprocessor/pp_macros.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | #ifdef NX_SP_CXX11_NULLPTR 15 | #include // std::nullptr_t 16 | #endif 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | /* 23 | null_t 24 | */ 25 | 26 | struct null_t; 27 | 28 | /* 29 | nulptr_t && nulptr 30 | */ 31 | 32 | #ifdef NX_SP_CXX11_NULLPTR 33 | typedef std::nullptr_t nulptr_t; 34 | #else /*NX_SP_CXX11_NULLPTR*/ 35 | class nulptr_t 36 | { 37 | public: 38 | template 39 | inline operator T*() const 40 | { return 0; } 41 | 42 | template 43 | inline operator T C::*() const 44 | { return 0; } 45 | 46 | private: 47 | void operator&() const; 48 | }; 49 | #endif/*NX_SP_CXX11_NULLPTR*/ 50 | 51 | static const nulptr_t nulptr = nulptr_t(); 52 | 53 | /* 54 | empty_t && none_t && none 55 | */ 56 | 57 | struct empty_t {}; 58 | typedef int empty_t::*none_t; 59 | static const none_t none = nx::nulptr; 60 | 61 | /* 62 | true_t && false_t 63 | */ 64 | 65 | #define NX_STATIC_PROPERTY(T, name, ...) \ 66 | static const T name = (__VA_ARGS__) 67 | 68 | #define NX_STATIC_VALUE(T, ...) NX_STATIC_PROPERTY(T, value, __VA_ARGS__) 69 | 70 | template 71 | struct ValueDef { NX_STATIC_VALUE(T, Val_); }; 72 | 73 | typedef ValueDef true_t; 74 | typedef ValueDef false_t; 75 | 76 | /* 77 | yes_t && not_t 78 | */ 79 | 80 | typedef char not_t; 81 | typedef struct { not_t dummy_[2]; } yes_t; 82 | 83 | #ifndef nx_judge 84 | #define nx_judge(...) NX_PP_VA(nx::ValueDef::value) 85 | #endif 86 | 87 | ////////////////////////////////////////////////////////////////////////// 88 | NX_END 89 | ////////////////////////////////////////////////////////////////////////// 90 | -------------------------------------------------------------------------------- /nixycore/typemanip/typemanip.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/typemanip/typedefs.h" 13 | #include "nixycore/typemanip/typetools.h" 14 | #include "nixycore/typemanip/typerelation.h" 15 | #include "nixycore/typemanip/typelist.h" 16 | #include "nixycore/typemanip/typeconcept.h" 17 | #include "nixycore/typemanip/typequalifier.h" 18 | #include "nixycore/typemanip/typebehavior.h" 19 | #include "nixycore/typemanip/typedetect.h" 20 | #include "nixycore/typemanip/typetraits.h" 21 | #include "nixycore/typemanip/typedecay.h" 22 | #include "nixycore/typemanip/typeof.h" 23 | 24 | ////////////////////////////////////////////////////////////////////////// 25 | -------------------------------------------------------------------------------- /nixycore/typemanip/typeof.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typedefs.h" 11 | #include "nixycore/typemanip/typedetect.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | ////////////////////////////////////////////////////////////////////////// 16 | 17 | #if defined(NX_CC_GNUC) 18 | # define NX_TYPEOF_(...) __typeof(__VA_ARGS__) 19 | #elif defined(NX_CC_MSVC) 20 | # include "detail/typeof_msvc.hxx" 21 | #else 22 | # define NX_TYPEOF_(...) nx::null_t 23 | #endif 24 | 25 | #ifndef nx_typeof 26 | #define nx_typeof(...) NX_TYPEOF_(__VA_ARGS__) 27 | #endif 28 | 29 | #ifndef nx_auto 30 | #ifdef NX_SP_CXX11_AUTO 31 | #define nx_auto(name, ...) auto name((__VA_ARGS__)) 32 | #else /*NX_SP_CXX11_AUTO*/ 33 | #define nx_auto(name, ...) nx_typeof(__VA_ARGS__) name((__VA_ARGS__)) 34 | #endif/*NX_SP_CXX11_AUTO*/ 35 | #endif 36 | 37 | ////////////////////////////////////////////////////////////////////////// 38 | -------------------------------------------------------------------------------- /nixycore/typemanip/typerelation.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Modified from The Loki Library 6 | Modified by : mutouyun (http://orzz.org) 7 | 8 | Copyright (c) 2001 by Andrei Alexandrescu 9 | */ 10 | 11 | #pragma once 12 | 13 | #include "nixycore/typemanip/typedefs.h" 14 | #include "nixycore/typemanip/typetools.h" 15 | #include "nixycore/typemanip/typebehavior.h" 16 | 17 | #include "nixycore/general/general.h" 18 | 19 | ////////////////////////////////////////////////////////////////////////// 20 | NX_BEG 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | /* 24 | Check the same type 25 | */ 26 | 27 | template 28 | struct is_same 29 | : type_if 30 | {}; 31 | 32 | template 33 | struct is_same 34 | : type_if 35 | {}; 36 | 37 | /* 38 | Check the conversion of two classes 39 | */ 40 | 41 | template 42 | struct is_convertible 43 | { 44 | private: 45 | static yes_t check(U); 46 | static not_t check(...); 47 | 48 | public: 49 | NX_STATIC_VALUE( bool, nx_judge( check(T()) ) ); 50 | }; 51 | 52 | template 53 | struct is_convertible : 54 | type_if 55 | {}; 56 | 57 | /* 58 | Check the Super-Sub inheritance of two classes 59 | */ 60 | 61 | namespace private_is_supersub 62 | { 63 | template 64 | struct detail : 65 | type_if::value && 66 | !is_same::value && 67 | !is_same::value> 68 | {}; 69 | 70 | template <> 71 | struct detail : 72 | type_if 73 | {}; 74 | 75 | template 76 | struct detail : 77 | type_if 78 | {}; 79 | 80 | template 81 | struct detail : 82 | type_if 83 | {}; 84 | } 85 | 86 | template 87 | struct is_supersub 88 | : private_is_supersub::detail 89 | ::type_t>::type_t, 90 | typename rm_reference::type_t>::type_t> 91 | {}; 92 | 93 | ////////////////////////////////////////////////////////////////////////// 94 | NX_END 95 | ////////////////////////////////////////////////////////////////////////// 96 | -------------------------------------------------------------------------------- /nixycore/typemanip/typetools.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typedefs.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | NX_BEG 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | /* 19 | Type Wrappers 20 | */ 21 | 22 | template 23 | struct type_wrap 24 | { 25 | typedef T type_t; 26 | }; 27 | 28 | template 29 | struct type_int 30 | { 31 | NX_STATIC_VALUE(int, N); 32 | }; 33 | 34 | /* 35 | For judge bool value 36 | */ 37 | 38 | template 39 | struct type_if; 40 | 41 | template <> 42 | struct type_if : true_t 43 | { 44 | typedef true_t type_t; 45 | }; 46 | 47 | template <> 48 | struct type_if : false_t 49 | { 50 | typedef false_t type_t; 51 | }; 52 | 53 | /* 54 | For select a type 55 | */ 56 | 57 | template 58 | struct select_if 59 | { 60 | typedef T type_t; 61 | }; 62 | 63 | template 64 | struct select_if 65 | { 66 | typedef U type_t; 67 | }; 68 | 69 | /* 70 | Enable if (bool == true) 71 | */ 72 | 73 | template 74 | struct enable_if 75 | { 76 | // Nothing 77 | }; 78 | 79 | template 80 | struct enable_if 81 | { 82 | typedef T type_t; 83 | }; 84 | 85 | /* 86 | Shield to protect the parameters are not destroyed by macro expansion 87 | 88 | #define MACRO_VALUE(x) x::value 89 | --> 90 | MACRO_VALUE(TemplateClass) // Error! 91 | MACRO_VALUE(NX_SHIELD(TemplateClass)) // OK~ 92 | */ 93 | 94 | template struct strip { typedef T type_t; }; 95 | template struct strip { typedef T type_t; }; 96 | 97 | #define NX_SHIELD(...) nx::strip::type_t 98 | 99 | ////////////////////////////////////////////////////////////////////////// 100 | NX_END 101 | ////////////////////////////////////////////////////////////////////////// 102 | -------------------------------------------------------------------------------- /nixycore/typemanip/typetraits.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typedetect.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | NX_BEG 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | /* 19 | Some functional features 20 | */ 21 | 22 | template 23 | struct rm_cv_ref 24 | { 25 | typedef typename rm_reference< 26 | typename rm_cv::type_t 27 | >::type_t type_t; 28 | }; 29 | 30 | template 31 | struct traits 32 | { 33 | typedef typename rm_cv_ref::type_t type_t; 34 | 35 | typedef type_t* point_t; 36 | typedef type_t& refer_t; 37 | typedef const type_t* cpoint_t; 38 | typedef const type_t& crefer_t; 39 | 40 | typedef typename select_if< 41 | is_scalar::value || is_reference::value, 42 | T, 43 | typename rm_reference::type_t& 44 | >::type_t forward_t; 45 | }; 46 | 47 | ////////////////////////////////////////////////////////////////////////// 48 | NX_END 49 | ////////////////////////////////////////////////////////////////////////// 50 | -------------------------------------------------------------------------------- /nixycore/utility/addressof.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | template 17 | inline T * addressof(T & v) 18 | { 19 | return reinterpret_cast(& const_cast(reinterpret_cast(v))); 20 | } 21 | 22 | template 23 | inline T * addressof(T * v) 24 | { 25 | return v; 26 | } 27 | 28 | ////////////////////////////////////////////////////////////////////////// 29 | NX_END 30 | ////////////////////////////////////////////////////////////////////////// 31 | -------------------------------------------------------------------------------- /nixycore/utility/alignof.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | #ifdef NX_SP_CXX11_ALIGNMENT 13 | #include // std::aligned_storage 14 | #endif 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | NX_BEG 18 | ////////////////////////////////////////////////////////////////////////// 19 | 20 | #ifdef NX_SP_CXX11_ALIGNMENT 21 | 22 | #define nx_alignof(...) alignof(__VA_ARGS__) 23 | #define nx_alignas(...) alignas(__VA_ARGS__) 24 | 25 | template 26 | struct aligned_storage 27 | { 28 | typedef typename std::aligned_storage::type type_t; 29 | }; 30 | 31 | #else /*NX_SP_CXX11_ALIGNMENT*/ 32 | 33 | #if defined(NX_CC_MSVC) 34 | 35 | #define nx_alignof(...) __alignof(__VA_ARGS__) 36 | #define nx_alignas(...) __declspec(align(__VA_ARGS__)) 37 | 38 | template 39 | struct aligned_t; 40 | 41 | /* 42 | __declspec(align(#)) 43 | Valid entries are integer powers of two from 1 to 8192 (bytes). 44 | See: http://msdn.microsoft.com/en-us/library/83ythb65.aspx 45 | */ 46 | template <> struct nx_alignas(1) aligned_t<1> {}; 47 | template <> struct nx_alignas(2) aligned_t<2> {}; 48 | template <> struct nx_alignas(4) aligned_t<4> {}; 49 | template <> struct nx_alignas(8) aligned_t<8> {}; 50 | template <> struct nx_alignas(16) aligned_t<16> {}; 51 | template <> struct nx_alignas(32) aligned_t<32> {}; 52 | template <> struct nx_alignas(64) aligned_t<64> {}; 53 | template <> struct nx_alignas(128) aligned_t<128> {}; 54 | template <> struct nx_alignas(256) aligned_t<256> {}; 55 | template <> struct nx_alignas(512) aligned_t<512> {}; 56 | template <> struct nx_alignas(1024) aligned_t<1024> {}; 57 | template <> struct nx_alignas(2048) aligned_t<2048> {}; 58 | template <> struct nx_alignas(4096) aligned_t<4096> {}; 59 | template <> struct nx_alignas(8192) aligned_t<8192> {}; 60 | 61 | #elif defined(NX_CC_GNUC) 62 | 63 | #define nx_alignof(...) __alignof__(__VA_ARGS__) 64 | #define nx_alignas(...) __attribute__((__aligned__((__VA_ARGS__)))) 65 | 66 | template 67 | struct nx_alignas(AlignN) aligned_t {}; 68 | 69 | #else /*defined(NX_CC_)*/ 70 | 71 | /* It's just a demo, may couldn't work */ 72 | 73 | #define NX_OFFSETOF_(s, m) (size_t)&(((s*)NULL)->m) 74 | #define nx_alignof(...) (NX_OFFSETOF_(struct { char c_; __VA_ARGS__ t_; }, t_)) 75 | 76 | template 77 | struct aligned_t; 78 | 79 | template <> struct aligned_t<1> { nx::uint8 dunmmy_; }; 80 | template <> struct aligned_t<2> { nx::uint16 dunmmy_; }; 81 | template <> struct aligned_t<4> { nx::uint32 dunmmy_; }; 82 | template <> struct aligned_t<8> { nx::uint64 dunmmy_; }; 83 | 84 | #endif/*defined(NX_CC_)*/ 85 | 86 | template 87 | struct aligned_storage 88 | { 89 | typedef union 90 | { 91 | nx::uchar data_[LenN]; 92 | nx::aligned_t align_; 93 | } type_t; 94 | }; 95 | 96 | #endif/*NX_SP_CXX11_ALIGNMENT*/ 97 | 98 | template 99 | struct aligned 100 | { 101 | typedef typename aligned_storage::type_t storage_t; 102 | }; 103 | 104 | ////////////////////////////////////////////////////////////////////////// 105 | NX_END 106 | ////////////////////////////////////////////////////////////////////////// 107 | -------------------------------------------------------------------------------- /nixycore/utility/countof.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | namespace private_countof 17 | { 18 | template 19 | nx::byte(* detail(const T(&)[N]) )[N]; 20 | } 21 | 22 | #define nx_countof(arr) sizeof(*nx::private_countof::detail(arr)) 23 | 24 | ////////////////////////////////////////////////////////////////////////// 25 | NX_END 26 | ////////////////////////////////////////////////////////////////////////// 27 | -------------------------------------------------------------------------------- /nixycore/utility/final.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | namespace private_final 17 | { 18 | template 19 | class detail 20 | { 21 | protected: 22 | detail(void) {} 23 | }; 24 | } 25 | 26 | #define nx_final(...) private virtual nx::private_final::detail<__VA_ARGS__ > 27 | 28 | ////////////////////////////////////////////////////////////////////////// 29 | NX_END 30 | ////////////////////////////////////////////////////////////////////////// 31 | -------------------------------------------------------------------------------- /nixycore/utility/initialize.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typeconcept.h" 11 | #include "nixycore/typemanip/typedetect.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | // placement new 16 | #include 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | NX_BEG 20 | ////////////////////////////////////////////////////////////////////////// 21 | 22 | NX_CONCEPT(initialize, initialize, void(C::*)(void)) 23 | 24 | template 25 | inline typename enable_if::value && 26 | !is_pointer::value && 27 | is_numeric::value 28 | >::type_t initialize(T& d) 29 | { 30 | d = 0; 31 | } 32 | 33 | template 34 | inline typename enable_if::value && 35 | !is_pointer::value && 36 | !is_numeric::value && 37 | is_pod::value 38 | >::type_t initialize(T& d) 39 | { 40 | memset(&d, 0, sizeof(d)); 41 | } 42 | 43 | template 44 | inline typename enable_if::value && 45 | !is_pointer::value && 46 | !is_numeric::value && 47 | !is_pod::value 48 | >::type_t initialize(T& d) 49 | { 50 | ::new (&d) T; 51 | } 52 | 53 | template 54 | inline typename enable_if::value 55 | >::type_t initialize(T& d) 56 | { 57 | d.initialize(); 58 | } 59 | 60 | template 61 | inline void initialize(T(& d)[N]) 62 | { 63 | for(size_t i = 0; i < N; ++i) 64 | initialize(d[i]); 65 | } 66 | 67 | template 68 | inline typename enable_if::value, 69 | T>::type_t initialize(T d) 70 | { 71 | initialize(*d); 72 | return d; 73 | } 74 | 75 | ////////////////////////////////////////////////////////////////////////// 76 | NX_END 77 | ////////////////////////////////////////////////////////////////////////// 78 | -------------------------------------------------------------------------------- /nixycore/utility/limit_of.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typedefs.h" 11 | #include "nixycore/typemanip/typedetect.h" 12 | 13 | #include "nixycore/general/general.h" 14 | 15 | ////////////////////////////////////////////////////////////////////////// 16 | NX_BEG 17 | ////////////////////////////////////////////////////////////////////////// 18 | 19 | template ::value 20 | , bool = is_signed::value> 21 | struct limit_of; 22 | 23 | template 24 | struct limit_of 25 | { 26 | NX_STATIC_PROPERTY(T, lower, 0); 27 | NX_STATIC_PROPERTY(T, upper, (T)~0); 28 | }; 29 | 30 | template 31 | struct limit_of 32 | { 33 | NX_STATIC_PROPERTY(T, lower, ((T)1) << ((sizeof(T) * CHAR_BIT) - 1) ); 34 | NX_STATIC_PROPERTY(T, upper, ~lower); 35 | }; 36 | 37 | template <> 38 | struct limit_of 39 | { 40 | NX_STATIC_PROPERTY(bool, lower, false); 41 | NX_STATIC_PROPERTY(bool, upper, true); 42 | }; 43 | 44 | ////////////////////////////////////////////////////////////////////////// 45 | NX_END 46 | ////////////////////////////////////////////////////////////////////////// 47 | -------------------------------------------------------------------------------- /nixycore/utility/max_min.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | #include "nixycore/preprocessor/preprocessor.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | NX_BEG 15 | ////////////////////////////////////////////////////////////////////////// 16 | 17 | /* 18 | Get the maximum of variables 19 | */ 20 | 21 | #define NX_MAX(x, y) (((x) > (y)) ? (x) : (y)) 22 | 23 | template 24 | inline const T& maxof(const T& x, const T& y) 25 | { 26 | return NX_MAX(x, y); 27 | } 28 | 29 | #ifndef nx_max 30 | #define nx_max(...) NX_PP_VA(NX_PP_ORDER(nx::maxof, __VA_ARGS__)) 31 | #endif 32 | 33 | /* 34 | Get the minimum of variables 35 | */ 36 | 37 | #define NX_MIN(x, y) (((x) < (y)) ? (x) : (y)) 38 | 39 | template 40 | inline const T& minof(const T& x, const T& y) 41 | { 42 | return NX_MIN(x, y); 43 | } 44 | 45 | #ifndef nx_min 46 | #define nx_min(...) NX_PP_VA(NX_PP_ORDER(nx::minof, __VA_ARGS__)) 47 | #endif 48 | 49 | ////////////////////////////////////////////////////////////////////////// 50 | NX_END 51 | ////////////////////////////////////////////////////////////////////////// 52 | -------------------------------------------------------------------------------- /nixycore/utility/noncopyable.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/general/general.h" 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | NX_BEG 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | class noncopyable 17 | { 18 | protected: 19 | noncopyable(void) {} 20 | ~noncopyable(void) {} 21 | 22 | private: 23 | noncopyable(const noncopyable&); 24 | noncopyable& operator=(const noncopyable&); 25 | }; 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | NX_END 29 | ////////////////////////////////////////////////////////////////////////// 30 | -------------------------------------------------------------------------------- /nixycore/utility/safe_bool.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Modified from http://en.wikibooks.org/wiki/More_C++_Idioms/Safe_bool 6 | Modified by : mutouyun (http://orzz.org) 7 | */ 8 | 9 | #pragma once 10 | 11 | #include "nixycore/general/general.h" 12 | 13 | ////////////////////////////////////////////////////////////////////////// 14 | NX_BEG 15 | ////////////////////////////////////////////////////////////////////////// 16 | 17 | namespace private_safe_bool 18 | { 19 | class detail 20 | { 21 | public: 22 | typedef void (detail::*bool_type)(void) const; 23 | void this_type_does_not_support_comparisons(void) const {} 24 | protected: 25 | detail(void) {} 26 | detail(const detail&) {} 27 | detail& operator=(const detail&) { return *this; } 28 | ~detail(void) {} 29 | }; 30 | } 31 | 32 | template 33 | class safe_bool : private_safe_bool::detail 34 | // private or protected inheritance is very important here 35 | // as it triggers the access control violation in main. 36 | { 37 | public: 38 | operator bool_type(void) const 39 | { 40 | return (static_cast(this))->check_safe_bool() ? 41 | &private_safe_bool::detail::this_type_does_not_support_comparisons : 0; 42 | } 43 | protected: 44 | ~safe_bool(void) {} 45 | }; 46 | 47 | /* 48 | Some helpful operators 49 | */ 50 | 51 | template 52 | bool operator==(const safe_bool& lhs, bool b) 53 | { 54 | if (lhs) 55 | return b; 56 | else 57 | return (!b); 58 | } 59 | 60 | template 61 | bool operator!=(const safe_bool& lhs, bool b) 62 | { 63 | if (lhs) 64 | return (!b); 65 | else 66 | return b; 67 | } 68 | 69 | template 70 | bool operator==(bool b, const safe_bool& rhs) 71 | { 72 | return operator==(rhs, b); 73 | } 74 | 75 | template 76 | bool operator!=(bool b, const safe_bool& rhs) 77 | { 78 | return operator!=(rhs, b); 79 | } 80 | 81 | template 82 | bool operator==(const safe_bool& lhs, const safe_bool& /*rhs*/) 83 | { 84 | lhs.this_type_does_not_support_comparisons(); 85 | return false; 86 | } 87 | 88 | template 89 | bool operator!=(const safe_bool& lhs, const safe_bool& /*rhs*/) 90 | { 91 | lhs.this_type_does_not_support_comparisons(); 92 | return false; 93 | } 94 | 95 | ////////////////////////////////////////////////////////////////////////// 96 | NX_END 97 | ////////////////////////////////////////////////////////////////////////// 98 | -------------------------------------------------------------------------------- /nixycore/utility/type_cast.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "nixycore/typemanip/typetools.h" 11 | 12 | #include "nixycore/general/general.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | NX_BEG 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | template 19 | inline T implicit_cast(typename type_wrap::type_t input) 20 | { 21 | return input; 22 | } 23 | 24 | template 25 | inline T horrible_cast(const U& input) 26 | { 27 | union { T out; U inp; } horrible; 28 | horrible.inp = input; 29 | return horrible.out; 30 | } 31 | 32 | ////////////////////////////////////////////////////////////////////////// 33 | NX_END 34 | ////////////////////////////////////////////////////////////////////////// 35 | -------------------------------------------------------------------------------- /nixycore/utility/utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | The Nixy Library 3 | Code covered by the MIT License 4 | 5 | Author: mutouyun (http://orzz.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | ////////////////////////////////////////////////////////////////////////// 11 | 12 | #include "nixycore/utility/alignof.h" 13 | #include "nixycore/utility/addressof.h" 14 | #include "nixycore/utility/type_cast.h" 15 | #include "nixycore/utility/countof.h" 16 | #include "nixycore/utility/operator.h" 17 | #include "nixycore/utility/noncopyable.h" 18 | #include "nixycore/utility/final.h" 19 | #include "nixycore/utility/initialize.h" 20 | #include "nixycore/utility/max_min.h" 21 | #include "nixycore/utility/limit_of.h" 22 | #include "nixycore/utility/safe_bool.h" 23 | #include "nixycore/utility/refer.h" 24 | #include "nixycore/utility/rvalue.h" 25 | #include "nixycore/utility/forward.h" 26 | #include "nixycore/utility/valid.h" 27 | #include "nixycore/utility/tuple.h" 28 | 29 | ////////////////////////////////////////////////////////////////////////// 30 | -------------------------------------------------------------------------------- /nixyx/config.cpp: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #include 4 | 5 | #include "config_base.h" 6 | #include "config_ini.h" 7 | #include "config_js.h" 8 | 9 | ////////////////////////////////////////////////////////////////////////// 10 | 11 | /* 12 | Test Config 13 | */ 14 | 15 | void test(const Config* p) 16 | { 17 | qDebug() << ""; 18 | qDebug() << p->solution().name_; 19 | qDebug() << ""; 20 | foreach (QString var, p->solution().include_paths_) 21 | { 22 | qDebug() << var; 23 | } 24 | qDebug() << p->solution().tmp_path_; 25 | qDebug() << p->solution().out_path_; 26 | foreach (QString var, p->solution().DEFINES_) 27 | { 28 | qDebug() << var; 29 | } 30 | qDebug() << p->solution().CFLAGS_; 31 | qDebug() << p->solution().LFLAGS_; 32 | for(int i = 0; i < p->projects().count(); ++i) 33 | { 34 | qDebug() << ""; 35 | qDebug() << p->projects()[i].name_; 36 | qDebug() << p->projects()[i].type_; 37 | foreach(QString file, p->projects()[i].depends_) 38 | { 39 | qDebug() << file; 40 | } 41 | foreach(QString file, p->projects()[i].heads_) 42 | { 43 | qDebug() << file; 44 | } 45 | foreach(QString file, p->projects()[i].sources_) 46 | { 47 | qDebug() << file; 48 | } 49 | } 50 | } 51 | 52 | ////////////////////////////////////////////////////////////////////////// 53 | 54 | struct Config::Impl_ 55 | { 56 | ConfigBase* cfg_; 57 | QString plat_, cc_; 58 | bool is_valid_; 59 | 60 | Impl_(const QString& script_path, const QString& plat, const QString& cc) 61 | : cfg_(NULL), plat_(plat), cc_(cc), is_valid_(false) 62 | { 63 | QString fmt(script_path); 64 | fmt = fmt.mid(fmt.lastIndexOf('.')); 65 | 66 | if (fmt == ".ini") 67 | cfg_ = new ConfigINI; 68 | else if (fmt == ".js") 69 | cfg_ = new ConfigJS(plat, cc); 70 | 71 | if (cfg_) is_valid_ = cfg_->load(script_path); 72 | } 73 | 74 | ~Impl_() 75 | { 76 | if (cfg_) delete cfg_; 77 | } 78 | }; 79 | 80 | ////////////////////////////////////////////////////////////////////////// 81 | 82 | Config::Config(const QString& script_path, const QString& plat, const QString& cc) 83 | : pimpl_(new Impl_(script_path, plat, cc)) 84 | { 85 | if (!isValid()) 86 | { 87 | setMessage("Configuration script parsing error."); 88 | } 89 | } 90 | 91 | Config::~Config() 92 | { 93 | if (pimpl_) delete pimpl_; 94 | } 95 | 96 | ////////////////////////////////////////////////////////////////////////// 97 | 98 | const QString& Config::plat(void) const 99 | { 100 | Q_ASSERT(pimpl_); 101 | return pimpl_->plat_; 102 | } 103 | 104 | const QString& Config::cc(void) const 105 | { 106 | Q_ASSERT(pimpl_); 107 | return pimpl_->cc_; 108 | } 109 | 110 | bool Config::isValid(void) 111 | { 112 | Q_ASSERT(pimpl_); 113 | return pimpl_->is_valid_; 114 | } 115 | 116 | solution_t& Config::solution(void) 117 | { 118 | static solution_t sln; 119 | return sln; 120 | } 121 | 122 | projects_t& Config::projects(void) 123 | { 124 | static projects_t pjs; 125 | return pjs; 126 | } 127 | 128 | void Config::setMessage(const QString& msg) 129 | { 130 | err_msg_ = msg; 131 | } 132 | 133 | const QString& Config::getMessage(void) const 134 | { 135 | return err_msg_; 136 | } 137 | -------------------------------------------------------------------------------- /nixyx/config.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H 2 | #define CONFIG_H 3 | 4 | #include "solution.h" 5 | 6 | #include 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | class Config 11 | { 12 | public: 13 | Config(const QString&, const QString&, const QString&); 14 | 15 | const QString& plat(void) const; 16 | const QString& cc(void) const; 17 | 18 | bool isValid(void); 19 | 20 | static solution_t& solution(void); 21 | static projects_t& projects(void); 22 | 23 | private: 24 | struct Impl_; 25 | Impl_* pimpl_; 26 | 27 | protected: 28 | QString err_msg_; 29 | 30 | public: 31 | void setMessage(const QString&); 32 | const QString& getMessage(void) const; 33 | 34 | public: 35 | virtual ~Config(); 36 | }; 37 | 38 | ////////////////////////////////////////////////////////////////////////// 39 | 40 | #endif // CONFIG_H 41 | -------------------------------------------------------------------------------- /nixyx/config_base.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_BASE_H 2 | #define CONFIG_BASE_H 3 | 4 | #include "solution.h" 5 | #include "config.h" 6 | #include "tools.h" 7 | 8 | ////////////////////////////////////////////////////////////////////////// 9 | 10 | class ConfigBase 11 | { 12 | public: 13 | virtual bool load(const QString&) = 0; 14 | 15 | public: 16 | virtual ~ConfigBase() {} 17 | }; 18 | 19 | ////////////////////////////////////////////////////////////////////////// 20 | 21 | #endif // CONFIG_BASE_H 22 | -------------------------------------------------------------------------------- /nixyx/config_ini.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_INI_H 2 | #define CONFIG_INI_H 3 | 4 | #include "config_base.h" 5 | 6 | #include 7 | #include 8 | 9 | ////////////////////////////////////////////////////////////////////////// 10 | 11 | class ConfigINI: public ConfigBase 12 | { 13 | public: 14 | bool load(const QString& script_path) 15 | { 16 | QScopedPointer resolver(new QSettings(script_path, QSettings::IniFormat)); 17 | #define ini_value(key) resolver->value(key).toString() 18 | 19 | Config::solution().name_ = ini_value("/solution/name"); 20 | 21 | QList projects; 22 | interceptList(ini_value("/solution/projects"), projects); 23 | for(int i = 0; i < projects.count(); ++i) 24 | { 25 | Project prj; prj.name_ = projects[i]; 26 | Config::projects().append(prj); 27 | } 28 | 29 | PathAppendFile_ path_file; 30 | path_file.path_ = Config::solution().path_ = intercept(ini_value("/solution/project_path")); 31 | 32 | Config::solution().include_paths_.append(path_file.path_); 33 | interceptList(ini_value("/solution/include_path"), 34 | Config::solution().include_paths_, path_file); 35 | 36 | Config::solution().tmp_path_ = intercept(ini_value("/solution/tmp_path")); 37 | Config::solution().out_path_ = intercept(ini_value("/solution/out_path")); 38 | 39 | interceptList (ini_value("/solution/DEFINES"), Config::solution().DEFINES_); 40 | Config::solution().CFLAGS_ = ini_value("/solution/CFLAGS"); 41 | Config::solution().LFLAGS_ = ini_value("/solution/LFLAGS"); 42 | 43 | for(int i = 0; i < projects.count(); ++i) 44 | { 45 | QString prj_tag("/project."); prj_tag += projects[i]; 46 | 47 | Config::projects()[i].GUID_ = ini_value(prj_tag + "/GUID"); 48 | Config::projects()[i].type_ = ini_value(prj_tag + "/type"); 49 | Config::projects()[i].libs_ = ini_value(prj_tag + "/libs"); 50 | 51 | interceptList(ini_value(prj_tag + "/depends"), 52 | Config::projects()[i].depends_); 53 | 54 | interceptList(ini_value(prj_tag + "/heads"), 55 | Config::projects()[i].heads_, path_file); 56 | 57 | interceptList(ini_value(prj_tag + "/sources"), 58 | Config::projects()[i].sources_, path_file); 59 | } 60 | 61 | #undef ini_value 62 | return true; 63 | } 64 | }; 65 | 66 | ////////////////////////////////////////////////////////////////////////// 67 | 68 | #endif // CONFIG_INI_H 69 | -------------------------------------------------------------------------------- /nixyx/main.cpp: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include "platform.h" 3 | 4 | #include 5 | #include 6 | 7 | ////////////////////////////////////////////////////////////////////////// 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | QCoreApplication app(argc, argv); 12 | 13 | QString script_file("build.js"); 14 | QString script_plat("win"); 15 | QString script_cc("vc11"); 16 | 17 | int cnt = (argc > 1) ? 0 : -1; 18 | for (int i = 1; i < argc; ++i) 19 | { 20 | if (strcmp(argv[i], "-f") == 0) 21 | { 22 | if (++i >= argc) break; 23 | script_file = argv[i]; 24 | cnt |= 0x1; 25 | } 26 | else if (strcmp(argv[i], "-p") == 0) 27 | { 28 | if (++i >= argc) break; 29 | script_plat = argv[i]; 30 | cnt |= 0x2; 31 | } 32 | else if (strcmp(argv[i], "-c") == 0) 33 | { 34 | if (++i >= argc) break; 35 | script_cc = argv[i]; 36 | cnt |= 0x4; 37 | } 38 | } 39 | 40 | QString in; 41 | if (cnt > 0) in = "y"; 42 | 43 | forever 44 | { 45 | if (!in.isEmpty()) 46 | { 47 | if (in == "y") break; 48 | QTextStream(stdout) << "\nPlease enter your configuration: "; 49 | if (in == "f") 50 | { 51 | QTextStream(stdout) << "(ini/js/...)\n"; 52 | QTextStream(stdin) >> script_file; 53 | } 54 | else if (in == "p") 55 | { 56 | QTextStream(stdout) << "(linux/win/...)\n"; 57 | QTextStream(stdin) >> script_plat; 58 | } 59 | else if (in == "c") 60 | { 61 | QTextStream(stdout) << "(gcc/vc8/vc9/...)\n"; 62 | QTextStream(stdin) >> script_cc; 63 | } 64 | else if (in == "n") 65 | { 66 | QTextStream(stdout) << "(filename linux gcc)\n"; 67 | QTextStream(stdin) >> script_file >> script_plat >> script_cc; 68 | } 69 | else 70 | { 71 | QTextStream(stdout) << "Error configuration...\n"; 72 | } 73 | } 74 | 75 | QTextStream(stdout) << "\n" 76 | << "Script File: " << script_file << "\n" 77 | << "Target Plat: " << script_plat << "\n" 78 | << "Target CC: " << script_cc << "\n\n" 79 | << "OK to start it ? (y/n/f/p/c) "; 80 | 81 | QTextStream(stdin) >> in; 82 | } 83 | 84 | Config config(script_file, script_plat, script_cc); 85 | if (Platform(config).make()) 86 | { 87 | QTextStream(stdout) << "\n" 88 | << "Make Successes!" << "\n"; 89 | } 90 | else 91 | { 92 | QTextStream(stdout) << "\n" 93 | << "Make Failure!" << " ->: " 94 | << config.getMessage() << "\n"; 95 | system("pause"); 96 | } 97 | 98 | return 0; 99 | } 100 | -------------------------------------------------------------------------------- /nixyx/nixyx.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2013-09-25T10:38:15 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core 8 | QT += script 9 | QT += xml 10 | QT -= gui 11 | 12 | TARGET = nixyx 13 | CONFIG += console 14 | CONFIG -= app_bundle 15 | 16 | TEMPLATE = app 17 | 18 | DESTDIR = ../build 19 | OBJECTS_DIR = ../build/!tmp/nixyx 20 | 21 | SOURCES += main.cpp \ 22 | config.cpp \ 23 | platform.cpp 24 | 25 | HEADERS += \ 26 | config.h \ 27 | platform.h \ 28 | platform_base.h \ 29 | platform_gcc.h \ 30 | solution.h \ 31 | config_base.h \ 32 | config_ini.h \ 33 | config_js.h \ 34 | platform_vc.h \ 35 | tools.h \ 36 | policy_vc10.h \ 37 | policy_vc8.h \ 38 | policy_vc9.h \ 39 | policy_vc_base.h \ 40 | policy_vc11.h \ 41 | policy_vc12.h 42 | -------------------------------------------------------------------------------- /nixyx/platform.cpp: -------------------------------------------------------------------------------- 1 | #include "platform.h" 2 | 3 | #include 4 | 5 | #include "platform_base.h" 6 | #include "platform_gcc.h" 7 | #include "platform_vc.h" 8 | #include "policy_vc8.h" 9 | #include "policy_vc9.h" 10 | #include "policy_vc10.h" 11 | #include "policy_vc11.h" 12 | #include "policy_vc12.h" 13 | 14 | ////////////////////////////////////////////////////////////////////////// 15 | 16 | struct Platform::Impl_ 17 | { 18 | Config& config_; 19 | PlatformBase* plat_; 20 | 21 | Impl_(Config& cfg) 22 | : config_(cfg), plat_(NULL) 23 | { 24 | if (cfg.cc() == "vc8" || 25 | cfg.cc() == "vc08" || cfg.cc() == "vc2005" || cfg.cc() == "vs2005") 26 | plat_ = new PlatformVC; 27 | else 28 | if (cfg.cc() == "vc9" || 29 | cfg.cc() == "vc09" || cfg.cc() == "vc2008" || cfg.cc() == "vs2008") 30 | plat_ = new PlatformVC; 31 | else 32 | if (cfg.cc() == "vc10" || cfg.cc() == "vc2010" || cfg.cc() == "vs2010") 33 | plat_ = new PlatformVC; 34 | else 35 | if (cfg.cc() == "vc11" || cfg.cc() == "vc2012" || cfg.cc() == "vs2012") 36 | plat_ = new PlatformVC; 37 | else 38 | if (cfg.cc() == "vc12" || cfg.cc() == "vc2013" || cfg.cc() == "vs2013") 39 | plat_ = new PlatformVC; 40 | else 41 | /* (cfg.cc() == "gcc") */ 42 | plat_ = new PlatformGCC; 43 | } 44 | 45 | ~Impl_() 46 | { 47 | if (plat_) delete plat_; 48 | } 49 | 50 | bool make(void) 51 | { 52 | if (plat_) 53 | return plat_->make(config_); 54 | else 55 | { 56 | config_.setMessage("It is not supported on this setting."); 57 | return false; 58 | } 59 | } 60 | }; 61 | 62 | ////////////////////////////////////////////////////////////////////////// 63 | 64 | Platform::Platform(Config& cfg) 65 | : pimpl_(new Impl_(cfg)) 66 | {} 67 | 68 | Platform::~Platform() 69 | { 70 | if (pimpl_) delete pimpl_; 71 | } 72 | 73 | ////////////////////////////////////////////////////////////////////////// 74 | 75 | bool Platform::make(void) 76 | { 77 | Q_ASSERT(pimpl_); 78 | return pimpl_->make(); 79 | } 80 | -------------------------------------------------------------------------------- /nixyx/platform.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_H 2 | #define PLATFORM_H 3 | 4 | #include "config.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | class Platform 9 | { 10 | public: 11 | Platform(Config&); 12 | 13 | bool make(void); 14 | 15 | private: 16 | struct Impl_; 17 | Impl_* pimpl_; 18 | 19 | public: 20 | virtual ~Platform(); 21 | }; 22 | 23 | ////////////////////////////////////////////////////////////////////////// 24 | 25 | #endif // PLATFORM_H 26 | -------------------------------------------------------------------------------- /nixyx/platform_base.h: -------------------------------------------------------------------------------- 1 | #ifndef PLATFORM_BASE_H 2 | #define PLATFORM_BASE_H 3 | 4 | #include "config.h" 5 | #include "solution.h" 6 | 7 | ////////////////////////////////////////////////////////////////////////// 8 | 9 | class PlatformBase 10 | { 11 | public: 12 | virtual bool make(Config& cfg) 13 | { 14 | return cfg.isValid(); 15 | } 16 | 17 | public: 18 | virtual ~PlatformBase() {} 19 | }; 20 | 21 | ////////////////////////////////////////////////////////////////////////// 22 | 23 | #endif // PLATFORM_BASE_H 24 | -------------------------------------------------------------------------------- /nixyx/policy_vc11.h: -------------------------------------------------------------------------------- 1 | #ifndef POLICY_VC11_H 2 | #define POLICY_VC11_H 3 | 4 | #include "policy_vc10.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | struct PolicyVC11 : PolicyVC10 9 | { 10 | /* 11 | Configuration PlatformToolset 12 | */ 13 | 14 | void decorateConfiguration(QDomElement& prop, QDomDocument& doc) 15 | { 16 | prop.appendChild(doc.createElement("PlatformToolset")) 17 | .appendChild(doc.createTextNode("v110")); 18 | } 19 | 20 | /* 21 | Version of Solution File 22 | */ 23 | 24 | const char* version(void) 25 | { 26 | return "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012"; 27 | } 28 | }; 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | 32 | #endif // POLICY_VC11_H 33 | -------------------------------------------------------------------------------- /nixyx/policy_vc12.h: -------------------------------------------------------------------------------- 1 | #ifndef POLICY_VC12_H 2 | #define POLICY_VC12_H 3 | 4 | #include "policy_vc10.h" 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | struct PolicyVC12 : PolicyVC10 9 | { 10 | /* 11 | Configuration PlatformToolset 12 | */ 13 | 14 | void decorateConfiguration(QDomElement& prop, QDomDocument& doc) 15 | { 16 | prop.appendChild(doc.createElement("PlatformToolset")) 17 | .appendChild(doc.createTextNode("v120")); 18 | } 19 | 20 | /* 21 | Version of Solution File 22 | */ 23 | 24 | const char* version(void) 25 | { 26 | return "Microsoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2013"; 27 | } 28 | }; 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | 32 | #endif // POLICY_VC12_H 33 | -------------------------------------------------------------------------------- /nixyx/policy_vc_base.h: -------------------------------------------------------------------------------- 1 | #ifndef POLICY_VC_BASE_H 2 | #define POLICY_VC_BASE_H 3 | 4 | #include "config.h" 5 | #include "solution.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | ////////////////////////////////////////////////////////////////////////// 13 | 14 | struct PolicyVCBase 15 | { 16 | /* 17 | The options of createRoot 18 | */ 19 | 20 | virtual QDomElement makeRoot (Config&, const Project&, QDomDocument&) { return QDomElement(); } 21 | virtual QDomElement makePlatforms (Config&, const Project&, QDomDocument&, QDomElement&) { return QDomElement(); } 22 | virtual QDomElement makeConfigurations(Config&, const Project&, QDomDocument&, QDomElement&) { return QDomElement(); } 23 | virtual QDomElement makeFilters (Config&, const Project&, QDomDocument&, QDomElement&) { return QDomElement(); } 24 | 25 | /* 26 | Make the root element of project file 27 | */ 28 | 29 | QDomElement createRoot(Config& cfg, const Project& prj, QDomDocument& doc) 30 | { 31 | QDomElement root = makeRoot(cfg, prj, doc); 32 | 33 | root.appendChild(makePlatforms (cfg, prj, doc, root)); 34 | root.appendChild(makeConfigurations(cfg, prj, doc, root)); 35 | root.appendChild(makeFilters (cfg, prj, doc, root)); 36 | 37 | return root; 38 | } 39 | 40 | /* 41 | Create GUID 42 | */ 43 | 44 | QString GUID(void) 45 | { 46 | return QUuid().createUuid().toString(); 47 | } 48 | 49 | /* 50 | Get filter of the file 51 | */ 52 | 53 | QString createFilterName(solution_t& solution, QString& file_path) 54 | { 55 | file_path.replace('/', '\\'); 56 | QString file_orig = file_path.mid(solution.path_.length()); 57 | 58 | if (file_orig.left(1) == "\\") 59 | file_orig = file_orig.mid(1); 60 | else if (file_orig.left(2) == ".\\") 61 | file_orig = file_orig.mid(2); 62 | 63 | int n = file_orig.indexOf('\\') + 1; 64 | int m = file_orig.indexOf('\\', n); 65 | return (m > 0) ? file_orig.mid(n, m - n) : QString(); 66 | } 67 | 68 | /* 69 | AdditionalIncludeDirectories && PreprocessorDefinitions 70 | */ 71 | 72 | QString createIncludePaths(solution_t& solution, const Project& /*prj*/) 73 | { 74 | // AdditionalIncludeDirectories 75 | QString path("$(SolutionDir)"); 76 | foreach(QString con, solution.include_paths_) 77 | { 78 | path += ";$(SolutionDir)"; 79 | path += con; 80 | } 81 | return path; 82 | } 83 | 84 | QString createDefines(solution_t& solution, const Project& prj) 85 | { 86 | // PreprocessorDefinitions 87 | QString cons; 88 | if (prj.type_ == "lib") 89 | cons = ";_LIB"; 90 | else if (prj.type_ == "dll") 91 | cons = ";_USRDLL"; 92 | else if (prj.type_ == "console") 93 | cons = ";_CONSOLE"; 94 | foreach(QString con, solution.DEFINES_) 95 | { 96 | cons += ";"; 97 | cons += con; 98 | } 99 | return cons; 100 | } 101 | }; 102 | 103 | ////////////////////////////////////////////////////////////////////////// 104 | 105 | #endif // POLICY_VC_BASE_H 106 | -------------------------------------------------------------------------------- /nixyx/solution.h: -------------------------------------------------------------------------------- 1 | #ifndef SOLUTION_H 2 | #define SOLUTION_H 3 | 4 | #include 5 | #include 6 | 7 | ////////////////////////////////////////////////////////////////////////// 8 | 9 | struct Solution 10 | { 11 | QString name_, path_; 12 | QList include_paths_; 13 | QString tmp_path_, out_path_; 14 | QList DEFINES_; 15 | QString CFLAGS_, LFLAGS_; 16 | }; 17 | 18 | struct Project 19 | { 20 | QString name_, GUID_; 21 | QString type_, libs_; 22 | QList depends_; 23 | QList heads_; 24 | QList sources_; 25 | }; 26 | 27 | typedef Solution solution_t; 28 | typedef QList projects_t; 29 | 30 | ////////////////////////////////////////////////////////////////////////// 31 | 32 | #endif // SOLUTION_H 33 | -------------------------------------------------------------------------------- /nixyx/tools.h: -------------------------------------------------------------------------------- 1 | #ifndef TOOLS_H 2 | #define TOOLS_H 3 | 4 | #include 5 | 6 | ////////////////////////////////////////////////////////////////////////// 7 | 8 | #define DEF_SOL(...) #__VA_ARGS__ 9 | #define DEF_STR(...) DEF_SOL(__VA_ARGS__) 10 | 11 | #define DEF_CAT(x, ...) x##__VA_ARGS__ 12 | #define DEF_JOIN(x, ...) DEF_CAT(x, __VA_ARGS__) 13 | 14 | #define DEF_ARGS(...) __VA_ARGS__ 15 | 16 | ////////////////////////////////////////////////////////////////////////// 17 | 18 | /* 19 | Intercept string from contents 20 | */ 21 | 22 | inline QString intercept(QString& cons, char c = '\'') 23 | { 24 | QString ret; 25 | int n = cons.indexOf(c); 26 | int m = cons.indexOf(c, n + 1); 27 | if (n < 0) 28 | { 29 | ret = cons; 30 | cons.clear(); 31 | } 32 | else if (m < 0) 33 | { 34 | ret = cons.right(n); 35 | cons.clear(); 36 | } 37 | else 38 | { 39 | ret = cons.mid(n + 1, m - n - 1); 40 | cons = cons.right(cons.length() - m - 1); 41 | } 42 | return ret.trimmed(); 43 | } 44 | 45 | inline QString intercept(const QString& cons, char c = '\'') 46 | { 47 | return intercept(const_cast(cons), c); 48 | } 49 | 50 | inline void interceptList(QString cons, QList& rets, char c = '\'') 51 | { 52 | while(!cons.isEmpty()) 53 | { 54 | rets.append(intercept(cons, c)); 55 | } 56 | } 57 | 58 | template 59 | inline void interceptList(QString cons, QList& rets, Format_& format, char c = '\'') 60 | { 61 | while(!cons.isEmpty()) 62 | { 63 | rets.append(format(intercept(cons, c))); 64 | } 65 | } 66 | 67 | struct PathAppendFile_ 68 | { 69 | QString path_; 70 | QString operator()(const QString& file) 71 | { 72 | return path_ + file; 73 | } 74 | }; 75 | 76 | ////////////////////////////////////////////////////////////////////////// 77 | 78 | #endif // TOOLS_H 79 | --------------------------------------------------------------------------------