diff --git a/.gdbinit b/.gdbinit
new file mode 100644
index 0000000..bdf921c
--- /dev/null
+++ b/.gdbinit
@@ -0,0 +1,7 @@
+python
+import sys
+import os
+sys.path.insert(0, os.path.join(os.getcwd(), 'debug'))
+import gdbinit
+print("GDB pretty-printer for original initialized.")
+end
\ No newline at end of file
diff --git a/.github/workflows/basic-tests.yml b/.github/workflows/basic-tests.yml
index cd7de7d..074599e 100644
--- a/.github/workflows/basic-tests.yml
+++ b/.github/workflows/basic-tests.yml
@@ -3,7 +3,7 @@
name: Test Branch CI - Basic Tests
on:
- push:
+ pull_request:
branches: [ test ]
jobs:
diff --git a/.github/workflows/deploy-docs-existing-tags.yml b/.github/workflows/deploy-docs-existing-tags.yml
deleted file mode 100644
index 2f942f5..0000000
--- a/.github/workflows/deploy-docs-existing-tags.yml
+++ /dev/null
@@ -1,116 +0,0 @@
-# .github/workflows/deploy-docs-existing-tags.yml
-name: Deploy Documentation - Existing Tags
-
-on:
- push:
- branches:
- - test # 监听 test 分支 push
-
-jobs:
- build-and-deploy:
- runs-on: ubuntu-latest
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
-
- - name: Install dependencies
- run: |
- sudo apt-get update
- sudo apt-get install -y doxygen graphviz plantuml jq
-
- - name: Set tags to deploy
- id: tags
- run: |
- # 一次性部署的指定 tags
- TAGS="v0.1.0 v0.1.2 v0.1.4"
- echo "tags=$TAGS" >> $GITHUB_OUTPUT
- echo "Deploying tags: $TAGS"
-
- - name: Build and deploy documentation
- env:
- GH_PAT: ${{ secrets.GH_PAT }}
- TAGS: ${{ steps.tags.outputs.tags }}
- run: |
- git config --global user.name "github-actions[bot]"
- git config --global user.email "github-actions[bot]@users.noreply.github.com"
-
- # 克隆文档仓库
- git clone -b master https://$GH_PAT@github.com/FrozenLemonTee/original_docs.git deploy-repo
-
- for TAG in $TAGS; do
- echo "Processing tag: $TAG"
-
- # 检出 tag
- git checkout $TAG || { echo "Tag $TAG not found"; continue; }
-
- # 提取版本号
- VERSION=${TAG#v}
-
- # 清理并创建文档目录
- mkdir -p ../original_docs/docs/html
- doxygen Doxyfile > doxygen.log 2>&1
-
- # 检查 HTML 是否生成
- if [ ! -d "../original_docs/docs/html" ]; then
- echo "Warning: Documentation not generated for $TAG"
- continue
- fi
-
- # 创建版本信息文件
- echo '' > ../original_docs/docs/html/version.html
- echo '
Version Info' >> ../original_docs/docs/html/version.html
- echo " Documentation Version
" >> ../original_docs/docs/html/version.html
- echo " Version: $VERSION
" >> ../original_docs/docs/html/version.html
- echo " Tag: $TAG
" >> ../original_docs/docs/html/version.html
- echo " Build Date: $(date -u)
" >> ../original_docs/docs/html/version.html
- echo " Commit: $(git rev-parse $TAG)
" >> ../original_docs/docs/html/version.html
- echo '' >> ../original_docs/docs/html/version.html
-
- # 部署到文档仓库
- cd deploy-repo
- mkdir -p versions
- VERSION_DIR="versions/$VERSION"
- rm -rf "$VERSION_DIR"
- mkdir -p "$VERSION_DIR"
- cp -r ../../original_docs/docs/html/* "$VERSION_DIR"/
- cd ..
- done
-
- # 更新主 index.html 和 versions/index.html
- cd deploy-repo
-
- echo '' > index.html
- echo '' >> index.html
- echo 'Redirecting to stable documentation...
' >> index.html
- echo 'Available versions:
Recent tag versions:
' >> index.html
- for dir in $(ls -1 versions/ | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V -r | head -5); do
- echo " - Version $dir
" >> index.html
- done
- echo '
' >> index.html
-
- # versions/index.html
- echo '' > versions/index.html
- echo 'Versioned Documentation' >> versions/index.html
- echo 'Versioned Documentation
Select a version:
' >> versions/index.html
- for dir in $(ls -1 versions/ | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V -r); do
- echo " - Version $dir
" >> versions/index.html
- done
- echo '
Stable (master branch)
' >> versions/index.html
- echo 'Latest (test branch)
' >> versions/index.html
-
- # 提交推送
- git add .
- if git diff-index --quiet HEAD --; then
- echo "No changes to deploy"
- else
- git commit -m "Deploy documentation for tags $TAGS"
- git push origin master
- echo "✅ Documentation deployed successfully for tags $TAGS"
- fi
diff --git a/.github/workflows/deploy-docs-latest.yml b/.github/workflows/deploy-docs-latest.yml
index a25ed8a..a136c01 100644
--- a/.github/workflows/deploy-docs-latest.yml
+++ b/.github/workflows/deploy-docs-latest.yml
@@ -4,10 +4,11 @@ name: Deploy Documentation - Latest
on:
push:
- branches: [ master ] # Temporary change from test to master to avoid concurrency push
+ branches: [ test ]
jobs:
build-and-deploy:
+ if: github.repository == 'FrozenLemonTee/original'
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/deploy-docs-stable.yml b/.github/workflows/deploy-docs-stable.yml
index 0b41a78..1b88f99 100644
--- a/.github/workflows/deploy-docs-stable.yml
+++ b/.github/workflows/deploy-docs-stable.yml
@@ -5,9 +5,12 @@ name: Deploy Documentation - Stable
on:
push:
branches: [ master ]
+ tags:
+ - 'v*.*.*'
jobs:
build-and-deploy:
+ if: github.repository == 'FrozenLemonTee/original'
runs-on: ubuntu-latest
steps:
@@ -45,7 +48,7 @@ jobs:
echo '' >> ../original_docs/docs/html/version.html
echo ' Documentation Version
' >> ../original_docs/docs/html/version.html
echo ' Version: stable
' >> ../original_docs/docs/html/version.html
- echo ' Branch: master
' >> index.html
+ echo ' Branch: master
' >> ../original_docs/docs/html/version.html
echo " Build Date: $(date -u)
" >> ../original_docs/docs/html/version.html
echo " Commit: ${{ github.sha }}
" >> ../original_docs/docs/html/version.html
echo '' >> ../original_docs/docs/html/version.html
@@ -64,12 +67,12 @@ jobs:
cd deploy-repo
- # Only update stable directory
+ # Update stable directory
rm -rf stable
mkdir -p stable
cp -r ../../original_docs/docs/html/* stable/
- # Create index.html redirection
+ # Regenerate the main index.html to include the latest tag version
echo '' > index.html
echo '' >> index.html
echo '' >> index.html
@@ -82,16 +85,47 @@ jobs:
echo ' Stable (master branch)' >> index.html
echo ' Latest (test branch)' >> index.html
echo ' Tag versions' >> index.html
+ echo ' ' >> index.html
+ echo ' Recent tag versions:
' >> index.html
+ echo ' ' >> index.html
+
+ # Regenerate the list of recent tag versions (last 5)
+ for dir in $(ls -1 versions/ 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V -r | head -5); do
+ echo " - Version $dir
" >> index.html
+ done
+
echo '
' >> index.html
echo '' >> index.html
echo '' >> index.html
+ # Also update versions/index.html to ensure that the list of all versions is up to date
+ echo '' > versions/index.html
+ echo '' >> versions/index.html
+ echo '' >> versions/index.html
+ echo ' Versioned Documentation' >> versions/index.html
+ echo '' >> versions/index.html
+ echo '' >> versions/index.html
+ echo ' Versioned Documentation
' >> versions/index.html
+ echo ' Select a version:
' >> versions/index.html
+ echo ' ' >> versions/index.html
+
+ # List all versions (from newest to oldest)
+ for dir in $(ls -1 versions/ 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | sort -V -r); do
+ echo " - Version $dir
" >> versions/index.html
+ done
+
+ echo '
' >> versions/index.html
+ echo ' Stable (master branch)
' >> versions/index.html
+ echo ' Latest (test branch)
' >> versions/index.html
+ echo '' >> versions/index.html
+ echo '' >> versions/index.html
+
# Submit and push
git add .
if git diff-index --quiet HEAD --; then
echo "No changes to deploy"
else
- git commit -m "Deploy ${{ steps.version.outputs.docs-version }} documentation from ${{ github.sha }}"
+ git commit -m "Deploy stable documentation from ${{ github.sha }} and update version lists"
git push origin master
- echo "✅ Stable documentation deployed successfully"
+ echo "✅ Stable documentation deployed successfully with updated version lists"
fi
\ No newline at end of file
diff --git a/.github/workflows/deploy-docs-tags.yml b/.github/workflows/deploy-docs-tags.yml
index c56feac..2666f9c 100644
--- a/.github/workflows/deploy-docs-tags.yml
+++ b/.github/workflows/deploy-docs-tags.yml
@@ -9,6 +9,7 @@ on:
jobs:
build-and-deploy:
+ if: github.repository == 'FrozenLemonTee/original'
runs-on: ubuntu-latest
steps:
diff --git a/.github/workflows/full-tests.yml b/.github/workflows/full-tests.yml
index 79ca7db..a175a66 100644
--- a/.github/workflows/full-tests.yml
+++ b/.github/workflows/full-tests.yml
@@ -56,7 +56,7 @@ jobs:
- name: Run tests
run: |
- cd build && ctest --output-on-failure
+ cd build && ctest --verbose --output-on-failure
windows-tests:
runs-on: windows-latest
@@ -75,4 +75,4 @@ jobs:
- name: Run tests
run: |
- cd build && ctest -C ${{ matrix.build_type }} --output-on-failure
\ No newline at end of file
+ cd build && ctest --verbose -C ${{ matrix.build_type }} --output-on-failure
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 5b69209..6792be8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,13 @@
-cmake-build-debug/
-.idea/
-test.exe
-original.zip
-original.rar
+cmake-build-*/
+**/.idea/
build/
install/
.vs/
+.vscode/
out/
-original/
\ No newline at end of file
+original/
+**/__pycache__/
+
+test.exe
+original.zip
+original.rar
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bcdefab..54f0e5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,12 +1,48 @@
# CMakeLists.txt Main
cmake_minimum_required(VERSION 3.31)
+if(CMAKE_GENERATOR MATCHES "Visual Studio" OR CMAKE_GENERATOR MATCHES "Ninja Multi-Config")
+ set(CMAKE_GENERATOR_PLATFORM x64 CACHE STRING "Platform" FORCE)
+endif()
project(original LANGUAGES CXX)
set(ORIGINAL_VERSION 0.1.5)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True)
+set(CMAKE_CXX_EXTENSIONS OFF)
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.0)
+ message(FATAL_ERROR "GCC version too old. Minimum required: 13.0. Current: ${CMAKE_CXX_COMPILER_VERSION}")
+ else()
+ message(STATUS "GCC version: ${CMAKE_CXX_COMPILER_VERSION} (>= 13.0 ✓)")
+ endif()
+endif()
+
+if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 20.0)
+ message(FATAL_ERROR "Clang version too old. Minimum required: 20.0. Current: ${CMAKE_CXX_COMPILER_VERSION}")
+ else()
+ message(STATUS "Clang version: ${CMAKE_CXX_COMPILER_VERSION} (>= 20.0 ✓)")
+ endif()
+endif()
+if(MSVC)
+ if(MSVC_VERSION LESS 1944)
+ message(FATAL_ERROR "MSVC version too old. Minimum required: 14.44.35207 (VS2022 17.10+). Current: ${MSVC_VERSION}")
+ else()
+ message(STATUS "MSVC version: ${MSVC_VERSION} (>= 14.44 ✓)")
+ endif()
+ set(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION "10.0" CACHE STRING "Windows Target Platform Version")
+endif()
+if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag("-std=c++23" HAS_CXX23_FLAG)
+ if(NOT HAS_CXX23_FLAG)
+ message(WARNING "Compiler may not fully support C++23 standard")
+ endif()
+endif()
+
if (NOT CMAKE_BUILD_TYPE)
- set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type (default Debug)" FORCE)
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type (default Release)" FORCE)
endif()
include(CMakePackageConfigHelpers)
@@ -69,24 +105,12 @@ install(FILES
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/original
)
+add_subdirectory(debug)
+
option(BUILD_TESTING "Build the testing directories" ON)
if (BUILD_TESTING)
include(CTest)
- if(MSVC)
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Zi")
- else()
- if (NOT CMAKE_SYSTEM_NAME STREQUAL "Windows")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -g")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address -g")
- else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g")
- endif()
- endif()
-
- # test cases
- add_subdirectory(test/other)
- add_subdirectory(test/unit_test)
+ enable_testing()
+ add_subdirectory(test)
endif ()
\ No newline at end of file
diff --git a/debug/CMakeLists.txt b/debug/CMakeLists.txt
new file mode 100644
index 0000000..2843c8d
--- /dev/null
+++ b/debug/CMakeLists.txt
@@ -0,0 +1,42 @@
+# debug/CMakeLists.txt
+
+if(CMAKE_BUILD_TYPE MATCHES "Debug")
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "MinGW")
+ message(STATUS "[GDB CONFIG] Detected GNU/MinGW toolchain, setting up GDB auto-load permissions")
+
+ if(WIN32)
+ file(TO_CMAKE_PATH "$ENV{USERPROFILE}" USER_HOME)
+ else()
+ file(TO_CMAKE_PATH "$ENV{HOME}" USER_HOME)
+ endif()
+
+ set(GDB_GLOBAL_INIT "${USER_HOME}/.config/gdb/gdbinit")
+ if(NOT EXISTS "${GDB_GLOBAL_INIT}")
+ set(GDB_GLOBAL_INIT "${USER_HOME}/.gdbinit")
+ endif()
+
+ set(PROJECT_GDBINIT "${CMAKE_SOURCE_DIR}/.gdbinit")
+
+ set(GDB_CONFIG_LINES
+ "set auto-load local-gdbinit on
+add-auto-load-safe-path ${PROJECT_GDBINIT}\n"
+ )
+
+ get_filename_component(GDB_CONFIG_DIR "${GDB_GLOBAL_INIT}" DIRECTORY)
+ file(MAKE_DIRECTORY "${GDB_CONFIG_DIR}")
+
+ if(EXISTS "${GDB_GLOBAL_INIT}")
+ file(READ "${GDB_GLOBAL_INIT}" EXISTING_CONTENT)
+ string(FIND "${EXISTING_CONTENT}" "${PROJECT_GDBINIT}" ALREADY_ADDED)
+ else()
+ set(ALREADY_ADDED -1)
+ endif()
+
+ if(ALREADY_ADDED EQUAL -1)
+ file(APPEND "${GDB_GLOBAL_INIT}" "\n# Added by Original CMake auto-config\n${GDB_CONFIG_LINES}")
+ message(STATUS "[GDB CONFIG] Added safe-path for ${PROJECT_GDBINIT} in ${GDB_GLOBAL_INIT}")
+ else()
+ message(STATUS "[GDB CONFIG] Safe-path already configured in ${GDB_GLOBAL_INIT}")
+ endif()
+ endif()
+endif()
diff --git a/debug/gdbinit.py b/debug/gdbinit.py
new file mode 100644
index 0000000..c9a86d9
--- /dev/null
+++ b/debug/gdbinit.py
@@ -0,0 +1,58 @@
+# debug/gdbinit.py
+
+import gdb
+import sys
+import os
+import importlib.util
+import inspect
+
+
+def load_printers_from_directory(pretty_printer_collection, directory):
+ """Load all pretty-printer scripts from the specified directory."""
+ if not os.path.isdir(directory):
+ print(f"[WARN] Skipped non-existent directory: {directory}")
+ return
+
+ for file_name in os.listdir(directory):
+ if not file_name.endswith("_printer.py"):
+ continue
+
+ file_path = os.path.join(directory, file_name)
+ module_name = os.path.splitext(file_name)[0]
+
+ try:
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
+ module = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(module)
+
+ printer_class = None
+ for name, cls in inspect.getmembers(module, inspect.isclass):
+ if name == "Printer":
+ printer_class = cls
+ break
+
+ if printer_class is None:
+ print(f"[SKIP] {module_name}: no 'Printer' class found")
+ continue
+ type_name = module_name.replace("_printer", "")
+ type_regex = f"^original::{type_name}(<.*>)?$"
+
+ pretty_printer_collection.add_printer(module_name, type_regex, printer_class)
+ print(f"Registered pretty-printer: {type_name}")
+
+ except Exception as e:
+ print(f"Failed to load {file_name}: {e}")
+
+
+this_dir = os.path.dirname(__file__)
+printers_dir = os.path.join(this_dir, "printers")
+core_dir = os.path.join(printers_dir, "core")
+
+sys.path.insert(0, printers_dir)
+sys.path.insert(0, core_dir)
+
+pp = gdb.printing.RegexpCollectionPrettyPrinter("original")
+load_printers_from_directory(pp, core_dir)
+gdb.printing.register_pretty_printer(None, pp)
+
+print("GDB pretty-printers for 'original' registered successfully.")
\ No newline at end of file
diff --git a/debug/printers/core/RBTree_printer.py b/debug/printers/core/RBTree_printer.py
new file mode 100644
index 0000000..8db4a04
--- /dev/null
+++ b/debug/printers/core/RBTree_printer.py
@@ -0,0 +1,79 @@
+# debug/printers/core/RBTree_printer.py
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+def get_successor_node(ptr):
+ if ptr == 0:
+ return 0
+ node = ptr.dereference()
+ if node["right_"] != 0:
+ ptr = node["right_"]
+ node = ptr.dereference()
+ while node["left_"] != 0:
+ ptr = node["left_"]
+ node = ptr.dereference()
+ return ptr
+
+ node = ptr.dereference()
+ ptr_parent = node["parent_"]
+ node = ptr_parent.dereference()
+
+ while ptr_parent != 0 and ptr == node["right_"]:
+ ptr = ptr_parent
+ node = ptr_parent.dereference()
+ ptr_parent = node["parent_"]
+ return ptr_parent
+
+
+class PrinterBase:
+ """Pretty printer for derived classes of RBTree in original"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def class_name(self):
+ return "original::RBTree"
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ return f"{self.class_name()}(size={size}, {addr_str(self.val)})"
+
+ def get_min_node(self):
+ p = self.val["root_"]
+ if p == 0:
+ return p
+ node = p.dereference()
+ while node["left_"] != 0:
+ p = node["left_"]
+ node = p.dereference()
+ return p
+
+ def get_max_node(self):
+ p = self.val["root_"]
+ if p == 0:
+ return p
+ node = p.dereference()
+ while node["right_"] != 0:
+ p = node["right_"]
+ node = p.dereference()
+ return p
+
+ def elem(self):
+ if self.val["root_"] == 0:
+ return
+ cur = self.get_min_node()
+ end = self.get_max_node()
+ while cur != end:
+ node = cur.dereference()
+ cp = node["data_"]
+ yield cp["first_"], cp["second_"]
+ cur = get_successor_node(cur)
+ if end != 0:
+ node = end.dereference()
+ cp = node["data_"]
+ yield cp["first_"], cp["second_"]
diff --git a/debug/printers/core/array_printer.py b/debug/printers/core/array_printer.py
new file mode 100644
index 0000000..5a85c91
--- /dev/null
+++ b/debug/printers/core/array_printer.py
@@ -0,0 +1,33 @@
+# debug/printers/core/array_printer.py
+
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::array"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ return f"original::array(cap={size}, {addr_str(self.val)})"
+
+ def children(self):
+ size = int(call(self.val, "size"))
+ for i in range(0, size):
+ v = call(self.val, "operator[]", f"{i}")
+ if v.type.code == gdb.TYPE_CODE_REF:
+ v = v.referenced_value()
+ yield f"[{i}]", v
+ if gdb.parameter('print pretty') > 0:
+ addr = addr_str(self.val["body"])
+ yield "body", f"{addr}"
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/autoPtr_printer.py b/debug/printers/core/autoPtr_printer.py
new file mode 100644
index 0000000..623fdfe
--- /dev/null
+++ b/debug/printers/core/autoPtr_printer.py
@@ -0,0 +1,59 @@
+# debug/printers/core/autoPtr_printer.py
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+def is_array_ptr(val):
+ type_str = str(val.type)
+
+ if "<" not in type_str or ">" not in type_str:
+ return False
+
+ inner = type_str[type_str.find("<")+1:type_str.rfind(">")]
+ parts = [p.strip() for p in inner.split(",")]
+ if len(parts) < 2:
+ return False
+ deleter_param = parts[1]
+ return deleter_param.endswith("[]>")
+
+
+class PrinterBase:
+ """Pretty printer for derived classes of autoPtr in original"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def class_name(self):
+ return "original::autoPtr"
+
+ def to_string(self):
+ ptr = int(call(self.val, "get"))
+ if ptr == 0:
+ return f"{self.class_name()}(nullptr)"
+ ref_count = self.val['ref_count']
+ loaded_ptr = call(ref_count, "operator*")
+ ref_count_base = loaded_ptr.dereference()
+ strong_refs_atomic = ref_count_base['strong_refs']
+ weak_refs_atomic = ref_count_base['weak_refs']
+ strong_refs = call(strong_refs_atomic, "operator*")
+ weak_refs = call(weak_refs_atomic, "operator*")
+ strong_refs = to_int(strong_refs, U_INTEGER_SIZE)
+ weak_refs = to_int(weak_refs, U_INTEGER_SIZE)
+ return f"{self.class_name()}(strong refs={strong_refs}, weak refs={weak_refs}, {addr_str(ptr)})"
+
+ def children(self):
+ ptr = call(self.val, "get")
+ ptr_val = int(ptr)
+
+ if ptr_val != 0:
+ if is_array_ptr(self.val):
+ yield "array", f"@{ptr_val:#x}"
+ else:
+ yield "object", ptr.dereference()
+ if gdb.parameter('print pretty') > 0:
+ yield "ref count", self.val["ref_count"]
+ yield "alias ptr", self.val["alias_ptr"]
\ No newline at end of file
diff --git a/debug/printers/core/bitSet_printer.py b/debug/printers/core/bitSet_printer.py
new file mode 100644
index 0000000..6393b52
--- /dev/null
+++ b/debug/printers/core/bitSet_printer.py
@@ -0,0 +1,30 @@
+# debug/printers/core/bitSet_printer.py
+
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::bitset"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ cnt = int(call(self.val, "count"))
+ return f"original::bitset(count={cnt}, cap={size}, {addr_str(self.val)})"
+
+ def children(self):
+ size = int(call(self.val, "size"))
+ for i in range(0, size):
+ yield f"[{i}]", call(self.val, "get", f"{i}")
+ if gdb.parameter('print pretty') > 0:
+ yield "map", self.val["map"]
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/blocksList_printer.py b/debug/printers/core/blocksList_printer.py
new file mode 100644
index 0000000..d5563d7
--- /dev/null
+++ b/debug/printers/core/blocksList_printer.py
@@ -0,0 +1,36 @@
+# debug/printers/core/blocksList_printer.py
+
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::blocksList"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ capacity = int(call(self.val["map"], "size")) * 16
+ return f"original::blocksList(size={size}, cap={capacity}, {addr_str(self.val)})"
+
+ def children(self):
+ size = int(call(self.val, "size"))
+ for i in range(0, size):
+ v = call(self.val, "operator[]", f"{i}")
+ if v.type.code == gdb.TYPE_CODE_REF:
+ v = v.referenced_value()
+ yield f"[{i}]", v
+ if gdb.parameter('print pretty') > 0:
+ yield "first", self.val["first_"]
+ yield "last", self.val["last_"]
+ yield "first block", self.val["first_block"]
+ yield "last block", self.val["last_block"]
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/chain_printer.py b/debug/printers/core/chain_printer.py
new file mode 100644
index 0000000..4b3eed3
--- /dev/null
+++ b/debug/printers/core/chain_printer.py
@@ -0,0 +1,30 @@
+# debug/printers/core/chain_printer.py
+
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::chain"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ return f"original::chain(size={size}, {addr_str(self.val)})"
+
+ def children(self):
+ size = int(call(self.val, "size"))
+ p = self.val["begin_"]
+ for i in range(0, size):
+ node = p.dereference()
+ yield f"[{i}]", node["data_"]
+ p = node["next"]
+ if gdb.parameter('print pretty') > 0:
+ yield "begin", self.val["begin_"]
+ yield "end", self.val["end_"]
\ No newline at end of file
diff --git a/debug/printers/core/containerAdaptor_printer.py b/debug/printers/core/containerAdaptor_printer.py
new file mode 100644
index 0000000..63bbcfd
--- /dev/null
+++ b/debug/printers/core/containerAdaptor_printer.py
@@ -0,0 +1,23 @@
+# debug/printers/core/containerAdaptor_printer.py
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class PrinterBase:
+ """Pretty printer for derived classes of containerAdaptor in original"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def class_name(self):
+ return "original::containerAdaptor"
+
+ def to_string(self):
+ return f"{self.class_name()}({addr_str(self.val)})"
+
+ def children(self):
+ yield "serial", self.val["serial_"]
\ No newline at end of file
diff --git a/debug/printers/core/couple_printer.py b/debug/printers/core/couple_printer.py
new file mode 100644
index 0000000..2e62aa9
--- /dev/null
+++ b/debug/printers/core/couple_printer.py
@@ -0,0 +1,24 @@
+# debug/printers/core/couple_printer.py
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::couple"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return f"original::couple({addr_str(self.val)})"
+
+ def children(self):
+ yield "[0]", self.val['first_']
+ yield "[1]", self.val['second_']
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/deque_printerr.py b/debug/printers/core/deque_printerr.py
new file mode 100644
index 0000000..9dc04dd
--- /dev/null
+++ b/debug/printers/core/deque_printerr.py
@@ -0,0 +1,14 @@
+# debug/printers/core/deque_printer.py
+
+import gdb
+from containerAdaptor_printer import PrinterBase as Base
+
+
+class Printer(Base):
+ """Pretty printer for original::deque"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::deque"
\ No newline at end of file
diff --git a/debug/printers/core/forwardChain_printer.py b/debug/printers/core/forwardChain_printer.py
new file mode 100644
index 0000000..c428632
--- /dev/null
+++ b/debug/printers/core/forwardChain_printer.py
@@ -0,0 +1,28 @@
+# debug/printers/core/forwardChain_printer.py
+
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::forwardChain"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ return f"original::forwardChain({addr_str(self.val)})"
+
+ def children(self):
+ size = int(call(self.val, "size"))
+ yield "size", size
+ p = self.val["begin_"]
+ for i in range(0, size):
+ node = p.dereference()
+ yield f"[{i}]", node["data_"]
+ p = node["next"]
+ yield "begin", self.val["begin_"]
\ No newline at end of file
diff --git a/debug/printers/core/hashMap_printer.py b/debug/printers/core/hashMap_printer.py
new file mode 100644
index 0000000..7dc608f
--- /dev/null
+++ b/debug/printers/core/hashMap_printer.py
@@ -0,0 +1,24 @@
+# debug/printers/core/hashMap_printer.py
+
+import gdb
+from hashTable_printer import PrinterBase as Base
+
+
+class Printer(Base):
+ """Pretty printer for original::hashMap"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::hashMap"
+
+ def children(self):
+ for i, cp in enumerate(self.elem()):
+ yield f"[{i}].key", cp[0]
+ yield f"[{i}].value", cp[1]
+ if gdb.parameter('print pretty') > 0:
+ yield "buckets", self.val["buckets"]
+
+ def display_hint(self):
+ return "map"
\ No newline at end of file
diff --git a/debug/printers/core/hashSet_printer.py b/debug/printers/core/hashSet_printer.py
new file mode 100644
index 0000000..1c97e88
--- /dev/null
+++ b/debug/printers/core/hashSet_printer.py
@@ -0,0 +1,23 @@
+# debug/printers/core/hashSet_printer.py
+
+import gdb
+from hashTable_printer import PrinterBase as Base
+
+
+class Printer(Base):
+ """Pretty printer for original::hashSet"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::hashSet"
+
+ def children(self):
+ for i, cp in enumerate(self.elem()):
+ yield f"[{i}]", cp[0]
+ if gdb.parameter('print pretty') > 0:
+ yield "buckets", self.val["buckets"]
+
+ def display_hint(self):
+ return "array"
diff --git a/debug/printers/core/hashTable_printer.py b/debug/printers/core/hashTable_printer.py
new file mode 100644
index 0000000..fb8958c
--- /dev/null
+++ b/debug/printers/core/hashTable_printer.py
@@ -0,0 +1,39 @@
+# debug/printers/core/hashTable_printer.py
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class PrinterBase:
+ """Pretty printer for derived classes of hashTable in original"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def class_name(self):
+ return "original::hashTable"
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ return f"{self.class_name()}(size={size}, {addr_str(self.val)})"
+
+ def elem(self):
+ size = int(call(self.val, "size"))
+ if size == 0:
+ return
+ cnt = 0
+ buckets = self.val['buckets']
+ length = int(call(buckets, "size"))
+ for i in range(length):
+ p = call(buckets, "operator[]", f"{i}")
+ while p != 0:
+ node = p.dereference()
+ cp = node["data_"]
+ yield cp["first_"], cp["second_"]
+ cnt += 1
+ if cnt == size:
+ return
+ p = node["next_"]
diff --git a/debug/printers/core/ownerPtr_printer.py b/debug/printers/core/ownerPtr_printer.py
new file mode 100644
index 0000000..49d82f8
--- /dev/null
+++ b/debug/printers/core/ownerPtr_printer.py
@@ -0,0 +1,15 @@
+# debug/printers/core/ownerPtr_printer.py
+
+import gdb
+
+from autoPtr_printer import PrinterBase as Base
+class Printer(Base):
+ """Pretty printer for original::ownerPtr"""
+
+
+ def __init__(self, val):
+ super().__init__(val)
+
+
+ def class_name(self):
+ return "original::ownerPtr"
\ No newline at end of file
diff --git a/debug/printers/core/prique_printer.py b/debug/printers/core/prique_printer.py
new file mode 100644
index 0000000..4b95bf6
--- /dev/null
+++ b/debug/printers/core/prique_printer.py
@@ -0,0 +1,20 @@
+# debug/printers/core/prique_printer.py
+
+import gdb
+from containerAdaptor_printer import PrinterBase as Base
+
+
+class Printer(Base):
+ """Pretty printer for original::prique"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::prique"
+
+ def children(self):
+ for _, e in enumerate(super().children()):
+ yield e
+ if gdb.parameter('print pretty') > 0:
+ yield "compare", self.val["compare_"]
\ No newline at end of file
diff --git a/debug/printers/core/queue_printer.py b/debug/printers/core/queue_printer.py
new file mode 100644
index 0000000..f9a6e45
--- /dev/null
+++ b/debug/printers/core/queue_printer.py
@@ -0,0 +1,14 @@
+# debug/printers/core/queue_printer.py
+
+import gdb
+from containerAdaptor_printer import PrinterBase as Base
+
+
+class Printer(Base):
+ """Pretty printer for original::queue"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::queue"
\ No newline at end of file
diff --git a/debug/printers/core/stack_printer.py b/debug/printers/core/stack_printer.py
new file mode 100644
index 0000000..7fcba7d
--- /dev/null
+++ b/debug/printers/core/stack_printer.py
@@ -0,0 +1,14 @@
+# debug/printers/core/stack_printer.py
+
+import gdb
+from containerAdaptor_printer import PrinterBase as Base
+
+
+class Printer(Base):
+ """Pretty printer for original::stack"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::stack"
\ No newline at end of file
diff --git a/debug/printers/core/strongPtr_printer.py b/debug/printers/core/strongPtr_printer.py
new file mode 100644
index 0000000..629c30b
--- /dev/null
+++ b/debug/printers/core/strongPtr_printer.py
@@ -0,0 +1,15 @@
+# debug/printers/core/strongPtr_printer.py
+
+import gdb
+
+from autoPtr_printer import PrinterBase as Base
+class Printer(Base):
+ """Pretty printer for original::strongPtr"""
+
+
+ def __init__(self, val):
+ super().__init__(val)
+
+
+ def class_name(self):
+ return "original::strongPtr"
\ No newline at end of file
diff --git a/debug/printers/core/treeMap_printer.py b/debug/printers/core/treeMap_printer.py
new file mode 100644
index 0000000..346f70c
--- /dev/null
+++ b/debug/printers/core/treeMap_printer.py
@@ -0,0 +1,31 @@
+# debug/printers/core/treeMap_printer.py
+
+import gdb
+from RBTree_printer import PrinterBase as Base
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer(Base):
+ """Pretty printer for original::treeMap"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::treeMap"
+
+ def children(self):
+ for i, cp in enumerate(self.elem()):
+ yield f"[{i}].key", cp[0]
+ yield f"[{i}].value", cp[1]
+ if gdb.parameter('print pretty') > 0:
+ addr_root = addr_str(self.val["root_"])
+ addr_cmp = addr_str(self.val["compare_"])
+ yield "root", f"{addr_root}"
+ yield "compare", f"{addr_cmp}"
+
+ def display_hint(self):
+ return "map"
\ No newline at end of file
diff --git a/debug/printers/core/treeSet_printer.py b/debug/printers/core/treeSet_printer.py
new file mode 100644
index 0000000..df2bbd8
--- /dev/null
+++ b/debug/printers/core/treeSet_printer.py
@@ -0,0 +1,30 @@
+# debug/printers/core/treeSet_printer.py
+
+import gdb
+from RBTree_printer import PrinterBase as Base
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer(Base):
+ """Pretty printer for original::treeSet"""
+
+ def __init__(self, val):
+ super().__init__(val)
+
+ def class_name(self):
+ return "original::treeSet"
+
+ def children(self):
+ for i, cp in enumerate(self.elem()):
+ yield f"[{i}]", cp[0]
+ if gdb.parameter('print pretty') > 0:
+ addr_root = addr_str(self.val["root_"])
+ addr_cmp = addr_str(self.val["compare_"])
+ yield "root", f"{addr_root}"
+ yield "compare", f"{addr_cmp}"
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/tuple_printer.py b/debug/printers/core/tuple_printer.py
new file mode 100644
index 0000000..88c1fff
--- /dev/null
+++ b/debug/printers/core/tuple_printer.py
@@ -0,0 +1,46 @@
+# debug/printers/core/tuple_printer.py
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::tuple"""
+
+ def __init__(self, val):
+ self.val = val
+ self.size = 0
+ try:
+ elems = val['elems']
+ current = elems
+ while True:
+ try:
+ _ = current['cur_elem']
+ self.size += 1
+ current = current['next']
+ except gdb.error:
+ break
+ except gdb.error:
+ self.size = 0
+
+ def to_string(self):
+ return f"original::tuple(size={self.size}, {addr_str(self.val)})"
+
+ def children(self):
+ elems = self.val['elems']
+ current = elems
+ index = 0
+ while True:
+ try:
+ elem = current['cur_elem']
+ yield f"[{index}]", elem
+ index += 1
+ current = current['next']
+ except gdb.error:
+ break
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/vector_printer.py b/debug/printers/core/vector_printer.py
new file mode 100644
index 0000000..cf69b0f
--- /dev/null
+++ b/debug/printers/core/vector_printer.py
@@ -0,0 +1,34 @@
+# debug/printers/core/vector_printer.py
+
+
+import gdb
+import sys
+import os
+sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+from utils import *
+
+
+class Printer:
+ """Pretty printer for original::vector"""
+
+ def __init__(self, val):
+ self.val = val
+
+ def to_string(self):
+ size = int(call(self.val, "size"))
+ capacity = self.val["max_size"]
+ return f"original::vector(size={size}, cap={capacity}, {addr_str(self.val)})"
+
+ def children(self):
+ size = int(call(self.val, "size"))
+ for i in range(0, size):
+ v = call(self.val, "operator[]", f"{i}")
+ if v.type.code == gdb.TYPE_CODE_REF:
+ v = v.referenced_value()
+ yield f"[{i}]", v
+ if gdb.parameter('print pretty') > 0:
+ yield "max size", self.val["max_size"]
+ yield "inner begin", self.val["inner_begin"]
+
+ def display_hint(self):
+ return "array"
\ No newline at end of file
diff --git a/debug/printers/core/weakPtr_printer.py b/debug/printers/core/weakPtr_printer.py
new file mode 100644
index 0000000..2333413
--- /dev/null
+++ b/debug/printers/core/weakPtr_printer.py
@@ -0,0 +1,15 @@
+# debug/printers/core/weakPtr_printer.py
+
+import gdb
+
+from autoPtr_printer import PrinterBase as Base
+class Printer(Base):
+ """Pretty printer for original::weakPtr"""
+
+
+ def __init__(self, val):
+ super().__init__(val)
+
+
+ def class_name(self):
+ return "original::weakPtr"
\ No newline at end of file
diff --git a/debug/printers/utils.py b/debug/printers/utils.py
new file mode 100644
index 0000000..f8e7da2
--- /dev/null
+++ b/debug/printers/utils.py
@@ -0,0 +1,37 @@
+# debug/printers/utils.py
+
+import gdb
+
+
+U_INTEGER_SIZE = 4
+
+def to_int(val, size = 8):
+ mask = (1 << (size * 8)) - 1
+ v = int(val)
+ return v & mask
+
+def address(obj):
+ try:
+ return int(obj.address) if obj.address else None
+ except gdb.error:
+ return None
+
+def addr_str(item):
+ if isinstance(item, int) or isinstance(item, str):
+ return f"@{item:#x}"
+ return f"@{address(item):#x}"
+
+def type_name(obj):
+ return obj.type.name
+
+def call(obj, method_name, *args):
+ try:
+ if obj.type.code == gdb.TYPE_CODE_REF:
+ obj = obj.referenced_value()
+ args_str = ', '.join(str(arg) for arg in args)
+ addr = address(obj)
+ expr = f'(({type_name(obj)}*)({addr}))->{method_name}({args_str})'
+ return gdb.parse_and_eval(expr)
+ except Exception as e:
+ print(f"Error calling {method_name} on {obj}: {e}")
+ return None
diff --git a/src/core/RBTree.h b/src/core/RBTree.h
index 4e2d01b..713f737 100644
--- a/src/core/RBTree.h
+++ b/src/core/RBTree.h
@@ -38,7 +38,7 @@ namespace original {
typename ALLOC = allocator,
typename Compare = increaseComparator>
class RBTree {
- protected:
+ public:
/**
* @class RBNode
@@ -200,10 +200,10 @@ namespace original {
static void connect(RBNode* parent, RBNode* child, bool is_left);
};
- using color = typename RBNode::color; ///< Color type alias
+ using color = RBNode::color; ///< Color type alias
static constexpr color BLACK = color::BLACK; ///< Black color constant
static constexpr color RED = color::RED; ///< Red color constant
- using rebind_alloc_node = typename ALLOC::template rebind_alloc; ///< Rebound allocator type
+ using rebind_alloc_node = ALLOC::template rebind_alloc; ///< Rebound allocator type
RBNode* root_; ///< Root node pointer
u_integer size_; ///< Number of elements
@@ -460,7 +460,7 @@ namespace original {
* @brief Destructor
* @details Cleans up all tree nodes and allocated memory
*/
- ~RBTree();
+ virtual ~RBTree();
};
}
@@ -476,7 +476,7 @@ original::RBTree::RBNode::RBNode(const RBNode &o
}
template
-typename original::RBTree::RBNode&
+original::RBTree::RBNode&
original::RBTree::RBNode::operator=(const RBNode &other) {
if (this == &other)
return *this;
@@ -539,38 +539,38 @@ void original::RBTree::RBNode::setValue(const V_
}
template
-typename original::RBTree::RBNode::color
+original::RBTree::RBNode::color
original::RBTree::RBNode::getColor() const {
return this->color_;
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::RBNode::getPParent() const {
return this->parent_;
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::RBNode::getPLeft() const {
return this->left_;
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::RBNode::getPRight() const {
return this->right_;
}
template
-typename original::RBTree::RBNode*&
+original::RBTree::RBNode*&
original::RBTree::RBNode::getPLeftRef()
{
return this->left_;
}
template
-typename original::RBTree::RBNode*&
+original::RBTree::RBNode*&
original::RBTree::RBNode::getPRightRef()
{
return this->right_;
@@ -617,7 +617,7 @@ original::RBTree::Iterator::Iterator(const Itera
}
template
-typename original::RBTree::Iterator&
+original::RBTree::Iterator&
original::RBTree::Iterator::operator=(const Iterator& other)
{
if (this == &other)
@@ -704,7 +704,7 @@ bool original::RBTree::Iterator::isValid() const
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::treeCopy() const {
if (!this->root_) {
return nullptr;
@@ -740,7 +740,7 @@ original::RBTree::treeCopy() const {
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::getPrecursorNode(RBNode *cur) const {
if (!cur)
return nullptr;
@@ -762,7 +762,7 @@ original::RBTree::getPrecursorNode(RBNode *cur)
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::getSuccessorNode(RBNode *cur) const {
if (!cur)
return nullptr;
@@ -784,7 +784,7 @@ original::RBTree::getSuccessorNode(RBNode *cur)
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::getMinNode() const
{
if (!root_) return nullptr;
@@ -797,7 +797,7 @@ original::RBTree::getMinNode() const
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::getMaxNode() const
{
if (!this->root_) {
@@ -812,7 +812,7 @@ original::RBTree::getMaxNode() const
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::replaceNode(RBNode* src, RBNode* tar)
{
auto moved_src = this->createNode(std::move(*src));
@@ -829,7 +829,7 @@ original::RBTree::replaceNode(RBNode* src, RBNod
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::createNode(const K_TYPE &key, const V_TYPE &value,
color color, RBNode* parent,
RBNode* left, RBNode* right) const {
@@ -839,7 +839,7 @@ original::RBTree::createNode(const K_TYPE &key,
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::createNode(RBNode&& other_node) const
{
auto node = this->rebind_alloc.allocate(1);
@@ -870,7 +870,7 @@ bool original::RBTree::highPriority(const K_TYPE
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::rotateLeft(RBNode *cur) {
RBNode* child_left = cur;
RBNode* child_root = child_left->getPRight();
@@ -884,7 +884,7 @@ original::RBTree::rotateLeft(RBNode *cur) {
}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::rotateRight(RBNode *cur) {
RBNode* child_right = cur;
RBNode* child_root = cur->getPLeft();
@@ -1117,7 +1117,7 @@ original::RBTree::RBTree(Compare compare)
: root_(nullptr), size_(0), compare_(std::move(compare)) {}
template
-typename original::RBTree::RBNode*
+original::RBTree::RBNode*
original::RBTree::find(const K_TYPE &key) const {
auto cur = this->root_;
while (cur){
diff --git a/src/core/allocator.h b/src/core/allocator.h
index 5d666f7..271c614 100644
--- a/src/core/allocator.h
+++ b/src/core/allocator.h
@@ -488,15 +488,15 @@ original::objPoolAllocator& original::objPoolAllocator::operator+=(o
if (this == &other)
return *this;
- auto size_class_count_max = max(this->size_class_count, other.size_class_count);
- auto chunk_count_init_max = max(this->chunk_count_init, other.chunk_count_init);
+ auto size_class_count_max = maximum(this->size_class_count, other.size_class_count);
+ auto chunk_count_init_max = maximum(this->chunk_count_init, other.chunk_count_init);
auto chunk_count_max = allocators::malloc(size_class_count_max);
auto free_list_head_max = allocators::malloc(size_class_count_max);
auto chunks_available_max = allocators::malloc(size_class_count_max);
for (u_integer i = 0; i < size_class_count_max; i++) {
if (i < this->size_class_count && i < other.size_class_count) {
- chunk_count_max[i] = max(this->chunk_count[i], other.chunk_count[i]);
+ chunk_count_max[i] = maximum(this->chunk_count[i], other.chunk_count[i]);
chunks_available_max[i] = this->chunks_available[i] + other.chunks_available[i];
auto cur_list_head_i = other.free_list_head[i];
if (cur_list_head_i) {
@@ -597,7 +597,7 @@ TYPE* original::objPoolAllocator::allocate(const u_integer size)
}
if (!this->free_list_head[index] || this->chunks_available[index] * (static_cast(1) << index) < size) {
- this->chunkAllocate(max(1, this->chunk_count[index]), index);
+ this->chunkAllocate(maximum(1, this->chunk_count[index]), index);
}
auto cur_ptr = this->free_list_head[index];
diff --git a/src/core/bitSet.h b/src/core/bitSet.h
index ed1216a..3cf4267 100644
--- a/src/core/bitSet.h
+++ b/src/core/bitSet.h
@@ -674,12 +674,12 @@ namespace std {
auto* other_it = dynamic_cast(&other);
if (other_it == nullptr)
return this > &other ?
- std::numeric_limits::max() :
- std::numeric_limits::min();
+ (std::numeric_limits::max)() :
+ (std::numeric_limits::min)();
if (this->container_ != other_it->container_)
return this->container_ > other_it->container_ ?
- std::numeric_limits::max() :
- std::numeric_limits::min();
+ (std::numeric_limits::max)() :
+ (std::numeric_limits::min)();
return toOuterIdx(this->cur_block, this->cur_bit) - toOuterIdx(other_it->cur_block, other_it->cur_bit);
}
@@ -800,7 +800,7 @@ namespace std {
}
auto nb = bitSet(new_size);
- const u_integer blocks_min = min(nb.map.size(),
+ const u_integer blocks_min = minimum(nb.map.size(),
this->map.size());
for (u_integer i = 0; i < blocks_min; i++) {
nb.map.set(i, this->map.get(i));
diff --git a/src/core/blocksList.h b/src/core/blocksList.h
index 06ff3ce..d7aba84 100644
--- a/src/core/blocksList.h
+++ b/src/core/blocksList.h
@@ -742,12 +742,12 @@ namespace std {
auto* other_it = dynamic_cast(&other);
if (other_it == nullptr)
return this > &other ?
- std::numeric_limits::max() :
- std::numeric_limits::min();
+ (std::numeric_limits::max)() :
+ (std::numeric_limits::min)();
if (this->container_ != other_it->container_)
return this->container_ > other_it->container_ ?
- std::numeric_limits::max() :
- std::numeric_limits::min();
+ (std::numeric_limits::max)() :
+ (std::numeric_limits::min)();
return static_cast(innerIdxToAbsIdx(this->cur_block, this->cur_pos)) -
static_cast(innerIdxToAbsIdx(other_it->cur_block, other_it->cur_pos));
diff --git a/src/core/chain.h b/src/core/chain.h
index 581ee41..b92083d 100644
--- a/src/core/chain.h
+++ b/src/core/chain.h
@@ -591,7 +591,12 @@ namespace std {
}
template
- original::chain::chain(ALLOC alloc) : baseList(std::move(alloc)), size_(0), rebind_alloc(std::move(rebind_alloc_node{}))
+ original::chain::chain(ALLOC alloc)
+ : baseList(std::move(alloc)),
+ size_(0),
+ begin_(nullptr),
+ end_(nullptr),
+ rebind_alloc(std::move(rebind_alloc_node{}))
{
chainInit();
}
diff --git a/src/core/config.h b/src/core/config.h
index b373d2e..741358d 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -17,22 +17,37 @@
* @{
*/
+// Initialize all platform macros to false
+#define ORIGINAL_PLATFORM_WINDOWS 0
+#define ORIGINAL_PLATFORM_WINDOWS_32 0
+#define ORIGINAL_PLATFORM_WINDOWS_64 0
+#define ORIGINAL_PLATFORM_LINUX 0
+#define ORIGINAL_PLATFORM_MACOS 0
+#define ORIGINAL_PLATFORM_UNIX 0
+#define ORIGINAL_PLATFORM_UNKNOWN 0
+
+// Override based on actual platform detection
#if defined(_WIN32) || defined(_WIN64)
-#define ORIGINAL_PLATFORM_WINDOWS 1
-#ifdef _WIN64
-#define ORIGINAL_PLATFORM_WINDOWS_64 1
-#elif
-#define ORIGINAL_PLATFORM_WINDOWS_32 1
-#else
- #define ORIGINAL_PLATFORM_WINDOWS 0
-#endif
+ #undef ORIGINAL_PLATFORM_WINDOWS
+ #define ORIGINAL_PLATFORM_WINDOWS 1
+ #ifdef _WIN64
+ #undef ORIGINAL_PLATFORM_WINDOWS_64
+ #define ORIGINAL_PLATFORM_WINDOWS_64 1
+ #else
+ #undef ORIGINAL_PLATFORM_WINDOWS_32
+ #define ORIGINAL_PLATFORM_WINDOWS_32 1
+ #endif
#elif defined(__linux__)
-#define ORIGINAL_PLATFORM_LINUX 1
+ #undef ORIGINAL_PLATFORM_LINUX
+ #define ORIGINAL_PLATFORM_LINUX 1
#elif defined(__APPLE__) && defined(__MACH__)
+ #undef ORIGINAL_PLATFORM_MACOS
#define ORIGINAL_PLATFORM_MACOS 1
#elif defined(__unix__)
+ #undef ORIGINAL_PLATFORM_UNIX
#define ORIGINAL_PLATFORM_UNIX 1
#else
+ #undef ORIGINAL_PLATFORM_UNKNOWN
#define ORIGINAL_PLATFORM_UNKNOWN 1
#endif
/** @} */ // end of PlatformDetection group
@@ -42,16 +57,28 @@
* @brief Macros for identifying the compiler being used
* @{
*/
+
+// Initialize all compiler macros to false
+#define ORIGINAL_COMPILER_CLANG 0
+#define ORIGINAL_COMPILER_GCC 0
+#define ORIGINAL_COMPILER_MSVC 0
+#define ORIGINAL_COMPILER_UNKNOWN 0
+
+// Override based on actual compiler detection
#if defined(__clang__)
-#define ORIGINAL_COMPILER_CLANG 1
+ #undef ORIGINAL_COMPILER_CLANG
+ #define ORIGINAL_COMPILER_CLANG 1
#define ORIGINAL_COMPILER_VERSION __clang_major__.__clang_minor__.__clang_patchlevel__
#elif defined(__GNUC__) || defined(__GNUG__)
-#define ORIGINAL_COMPILER_GCC 1
-#define ORIGINAL_COMPILER_VERSION __GNUC__.__GNUC_MINOR__.__GNUC_PATCHLEVEL__
+ #undef ORIGINAL_COMPILER_GCC
+ #define ORIGINAL_COMPILER_GCC 1
+ #define ORIGINAL_COMPILER_VERSION __GNUC__.__GNUC_MINOR__.__GNUC_PATCHLEVEL__
#elif defined(_MSC_VER)
-#define ORIGINAL_COMPILER_MSVC 1
+ #undef ORIGINAL_COMPILER_MSVC
+ #define ORIGINAL_COMPILER_MSVC 1
#define ORIGINAL_COMPILER_VERSION _MSC_VER
#else
+ #undef ORIGINAL_COMPILER_UNKNOWN
#define ORIGINAL_COMPILER_UNKNOWN 1
#endif
/** @} */ // end of CompilerDetection group
@@ -228,50 +255,71 @@ namespace original {
* @{
*/
- /**
- * @brief Unsigned 8-bit integer type (byte)
- * @details Typically used for raw byte manipulation and binary data handling.
- * @note Range: 0 to 255
- * @note Equivalent to std::uint8_t
- */
- using byte = std::uint8_t;
+ #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
+ /**
+ * @brief Unsigned 8-bit integer type (byte)
+ * @details Typically used for raw byte manipulation and binary data handling.
+ * @note Range: 0 to 255
+ * @note Equivalent to std::uint8_t
+ */
+ using byte = std::uint8_t;
+ #elif ORIGINAL_COMPILER_MSVC
+ using byte = uint8_t;
+ #endif
- /**
- * @brief Signed 8-bit integer type
- * @details Used for small signed numeric values.
- * @note Range: -128 to 127
- * @note Equivalent to std::int8_t
- */
- using s_byte = std::int8_t;
- /**
- * @brief 64-bit signed integer type for arithmetic operations
- * @details Primary type for most arithmetic operations where large range is needed.
- * @note Range: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
- * @note Use this for calculations that may require large numbers
- * @note Equivalent to std::int64_t
- */
- using integer = std::int64_t;
+ #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
+ /**
+ * @brief Signed 8-bit integer type
+ * @details Used for small signed numeric values.
+ * @note Range: -128 to 127
+ * @note Equivalent to std::int8_t
+ */
+ using s_byte = std::int8_t;
+ #elif ORIGINAL_COMPILER_MSVC
+ using s_byte = int8_t;
+ #endif
- /**
- * @brief 32-bit unsigned integer type for sizes and indexes
- * @details Used for array indexing, sizes, and counts where negative values are not needed.
- * @note Range: 0 to 4,294,967,295
- * @warning Not suitable for very large containers (>4GB)
- * @note Equivalent to std::uint32_t
- */
- using u_integer = std::uint32_t;
+ #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
+ /**
+ * @brief 64-bit signed integer type for arithmetic operations
+ * @details Primary type for most arithmetic operations where large range is needed.
+ * @note Range: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
+ * @note Use this for calculations that may require large numbers
+ * @note Equivalent to std::int64_t
+ */
+ using integer = std::int64_t;
+ #elif ORIGINAL_COMPILER_MSVC
+ using integer = int64_t;
+ #endif
- /**
- * @brief 64-bit unsigned integer type
- * @details Large unsigned integer type for big sizes and counters.
- * Guaranteed to be exactly 64 bits wide across all platforms.
- * @note Range: 0 to 18,446,744,073,709,551,615
- * @note Preferred for: Large containers, filesystem sizes, big counters
- * @see u_integer For smaller unsigned needs
- * @note Equivalent to std::uint64_t
- */
- using ul_integer = std::uint64_t;
+ #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
+ /**
+ * @brief 32-bit unsigned integer type for sizes and indexes
+ * @details Used for array indexing, sizes, and counts where negative values are not needed.
+ * @note Range: 0 to 4,294,967,295
+ * @warning Not suitable for very large containers (>4GB)
+ * @note Equivalent to std::uint32_t
+ */
+ using u_integer = std::uint32_t;
+ #elif ORIGINAL_COMPILER_MSVC
+ using u_integer = uint32_t;
+ #endif
+
+ #if ORIGINAL_COMPILER_GCC || ORIGINAL_COMPILER_CLANG
+ /**
+ * @brief 64-bit unsigned integer type
+ * @details Large unsigned integer type for big sizes and counters.
+ * Guaranteed to be exactly 64 bits wide across all platforms.
+ * @note Range: 0 to 18,446,744,073,709,551,615
+ * @note Preferred for: Large containers, filesystem sizes, big counters
+ * @see u_integer For smaller unsigned needs
+ * @note Equivalent to std::uint64_t
+ */
+ using ul_integer = std::uint64_t;
+ #elif ORIGINAL_COMPILER_MSVC
+ using ul_integer = uint64_t;
+ #endif
/**
* @brief Double-precision floating-point type
diff --git a/src/core/filterStream.h b/src/core/filterStream.h
index b903183..0705e2e 100644
--- a/src/core/filterStream.h
+++ b/src/core/filterStream.h
@@ -26,14 +26,15 @@ namespace original{
template
class filterStream
{
- ///< Null filter instance used as operator placeholder in stream processing
- static const strongPtr> nullFilter;
-
+ public:
/// @internal Operator types for postfix conversion
enum class opts{AND = 1, OR = 0, NOT = 2, LEFT_BRACKET = 3, RIGHT_BRACKET = 4};
+ private:
+ ///< Null filter instance used as operator placeholder in stream processing
+ static const strongPtr> nullFilter;
- mutable chain>> stream; ///< Filter operand chain
- mutable chain ops; ///< Operator sequence storage
+ mutable chain>> stream{}; ///< Filter operand chain
+ mutable chain ops{}; ///< Operator sequence storage
mutable bool flag; ///< Postfix conversion status flag
protected:
diff --git a/src/core/forwardChain.h b/src/core/forwardChain.h
index a00e4ee..eee4eda 100644
--- a/src/core/forwardChain.h
+++ b/src/core/forwardChain.h
@@ -559,7 +559,10 @@ namespace original {
template
original::forwardChain::forwardChain(ALLOC alloc)
- : baseList(std::move(alloc)), size_(0) , rebind_alloc(std::move(rebind_alloc_node{}))
+ : baseList(std::move(alloc)),
+ size_(0),
+ begin_(nullptr),
+ rebind_alloc(std::move(rebind_alloc_node{}))
{
this->chainInit();
}
diff --git a/src/core/hashTable.h b/src/core/hashTable.h
index 5b70e87..e9bc169 100644
--- a/src/core/hashTable.h
+++ b/src/core/hashTable.h
@@ -4,7 +4,6 @@
#include "allocator.h"
#include "couple.h"
#include "hash.h"
-#include "singleDirectionIterator.h"
#include "vector.h"
#include "wrapper.h"
@@ -53,7 +52,7 @@ namespace original {
*/
template, typename HASH = hash>
class hashTable{
- protected:
+ public:
/**
* @class hashNode
@@ -165,13 +164,13 @@ namespace original {
* @typedef rebind_alloc_node
* @brief Rebound allocator type for node storage
*/
- using rebind_alloc_node = typename ALLOC::template rebind_alloc;
+ using rebind_alloc_node = ALLOC::template rebind_alloc;
/**
* @typedef rebind_alloc_pointer
* @brief Rebound allocator type for pointer storage
*/
- using rebind_alloc_pointer = typename ALLOC::template rebind_alloc;
+ using rebind_alloc_pointer = ALLOC::template rebind_alloc;
/**
* @typedef buckets_type
@@ -492,7 +491,7 @@ namespace original {
* @brief Destroys hashTable
* @details Cleans up all nodes and buckets
*/
- ~hashTable();
+ virtual ~hashTable();
};
}
@@ -506,7 +505,7 @@ original::hashTable::hashNode::hashNode(const hashN
}
template
-typename original::hashTable::hashNode&
+original::hashTable::hashNode&
original::hashTable::hashNode::operator=(const hashNode& other) {
if (this == &other)
return *this;
@@ -553,13 +552,13 @@ void original::hashTable::hashNode::setValue(const
}
template
-typename original::hashTable::hashNode*
+original::hashTable::hashNode*
original::hashTable::hashNode::getPPrev() const {
throw unSupportedMethodError();
}
template
-typename original::hashTable::hashNode*
+original::hashTable::hashNode*
original::hashTable::hashNode::getPNext() const {
return this->next_;
}
@@ -611,7 +610,7 @@ original::hashTable::Iterator::Iterator(const Itera
}
template
-typename original::hashTable::Iterator&
+original::hashTable::Iterator&
original::hashTable::Iterator::operator=(const Iterator &other) {
if (this == &other)
return *this;
@@ -689,7 +688,7 @@ bool original::hashTable::Iterator::isValid() const
}
template
-typename original::hashTable::buckets_type
+original::hashTable::buckets_type
original::hashTable::bucketsCopy(const buckets_type& old_buckets) const
{
buckets_type new_buckets = buckets_type(old_buckets.size(), rebind_alloc_pointer{}, nullptr);
@@ -714,7 +713,7 @@ original::hashTable::bucketsCopy(const buckets_type
}
template
-typename original::hashTable::hashNode*
+original::hashTable::hashNode*
original::hashTable::createNode(const K_TYPE& key, const V_TYPE& value, hashNode* next) const {
auto node = this->rebind_alloc.allocate(1);
this->rebind_alloc.construct(node, key, value, next);
@@ -740,7 +739,7 @@ original::hashTable::getBucketCount() const {
}
template
-typename original::hashTable::hashNode*
+original::hashTable::hashNode*
original::hashTable::getBucket(const K_TYPE &key) const {
u_integer code = this->getHashCode(key);
return this->buckets[code];
@@ -812,7 +811,7 @@ original::hashTable::hashTable(HASH hash)
}
template
-typename original::hashTable::hashNode*
+original::hashTable::hashNode*
original::hashTable::find(const K_TYPE& key) const {
if (this->size_ == 0)
return nullptr;
diff --git a/src/core/maps.h b/src/core/maps.h
index 33ba211..c06034c 100644
--- a/src/core/maps.h
+++ b/src/core/maps.h
@@ -830,8 +830,8 @@ namespace original {
typename V_TYPE,
typename Compare = increaseComparator,
typename ALLOC = allocator>>
- class JMap final : public skipList,
- public map,
+ class JMap final : public map,
+ public skipList,
public iterable>,
public printable {
@@ -1923,8 +1923,8 @@ original::JMap::Iterator::operator-(
auto other_it = dynamic_cast(&other);
if (other_it == nullptr)
return this > &other ?
- std::numeric_limits::max() :
- std::numeric_limits::min();
+ (std::numeric_limits::max)() :
+ (std::numeric_limits::min)();
return skipListType::Iterator::operator-(*other_it);
}
@@ -1993,8 +1993,7 @@ bool original::JMap::Iterator::isValid() const {
template
original::JMap::JMap(Compare comp, ALLOC alloc)
- : skipListType(std::move(comp)) ,
- map(std::move(alloc)) {}
+ : map(std::move(alloc)), skipListType(std::move(comp)) {}
template
original::JMap::JMap(const JMap& other) : JMap() {
diff --git a/src/core/maths.h b/src/core/maths.h
index b5299d0..982b69c 100644
--- a/src/core/maths.h
+++ b/src/core/maths.h
@@ -79,7 +79,7 @@ TYPE abs(TYPE a);
* @endcode
*/
template
-TYPE max(TYPE a, TYPE b);
+TYPE maximum(TYPE a, TYPE b);
/**
* @brief Returns the smaller of two given values.
@@ -100,7 +100,7 @@ TYPE max(TYPE a, TYPE b);
* @endcode
*/
template
-TYPE min(TYPE a, TYPE b);
+TYPE minimum(TYPE a, TYPE b);
/**
* @brief Returns the result of raising a base to an exponent.
@@ -186,13 +186,13 @@ auto original::abs(TYPE a) -> TYPE
}
template
-auto original::max(TYPE a, TYPE b) -> TYPE
+auto original::maximum(TYPE a, TYPE b) -> TYPE
{
return a > b ? a : b;
}
template
-auto original::min(TYPE a, TYPE b) -> TYPE
+auto original::minimum(TYPE a, TYPE b) -> TYPE
{
return a < b ? a : b;
}
diff --git a/src/core/optional.h b/src/core/optional.h
index 9726891..f86036c 100644
--- a/src/core/optional.h
+++ b/src/core/optional.h
@@ -8,7 +8,7 @@
* @file optional.h
* @brief Type-safe optional value container
* @details Provides an alternative class that can either contain a value of type 'TYPE'
- * or be in an empty state (represented by original::none from types.h). This implementation
+ * or be in an empty state (represented by original::null from types.h). This implementation
* provides:
* - Value semantics with proper construction/destruction
* - Safe access operations with error checking
@@ -20,7 +20,7 @@
* Key features:
* - Type-safe alternative to raw pointers for optional values
* - No dynamic memory allocation (uses union storage)
- * - Explicit empty state handling with original::none
+ * - Explicit empty state handling with original::null
* - Exception-safe operations
* - STL-compatible interface
*/
@@ -33,7 +33,7 @@ namespace original {
* @tparam TYPE The type of value to store
* @details This class provides a way to represent optional values without
* using pointers. It can either contain a value of type TYPE or be empty.
- * The empty state is represented using original::none from types.h.
+ * The empty state is represented using original::null from types.h.
*
* The implementation uses a union for storage to avoid dynamic allocation
* and ensure optimal performance. All operations provide strong exception
@@ -62,18 +62,18 @@ namespace original {
class alternative {
/**
* @union storage
- * @brief Internal storage for either TYPE or none
- * @details Uses a union to store either the value type or none,
+ * @brief Internal storage for either TYPE or null
+ * @details Uses a union to store either the value type or null,
* with proper construction/destruction handling. The union ensures
* that only one member is active at any time, managed by the
- * non_none_type_ flag.
+ * non_null_type_ flag.
*/
union storage {
TYPE type_; ///< Storage for the contained value
- none none_; ///< Storage for empty state (from types.h)
+ null null_; ///< Storage for empty state (from types.h)
/**
- * @brief Default constructor (initializes to none)
+ * @brief Default constructor (initializes to null)
*/
storage() noexcept;
@@ -87,14 +87,14 @@ namespace original {
~storage();
};
- bool non_none_type_; ///< Flag indicating whether value is present (true = TYPE, false = none)
+ bool non_null_type_; ///< Flag indicating whether value is present (true = TYPE, false = null)
storage val_; ///< The actual storage union
/**
* @brief Safely destroys the current contents
* @note Properly calls destructor based on current state
- * @details If non_none_type_ is true, calls TYPE destructor,
- * otherwise calls none destructor. Ensures RAII compliance.
+ * @details If non_null_type_ is true, calls TYPE destructor,
+ * otherwise calls null destructor. Ensures RAII compliance.
*/
void destroy() noexcept;
@@ -286,11 +286,11 @@ namespace original {
explicit alternative();
/**
- * @brief Constructs from none (empty state)
- * @param n none value indicating empty state
+ * @brief Constructs from null (empty state)
+ * @param n null value indicating empty state
* @post hasValue() == false
*/
- explicit alternative(none n);
+ explicit alternative(null n);
/**
* @brief Constructs with value present
@@ -331,19 +331,19 @@ namespace original {
alternative& operator=(std::in_place_t t) noexcept;
/**
- * @brief Assignment from none to reset to empty state
- * @param n none value indicating empty state
+ * @brief Assignment from null to reset to empty state
+ * @param n null value indicating empty state
* @return Reference to this alternative
* @post hasValue() == false
* @details Resets the alternative to the empty state. This operation
* is equivalent to calling reset() but provides a more expressive syntax
- * when working with none values. The assignment clears the "present" state
+ * when working with null values. The assignment clears the "present" state
* and ensures the alternative is empty.
*
* Example usage:
* @code
* alternative flag(std::in_place); // Present state
- * flag = original::none; // Now empty
+ * flag = original::null; // Now empty
*
* if (!flag) {
* // This will execute since flag is now empty
@@ -352,14 +352,14 @@ namespace original {
* // In generic code:
* template
* void clearAlternative(alternative& opt) {
- * opt = original::none; // Works for both alternative and alternative
+ * opt = original::null; // Works for both alternative and alternative
* }
* @endcode
*
* @note This operation is noexcept and always succeeds.
* @see reset()
*/
- alternative& operator=(none n) noexcept;
+ alternative& operator=(null n) noexcept;
/**
* @brief Resets to empty state
@@ -422,7 +422,7 @@ namespace std {
template
original::alternative::storage::storage() noexcept
{
- new(&this->none_) none{};
+ new(&this->null_) null;
}
template
@@ -430,33 +430,33 @@ original::alternative::storage::~storage() {}
template
void original::alternative::destroy() noexcept {
- if (this->non_none_type_){
+ if (this->non_null_type_){
this->val_.type_.~TYPE();
- this->non_none_type_ = false;
+ this->non_null_type_ = false;
} else {
- this->val_.none_.~none();
- this->non_none_type_ = true;
+ this->val_.null_.~null();
+ this->non_null_type_ = true;
}
}
template
original::alternative::alternative()
- : non_none_type_(false), val_() {}
+ : non_null_type_(false), val_() {}
template
template
original::alternative::alternative(Args &&... args)
- : non_none_type_(true), val_() {
+ : non_null_type_(true), val_() {
new (&this->val_.type_) TYPE{ std::forward(args)... };
}
template
original::alternative::alternative(const alternative& other) {
- this->non_none_type_ = other.non_none_type_;
- if (other.non_none_type_) {
+ this->non_null_type_ = other.non_null_type_;
+ if (other.non_null_type_) {
new (&val_.type_) TYPE{ other.val_.type_ };
} else {
- new (&val_.none_) none{};
+ new (&val_.null_) null;
}
}
@@ -467,22 +467,22 @@ original::alternative::operator=(const alternative& other) {
return *this;
this->destroy();
- this->non_none_type_ = other.non_none_type_;
- if (other.non_none_type_) {
+ this->non_null_type_ = other.non_null_type_;
+ if (other.non_null_type_) {
new (&val_.type_) TYPE{ other.val_.type_ };
} else {
- new (&val_.none_) none{};
+ new (&val_.null_) null;
}
return *this;
}
template
original::alternative::alternative(alternative&& other) noexcept {
- this->non_none_type_ = other.non_none_type_;
- if (this->non_none_type_){
+ this->non_null_type_ = other.non_null_type_;
+ if (this->non_null_type_){
new (&val_.type_) TYPE{ std::move(other.val_.type_) };
} else{
- new (&val_.none_) none{};
+ new (&val_.null_) null;
}
}
@@ -493,11 +493,11 @@ original::alternative::operator=(alternative&& other) noexcept {
return *this;
this->destroy();
- this->non_none_type_ = other.non_none_type_;
- if (this->non_none_type_){
+ this->non_null_type_ = other.non_null_type_;
+ if (this->non_null_type_){
new (&val_.type_) TYPE{ std::move(other.val_.type_) };
} else{
- new (&val_.none_) none{};
+ new (&val_.null_) null;
}
return *this;
}
@@ -508,15 +508,15 @@ void original::alternative::swap(alternative& other) noexcept
if (this == &other)
return;
- std::swap(this->non_none_type_, other.non_none_type_);
+ std::swap(this->non_null_type_, other.non_null_type_);
std::swap(this->val_, other.val_);
}
template
const TYPE&
original::alternative::operator*() const {
- if (!this->non_none_type_)
- throw valueError("Dereferencing a original::none value");
+ if (!this->non_null_type_)
+ throw valueError("Dereferencing a original::null value");
return this->val_.type_;
}
@@ -524,8 +524,8 @@ original::alternative::operator*() const {
template
TYPE&
original::alternative::operator*() {
- if (!this->non_none_type_)
- throw valueError("Dereferencing a original::none value");
+ if (!this->non_null_type_)
+ throw valueError("Dereferencing a original::null value");
return this->val_.type_;
}
@@ -533,8 +533,8 @@ original::alternative::operator*() {
template
const TYPE*
original::alternative::operator->() const {
- if (!this->non_none_type_)
- throw valueError("Accessing member of a original::none value");
+ if (!this->non_null_type_)
+ throw valueError("Accessing member of a original::null value");
return &this->val_.type_;
}
@@ -542,20 +542,20 @@ original::alternative::operator->() const {
template
TYPE*
original::alternative::operator->() {
- if (!this->non_none_type_)
- throw valueError("Accessing member of a original::none value");
+ if (!this->non_null_type_)
+ throw valueError("Accessing member of a original::null value");
return &this->val_.type_;
}
template
const TYPE* original::alternative::get() const {
- return this->non_none_type_ ? &this->val_.type_ : nullptr;
+ return this->non_null_type_ ? &this->val_.type_ : nullptr;
}
template
TYPE* original::alternative::get() {
- return this->non_none_type_ ? &this->val_.type_ : nullptr;
+ return this->non_null_type_ ? &this->val_.type_ : nullptr;
}
template
@@ -567,14 +567,14 @@ template
template