├── KCLib.pro ├── KC_library ├── KC_bitfield.h ├── KC_c_fun.c ├── KC_cpp_fun.cpp ├── KC_daemon.cpp ├── KC_daemon.h ├── KC_debug.h ├── KC_library.h ├── KC_library_declarations.h ├── KC_list.h ├── KC_memory.h ├── KC_new.h ├── KC_pod_array.h ├── KC_pod_array_internal.h ├── KC_pointers.h ├── KC_random.h ├── KC_string.h ├── KC_types.h ├── KC_vector.h └── kernel_memory_map.h ├── LICENSE ├── README.md └── main.cpp /KCLib.pro: -------------------------------------------------------------------------------- 1 | TEMPLATE = app 2 | CONFIG += console c++11 3 | CONFIG -= app_bundle 4 | #CONFIG -= qt 5 | 6 | SOURCES += main.cpp \ 7 | KC_library/KC_c_fun.c \ 8 | KC_library/KC_cpp_fun.cpp 9 | INCLUDEPATH += KC_Library 10 | 11 | DEFINES += KCL_NO_KERNEL 12 | 13 | 14 | MOC_DIR = build/.moc 15 | OBJECTS_DIR = build/.obj 16 | RCC_DIR = build/.rcc 17 | UI_DIR = build/.ui 18 | 19 | unix { 20 | TARGET = bin/KCLib_test 21 | } 22 | windows { 23 | TARGET = ../bin/KCLib_test 24 | } 25 | 26 | #CONFIG(debug, debug|release) { 27 | CONFIG(debug) { 28 | DEFINES += KC_LIBRARY_PROTECT_OFF #Защита заголовочных файлов, применённая в заголовочниках библиотеки KC_Lib, путает qtcreator, и он считает, что текст не компилится, что отключает полезные опции редактирования. Для обхода этого применён этот флаг 29 | } 30 | 31 | HEADERS += \ 32 | KC_library/KC_library.h \ 33 | KC_library/KC_library_declarations.h \ 34 | KC_library/KC_bitfield.h \ 35 | KC_library/KC_debug.h \ 36 | KC_library/KC_list.h \ 37 | KC_library/KC_memory.h \ 38 | KC_library/KC_new.h \ 39 | KC_library/KC_pod_array.h \ 40 | KC_library/KC_pod_array_internal.h \ 41 | KC_library/KC_pointers.h \ 42 | KC_library/KC_random.h \ 43 | KC_library/KC_string.h \ 44 | KC_library/KC_types.h \ 45 | KC_library/KC_vector.h 46 | -------------------------------------------------------------------------------- /KC_library/KC_bitfield.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | # ifdef __cplusplus 6 | 7 | #pragma pack(push,1) 8 | template 9 | class BaseFlags { 10 | public: 11 | typedef IntegerTn Integer; 12 | typedef BaseFlags This; 13 | enum { 14 | kByteSize = sizeof(Integer), 15 | kBitSize = kByteSize<<3 16 | }; 17 | 18 | explicit BaseFlags(Integer value) : int_(value) {} 19 | explicit BaseFlags() : int_(0) {} 20 | 21 | KCL_FINLINE Integer Value() {return data();} 22 | 23 | KCL_FINLINE void Set(Size bit_to_set) { 24 | KCL_ASSERT(bit_to_set < kBitSize, "BaseFlags::Set(Size) : Indexation error"); 25 | Integer mask = 1<(&value);} 55 | 56 | protected: 57 | KCL_FINLINE Integer data() const {return int_;} 58 | KCL_FINLINE void data(Integer value) {int_ = value;} 59 | KCL_FINLINE Integer & get_data() {return int_;} 60 | 61 | private: 62 | Integer int_; 63 | }; 64 | typedef BaseFlags Flags; 65 | #pragma pack(pop) 66 | 67 | #pragma pack(push,1) 68 | template 69 | class BitField { 70 | public: 71 | typedef UInteger64 IntegerOfBase; 72 | typedef BaseFlags Base; 73 | typedef BitField This; 74 | enum { 75 | kDimensionX = DimensionX, 76 | kDimensionY = DimensionY, 77 | kBitLength = kDimensionX * kDimensionY, 78 | kByteLength = KCL_GET_INFINUM_SIZE( kBitLength, sizeof(Byte) ), 79 | kSizeofBase = sizeof(IntegerOfBase) , 80 | kSize = KCL_GET_INFINUM_SIZE(kByteLength, kSizeofBase), 81 | kNumberBits = kByteLength * sizeof(Byte), 82 | kSizeofBaseBitSize = kSizeofBase * sizeof(Byte) 83 | }; 84 | 85 | KCL_FINLINE void Set(Size bit_to_set) { 86 | KCL_ASSERT(bit_to_set < kNumberBits, "BitField::Set(Size) : Indexation error"); 87 | Size index = bit_to_set / kSizeofBaseBitSize; 88 | Size bit_number = bit_to_set % kSizeofBaseBitSize; 89 | get_data()[index].Set(bit_number); 90 | } 91 | KCL_FINLINE void SetTo(Size bit_to_set, bool value) { 92 | KCL_ASSERT(bit_to_set < kNumberBits, "BitField::Set(Size, bool) : Indexation error"); 93 | Size index = bit_to_set / kSizeofBaseBitSize; 94 | Size bit_number = bit_to_set % kSizeofBaseBitSize; 95 | get_data()[index].SetTo(bit_number, value); 96 | } 97 | KCL_FINLINE void Reset(Size bit_to_reset) { 98 | KCL_ASSERT(bit_to_reset < kNumberBits, "BitField::Reset : Indexation error"); 99 | Size index = bit_to_reset / kSizeofBaseBitSize; 100 | Size bit_number = bit_to_reset % kSizeofBaseBitSize; 101 | get_data()[index].Reset(bit_number); 102 | } 103 | KCL_FINLINE bool Get(Size bit_to_get) const { 104 | KCL_ASSERT(bit_to_get < kNumberBits, "BitField::Get : Indexation error"); 105 | Size index = bit_to_get / kSizeofBaseBitSize; 106 | Size bit_number = bit_to_get % kSizeofBaseBitSize; 107 | return data()[index].Get(bit_number); 108 | } 109 | KCL_FINLINE void Invert(Size bit_to_invert) { 110 | KCL_ASSERT(bit_to_invert < kNumberBits, "BitField::Invert : Indexation error"); 111 | Size index = bit_to_invert / kSizeofBaseBitSize; 112 | Size bit_number = bit_to_invert % kSizeofBaseBitSize; 113 | get_data()[index].Invert(bit_number); 114 | } 115 | 116 | KCL_FINLINE void Set(Size x, Size y) { return Set (x * kDimensionY + y); } 117 | KCL_FINLINE void SetTo(Size x, Size y, bool value) { return SetTo (x * kDimensionY + y, value); } 118 | KCL_FINLINE void Reset(Size x, Size y) { return Reset (x * kDimensionY + y); } 119 | KCL_FINLINE bool Get(Size x, Size y) const { return Get (x * kDimensionY + y); } 120 | KCL_FINLINE void Invert(Size x, Size y) { return Invert(x * kDimensionY + y); } 121 | 122 | KCL_FINLINE void Clear() { 123 | Size counter = 0 - kSize; 124 | Base * base = end_pointer(); 125 | for (; counter; ++counter) { 126 | base[counter].Clear(); 127 | } 128 | } 129 | 130 | protected: 131 | KCL_FINLINE Base * get_data() {return data_;} 132 | KCL_FINLINE Base const * data() const {return data_;} 133 | KCL_FINLINE Base * end_pointer() {return get_data() + kSize;} 134 | 135 | private: 136 | Base data_[kSize]; 137 | }; 138 | #pragma pack(pop) 139 | 140 | //extern BitField<16> debug_bit_field; 141 | 142 | 143 | 144 | # endif //__cplusplus 145 | 146 | #endif // KC_LIBRARY_PROTECT_OFF 147 | -------------------------------------------------------------------------------- /KC_library/KC_c_fun.c: -------------------------------------------------------------------------------- 1 | #ifdef KCL_NO_KERNEL 2 | # include 3 | # include 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # include 10 | # include 11 | # include 12 | # ifndef _WIN32 13 | # include 14 | # include 15 | # endif //not _WIN32 16 | #else //KCL_NO_KERNEL 17 | #endif //KCL_NO_KERNEL 18 | 19 | 20 | # ifndef _WIN32 21 | # include 22 | 23 | # endif //not _WIN32 24 | 25 | #include "KC_library.h" 26 | 27 | 28 | 29 | enum {kStandardSendFlags = 0,}; 30 | 31 | ///@todo примитив синхронизации для функций памяти в случае отладки памяти 32 | char const * const kBoolValueNames[] = { 33 | "False", 34 | "True" 35 | }; 36 | 37 | Size debug_locker_counter = 0; 38 | 39 | # ifdef KCL_MEMORY_DEBUG 40 | 41 | # ifdef KCL_NO_KERNEL 42 | 43 | # endif // KCL_NO_KERNEL 44 | 45 | # endif // KCL_MEMORY_DEBUG 46 | 47 | 48 | void *KCL_Allocate_C(size_t s) { 49 | #ifndef KCL_NO_KERNEL 50 | return kmalloc(s, kAllocateFlags); 51 | #else //KCL_NO_KERNEL 52 | return malloc(s); 53 | #endif //KCL_NO_KERNEL 54 | } 55 | 56 | extern void * KCL_Rellocate_C(const void *pointer, Size number_of_bytes) { 57 | #ifndef KCL_NO_KERNEL 58 | return krealloc(pointer, number_of_bytes, kAllocateFlags); 59 | #else //not KCL_NO_KERNEL 60 | return realloc( (void *)pointer, number_of_bytes); 61 | #endif //not KCL_NO_KERNEL 62 | } 63 | 64 | extern void KCL_FreeOrDie_C(void *p) { 65 | KCL_ASSERT(p != NULL, "KCL_FreeOrDie_C warning: try to destruct null pointer!!!"); 66 | #ifndef KCL_NO_KERNEL 67 | kfree(p); 68 | #else //KCL_NO_KERNEL 69 | free(p); 70 | #endif //KCL_NO_KERNEL 71 | } 72 | 73 | 74 | 75 | KCL_EXTERN RandInteger * GetKCLDummy_C() { 76 | static RandInteger dummy; 77 | return &dummy; 78 | } 79 | 80 | -------------------------------------------------------------------------------- /KC_library/KC_cpp_fun.cpp: -------------------------------------------------------------------------------- 1 | #include "KC_library.h" 2 | extern "C" { 3 | #ifdef KCL_NO_KERNEL 4 | # ifndef _WIN32 5 | # include 6 | # endif //_WIN32 7 | #endif 8 | } 9 | 10 | 11 | #ifndef _WIN32 12 | #endif //_WIN32 13 | //typedef size_t Size; 14 | #ifdef KCL_NO_KERNEL 15 | #include 16 | #endif //KCL_NO_KERNEL 17 | 18 | 19 | 20 | 21 | # ifdef KCL_MEMORY_DEBUG 22 | 23 | 24 | namespace KCL_NAMESPACE { //namespace kcl started 25 | MemoryMap g_memory_map; 26 | } //namespace kcl finished 27 | 28 | extern "C" { 29 | 30 | /// @debug 31 | class IntHash { 32 | public: 33 | static Size Calculate(Size x) {return x;} 34 | }; 35 | 36 | void InitializeMemoryDebugger() { 37 | 38 | InitializeDebugMemoryLock(); 39 | bool is_success = g_memory_map. Initialize(); 40 | KCL_ASSERT(is_success, "DebugMemoryMap initialization failed!!!"); 41 | } 42 | 43 | void UninitializeMemoryDebugger() { 44 | WriteLockDebugMemoryLocker(); 45 | g_memory_map.Destroy(); 46 | WriteUnlockDebugMemoryLocker(); 47 | UninitializeDebugMemoryLock(); 48 | } 49 | 50 | bool FindLeaks() { 51 | 52 | return KCL_NAMESPACE_PERFIX g_memory_map.FindLeaks(); 53 | } 54 | 55 | bool FindLeaksAndAlert() { 56 | return KCL_NAMESPACE_PERFIX g_memory_map.FindLeaksAndAlert(); 57 | } 58 | void GetSnapshotMemoryDebugger(void * snapshot_pointer) { 59 | typedef KCL_NAMESPACE_PERFIX MemoryMap::Snapshot Snapshot; 60 | Snapshot * snapshot = static_cast(snapshot_pointer); 61 | KCL_NAMESPACE_PERFIX g_memory_map.GetSnapshot(*snapshot); 62 | } 63 | bool IsEqualMemoryDebugger(const void * snapshot_pointer, bool need_alert) { 64 | typedef KCL_NAMESPACE_PERFIX MemoryMap::Snapshot Snapshot; 65 | const Snapshot * snapshot = static_cast(snapshot_pointer); 66 | return KCL_NAMESPACE_PERFIX g_memory_map.IsEqual(*snapshot, need_alert); 67 | } 68 | 69 | } //extern "C" 70 | 71 | # else // KCL_MEMORY_DEBUG 72 | void InitializeMemoryDebugger() {} 73 | void UninitializeMemoryDebugger() {} 74 | # endif // KCL_MEMORY_DEBUG 75 | 76 | 77 | 78 | namespace KCL_NAMESPACE { 79 | 80 | 81 | extern "C" { 82 | 83 | void * Allocate(Size number_of_bytes) { 84 | #ifdef KCL_NO_KERNEL 85 | void * return_address = malloc(number_of_bytes); 86 | return return_address; 87 | #else 88 | void * return_address = KCL_Allocate_C(number_of_bytes); 89 | return return_address; 90 | #endif 91 | } 92 | 93 | extern void DeallocateOrDie(const void * pointer) { 94 | #ifdef KCL_NO_KERNEL 95 | free( (void*) pointer); 96 | #else 97 | KCL_FreeOrDie_C( const_cast(pointer) ); 98 | #endif 99 | } 100 | 101 | extern void SafeDeallocate(const void * pointer) { 102 | #ifdef KCL_NO_KERNEL 103 | if (pointer) free( (void*) pointer); 104 | #else 105 | if (pointer) KCL_FreeOrDie_C( const_cast(pointer) ); 106 | #endif 107 | } 108 | 109 | extern void * Reallocate(const void *pointer, Size number_of_bytes) { 110 | #ifdef KCL_NO_KERNEL 111 | return realloc( (void*) pointer, number_of_bytes); 112 | #else 113 | return KCL_Rellocate_C(pointer, number_of_bytes); 114 | #endif 115 | } 116 | 117 | #ifdef KCL_NO_KERNEL 118 | # ifndef _WIN32 119 | # define RECEIVE_FUNCTIONS_ON 120 | # endif 121 | #else 122 | # define GET_NLA_DATA_MACRO(na) ((void *)((char*)(na) + NLA_HDRLEN)) 123 | #endif 124 | 125 | 126 | } 127 | 128 | 129 | 130 | 131 | ///@todo сделать нормальный MemoryLength, более оптимальный 132 | Size MemoryLength(const void * pointer) { 133 | if (!pointer) return 0; 134 | const Byte * bytes = static_cast(pointer); 135 | PointerDifference intptr = reinterpret_cast(pointer); 136 | Size max_size = (0 - intptr); 137 | enum {kMaxRationalLength = 0xFFffFF}; 138 | enum {kNullSym = 0}; 139 | max_size = Min(kMaxRationalLength, max_size); 140 | for ( Size i = 0; i < max_size; ++i ) { 141 | if ( bytes[i] == kNullSym ) return i; 142 | } 143 | return kMaxRationalLength; 144 | } 145 | 146 | 147 | void String::Append_(const CharType * to_add, Size number_chars_to_add) { 148 | 149 | } 150 | 151 | void String::Resize_(Size new_size) { 152 | if ( IsNull() ) { 153 | MakeDataForThis_(new_size); 154 | } 155 | } 156 | 157 | void String::MakeDataForThis_(Size new_size) { 158 | data(MakeData_(new_size)); 159 | size(new_size); 160 | is_owner(true); 161 | } 162 | 163 | typename String::CharType * 164 | String::MakeData_(Size new_size) { 165 | CharType * re = static_cast ( KCL_ALLOCATE(new_size + kTerminatorSize) ); 166 | KCL_ASSERT( (bool)re, "String: out of memory"); 167 | return re; 168 | } 169 | 170 | void String::DeleteData_(CharType * pointer) { 171 | KCL_DEALLOCATE(pointer); 172 | } 173 | 174 | void String::DeleteDataForThis_() { 175 | if ( is_owner() ) DeleteData_(data()); 176 | data(NULL); 177 | size(0); 178 | is_owner(0); 179 | } 180 | 181 | typename String::This 182 | String::MakeReference(const CharType * string) { 183 | CharType * string_value = const_cast (string); 184 | This re; 185 | bool is_error; 186 | re.is_owner(false); 187 | re.data(string_value); 188 | re.size( GetStringLength(string_value, &is_error) ); 189 | KCL_ASSERT(!is_error, "Creating reference String from const multibyte string failed!!! Source String not null-terminated"); 190 | if (is_error) { 191 | re.size(0); 192 | } 193 | return re; 194 | } 195 | 196 | } //namespace kcl 197 | 198 | KCL_EXTERN const Char * GetErrorTextForSafePointers(Size error_code, Size operator_code) { 199 | Size index = 0; 200 | static const Char * error_parameter = "Safe pointers error : invalid GetErrorTextFolrSafePointers parameters"; 201 | static const Char * errors[] = { 202 | "Safe pointers error : No error", 203 | "Safe pointers error, operator* : Null dereferencing", 204 | "Safe pointers error, operator* : Overwrite", 205 | "Safe pointers error, operator* : Underwrite", 206 | 207 | "Safe pointers error, operator-> : Null dereferencing", 208 | "Safe pointers error, operator-> : Overwrite", 209 | "Safe pointers error, operator-> : Underwrite", 210 | 211 | "Safe pointers error, operator[] : Null dereferencing", 212 | "Safe pointers error, operator[] : Overwrite", 213 | "Safe pointers error, operator[] : Underwrite" 214 | }; 215 | enum {kIndexLimit = KCL_NAMESPACE_PERFIX PointerRangeEnums::kErrorLimit * KCL_NAMESPACE_PERFIX PointerRangeEnums::kOperatorNumber}; 216 | index = (error_code != KCL_NAMESPACE_PERFIX PointerRangeEnums::kNoError) ? 217 | (error_code + operator_code * (KCL_NAMESPACE_PERFIX PointerRangeEnums::kErrorLimit) ) : 218 | ( 0 ); 219 | if (index > kIndexLimit) return error_parameter; 220 | return errors[index]; 221 | } 222 | 223 | -------------------------------------------------------------------------------- /KC_library/KC_daemon.cpp: -------------------------------------------------------------------------------- 1 | #include "KC_daemon.h" 2 | 3 | #define D_FUNCTION(type) template type Daemon:: 4 | 5 | D_FUNCTION(int) Start() { 6 | } 7 | 8 | #undef D_FUNCTION 9 | -------------------------------------------------------------------------------- /KC_library/KC_daemon.h: -------------------------------------------------------------------------------- 1 | template class Daemon { 2 | public: 3 | typedef FunctionalityTn Functionality; 4 | typedef Daemon This; 5 | template Init(Args args); 6 | int Start(); 7 | 8 | protected: 9 | Functionality const * worker() const {return worker_ptr;} 10 | Functionality * worker() {return worker_ptr;} 11 | 12 | private: 13 | UniquePointer worker_ptr; 14 | }; 15 | -------------------------------------------------------------------------------- /KC_library/KC_debug.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | enum {kErrorPrintSleep = 10}; 6 | 7 | # ifdef KCL_NO_KERNEL 8 | # define DiagnosticPrintServ printf 9 | # define PrintError printf 10 | # define Print printf 11 | # define sprintf __builtin_sprintf 12 | # else //KCL_NO_KERNEL 13 | #define Print printk 14 | # ifdef __cplusplus 15 | # endif //__cplusplus 16 | 17 | # ifdef __cplusplus 18 | extern "C" { 19 | extern void printk(const char *fmt, ...); 20 | # endif //__cplusplus 21 | # define DiagnosticPrintServ printk 22 | # define PrintError(...) { \ 23 | Size i; \ 24 | enum {kLocalRepeats = 2<<8}; \ 25 | printk( __VA_ARGS__); \ 26 | printk(KERN_EMERG "\n"); \ 27 | for(i = 0 - kLocalRepeats; i; ++i) { \ 28 | printk(KERN_CONT ".");\ 29 | KCL_NAMESPACE_PERFIX Shedule(kErrorPrintSleep); \ 30 | } \ 31 | printk(KERN_EMERG "\n"); \ 32 | } 33 | # define sprintf __builtin_sprintf 34 | # ifdef __cplusplus 35 | } 36 | # endif //__cplusplus 37 | # endif //KCL_NO_KERNEL 38 | 39 | # ifdef _DEBUG 40 | # define DiagnosticPrint DiagnosticPrintServ 41 | # else // _DEBUG 42 | # define DiagnosticPrint(...) 43 | # endif // _DEBUG 44 | 45 | # define INT3 asm ( "int $3" ); 46 | 47 | # ifndef KCL_NO_KERNEL 48 | # define BREAK() 49 | # else //KCL_NO_KERNEL 50 | # ifdef __GNUC__ 51 | # define BREAK() { __builtin_trap(); } 52 | //# define BREAK() { raise(SIGTRAP); } 53 | # else // __GNUC__ 54 | # define BREAK() { INT3 } 55 | # endif // __GNUC__ 56 | # endif //KCL_NO_KERNEL 57 | 58 | 59 | # ifndef NO_KERN //для работы в ядре 60 | # define KCL_ASSERT_SERVICE(condition, message, file, line) {if (!(condition)) {PrintError(KERN_EMERG " * * * ASSERTION_ERROR * * * ---> %s ( in file %s at %d ) ", message, file, line); BREAK();} } 61 | # else //NO_KERN 62 | # define KCL_ASSERT_SERVICE(condition, message, file, line) {if (!(condition)) {PrintError( " * * * ASSERTION_ERROR * * * ---> %s ( in file %s at %d ) ", message, file, line); BREAK(); } } 63 | # endif //NO_KERN 64 | # define KCL_ASSERT(condition, message) { KCL_ASSERT_SERVICE(condition, message, __FILE__, __LINE__) } 65 | 66 | #define CONDITIONAL_BREAK(Condition, Iteration) {static unsigned long __debug_counter = 1; if ( Condition ) { if ( __debug_counter >= (Iteration) ) BREAK(); ++__debug_counter;} } 67 | 68 | #define CONDITIONAL_BREAK_N_PRINT(Condition, Iteration, StartPrintIteration, PrintFrequency, Name) \ 69 | {\ 70 | static unsigned long __debug_counter = 1;\ 71 | if ( (__debug_counter >= StartPrintIteration) && (__debug_counter % PrintFrequency) == 0 ) DiagnosticPrint("\nCondition %s, iteration = %lu\n", Name, __debug_counter); \ 72 | if ( Condition ) { \ 73 | if ( __debug_counter >= (Iteration) ) BREAK(); \ 74 | ++__debug_counter; \ 75 | } \ 76 | } 77 | 78 | # ifdef __cplusplus 79 | # endif //__cplusplus 80 | 81 | 82 | # ifdef __cplusplus 83 | extern "C" { 84 | # endif //__cplusplus 85 | extern char const * const kBoolValueNames[2]; 86 | # ifdef __cplusplus 87 | } 88 | # endif //__cplusplus 89 | 90 | 91 | #endif // KC_LIBRARY_PROTECT_OFF 92 | -------------------------------------------------------------------------------- /KC_library/KC_library.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_H 2 | #define KC_LIBRARY_H 3 | 4 | //#define KCL_ALIEN_OFF 5 | 6 | # ifndef __PRETTY_FUNCTION__ 7 | # ifdef __BORLANDC__ 8 | # define __PRETTY_FUNCTION__ __func__ 9 | # endif // __BORLANDC__ 10 | 11 | # ifdef _MSC_VER 12 | # define __PRETTY_FUNCTION__ __FUNCSIG__ 13 | # endif // _MSC_VER 14 | 15 | # ifndef __PRETTY_FUNCTION__ 16 | # define __PRETTY_FUNCTION__ "Function name unsupported for this compiler" 17 | # endif // not __PRETTY_FUNCTION__ 18 | # endif // not __PRETTY_FUNCTION__ 19 | 20 | 21 | # ifdef __GNUC__ 22 | # define KCL_FORCE_INLINE_SERV inline __attribute__((always_inline)) 23 | # else // __GNUC__ 24 | # ifdef _MSC_VER 25 | # define KCL_FORCE_INLINE_SERV __forceinline 26 | # endif // _MSC_VER 27 | # ifndef KCL_FORCE_INLINE_SERV 28 | # define KCL_FORCE_INLINE_SERV inline 29 | # endif 30 | # endif // __GNUC__ 31 | 32 | 33 | # ifdef NO_FORCE_INLINE 34 | # define KCL_FORCE_INLINE 35 | # else // NO_FORCE_INLINE 36 | # define KCL_FORCE_INLINE KCL_FORCE_INLINE_SERV /// @debug нужно разремить эту строку и убрать следующую 37 | //# define KCL_FINLINE /// @debug нужно убрать эту строку и разремить предыдущую 38 | # endif // NO_FORCE_INLINE 39 | 40 | # define KCL_FINLINE KCL_FORCE_INLINE // сокращение от KCL_FORCE_INLINE 41 | 42 | #define KCL_HEADER_DEFINITION inline 43 | #define KCL_INLINE_HEADER_DEFINITION KCL_FORCE_INLINE_SERV 44 | 45 | # define KCL_USED(x) { (void )(x); } 46 | 47 | # ifndef KCL_NO_KERNEL 48 | # ifdef __cplusplus 49 | # define KCL_CPP_LINUX_KERNEL // Принак того, что библиотека собирается под ядром linux и ПРИ ЭТОМ сейчас компилируется c++ код 50 | # endif // __cplusplus 51 | # endif // KCL_NO_KERNEL 52 | 53 | # ifndef _WIN32 54 | # ifndef KCL_SEPARATE_COMPILE_FOR_LINUX_KERNEL 55 | # include 56 | # ifndef KCL_NO_KERNEL 57 | # include 58 | # include 59 | # endif // KCL_NO_KERNEL 60 | # endif //KCL_SEPARATE_COMPILE_FOR_LINUX_KERNEL 61 | # else //_WIN32 62 | # include 63 | # endif //_WIN32 64 | 65 | 66 | # ifdef KCL_MEMORY_DEBUG 67 | # ifndef _DEBUG 68 | # error Key 'KCL_MEMORY_DEBUG' without '_DEBUG' key! 69 | # endif // _DEBUG 70 | # endif // KCL_MEMORY_DEBUG 71 | 72 | 73 | # ifdef KCL_MEMORY_DEBUG_ACCESS 74 | # ifndef _DEBUG 75 | # error Key 'KCL_MEMORY_DEBUG_ACCESS' without '_DEBUG' key! 76 | # endif // not _DEBUG 77 | # ifndef KCL_MEMORY_DEBUG 78 | # error Key 'KCL_MEMORY_DEBUG_ACCESS' without 'KCL_MEMORY_DEBUG' key! 79 | # endif // not KCL_MEMORY_DEBUG 80 | # endif // KCL_MEMORY_DEBUG_ACCESS 81 | 82 | 83 | # ifdef __cplusplus 84 | extern "C" { 85 | # endif //__cplusplus 86 | 87 | 88 | 89 | # ifdef KCL_NO_KERNEL 90 | # include 91 | # else //KCL_NO_KERNEL 92 | # endif //KCL_NO_KERNEL 93 | 94 | 95 | # ifdef __cplusplus 96 | } 97 | # endif //__cplusplus 98 | 99 | # ifndef _WIN32 100 | # include 101 | # endif 102 | # include 103 | # include 104 | # include 105 | //#define KCL_MEMORY_DEBUG 106 | 107 | 108 | # ifdef __cplusplus 109 | # define KCL_EXTERN extern "C" 110 | # ifndef KCL_USER_NAMESPACE /// @warning ключ KCL_USER_NAMESPACE позволяет задать библиотеку KC в другом namespace 111 | # define KCL_NAMESPACE kcl 112 | # else // KCL_USER_NAMESPACE 113 | # define KCL_NAMESPACE KCL_USER_NAMESPACE 114 | # endif 115 | # define KCL_NAMESPACE_PERFIX KCL_NAMESPACE:: 116 | # else //__cplusplus 117 | # define KCL_EXTERN extern 118 | # define KCL_NAMESPACE 119 | # define KCL_NAMESPACE_PERFIX 120 | # endif //__cplusplus 121 | 122 | 123 | # ifdef __cplusplus 124 | namespace KCL_NAMESPACE {} 125 | template void Swap(Tn & a, Tn & b) {Tn temp; temp = b; b = a; a = temp;} 126 | # endif //__cplusplus 127 | 128 | # define KCL_ALLOCATE(number_of_bytes) Allocate(number_of_bytes) 129 | # define KCL_DEALLOCATE(pointer) SafeDeallocate(pointer) 130 | 131 | # define KCL_INLINE static inline 132 | 133 | # define Max(a,b) ( ( (a) > (b) ) ? (a) : (b) ) 134 | # define Min(a,b) ( ( (a) < (b) ) ? (a) : (b) ) 135 | 136 | 137 | 138 | # ifdef KCL_NO_KERNEL 139 | # include "stdio.h" 140 | # include "stdlib.h" 141 | //# include "conio.h" 142 | # else //KCL_NO_KERNEL 143 | # endif //KCL_NO_KERNEL 144 | 145 | 146 | # define KC_LIBRARY_PROTECT_OFF 147 | 148 | # include "KC_types.h" 149 | 150 | # ifdef KCL_SEPARATE_COMPILE_FOR_LINUX_KERNEL 151 | KCL_INLINE void * memcpy(void * dest, const void * src, size_t n) {return __builtin_memcpy( (dest), (src), (n) );} 152 | KCL_INLINE void * memset( void * ptr, int value, size_t num ) {return __builtin_memset( (ptr), (value), (num) );} 153 | KCL_INLINE Size strlen(const Char * ptr ) {return __builtin_strlen( (ptr) );} 154 | KCL_INLINE void * memchr ( const Char * ptr, int value, size_t num ) {return __builtin_memchr( (ptr), (value), (num) );} 155 | //KCL_INLINE void va_start(__va_list_tag * tag, va_list args) {__builtin_va_start( tag, args );} 156 | # define va_start(v,l) __builtin_va_start(v,l) 157 | # endif //KCL_SEPARATE_COMPILE_FOR_LINUX_KERNEL 158 | 159 | # include "KC_library_declarations.h" 160 | 161 | # ifdef KCL_NO_NEW_HEADER 162 | # include "new" 163 | # else //KCL_NO_NEW_HEADER 164 | # include "KC_new.h" 165 | # endif //KCL_NO_NEW_HEADER 166 | 167 | # include "KC_debug.h" 168 | 169 | 170 | # ifdef __cplusplus 171 | namespace KCL_NAMESPACE { //namespace kcl started 172 | 173 | # endif //__cplusplus 174 | 175 | # include "KC_random.h" 176 | # include "KC_pointers.h" 177 | # include "KC_memory.h" 178 | # include "KC_list.h" 179 | # include "KC_vector.h" 180 | # include "KC_pod_array.h" 181 | # include "KC_bitfield.h" 182 | # include "KC_string.h" 183 | 184 | # undef KC_LIBRARY_PROTECT_OFF 185 | 186 | # ifdef __cplusplus 187 | } //namespace kcl finished 188 | # endif //__cplusplus 189 | 190 | #endif //KC_LIBRARY_H 191 | -------------------------------------------------------------------------------- /KC_library/KC_library_declarations.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_DECLARATIONS_H 2 | #define KC_LIBRARY_DECLARATIONS_H 3 | 4 | #define KCL_DISALLOW_COPY_AND_ASSIGN(TypeName) \ 5 | TypeName(const TypeName&); \ 6 | void operator=(const TypeName&); 7 | 8 | # ifdef KCL_MEMORY_DEBUG_ACCESS 9 | # ifdef __cplusplus 10 | 11 | # define KCL_POINTER(ObjectType) KCL_NAMESPACE_PERFIX SafePointer 12 | # define CONST_KCL_POINTER(ObjectType) KCL_NAMESPACE_PERFIX SafeConstPointer 13 | # define KCL_WEAK_POINTER(ObjectType) KCL_NAMESPACE_PERFIX SafePointer 14 | # define CONST_KCL_WEAK_POINTER(ObjectType) KCL_NAMESPACE_PERFIX SafeConstPointer 15 | 16 | # define KCL_ARRAY_POINTER(Type) KCL_NAMESPACE_PERFIX ArrayPointer 17 | # endif //__cplusplus 18 | # else // KCL_MEMORY_DEBUG_ACCESS 19 | # define KCL_POINTER(ObjectType) ObjectType * 20 | # define CONST_KCL_POINTER(ObjectType) const ObjectType * 21 | # define KCL_WEAK_POINTER(ObjectType) ObjectType * 22 | # define CONST_KCL_WEAK_POINTER(ObjectType) const ObjectType * 23 | # define KCL_ARRAY_POINTER(Type) KCL_NAMESPACE::ArrayPointer 24 | # endif // KCL_MEMORY_DEBUG_ACCESS 25 | 26 | 27 | # ifdef KCL_MEMORY_DEBUG 28 | # define KCL_CREATE_OBJECT(ObjectType) KCL_NAMESPACE_PERFIX CreateObjectDebug(__FILE__, __LINE__) 29 | # define KCL_DELETE_OBJECT(pointer) KCL_NAMESPACE_PERFIX DeleteObjectDebug(pointer, __FILE__, __LINE__) 30 | # else // KCL_MEMORY_DEBUG 31 | # define KCL_CREATE_OBJECT(ObjectType) KCL_NAMESPACE_PERFIX CreateObject() 32 | # define KCL_DELETE_OBJECT(pointer) KCL_NAMESPACE_PERFIX DeleteObject(pointer) 33 | # endif // KCL_MEMORY_DEBUG 34 | 35 | # ifndef KERN_INFO 36 | # ifdef KCL_NO_KERNEL 37 | # define KERN_EMERG "\n" 38 | # define KERN_ALERT "\n" 39 | # define KERN_CRIT "\n" 40 | # define KERN_ERR "\n" 41 | # define KERN_WARNING "\n" 42 | # define KERN_NOTICE "\n" 43 | # define KERN_INFO "\n" 44 | # define KERN_DEBUG "\n" 45 | # define KERN_DEFAULT "\n" 46 | # define KERN_CONT 47 | # else //KCL_NO_KERNEL 48 | # define KERN_EMERG "<0>" // system is unusable 49 | # define KERN_ALERT "<1>" // action must be taken immediately 50 | # define KERN_CRIT "<2>" // critical conditions 51 | # define KERN_ERR "<3>" // error conditions 52 | # define KERN_WARNING "<4>" // warning conditions 53 | # define KERN_NOTICE "<5>" // normal but significant condition 54 | # define KERN_INFO "<6>" // informational 55 | # define KERN_DEBUG "<7>" // debug-level messages 56 | # define KERN_DEFAULT "" // Use the default kernel loglevel 57 | # define KERN_CONT "" 58 | # endif //KCL_NO_KERNEL 59 | # endif //KERN_INFO 60 | 61 | KCL_INLINE void MemoryZeroizing(const void * memory_block, Size number_bytes) { 62 | memset( (void*) memory_block, 0, number_bytes); 63 | } 64 | 65 | KCL_INLINE void MemoryCopy(const void * source, Size number_bytes, void * destination) { 66 | memcpy(destination, source, number_bytes); 67 | } 68 | 69 | KCL_INLINE Size GetUnsafeStringLength(const Char * string) { 70 | return strlen(string); 71 | } 72 | 73 | enum {kStringTerminator = 0}; 74 | KCL_INLINE Size GetSafeStringLength(const Char * string, bool * out_is_error) { 75 | bool is_error; 76 | Size re = (Size)(-1); 77 | Size limit = re - (Size)string; 78 | const Char * memchr_retvalue = (const Char *)memchr(string, kStringTerminator ,limit); 79 | is_error = memchr_retvalue < string; 80 | if (!is_error) { 81 | re = memchr_retvalue - string; 82 | } 83 | if (out_is_error) out_is_error[0] = is_error; 84 | return re; 85 | } 86 | 87 | KCL_INLINE Size GetStringLength(const Char * string, bool * out_is_error) { 88 | return GetSafeStringLength(string, out_is_error); 89 | } 90 | 91 | KCL_EXTERN void * Allocate(Size number_of_bytes); 92 | KCL_EXTERN void DeallocateOrDie(const void * pointer); 93 | KCL_EXTERN void SafeDeallocate(const void * pointer); 94 | KCL_EXTERN void * Reallocate(const void *pointer, Size number_of_bytes); 95 | KCL_EXTERN const Char * GetErrorTextForSafePointers(Size error_code, Size operator_code); 96 | KCL_EXTERN void SaveAndDisableLocalIrq(unsigned long * out_for_save); 97 | KCL_EXTERN void RestoreLocalIrq(unsigned long const * saved); 98 | KCL_EXTERN void SaveAndDisableLocalIrqBH(void); 99 | KCL_EXTERN void RestoreLocalIrqBH(void); 100 | 101 | 102 | KCL_EXTERN void CPP_EnvironmentInstall(void); 103 | KCL_EXTERN void InitializeMemoryDebugger(void); 104 | KCL_EXTERN void UninitializeMemoryDebugger(void); 105 | # ifdef KCL_MEMORY_DEBUG 106 | # ifdef __cplusplus 107 | namespace KCL_NAMESPACE { //namespace kcl started 108 | class MemoryMap; 109 | template class ArrayPointer; 110 | extern MemoryMap g_memory_map; 111 | template ArrayPointer CreateArrayDebug(Size number_elements, const Char * file, int line); 112 | template void DeleteArrayDebug(ArrayPointer what_delete, const Char * file, int line); 113 | } //namespace kcl finished 114 | # endif //__cplusplus 115 | KCL_EXTERN bool FindLeaks(void); 116 | KCL_EXTERN bool FindLeaksAndAlert(void); 117 | KCL_EXTERN void GetSnapshotMemoryDebugger(void * snapshot_pointer); 118 | KCL_EXTERN bool IsEqualMemoryDebugger(const void * snapshot_pointer, bool need_alert); 119 | KCL_EXTERN void UninitializeMemoryDebugger(void); 120 | KCL_EXTERN void InitializeDebugMemoryLock(void); 121 | KCL_EXTERN void UninitializeDebugMemoryLock(void); 122 | KCL_EXTERN void ReadLockDebugMemoryLocker(void); 123 | KCL_EXTERN void ReadUnlockDebugMemoryLocker(void); 124 | KCL_EXTERN void WriteLockDebugMemoryLocker(void); 125 | KCL_EXTERN void WriteUnlockDebugMemoryLocker(void); 126 | KCL_EXTERN void UpgradeDebugMemoryLocker(void); 127 | # ifdef __cplusplus 128 | # endif //__cplusplus 129 | # endif // KCL_MEMORY_DEBUG 130 | 131 | 132 | # ifdef __cplusplus 133 | namespace KCL_NAMESPACE { //namespace kcl started 134 | 135 | template class BasePointer; 136 | template class BaseConstPointer; 137 | template class SafePointer; 138 | template class SafeConstPointer; 139 | 140 | template class Vector; 141 | template class Allocator; 142 | template class BaseFlags; 143 | template class BitField; 144 | 145 | 146 | template class PointerLimits; 147 | 148 | template const char * GetTypeName(); 149 | template KCL_POINTER(Tn) CreateObject(); 150 | template inline Size SizeOf() {return sizeof(Tn);} 151 | template inline Size SizeOf(Tn&) {return SizeOf();} 152 | template KCL_INLINE Tn * CreateObjectInternal(); 153 | template void DeleteObject(KCL_POINTER(Tn) what_delete); 154 | template KCL_POINTER(Tn) CreateObjectDebug(const Char * file, int line); 155 | template void DeleteObjectDebug(const Char * file, int line, KCL_POINTER(Tn) what_delete); 156 | 157 | template void Construct(Tn * address); 158 | template void Destruct(Tn & object); 159 | template void Destruct( KCL_POINTER(Tn) pointer); 160 | template KCL_POINTER(Tn) CreatePointer( Tn * address); 161 | template KCL_POINTER(Tn) CreatePointer(const Tn * address); 162 | template Tn * GetAddressFromPointer( KCL_POINTER(Tn) address); 163 | 164 | template CONST_KCL_POINTER(Tn) ConstCastPointer( KCL_POINTER(Tn) address); 165 | template KCL_POINTER(Tn) UnconstCastPointer(CONST_KCL_POINTER(Tn) address); 166 | template CONST_KCL_WEAK_POINTER(Tn) ConstCastWeakPointer (KCL_WEAK_POINTER(Tn) address); 167 | template KCL_WEAK_POINTER(Tn) UnconstCastWeakPointer (CONST_KCL_WEAK_POINTER(Tn) address); 168 | template KCL_WEAK_POINTER(Tn) StrongToWeak ( KCL_POINTER(Tn) pointer); 169 | template KCL_WEAK_POINTER(Tn) AddressToWeak ( Tn * pointer); 170 | 171 | KCL_EXTERN void Shedule(unsigned long timeout); 172 | 173 | # define KCL_GET_INFINUM_SIZE(total_size, item_size) ( ( (total_size) / (item_size) ) + ( (total_size) % (item_size) != 0) ) 174 | KCL_HEADER_DEFINITION Size GetInfinumSize(Size total_size, Size item_size) {return KCL_GET_INFINUM_SIZE (total_size, item_size);} 175 | KCL_HEADER_DEFINITION Size Align(Size number, Size align_base) { return GetInfinumSize(number, align_base) * align_base; } 176 | } //namespace kcl finished 177 | # else //__cplusplus 178 | KCL_EXTERN void Shedule(unsigned long timeout); 179 | # endif //__cplusplus 180 | 181 | # ifndef NULL 182 | # define NULL ((void *)0UL) 183 | # endif 184 | 185 | 186 | #endif // KC_LIBRARY_DECLARATIONS_H 187 | -------------------------------------------------------------------------------- /KC_library/KC_list.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | 6 | # ifdef __cplusplus 7 | 8 | template class ListNode; 9 | 10 | #pragma pack(push, 1) 11 | template class PairOfWeakPtr; 12 | #pragma pack(pop) 13 | 14 | template class ListNode : public PairOfWeakPtr { 15 | public: 16 | typedef Tn Type; 17 | typedef ListNode This; 18 | typedef const ListNode ConstThis; 19 | typedef KCL_POINTER(This) StrongPointer; 20 | typedef CONST_KCL_POINTER(This) ConstStrongPointer; 21 | typedef KCL_WEAK_POINTER(This) WeakPointer; 22 | typedef CONST_KCL_WEAK_POINTER(This) ConstWeakPointer; 23 | typedef KCL_POINTER(Type) ObjectPointer; 24 | typedef CONST_KCL_POINTER(Type) ConstObjectPointer; 25 | 26 | class iterator; 27 | typedef iterator Iterator; 28 | typedef Type value_type; 29 | typedef value_type ValueType; 30 | 31 | ListNode() 32 | : PairOfWeakPtr (), 33 | object_(GetNullWeak()), autodelete_(0) { 34 | } 35 | ~ListNode() { 36 | DeleteObject(); 37 | } 38 | 39 | KCL_FINLINE bool Initialize(const Type& to_copy); 40 | 41 | KCL_FINLINE bool Initialize( 42 | const Type& to_copy, 43 | WeakPointer previous_value, 44 | WeakPointer next_value); 45 | 46 | KCL_FINLINE bool FindStrong(const Type & to_find, StrongPointer & out_found, bool & out_is_locked_rule) const; 47 | KCL_FINLINE bool FindWeak (const Type & to_find, WeakPointer & out_found, bool & out_is_locked_rule) const; 48 | 49 | KCL_FINLINE bool SetToNoAutodelete( ObjectPointer to_set ); 50 | KCL_FINLINE bool SetToAutodelete( ObjectPointer to_set ); 51 | KCL_FINLINE bool SetTo( ObjectPointer to_set, bool autodelete_value = 1 ); 52 | 53 | KCL_FINLINE bool InsertBefore(WeakPointer element); 54 | KCL_FINLINE bool InsertAfter(WeakPointer element); 55 | KCL_FINLINE bool InsertBefore(ObjectPointer reference, bool autodelete = 1); 56 | KCL_FINLINE bool AddBefore(const Type & element); 57 | KCL_FINLINE bool AddAfter(const Type & element); 58 | KCL_FINLINE bool AddBefore(); 59 | KCL_FINLINE bool AddAfter(); 60 | KCL_FINLINE void DeleteElement(); 61 | KCL_FINLINE void DeleteThis(); 62 | KCL_FINLINE void ExcludeThis(); 63 | KCL_FINLINE void push_back(const Type & element, WeakPointer postend) {FindTail(postend)->AddAfter(element);} 64 | KCL_FINLINE void DeleteObject() { 65 | if ( autodelete() ) { 66 | KCL_DELETE_OBJECT(object()); 67 | } 68 | set_autodelete(0); 69 | set_object(GetNullStrong()); 70 | } 71 | KCL_FINLINE ConstStrongPointer GetConstPointerToThis() const {return ConstCastPointer(GetPointerToThis());} 72 | KCL_FINLINE StrongPointer GetPointerToThis() const { 73 | # ifdef KCL_MEMORY_DEBUG_ACCESS 74 | return CreatePointer(this, this); 75 | # else // KCL_MEMORY_DEBUG_ACCESS 76 | return CreatePointer(this); 77 | # endif // KCL_MEMORY_DEBUG_ACCESS 78 | return CreatePointer(this); 79 | } 80 | KCL_FINLINE bool IsHead() const {return !previous();} 81 | KCL_FINLINE bool IsTail() const {return !next();} 82 | KCL_FINLINE bool IsContainerEmpty() const {return IsHead() && IsTail() && IsElementEmpty(); } 83 | KCL_FINLINE bool IsOnlyOne() const {return !IsElementEmpty() && IsHead() && IsTail(); } 84 | KCL_FINLINE bool IsElementEmpty() const {return !Data(); } 85 | KCL_FINLINE bool IsNext() const {return next();} 86 | KCL_FINLINE bool IsPrevious() const {return previous();} 87 | 88 | 89 | template 90 | KCL_FINLINE bool Search(ParametersTn & param, OutTn& out); 91 | 92 | template 93 | KCL_FINLINE void DoForeach(ParamTn & param, iterator postend); 94 | 95 | template 96 | KCL_FINLINE bool Search(ParametersTn & param, OutTn& out) const { 97 | return GetSelfAddress()->Search< FunctorTn, ParametersTn, OutTn > (param, out); 98 | } 99 | 100 | template 101 | //KCL_FINLINE 102 | void DoForeach(ParamTn & param, iterator postend) const { 103 | bool debug_notnull = (bool)postend; /// @debug 104 | DiagnosticPrint("DoForeach: is postend notnull = %d", (int)((bool)postend) ); 105 | DiagnosticPrint("DoForeach: is postend notnull = %d", (int)((bool)postend) ); 106 | GetSelfAddress()->DoForeach(param, postend); 107 | KCL_USED(debug_notnull); /// @debug 108 | } 109 | 110 | KCL_FINLINE WeakPointer FindHead(WeakPointer prestart); 111 | KCL_FINLINE ConstWeakPointer FindHead(WeakPointer prestart) const { return ConstCastWeakPointer( GetSelfAddress()->FindHead(prestart) );} 112 | KCL_FINLINE WeakPointer FindTail(WeakPointer postend); 113 | KCL_FINLINE ConstWeakPointer FindTail(WeakPointer postend) const { return ConstCastWeakPointer( GetSelfAddress()->FindTail(postend) );} 114 | KCL_FINLINE void UnsafeSetNext (WeakPointer value) { 115 | set_next (value); 116 | } 117 | KCL_FINLINE void UnsafeSetPrevious(WeakPointer value) { 118 | set_previous(value); 119 | } 120 | KCL_FINLINE WeakPointer GetNext() {return next();} 121 | KCL_FINLINE WeakPointer GetPrevious() {return previous();} 122 | KCL_FINLINE ConstWeakPointer GetNext() const {return next();} 123 | KCL_FINLINE ConstWeakPointer GetPrevious() const {return previous();} 124 | KCL_FINLINE ConstWeakPointer GetConstNext() const {return ConstCastWeakPointer( next() );} 125 | KCL_FINLINE ConstWeakPointer GetConstPrevious() const {return ConstCastWeakPointer( previous() );} 126 | KCL_FINLINE ObjectPointer Access() {return object();} 127 | KCL_FINLINE ConstObjectPointer Data() const {return object_const();} 128 | KCL_FINLINE iterator GetIterator() {return iterator(this);} 129 | KCL_FINLINE WeakPointer GetThisWeak() const {return StrongToWeak(GetPointerToThis());} 130 | KCL_FINLINE ConstWeakPointer GetConstThisWeak() const {return ConstCastWeakPointer(GetThisWeak());} 131 | //KCL_FINLINE 132 | Size size(iterator postend) const; 133 | 134 | # ifdef KCL_MEMORY_DEBUG_ACCESS 135 | KCL_FINLINE WeakPointer GetThis() {return GetThisWeak();} 136 | KCL_FINLINE ConstWeakPointer GetThis() const {return GetConstThisWeak();} 137 | # else // KCL_MEMORY_DEBUG_ACCESS 138 | KCL_FINLINE WeakPointer GetThis() {return this;} 139 | KCL_FINLINE ConstWeakPointer GetThis() const {return this;} 140 | # endif // KCL_MEMORY_DEBUG_ACCESS 141 | 142 | KCL_FINLINE void ClearAll(); 143 | KCL_FINLINE void ClearElement(); 144 | KCL_FINLINE static KCL_POINTER(This) Create(); 145 | KCL_FINLINE static KCL_POINTER(This) Create(const Type& value); 146 | 147 | protected: 148 | class CalculateSizeFunctor; 149 | class CompareFunctor; 150 | KCL_FINLINE void VerifyInsertParameters(WeakPointer previous_value, WeakPointer next_value) { 151 | KCL_USED(previous_value); 152 | KCL_USED(next_value); 153 | KCL_ASSERT(previous_value != GetThisWeak(), "Create loop in kcl list, previous parameter error"); 154 | KCL_ASSERT(next_value != GetThisWeak(), "Create loop in kcl list, next parameter error"); 155 | bool prev_n_next_is_listobj = (previous_value == next_value) && (next_value) && (next_value->next() == next_value) && (next_value->previous() == next_value); //в качестве postend значения взят описатель списка List, у пустого списка в качестве "головы" и "хвоста" используются адрес его самого (хотя List не является потомком ListNode, однако, сделано так, чтобы хвост списка совпадал с полем next_ у ListNode, а поле "голова списка" с полем previous_ у ListNode 156 | KCL_ASSERT( prev_n_next_is_listobj || !next_value || (next_value != previous_value) , "Create loop in kcl list, next and previous are equal (parameter error)"); 157 | KCL_ASSERT( prev_n_next_is_listobj || !next_value || !previous_value || next_value->previous() != previous_value->next() , "Create loop in kcl list, next MUST be after previous (parameter error)"); 158 | } 159 | KCL_FINLINE void InsertThisToList_(WeakPointer previous_value, WeakPointer next_value) { 160 | set_next(next_value); 161 | set_previous(previous_value); 162 | if (previous_value) { 163 | previous_value->set_next( GetThis() ); 164 | } 165 | if (next_value) { 166 | next_value->set_previous( GetThis() ); 167 | } 168 | } 169 | 170 | KCL_FINLINE WeakPointer next() const {return this->first();} 171 | KCL_FINLINE WeakPointer previous() const {return this->second();} 172 | KCL_FINLINE void set_next(WeakPointer address) { this->first(address);} 173 | KCL_FINLINE void set_previous(WeakPointer address) {this->second(address);} 174 | KCL_FINLINE ObjectPointer object() {return object_;} 175 | KCL_FINLINE void set_object(ObjectPointer address) { 176 | object_ = address; 177 | } 178 | KCL_FINLINE void reset_object(void) {object_ = GetNullStrong();} 179 | KCL_FINLINE bool autodelete() const {return autodelete_;} 180 | KCL_FINLINE void set_autodelete(bool value) {autodelete_ = value;} 181 | 182 | KCL_FINLINE This * GetSelfAddress() const {return ( This *)this;} 183 | KCL_FINLINE This const * GetConstSelfAddress() const {return (const This *)this;} 184 | KCL_FINLINE ConstObjectPointer object_const() const {return ConstCastPointer(object_);} 185 | 186 | 187 | private: 188 | ObjectPointer object_; 189 | bool autodelete_; 190 | }; 191 | 192 | 193 | /////////////////////////////////////////////////////////////////////////////// 194 | /// 195 | /// ListNode functions 196 | /// 197 | /////////////////////////////////////////////////////////////////////////////// 198 | 199 | 200 | template 201 | bool ListNode::Initialize(const Type& to_copy) { 202 | set_object(KCL_CREATE_OBJECT(Type)); 203 | set_autodelete(1); 204 | if ( object() ) { 205 | *object() = to_copy; 206 | return 1; 207 | } else { 208 | return 0; 209 | } 210 | } 211 | 212 | template 213 | bool ListNode::Initialize( 214 | const Type& to_copy, 215 | WeakPointer previous_value, 216 | WeakPointer next_value) { 217 | VerifyInsertParameters(); 218 | bool success = Initialize(to_copy); 219 | if (success) { 220 | InsertThisToList_(previous_value, next_value); 221 | } 222 | return success; 223 | } 224 | 225 | 226 | template 227 | bool ListNode::SetTo( ObjectPointer to_set, bool autodelete_value ) { 228 | set_autodelete(autodelete_value); 229 | set_object(to_set); 230 | return 1; 231 | } 232 | 233 | template 234 | bool ListNode::SetToNoAutodelete( ObjectPointer to_set ) { 235 | set_autodelete(0); 236 | set_object(to_set); 237 | return 1; 238 | } 239 | 240 | template 241 | void ListNode::ClearElement( void ) { 242 | set_autodelete(0); 243 | set_object(GetNullStrong()); 244 | } 245 | 246 | template 247 | bool ListNode::SetToAutodelete( ObjectPointer to_set ) { 248 | set_autodelete(1); 249 | set_object(to_set); 250 | return 1; 251 | } 252 | 253 | template 254 | bool ListNode::InsertBefore(WeakPointer element) { 255 | KCL_ASSERT(element, "Insert before: NULL inserting"); 256 | element->VerifyInsertParameters(previous(), GetThis() ); 257 | element->InsertThisToList_(previous(), GetThis() ); 258 | return 1; 259 | } 260 | 261 | template 262 | KCL_FINLINE bool ListNode::InsertBefore (ObjectPointer reference, bool autodelete) { 263 | StrongPointer to_insert = KCL_CREATE_OBJECT(This); 264 | to_insert->SetTo(reference, autodelete); 265 | bool re = InsertBefore(to_insert); 266 | return re; 267 | } 268 | 269 | template 270 | bool ListNode::InsertAfter(WeakPointer element) { 271 | KCL_ASSERT(element, "Insert after: NULL inserting"); 272 | element->VerifyInsertParameters(GetThis(), next() ); 273 | element->InsertThisToList_(GetThis(), next() ); 274 | return 1; 275 | } 276 | 277 | template 278 | bool ListNode::AddBefore(const Type & element) { 279 | bool re = AddBefore(); 280 | if (re) { 281 | (*previous()->Access()) = element; 282 | } 283 | return re; 284 | } 285 | 286 | template 287 | bool ListNode::AddAfter(const Type & element) { 288 | bool re = AddAfter(); 289 | if (re) { 290 | (*next()->Access()) = element; 291 | } 292 | return re; 293 | } 294 | 295 | template 296 | bool ListNode::AddBefore() { 297 | WeakPointer element = KCL_CREATE_OBJECT(This) ; 298 | if (!element) return 0; 299 | ObjectPointer new_obj = KCL_CREATE_OBJECT(Type); 300 | set_autodelete(1); 301 | if (!new_obj) { 302 | KCL_DELETE_OBJECT(element); 303 | return 0; 304 | } 305 | bool re = InsertBefore(element); 306 | element->set_object(new_obj); 307 | return re; 308 | } 309 | 310 | template 311 | bool ListNode::AddAfter() { 312 | WeakPointer element = KCL_CREATE_OBJECT(This) ; 313 | if (!element) return 0; 314 | ObjectPointer new_obj = KCL_CREATE_OBJECT(Type); 315 | set_autodelete(1); 316 | if (!new_obj) { 317 | KCL_DELETE_OBJECT(element); 318 | return 0; 319 | } 320 | bool re = InsertAfter(element); 321 | element->set_object(new_obj); 322 | return re; 323 | } 324 | 325 | template 326 | void ListNode::DeleteElement() { 327 | if ( autodelete() ) KCL_DELETE_OBJECT(object()); 328 | reset_object(); 329 | set_autodelete(0); 330 | } 331 | 332 | template 333 | void ListNode::DeleteThis() { 334 | ExcludeThis(); 335 | KCL_DELETE_OBJECT(GetThis()); 336 | } 337 | 338 | template 339 | void ListNode::ExcludeThis() { 340 | KCL_ASSERT(this, "Dereferencing error!!!"); 341 | WeakPointer next_value = next(); 342 | WeakPointer prev_value = previous(); 343 | if (next_value) { 344 | next_value->set_previous(prev_value); 345 | } 346 | if (prev_value) { 347 | prev_value->set_next(next_value); 348 | } 349 | } 350 | 351 | template 352 | typename ListNode::WeakPointer ListNode::FindHead(WeakPointer prestart) { 353 | WeakPointer re = GetThis(); 354 | while (re->previous() != prestart) { 355 | re = re->previous(); 356 | } 357 | return re; 358 | } 359 | 360 | template 361 | KCL_FINLINE KCL_POINTER(ListNode) ListNode::Create() { 362 | StrongPointer new_node = KCL_CREATE_OBJECT(This); 363 | KCL_ASSERT(new_node, "ListNode::Create : not enough memory"); 364 | return new_node; 365 | } 366 | 367 | template 368 | KCL_FINLINE KCL_POINTER(ListNode) ListNode::Create(const Type& value) { 369 | StrongPointer new_node = Create(); 370 | if (new_node) { 371 | new_node->Initialize( value ); 372 | } 373 | return new_node; 374 | } 375 | 376 | 377 | template 378 | template 379 | KCL_FINLINE bool ListNode::Search(ParametersTn & param, OutTn& out) { 380 | bool re = 0; 381 | iterator start = this; 382 | if ( FunctorTn::Do(start, param, out) ) { 383 | re = 1; 384 | goto finish; 385 | } 386 | for (iterator current = start->GetNext(); 387 | current; 388 | current = current->GetNext() ) { 389 | if ( FunctorTn::Do(current, param, out) ) { 390 | re = 1; 391 | goto finish; 392 | } 393 | } 394 | for (iterator current = start->GetPrevious(); 395 | current; 396 | current = current->GetPrevious() ) { 397 | if ( FunctorTn::Do(current, param, out) ) { 398 | re = 1; 399 | goto finish; 400 | } 401 | } 402 | finish: 403 | return re; 404 | } 405 | 406 | template 407 | class ListNode::CompareFunctor { 408 | public: 409 | KCL_FINLINE static bool Do(iterator first, Tn& second, iterator & out) { 410 | bool re = (*first) == second; 411 | if (re) out = first; 412 | return re; 413 | } 414 | }; 415 | 416 | template 417 | KCL_FINLINE bool ListNode::FindStrong(const Type & to_find, StrongPointer & out_found, bool & out_is_locked_rule) const { 418 | iterator out; 419 | iterator start = GetIterator(); 420 | bool re = Search (to_find, out); 421 | out_found = out->GetPointerToThis(); 422 | return re; 423 | } 424 | 425 | template 426 | KCL_FINLINE bool ListNode::FindWeak (const Type & to_find, WeakPointer & out_found, bool & out_is_locked_rule) const { 427 | iterator out; 428 | iterator start = GetIterator(); 429 | bool re = Search (to_find, out); 430 | out_found = out->GetThisWeak(); 431 | return re; 432 | } 433 | 434 | 435 | 436 | template 437 | template 438 | KCL_FINLINE void ListNode::DoForeach(ParamTn & param, iterator postend) { 439 | if ( IsContainerEmpty() ) return; 440 | iterator start = GetIterator(); 441 | FunctorTn::Do(start, param); 442 | for (iterator current = start->GetNext(); 443 | current != postend; 444 | current = current->GetNext() ) { 445 | FunctorTn::Do(current, param); 446 | } 447 | if (start == postend) return; //для случая кольцевого списка, когда postend указывает на this 448 | for (iterator current = start->GetPrevious(); 449 | current != postend; 450 | current = current->GetPrevious() ) { 451 | FunctorTn::Do(current, param); 452 | } 453 | } 454 | 455 | template 456 | class ListNode::CalculateSizeFunctor { 457 | public: 458 | KCL_FINLINE static void Do(iterator current, Size& size_counter) { 459 | ++size_counter; 460 | KCL_USED(current); 461 | } 462 | }; 463 | 464 | template 465 | Size ListNode::size(iterator postend) const { 466 | Size re = 0; 467 | DoForeach(re,postend); 468 | return re; 469 | } 470 | 471 | 472 | template 473 | void ListNode::ClearAll() { 474 | WeakPointer head = FindHead(), 475 | tail = FindTail(), 476 | old_current = GetNullWeak(), 477 | this_val = GetThis(); 478 | WeakPointer current = head; 479 | while (old_current != tail) { 480 | old_current = current; 481 | KCL_ASSERT(current , "ClearAll: integrity error!!! no next"); 482 | current = current->GetNext(); 483 | if (old_current != this_val) old_current->DeleteThis(); 484 | }; 485 | DeleteObject(); 486 | } 487 | 488 | template 489 | typename ListNode::WeakPointer 490 | ListNode::FindTail(WeakPointer postend) { 491 | WeakPointer re = GetThis(); 492 | while ( re->next() != postend ) { 493 | re = re->next(); 494 | } 495 | return re; 496 | } 497 | 498 | /////////////////////////////////////////////////////////////////////////////// 499 | /// 500 | /// PairOfWeakPtr 501 | /// 502 | /////////////////////////////////////////////////////////////////////////////// 503 | #pragma pack(push, 1) 504 | template class PairOfWeakPtr { 505 | public: 506 | typedef Tn Type; 507 | typedef PairOfWeakPtr This; 508 | typedef ListNode Node; 509 | typedef KCL_WEAK_POINTER(Node) WeakPointer; 510 | 511 | KCL_FINLINE PairOfWeakPtr() 512 | : first_(GetNullWeak()), 513 | second_(GetNullWeak()) {} 514 | 515 | KCL_FINLINE PairOfWeakPtr(WeakPointer value1, WeakPointer value2) 516 | : first_ ( value1 ), 517 | second_( value2 ) {} 518 | 519 | protected: 520 | KCL_FINLINE WeakPointer first () const {return first_;} 521 | KCL_FINLINE WeakPointer second() const {return second_;} 522 | KCL_FINLINE void first(WeakPointer value) {first_ = value;} 523 | KCL_FINLINE void second(WeakPointer value) {second_ = value;} 524 | 525 | private: 526 | WeakPointer first_; 527 | WeakPointer second_; 528 | }; 529 | #pragma pack(pop) 530 | 531 | /////////////////////////////////////////////////////////////////////////////// 532 | /// 533 | /// ListNode::iterator 534 | /// 535 | /////////////////////////////////////////////////////////////////////////////// 536 | 537 | template 538 | class ListNode::iterator { 539 | public: 540 | friend class ListNode; 541 | iterator() : pointer_(GetNullWeak()) {} 542 | #ifdef KCL_MEMORY_DEBUG_ACCESS 543 | iterator( This * arg) : pointer_(arg->GetThisWeak()) {} 544 | iterator(const This * arg) : pointer_( arg->GetThisWeak() ) {} 545 | #endif // KCL_MEMORY_DEBUG_ACCESS 546 | iterator( WeakPointer arg) : pointer_(arg) {} 547 | iterator(ConstWeakPointer arg) : pointer_( UnconstCastWeakPointer(arg) ) {} 548 | ConstWeakPointer operator->() const {return ConstCastWeakPointer(pointer());} 549 | WeakPointer operator->() {return pointer();} 550 | This const & operator*() const {return *pointer();} 551 | This & operator*() {return *pointer();} 552 | iterator operator++(); 553 | iterator operator++(int); 554 | iterator operator--(); 555 | iterator operator--(int); 556 | This const & operator[](Size index) const; 557 | This & operator[](Size index); 558 | const iterator * GetConstThis() const {return this;} 559 | iterator * GetThis() const {return this;} 560 | operator bool() const {return (bool)pointer();} 561 | inline bool operator==(WeakPointer to_compare) {return to_compare == pointer();} 562 | inline bool operator!=(WeakPointer to_compare) {return to_compare != pointer();} 563 | inline bool operator==(iterator to_compare) {return to_compare.pointer() == pointer();} 564 | inline bool operator!=(iterator to_compare) {return to_compare.pointer() != pointer();} 565 | 566 | protected: 567 | WeakPointer pointer() const {return pointer_;} 568 | void pointer(WeakPointer arg) {pointer_ = arg;} 569 | void Decrease_(); 570 | void Increase_(); 571 | 572 | private: 573 | WeakPointer pointer_; 574 | }; 575 | 576 | /////////////////////////////////////////////////////////////////////////////// 577 | /// 578 | /// ListNode::iterator FUNCTIONS 579 | /// 580 | /////////////////////////////////////////////////////////////////////////////// 581 | 582 | 583 | template 584 | typename ListNode::iterator 585 | ListNode::iterator::operator++() { 586 | Increase_(); 587 | return *this; 588 | } 589 | 590 | template 591 | typename ListNode::iterator 592 | ListNode::iterator::operator++(int) { 593 | iterator re = *this; 594 | Increase_(); 595 | return re; 596 | } 597 | 598 | template 599 | typename ListNode::iterator 600 | ListNode::iterator::operator--() { 601 | Decrease_(); 602 | return *this; 603 | } 604 | 605 | template 606 | typename ListNode::iterator 607 | ListNode::iterator::operator--(int) { 608 | iterator re = *this; 609 | Decrease_(); 610 | return re; 611 | } 612 | 613 | template 614 | typename ListNode::This const & 615 | ListNode::iterator::operator[](Size index) const { 616 | return const_cast( GetThis()->operator[](index) ); 617 | } 618 | 619 | template 620 | typename ListNode::This & 621 | ListNode::iterator::operator[](Size index) { 622 | This * data = pointer(); 623 | for (Size counter = index; counter; --counter) { 624 | KCL_ASSERT(pointer(), "ListNode::iterator::operator[] index out of range"); 625 | if (pointer()) return *this; 626 | data = data->GetNext(); 627 | } 628 | return *data; 629 | } 630 | 631 | template 632 | void 633 | ListNode::iterator::Decrease_() { 634 | KCL_ASSERT(pointer(), "ListNode::iterator::Decrease_ null pointer decrement"); 635 | pointer(pointer()->GetPrevious()); 636 | } 637 | 638 | template 639 | void 640 | ListNode::iterator::Increase_() { 641 | KCL_ASSERT(pointer(), "ListNode::iterator::Increase_ null pointer increment"); 642 | pointer(pointer()->GetNext()); 643 | } 644 | 645 | //////////////////////////////////////////////////////////////////////////////// 646 | //////////////////////////////////////////////////////////////////////////////// 647 | //////////////////////////////////////////////////////////////////////////////// 648 | /// 649 | /// List 650 | /// 651 | //////////////////////////////////////////////////////////////////////////////// 652 | //////////////////////////////////////////////////////////////////////////////// 653 | //////////////////////////////////////////////////////////////////////////////// 654 | 655 | template class List : public PairOfWeakPtr { 656 | public: 657 | typedef Tn Type; 658 | typedef List This; 659 | typedef ListNode Parent; 660 | typedef const List ConstThis; 661 | typedef ListNode Node; 662 | typedef const ListNode ConstNode; 663 | typedef typename Node::StrongPointer StrongPointer; 664 | typedef CONST_KCL_POINTER(This) ConstStrongPointer; 665 | typedef typename Node::WeakPointer WeakPointer; 666 | typedef typename Node::ConstWeakPointer ConstWeakPointer; 667 | typedef typename Node::ObjectPointer ObjectPointer; 668 | typedef typename Node::ConstObjectPointer ConstObjectPointer; 669 | typedef typename Node::iterator NodeIterator; 670 | typedef typename Node::ValueType value_type; 671 | typedef typename Node::ValueType ValueType; 672 | class iterator; 673 | typedef iterator const_iterator; 674 | typedef iterator Iterator; 675 | typedef const_iterator ConstIterator; 676 | enum { 677 | kAutoDelete = 1, 678 | kExternalDelete = 0, 679 | kSetAsOwner = kAutoDelete, 680 | kExternalOwner = kExternalDelete 681 | }; 682 | List() 683 | : PairOfWeakPtr( PostEndAsWeak(), PostEndAsWeak() ), 684 | number_elements_(0) {} 685 | ~List() { 686 | clear(); 687 | } 688 | 689 | KCL_FINLINE bool FindStrong( 690 | const Type & to_find, 691 | WeakPointer & out_found, 692 | bool & out_is_locked_rule ) const { 693 | return Node::FindStrong(to_find, out_found, out_is_locked_rule); 694 | } 695 | KCL_FINLINE bool FindWeak( 696 | const Type & to_find, 697 | WeakPointer & out_found, 698 | bool & out_is_locked_rule ) const { 699 | return Node::FindWeak(to_find, out_found, out_is_locked_rule); 700 | } 701 | KCL_FINLINE Size size() const; 702 | 703 | 704 | KCL_FINLINE bool Initialize() {return 1;} 705 | 706 | KCL_FINLINE bool Initialize(const Type& to_copy); 707 | 708 | KCL_FINLINE bool Initialize( 709 | const Type& to_copy, 710 | WeakPointer previous_value, 711 | WeakPointer next_value); 712 | 713 | template 714 | KCL_FINLINE bool Search(ParametersTn & param, OutTn& out); 715 | 716 | template 717 | KCL_FINLINE bool Search(ParametersTn & param, OutTn& out, Size start_index, Size number_elements_to_iterate); 718 | 719 | template 720 | KCL_FINLINE void DoForeach(); 721 | template 722 | KCL_FINLINE void DoForeach(ParamTn & param); 723 | 724 | template 725 | KCL_FINLINE bool Search(ParametersTn & param, OutTn& out) const { 726 | return GetSelfAddress()->Search< FunctorTn, ParametersTn, OutTn > (param, out); 727 | } 728 | 729 | template 730 | KCL_FINLINE void DoForeach(ParamTn & param) const { 731 | GetSelfAddress()->DoForeach(param); 732 | } 733 | 734 | KCL_FINLINE iterator begin() const { 735 | if ( !size() ) return end(); 736 | return iterator(head()->GetIterator()); 737 | } 738 | KCL_FINLINE iterator end() const { 739 | return PostEndAsWeak()->GetIterator(); 740 | } 741 | KCL_FINLINE WeakPointer FindHead() {return StrongToWeak( head() );} 742 | KCL_FINLINE ConstWeakPointer FindHead() const { return ConstCastWeakPointer( GetSelfAddress()->FindHead() );} 743 | KCL_FINLINE WeakPointer FindTail() {return tail();} 744 | KCL_FINLINE ConstWeakPointer FindTail() const { return ConstCastWeakPointer( GetSelfAddress()->FindTail() );} 745 | 746 | KCL_FINLINE KCL_POINTER(Node) CreateNode() { 747 | StrongPointer new_node = Node::Create(); 748 | if (new_node) { 749 | tail(new_node); 750 | head(new_node); 751 | IncreaseSize(); 752 | } 753 | return new_node; 754 | } 755 | KCL_FINLINE KCL_POINTER(Node) CreateNode(const Type& value) { 756 | StrongPointer new_node = Node::Create(value); 757 | return new_node; 758 | } 759 | 760 | class ClearFunctor { 761 | public: 762 | KCL_FINLINE static void Do(iterator data) {data.GetNode()->DeleteThis();} 763 | }; 764 | void clear() { DoForeach(); } 765 | KCL_FINLINE bool IsContainerEmpty() {return size() == 0;} 766 | 767 | KCL_FINLINE bool push_back (const Type& value) { 768 | return AddAfter(value); 769 | } 770 | KCL_FINLINE bool AddAfter( const Type& value) { 771 | if (size() == 0) { 772 | StrongPointer new_node = CreateNode(value); 773 | Assign_(new_node); 774 | return 1; 775 | } 776 | bool re = tail()->AddAfter(value); 777 | if (re) { 778 | tail( tail()->GetNext() ); 779 | IncreaseSize(); 780 | } 781 | return re; 782 | } 783 | KCL_FINLINE Iterator insert(Iterator position, ObjectPointer value) { 784 | Iterator re; 785 | bool success = position.GetNode()->InsertBefore( value, (bool)kAutoDelete); 786 | if (success) { 787 | re = begin(); 788 | if (re == position) { 789 | WeakPointer position_node = position.GetNode(); 790 | WeakPointer new_head = position_node->GetPrevious(); 791 | head( new_head ); 792 | re = head()->GetIterator(); 793 | if (tail() == position_node) { 794 | tail(new_head); 795 | } 796 | } 797 | IncreaseSize(); 798 | } 799 | return re; 800 | } 801 | 802 | KCL_FINLINE Iterator erase(Iterator position) { 803 | Iterator re; 804 | if (size() == 0) return end(); 805 | if (position.GetNode()->GetNext()) { 806 | re = position.GetNode()->GetNext()->GetIterator(); 807 | } 808 | Delete(position.GetNode()); 809 | return re; 810 | } 811 | 812 | KCL_FINLINE bool InsertAfter (WeakPointer reference) { 813 | if (size() == 0) { 814 | Assign_(reference); 815 | return 1; 816 | } 817 | bool re = tail()->InsertAfter(reference); 818 | if (re) { 819 | tail( reference ); 820 | IncreaseSize(); 821 | } 822 | return re; 823 | } 824 | KCL_FINLINE bool AddBefore( const Type& value) { 825 | bool re = head()->AddBefore(value); 826 | if (re) { 827 | head( head()->GetPrevious() ); 828 | IncreaseSize(); 829 | } 830 | return re; 831 | } 832 | KCL_FINLINE bool InsertBefore (WeakPointer reference) { 833 | bool re = head()->InsertBefore(reference); 834 | if (re) { 835 | head( head->GetPrevious() ); 836 | IncreaseSize(); 837 | } 838 | return re; 839 | } 840 | KCL_FINLINE bool InsertBefore (ObjectPointer reference, bool autodelete = 1) { 841 | StrongPointer to_insert = KCL_CREATE_OBJECT(Node); 842 | to_insert->SetTo(reference, autodelete); 843 | bool re = InsertBefore(to_insert); 844 | return re; 845 | } 846 | 847 | KCL_FINLINE void DeleteHead() { 848 | if ( size() != 0 ) { 849 | KCL_ASSERT(head(), "zero head, but size not zero"); 850 | KCL_ASSERT(tail(), "zero tail, but size not zero"); 851 | WeakPointer new_head = head()->GetNext(); 852 | head()->DeleteThis(); 853 | head( new_head->GetPointerToThis() ); 854 | DecreaseSize(); 855 | } 856 | } 857 | KCL_FINLINE void DeleteTail() { 858 | if ( size() != 0 ) { 859 | KCL_ASSERT(head(), "zero head, but size not zero"); 860 | KCL_ASSERT(tail(), "zero tail, but size not zero"); 861 | WeakPointer new_tail = tail()->GetPrevious(); 862 | tail()->DeleteThis(); 863 | tail( new_tail ); 864 | DecreaseSize(); 865 | } 866 | } 867 | KCL_FINLINE 868 | void Delete(WeakPointer to_delete) { 869 | KCL_ASSERT( size() != 0, "List::Delete(Weakpointer) : delete by pointer, but list is empty") 870 | KCL_ASSERT( head(), "List integrity error: null head & non-zero size"); 871 | KCL_ASSERT( tail(), "List integrity error: null tail & non-zero size"); 872 | if ( to_delete == head() ) { 873 | DeleteHead(); 874 | return; 875 | } 876 | if ( to_delete == tail() ) { 877 | DeleteTail(); 878 | return; 879 | } 880 | if ( size() < 3 ) return; 881 | DecreaseSize(); 882 | # ifdef _DEBUG 883 | KCL_ASSERT(IsIn(to_delete), "List::Delete ERROR!!! Deleting non-list element"); 884 | # endif 885 | to_delete->DeleteThis(); 886 | //DecreaseSize(); 887 | } 888 | 889 | KCL_FINLINE bool Delete(const Type & to_delete) { 890 | if ( size() == 0 ) return 0; 891 | KCL_ASSERT( head(), "List integrity error: null head & non-zero size"); 892 | KCL_ASSERT( tail(), "List integrity error: null tail & non-zero size"); 893 | if ( !head()->IsElementEmpty() && to_delete == head()->Data() ) { 894 | DeleteHead(); 895 | return 1; 896 | } 897 | if ( !tail()->IsElementEmpty() && to_delete == tail()->Data() ) { 898 | DeleteTail(); 899 | return 1; 900 | } 901 | if ( size() < 3 ) return 0; 902 | WeakPointer found = GetNullWeak(); 903 | bool re = Find(to_delete, found, 1, size() - 2 ); 904 | if (re) { 905 | found->DeleteThis(); 906 | DecreaseSize(); 907 | } 908 | return re; 909 | } 910 | class IsInFunctor { 911 | public: 912 | KCL_FINLINE static bool Do( 913 | iterator current, 914 | WeakPointer & to_find, 915 | WeakPointer & out_found ) { 916 | bool re = (current.GetNode()->GetThis() == to_find); 917 | if (re) { 918 | out_found = current.GetNode()->GetThis(); 919 | } 920 | return re; 921 | } 922 | }; 923 | class FindFunctor { 924 | public: 925 | KCL_FINLINE static bool Do( 926 | iterator current, 927 | Type & to_find, 928 | WeakPointer & out_found ) { 929 | bool re = (current->Data() == to_find); 930 | out_found = re; 931 | return re; 932 | } 933 | }; 934 | class DeleteFunctor { 935 | public: 936 | KCL_FINLINE static void Do( 937 | iterator current) { 938 | current.GetNode()->DeleteThis(); 939 | } 940 | }; 941 | KCL_FINLINE bool IsIn(WeakPointer to_find) { 942 | WeakPointer out_found = GetNullWeak(); 943 | return Search(to_find, out_found); 944 | } 945 | KCL_FINLINE bool Find(const Type & to_find, WeakPointer & out_found) { 946 | return Search(const_cast(to_find), out_found); 947 | } 948 | 949 | protected: 950 | KCL_FINLINE WeakPointer head() const {return this->first();} 951 | KCL_FINLINE WeakPointer tail() const {return this->second();} 952 | KCL_FINLINE void head(WeakPointer value) {this->first(value);} 953 | KCL_FINLINE void tail(WeakPointer value) {this->second(value);} 954 | KCL_FINLINE void IncreaseSize() {++number_elements_;} 955 | KCL_FINLINE void DecreaseSize() {--number_elements_;} 956 | KCL_FINLINE void ZeroizeSize() {number_elements_ = 0;} 957 | KCL_FINLINE void number_elements(Size value) {number_elements_ = value;} 958 | KCL_FINLINE This * GetSelfAddress() const {return ( This *)this;} 959 | KCL_FINLINE This const * GetConstSelfAddress() const {return (const This *)this;} 960 | KCL_FINLINE WeakPointer GetThisAsNode() const { return AddressToWeak( (Node*)((PairOfWeakPtr *) this) );} 961 | KCL_FINLINE WeakPointer PostEndAsWeak() const { return GetThisAsNode();} 962 | 963 | KCL_FINLINE ConstWeakPointer GetThisAsConstNode() const { return ConstCastWeakPointer( GetThisAsNode() );} 964 | KCL_FINLINE ConstWeakPointer PostEndAsConstWeak() const { return GetThisAsConstNode();} 965 | 966 | KCL_FINLINE void Assign_(StrongPointer value) { 967 | head( StrongToWeak(value) ); 968 | tail( StrongToWeak(value) ); 969 | if (value) { 970 | number_elements(1); 971 | value->UnsafeSetNext( GetThisAsNode() ); 972 | value->UnsafeSetPrevious( GetThisAsNode() ); 973 | } else { 974 | number_elements(0); 975 | } 976 | Node * debug_prev = &( * value->GetPrevious() ); KCL_USED(debug_prev); 977 | volatile Node * debug_next = &( * value->GetNext() ); KCL_USED(debug_next); 978 | Node * debug_this = &( * value); KCL_USED(debug_this); 979 | debug_next+=1; 980 | KCL_USED(debug_next); 981 | } 982 | 983 | private: 984 | Size number_elements_; 985 | }; 986 | 987 | 988 | //////////////////////////////////////////////////////////////////////////////// 989 | /// 990 | /// List::iterator 991 | /// 992 | //////////////////////////////////////////////////////////////////////////////// 993 | 994 | 995 | template 996 | class List::iterator : public List::NodeIterator { 997 | public: 998 | typedef typename List::NodeIterator Parent; 999 | iterator() : Parent::iterator() {} 1000 | iterator(const Parent & value) : Parent::iterator(value) {} 1001 | 1002 | Type const & operator*() const {return *( pointer()->Data() );} 1003 | Type & operator*() {return *pointer()->Access();} 1004 | ConstObjectPointer operator->() const {return pointer()->Data();} 1005 | ObjectPointer operator->() {return pointer()->Access();} 1006 | WeakPointer GetNode() {return pointer()->GetThis();} 1007 | ConstWeakPointer GetNode() const {return pointer()->GetThis();} 1008 | 1009 | protected: 1010 | using Parent::pointer; 1011 | }; 1012 | 1013 | template 1014 | template 1015 | KCL_FINLINE bool List::Search(ParametersTn & param, OutTn& out) { 1016 | bool re = 0; 1017 | Size n = size(); 1018 | if (!n) return re; 1019 | iterator current = begin(); 1020 | for (;n; --n) { 1021 | if (FunctorTn::Do(current, param, out)) { 1022 | re = 1; 1023 | break; 1024 | } 1025 | ++current; 1026 | } 1027 | return re; 1028 | } 1029 | 1030 | 1031 | template 1032 | template 1033 | KCL_FINLINE bool List::Search(ParametersTn & param, OutTn& out, Size start_index, Size number_elements_to_iterate) { 1034 | bool re = 0; 1035 | Size n = number_elements_to_iterate + start_index; 1036 | KCL_ASSERT(start_index + n < size() , "List::Search indexation error"); 1037 | Size begin_it = n - start_index; 1038 | if (!n) return re; 1039 | iterator current = begin(); 1040 | iterator end_it = end(); 1041 | for (;n; --n) { 1042 | KCL_ASSERT(current, "List::Search : List integrity error"); 1043 | KCL_ASSERT(current == end_it, "List::Search : List integrity error"); 1044 | if (n <= begin_it) { 1045 | if (FunctorTn::Do(current, param, out)) { 1046 | re = 1; 1047 | break; 1048 | } 1049 | } 1050 | ++current; 1051 | } 1052 | return re; 1053 | } 1054 | 1055 | template 1056 | template 1057 | KCL_FINLINE void List::DoForeach() { 1058 | Size n = size(); 1059 | if (!n) return; 1060 | iterator current = begin(); 1061 | for (;n; --n) { 1062 | Iterator next = current; 1063 | ++next; 1064 | KCL_ASSERT(current, "List::DoForeach : List integrity error"); 1065 | KCL_ASSERT(GetAddressFromPointer(current.GetNode()) != (Node*)this, "List::DoForeach(param) : List integrity error, iterator == descriptor"); 1066 | FunctorTn::Do(current); 1067 | current = next; 1068 | } 1069 | } 1070 | 1071 | template 1072 | template 1073 | KCL_FINLINE void List::DoForeach(ParamTn & param) { 1074 | Size n = size(); 1075 | if (!n) return; 1076 | iterator current = begin(); 1077 | for (;n; --n) { 1078 | Iterator next = current; 1079 | ++next; 1080 | KCL_ASSERT(current, "List::DoForeach(param) : List integrity error, iterator == null"); 1081 | KCL_ASSERT(GetAddressFromPointer(current.GetNode()) != (Node*)this, "List::DoForeach(param) : List integrity error, iterator == descriptor"); 1082 | FunctorTn::Do(current, param); 1083 | current = next; 1084 | } 1085 | } 1086 | 1087 | template 1088 | Size List::size() const { 1089 | return number_elements_; 1090 | } 1091 | 1092 | 1093 | 1094 | # endif //__cplusplus 1095 | 1096 | #endif // KC_LIBRARY_PROTECT_OFF 1097 | -------------------------------------------------------------------------------- /KC_library/KC_memory.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | 6 | 7 | //# define MAKE_USED(var) {(void)(var);} 8 | 9 | # ifndef __cplusplus 10 | # ifndef GFP_ATOMIC 11 | # define GFP_ATOMIC 0 12 | # endif // not GFP_ATOMIC 13 | enum {kAllocateFlags = GFP_ATOMIC}; 14 | # endif //NOT __cplusplus 15 | 16 | KCL_EXTERN void *KCL_Allocate_C(size_t size); 17 | KCL_EXTERN void *KCL_Rellocate_C(const void *pointer, Size new_size_in_bytes); 18 | KCL_EXTERN void KCL_FreeOrDie_C(void *p); 19 | KCL_EXTERN void SafeFree_C(void *p); 20 | KCL_EXTERN void * Allocate(Size number_of_bytes); 21 | KCL_EXTERN void DeallocateOrDie(const void * pointer); 22 | KCL_EXTERN void * Reallocate(const void *pointer, Size number_of_bytes); 23 | 24 | 25 | 26 | 27 | # ifdef __cplusplus 28 | 29 | template void Construct(Tn * address) { 30 | new (address) Tn; 31 | } 32 | 33 | template void Destruct(Tn & object) { 34 | //DiagnosticPrint(KERN_INFO "Destruct object"); 35 | object.~Tn(); 36 | } 37 | 38 | template void Destruct( KCL_POINTER(Tn) pointer) { 39 | pointer->~Tn(); 40 | } 41 | 42 | # ifdef KCL_MEMORY_DEBUG_ACCESS 43 | template KCL_POINTER(Tn) CreatePointer( Tn * address, Tn* low_limit, Tn * high_postend) { 44 | void * last_correct_byte = reinterpret_cast(high_postend) - 1; 45 | return KCL_POINTER(Tn) (address, low_limit, last_correct_byte); 46 | } 47 | 48 | template KCL_POINTER(Tn) CreatePointer(const Tn * address, const Tn* low_limit, const Tn * high_postend) { 49 | const void * last_correct_byte = reinterpret_cast(high_postend) - 1; 50 | return KCL_POINTER(Tn) ( const_cast(address), low_limit, last_correct_byte ); 51 | } 52 | 53 | template KCL_POINTER(Tn) CreatePointer( Tn * address, Tn* low_limit) { 54 | void * last_correct_byte = reinterpret_cast(low_limit) + SizeOf() - 1; 55 | return KCL_POINTER(Tn) (address, low_limit, last_correct_byte); 56 | } 57 | 58 | template KCL_POINTER(Tn) CreatePointer(const Tn * address, const Tn* low_limit) { 59 | const void * last_correct_byte = reinterpret_cast(low_limit) + SizeOf() - 1; 60 | return KCL_POINTER(Tn) ( const_cast(address), low_limit, last_correct_byte ); 61 | } 62 | # else // KCL_MEMORY_DEBUG_ACCESS 63 | 64 | template KCL_POINTER(Tn) CreatePointer( Tn * address) { 65 | return address; 66 | } 67 | 68 | template KCL_POINTER(Tn) CreatePointer(const Tn * address) { 69 | return const_cast(address); 70 | } 71 | # endif // KCL_MEMORY_DEBUG_ACCESS 72 | 73 | 74 | template Tn * GetAddressFromPointer 75 | ( KCL_POINTER(Tn) address) { 76 | # ifdef KCL_MEMORY_DEBUG_ACCESS 77 | return address.GetData(); 78 | # else // KCL_MEMORY_DEBUG_ACCESS 79 | return address; 80 | # endif // KCL_MEMORY_DEBUG_ACCESS 81 | 82 | } 83 | 84 | template const Tn * GetAddressFromPointer 85 | ( CONST_KCL_POINTER(Tn) address) { 86 | # ifdef KCL_MEMORY_DEBUG_ACCESS 87 | return address.Data(); 88 | # else // KCL_MEMORY_DEBUG_ACCESS 89 | return address; 90 | # endif // KCL_MEMORY_DEBUG_ACCESS 91 | 92 | } 93 | 94 | template CONST_KCL_POINTER(Tn) ConstCastPointer 95 | ( KCL_POINTER(Tn) address) { 96 | // ( Tn* address) { 97 | # ifdef KCL_MEMORY_DEBUG_ACCESS 98 | return address.ConstCast(); 99 | # else // KCL_MEMORY_DEBUG_ACCESS 100 | return const_cast< CONST_KCL_POINTER(Tn) >(address); 101 | # endif // KCL_MEMORY_DEBUG_ACCESS 102 | } 103 | 104 | template KCL_POINTER(Tn) UnconstCastPointer 105 | (CONST_KCL_POINTER(Tn) address) { 106 | # ifdef KCL_MEMORY_DEBUG_ACCESS 107 | return address.Unconst(); 108 | # else // KCL_MEMORY_DEBUG_ACCESS 109 | return const_cast< KCL_POINTER(Tn) >(address); 110 | # endif // KCL_MEMORY_DEBUG_ACCESS 111 | } 112 | 113 | template CONST_KCL_WEAK_POINTER(Tn) ConstCastWeakPointer 114 | (KCL_WEAK_POINTER(Tn) address) { 115 | # ifdef KCL_MEMORY_DEBUG_ACCESS 116 | return address.ConstCast(); 117 | # else // KCL_MEMORY_DEBUG_ACCESS 118 | return const_cast< CONST_KCL_WEAK_POINTER(Tn) >(address); 119 | # endif // KCL_MEMORY_DEBUG_ACCESS 120 | } 121 | 122 | template KCL_WEAK_POINTER(Tn) UnconstCastWeakPointer 123 | (CONST_KCL_WEAK_POINTER(Tn) address) { 124 | return const_cast< KCL_WEAK_POINTER(Tn) >(address); 125 | } 126 | 127 | template KCL_WEAK_POINTER(Tn) StrongToWeak ( KCL_POINTER(Tn) pointer) { 128 | return pointer; 129 | } 130 | 131 | template KCL_WEAK_POINTER(Tn) AddressToWeak ( Tn * pointer) { 132 | # ifdef KCL_MEMORY_DEBUG_ACCESS 133 | char const * high_limit = (char const *) pointer; 134 | high_limit += sizeof(Tn) - 1; 135 | return KCL_WEAK_POINTER(Tn)(pointer, pointer, high_limit); 136 | # else // KCL_MEMORY_DEBUG_ACCESS 137 | return pointer; 138 | # endif // KCL_MEMORY_DEBUG_ACCESS 139 | } 140 | 141 | template KCL_WEAK_POINTER(Tn) AddressToWeak ( Tn * pointer, Size n_valid_bytes) { 142 | # ifdef KCL_MEMORY_DEBUG_ACCESS 143 | char const * high_limit = (char const *) pointer; 144 | high_limit += n_valid_bytes; 145 | return KCL_WEAK_POINTER(Tn)(pointer, pointer, high_limit); 146 | # else // KCL_MEMORY_DEBUG_ACCESS 147 | KCL_USED(n_valid_bytes); 148 | return pointer; 149 | # endif // KCL_MEMORY_DEBUG_ACCESS 150 | } 151 | 152 | template KCL_INLINE 153 | KCL_WEAK_POINTER(Tn) GetNullWeak() { 154 | # ifdef KCL_MEMORY_DEBUG_ACCESS 155 | return KCL_WEAK_POINTER(Tn)::GetNullObject(); 156 | # else // KCL_MEMORY_DEBUG_ACCESS 157 | return static_cast(NULL); 158 | # endif // KCL_MEMORY_DEBUG_ACCESS 159 | } 160 | 161 | template KCL_INLINE 162 | CONST_KCL_WEAK_POINTER(Tn) GetNullConstWeak() { 163 | # ifdef KCL_MEMORY_DEBUG_ACCESS 164 | return CONST_KCL_WEAK_POINTER(Tn)::GetNullObject(); 165 | # else // KCL_MEMORY_DEBUG_ACCESS 166 | return static_cast(NULL); 167 | # endif // KCL_MEMORY_DEBUG_ACCESS 168 | } 169 | 170 | template KCL_INLINE 171 | KCL_POINTER(Tn) GetNullStrong() { 172 | # ifdef KCL_MEMORY_DEBUG_ACCESS 173 | return KCL_POINTER(Tn)::GetNullObject(); 174 | # else // KCL_MEMORY_DEBUG_ACCESS 175 | return static_cast(NULL); 176 | # endif // KCL_MEMORY_DEBUG_ACCESS 177 | } 178 | 179 | template KCL_INLINE 180 | CONST_KCL_POINTER(Tn) GetNullConstStrong() { 181 | # ifdef KCL_MEMORY_DEBUG_ACCESS 182 | return CONST_KCL_POINTER(Tn)::GetNullObject(); 183 | # else // KCL_MEMORY_DEBUG_ACCESS 184 | return static_cast(NULL); 185 | # endif // KCL_MEMORY_DEBUG_ACCESS 186 | } 187 | 188 | template KCL_INLINE Tn* CreateObjectInternal() { 189 | Size size = SizeOf(); 190 | Tn * address = static_cast ( KCL_ALLOCATE( size ) ); 191 | if (address) { 192 | Construct(address); 193 | } 194 | return address; 195 | } 196 | template KCL_POINTER(Tn) CreateObject() { 197 | Tn * address = CreateObjectInternal(); 198 | # ifdef KCL_MEMORY_DEBUG_ACCESS 199 | return CreatePointer(address, address); 200 | # else // KCL_MEMORY_DEBUG_ACCESS 201 | return CreatePointer(address); 202 | # endif // KCL_MEMORY_DEBUG_ACCESS 203 | } 204 | 205 | template void DeleteObject(KCL_POINTER(Tn) what_delete) { 206 | if (what_delete) { 207 | Destruct(what_delete); 208 | void * reference = static_cast( GetAddressFromPointer(what_delete) ); 209 | KCL_DEALLOCATE( const_cast( reference ) ); 210 | } 211 | } 212 | 213 | #ifdef KCL_MEMORY_DEBUG 214 | KCL_INLINE void RegisterAllocatedMemory(void * address, const Char * file, int line) { 215 | if (address == NULL) return; 216 | void * & key = address; 217 | MemoryMap::value_type val; 218 | MemoryMap::TypeInsertReturn insert_return; 219 | MemoryMap::Element & second = val.second; 220 | second.line = line; 221 | second.file = file; 222 | second.is_deleted = 0; 223 | second.address = address; 224 | val.first = key; 225 | ReadLockDebugMemoryLocker(); { 226 | bool is_new_address = g_memory_map.IsNewAddress(key); 227 | if (!is_new_address) { 228 | Char * string_buffer = (Char *) KCL_ALLOCATE(500); 229 | sprintf(string_buffer, "New object:: twice allocated address, possible heap destroyed!!! address = %p; at file = %s, line = %d; ", address, file, line); 230 | KCL_ASSERT(0, string_buffer); 231 | KCL_DEALLOCATE(string_buffer); 232 | } 233 | } UpgradeDebugMemoryLocker(); { 234 | g_memory_map.insert(val); 235 | } WriteUnlockDebugMemoryLocker(); 236 | } 237 | 238 | KCL_INLINE void UnregisterAllocatedMemory(void * address, const Char * file, int line, bool & is_correct) { 239 | is_correct = 1; 240 | if (!address) return; 241 | void * & pointer = address; 242 | MemoryMap::iterator data = (MemoryMap::iterator)NULL; 243 | 244 | ReadLockDebugMemoryLocker(); { 245 | if ( g_memory_map.count(pointer) ) { 246 | data = g_memory_map.find(pointer); 247 | bool is_deleted = data->is_deleted; 248 | if (is_deleted) { 249 | Char * string_buffer = (Char *) KCL_ALLOCATE(500); 250 | is_correct = 0; 251 | sprintf(string_buffer, "Debug memory control: double deletion!!! address = %p; at file = %s, line = %d; allocated at: file = %s, line = %d; first deleted at: file = %s, line = %d", address, file, line, data->file, data->line, data->file_of_delete, data->line_of_delete); 252 | KCL_ASSERT(0, string_buffer); 253 | KCL_DEALLOCATE(string_buffer); 254 | } else { 255 | data->file_of_delete = file; 256 | data->line_of_delete = line; 257 | } 258 | } else { 259 | Char * string_buffer = (Char *) KCL_ALLOCATE(500); 260 | is_correct = 0; 261 | KCL_ASSERT(0, string_buffer) 262 | KCL_DEALLOCATE(string_buffer); 263 | } 264 | } UpgradeDebugMemoryLocker(); { 265 | if (data != NULL) { 266 | data->is_deleted = 1; 267 | } 268 | } WriteUnlockDebugMemoryLocker(); 269 | } 270 | 271 | template KCL_POINTER(Tn) CreateObjectDebug(const Char * file, int line) { 272 | KCL_POINTER(Tn) re = CreateObject(); 273 | RegisterAllocatedMemory( GetAddressFromPointer(re), file, line); 274 | return re; 275 | } 276 | 277 | template void DeleteObjectDebug(KCL_POINTER(Tn) what_delete, const Char * file, int line) { 278 | bool allow; 279 | UnregisterAllocatedMemory( GetAddressFromPointer(what_delete), file, line, allow ); 280 | if (allow) { 281 | DeleteObject( what_delete ); 282 | } 283 | } 284 | #else // KCL_MEMORY_DEBUG 285 | #endif // KCL_MEMORY_DEBUG 286 | 287 | template 288 | KCL_POINTER(Tn_out) UpperCastPointer( KCL_POINTER(Tn_in) in) { 289 | 290 | # ifdef KCL_MEMORY_DEBUG_ACCESS 291 | return in.template UpperCast(); 292 | # else // KCL_MEMORY_DEBUG_ACCESS 293 | return (KCL_POINTER(Tn_out)) in; 294 | # endif // KCL_MEMORY_DEBUG_ACCESS 295 | } 296 | 297 | //////////////////////////////////////////////////////////////////////////////// 298 | /// StandardMemoryPolicy 299 | //////////////////////////////////////////////////////////////////////////////// 300 | template 301 | struct StandardMemoryPolicy { 302 | typedef Tn Type; 303 | typedef Allocator AllocatorType; 304 | typedef KCL_POINTER(Type) StrongPointer; 305 | typedef CONST_KCL_POINTER(Type) StrongConstPointer; 306 | typedef KCL_WEAK_POINTER(Type) WeakPointer; 307 | typedef CONST_KCL_WEAK_POINTER(Type) WeakConstPointer; 308 | 309 | KCL_FINLINE static StrongPointer GetNullStrong() {return KCL_NAMESPACE::GetNullStrong();} 310 | KCL_FINLINE static StrongPointer GetNullWeak() {return KCL_NAMESPACE::GetNullWeak();} 311 | KCL_FINLINE static StrongPointer UnconstCastPointer(StrongConstPointer p) {return KCL_NAMESPACE::UnconstCastPointer(p);} 312 | KCL_FINLINE static StrongConstPointer ConstCastPointer (StrongPointer p) {return KCL_NAMESPACE::ConstCastPointer(p);} 313 | 314 | template 315 | struct rebind { typedef StandardMemoryPolicy other; }; 316 | }; 317 | 318 | # endif //__cplusplus 319 | 320 | #endif // KC_LIBRARY_PROTECT_OFF 321 | -------------------------------------------------------------------------------- /KC_library/KC_new.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | # ifdef __cplusplus 6 | void *operator new(size_t size, void *p) throw(); 7 | # endif //__cplusplus 8 | 9 | #endif // KC_LIBRARY_PROTECT_OFF 10 | -------------------------------------------------------------------------------- /KC_library/KC_pod_array.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | # ifdef __cplusplus 6 | # define POD_ARRAY_PROTECT_OFF 7 | # include "KC_pod_array_internal.h" 8 | 9 | #define CreatePODArray(TypeOfElement, SizeOfArray, OutHandle, OutPointer) \ 10 | KCL_NAMESPACE_PERFIX CreatePODArrayInternal( \ 11 | SizeOfArray, \ 12 | OutHandle,\ 13 | OutPointer); 14 | template KCL_INLINE 15 | void CreatePODArrayInternal( 16 | Size number_elements_of_array, 17 | KCL_ARRAY_POINTER(Byte) & out_handle, 18 | PODArray *& out_pointer) { 19 | out_handle = KCL_CREATE_ARRAY(Byte, sizeof(Size)+ sizeof(TypeOfElement) * number_elements_of_array); 20 | if (out_handle) { 21 | out_pointer = reinterpret_cast< KCL_NAMESPACE_PERFIX PODArray * >( out_handle.GetMemoryBlock () ); 22 | out_pointer -> SetSize(number_elements_of_array); 23 | } else { 24 | out_pointer = 0; 25 | } 26 | } 27 | 28 | 29 | #define DeletePODArray(Handle) { KCL_DELETE_ARRAY(Handle);} 30 | #define PODArrayHandle KCL_ARRAY_POINTER(Byte) 31 | 32 | # endif //__cplusplus 33 | 34 | #endif // KC_LIBRARY_PROTECT_OFF 35 | -------------------------------------------------------------------------------- /KC_library/KC_pod_array_internal.h: -------------------------------------------------------------------------------- 1 | #ifndef POD_ARRAY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" or other 3 | #else // POD_ARRAY_PROTECT_OFF 4 | 5 | # undef POD_ARRAY_PROTECT_OFF 6 | 7 | 8 | # ifdef __cplusplus 9 | # pragma pack(push,1) 10 | 11 | template class PODArray { 12 | public: 13 | typedef Tn Element; 14 | typedef PODArray This; 15 | typedef Element * iterator; 16 | typedef const Element * const_iterator; 17 | Size size() const {return size_;} 18 | void SetSize(Size value) {size_ = value;} 19 | bool empty() const {return size() == 0;} 20 | iterator GetReference(Size index) {return data() + index;} 21 | const_iterator GetReference(Size index) const {return data() + index;} 22 | Element const & operator[](Size index) const {return data()[index];} 23 | Element & operator[](Size index) {return data()[index];} 24 | const_iterator begin() const {return data();} 25 | iterator begin() {return data();} 26 | const_iterator end() const {return GetReference( size() );} 27 | iterator end() {return GetReference( size() );} 28 | Size GetSizeof() {return GetDataOffset() + size()*sizeof(Tn);} 29 | 30 | static This * ReinterpretAsPODArray(void * what) { 31 | return static_cast(what); 32 | } 33 | 34 | protected: 35 | Element const * data() const {return data_;} 36 | Element * data() {return data_;} 37 | 38 | private: 39 | static inline Size GetDataOffset() {This * reference = (This *)NULL; return (Byte*)reference->data_ - (Byte*)reference;} 40 | PODArray() : size_(0) {} 41 | PODArray(const This &); 42 | This & operator=(const This &); 43 | 44 | Size size_; 45 | Element data_[1]; 46 | }; 47 | 48 | # pragma pack(pop) 49 | # endif //__cplusplus 50 | 51 | #endif // POD_ARRAY_PROTECT_OFF 52 | -------------------------------------------------------------------------------- /KC_library/KC_pointers.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | #ifdef __cplusplus 6 | 7 | template class BasePointer; 8 | template class BaseConstPointer; 9 | template class SafePointer; 10 | template class SafeConstPointer; 11 | 12 | namespace internal { 13 | //////////////////////////////////////////////////////////////////////////////// 14 | 15 | template< class T > struct DereferenceTypeFor 16 | { 17 | typedef T & type; 18 | }; 19 | template<> struct DereferenceTypeFor< void > 20 | { 21 | typedef void type; 22 | }; 23 | template<> struct DereferenceTypeFor< void const > 24 | { 25 | typedef void type; 26 | }; 27 | template<> struct DereferenceTypeFor< void volatile > 28 | { 29 | typedef void type; 30 | }; 31 | template<> struct DereferenceTypeFor< void const volatile > 32 | { 33 | typedef void type; 34 | }; 35 | 36 | template< class T > struct DereferenceTypeFor< T[] > 37 | { 38 | typedef void type; 39 | }; 40 | template< class T, Size N > struct DereferenceTypeFor< T[N] > 41 | { 42 | typedef void type; 43 | }; 44 | 45 | template< class T > struct AccessTypeFor 46 | { 47 | typedef T * type; 48 | }; 49 | 50 | template< class T > struct AccessTypeFor< T[] > 51 | { 52 | typedef void type; 53 | }; 54 | 55 | template< class T, Size N > struct AccessTypeFor< T[N] > 56 | { 57 | typedef void type; 58 | }; 59 | 60 | 61 | //////////////////////////////////////////////////////////////////////////////// 62 | } // internal namespace 63 | 64 | template class AbstractBasePointer { 65 | public: 66 | typedef Tn Type; 67 | typedef AbstractBasePointer ThisT; 68 | typedef BaseConstPointer ConstPointerT; 69 | AbstractBasePointer(const ThisT& value) : pointer_(value.pointer_) {} 70 | AbstractBasePointer() : pointer_((Type*)NULL) {} 71 | explicit AbstractBasePointer(Type * value) : pointer_(value) { 72 | } 73 | explicit AbstractBasePointer(int value) : pointer_((Type*)value) { 74 | KCL_ASSERT(value == 0, "BasePointer constructor: not null integer assigment"); 75 | } 76 | KCL_FINLINE ThisT & operator=(int value); 77 | KCL_FINLINE ThisT & operator=(Type * value); 78 | 79 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 80 | KCL_FINLINE ConstPointerT ConstCast() const {return ConstPointerT( get_pointer() ); } 81 | template KCL_FINLINE BasePointer UpperCast() {return BasePointer((ToCast*)get_pointer());} 82 | template static KCL_FINLINE BasePointer UpperCast(ThisT& from_cast) {return BasePointer( (ToCast*)from_cast.get_pointer());} 83 | 84 | KCL_FINLINE Type * operator->() const {return get_pointer();} 85 | KCL_FINLINE Type * operator[](int index) const {return get_pointer()[index];} 86 | 87 | KCL_FINLINE operator bool() const { 88 | return pointer() != NULL; 89 | } 90 | 91 | KCL_FINLINE bool operator==(Type * value) const; 92 | KCL_FINLINE bool operator!=(Type * value) const; 93 | KCL_FINLINE bool operator==(const ThisT & value) const; 94 | KCL_FINLINE bool operator!=(const ThisT & value) const; 95 | 96 | KCL_FINLINE Type const * Data() const {return pointer();} 97 | KCL_FINLINE Type * GetData() {return get_pointer();} 98 | 99 | protected: 100 | template friend class AbstractSafePointer; 101 | KCL_FINLINE Type const * pointer() const {return pointer_;} 102 | KCL_FINLINE Type * get_pointer() const {return pointer_;} 103 | KCL_FINLINE void pointer(Type * value) {pointer_ = value;} 104 | 105 | private: 106 | Type * pointer_; 107 | }; 108 | 109 | template <> class BasePointer : public AbstractBasePointer { 110 | }; 111 | 112 | template class BasePointer : public AbstractBasePointer { 113 | public: 114 | typedef Tn Type; 115 | typedef BasePointer ThisT; 116 | typedef BaseConstPointer ConstPointerT; 117 | typedef AbstractBasePointer Parent; 118 | KCL_FINLINE BasePointer(const ThisT& value) : Parent(value) {} 119 | KCL_FINLINE BasePointer() : Parent((Type*)NULL) {} 120 | KCL_FINLINE explicit BasePointer(Type * value) : Parent(value) {} 121 | KCL_FINLINE explicit BasePointer(void * value) : Parent((Type*)value) {} 122 | KCL_FINLINE explicit BasePointer(int value) : Parent((Type*)value) { } 123 | 124 | KCL_FINLINE ThisT & operator=(void * value); 125 | KCL_FINLINE Type & operator*() const {return *get_pointer();} 126 | KCL_FINLINE bool operator==(void * value) const; 127 | KCL_FINLINE bool operator!=(void * value) const; 128 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 129 | 130 | protected: 131 | using Parent::get_pointer; 132 | using Parent::pointer; 133 | }; 134 | 135 | template class AbstractBaseConstPointer : public AbstractBasePointer { 136 | public: 137 | typedef Tn Type; 138 | typedef AbstractBaseConstPointer ThisT; 139 | typedef AbstractBasePointer ParentT; 140 | typedef BasePointer PointerT; 141 | 142 | KCL_FINLINE AbstractBaseConstPointer(const ThisT& value) : ParentT(value) {} 143 | KCL_FINLINE AbstractBaseConstPointer() : ParentT() {} 144 | KCL_FINLINE explicit AbstractBaseConstPointer(Type * value) : ParentT(value) {} 145 | KCL_FINLINE ThisT& operator=(void * value) {return static_cast ( ParentT::operator=((Type*)value) );} 146 | KCL_FINLINE ThisT& operator=(const ThisT & value) {return operator=( value.get_pointer() );} 147 | 148 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 149 | KCL_FINLINE PointerT Unconst() const {return PointerT (get_pointer());} 150 | template KCL_FINLINE AbstractBaseConstPointer UpperCast() {return AbstractBaseConstPointer( (ToCast*)get_pointer());} 151 | template static KCL_FINLINE AbstractBaseConstPointer UpperCast(ThisT& from_cast) {return AbstractBaseConstPointer( (ToCast*)from_cast.get_pointer());} 152 | 153 | 154 | KCL_FINLINE Type const * operator->() const {return pointer();} 155 | KCL_FINLINE Type const * operator[](int index) const {return pointer()[index];} 156 | 157 | protected: 158 | using ParentT::get_pointer; 159 | using ParentT::pointer; 160 | 161 | private: 162 | template friend class AbstractSafeConstPointer; 163 | template friend class BaseConstPointer; 164 | 165 | Type * GetData() ; 166 | }; 167 | 168 | 169 | template <> class BaseConstPointer : public AbstractBaseConstPointer { 170 | public: 171 | typedef void Type; 172 | typedef BaseConstPointer ThisT; 173 | typedef AbstractBaseConstPointer ParentT; 174 | typedef BasePointer PointerT; 175 | KCL_FINLINE explicit BaseConstPointer(void * value) : ParentT(value) {} 176 | }; 177 | 178 | 179 | template class BaseConstPointer : public AbstractBaseConstPointer { 180 | public: 181 | typedef Tn Type; 182 | typedef BaseConstPointer ThisT; 183 | typedef AbstractBaseConstPointer ParentT; 184 | typedef BasePointer PointerT; 185 | 186 | KCL_FINLINE BaseConstPointer(const ThisT& value) : ParentT(value) {} 187 | KCL_FINLINE BaseConstPointer() : ParentT() {} 188 | KCL_FINLINE explicit BaseConstPointer(Type * value) : ParentT(value) {} 189 | KCL_FINLINE explicit BaseConstPointer(void * value) : ParentT((Type*)value) {} 190 | KCL_FINLINE ThisT& operator=(void * value) {return static_cast ( ParentT::operator=((Type*)value) );} 191 | KCL_FINLINE ThisT& operator=(const ThisT & value) {return operator=( value.get_pointer() );} 192 | 193 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 194 | using ParentT::Unconst; 195 | using ParentT::UpperCast; 196 | 197 | KCL_FINLINE Type const & operator*() const {return * pointer();} 198 | 199 | protected: 200 | using ParentT::get_pointer; 201 | using ParentT::pointer; 202 | }; 203 | 204 | class PointerRangeEnums { 205 | public: 206 | enum ErrorsEnum { 207 | kNoError = 0, 208 | kErrorNull = 1, 209 | kErrorOverwrite = 2, 210 | kErrorUnderwrite = 3, 211 | kErrorNumber, 212 | kErrorPostEnd =kErrorNumber , 213 | kErrorLimit = kErrorPostEnd - 1 214 | } ; 215 | enum OperatorsEnum { 216 | kOperatorDereferencing = 0, 217 | kOperatorAccess = 1, 218 | kOperatorIndexation = 2, 219 | kOperatorNumber, 220 | kOperatorLimit = kOperatorNumber -1 221 | }; 222 | }; 223 | 224 | template class PointerRange : public PointerRangeEnums { 225 | public: 226 | typedef Tn Type; 227 | typedef PointerRange ThisT; 228 | typedef PointerRangeEnums Enums; 229 | using Enums::ErrorsEnum; 230 | using Enums::OperatorsEnum; 231 | KCL_FINLINE PointerRange(const void * low_limit_arg, const void * high_limit_arg) 232 | : low_limit_(low_limit_arg), 233 | high_limit_(high_limit_arg) {} 234 | 235 | protected: 236 | bool KCL_FINLINE Verify(const Tn * pointer_arg, Size & out_error_code) const; 237 | bool KCL_FINLINE Verify(const Tn * pointer_arg, Size length_in_bytes, Size & out_error_code) const; 238 | 239 | KCL_FINLINE void const * low_limit() const {return low_limit_;} 240 | KCL_FINLINE void * get_low_limit() const {return (void *)low_limit_;} 241 | KCL_FINLINE void low_limit(void * value) {low_limit_ = value;} 242 | KCL_FINLINE void const * high_limit() const {return high_limit_;} 243 | KCL_FINLINE void * get_high_limit() const {return (void *)high_limit_;} 244 | KCL_FINLINE void high_limit(void * value) {high_limit_ = value;} 245 | 246 | private: 247 | const void * low_limit_; 248 | const void * high_limit_; 249 | }; 250 | 251 | template class AbstractSafePointer 252 | : public BasePointer, 253 | protected PointerRange 254 | { 255 | public: 256 | typedef Tn Type; 257 | typedef AbstractSafePointer ThisT; 258 | typedef BasePointer ParentT; 259 | typedef PointerRange RangeT; 260 | typedef SafeConstPointer ConstPointerT; 261 | typedef typename RangeT::ErrorsEnum ErrorsEnum; 262 | typedef typename RangeT::OperatorsEnum OperatorsEnum; 263 | using ParentT::operator bool; 264 | using ParentT::operator==; 265 | using ParentT::operator!=; 266 | using ParentT::GetData; 267 | 268 | KCL_FINLINE AbstractSafePointer( 269 | Type * pointer_arg, 270 | const void * low_limit_arg, 271 | const void * high_limit_arg) 272 | : ParentT(pointer_arg), 273 | RangeT(low_limit_arg, high_limit_arg) { 274 | } 275 | KCL_FINLINE AbstractSafePointer(const ThisT& value) 276 | : ParentT(value.get_pointer()), 277 | RangeT(value.get_low_limit(), value.get_high_limit()) { 278 | } 279 | KCL_FINLINE ThisT& operator=(const ThisT& value); 280 | 281 | KCL_FINLINE Type const * operator->() const; 282 | KCL_FINLINE Type * operator->(); 283 | KCL_FINLINE Type * operator[](int index); 284 | 285 | 286 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 287 | KCL_FINLINE ConstPointerT ConstCast() const {return ConstPointerT( get_pointer() , get_low_limit(), get_high_limit() ); } 288 | template KCL_FINLINE AbstractSafePointer UpperCast() {return AbstractSafePointer( (ToCast*)get_pointer(), get_low_limit(), get_high_limit());} 289 | template static KCL_FINLINE AbstractSafePointer UpperCast(ThisT& from_cast) {return AbstractSafePointer( (ToCast*)from_cast.get_pointer(), from_cast.get_low_limit(), from_cast.get_high_limit());} 290 | 291 | protected: 292 | KCL_FINLINE AbstractSafePointer() : ParentT((void*)NULL), RangeT(NULL, NULL) { 293 | return; 294 | } 295 | 296 | using ParentT::pointer; 297 | using ParentT::get_pointer; 298 | using RangeT::Verify; 299 | using RangeT::get_low_limit; 300 | using RangeT::low_limit; 301 | using RangeT::get_high_limit; 302 | using RangeT::high_limit; 303 | KCL_FINLINE bool Verify(Size & out_error_code) const {return this->Verify(pointer(),out_error_code);} 304 | 305 | private: 306 | }; 307 | 308 | 309 | template class AbstractSafeConstPointer 310 | : public AbstractBaseConstPointer, 311 | protected PointerRange { 312 | public: 313 | typedef Tn Type; 314 | typedef AbstractSafeConstPointer ThisT; 315 | typedef AbstractBaseConstPointer ParentT; 316 | typedef PointerRange RangeT; 317 | typedef AbstractSafePointer PointerT; 318 | typedef typename RangeT::ErrorsEnum ErrorsEnum; 319 | typedef typename RangeT::OperatorsEnum OperatorsEnum; 320 | using ParentT::operator bool; 321 | using ParentT::Data; 322 | 323 | KCL_FINLINE AbstractSafeConstPointer( 324 | Type * pointer_arg, 325 | const void * low_limit_arg, 326 | const void * high_limit_arg) 327 | : ParentT(pointer_arg), 328 | RangeT(low_limit_arg, high_limit_arg) {} 329 | KCL_FINLINE AbstractSafeConstPointer(const ThisT& value) 330 | : ParentT((Type*)value.get_pointer()), 331 | RangeT(value.get_low_limit(), value.get_high_limit()) {} 332 | KCL_FINLINE ThisT& operator=(const ThisT& value); 333 | 334 | 335 | KCL_FINLINE Type const * operator->() const; 336 | KCL_FINLINE Type const * operator[](int index) const; 337 | 338 | 339 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 340 | KCL_FINLINE PointerT Unconst() const {return PointerT (get_pointer() , get_low_limit(), get_high_limit() );} 341 | template KCL_FINLINE AbstractSafeConstPointer UpperCast() {return AbstractSafeConstPointer( (ToCast*)get_pointer(), get_low_limit(), get_high_limit());} 342 | template static KCL_FINLINE AbstractSafeConstPointer UpperCast(ThisT& from_cast) {return AbstractSafeConstPointer( (ToCast*)from_cast.get_pointer(), from_cast.get_low_limit(), from_cast.get_high_limit());} 343 | 344 | protected: 345 | KCL_FINLINE AbstractSafeConstPointer() : ParentT( ParentT::GetNullObject() ), RangeT(NULL, NULL) { 346 | } 347 | 348 | using ParentT::pointer; 349 | using ParentT::get_pointer; 350 | using RangeT::Verify; 351 | using RangeT::get_low_limit; 352 | using RangeT::low_limit; 353 | using RangeT::get_high_limit; 354 | using RangeT::high_limit; 355 | bool Verify(Size & out_error_code) const {return this->Verify(pointer(),out_error_code);} 356 | 357 | private: 358 | }; 359 | 360 | 361 | template <> class SafePointer 362 | : public AbstractSafePointer { 363 | }; 364 | 365 | template class SafePointer 366 | : public AbstractSafePointer 367 | { 368 | public: 369 | typedef Tn Type; 370 | typedef SafePointer ThisT; 371 | typedef AbstractSafePointer ParentT; 372 | typedef PointerRange RangeT; 373 | typedef SafeConstPointer ConstPointerT; 374 | typedef typename RangeT::ErrorsEnum ErrorsEnum; 375 | typedef typename RangeT::OperatorsEnum OperatorsEnum; 376 | using ParentT::operator bool; 377 | using ParentT::operator==; 378 | using ParentT::operator!=; 379 | using ParentT::GetData; 380 | 381 | KCL_FINLINE SafePointer() : ParentT() {} ///@debug после отладки перенести в protected 382 | KCL_FINLINE SafePointer( 383 | Type * pointer_arg, 384 | const void * low_limit_arg, 385 | const void * high_limit_arg) 386 | : ParentT(pointer_arg, low_limit_arg, high_limit_arg) {} 387 | SafePointer(const ThisT& value) 388 | : ParentT(value) { 389 | static volatile int debug_x = 0; /// @debug 390 | ++debug_x; /// @debug 391 | } 392 | 393 | 394 | KCL_FINLINE ThisT& operator=(const ThisT & value) { 395 | return static_cast( ParentT::operator=( static_cast(value) ) ); 396 | } 397 | 398 | KCL_FINLINE bool operator!=(const ThisT & arg) const {return AbstractBasePointer::operator !=( (AbstractBasePointer&)arg );} 399 | KCL_FINLINE bool operator==(const ThisT & arg) const {return AbstractBasePointer::operator ==( (AbstractBasePointer&)arg );} 400 | 401 | KCL_FINLINE Type const & operator*() const; 402 | KCL_FINLINE Type & operator*(); 403 | KCL_FINLINE Type & operator[](int index); 404 | 405 | 406 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 407 | using ParentT::ConstCast; 408 | using ParentT::UpperCast; 409 | 410 | protected: 411 | 412 | using ParentT::pointer; 413 | using ParentT::get_pointer; 414 | using RangeT::Verify; 415 | using RangeT::get_low_limit; 416 | using RangeT::low_limit; 417 | using RangeT::get_high_limit; 418 | using RangeT::high_limit; 419 | KCL_FINLINE bool Verify(Size & out_error_code) const {return this->Verify(pointer(),out_error_code);} 420 | 421 | private: 422 | }; 423 | 424 | template <> class SafeConstPointer 425 | : public AbstractSafeConstPointer { 426 | }; 427 | 428 | template class SafeConstPointer 429 | : public AbstractSafeConstPointer { 430 | public: 431 | typedef Tn Type; 432 | typedef SafeConstPointer ThisT; 433 | typedef AbstractSafeConstPointer ParentT; 434 | typedef PointerRange RangeT; 435 | typedef SafePointer PointerT; 436 | typedef typename RangeT::ErrorsEnum ErrorsEnum; 437 | typedef typename RangeT::OperatorsEnum OperatorsEnum; 438 | using ParentT::operator bool; 439 | KCL_FINLINE bool operator!=(const ThisT & arg) const {return AbstractBasePointer::operator !=( (AbstractBasePointer&)arg );} 440 | KCL_FINLINE bool operator==(const ThisT & arg) const {return AbstractBasePointer::operator ==( (AbstractBasePointer&)arg );} 441 | using ParentT::Data; 442 | 443 | KCL_FINLINE SafeConstPointer( 444 | Type * pointer_arg, 445 | const void * low_limit_arg, 446 | const void * high_limit_arg) 447 | : ParentT(pointer_arg, low_limit_arg, high_limit_arg) {} 448 | KCL_FINLINE SafeConstPointer(const ThisT& value) 449 | : ParentT(value) {} 450 | 451 | KCL_FINLINE ThisT& operator=(const ThisT & value) {return static_cast( ParentT::operator=( static_cast(value) ) );} 452 | 453 | KCL_FINLINE Type const & operator*() const; 454 | KCL_FINLINE Type const & operator[](int index) const; 455 | 456 | 457 | KCL_FINLINE static ThisT GetNullObject() {return ThisT();} 458 | using ParentT::Unconst; 459 | using ParentT::UpperCast; 460 | 461 | protected: 462 | KCL_FINLINE SafeConstPointer() : ParentT( ) { 463 | } 464 | 465 | using ParentT::pointer; 466 | using ParentT::get_pointer; 467 | using RangeT::Verify; 468 | using RangeT::get_low_limit; 469 | using RangeT::low_limit; 470 | using RangeT::get_high_limit; 471 | using RangeT::high_limit; 472 | KCL_FINLINE bool Verify(Size & out_error_code) const {return this->Verify(pointer(),out_error_code);} 473 | 474 | private: 475 | }; 476 | 477 | template 478 | typename AbstractBasePointer::ThisT & AbstractBasePointer::operator=(int value) { 479 | KCL_ASSERT(value == 0, "BasePointer::operartor= assigment not null integer!!!"); 480 | pointer((Type*)value); 481 | } 482 | 483 | template 484 | typename BasePointer::ThisT & BasePointer::operator=(void * value) { 485 | pointer((Type*)value); 486 | } 487 | 488 | template 489 | typename AbstractBasePointer::ThisT & AbstractBasePointer::operator=(Type * value) { 490 | pointer(value); 491 | } 492 | 493 | template 494 | bool AbstractBasePointer::operator==(Type * value) const { 495 | return pointer() == (const Type *)value; 496 | } 497 | 498 | template 499 | bool AbstractBasePointer::operator!=(Type * value) const { 500 | return pointer() != (const Type *)value; 501 | } 502 | 503 | template 504 | bool AbstractBasePointer::operator==(const ThisT & value) const { 505 | return pointer() == value.pointer(); 506 | } 507 | 508 | template 509 | bool AbstractBasePointer::operator!=(const ThisT & value) const { 510 | return pointer() != value.pointer(); 511 | } 512 | 513 | template 514 | bool inline PointerRange::Verify(const Type * pointer_arg, Size & out_error_code) const { 515 | return Verify(pointer_arg, sizeof(Tn), out_error_code); 516 | } 517 | 518 | template 519 | bool inline PointerRange::Verify(const Tn * pointer_arg, Size length_in_bytes, Size & out_error_code) const { 520 | const Byte * data_limit = reinterpret_cast(pointer_arg) + length_in_bytes - 1; 521 | if ( pointer_arg == (Type*)NULL ) { 522 | DiagnosticPrint(KERN_EMERG "null pointer dereferencing: pointer = %p, dn = %p, up = %p, size = %lu, up-dn = %lu, data_last_byte = %p, size_parameter = %lu", pointer_arg, low_limit(), high_limit(), KCL_NAMESPACE_PERFIX SizeOf(), (Byte*)high_limit() - (Byte*)low_limit(), data_limit, length_in_bytes ); 523 | out_error_code = kErrorNull; 524 | return 0; 525 | } 526 | KCL_ASSERT(high_limit() >= low_limit(), "PointerRange/AbstractSafePointer: Integrity Error!!! Pointer destroyed"); 527 | if ( data_limit < (Byte *)pointer_arg ) { 528 | DiagnosticPrint(KERN_EMERG "overflow: ( finish out of address space ) pointer = %p, dn = %p, up = %p, size = %lu, up-dn = %lu, data_last_byte = %p, size_parameter = %lu", pointer_arg, low_limit(), high_limit(), KCL_NAMESPACE_PERFIX SizeOf(), (Byte*)high_limit() - (Byte*)low_limit(), data_limit, length_in_bytes ); 529 | out_error_code = kErrorOverwrite; 530 | return 0; 531 | } 532 | if ( pointer_arg > high_limit() ) { 533 | DiagnosticPrint(KERN_EMERG "overwrite: pointer = %p, dn = %p, up = %p, size = %lu, up-dn = %lu", pointer_arg, low_limit(), high_limit(), KCL_NAMESPACE_PERFIX SizeOf(), (Byte*)high_limit() - (Byte*)low_limit() ); 534 | out_error_code = kErrorOverwrite; 535 | return 0; 536 | } 537 | if ( pointer_arg < low_limit() ) { 538 | DiagnosticPrint(KERN_EMERG "underwrite: ( begin out of range ) pointer = %p, dn = %p, up = %p, size = %lu, up-dn = %lu", pointer_arg, low_limit(), high_limit(), KCL_NAMESPACE_PERFIX SizeOf(), (Byte*)high_limit() - (Byte*)low_limit() ); 539 | out_error_code = kErrorUnderwrite; 540 | return 0; 541 | } 542 | if ( data_limit > (Byte *)high_limit() ) { 543 | DiagnosticPrint(KERN_EMERG "overwrite: ( finish out of range ) pointer = %p, dn = %p, up = %p, size = %lu, up-dn = %lu, data_last_byte = %p, size_parameter = %lu", pointer_arg, low_limit(), high_limit(), KCL_NAMESPACE_PERFIX SizeOf(), (Byte*)high_limit() - (Byte*)low_limit(), data_limit, length_in_bytes ); 544 | out_error_code = kErrorOverwrite; 545 | return 0; 546 | } 547 | out_error_code = kNoError; 548 | return 1; 549 | } 550 | 551 | template 552 | typename AbstractSafePointer::ThisT& 553 | AbstractSafePointer::operator=(const ThisT& value) { 554 | new (this) AbstractSafePointer(value); 555 | return *this; 556 | } 557 | 558 | template 559 | typename AbstractSafeConstPointer::ThisT& 560 | AbstractSafeConstPointer::operator=(const ThisT& value) { 561 | new (this) AbstractSafeConstPointer(value); 562 | return *this; 563 | } 564 | 565 | 566 | template 567 | typename SafePointer::Type & SafePointer::operator*() { 568 | Size error; 569 | if ( Verify(error) ) { 570 | return *get_pointer(); 571 | } else { 572 | DiagnosticPrint(KERN_EMERG "error = %lu", error); 573 | KCL_ASSERT(0, GetErrorTextForSafePointers(error, RangeT::kOperatorDereferencing) ); 574 | return *( KCL_CREATE_OBJECT(Type).get_pointer() ); 575 | } 576 | } 577 | 578 | template 579 | typename SafePointer::Type const & SafePointer::operator*() const { 580 | return const_cast< SafePointer *> (this) -> operator*(); 581 | } 582 | 583 | template 584 | typename AbstractSafePointer::Type * AbstractSafePointer::operator->() { 585 | Size error; 586 | if ( Verify(error) ) { 587 | return get_pointer(); 588 | } else { 589 | DiagnosticPrint(KERN_EMERG "error = %lu, operator N = %d, er_lim = %lu, op_num = %lu.", error, RangeT::kOperatorAccess, (Size)PointerRangeEnums::kErrorLimit, (Size)PointerRangeEnums::kOperatorNumber); 590 | KCL_ASSERT(0, GetErrorTextForSafePointers(error, RangeT::kOperatorAccess) ); 591 | return GetAddressFromPointer(KCL_CREATE_OBJECT(Type)); 592 | } 593 | } 594 | 595 | template 596 | typename SafePointer::Type & SafePointer::operator[](int index) { 597 | Size error; 598 | if ( Verify(error) ) { 599 | return get_pointer(); 600 | } else { 601 | KCL_ASSERT(0, GetErrorTextForSafePointers(error, RangeT::kOperatorIndexation) ); 602 | return KCL_CREATE_OBJECT(Type); 603 | } 604 | ; 605 | } 606 | 607 | 608 | template 609 | const typename SafeConstPointer::Type & SafeConstPointer::operator*() const { 610 | Size error; 611 | if ( Verify(error) ) { 612 | return *get_pointer(); 613 | } else { 614 | KCL_ASSERT(0, GetErrorTextForSafePointers(error, RangeT::kOperatorDereferencing) ); 615 | return *KCL_CREATE_OBJECT(Type); 616 | } 617 | } 618 | 619 | template 620 | const typename AbstractSafeConstPointer::Type * AbstractSafeConstPointer::operator->() const { 621 | Size error; 622 | if ( Verify(error) ) { 623 | return get_pointer(); 624 | } else { 625 | KCL_ASSERT(0, GetErrorTextForSafePointers(error, RangeT::kOperatorAccess) ); 626 | return GetAddressFromPointer(KCL_CREATE_OBJECT(Type)); 627 | } 628 | } 629 | 630 | template 631 | const typename AbstractSafeConstPointer::Type * AbstractSafeConstPointer::operator[](int index) const { 632 | Size error; 633 | if ( Verify(error) ) { 634 | return get_pointer(); 635 | } else { 636 | KCL_ASSERT(0, GetErrorTextForSafePointers(error, RangeT::kOperatorIndexation) ); 637 | return KCL_CREATE_OBJECT(Type); 638 | } 639 | ; 640 | } 641 | 642 | #endif // __cplusplus 643 | 644 | #endif // KC_LIBRARY_PROTECT_OFF 645 | -------------------------------------------------------------------------------- /KC_library/KC_random.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | typedef long RandInteger; 6 | 7 | 8 | KCL_EXTERN RandInteger * GetKCLDummy_C(void); 9 | KCL_EXTERN UInteger64 GetTimeInNano_C(void); 10 | 11 | # ifdef __cplusplus 12 | 13 | KCL_HEADER_DEFINITION UInteger64 GetTimeInNano() { 14 | return GetTimeInNano_C(); 15 | } 16 | 17 | KCL_HEADER_DEFINITION RandInteger & GetDummy() { 18 | return *GetKCLDummy_C(); 19 | } 20 | 21 | enum { 22 | NTAB = 32, 23 | NWUP = 8, 24 | IA = 16807, 25 | IM = 2147483647, 26 | IQ = 12773, 27 | IR = 2836, 28 | NDIV = (1+(IM-1)/NTAB) 29 | }; 30 | 31 | /// @brief L'Ecuyer PRNG - алгоритм генерации псевдослучайных чисел имени L'Ecuyer 32 | KCL_HEADER_DEFINITION RandInteger GetRandom(void) { 33 | int j; 34 | long k; 35 | static long iy=0,iv[NTAB]; 36 | if ( GetDummy() <= 0 || !iy ) { // initialize 37 | if( GetDummy() < 0 ) { 38 | GetDummy() = - GetDummy(); //avoid negative or zero seed 39 | } else { 40 | if ( GetDummy() == 0 ) GetDummy() = 1; 41 | for (j = NTAB + NWUP - 1; j >= 0; j--) { //after NWUP warmups, initialize shuffle table 42 | k = GetDummy() / IQ; 43 | if ( (GetDummy() = IA * (GetDummy() - k * IQ) - IR * k) < 0 ) GetDummy() += IM; 44 | if (j < NTAB) iv[j] = GetDummy(); 45 | } 46 | } 47 | iy = iv[0]; //first specimen from the table 48 | } 49 | k = GetDummy()/IQ; //regular work: generate new number 50 | GetDummy() = IA * ( GetDummy() - k * IQ ) - IR * k; 51 | if ( GetDummy() < 0 ) { 52 | GetDummy() += IM; 53 | } 54 | //shuffle output 55 | j = iy / NDIV; 56 | iy = iv[j]; 57 | iv[j] = GetDummy(); 58 | return iy; 59 | } 60 | 61 | # else //__cplusplus 62 | KCL_EXTERN RandInteger GetRandom(void); 63 | # endif //__cplusplus 64 | 65 | #endif // KC_LIBRARY_PROTECT_OFF 66 | -------------------------------------------------------------------------------- /KC_library/KC_string.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | 6 | # ifdef __cplusplus 7 | 8 | Size MemoryLength(const void * pointer); 9 | 10 | ///@brief null-terminated string 11 | /// @warning класс должен быть легким, так как используется для вывода ошибок. Никаких сложных указателей!!! 12 | class String { 13 | public: 14 | enum {kTerminator = 0, kTerminatorSize = 1}; 15 | typedef Char CharType; 16 | typedef String This; 17 | String() : data_(NULL), size_(0), is_owner_(0) {} 18 | CharType * c_str() {return data();} 19 | void operator+=(const CharType * to_add) {Append_( to_add, MemoryLength( reinterpret_cast(to_add) ) );} 20 | Size length() const {return size();} 21 | static This MakeReference(const CharType *string); 22 | 23 | protected: 24 | void Append_(const CharType * to_add, Size number_chars_to_add); 25 | String(const This &); 26 | This & operator=(const This &); 27 | bool IsNull() {return !data_;} 28 | void Resize_(Size new_size); 29 | static CharType * MakeData_(Size new_size); 30 | void MakeDataForThis_(Size new_size); 31 | static void DeleteData_(CharType * pointer); 32 | void DeleteDataForThis_(); 33 | 34 | CharType * data() const {return data_;} 35 | void data(CharType *value) {data_ = value;} 36 | Size size() const {return size_;} 37 | void size(Size value) {size_ = value;} 38 | bool is_owner() const {return is_owner_;} 39 | void is_owner(bool value) {is_owner_ = value;} 40 | 41 | private: 42 | CharType * data_; 43 | Size size_; 44 | bool is_owner_; 45 | }; 46 | 47 | 48 | # endif //__cplusplus 49 | 50 | #endif // KC_LIBRARY_PROTECT_OFF 51 | -------------------------------------------------------------------------------- /KC_library/KC_types.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | # ifdef KCL_NO_KERNEL 5 | # include 6 | # endif // KCL_NO_KERNEL 7 | 8 | # ifdef KCL_SEPARATE_COMPILE_FOR_LINUX_KERNEL 9 | //C-standard like types 10 | typedef unsigned char uint8_t; 11 | typedef unsigned short uint16_t; 12 | typedef unsigned int uint32_t; 13 | typedef long long unsigned int uint64_t; 14 | typedef signed char int8_t; 15 | typedef signed char int16_t; 16 | typedef signed char int32_t; 17 | typedef long long signed int int64_t; 18 | typedef long unsigned int size_t; 19 | typedef signed long ptrdiff_t; 20 | # endif 21 | 22 | #define Debug_KGTypes 23 | //Google-Style types 24 | typedef size_t Size; 25 | typedef char Char; 26 | typedef uint8_t Byte; 27 | typedef uint8_t UInteger8; 28 | typedef uint16_t UInteger16; 29 | typedef uint32_t UInteger32; 30 | typedef uint64_t UInteger64; 31 | typedef uint8_t Integer8; 32 | typedef uint16_t Integer16; 33 | typedef uint32_t Integer32; 34 | typedef uint64_t Integer64; 35 | typedef ptrdiff_t PointerDifference; 36 | 37 | # ifndef __cplusplus 38 | # ifndef bool 39 | # ifdef KCL_NO_KERNEL 40 | typedef uint8_t bool; 41 | # endif //KCL_NO_KERNEL 42 | # endif //ifndef bool 43 | # endif //not __cplusplus 44 | 45 | #endif // KC_LIBRARY_PROTECT_OFF 46 | -------------------------------------------------------------------------------- /KC_library/KC_vector.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | # ifdef KCL_MEMORY_DEBUG 6 | # define KCL_CREATE_ARRAY(ObjectType, number_elements) KCL_NAMESPACE_PERFIX CreateArrayDebug(number_elements, __FILE__, __LINE__) 7 | # define KCL_DELETE_ARRAY(pointer) KCL_NAMESPACE_PERFIX DeleteArrayDebug(pointer, __FILE__, __LINE__) 8 | # else // KCL_MEMORY_DEBUG 9 | # define KCL_CREATE_ARRAY(ObjectType, number_elements) KCL_NAMESPACE_PERFIX CreateArray(number_elements) 10 | # define KCL_DELETE_ARRAY(pointer) KCL_NAMESPACE_PERFIX DeleteArray(pointer) 11 | # endif // KCL_MEMORY_DEBUG 12 | 13 | # ifdef KCL_MEMORY_DEBUG 14 | # else // KCL_MEMORY_DEBUG 15 | # endif // KCL_MEMORY_DEBUG 16 | 17 | # ifdef __cplusplus 18 | 19 | template class ArrayPointer; 20 | template ArrayPointer CreateArray(Size number_elements); 21 | template void DeleteArray(ArrayPointer what_delete); 22 | 23 | //@class ArrayPointer 24 | 25 | #pragma pack(push,1) 26 | template class ArrayPointer { 27 | public: 28 | typedef Tn Type; 29 | typedef ArrayPointer ThisT; 30 | 31 | ArrayPointer() : data_((Byte*)NULL) {} 32 | Size number_elements() const { 33 | return byte_ptr() ? ( *static_cast( block_address() ) ) : (0) ;} 34 | Type const * data() const { return reinterpret_cast(data_); } 35 | Type * data() { return reinterpret_cast(data_); } 36 | void Set(void * new_data) {data_ = new_data;} 37 | Type const * operator+(int index) const {return data() + index;} 38 | Type * operator+(int index) {return data() + index;} 39 | Type const * operator+(Size index) const {return data() + index;} 40 | Type * operator+(Size index) {return data() + index;} 41 | Type const & operator[](int index) const {return data()[index];} 42 | Type const * operator*() const {return data();} 43 | Type * operator*() {return data();} 44 | operator bool() {return data() != NULL; } 45 | void * GetMemoryBlock() {return block_address();} 46 | 47 | 48 | protected: 49 | const ThisT * ConstThis() {return this;} 50 | ArrayPointer(void * pointer) {data_ = static_cast(pointer);} 51 | Byte const * byte_ptr() const {return reinterpret_cast( data() );} 52 | Byte * byte_ptr() {return const_cast( ConstThis() -> byte_ptr() );} 53 | void const * block_address() const { return static_cast(byte_ptr()-sizeof(Size)); } 54 | void * block_address() { return const_cast( ConstThis() -> block_address() ); } 55 | friend ThisT CreateArray(Size); 56 | friend void DeleteArray(ArrayPointer what_delete); 57 | # ifdef KCL_MEMORY_DEBUG 58 | friend ThisT CreateArrayDebug(Size, const Char * file, int line); 59 | friend void DeleteArrayDebug(ArrayPointer what_delete, const Char * file, int line); 60 | # endif // KCL_MEMORY_DEBUG 61 | 62 | private: 63 | Byte * data_; 64 | }; 65 | #pragma pack(pop) 66 | 67 | 68 | 69 | template KCL_INLINE void InitializeArray(Size number_elements, Byte * memory_block) { 70 | Tn * address = static_cast( memory_block + sizeof(Size) ); 71 | (reinterpret_cast(memory_block))[0] = number_elements; 72 | Tn * base = address + number_elements; 73 | Size counter = 0 - number_elements; 74 | for (;counter; ++counter) { 75 | Construct(base + counter); 76 | } 77 | } 78 | 79 | 80 | template void KCL_INLINE DeinitializeArray(ArrayPointer what_deinit) { 81 | Size number_elements = what_deinit.number_elements(); 82 | Tn * base = what_deinit.data() + number_elements; 83 | Size counter = 0 - number_elements; 84 | for (;counter; ++counter) { 85 | Destruct( reinterpret_cast(base[counter]) ); 86 | } 87 | } 88 | 89 | # ifdef KCL_MEMORY_DEBUG 90 | template ArrayPointer CreateArrayDebug(Size number_elements, const Char * file, int line) { 91 | Byte * memory_block = static_cast ( KCL_ALLOCATE( sizeof(Tn) * number_elements + sizeof(Size) ) ); 92 | if (memory_block) { 93 | RegisterAllocatedMemory(memory_block, file, line); 94 | InitializeArray(number_elements, memory_block); 95 | return ArrayPointer(memory_block + sizeof(Size)); 96 | } else { 97 | return ArrayPointer(); 98 | } 99 | } 100 | 101 | template void DeleteArrayDebug(ArrayPointer what_delete, const Char * file, int line) { 102 | if (what_delete) { 103 | bool allow; 104 | UnregisterAllocatedMemory( what_delete.block_address(), file, line, allow ); 105 | DeinitializeArray(what_delete); 106 | DeallocateOrDie( what_delete.block_address() ); 107 | } 108 | } 109 | # endif // KCL_MEMORY_DEBUG 110 | 111 | template ArrayPointer CreateArray(Size number_elements) { 112 | Byte * memory_block = static_cast ( KCL_ALLOCATE( sizeof(Tn)*number_elements + sizeof(Size) ) ); 113 | DiagnosticPrint(KERN_EMERG "Universal CreateArray started, memory_block = %p",memory_block); 114 | if (memory_block) { 115 | InitializeArray(number_elements, memory_block); 116 | return ArrayPointer(memory_block + sizeof(Size)); 117 | } else { 118 | return ArrayPointer(); 119 | } 120 | } 121 | 122 | template void DeleteArray(ArrayPointer what_delete) { 123 | if (what_delete) { 124 | DeinitializeArray(what_delete); 125 | KCL_DEALLOCATE( what_delete.block_address() ); 126 | } 127 | } 128 | 129 | template class Vector { 130 | public: 131 | typedef Tn Type; 132 | typedef Vector ThisT; 133 | typedef KCL_ARRAY_POINTER(Type) StrongPointer; 134 | typedef KCL_ARRAY_POINTER(Type) ConstStrongPointer; 135 | typedef Type * iterator; 136 | typedef Type const * const_iterator; 137 | 138 | enum { kMinReservedElements = 8, }; 139 | 140 | Vector() : size_(0) {} 141 | ~Vector() { DeleteData();} 142 | bool Initialize(Size number_elements); 143 | bool reserve(Size number_elements); 144 | bool resize(Size number_elements); 145 | Type const & operator[](int index) const; 146 | Type & operator[](int index); 147 | Type const & at(int index) const; 148 | Type & at(int index); 149 | void push_back(const Type & to_add); 150 | void push_back(); 151 | void pop_back(); 152 | Type const & back() const; 153 | Type & back(); 154 | bool empty() {return size() == NULL;} 155 | const_iterator begin() const {return array();} 156 | const_iterator end() const {return postend();} 157 | iterator begin() {return array();} 158 | iterator end() {return postend();} 159 | Size size() const {return data().number_elements();} 160 | 161 | protected: 162 | Size capacity() const; 163 | Type * postend() const; 164 | void postend(Type *); 165 | StrongPointer data() {return data_;} 166 | ConstStrongPointer data() const {return data_;} 167 | void data(StrongPointer value) {data_ = value;} 168 | bool IsDataNull() const {return !data();} 169 | Type const * array() const {return data().data();} 170 | Type * array() {return data().data();} 171 | void Push_(); 172 | void Pop_(); 173 | 174 | StrongPointer AllocateArray(Size number_elements); 175 | void FreeArray(StrongPointer to_delete); 176 | bool CreateData(Size number_elements); 177 | void DeleteData(); 178 | static void CopyElementsPostend( iterator source_postend, iterator destination_postend, Size number_elements ); 179 | static void CopyElements( iterator source, iterator destination, Size number_elements ); 180 | static Size GetUpper2exp(Size value); 181 | static Size GetLowerEqual2exp(Size value); 182 | 183 | private: 184 | Vector(const ThisT &); 185 | ThisT& operator=(const ThisT &); 186 | 187 | Size size_; 188 | StrongPointer data_; 189 | }; 190 | 191 | 192 | template 193 | bool Vector::Initialize(Size number_elements) { 194 | KCL_ASSERT( !data(), "Vector::Initialize - memory leak"); 195 | return CreateData(number_elements); 196 | } 197 | 198 | template 199 | bool Vector::reserve(Size number_elements) { 200 | if ( number_elements > capacity() ) { 201 | StrongPointer new_data = AllocateArray(number_elements); 202 | if (!new_data) return 0; 203 | StrongPointer old_data = data(); 204 | if (!IsDataNull()) { 205 | Size old_size = capacity(); 206 | Type * src_postend = postend(); 207 | Type * dst_postend = data().data() + data(); 208 | CopyElementsPostend(src_postend, dst_postend, old_size); 209 | DeleteData(); 210 | } 211 | data(new_data); 212 | } 213 | return 1; 214 | } 215 | 216 | template 217 | bool Vector::resize(Size number_elements) { 218 | Size old_capacity = capacity(); 219 | Size old_size = size(); 220 | if (number_elements > old_capacity ) { 221 | reserve(number_elements << 1); 222 | } 223 | if (old_size < number_elements) { 224 | number_elements -= old_size; 225 | for (; number_elements; --number_elements) Push_(); 226 | } 227 | return 1; 228 | } 229 | 230 | template 231 | Size Vector::capacity() const { 232 | return IsDataNull() ? 0 : data().number_elements(); 233 | } 234 | 235 | template 236 | typename Vector::StrongPointer 237 | Vector::AllocateArray(Size number_elements) { 238 | return KCL_CREATE_ARRAY(Type, number_elements); 239 | } 240 | 241 | template 242 | void Vector::FreeArray(StrongPointer to_delete) { 243 | return KCL_DELETE_ARRAY(to_delete); 244 | } 245 | 246 | template 247 | void Vector::DeleteData() { 248 | return FreeArray( data() ); 249 | } 250 | 251 | template 252 | void Vector::CopyElementsPostend( iterator source_postend, iterator destination_postend, Size number_elements ) { 253 | Size current = 0 - number_elements; 254 | for (; current; ++current) { 255 | destination_postend[current] = source_postend[current]; 256 | } 257 | } 258 | 259 | template 260 | void Vector::CopyElements( iterator source, iterator destination, Size number_elements ) { 261 | CopyElementsPostend( source + number_elements, destination + number_elements, number_elements); 262 | } 263 | 264 | template 265 | bool Vector::CreateData(Size number_elements) { 266 | data(AllocateArray(number_elements)); 267 | return data(); 268 | } 269 | 270 | template 271 | Size Vector::GetUpper2exp(Size value) { 272 | if (value == 0) return 1; 273 | Size re = 1; 274 | while (re <= value) re <<= 1; 275 | return re; 276 | } 277 | 278 | template 279 | Size Vector::GetLowerEqual2exp(Size value) { 280 | if (value == 0) return 0; 281 | Size re = 1; 282 | while (re < value) re <<= 1; 283 | return re; 284 | } 285 | 286 | template 287 | void Vector::Push_() { 288 | Construct( array() + (size_++) ); 289 | } 290 | 291 | template 292 | void Vector::push_back() { 293 | Size new_capacity = capacity(); 294 | KCL_ASSERT(size() <= new_capacity, "Vector::push_back : Integrity Error!!! size > capacity" ); 295 | if ( size() == new_capacity ) { 296 | new_capacity = Max( kMinReservedElements, new_capacity << 1); 297 | reserve( new_capacity ); 298 | } 299 | Push_(); 300 | } 301 | 302 | template 303 | void Vector::pop_back() { 304 | Size sz = size(); 305 | KCL_ASSERT ( sz != 0, "Vector::pop_back : Integrity error -> empty vector"); 306 | if (sz) { 307 | Pop_(); 308 | } 309 | } 310 | 311 | template 312 | void Vector::Pop_() { 313 | Destruct(array()[--size_]); 314 | } 315 | 316 | template 317 | Tn * Vector::postend() const { 318 | return ( data() + size() ); 319 | } 320 | 321 | # endif //__cplusplus 322 | 323 | #endif // KC_LIBRARY_PROTECT_OFF 324 | -------------------------------------------------------------------------------- /KC_library/kernel_memory_map.h: -------------------------------------------------------------------------------- 1 | #ifndef KC_LIBRARY_PROTECT_OFF 2 | # error Do not include this directly!!! Use #include "KC_library.h" 3 | #else // KC_LIBRARY_PROTECT_OFF 4 | 5 | # ifdef __cplusplus 6 | 7 | 8 | template class pair { 9 | public: 10 | template friend class SafePointer; 11 | typedef FirstTn First; 12 | typedef SecondTn Second; 13 | pair() : first(), second() {} 14 | 15 | pair(const FirstTn & val1, const SecondTn & val2) 16 | : first(val1), second(val2) { } 17 | 18 | pair(First & val1, Second & val2) 19 | : first(val1), second(val2) { } 20 | 21 | // pair(First & val1, Second & val2) { 22 | // first = val1; 23 | // second = val2; 24 | // } 25 | // pair(const First & val1, const Second & val2) : pair() { 26 | // first = val1; 27 | // second = val2; 28 | // } 29 | 30 | First first; 31 | Second second; 32 | }; 33 | 34 | 35 | # ifdef KCL_MEMORY_DEBUG 36 | 37 | class MemoryMap { 38 | 39 | public: 40 | 41 | struct Element { 42 | int line; 43 | const Char * file; 44 | bool is_deleted; 45 | void * address; 46 | const Char * file_of_delete; 47 | int line_of_delete; 48 | }; 49 | typedef MemoryMap ThisT; 50 | typedef void * MapKey; 51 | typedef UInteger32 HashType; 52 | typedef const Element * ConstIterator; 53 | typedef Element * Iterator; 54 | typedef pair ValueType; 55 | class Snapshot; 56 | 57 | //stl-like 58 | typedef MapKey key_type; 59 | typedef ConstIterator const_iterator; 60 | typedef Iterator iterator; 61 | typedef Size size_type; 62 | typedef Element mapped_type; 63 | typedef ValueType value_type; 64 | 65 | typedef pair TypeInsertReturn; 66 | 67 | protected: 68 | HashType GetElementHash(const Element & arg) { 69 | //UInteger64 int_val = (UInteger64) arg.address >> 12; 70 | UInteger64 int_val = (UInteger64) arg.address; 71 | UInteger32 hash = (UInteger32)((int_val)>>33^(int_val)^(int_val)<<11); 72 | return hash; 73 | } 74 | static HashType GetKeyHash(const MapKey & arg) { 75 | UInteger64 int_val = (UInteger64) arg; 76 | UInteger32 hash = (UInteger32)((int_val)>>33^(int_val)^(int_val)<<11); 77 | return hash; 78 | //#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) 79 | } 80 | static bool IsHashesEqual(const HashType arg1, const HashType arg2) { 81 | return arg1 == arg2; 82 | } 83 | static bool IsHashesEqual(const MapKey arg1, const MapKey arg2) { 84 | return arg1 == arg2; 85 | } 86 | 87 | public: 88 | MemoryMap() {} 89 | //~MemoryMap() {Destroy_();} 90 | bool Initialize() {return Initialize_();} 91 | void Destroy() {Destroy_();} 92 | Size count (const MapKey& k) const {return Count_(k);} 93 | bool IsNewAddress (const MapKey& k) const {return IsNewAddress_(k);} 94 | Iterator find (const MapKey& k) {return Find_(k);} 95 | ConstIterator find (const MapKey& k) const {return Find_(k);} 96 | void clear() {Clear_();} 97 | TypeInsertReturn insert (const ValueType& val) {return Insert_(val);} 98 | Size erase (const MapKey& k) {return Erase_(k);} 99 | //void erase (Iterator position) {Erase_(position);} 100 | Element& operator[] (const MapKey& k) {return Get_(k);} 101 | Iterator begin() {return begin_();} 102 | Iterator end() {return end_();}//*/ 103 | bool GetSnapshot(Snapshot & out_snapshot) const {return GetSnapshot_(out_snapshot);} 104 | bool FindLeaks() const {return FindLeaks_();} 105 | bool IsEqual(const Snapshot & with, bool need_alert) const {return IsEqual_(with, need_alert);} 106 | bool FindLeaksAndAlert() const {return FindLeaksAndAlert_();} 107 | void * DebugHash() {return DebugHash_();} 108 | }; 109 | # endif // KCL_MEMORY_DEBUG 110 | 111 | # endif //__cplusplus 112 | 113 | #endif // KC_LIBRARY_PROTECT_OFF 114 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU General Public License is a free, copyleft license for 11 | software and other kinds of works. 12 | 13 | The licenses for most software and other practical works are designed 14 | to take away your freedom to share and change the works. By contrast, 15 | the GNU General Public License is intended to guarantee your freedom to 16 | share and change all versions of a program--to make sure it remains free 17 | software for all its users. We, the Free Software Foundation, use the 18 | GNU General Public License for most of our software; it applies also to 19 | any other work released this way by its authors. You can apply it to 20 | your programs, too. 21 | 22 | When we speak of free software, we are referring to freedom, not 23 | price. Our General Public Licenses are designed to make sure that you 24 | have the freedom to distribute copies of free software (and charge for 25 | them if you wish), that you receive source code or can get it if you 26 | want it, that you can change the software or use pieces of it in new 27 | free programs, and that you know you can do these things. 28 | 29 | To protect your rights, we need to prevent others from denying you 30 | these rights or asking you to surrender the rights. Therefore, you have 31 | certain responsibilities if you distribute copies of the software, or if 32 | you modify it: responsibilities to respect the freedom of others. 33 | 34 | For example, if you distribute copies of such a program, whether 35 | gratis or for a fee, you must pass on to the recipients the same 36 | freedoms that you received. You must make sure that they, too, receive 37 | or can get the source code. And you must show them these terms so they 38 | know their rights. 39 | 40 | Developers that use the GNU GPL protect your rights with two steps: 41 | (1) assert copyright on the software, and (2) offer you this License 42 | giving you legal permission to copy, distribute and/or modify it. 43 | 44 | For the developers' and authors' protection, the GPL clearly explains 45 | that there is no warranty for this free software. For both users' and 46 | authors' sake, the GPL requires that modified versions be marked as 47 | changed, so that their problems will not be attributed erroneously to 48 | authors of previous versions. 49 | 50 | Some devices are designed to deny users access to install or run 51 | modified versions of the software inside them, although the manufacturer 52 | can do so. This is fundamentally incompatible with the aim of 53 | protecting users' freedom to change the software. The systematic 54 | pattern of such abuse occurs in the area of products for individuals to 55 | use, which is precisely where it is most unacceptable. Therefore, we 56 | have designed this version of the GPL to prohibit the practice for those 57 | products. If such problems arise substantially in other domains, we 58 | stand ready to extend this provision to those domains in future versions 59 | of the GPL, as needed to protect the freedom of users. 60 | 61 | Finally, every program is threatened constantly by software patents. 62 | States should not allow patents to restrict development and use of 63 | software on general-purpose computers, but in those that do, we wish to 64 | avoid the special danger that patents applied to a free program could 65 | make it effectively proprietary. To prevent this, the GPL assures that 66 | patents cannot be used to render the program non-free. 67 | 68 | The precise terms and conditions for copying, distribution and 69 | modification follow. 70 | 71 | TERMS AND CONDITIONS 72 | 73 | 0. Definitions. 74 | 75 | "This License" refers to version 3 of the GNU General Public License. 76 | 77 | "Copyright" also means copyright-like laws that apply to other kinds of 78 | works, such as semiconductor masks. 79 | 80 | "The Program" refers to any copyrightable work licensed under this 81 | License. Each licensee is addressed as "you". "Licensees" and 82 | "recipients" may be individuals or organizations. 83 | 84 | To "modify" a work means to copy from or adapt all or part of the work 85 | in a fashion requiring copyright permission, other than the making of an 86 | exact copy. The resulting work is called a "modified version" of the 87 | earlier work or a work "based on" the earlier work. 88 | 89 | A "covered work" means either the unmodified Program or a work based 90 | on the Program. 91 | 92 | To "propagate" a work means to do anything with it that, without 93 | permission, would make you directly or secondarily liable for 94 | infringement under applicable copyright law, except executing it on a 95 | computer or modifying a private copy. Propagation includes copying, 96 | distribution (with or without modification), making available to the 97 | public, and in some countries other activities as well. 98 | 99 | To "convey" a work means any kind of propagation that enables other 100 | parties to make or receive copies. Mere interaction with a user through 101 | a computer network, with no transfer of a copy, is not conveying. 102 | 103 | An interactive user interface displays "Appropriate Legal Notices" 104 | to the extent that it includes a convenient and prominently visible 105 | feature that (1) displays an appropriate copyright notice, and (2) 106 | tells the user that there is no warranty for the work (except to the 107 | extent that warranties are provided), that licensees may convey the 108 | work under this License, and how to view a copy of this License. If 109 | the interface presents a list of user commands or options, such as a 110 | menu, a prominent item in the list meets this criterion. 111 | 112 | 1. Source Code. 113 | 114 | The "source code" for a work means the preferred form of the work 115 | for making modifications to it. "Object code" means any non-source 116 | form of a work. 117 | 118 | A "Standard Interface" means an interface that either is an official 119 | standard defined by a recognized standards body, or, in the case of 120 | interfaces specified for a particular programming language, one that 121 | is widely used among developers working in that language. 122 | 123 | The "System Libraries" of an executable work include anything, other 124 | than the work as a whole, that (a) is included in the normal form of 125 | packaging a Major Component, but which is not part of that Major 126 | Component, and (b) serves only to enable use of the work with that 127 | Major Component, or to implement a Standard Interface for which an 128 | implementation is available to the public in source code form. A 129 | "Major Component", in this context, means a major essential component 130 | (kernel, window system, and so on) of the specific operating system 131 | (if any) on which the executable work runs, or a compiler used to 132 | produce the work, or an object code interpreter used to run it. 133 | 134 | The "Corresponding Source" for a work in object code form means all 135 | the source code needed to generate, install, and (for an executable 136 | work) run the object code and to modify the work, including scripts to 137 | control those activities. However, it does not include the work's 138 | System Libraries, or general-purpose tools or generally available free 139 | programs which are used unmodified in performing those activities but 140 | which are not part of the work. For example, Corresponding Source 141 | includes interface definition files associated with source files for 142 | the work, and the source code for shared libraries and dynamically 143 | linked subprograms that the work is specifically designed to require, 144 | such as by intimate data communication or control flow between those 145 | subprograms and other parts of the work. 146 | 147 | The Corresponding Source need not include anything that users 148 | can regenerate automatically from other parts of the Corresponding 149 | Source. 150 | 151 | The Corresponding Source for a work in source code form is that 152 | same work. 153 | 154 | 2. Basic Permissions. 155 | 156 | All rights granted under this License are granted for the term of 157 | copyright on the Program, and are irrevocable provided the stated 158 | conditions are met. This License explicitly affirms your unlimited 159 | permission to run the unmodified Program. The output from running a 160 | covered work is covered by this License only if the output, given its 161 | content, constitutes a covered work. This License acknowledges your 162 | rights of fair use or other equivalent, as provided by copyright law. 163 | 164 | You may make, run and propagate covered works that you do not 165 | convey, without conditions so long as your license otherwise remains 166 | in force. You may convey covered works to others for the sole purpose 167 | of having them make modifications exclusively for you, or provide you 168 | with facilities for running those works, provided that you comply with 169 | the terms of this License in conveying all material for which you do 170 | not control copyright. Those thus making or running the covered works 171 | for you must do so exclusively on your behalf, under your direction 172 | and control, on terms that prohibit them from making any copies of 173 | your copyrighted material outside their relationship with you. 174 | 175 | Conveying under any other circumstances is permitted solely under 176 | the conditions stated below. Sublicensing is not allowed; section 10 177 | makes it unnecessary. 178 | 179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 180 | 181 | No covered work shall be deemed part of an effective technological 182 | measure under any applicable law fulfilling obligations under article 183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 184 | similar laws prohibiting or restricting circumvention of such 185 | measures. 186 | 187 | When you convey a covered work, you waive any legal power to forbid 188 | circumvention of technological measures to the extent such circumvention 189 | is effected by exercising rights under this License with respect to 190 | the covered work, and you disclaim any intention to limit operation or 191 | modification of the work as a means of enforcing, against the work's 192 | users, your or third parties' legal rights to forbid circumvention of 193 | technological measures. 194 | 195 | 4. Conveying Verbatim Copies. 196 | 197 | You may convey verbatim copies of the Program's source code as you 198 | receive it, in any medium, provided that you conspicuously and 199 | appropriately publish on each copy an appropriate copyright notice; 200 | keep intact all notices stating that this License and any 201 | non-permissive terms added in accord with section 7 apply to the code; 202 | keep intact all notices of the absence of any warranty; and give all 203 | recipients a copy of this License along with the Program. 204 | 205 | You may charge any price or no price for each copy that you convey, 206 | and you may offer support or warranty protection for a fee. 207 | 208 | 5. Conveying Modified Source Versions. 209 | 210 | You may convey a work based on the Program, or the modifications to 211 | produce it from the Program, in the form of source code under the 212 | terms of section 4, provided that you also meet all of these conditions: 213 | 214 | a) The work must carry prominent notices stating that you modified 215 | it, and giving a relevant date. 216 | 217 | b) The work must carry prominent notices stating that it is 218 | released under this License and any conditions added under section 219 | 7. This requirement modifies the requirement in section 4 to 220 | "keep intact all notices". 221 | 222 | c) You must license the entire work, as a whole, under this 223 | License to anyone who comes into possession of a copy. This 224 | License will therefore apply, along with any applicable section 7 225 | additional terms, to the whole of the work, and all its parts, 226 | regardless of how they are packaged. This License gives no 227 | permission to license the work in any other way, but it does not 228 | invalidate such permission if you have separately received it. 229 | 230 | d) If the work has interactive user interfaces, each must display 231 | Appropriate Legal Notices; however, if the Program has interactive 232 | interfaces that do not display Appropriate Legal Notices, your 233 | work need not make them do so. 234 | 235 | A compilation of a covered work with other separate and independent 236 | works, which are not by their nature extensions of the covered work, 237 | and which are not combined with it such as to form a larger program, 238 | in or on a volume of a storage or distribution medium, is called an 239 | "aggregate" if the compilation and its resulting copyright are not 240 | used to limit the access or legal rights of the compilation's users 241 | beyond what the individual works permit. Inclusion of a covered work 242 | in an aggregate does not cause this License to apply to the other 243 | parts of the aggregate. 244 | 245 | 6. Conveying Non-Source Forms. 246 | 247 | You may convey a covered work in object code form under the terms 248 | of sections 4 and 5, provided that you also convey the 249 | machine-readable Corresponding Source under the terms of this License, 250 | in one of these ways: 251 | 252 | a) Convey the object code in, or embodied in, a physical product 253 | (including a physical distribution medium), accompanied by the 254 | Corresponding Source fixed on a durable physical medium 255 | customarily used for software interchange. 256 | 257 | b) Convey the object code in, or embodied in, a physical product 258 | (including a physical distribution medium), accompanied by a 259 | written offer, valid for at least three years and valid for as 260 | long as you offer spare parts or customer support for that product 261 | model, to give anyone who possesses the object code either (1) a 262 | copy of the Corresponding Source for all the software in the 263 | product that is covered by this License, on a durable physical 264 | medium customarily used for software interchange, for a price no 265 | more than your reasonable cost of physically performing this 266 | conveying of source, or (2) access to copy the 267 | Corresponding Source from a network server at no charge. 268 | 269 | c) Convey individual copies of the object code with a copy of the 270 | written offer to provide the Corresponding Source. This 271 | alternative is allowed only occasionally and noncommercially, and 272 | only if you received the object code with such an offer, in accord 273 | with subsection 6b. 274 | 275 | d) Convey the object code by offering access from a designated 276 | place (gratis or for a charge), and offer equivalent access to the 277 | Corresponding Source in the same way through the same place at no 278 | further charge. You need not require recipients to copy the 279 | Corresponding Source along with the object code. If the place to 280 | copy the object code is a network server, the Corresponding Source 281 | may be on a different server (operated by you or a third party) 282 | that supports equivalent copying facilities, provided you maintain 283 | clear directions next to the object code saying where to find the 284 | Corresponding Source. Regardless of what server hosts the 285 | Corresponding Source, you remain obligated to ensure that it is 286 | available for as long as needed to satisfy these requirements. 287 | 288 | e) Convey the object code using peer-to-peer transmission, provided 289 | you inform other peers where the object code and Corresponding 290 | Source of the work are being offered to the general public at no 291 | charge under subsection 6d. 292 | 293 | A separable portion of the object code, whose source code is excluded 294 | from the Corresponding Source as a System Library, need not be 295 | included in conveying the object code work. 296 | 297 | A "User Product" is either (1) a "consumer product", which means any 298 | tangible personal property which is normally used for personal, family, 299 | or household purposes, or (2) anything designed or sold for incorporation 300 | into a dwelling. In determining whether a product is a consumer product, 301 | doubtful cases shall be resolved in favor of coverage. For a particular 302 | product received by a particular user, "normally used" refers to a 303 | typical or common use of that class of product, regardless of the status 304 | of the particular user or of the way in which the particular user 305 | actually uses, or expects or is expected to use, the product. A product 306 | is a consumer product regardless of whether the product has substantial 307 | commercial, industrial or non-consumer uses, unless such uses represent 308 | the only significant mode of use of the product. 309 | 310 | "Installation Information" for a User Product means any methods, 311 | procedures, authorization keys, or other information required to install 312 | and execute modified versions of a covered work in that User Product from 313 | a modified version of its Corresponding Source. The information must 314 | suffice to ensure that the continued functioning of the modified object 315 | code is in no case prevented or interfered with solely because 316 | modification has been made. 317 | 318 | If you convey an object code work under this section in, or with, or 319 | specifically for use in, a User Product, and the conveying occurs as 320 | part of a transaction in which the right of possession and use of the 321 | User Product is transferred to the recipient in perpetuity or for a 322 | fixed term (regardless of how the transaction is characterized), the 323 | Corresponding Source conveyed under this section must be accompanied 324 | by the Installation Information. But this requirement does not apply 325 | if neither you nor any third party retains the ability to install 326 | modified object code on the User Product (for example, the work has 327 | been installed in ROM). 328 | 329 | The requirement to provide Installation Information does not include a 330 | requirement to continue to provide support service, warranty, or updates 331 | for a work that has been modified or installed by the recipient, or for 332 | the User Product in which it has been modified or installed. Access to a 333 | network may be denied when the modification itself materially and 334 | adversely affects the operation of the network or violates the rules and 335 | protocols for communication across the network. 336 | 337 | Corresponding Source conveyed, and Installation Information provided, 338 | in accord with this section must be in a format that is publicly 339 | documented (and with an implementation available to the public in 340 | source code form), and must require no special password or key for 341 | unpacking, reading or copying. 342 | 343 | 7. Additional Terms. 344 | 345 | "Additional permissions" are terms that supplement the terms of this 346 | License by making exceptions from one or more of its conditions. 347 | Additional permissions that are applicable to the entire Program shall 348 | be treated as though they were included in this License, to the extent 349 | that they are valid under applicable law. If additional permissions 350 | apply only to part of the Program, that part may be used separately 351 | under those permissions, but the entire Program remains governed by 352 | this License without regard to the additional permissions. 353 | 354 | When you convey a copy of a covered work, you may at your option 355 | remove any additional permissions from that copy, or from any part of 356 | it. (Additional permissions may be written to require their own 357 | removal in certain cases when you modify the work.) You may place 358 | additional permissions on material, added by you to a covered work, 359 | for which you have or can give appropriate copyright permission. 360 | 361 | Notwithstanding any other provision of this License, for material you 362 | add to a covered work, you may (if authorized by the copyright holders of 363 | that material) supplement the terms of this License with terms: 364 | 365 | a) Disclaiming warranty or limiting liability differently from the 366 | terms of sections 15 and 16 of this License; or 367 | 368 | b) Requiring preservation of specified reasonable legal notices or 369 | author attributions in that material or in the Appropriate Legal 370 | Notices displayed by works containing it; or 371 | 372 | c) Prohibiting misrepresentation of the origin of that material, or 373 | requiring that modified versions of such material be marked in 374 | reasonable ways as different from the original version; or 375 | 376 | d) Limiting the use for publicity purposes of names of licensors or 377 | authors of the material; or 378 | 379 | e) Declining to grant rights under trademark law for use of some 380 | trade names, trademarks, or service marks; or 381 | 382 | f) Requiring indemnification of licensors and authors of that 383 | material by anyone who conveys the material (or modified versions of 384 | it) with contractual assumptions of liability to the recipient, for 385 | any liability that these contractual assumptions directly impose on 386 | those licensors and authors. 387 | 388 | All other non-permissive additional terms are considered "further 389 | restrictions" within the meaning of section 10. If the Program as you 390 | received it, or any part of it, contains a notice stating that it is 391 | governed by this License along with a term that is a further 392 | restriction, you may remove that term. If a license document contains 393 | a further restriction but permits relicensing or conveying under this 394 | License, you may add to a covered work material governed by the terms 395 | of that license document, provided that the further restriction does 396 | not survive such relicensing or conveying. 397 | 398 | If you add terms to a covered work in accord with this section, you 399 | must place, in the relevant source files, a statement of the 400 | additional terms that apply to those files, or a notice indicating 401 | where to find the applicable terms. 402 | 403 | Additional terms, permissive or non-permissive, may be stated in the 404 | form of a separately written license, or stated as exceptions; 405 | the above requirements apply either way. 406 | 407 | 8. Termination. 408 | 409 | You may not propagate or modify a covered work except as expressly 410 | provided under this License. Any attempt otherwise to propagate or 411 | modify it is void, and will automatically terminate your rights under 412 | this License (including any patent licenses granted under the third 413 | paragraph of section 11). 414 | 415 | However, if you cease all violation of this License, then your 416 | license from a particular copyright holder is reinstated (a) 417 | provisionally, unless and until the copyright holder explicitly and 418 | finally terminates your license, and (b) permanently, if the copyright 419 | holder fails to notify you of the violation by some reasonable means 420 | prior to 60 days after the cessation. 421 | 422 | Moreover, your license from a particular copyright holder is 423 | reinstated permanently if the copyright holder notifies you of the 424 | violation by some reasonable means, this is the first time you have 425 | received notice of violation of this License (for any work) from that 426 | copyright holder, and you cure the violation prior to 30 days after 427 | your receipt of the notice. 428 | 429 | Termination of your rights under this section does not terminate the 430 | licenses of parties who have received copies or rights from you under 431 | this License. If your rights have been terminated and not permanently 432 | reinstated, you do not qualify to receive new licenses for the same 433 | material under section 10. 434 | 435 | 9. Acceptance Not Required for Having Copies. 436 | 437 | You are not required to accept this License in order to receive or 438 | run a copy of the Program. Ancillary propagation of a covered work 439 | occurring solely as a consequence of using peer-to-peer transmission 440 | to receive a copy likewise does not require acceptance. However, 441 | nothing other than this License grants you permission to propagate or 442 | modify any covered work. These actions infringe copyright if you do 443 | not accept this License. Therefore, by modifying or propagating a 444 | covered work, you indicate your acceptance of this License to do so. 445 | 446 | 10. Automatic Licensing of Downstream Recipients. 447 | 448 | Each time you convey a covered work, the recipient automatically 449 | receives a license from the original licensors, to run, modify and 450 | propagate that work, subject to this License. You are not responsible 451 | for enforcing compliance by third parties with this License. 452 | 453 | An "entity transaction" is a transaction transferring control of an 454 | organization, or substantially all assets of one, or subdividing an 455 | organization, or merging organizations. If propagation of a covered 456 | work results from an entity transaction, each party to that 457 | transaction who receives a copy of the work also receives whatever 458 | licenses to the work the party's predecessor in interest had or could 459 | give under the previous paragraph, plus a right to possession of the 460 | Corresponding Source of the work from the predecessor in interest, if 461 | the predecessor has it or can get it with reasonable efforts. 462 | 463 | You may not impose any further restrictions on the exercise of the 464 | rights granted or affirmed under this License. For example, you may 465 | not impose a license fee, royalty, or other charge for exercise of 466 | rights granted under this License, and you may not initiate litigation 467 | (including a cross-claim or counterclaim in a lawsuit) alleging that 468 | any patent claim is infringed by making, using, selling, offering for 469 | sale, or importing the Program or any portion of it. 470 | 471 | 11. Patents. 472 | 473 | A "contributor" is a copyright holder who authorizes use under this 474 | License of the Program or a work on which the Program is based. The 475 | work thus licensed is called the contributor's "contributor version". 476 | 477 | A contributor's "essential patent claims" are all patent claims 478 | owned or controlled by the contributor, whether already acquired or 479 | hereafter acquired, that would be infringed by some manner, permitted 480 | by this License, of making, using, or selling its contributor version, 481 | but do not include claims that would be infringed only as a 482 | consequence of further modification of the contributor version. For 483 | purposes of this definition, "control" includes the right to grant 484 | patent sublicenses in a manner consistent with the requirements of 485 | this License. 486 | 487 | Each contributor grants you a non-exclusive, worldwide, royalty-free 488 | patent license under the contributor's essential patent claims, to 489 | make, use, sell, offer for sale, import and otherwise run, modify and 490 | propagate the contents of its contributor version. 491 | 492 | In the following three paragraphs, a "patent license" is any express 493 | agreement or commitment, however denominated, not to enforce a patent 494 | (such as an express permission to practice a patent or covenant not to 495 | sue for patent infringement). To "grant" such a patent license to a 496 | party means to make such an agreement or commitment not to enforce a 497 | patent against the party. 498 | 499 | If you convey a covered work, knowingly relying on a patent license, 500 | and the Corresponding Source of the work is not available for anyone 501 | to copy, free of charge and under the terms of this License, through a 502 | publicly available network server or other readily accessible means, 503 | then you must either (1) cause the Corresponding Source to be so 504 | available, or (2) arrange to deprive yourself of the benefit of the 505 | patent license for this particular work, or (3) arrange, in a manner 506 | consistent with the requirements of this License, to extend the patent 507 | license to downstream recipients. "Knowingly relying" means you have 508 | actual knowledge that, but for the patent license, your conveying the 509 | covered work in a country, or your recipient's use of the covered work 510 | in a country, would infringe one or more identifiable patents in that 511 | country that you have reason to believe are valid. 512 | 513 | If, pursuant to or in connection with a single transaction or 514 | arrangement, you convey, or propagate by procuring conveyance of, a 515 | covered work, and grant a patent license to some of the parties 516 | receiving the covered work authorizing them to use, propagate, modify 517 | or convey a specific copy of the covered work, then the patent license 518 | you grant is automatically extended to all recipients of the covered 519 | work and works based on it. 520 | 521 | A patent license is "discriminatory" if it does not include within 522 | the scope of its coverage, prohibits the exercise of, or is 523 | conditioned on the non-exercise of one or more of the rights that are 524 | specifically granted under this License. You may not convey a covered 525 | work if you are a party to an arrangement with a third party that is 526 | in the business of distributing software, under which you make payment 527 | to the third party based on the extent of your activity of conveying 528 | the work, and under which the third party grants, to any of the 529 | parties who would receive the covered work from you, a discriminatory 530 | patent license (a) in connection with copies of the covered work 531 | conveyed by you (or copies made from those copies), or (b) primarily 532 | for and in connection with specific products or compilations that 533 | contain the covered work, unless you entered into that arrangement, 534 | or that patent license was granted, prior to 28 March 2007. 535 | 536 | Nothing in this License shall be construed as excluding or limiting 537 | any implied license or other defenses to infringement that may 538 | otherwise be available to you under applicable patent law. 539 | 540 | 12. No Surrender of Others' Freedom. 541 | 542 | If conditions are imposed on you (whether by court order, agreement or 543 | otherwise) that contradict the conditions of this License, they do not 544 | excuse you from the conditions of this License. If you cannot convey a 545 | covered work so as to satisfy simultaneously your obligations under this 546 | License and any other pertinent obligations, then as a consequence you may 547 | not convey it at all. For example, if you agree to terms that obligate you 548 | to collect a royalty for further conveying from those to whom you convey 549 | the Program, the only way you could satisfy both those terms and this 550 | License would be to refrain entirely from conveying the Program. 551 | 552 | 13. Use with the GNU Affero General Public License. 553 | 554 | Notwithstanding any other provision of this License, you have 555 | permission to link or combine any covered work with a work licensed 556 | under version 3 of the GNU Affero General Public License into a single 557 | combined work, and to convey the resulting work. The terms of this 558 | License will continue to apply to the part which is the covered work, 559 | but the special requirements of the GNU Affero General Public License, 560 | section 13, concerning interaction through a network will apply to the 561 | combination as such. 562 | 563 | 14. Revised Versions of this License. 564 | 565 | The Free Software Foundation may publish revised and/or new versions of 566 | the GNU General Public License from time to time. Such new versions will 567 | be similar in spirit to the present version, but may differ in detail to 568 | address new problems or concerns. 569 | 570 | Each version is given a distinguishing version number. If the 571 | Program specifies that a certain numbered version of the GNU General 572 | Public License "or any later version" applies to it, you have the 573 | option of following the terms and conditions either of that numbered 574 | version or of any later version published by the Free Software 575 | Foundation. If the Program does not specify a version number of the 576 | GNU General Public License, you may choose any version ever published 577 | by the Free Software Foundation. 578 | 579 | If the Program specifies that a proxy can decide which future 580 | versions of the GNU General Public License can be used, that proxy's 581 | public statement of acceptance of a version permanently authorizes you 582 | to choose that version for the Program. 583 | 584 | Later license versions may give you additional or different 585 | permissions. However, no additional obligations are imposed on any 586 | author or copyright holder as a result of your choosing to follow a 587 | later version. 588 | 589 | 15. Disclaimer of Warranty. 590 | 591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 599 | 600 | 16. Limitation of Liability. 601 | 602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 610 | SUCH DAMAGES. 611 | 612 | 17. Interpretation of Sections 15 and 16. 613 | 614 | If the disclaimer of warranty and limitation of liability provided 615 | above cannot be given local legal effect according to their terms, 616 | reviewing courts shall apply local law that most closely approximates 617 | an absolute waiver of all civil liability in connection with the 618 | Program, unless a warranty or assumption of liability accompanies a 619 | copy of the Program in return for a fee. 620 | 621 | END OF TERMS AND CONDITIONS 622 | 623 | How to Apply These Terms to Your New Programs 624 | 625 | If you develop a new program, and you want it to be of the greatest 626 | possible use to the public, the best way to achieve this is to make it 627 | free software which everyone can redistribute and change under these terms. 628 | 629 | To do so, attach the following notices to the program. It is safest 630 | to attach them to the start of each source file to most effectively 631 | state the exclusion of warranty; and each file should have at least 632 | the "copyright" line and a pointer to where the full notice is found. 633 | 634 | {one line to give the program's name and a brief idea of what it does.} 635 | Copyright (C) {year} {name of author} 636 | 637 | This program is free software: you can redistribute it and/or modify 638 | it under the terms of the GNU General Public License as published by 639 | the Free Software Foundation, either version 3 of the License, or 640 | (at your option) any later version. 641 | 642 | This program is distributed in the hope that it will be useful, 643 | but WITHOUT ANY WARRANTY; without even the implied warranty of 644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 645 | GNU General Public License for more details. 646 | 647 | You should have received a copy of the GNU General Public License 648 | along with this program. If not, see . 649 | 650 | Also add information on how to contact you by electronic and paper mail. 651 | 652 | If the program does terminal interaction, make it output a short 653 | notice like this when it starts in an interactive mode: 654 | 655 | {project} Copyright (C) {year} {fullname} 656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 657 | This is free software, and you are welcome to redistribute it 658 | under certain conditions; type `show c' for details. 659 | 660 | The hypothetical commands `show w' and `show c' should show the appropriate 661 | parts of the General Public License. Of course, your program's commands 662 | might be different; for a GUI interface, you would use an "about box". 663 | 664 | You should also get your employer (if you work as a programmer) or school, 665 | if any, to sign a "copyright disclaimer" for the program, if necessary. 666 | For more information on this, and how to apply and follow the GNU GPL, see 667 | . 668 | 669 | The GNU General Public License does not permit incorporating your program 670 | into proprietary programs. If your program is a subroutine library, you 671 | may consider it more useful to permit linking proprietary applications with 672 | the library. If this is what you want to do, use the GNU Lesser General 673 | Public License instead of this License. But first, please read 674 | . 675 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KCL 2 | Kernel Context [template c++] Library - K C L. Your stl for work in linux/windows kernel !!! 3 | 4 | 5 | Remark: not work with KCL_MEMORY_DEBUG, because debug analog std::map not finished 6 | if you want use builtin powerfull memory leak tool, add to file kernel_memory_map.h implementation of map. For example, you can use this : https://github.com/attractivechaos/klib/blob/master/khash.h 7 | 8 | Built-in memory debug show you file, line, function where your memory leak, double deletion e.t.c. 9 | 10 | But you MUST use KCL_ALLOCATE, KCL_CREATE_OBJECT, KCL_DELETE_OBJECT, KCL_DEALLOCATE, KCL_POINTER, KCL_WEAK_POINTER e.t.c. for correct work of built-in memory debug. 11 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "KC_library/KC_library.h" 4 | 5 | using namespace std; 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | cout << "Hello World!" << endl; 10 | kcl::List list; 11 | KCL_USED(list); 12 | PODArrayHandle pod_array_handle; 13 | kcl::PODArray * pod_ptr; 14 | CreatePODArray(int, 10, pod_array_handle, pod_ptr); 15 | DeletePODArray(pod_array_handle); 16 | kcl::SafePointer sfp; 17 | KCL_USED(sfp) 18 | //kcl::SafeConstPointer sfpc; 19 | //KCL_USED(sfpc) 20 | kcl::RandInteger irand = kcl::GetRandom(); 21 | KCL_USED(irand); 22 | //kcl::String str= kcl::String::MakeReference("ddd"); 23 | //printf("%s", str.c_str() ); 24 | kcl::Vector vect; 25 | KCL_USED(vect); 26 | kcl::BitField<8,8> bf; 27 | KCL_USED(bf); 28 | return 0; 29 | } 30 | --------------------------------------------------------------------------------