First commit

This commit is contained in:
King_DuckZ 2016-10-24 00:48:30 +02:00
commit 95499e3d77
49 changed files with 10741 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
compile_commands.json
.ycm_extra_conf.py

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule "lib/vectorwrapper"]
path = lib/vectorwrapper
url = ../vectorwrapper/.git

97
CMakeLists.txt Normal file
View file

@ -0,0 +1,97 @@
cmake_minimum_required(VERSION 3.2)
project(mycurry CXX)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/include")
include(TargetArch)
include(FindPkgConfig)
set(common_gcc_flags "-Wall -Wextra -pedantic")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${common_gcc_flags}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${common_gcc_flags}")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${common_gcc_flags}")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${common_gcc_flags}")
option(CURRY_FORCE_OPENGLES "Try to chose the openGL ES renderer if available. Enable this on Raspberry Pi" OFF)
option(CURRY_RASPBERRY_PI "Compile for Raspberry Pi" OFF)
target_architecture(TARGET_ARCH)
message (STATUS "Target architecture: ${TARGET_ARCH}")
if (TARGET_ARCH MATCHES "^x86_64$")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -msse3")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -msse3")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -msse3")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -msse3")
endif (TARGET_ARCH MATCHES "^x86_64$")
if (CURRY_FORCE_OPENGLES OR CURRY_RASPBERRY_PI)
add_definitions(-DFORCE_OPENGLES)
if (CURRY_RASPBERRY_PI)
add_definitions(-DRASPBERRY_PI)
endif(CURRY_RASPBERRY_PI)
endif (CURRY_FORCE_OPENGLES OR CURRY_RASPBERRY_PI)
PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2)
find_package(PNG REQUIRED)
find_package(Boost 1.55.0 REQUIRED)
if (CURRY_RASPBERRY_PI)
message(STATUS "Will build for Raspberry Pi")
include_directories(SYSTEM
/opt/vc/include
/opt/vc/include/interface/vcos/pthreads
/opt/vc/include/interface/vmcs_host/linux
)
link_directories(
/opt/vc/lib
)
endif (CURRY_RASPBERRY_PI)
add_executable(${PROJECT_NAME}
src/main.cpp
src/sdlmain.cpp
src/ingamescene.cpp
src/sizenotifiable.cpp
src/sizeratio.cpp
)
target_include_directories(${PROJECT_NAME} SYSTEM
PRIVATE ${SDL2_INCLUDE_DIR}
PRIVATE ${PNG_INCLUDE_DIRS}
PRIVATE ${Boost_INCLUDE_DIRS}
PRIVATE lib/tree-2.81/src
)
target_include_directories(${PROJECT_NAME}
PRIVATE src
PRIVATE lib/vectorwrapper/include
)
target_link_libraries(${PROJECT_NAME}
PRIVATE ${SDL2_LIBRARIES}
PRIVATE ${PNG_LIBRARIES}
)
if (CURRY_RASPBERRY_PI)
target_link_libraries(${PROJECT_NAME}
PRIVATE bcm_host
)
endif(CURRY_RASPBERRY_PI)
target_compile_features(${PROJECT_NAME}
PRIVATE cxx_nullptr
PRIVATE cxx_range_for
PRIVATE cxx_lambdas
PRIVATE cxx_decltype_auto
PRIVATE cxx_defaulted_functions
PRIVATE cxx_deleted_functions
PRIVATE cxx_auto_type
PRIVATE cxx_defaulted_move_initializers
PRIVATE cxx_noexcept
PRIVATE cxx_rvalue_references
)
target_compile_definitions(${PROJECT_NAME}
PRIVATE ${PNG_DEFINITIONS}
)

View file

@ -0,0 +1,134 @@
# Based on the Qt 5 processor detection code, so should be very accurate
# https://qt.gitorious.org/qt/qtbase/blobs/master/src/corelib/global/qprocessordetection.h
# Currently handles arm (v5, v6, v7), x86 (32/64), ia64, and ppc (32/64)
# Regarding POWER/PowerPC, just as is noted in the Qt source,
# "There are many more known variants/revisions that we do not handle/detect."
set(archdetect_c_code "
#if defined(__arm__) || defined(__TARGET_ARCH_ARM)
#if defined(__ARM_ARCH_7__) \\
|| defined(__ARM_ARCH_7A__) \\
|| defined(__ARM_ARCH_7R__) \\
|| defined(__ARM_ARCH_7M__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 7)
#error cmake_ARCH armv7
#elif defined(__ARM_ARCH_6__) \\
|| defined(__ARM_ARCH_6J__) \\
|| defined(__ARM_ARCH_6T2__) \\
|| defined(__ARM_ARCH_6Z__) \\
|| defined(__ARM_ARCH_6K__) \\
|| defined(__ARM_ARCH_6ZK__) \\
|| defined(__ARM_ARCH_6M__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 6)
#error cmake_ARCH armv6
#elif defined(__ARM_ARCH_5TEJ__) \\
|| (defined(__TARGET_ARCH_ARM) && __TARGET_ARCH_ARM-0 >= 5)
#error cmake_ARCH armv5
#else
#error cmake_ARCH arm
#endif
#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
#error cmake_ARCH i386
#elif defined(__x86_64) || defined(__x86_64__) || defined(__amd64) || defined(_M_X64)
#error cmake_ARCH x86_64
#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
#error cmake_ARCH ia64
#elif defined(__ppc__) || defined(__ppc) || defined(__powerpc__) \\
|| defined(_ARCH_COM) || defined(_ARCH_PWR) || defined(_ARCH_PPC) \\
|| defined(_M_MPPC) || defined(_M_PPC)
#if defined(__ppc64__) || defined(__powerpc64__) || defined(__64BIT__)
#error cmake_ARCH ppc64
#else
#error cmake_ARCH ppc
#endif
#endif
#error cmake_ARCH unknown
")
# Set ppc_support to TRUE before including this file or ppc and ppc64
# will be treated as invalid architectures since they are no longer supported by Apple
function(target_architecture output_var)
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
# On OS X we use CMAKE_OSX_ARCHITECTURES *if* it was set
# First let's normalize the order of the values
# Note that it's not possible to compile PowerPC applications if you are using
# the OS X SDK version 10.6 or later - you'll need 10.4/10.5 for that, so we
# disable it by default
# See this page for more information:
# http://stackoverflow.com/questions/5333490/how-can-we-restore-ppc-ppc64-as-well-as-full-10-4-10-5-sdk-support-to-xcode-4
# Architecture defaults to i386 or ppc on OS X 10.5 and earlier, depending on the CPU type detected at runtime.
# On OS X 10.6+ the default is x86_64 if the CPU supports it, i386 otherwise.
foreach(osx_arch ${CMAKE_OSX_ARCHITECTURES})
if("${osx_arch}" STREQUAL "ppc" AND ppc_support)
set(osx_arch_ppc TRUE)
elseif("${osx_arch}" STREQUAL "i386")
set(osx_arch_i386 TRUE)
elseif("${osx_arch}" STREQUAL "x86_64")
set(osx_arch_x86_64 TRUE)
elseif("${osx_arch}" STREQUAL "ppc64" AND ppc_support)
set(osx_arch_ppc64 TRUE)
else()
message(FATAL_ERROR "Invalid OS X arch name: ${osx_arch}")
endif()
endforeach()
# Now add all the architectures in our normalized order
if(osx_arch_ppc)
list(APPEND ARCH ppc)
endif()
if(osx_arch_i386)
list(APPEND ARCH i386)
endif()
if(osx_arch_x86_64)
list(APPEND ARCH x86_64)
endif()
if(osx_arch_ppc64)
list(APPEND ARCH ppc64)
endif()
else()
file(WRITE "${CMAKE_BINARY_DIR}/arch.c" "${archdetect_c_code}")
enable_language(C)
# Detect the architecture in a rather creative way...
# This compiles a small C program which is a series of ifdefs that selects a
# particular #error preprocessor directive whose message string contains the
# target architecture. The program will always fail to compile (both because
# file is not a valid C program, and obviously because of the presence of the
# #error preprocessor directives... but by exploiting the preprocessor in this
# way, we can detect the correct target architecture even when cross-compiling,
# since the program itself never needs to be run (only the compiler/preprocessor)
try_run(
run_result_unused
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/arch.c"
COMPILE_OUTPUT_VARIABLE ARCH
CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}
)
# Parse the architecture name from the compiler output
string(REGEX MATCH "cmake_ARCH ([a-zA-Z0-9_]+)" ARCH "${ARCH}")
# Get rid of the value marker leaving just the architecture name
string(REPLACE "cmake_ARCH " "" ARCH "${ARCH}")
# If we are compiling with an unknown architecture this variable should
# already be set to "unknown" but in the case that it's empty (i.e. due
# to a typo in the code), then set it to unknown
if (NOT ARCH)
set(ARCH unknown)
endif()
endif()
set(${output_var} "${ARCH}" PARENT_SCOPE)
endfunction()

391
lib/tree-2.81/ChangeLog Normal file
View file

@ -0,0 +1,391 @@
2011-08-23 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Brown paper bag release 2.81.
2011-08-23 Kasper Peeters <kasper@phi-sci.com>
* Released 2.8
* License updated.
2010-12-24 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Added a number of asserts to trip when passing invalid iterators
to append_child/prepend_child members.
2010-03-24 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.70
* Fixed handling of std::allocator to make it more likely to work
on non-GNU platforms.
2009-12-28 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed the operator= return type and handled self-assignment
(thanks to Xinlin Cao for the fix).
2009-05-05 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.65
* Added skip_children(bool), fixed post-increment/decrement
operators to not refer to 'n' anymore.
2009-04-03 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Added a sibling member for quick access to the n-th sibling
(thanks to Adam Connell for sending the patch).
2009-03-06 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed an old bug in compare_nodes (pointed out to me in 2005 but
never fixed properly...)
2008-08-28 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.62
* Changed the behaviour of max_depth() so that it returns -1 for
an empty tree, instead of bailing out with an error (strictly
speaking max_depth should be undefined...).
2008-08-26 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.61
* Fixed a bug in max_depth() which would fail on trees with more
than one head node (thanks to Marc Noirot for pointing this out).
2008-08-23 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.60
* Fixed several problems with fixed_depth iterators: iterating
beyond the top node now disabled and operator-- fixed.
2008-07-25 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Made 'child()' static.
2008-07-20 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.54
* Changed size() members to return size_t instead of unsigned int.
* Changed behaviour of operator++ for leaf_iterator so that it can
be used in situations where new leaves get added during iteration.
2008-06-30 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.52
* Made depth member function static so it can be used independent
of an actual tree, and added a version with two iterators to
measure depths relative to a different node.
2008-02-28 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.51
* Added a top node to leaf_iterators, so that they can be
instructed to iterate only over the leaves of a given node.
2007-10-19 Kasper Peeters <kasper@pooh>
* Released 2.4.
2007-10-18 Kasper Peeters <kasper@pooh>
* Added max_depth() members.
* Fixed a bug in begin_fixed() which would fail on
A
/ \
B C
/ \
D E
/ \
F G
when asked for the first node at depth 3 from 'A' (since it
failed to go back up the tree from 'D').
2007-08-21 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.31.
* Added GPL version 3 licensing as an option.
2007-01-19 Kasper Peeters <kasper@pooh>
* Fixed a bug in "replace" which appeared when trying to replace a
head node (it tried to access the parent).
2006-11-29 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Release 2.3.
Fixed a bug in number_of_siblings which only counted siblings in
one direction (thanks to Fanzhe Cui for pointing this out).
2006-08-20 Kasper Peeters <kasper@pooh>
* Released 2.2.
* Added operator== and operator!= for fixed_depth_iterator.
2006-08-07 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 2.1.
* Added leaf iterators, code contributed by Peter Wienemann.
* Fixed a bug in is_valid (thanks to Antonio Morillas). 1.131.
2006-07-19 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed bugs in move_before and move_after which would show up
when the node was already in the right place. 1.130.
2006-03-02 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Added the "wrap" member function.
2006-03-01 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Added a simple queue-based breadth-first iterator.
2006-01-31 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed move_before to work when the target is a sibling_iterator
pointing to the end of a range of siblings.
2005-11-20 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Added move_after, which for some mysterious reason was
missing. Thanks to Dennis Jones for pointing this out.
* Fixed a bug in operator++ for post_order iterators
(skip_children could remain set if no next sibling present).
Thanks to Ohad for pointing out the bug.
2005-10-12 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed a bug in the 'sort' member which takes a Comparator
function object (thanks to Robin Taylor for the patch).
2005-09-14 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Doxygen documentation added, plus a new web page.
2004-11-05 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed a bug which shows up when inserting nodes at the top of
the tree (thanks to Matthias Bernt for pointing me to this one).
2004-07-21 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixed kp::destructor -> destructor.
* Moved body of 'compare_nodes::operator()' into the class
declaration in order to satisfy buggy Borland compilers (and stop
regular email messages about this problem).
* Fixed a completely buggy number_of_siblings() (thanks to Caleb
Epstein for the patch).
2004-02-04 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 1.106
* Fixed a bug in insert(sibling_iterator, const T&) (thanks to
Maxim Yegorushkin for the patch).
2003-11-21 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Put some things in a namespace to avoid clashes with other
libraries.
2003-10-13 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 1.102.
* Fixed return type of postincrement/decrement operators (thanks
to Yevhen Tymokhin for pointing this out).
2003-09-18 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Fixes for standard compliance, as required to compile with
gcc 3.4 and later.
2003-08-12 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Added 'empty' member (patch by Michael Vogt).
2003-08-01 <kasper@whiteroom2.localdomain>
* Released 1.95
* Fixed two bugs in sort (which were corrupting the tree); thanks
to Michael Vogt for informing me about the problem.
2003-07-17 <kasper@whiteroom2.localdomain>
* Added a hack to enable compilation with STLport.
2003-07-11 <kasper@whiteroom2.localdomain>
* Released 1.90
* Added postfix increment and decrement operators; thanks to
Claudio Andreatta for sending the patch.
* Fixed a bug in reparent(iter pos, iter from). Thanks to Claudio
Andreatta for fixing this.
2003-06-25 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Many bug fixes for fixed depth iterators, thanks to Ruben
Niederhagen for pointing out several problems (a few still exist,
see the 'TODO' part of tree.hh).
2003-04-17 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 1.85
* Corrected return type of operator++ and friends.
* Added preliminary support for 'fixed_depth_iterator' to iterate
over children at a given level. Not quite finished yet, sorry.
2003-03-24 Kasper Peeters <kasper.peeters@aei.mpg.de>
* Released 1.83
* Changed return type of 'child' member function to be a sibling
iterator instead of a reference to the actual node (sorry for the
incompatibility with previous versions). Change also propagated to
tree_msvc.hh.
2003-02-07 <kasper@whiteroom2.localdomain>
* Released 1.80
* Fixed another bug in sort (thanks to Tony Cook for fixing this
bug).
2003-01-29 Kasper Peeters <peekas@xeon25.aei-potsdam.mpg.de>
* Released 1.78.
* Fixed a bug in sort, which resulted in a corrupt tree (thanks to
Michael Vogt for fixing this bug).
2003-01-07 Kasper Peeters <peekas@xeon25.aei-potsdam.mpg.de>
* Released 1.75 and msvc version 1.72
* Fixed a wrongly specialised 'insert' method for
sibling_iterators (thanks to Tony Cook for pointing this out).
2002-11-15 Kasper Peeters <peekas@xeon25.aei-potsdam.mpg.de>
* Released 1.72
* Fixed a bug in 'index' when called on nodes at the top level of
the tree (thanks to David Zajic for the bug report). Be warned
that the top level is a bit special at the moment; the end
sibling_iterator is ill-defined for siblings there (to be fixed in
a future version).
2002-10-31 Kasper Peeters <peekas@sshserv.aei-potsdam.mpg.de>
* Released 1.70.
* Finished the merge algorithm, updated the documentation with
examples about its use, and added a test-case to the test_tree.cc
program.
* Fixed a bug in pre_order_iterator::operator--.
2002-10-20 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
* Released 1.66.
2002-10-15 Kasper Peeters <kasper@whiteroom.nikhef.nl>
* Code for post_order_iterator implemented.
2002-10-13 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
* Rewrote large parts of the code to allow for multiple iterator
types, such as pre_order_iterator (which was the previous iterator
type), post_order_iterator and so on. This required small changes
to the interface, the most visible one being
- insert(iterator, iterator) for the insertion of a subtree
is now called insert_subtree(iterator, iterator).
Apologies if this breaks your code.
2002-10-11 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
* Removed '(void)' type declarations in favour of the C++ standard
empty brackets '()'.
2002-10-10 Kasper Peeters <peekas@xeon24.aei-potsdam.mpg.de>
* Added 'index' in response to a discussion on the Boost mailing
list.
2002-10-03 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
* reparent(iterator,sibling_iterator,sibling_iterator) now accepts
an empty range, in which case it does nothing (request by Jos de
Laender).
* Fixed a bug in the iterator(sibling_iterator) constructor
(thanks to Jos de Laender for pointing this out).
2002-09-04 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
* Fixed a bug in insert_after (thanks to Carl Blanchette for the
patch).
2002-08-29 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
* The problem in test_tree of the previous item was actually do to
tree::end(iterator) returning the end of the tree, not the end of
the current sibling list. Fixed now, released 1.55.
2002-08-26 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
* Released 1.54.
* Printing a single-node tree in test_tree would result in a
segfault; more robust now (thanks to Yutaka Sato for the bug
report).
2002-05-07 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
* Fixed a bug in "sort" which would remove duplicate nodes altogether.
2002-03-24 Kasper Peeters <kasper@whiteroom.nikhef.nl>
* Added "append_child" without child argument, to add empty child
node.
2002-05-04 Kasper Peeters <K.Peeters@damtp.cam.ac.uk>
* Released 1.45.
* Removed restriction of having only a single node at the top of
the tree (associated with this, the top nodes should now be inserted
with "insert", not with "append_child").
* Fixes for ISO compatibility (now works with gcc-3.1). Thanks to
Olivier Verdier.

27
lib/tree-2.81/Makefile Normal file
View file

@ -0,0 +1,27 @@
RELEASE=2.8
HTML=${HOME}/public_html/
.PHONY: doc tarball
tarball:
git archive --format=tar --prefix=tree-${RELEASE}/ HEAD | gzip > ${HOME}/tmp/tree-${RELEASE}.tar.gz
site: tarball doc
install -d ${HTML}/tree
install -d ${HTML}/tree/doxygen/html
install doc/index.html doc/tree.css doc/tree.jpg ChangeLog ${HTML}/tree
install src/test_tree.cc src/test_tree.output src/tree_example.cc src/tree.hh src/tree_util.hh ${HTML}/tree
install doxygen/html/* ${HTML}/tree/doxygen/html
install ${HOME}/tmp/tree-${RELEASE}.tar.gz ${HTML}/tree
install ${HOME}/tmp/kt_temp/kt_temp_tree/tree.pdf ${HTML}/tree
upload:
rsync -avz ${HTML}/tree/ zmaya:tree
doc:
(cd doc; kt -f tree.tex)
doxygen doc/doxygen_tree.config
test_tree: test_tree.o
g++ -o test_tree test_tree.o

View file

@ -0,0 +1,220 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="verify-v1"
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<meta name="description" content="The tree.hh library provides C++
programmers with a container class to store arbitrary data in
n-ary tree form. It is compatible with the STL and its
algorithms wherever possible. Available under the terms of the GPL." />
<meta name="keywords" content="data structure, C++, programming, STL,
open source, container class" />
<title>tree.hh: an STL-like C++ tree class, documentation</title>
<link rel="stylesheet" type="text/css" href="tree.css" />
</head>
<body>
<div id="container">
<div id="title">
<div id="share">
<!-- AddThis Button BEGIN -->
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&amp;username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
<!-- AddThis Button END -->
</div>
<div id="filler">
<img id="treeimg" src="tree2.png" alt="[background image]"/>
</div>
<div id="titletxt">
<h1>tree.hh: an STL-like C++ tree class</h1>
<h2 class="author">
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
</h2>
</div>
</div>
<ul id="menubar">
<li><a href="index.html">Overview</a></li>
<li><a href="download.html">Download</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="projects.html">Projects using tree.hh</a></li>
</ul>
<div id="linkbar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree linkbar */
google_ad_slot = "0194609917";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div id="main">
<div id="sidebar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree.hh vertical ads */
google_ad_slot = "3744417434";
google_ad_width = 120;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<h2>Data structure overview</h2>
<div class="text">The data structure of the <code>tree</code> class is depicted
below (see the documentation for more detailed information).
Each node contains a pointer to the first and last child element,
and each child contains pointers to its previous and next sibling:
<img class="structure" src="structure.png" alt="[structure
diagram]" />
</div>
<div class="text">
Iterators come in various types. The normal <code>iterator</code> iterates depth-first
over all nodes. The beginning and end of the tree can be obtained by using the
<code>begin()</code> and <code>end()</code> members. The other type of iterator
only iterates over the nodes at one given depth (ie. over all siblings). One
typically uses these iterators to iterate over all children of a node, in which
case the [begin,end) range can be obtained by calling <code>begin(iterator)</code>
and <code>end(iterator)</code>.</div>
<div class="text">Iterators can be converted from one type to the other; this includes the `end'
iterators (all intervals are as usual closed at the beginning and open
at the end).</div>
<h2>Sample program</h2>
<div class="text">
Here is a small sample program to illustrate
how <code>tree.hh</code> is used in practise.
<div class="code">
<pre>#include &lt;algorithm&gt;
#include &lt;string&gt;
#include &lt;iostream&gt;
#include "tree.hh"
using namespace std;
int main(int, char **)
{
tree&lt;string&gt; tr;
tree&lt;string&gt;::iterator top, one, two, loc, banana;
top=tr.begin();
one=tr.insert(top, "one");
two=tr.append_child(one, "two");
tr.append_child(two, "apple");
banana=tr.append_child(two, "banana");
tr.append_child(banana,"cherry");
tr.append_child(two, "peach");
tr.append_child(one,"three");
loc=find(tr.begin(), tr.end(), "two");
if(loc!=tr.end()) {
tree&lt;string&gt;::sibling_iterator sib=tr.begin(loc);
while(sib!=tr.end(loc)) {
cout &lt;&lt; (*sib) &lt;&lt; endl;
++sib;
}
cout &lt;&lt; endl;
tree&lt;string&gt;::iterator sib2=tr.begin(loc);
tree&lt;string&gt;::iterator end2=tr.end(loc);
while(sib2!=end2) {
for(int i=0; i&lt;tr.depth(sib2)-2; ++i)
cout &lt;&lt; " ";
cout &lt;&lt; (*sib2) &lt;&lt; endl;
++sib2;
}
}
}</pre>
</div>
The output of this program is
<div class="code">
<pre>apple
banana
peach
apple
banana
cherry
peach</pre>
</div>
Note that this example only has one element at the
top of the tree (in this case that is the node containing "one") but
it is possible to have an arbitary number of such elements (then the
tree is more like a "bush"). Observe the way in which the two types of
iterators work. The first block of output, obtained using the
sibling_iterator, only displays the children directly below "two". The
second block iterates over all children at any depth below "two". In
the second output block, the <code>depth</code> member has been used
to determine the distance of a given node to the root of the
tree.
</div>
<h2>API documentation</h2>
<div class="text">
Documentation is available in the form of
a <a href="tree.pdf">pdf</a> file. This file is also available
in the tarball as a LaTeX file. Further information can be
obtained by reading the test program (included in the
distribution). Also look at the <a href="#example">simple
example</a> below.
</div>
<div class="text">
The most complete documentation of the interface is always
available in the <a href="doxygen/html/index.html">doxygen
generated documentation</a>.
</div>
</div>
<div id="flush"></div>
<p>
<a href="http://validator.w3.org/check?uri=referer">
<img
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
</p>
<!-- Start of StatCounter Code -->
<script type="text/javascript">
var sc_project=4068217;
var sc_invisible=1;
var sc_partition=50;
var sc_click_stat=1;
var sc_security="3f2419f9";
</script>
<script type="text/javascript"
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
<noscript>
<div class="statcounter">
<a title="blogspot statistics"
class="statcounter"
href="http://www.statcounter.com/blogger/">
<img
class="statcounter"
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
alt="blogspot statistics" /></a>
</div>
</noscript>
<!-- End of StatCounter Code -->
</div>
</body>
</html>

View file

@ -0,0 +1,175 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="verify-v1"
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<meta name="description" content="The tree.hh library provides C++
programmers with a container class to store arbitrary data in
n-ary tree form. It is compatible with the STL and its
algorithms wherever possible. Available under the terms of the GPL." />
<meta name="keywords" content="data structure, C++, programming, STL,
open source, container class" />
<title>tree.hh: an STL-like C++ tree class, download</title>
<link rel="stylesheet" type="text/css" href="tree.css" />
</head>
<body>
<div id="container">
<div id="title">
<div id="share">
<!-- AddThis Button BEGIN -->
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&amp;username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
<!-- AddThis Button END -->
</div>
<div id="filler">
<img id="treeimg" src="tree2.png" alt="[background image]"/>
</div>
<div id="titletxt">
<h1>tree.hh: an STL-like C++ tree class</h1>
<h2 class="author">
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
</h2>
</div>
</div>
<ul id="menubar">
<li><a href="index.html">Overview</a></li>
<li><a href="download.html">Download</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="projects.html">Projects using tree.hh</a></li>
</ul>
<div id="linkbar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree linkbar */
google_ad_slot = "0194609917";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div id="main">
<div id="sidebar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree.hh vertical ads */
google_ad_slot = "3744417434";
google_ad_width = 120;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<h2>Download</h2>
<div class="text">Everything (the header file, examples, documentation
and all other things referred to on this page) is contained in the
tarball</div>
<div class="filename">
<a href="tree-2.8.tar.gz">tree-2.8.tar.gz</a>
</div>
<div class="text">
Feel free to copy the header <a href="tree.hh">tree.hh</a>
(which is all you need code-wise) into your own source
directory as long as you respect the license (see above).
</div>
<div class="text">
The list of changes can be found in the <a href="ChangeLog">ChangeLog</a>.
</div>
<div class="text">
There is a small utility
library <a href="tree_util.hh">tree_util.hh</a> originally
written by Linda Buisman. This library contains a number of
functions to output a tree as text, to aid in debugging your
project.
</div>
<div class="text">The current version works with GNU gcc 3.x and
higher, Borland&nbsp;C++&nbsp;builder and Microsoft Visual C++ 7.1 and
higher (I no longer support older versions of Visual C++). It is
compatible with STLport (though older versions may not work
correctly, best to upgrade to something fairly recent).
</div>
<div class="text">The library is available for free, but if it
helps you a lot, why not consider a small donation?
<form id="donate"
action="https://www.paypal.com/cgi-bin/webscr" method="post">
<p>
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id"
value="YVWFQTJRGD8SW" />
<input type="image"
src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif"
name="submit"
alt="PayPal - The safer, easier way to pay online!" />
<img alt=""
src="https://www.paypal.com/en_GB/i/scr/pixel.gif"
width="1"
height="1" />
</p>
</form>
Your contribution is greatly appreciated!
</div>
<h2>Installation</h2>
<div class="text">
No installation is required as the tree.hh library is
contained in the single header file tree.hh. Just copy it into
your source directory (and upgrade it from the master site
when a new version becomes available).
</div>
</div>
<div id="flush"></div>
<p>
<a href="http://validator.w3.org/check?uri=referer">
<img
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
</p>
<!-- Start of StatCounter Code -->
<script type="text/javascript">
var sc_project=4068217;
var sc_invisible=1;
var sc_partition=50;
var sc_click_stat=1;
var sc_security="3f2419f9";
</script>
<script type="text/javascript"
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
<noscript>
<div class="statcounter">
<a title="blogspot statistics"
class="statcounter"
href="http://www.statcounter.com/blogger/">
<img
class="statcounter"
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
alt="blogspot statistics" /></a>
</div>
</noscript>
<!-- End of StatCounter Code -->
</div>
</body>
</html>

View file

@ -0,0 +1,270 @@
# Doxyfile 1.4.4
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = tree
PROJECT_NUMBER = "release 2.0"
OUTPUT_DIRECTORY = doxygen
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = "The $name class" \
"The $name widget" \
"The $name file" \
is \
provides \
specifies \
contains \
represents \
a \
an \
the
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = NO
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = NO
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = NO
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
FILE_VERSION_FILTER =
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text"
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = src/tree.hh
FILE_PATTERNS = *.c \
*.cc \
*.cxx \
*.cpp \
*.c++ \
*.d \
*.java \
*.ii \
*.ixx \
*.ipp \
*.i++ \
*.inl \
*.h \
*.hh \
*.hxx \
*.hpp \
*.h++ \
*.idl \
*.odl \
*.cs \
*.php \
*.php3 \
*.inc \
*.m \
*.mm \
*.dox \
*.C \
*.CC \
*.C++ \
*.II \
*.I++ \
*.H \
*.HH \
*.H++ \
*.CS \
*.PHP \
*.PHP3 \
*.M \
*.MM
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS = *
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = NO
USE_HTAGS = NO
VERBATIM_HEADERS = NO
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = NO
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
MAX_DOT_GRAPH_WIDTH = 1024
MAX_DOT_GRAPH_HEIGHT = 1024
MAX_DOT_GRAPH_DEPTH = 1000
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = NO

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 782 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

View file

@ -0,0 +1,205 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="verify-v1"
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<meta name="description" content="The tree.hh library provides C++
programmers with a container class to store arbitrary data in
n-ary tree form. It is compatible with the STL and its
algorithms wherever possible. Available under the terms of the GPL." />
<meta name="keywords" content="data structure, C++, programming, STL,
open source, container class" />
<title>tree.hh: an STL-like C++ tree class</title>
<link rel="stylesheet" type="text/css" href="tree.css" />
</head>
<body>
<div id="container">
<div id="title">
<div id="share">
<!-- AddThis Button BEGIN -->
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&amp;username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
<!-- AddThis Button END -->
</div>
<div id="plusone">
<!-- Place this tag where you want the +1 button to render -->
<g:plusone></g:plusone>
<!-- Place this tag after the last plusone tag -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
</div>
<div id="filler">
<img id="treeimg" src="tree2.png" alt="[background image]"/>
</div>
<div id="titletxt">
<h1>tree.hh:&nbsp;an&nbsp;STL-like&nbsp;C++&nbsp;tree&nbsp;class</h1>
<h2 class="author">
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
</h2>
</div>
</div>
<ul id="menubar">
<li><a href="index.html">Overview</a></li>
<li><a href="download.html">Download</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="projects.html">Projects using tree.hh</a></li>
</ul>
<div id="linkbar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree linkbar */
google_ad_slot = "0194609917";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div id="main">
<div id="sidebar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree.hh vertical ads */
google_ad_slot = "3744417434";
google_ad_width = 120;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<h2>Overview</h2>
<div class="text">
The <code>tree.hh</code> library for C++ provides an STL-like container class
for <i>n</i>-ary trees, templated over the data stored at the nodes. Various
types of iterators are provided (post-order, pre-order, and
others). Where possible the access methods are compatible with the STL
or alternative algorithms are available. The library is available
under the terms of the GNU General Public License version 2 or
3 (see below).</div>
<div class="text">Documentation is available in the form of
a <a href="tree.pdf">pdf</a> file. See
the <a href="documentation.html">documentation page</a> for
more details and sample programs.
</div>
<div class="text">The <code>tree.hh</code> library is meant for generic <i>n</i>-ary
trees. For binary trees, AVL trees, quad trees and other data
structures, you may want to look elsewhere. </div>
<div class="text">The library is available for free, but if it
helps you a lot, why not consider a small donation?
<form id="donate"
action="https://www.paypal.com/cgi-bin/webscr" method="post">
<p>
<input type="hidden" name="cmd" value="_s-xclick" />
<input type="hidden" name="hosted_button_id"
value="YVWFQTJRGD8SW" />
<input type="image"
src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif"
name="submit"
alt="PayPal - The safer, easier way to pay online!" />
<img alt=""
src="https://www.paypal.com/en_GB/i/scr/pixel.gif"
width="1"
height="1" />
</p>
</form>
Your contribution is greatly appreciated!
</div>
<div class="text">
I have considered this class for inclusion in Boost. However,
there are many ways to implement a tree container, and there
is no good way to simultaneously satisfy everyone who would
use it. See the discussion on the Boost mailing list in
<a href="http://lists.boost.org/Archives/boost/2002/10/37383.php">2002</a>
and <a href="http://lists.boost.org/Archives/boost/2009/07/153719.php">2009</a>.
</div>
<h2>License</h2>
<div class="text">In principle, the <code>tree.hh</code> code is
available under the terms of the GNU General Public
License <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">2</a>
or <a href="http://www.gnu.org/copyleft/gpl.html">3</a>. However,
if you would like to use <code>tree.hh</code> under different
conditions, contact me and we will work something out.</div>
<div class="license">
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public
License along with this program. If not,
see <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
</div>
<div class="text">If you use <code>tree.hh</code>,
please satisfy my curiosity and write me a small email with
a bit of explanation of your software and the role of my tree
class in it.</div>
</div>
<div id="flush"></div>
<p>
<a href="http://validator.w3.org/check?uri=referer">
<img
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
</p>
<!-- Start of StatCounter Code -->
<script type="text/javascript">
var sc_project=4068217;
var sc_invisible=1;
var sc_partition=50;
var sc_click_stat=1;
var sc_security="3f2419f9";
</script>
<script type="text/javascript"
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
<noscript>
<div class="statcounter">
<a title="blogspot statistics"
class="statcounter"
href="http://www.statcounter.com/blogger/">
<img
class="statcounter"
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
alt="blogspot statistics" /></a>
</div>
</noscript>
<!-- End of StatCounter Code -->
</div>
</body>
</html>

View file

@ -0,0 +1,162 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" >
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta name="verify-v1"
content="LkU+jobePpu3F8I4GPuTiOjrTukmo1qpWT+dT6SeAfk=" />
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii" />
<meta name="description" content="The tree.hh library provides C++
programmers with a container class to store arbitrary data in
n-ary tree form. It is compatible with the STL and its
algorithms wherever possible. Available under the terms of the GPL." />
<meta name="keywords" content="data structure, C++, programming, STL,
open source, container class" />
<title>tree.hh: an STL-like C++ tree class, projects using tree.hh</title>
<link rel="stylesheet" type="text/css" href="tree.css" />
</head>
<body>
<div id="container">
<div id="title">
<div id="share">
<!-- AddThis Button BEGIN -->
<a class="addthis_button" href="http://www.addthis.com/bookmark.php?v=250&amp;username=kpeeters"><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a><script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#username=kpeeters"></script>
<!-- AddThis Button END -->
</div>
<div id="filler">
<img id="treeimg" src="tree2.png" alt="[background image]"/>
</div>
<div id="titletxt">
<h1>tree.hh: an STL-like C++ tree class</h1>
<h2 class="author">
<a href="http://maths.dur.ac.uk/users/kasper.peeters/">Kasper Peeters</a>, kasper.peeters (at) phi-sci.com
</h2>
</div>
</div>
<ul id="menubar">
<li><a href="index.html">Overview</a></li>
<li><a href="download.html">Download</a></li>
<li><a href="documentation.html">Documentation</a></li>
<li><a href="projects.html">Projects using tree.hh</a></li>
</ul>
<div id="linkbar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree linkbar */
google_ad_slot = "0194609917";
google_ad_width = 728;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div id="main">
<div id="sidebar">
<script type="text/javascript"><!--
google_ad_client = "pub-9577963716105989";
/* tree.hh vertical ads */
google_ad_slot = "3744417434";
google_ad_width = 120;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<h2>Projects using tree.hh</h2>
<div class="text">The <code>tree.hh</code> library is used in various projects:
<dl>
<dt><strong><a
href="http://cadabra.phi-sci.com/">Cadabra</a></strong></dt>
<dd>A field-theory motivated approach to symbolic computer
algebra.</dd>
<dt><strong><a
href="http://www.gnu.org/software/gnash/">Gnash</a></strong></dt>
<dd>Gnash is a GNU Flash movie player. Previously, it was only
possible to play flash movies with proprietary software. While there
are some other free flash players, none support anything beyond SWF
v4. Gnash is based on GameSWF, and supports many SWF v7 features.</dd>
<dt><strong><a href="http://htmlcxx.sourceforge.net/">htmlcxx</a></strong></dt>
<dd>A simple non-validating css1 and html parser for C++.</dd>
<dt><strong><a href="http://www.cs.sfu.ca/~anoop/courses/CMPT-379-Fall-2007/index.html">Principles of Compiler Design</a></strong></dt>
<dd>A course in compiler design at the Simon Fraser University, Canada.</dd>
<dt><strong><a href="http://sourceforge.net/projects/liborigin/">liborigin</a></strong></dt>
<dd>A library for reading OriginLab OPJ project files, which is used
by <a href="http://soft.proindependent.com/qtiplot.html">QtiPlot</a>
and <a href="http://labplot.sourceforge.net/">LabPlot</a>, two
applications for data analysis and visualisation.</dd>
<dt><strong><a href="http://www.echem.uni-tuebingen.de/~bs/echem/software/EChem++/echem++.shtml">EChem++</a></strong></dt>
<dd>A project realizing the idea of a Problem Solving Environment
(PSE) in the field of computational electrochemistry. Computer
controlled experimental measurements, numerical simulation and
analysis of electrochemical processes will be combined under a common
user interface.</dd>
<dt><strong><a
href="http://www.infor.uva.es/~jadiego/">LZCS</a></strong></dt>
<dd>A semistructured document transformation tool. LZCS compresses
structured documents taking advantage of the redundant information
that can appear in the structure. The main idea is that frequently
repeated subtrees may exist and these can be replaced by a backward
reference to their first occurance. See the <a
href="http://www.dcc.uchile.cl/~gnavarro/ps/dcc04.1.ps.gz">accompanying
paper</a> for more details.</dd>
<dt><strong><a href="http://libofx.sourceforge.net/">libOFX</a></strong></dt>
<dd>A parser and an API designed to allow applications to very easily support OFX
command responses, usually provided by financial institutions for
statement downloads.</dd>
<dt><strong>A genetic programming project</strong></dt>
<dd>See this <a
href="http://www.cs.adfa.edu.au/~shanyin/publications/peel.pdf">paper</a> for
more information.</dd>
<dt><strong><a href="http://nlp.lsi.upc.edu/freeling/">FreeLing</a></strong></dt>
<dd> The FreeLing package consists of a library providing language analysis services (such as morfological analysis, date recognition, PoS tagging, etc.)</dd>
</dl>
Let me know about your project when you are using
<code>tree.hh</code>, so that I can add it to the list.</div>
</div>
<div id="flush"></div>
<p>
<a href="http://validator.w3.org/check?uri=referer">
<img
src="http://www.w3.org/Icons/valid-xhtml10"
alt="Valid XHTML 1.0 Strict" height="31" width="88" /></a>
</p>
<!-- Start of StatCounter Code -->
<script type="text/javascript">
var sc_project=4068217;
var sc_invisible=1;
var sc_partition=50;
var sc_click_stat=1;
var sc_security="3f2419f9";
</script>
<script type="text/javascript"
src="http://www.statcounter.com/counter/counter_xhtml.js"></script>
<noscript>
<div class="statcounter">
<a title="blogspot statistics"
class="statcounter"
href="http://www.statcounter.com/blogger/">
<img
class="statcounter"
src="http://c.statcounter.com/4068217/0/3f2419f9/1/"
alt="blogspot statistics" /></a>
</div>
</noscript>
<!-- End of StatCounter Code -->
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

View file

@ -0,0 +1,417 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="631.06183"
height="496.98901"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.46"
version="1.0"
sodipodi:docname="structure.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-filename="/home/kasper/git/tree/doc/structure.png"
inkscape:export-xdpi="71.308388"
inkscape:export-ydpi="71.308388">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lend"
style="overflow:visible">
<path
id="path3222"
d="M 0,0 L 5,-5 L -12.5,0 L 5,5 L 0,0 z"
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt;marker-start:none"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
id="perspective10" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
gridtolerance="10000"
guidetolerance="10"
objecttolerance="10"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.7"
inkscape:cx="401.3348"
inkscape:cy="195.91012"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="904"
inkscape:window-height="715"
inkscape:window-x="155"
inkscape:window-y="123" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-79.177704,-27.247875)">
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect2391"
width="75"
height="25.714285"
x="195.57071"
y="51.866875" />
<text
xml:space="preserve"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="204.05081"
y="71.504051"
id="text2383"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan2385"
x="204.05081"
y="71.504051">head 1</tspan></text>
<g
id="g4556"
transform="translate(-30.304576,0.5199496)">
<g
transform="translate(120.20815,-92.934035)"
id="g4517">
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3163"
width="75"
height="25.714285"
x="290.87708"
y="144.28096" />
<text
xml:space="preserve"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="299.35718"
y="163.91814"
id="text3165"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3167"
x="299.35718"
y="163.91814">head 2</tspan></text>
</g>
</g>
<g
id="g3185">
<rect
y="260.67743"
x="79.677704"
height="25.714285"
width="60.857864"
id="rect3175"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text3181"
y="278.85458"
x="87.344574"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
xml:space="preserve"><tspan
y="278.85458"
x="87.344574"
id="tspan3183"
sodipodi:role="line">node</tspan></text>
</g>
<g
id="g3190"
transform="translate(92.934022,-1.0101541)">
<rect
y="260.67743"
x="79.677704"
height="25.714285"
width="60.857864"
id="rect3192"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text3194"
y="278.85458"
x="87.344574"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
xml:space="preserve"><tspan
y="278.85458"
x="87.344574"
id="tspan3196"
sodipodi:role="line">node</tspan></text>
</g>
<g
id="g3198"
transform="translate(201.02035,-1.010154)">
<rect
y="260.67743"
x="79.677704"
height="25.714285"
width="60.857864"
id="rect3200"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text3202"
y="278.85458"
x="87.344574"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
xml:space="preserve"><tspan
y="278.85458"
x="87.344574"
id="tspan3204"
sodipodi:role="line">node</tspan></text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 112.12693,256.36198 C 148.49242,226.0574 178.797,238.17923 196.97975,252.32137"
id="path3206"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="148.49242"
y="228.07771"
id="text3208"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3210"
x="148.49242"
y="228.07771">next sibling</tspan></text>
<text
xml:space="preserve"
style="font-size:15px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="108.37365"
y="333.25311"
id="text3212"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3214"
x="108.37365"
y="333.25311">previous sibling</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 200.01021,290.38754 C 163.64472,320.69212 133.34014,308.57029 115.15739,294.42815"
id="path3994"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 209.10158,83.625892 L 101.01525,249.29091"
id="path3996" />
<text
xml:space="preserve"
style="font-size:14.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="-66.628067"
y="212.73572"
id="text4513"
sodipodi:linespacing="100%"
transform="matrix(0.5909299,-0.8067229,0.8067229,0.5909299,0,0)"><tspan
sodipodi:role="line"
id="tspan4515"
x="-66.628067"
y="212.73572">first child</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 220.21325,254.6613 C 256.57874,224.35672 286.88332,236.47855 305.06607,250.62069"
id="path4522"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 306.07622,290.38754 C 269.71073,320.69212 239.40615,308.57029 221.2234,294.42815"
id="path4524"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 257.96217,83.372105 L 323.88568,251.56499"
id="path4526"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:14.99999809px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="241.30775"
y="-202.79788"
id="text4528"
sodipodi:linespacing="100%"
transform="matrix(0.4272211,0.9041472,-0.9041472,0.4272211,0,0)"><tspan
sodipodi:role="line"
id="tspan4530"
x="241.30775"
y="-202.79788">last child</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 274.76149,46.569867 C 311.12698,16.265292 341.43156,28.387122 359.61431,42.529262"
id="path4532"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 360.62446,84.316419 C 324.25897,114.621 293.95439,102.49917 275.77164,88.357029"
id="path4534"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:9.99999974, 9.99999974;stroke-dashoffset:0;stroke-opacity:1"
d="M 471.64002,63.927916 C 549.62414,63.927916 549.62414,63.927916 549.62414,63.927916"
id="path4546" />
<g
id="g4562"
transform="translate(-95.964492,0.2910246)">
<g
transform="translate(365.59772,-92.70511)"
id="g4548">
<rect
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4550"
width="75"
height="25.714285"
x="290.87708"
y="144.28096" />
<text
xml:space="preserve"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="299.35718"
y="163.91814"
id="text4552"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan4554"
x="299.35718"
y="163.91814">head n</tspan></text>
</g>
</g>
<g
id="g4568"
transform="translate(102.53048,214.52734)">
<rect
y="260.67743"
x="79.677704"
height="25.714285"
width="60.857864"
id="rect4570"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4572"
y="278.85458"
x="87.344574"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
xml:space="preserve"><tspan
y="278.85458"
x="87.344574"
id="tspan4574"
sodipodi:role="line">node</tspan></text>
</g>
<g
id="g4576"
transform="translate(195.4645,213.51719)">
<rect
y="260.67743"
x="79.677704"
height="25.714285"
width="60.857864"
id="rect4578"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4580"
y="278.85458"
x="87.344574"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
xml:space="preserve"><tspan
y="278.85458"
x="87.344574"
id="tspan4582"
sodipodi:role="line">node</tspan></text>
</g>
<g
id="g4584"
transform="translate(303.55083,213.51719)">
<rect
y="260.67743"
x="79.677704"
height="25.714285"
width="60.857864"
id="rect4586"
style="opacity:1;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<text
sodipodi:linespacing="100%"
id="text4588"
y="278.85458"
x="87.344574"
style="font-size:20px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
xml:space="preserve"><tspan
y="278.85458"
x="87.344574"
id="tspan4590"
sodipodi:role="line">node</tspan></text>
</g>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 214.65741,470.88933 C 251.0229,440.58475 281.32748,452.70658 299.51023,466.84872"
id="path4592"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 302.54069,504.91489 C 266.1752,535.21947 235.87062,523.09764 217.68787,508.9555"
id="path4602"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 313.65237,301.1837 L 205.56604,466.84872"
id="path4604" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 322.74373,469.18865 C 359.10922,438.88407 389.4138,451.0059 407.59655,465.14804"
id="path4610"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 408.6067,504.91489 C 372.24121,535.21947 341.93663,523.09764 323.75388,508.9555"
id="path4612"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1"
d="M 329.17792,299.91976 L 426.41616,466.09234"
id="path4614"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-size:25px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Charter;-inkscape-font-specification:Bitstream Charter"
x="257.5726"
y="-691.83954"
id="text4620"
sodipodi:linespacing="100%"
transform="matrix(0,1,-1,0,0,0)"><tspan
sodipodi:role="line"
id="tspan4622"
x="257.5726"
y="-691.83954">depth</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.70000005;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 665.71429,68.076468 L 665.71429,479.50504"
id="path4624" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

171
lib/tree-2.81/doc/tree.css Normal file
View file

@ -0,0 +1,171 @@
body {
font: 10pt "Lucida Grande", "Lucida Sans Unicode", Arial, Verdana, sans-serif;
}
div#container {
min-width: 700px;
margin-left: 20px;
margin-right: 20px;
margin-top: 20px;
margin-bottom: 30px;
background: #f0f0f0;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
-moz-box-shadow: 1px 1px 9px #888;
padding: 5px 15px 5px 15px;
}
div#titletxt {
margin: -150px 0 30px 240px;
height: 70px;
}
div#filler {
width: 100%;
height: 160px;
background: url("filler.png");
padding: 0;
margin: 0;
margin-top: 5px;
-moz-box-shadow: 1px 1px 5px #888;
}
img#treeimg {
margin-top: 0;
}
/* Donations */
form#donate {
text-align: center;
margin-top: 1ex;
margin-bottom: 1ex;
}
/* Layout containers */
div#linkbar {
margin-right: 135px;
display: inline;
}
div#main {
margin-right: 135px;
display: inline;
}
div#sidebar {
margin-top: 16px;
float: right;
display: inline;
width: 125px;
margin-left: 10px;
}
div#flush {
clear: both;
}
/* Title color/style */
#title h1 {
font-size: 30px;
color: #b00000;
}
#title h2 {
font-size: 11pt;
font-weight: normal;
color: black;
border-bottom: 0px;
}
/* Menu */
ul#menubar {
margin-top: 0px;
margin-bottom: 35px;
margin-right: 2ex;
text-align: right;
}
#menubar li {
display: inline;
background: #b00000;
color: white;
font-weight: bold;
padding: .5ex 1ex .5ex 1ex;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
-moz-box-shadow: 1px 1px 9px #888;
}
#menubar li:hover {
background: #009000;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
-moz-box-shadow: 1px 1px 6px #888;
}
#menubar a {
text-decoration: none;
color: white;
}
/* Main color/style */
div#share {
position: absolute;
right: 50px;
top: 36px;
}
div#plusone {
position: absolute;
left: 50px;
top: 36px;
}
#main h2 {
margin-top: 2ex;
margin-right: 135px;
display: block;
background: #b00000;
color: white;
padding-left: 1ex;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
-moz-box-shadow: 1px 1px 9px #888;
}
div.text {
margin-left: 120px;
margin-bottom: 2ex;
margin-right: 145px;
}
div.license {
margin-left: 140px;
margin-bottom: 2ex;
margin-right: 155px;
}
div.filename {
margin-left: 200px;
margin-bottom: 1ex;
}
img.structure {
margin-top: 1ex;
margin-bottom: 1ex;
margin-left: 3ex;
}
dd {
margin-bottom: 2ex;
}
img {
border-style: none;
}
/* Code listing */
div.code {
margin: 1ex;
width: 90%;
border: dotted 1px black;
background: #f8f8f8;
font-size: 8pt;
padding: 1ex;
}
.code pre {
white-space: pre-wrap;
}

BIN
lib/tree-2.81/doc/tree.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
lib/tree-2.81/doc/tree.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 888 KiB

388
lib/tree-2.81/doc/tree.tex Normal file
View file

@ -0,0 +1,388 @@
\documentclass[11pt]{kasper}
%
% If you do not have 'kasper.cls', see
% http://www.damtp.cam.ac.uk/user/kp229/texstuff .
\usepackage{makeidx}
\usepackage{verbatim}
\usepackage{relsize}
\makeindex
%\newcommand{\toindex}[1]{#1\index{#1}}
\newcommand{\member}[1]{{\tt #1}\index{#1}}
%\newcommand{\member}[1]{{\tt #1}}
\def\mystrut{\vbox to 8.5pt{}\vtop to 3.5pt{}}
\def\V{\hskip10pt\vrule\hskip10pt}
\def\T{\hskip10pt\vrule\vrule height2.5pt depth -2.1pt width 10pt}
\def\L{\hskip10pt\vrule height 8.5pt depth -2.1pt
\vrule height2.5pt depth -2.1pt width 10pt}
\def\N{\hskip10pt\phantom{\vrule}\hskip10pt}
\def\hw{\hskip-1000pt plus 1fil}
% to test: insert before end of subtree
\begin{document}
\title{{\tt tree.hh} documentation}
\author{Kasper Peeters}
\email{kasper.peeters@gmail.com}
\maketitle
\begin{abstract}
The {\tt tree.hh} library for C++ provides an STL-like container class
for n-ary trees, templated over the data stored at the nodes. Various
types of iterators are provided (post-order, pre-order, and
others). Where possible the access methods are compatible with the STL
or alternative algorithms are available. The library is available
under the terms of the GNU General Public License.\\[3ex]
Code and examples available at: {\tt http://tree.phi-sci.com/}\\[3ex]
{\bf This documentation is not yet entirely complete. Refer to the {\tt
tree.hh} header file for a full list of member functions.}
\end{abstract}
\vfill
\maketoc
\eject
\begin{sectionunit}
\title{Overview}
\maketitle
\begin{sectionunit}
\title{The container class}
\maketitle
The tree class of {\tt tree.hh} is a templated container class in the
spirit of the STL. It organises data in the form of a so-called n-ary
tree. This is a tree in which every node is connected to an arbitrary
number of child nodes. Nodes at the same level of the tree are called
``siblings'', while nodes that are below a given node are called its
``children''. At the top of the tree, there is a set of nodes which
are characterised by the fact that they do not have any parents. The
collection of these nodes is called the ``head'' of the tree. See
figure~\ref{f:overview} for a pictorial illustration of this
structure (90 degrees rotated for convenience).
\begin{figure}[th]
\begin{center}
\includegraphics[width=.5\textwidth]{treefig}
\caption{Overview of the tree structure. The elements at the top of
the tree (here displayed at the left for convenience) are in the
``head'' (there can be more than one such element). Every node is
linked to its children using the ``first child'' and ``last child''
links. In addition, all nodes on a given level are doubly-linked using
the ``previous sibling'' and ``next sibling'' links. The ``depth'' of
a given node refers to the horizontal distance from the head nodes.}
\label{f:overview}
\end{center}
\end{figure}
The tree class is templated over the data objects stored at the nodes;
just like you can have a {\tt vector<string>} you can now have a
{\tt tree<string>}. Many STL algorithms work on this data structure,
and where necessary alternatives have been provided.
\medskip
\end{sectionunit}
\begin{sectionunit}
\title{Iterators}
\maketitle
The essential difference between a container with the structure of a
tree and the STL containers is that the latter are ``linear''. While
the STL containers thus only have essentially one way in which one can
iterate over their elements, this is not true for trees. The {\tt
tree.hh} library provides (at present) four different iteration
schemes. To describe them, consider the following tree:
\begin{equation*}
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
root \hw\cr
\T A \cr
\V \T B \cr
\V \L C \cr
\L D \cr
\N \T E \cr
\N \L F \cr}}
\end{equation*}
The three iteration types and the resulting order in which nodes are
visited are tabulated below:
\begin{center}
\begin{tabular}{llll}
pre-order (default) & ``element before children'' &
\member{pre\_order\_iterator} & root A B C D E F \\
post-order & ``element after children'' &
\member{post\_order\_iterator} & B C A E F D root \\
breadth-first & &
\member{breadth\_first\_iterator} & root A D B C E F \\
sibling & ``only siblings'' &
\member{sibling\_iterator} & (for ex.) A D \\
fixed-depth & &
\member{fixed\_depth\_iterator} & (for ex.) A D \\
leaf & &
\member{leaf\_iterator} & B C E F
\end{tabular}
\end{center}
The pre-order ones are the default iterators, and therefore also known
under the name of {\tt iterator}. Sibling iterators and fixed-depth
iterators iterate only over the nodes at a given depth of the
tree. The former restrict themselves to the child nodes of one given
node, while the latter iterates over all child nodes at the given
depth. Finally, leaf iterators iterate over all leafs (bottom-most)
nodes of the tree.
There are copy constructors that will convert iterators of the
various types into each other. The post- and pre-order iterators are
both also known as ``depth-first'', in contrast to the
``breadth-first'' iterator.
The begin and end iterators of a tree can be obtained using
\member{begin()} and \member{end()} (for pre-order iterators) or
alternatively \member{begin\_post()} and \member{end\_post()} (for
post-order iterators) and \member{begin\_leaf()} and
\member{end\_leaf()} (for leaf iterators). Similarly, the begin and
end sibling iterators can be obtained by calling
\member{begin(iterator)} and \member{end(iterator)}. The range of
children of a given node can also be obtained directly from an
iterator, by using the {\tt iterator::begin()} and {\tt
iterator::end()} member functions.
If you want to (temporarily) make an iterator not go into the child
subtree, call the member function \member{skip\_children}. This will only
keep effect for a single increment or decrement of the
iterator. Finally, whether or not an iterator is actually pointing at
a node (i.e.~is not an ``end'' iterator) can be tested using the
\member{is\_valid(iterator)} member of the tree class.
\end{sectionunit}
\end{sectionunit}
\begin{sectionunit}
\title{Basic operations}
\maketitle
\begin{description}
\item[Initialising] There are two nontrivial constructors. One which takes
a single node element as argument. It constructs a tree with this node
begin the sole node in the head (in other words, it is a combination
of a trivial constructor together with a \member{set\_head} call).
The other non-trivial constructor takes an iterator, and copies the
subtree starting at that node into the newly created tree (useful for
constructing new tree objects given by subtrees of existing trees).
\item[Tree traversal] Besides the \member{operator++} and
\member{operator--} members for step-wise traversal through the tree,
it is also possible to use the \member{operator+=} and \member{operator-=}
member functions to make more than one step at the same time (though
these are linear time, not amortized constant). The result of stepping
beyond the end of the tree or stepping beyond the end of a sibling
range (for sibling iterators) is undefined.
The parent of a given node can be reached by calling the \member{parent}
member of the tree object, giving it an iterator pointing to the node.
If you know the number of children of a given node, you can get direct
access to the $n$th child by using the \member{child} member
function. Note that the value of the index is not checked and should
therefore always be valid.
\item[Appending child nodes] Nodes can be added as children of a given
node using the \member{append\_child} member function.
\item[Inserting nodes] Nodes can be inserted at the same depth as a
given other node using the \member{insert} and \member{insert\_after}
members functions. This is also how you insert the first node into a
tree.
\end{description}
\end{sectionunit}
\begin{sectionunit}
\title{Other algorithms}
\maketitle
\begin{sectionunit}
\title{Non-mutating algorithms}
\maketitle
\begin{description}
\item[Counting nodes] The total number of nodes of a tree can be
obtained using the \member{size} member function, while the number of
children of a given node can be obtained with a call to
\member{number\_of\_children(iterator)}. Similarly, the number of
nodes at a given depth (the number of siblings of a given node) can be
obtained using the \member{number\_of\_siblings} member function.
\item[Determining depth] The \member{depth()} member function returns the
distance of a node to the root.
\item[Accessing siblings by their index] See the next item.
\item[Determining index in a sibling range] In order to determine the
index of a node in the range of siblings to which it belongs, use the
\member{index(sibling\_iterator)} member function. The first sibling node
has index 0. The reverse of this function (obtaining a sibling node
given its index in the range of siblings) is called
\member{child(const iterator\_base\&, unsigned int)}.
\item[Comparing trees] While the STL \member{equal} algorithm can be used
to compare the values of the nodes in two different trees, it does not
know about the structure of the tree. If you want the comparison to
take this into account, use the \member{equal(iterator, iterator,
iterator, BinaryPredicate)} call of the tree class. As an addition to
the STL algorithm, the length of the first range does not have to be
equal to the length of the range pointed to by the second iterator.
There is also an \member{equal\_subtree} algorithm which takes only
two iterators, pointing to the (single-node) heads of two
subtrees.
\end{description}
\end{sectionunit}
\begin{sectionunit}
\title{Mutating algorithms}
\maketitle
\begin{description}
\item[Erasing nodes and subtrees] In order to remove a node including
its children from the tree, use the \member{erase(iterator)} call. If you
just want to erase the children, but not the node itself, use the
\member{erase\_children(iterator)} call.
\item[Replacing individual nodes or subtrees]
\item[Flattening subtrees] The procedure of moving all children of a
given node to be siblings of that node is called ``flattening''; it
acts as
\begin{equation*}
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\T banana\cr
\V \T pear \cr
\V \T strawberry \cr
\V \L cherry \cr
\L grape\cr}}\quad\rightarrow\quad
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\T banana\cr
\T pear \cr
\T strawberry \cr
\T cherry \cr
\L grape\cr}}
\end{equation*}
% \begin{screen}
% apple apple
% banana banana
% pear -> pear
% strawberry strawberry
% cherry cherry
% grape grape
% \end{screen}
when the tree is flattened at the ``banana'' node.
\item[Moving or exchanging subtrees] Simple exchange of one sibling node with the
next one is done through the member function \member{swap(sibling\_iterator)}. The
iterator remains valid and remains pointing to the moved subtree.
More complicated move operations are the \member{move\_ontop},
\member{move\_before} and \member{move\_after} ones. These all take
two iterators, a source and a target. The member
\member{move\_ontop(target, source)} removes the `target' node and
all its children, and replaces it with the `source' node and its
children. The `source' subtree is removed from its original location.
The other two move members do a similar thing, differing only in the
node which is to be replaced.
\item[Extracting subtrees] You can create a new tree object
filled with the data of a subtree of the original tree. This is
analogous to the extraction of a substring of a string. The relevant
member function is \member{subtree(sibling\_iterator,
sibling\_iterator)} which takes a range of siblings as argument.
There is also a slight variation of this member, which does not return
a tree object but instead populates one that is passed as an argument
(useful if you want to call this on a tree object subclassed from
{\tt tree<T>}.
\item[Sorting] The standard STL sort algorithm is not very useful for
trees, because it only exchanges values, not nodes. Applying it to a
tree would mean that the structure of the tree remains unmodified,
only node values get moved around (not their subtrees).
Therefore, the {\tt tree} class has its own sort member. It comes in
two forms, just like the STL sort, namely
\begin{screen}
void sort(sibling_iterator from, sibling_iterator to, bool deep=false);
template<class StrictWeakOrdering>
void sort(sibling_iterator from, sibling_iterator to,
StrictWeakOrdering comp, bool deep=false);
\end{screen}
The result of a call to either of these is that the nodes in the range
described by the two iterators get sorted. If the boolean {\tt deep}
is true, the subtrees of all these nodes will get sorted as well (and
so one can sort the entire tree in one call). As in the STL, you can
use the second form of this function to pass your own comparison
class.
If the nodes to which the two iterators point are not in the same
sibling range (i.e.~not at the same depth in the tree), the result is undefined.
\item[Merging] One way in which one might think of indicating the
position where new nodes are to be inserted, is to give the path that
leads to the insertion point. For instance, given the tree
\begin{equation*}
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\T banana\cr
\V \T pear \cr
\V \T strawberry \cr
\V \L cherry \cr
\L grape\cr}}
\end{equation*}
one could imagine using the sub-tree
\begin{equation*}
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\L banana\cr
\N \T coconut \cr
\N \L raspberry \cr}}
\end{equation*}
to indicate that the nodes ``coconut'' and ``raspberry'' are to be
inserted as new children of the ``banana'' node. In {\tt tree.hh} this
process is called \emph{tree merging}. It can do the simple addition
of children as above, but actually handles the generic case too: as
an example consider the merge
\begin{equation*}
\text{\tt merge}\left[
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\T banana\cr
\V \T pear \cr
\V \T strawberry \cr
\V \L cherry \cr
\T grape\cr
blueberry \cr}}\quad, \quad
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\T banana\cr
\V \T coconut \cr
\V \L raspberry \cr
\T tangerine \cr
\V \L plum\cr
blueberry \cr
\N \L orange \cr}}\right]\quad\rightarrow\quad
\vcenter{\offinterlineskip
\halign{&#\mystrut\hfil\cr
apple \hw\cr
\T banana\cr
\V \T pear\cr
\V \T strawberry\cr
\V \T cherry\cr
\V \T coconut \cr
\V \L raspberry \cr
\T grape\cr
\T tangerine \cr
\V \L plum\cr
blueberry \cr
\N \L orange \cr}}
\end{equation*}
As is clear from the above, the arguments to \member{merge} are two
sibling ranges.
\end{description}
\end{sectionunit}
\end{sectionunit}
\printindex
\end{document}

BIN
lib/tree-2.81/doc/tree2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View file

@ -0,0 +1,190 @@
%!PS-Adobe-2.0 EPSF-2.0
%%Title: tree.eps
%%Creator: fig2dev Version 3.2 Patchlevel 0-beta3
%%CreationDate: Fri May 3 12:41:08 2002
%%For: kp229@church.amtp.cam.ac.uk (Kasper Peeters)
%%Orientation: Portrait
%%BoundingBox: 0 0 324 252
%%Pages: 0
%%BeginSetup
%%EndSetup
%%Magnification: 1.0000
%%EndComments
/$F2psDict 200 dict def
$F2psDict begin
$F2psDict /mtrx matrix put
/col-1 {0 setgray} bind def
/col0 {0.000 0.000 0.000 srgb} bind def
/col1 {0.000 0.000 1.000 srgb} bind def
/col2 {0.000 1.000 0.000 srgb} bind def
/col3 {0.000 1.000 1.000 srgb} bind def
/col4 {1.000 0.000 0.000 srgb} bind def
/col5 {1.000 0.000 1.000 srgb} bind def
/col6 {1.000 1.000 0.000 srgb} bind def
/col7 {1.000 1.000 1.000 srgb} bind def
/col8 {0.000 0.000 0.560 srgb} bind def
/col9 {0.000 0.000 0.690 srgb} bind def
/col10 {0.000 0.000 0.820 srgb} bind def
/col11 {0.530 0.810 1.000 srgb} bind def
/col12 {0.000 0.560 0.000 srgb} bind def
/col13 {0.000 0.690 0.000 srgb} bind def
/col14 {0.000 0.820 0.000 srgb} bind def
/col15 {0.000 0.560 0.560 srgb} bind def
/col16 {0.000 0.690 0.690 srgb} bind def
/col17 {0.000 0.820 0.820 srgb} bind def
/col18 {0.560 0.000 0.000 srgb} bind def
/col19 {0.690 0.000 0.000 srgb} bind def
/col20 {0.820 0.000 0.000 srgb} bind def
/col21 {0.560 0.000 0.560 srgb} bind def
/col22 {0.690 0.000 0.690 srgb} bind def
/col23 {0.820 0.000 0.820 srgb} bind def
/col24 {0.500 0.190 0.000 srgb} bind def
/col25 {0.630 0.250 0.000 srgb} bind def
/col26 {0.750 0.380 0.000 srgb} bind def
/col27 {1.000 0.500 0.500 srgb} bind def
/col28 {1.000 0.630 0.630 srgb} bind def
/col29 {1.000 0.750 0.750 srgb} bind def
/col30 {1.000 0.880 0.880 srgb} bind def
/col31 {1.000 0.840 0.000 srgb} bind def
end
save
-126.0 342.0 translate
1 -1 scale
/cp {closepath} bind def
/ef {eofill} bind def
/gr {grestore} bind def
/gs {gsave} bind def
/sa {save} bind def
/rs {restore} bind def
/l {lineto} bind def
/m {moveto} bind def
/rm {rmoveto} bind def
/n {newpath} bind def
/s {stroke} bind def
/sh {show} bind def
/slc {setlinecap} bind def
/slj {setlinejoin} bind def
/slw {setlinewidth} bind def
/srgb {setrgbcolor} bind def
/rot {rotate} bind def
/sc {scale} bind def
/sd {setdash} bind def
/ff {findfont} bind def
/sf {setfont} bind def
/scf {scalefont} bind def
/sw {stringwidth} bind def
/tr {translate} bind def
/tnt {dup dup currentrgbcolor
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add
4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb}
bind def
/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul
4 -2 roll mul srgb} bind def
/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
/$F2psEnd {$F2psEnteredState restore end} def
%%EndProlog
$F2psBegin
10 setmiterlimit
n -1000 6700 m -1000 -1000 l 8494 -1000 l 8494 6700 l cp clip
0.06000 0.06000 sc
% Polyline
7.500 slw
gs clippath
4380 3828 m 4350 3948 l 4320 3828 l 4320 3990 l 4380 3990 l cp
4320 3222 m 4350 3102 l 4380 3222 l 4380 3060 l 4320 3060 l cp
clip
n 4350 3075 m 4350 3975 l gs col0 s gr gr
% arrowhead
n 4320 3222 m 4350 3102 l 4380 3222 l 4350 3222 l 4320 3222 l cp gs 0.00 setgray ef gr col0 s
% arrowhead
n 4380 3828 m 4350 3948 l 4320 3828 l 4350 3828 l 4380 3828 l cp gs 0.00 setgray ef gr col0 s
% Polyline
[60] 0 sd
n 4350 4350 m 4350 5475 l gs col0 s gr [] 0 sd
% Polyline
gs clippath
4021 5328 m 4039 5450 l 3966 5351 l 4028 5500 l 4083 5477 l cp
clip
n 2550 1875 m 4050 5475 l gs col0 s gr gr
% arrowhead
n 4021 5328 m 4039 5450 l 3966 5351 l 3993 5339 l 4021 5328 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
4380 2628 m 4350 2748 l 4320 2628 l 4320 2790 l 4380 2790 l cp
4320 2022 m 4350 1902 l 4380 2022 l 4380 1860 l 4320 1860 l cp
clip
n 4350 1875 m 4350 2775 l gs col0 s gr gr
% arrowhead
n 4320 2022 m 4350 1902 l 4380 2022 l 4350 2022 l 4320 2022 l cp gs 0.00 setgray ef gr col0 s
% arrowhead
n 4380 2628 m 4350 2748 l 4320 2628 l 4350 2628 l 4380 2628 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
3903 1695 m 4023 1725 l 3903 1755 l 4065 1755 l 4065 1695 l cp
clip
n 2550 1725 m 4050 1725 l gs col0 s gr gr
% arrowhead
n 3903 1695 m 4023 1725 l 3903 1755 l 3903 1725 l 3903 1695 l cp gs 0.00 setgray ef gr col0 s
% Polyline
gs clippath
6828 1695 m 6948 1725 l 6828 1755 l 6990 1755 l 6990 1695 l cp
clip
n 4725 1725 m 6975 1725 l gs col0 s gr gr
% arrowhead
n 6828 1695 m 6948 1725 l 6828 1755 l 6828 1725 l 6828 1695 l cp gs 0.00 setgray ef gr col0 s
% Polyline
[60] 0 sd
n 7275 1950 m 7275 2625 l gs col0 s gr [] 0 sd
/Times-Roman ff 180.00 scf sf
2100 1800 m
gs 1 -1 sc (head) col0 sh gr
/Times-Roman ff 180.00 scf sf
4200 1800 m
gs 1 -1 sc (node) col0 sh gr
/Times-Roman ff 180.00 scf sf
4200 3000 m
gs 1 -1 sc (node) col0 sh gr
/Times-Roman ff 180.00 scf sf
4200 4200 m
gs 1 -1 sc (node) col0 sh gr
/Times-Roman ff 180.00 scf sf
4200 5700 m
gs 1 -1 sc (node) col0 sh gr
/Times-Roman ff 180.00 scf sf
4575 2250 m
gs 1 -1 sc (next sibling) col0 sh gr
/Times-Roman ff 180.00 scf sf
4575 2475 m
gs 1 -1 sc (prev sibling) col0 sh gr
/Times-Roman ff 180.00 scf sf
4575 3450 m
gs 1 -1 sc (next sibling) col0 sh gr
/Times-Roman ff 180.00 scf sf
4575 3675 m
gs 1 -1 sc (prev sibling) col0 sh gr
/Times-Roman ff 180.00 scf sf
5850 1650 m
gs 1 -1 sc (first child) col0 sh gr
/Times-Roman ff 180.00 scf sf
2925 1650 m
gs 1 -1 sc (first child) col0 sh gr
/Times-Roman ff 180.00 scf sf
7125 1800 m
gs 1 -1 sc (node) col0 sh gr
/Times-Roman ff 180.00 scf sf
7125 2925 m
gs 1 -1 sc (node) col0 sh gr
/Times-Roman ff 180.00 scf sf
2550 3900 m
gs 1 -1 sc (last child) col0 sh gr
$F2psEnd
rs

View file

@ -0,0 +1,44 @@
#FIG 3.2
Landscape
Center
Inches
Letter
100.00
Single
-2
1200 2
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
4350 3075 4350 3975
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
4350 4350 4350 5475
2 1 0 1 0 7 0 0 -1 4.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2550 1875 4050 5475
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 1 2
1 1 1.00 60.00 120.00
1 1 1.00 60.00 120.00
4350 1875 4350 2775
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
2550 1725 4050 1725
2 1 0 1 0 7 0 0 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4725 1725 6975 1725
2 1 1 1 0 7 0 0 -1 4.000 0 0 -1 0 0 2
7275 1950 7275 2625
4 0 0 0 0 0 12 0.0000 0 135 360 2100 1800 head\001
4 0 0 0 0 0 12 0.0000 4 135 360 4200 1800 node\001
4 0 0 0 0 0 12 0.0000 4 135 360 4200 3000 node\001
4 0 0 0 0 0 12 0.0000 4 135 360 4200 4200 node\001
4 0 0 0 0 0 12 0.0000 4 135 360 4200 5700 node\001
4 0 0 0 0 0 12 0.0000 4 180 870 4575 2250 next sibling\001
4 0 0 0 0 0 12 0.0000 4 180 870 4575 2475 prev sibling\001
4 0 0 0 0 0 12 0.0000 4 180 870 4575 3450 next sibling\001
4 0 0 0 0 0 12 0.0000 4 180 870 4575 3675 prev sibling\001
4 0 0 0 0 0 12 0.0000 4 135 720 5850 1650 first child\001
4 0 0 0 0 0 12 0.0000 4 135 720 2925 1650 first child\001
4 0 0 0 0 0 12 0.0000 4 135 360 7125 1800 node\001
4 0 0 0 0 0 12 0.0000 4 135 360 7125 2925 node\001
4 0 0 0 0 0 12 0.0000 4 135 690 2550 3900 last child\001

View file

@ -0,0 +1,71 @@
%PDF-1.3
%Çì<C387>¢
6 0 obj
<</Length 7 0 R/Filter /FlateDecode>>
stream
­UK<EFBFBD>Ó0¾ûWøÖ©YÏø}]‰—…H‡¥<E280A1>MPZØí
øùŒ_‰³©©h¤zÆóøÆó°E\„/¯›{b·<±{"?±°{ Ô(øÀ$ª9ˆŽ<CB86> l<C2A0>´AjÁAh n NbN ‰t°Jt—%Ê™Æ<E284A2>>´Í$+œvjô—èŽðž©Fó_ŃÕSDR“ÖÇx² ·Øþíq<>ƒŽX²I3_k`?siø*Û6:£<>*=46†c‰Œl%!HÀ™ðM¬èpzÀ$s>0Ræ„Ô•CKPècáÀÎu[*5! ˜Æ¤&˺<C38B>ÿËc·4±@NÕ¥´¶.eΪip<12>QT]ˆh«.̲ÂI1N¦Ï ŠHŸœ ׃s…ƒip.KÙ¤Y ÎrÓÅUB<>(!c7éÐå(]ÈbIccûX?§ƒÍÙ<C38D>æy ²«ª —VšuA®t°43褙pÐ YÂA/Õœ>—™x¿çÔ Gýwj VšUj®uð궕tES#ë<>¥HSw¥HŸèöŽ¯o^6~×Ò+ìiƒÜµ{gàkÑú¡R@˜Š·vÓí¶oÚo è¼Ý²›ã÷í.ìXäíûÌ®ÆÕz‘ΈÂ&ÃÝï~ê¿ýñ1º”$ Ê?žw?GÁŠÑ —ög«ê[Cû€¤³ïŸO/|ÓõC |M× IÄ95_ûÙ©Œ-àék´¡Në)µ‡w-¿§^øöÌÐcendstream
endobj
7 0 obj
588
endobj
10 0 obj
<</R4
4 0 R>>
endobj
11 0 obj
<</R9
9 0 R>>
endobj
5 0 obj
<</Type/Page/MediaBox [0 0 324 252]
/Rotate 0/Parent 3 0 R
/Resources<</ProcSet[/PDF /Text]
/ExtGState 10 0 R
/Font 11 0 R
>>
/Contents 6 0 R
>>
endobj
3 0 obj
<< /Type /Pages /Kids [
5 0 R
] /Count 1
>>
endobj
1 0 obj
<</Type /Catalog /Pages 3 0 R
>>
endobj
4 0 obj
<</Type/ExtGState/Name/R4/TR/Identity/OPM 1/SM 0.02>>
endobj
9 0 obj
<</Subtype/Type1/BaseFont/Times-Roman/Type/Font/Name/R9>>
endobj
8 0 obj
<</Type/FontDescriptor/FontName/Times-Roman>>
endobj
2 0 obj
<</Producer (GNU Ghostscript 6.51)
>>endobj
xref
0 12
0000000000 65535 f
0000000971 00000 n
0000001222 00000 n
0000000912 00000 n
0000001019 00000 n
0000000752 00000 n
0000000015 00000 n
0000000673 00000 n
0000001161 00000 n
0000001088 00000 n
0000000692 00000 n
0000000722 00000 n
trailer
<< /Size 12 /Root 1 0 R /Info 2 0 R
>>
startxref
1274
%%EOF

3
lib/tree-2.81/src/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.o
*.res
test1

View file

@ -0,0 +1,14 @@
%.o: %.cc
g++ -c -I. $^
test1: test1.o
g++ -o test1 test1.o
run_tests: test1 test1.req
./test1 > test1.res
@diff test1.res test1.req
@echo "*** All tests OK ***"
clean:
rm -f *.o *~ *.res

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,18 @@
#include "tree.hh"
#include "tree_util.hh"
int main(int, char **)
{
tree<int> tr;
tr.insert(tr.begin(), 1);
tree<int>::iterator i2 = tr.insert(tr.end(), 2);
tree<int>::iterator i3 = tr.insert(tr.end(), 3);
tr.append_child(i2, 21);
tr.append_child(i3, 31);
tree<int>::iterator i4 = tr.insert(tr.end(), 4);
kptree::print_tree_bracketed(tr, std::cout);
std::cout << std::endl;
}

View file

@ -0,0 +1,4 @@
1
2(21)
3(31)
4

View file

@ -0,0 +1,378 @@
/*
STL-like templated tree class; test program.
Copyright (C) 2001-2009 Kasper Peeters <kasper.peeters@aei.mpg.de>
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tree.hh"
#include "tree_util.hh"
#include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <list>
#include <utility>
#include <stdexcept>
/*
Simple test program for the tree.hh class library. Run it and see
what happens. Or, if you want to see that it does not leak memory,
run it like
./test_tree 10000 >/dev/null
or some other large number and have 'top' running in a different
shell. This will run the tests 10000 times, creating and destroying
the trees for every iteration of the loop.
*/
bool truefunc(std::string& one, std::string& two)
{
// std::cout << "comparing " << one << "==" << two << std::endl;
return true;
}
void print_tree(const tree<std::string>& tr, tree<std::string>::pre_order_iterator it, tree<std::string>::pre_order_iterator end)
{
if(!tr.is_valid(it)) return;
int rootdepth=tr.depth(it);
std::cout << "-----" << std::endl;
while(it!=end) {
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
std::cout << " ";
std::cout << (*it) << std::endl << std::flush;
++it;
}
std::cout << "-----" << std::endl;
}
void print_tree_post(const tree<std::string>& tr, tree<std::string>::post_order_iterator it, tree<std::string>::post_order_iterator end)
{
int rootdepth=tr.depth(it);
std::cout << "-----" << std::endl;
while(it!=end) {
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
std::cout << " ";
std::cout << (*it) << std::endl << std::flush;
++it;
}
std::cout << "-----" << std::endl;
}
void print_tree_rev(const tree<std::string>& tr, tree<std::string>::pre_order_iterator it, tree<std::string>::pre_order_iterator end)
{
--it;
int rootdepth=0;//tr.depth(it);
std::cout << "-----" << std::endl;
while(1==1) {
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
std::cout << " ";
std::cout << (*it) << std::endl;
if(it==end) break;
--it;
}
std::cout << "-----" << std::endl;
}
void print_tree_rev_post(const tree<std::string>& tr, tree<std::string>::post_order_iterator it, tree<std::string>::post_order_iterator end)
{
--it;
int rootdepth=0;//tr.depth(it);
std::cout << "-----" << std::endl;
while(1==1) {
for(int i=0; i<tr.depth(it)-rootdepth; ++i)
std::cout << " ";
std::cout << (*it) << std::endl;
if(it==end) break;
--it;
}
std::cout << "-----" << std::endl;
}
int main(int argc, char **argv)
{
unsigned int maxloop=1;
if(argc>1)
maxloop=atoi(argv[1]);
for(unsigned int j=0; j<maxloop; ++j) {
tree<std::string> tr9;
tr9.set_head("hi");
tr9.insert(tr9.begin().begin(), "0");
tr9.insert(tr9.begin().begin(), "1");
print_tree(tr9, tr9.begin(), tr9.end());
tree<std::string> tr;
tree<std::string>::pre_order_iterator html, body, h1, h3, bh1, mv1;
std::cout << "empty tree to begin with:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
html=tr.insert(tr.begin(), "html");
tr.insert(html,"extra");
// tr.insert(html,"zextra2");
body=tr.append_child(html, "body");
h1 =tr.append_child(body, "h1");
std::cout << tr.index(h1) << std::endl;
bh1 =tr.insert(h1,"before h1");
tr.append_child(h1, "some text");
tree<std::string>::sibling_iterator more_text=tr.append_child(body, "more text");
std::cout << " 'more text' is sibling " << tr.index(more_text) << " in its sibling range" << std::endl;
std::cout << "filled tree:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
std::cout << "filled tree, post-order traversal:" << std::endl;
print_tree_post(tr, tr.begin_post(), tr.end_post());
tr.swap(bh1);
std::cout << "swapped elements:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
tr.swap(h1);
std::cout << "swapped back:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
tree<std::string> copytree(h1);
std::cout << "copied tree:" << std::endl;
print_tree(copytree, copytree.begin(), copytree.end());
// Now test the STL algorithms
std::cout << "result of search for h1 and kasper:" << std::endl;
tree<std::string>::pre_order_iterator it;
it=std::find(tr.begin(),tr.end(),std::string("h1"));
if(it!=tr.end()) print_tree(tr, it, tr.next_sibling(it));
else std::cout << "h1 not found" << std::endl;
it=std::find(tr.begin(),tr.end(), std::string("kasper"));
if(it!=tr.end()) print_tree(tr, it, tr.next_sibling(it));
else std::cout << "kasper not found" << std::endl;
std::cout << std::endl;
// remove the h1, replace it with new subtree
tree<std::string> replacement;
h3 =replacement.insert(replacement.begin(), "h3");
replacement.append_child(h3, "text in h3");
std::cout << "replacement tree:" << std::endl;
print_tree(replacement, replacement.begin(), replacement.end());
print_tree(tr, tr.begin(), tr.end());
h1=tr.replace(tree<std::string>::sibling_iterator(h1), tr.next_sibling(h1),
tree<std::string>::sibling_iterator(h3), tr.next_sibling(h3));
std::cout << "filled tree with replacement done:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
// replace h3 node while keeping children
h1=tr.replace(h1, "<foobar>");
print_tree(tr, tr.begin(), tr.end());
// add a sibling to the head
tr.insert_after(h1, "more");
// Copy object.
tree<std::string> tr2=tr;
print_tree(tr2, tr2.begin(), tr2.end());
tree<std::string> tr3(tr);
// reparent "before h1" to h3 node
tr.reparent(h1, bh1, tr.next_sibling(bh1));
std::cout << "moved content:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
// iterate over children only
tree<std::string>::sibling_iterator ch=tr.begin(h1);
std::cout << "children of h1:" << std::endl;
while(ch!=tr.end(h1)) {
std::cout << (*ch) << std::endl;
++ch;
}
std::cout << std::endl;
// flatten the h3 node
tr.flatten(h1);
std::cout << "flattened (at h3) tree:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
// Erase the subtree of tr below body.
tr.erase_children(body);
std::cout << "children of body erased:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
it=std::find(tr.begin(),tr.end(),"h1");
if(it!=tr.end()) print_tree(tr, it, tr.next_sibling(it));
else std::cout << "h1 not found" << std::endl;
// Erase everything
tr.erase(tr.begin());
std::cout << "erased tree:" << std::endl;
print_tree(tr, tr.begin(), tr.end());
// The copies are deep, ie. all nodes have been copied.
std::cout << "copies still exist:" << std::endl;
print_tree(tr2, tr2.begin(), tr2.end());
print_tree(tr3, tr3.begin(), tr3.end());
// Test comparison
std::cout << "testing comparison functions:" << std::endl;
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 1)" << std::endl;
// modify content but not structure
tree<std::string>::pre_order_iterator fl3=tr3.begin();
fl3+=4; // pointing to "<foobar>" node
std::cout << (*fl3) << std::endl;
std::string tmpfl3=(*fl3);
(*fl3)="modified";
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 0)" << std::endl;
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 0)" << std::endl;
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), truefunc)
<< " (should be 1)" << std::endl;
// modify tr3 structure (but not content)
(*fl3)=tmpfl3;
tr3.flatten(fl3);
std::cout << "tree flattened, test again" << std::endl;
print_tree(tr3, tr3.begin(), tr3.end());
// Test comparison again
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 0)" << std::endl;
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 1)" << std::endl;
// Change content
(*fl3)="modified";
// Test comparison again
std::cout << std::equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 0)" << std::endl;
std::cout << tr2.equal(tr2.begin(), tr2.end(), tr3.begin(), std::equal_to<std::string>())
<< " (should be 0)" << std::endl;
// Testing sort. First add a subtree to one leaf
tree<std::string>::pre_order_iterator txx3=tr3.begin();
txx3+=5;
tr3.append_child(txx3,"ccc");
tr3.append_child(txx3,"bbb");
tr3.append_child(txx3,"bbb");
tr3.append_child(txx3,"aaa");
std::less<std::string> comp;
tree<std::string>::pre_order_iterator bdy=tr3.begin();
bdy+=2;
assert(tr.is_valid(bdy));
std::cout << "unsorted subtree:" << std::endl;
print_tree(tr3, tr3.begin(), tr3.end());
tree<std::string>::sibling_iterator sortit1=tr3.begin(bdy), sortit2=tr3.begin(bdy);
sortit1+=2;
sortit2+=4;
assert(tr.is_valid(sortit1));
assert(tr.is_valid(sortit2));
std::cout << "partially sorted subtree: ("
<< "sorted from " << (*sortit1) << " to "
<< (*sortit2) << ", excluding the last element)" << std::endl;
mv1=tr3.begin();
++mv1;
tr3.sort(sortit1, sortit2);
print_tree(tr3, tr3.begin(), tr3.end());
tr3.sort(tr3.begin(bdy), tr3.end(bdy), comp, true); // false: no sorting of subtrees
// Sorting the entire tree, level by level, is much simpler:
// tr3.sort(tr3.begin(), tr3.end(), true);
std::cout << "sorted subtree:" << std::endl;
print_tree(tr3, tr3.begin(), tr3.end());
// Michael's problem
// std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
// std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
// tr3.sort(tr3.begin(), tr3.end(), true);
// std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
// std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
// print_tree(tr3, tr3.begin(), tr3.end());
// tr3.sort(tr3.begin(), tr3.end(), true);
// std::cout << mv1.node << ", " << tr3.feet << ", " << tr3.feet->prev_sibling << std::endl;
// std::cout << mv1.node->next_sibling << ", " << tr3.feet->prev_sibling << ", " << tr3.end().node << std::endl;
// print_tree(tr3, tr3.begin(), tr3.end());
// return 1;
// Test merge algorithm.
std::cout << "test merge" << std::endl;
tree<std::string> mtree;
tree<std::string>::pre_order_iterator mt1, mt2, mt3;
mt1=mtree.insert(mtree.begin(),"html");
mt2=mtree.append_child(mt1,"head");
mt3=mtree.append_child(mt1,"body");
// Adding it without head having any children tests whether we can
// insert at the end of an empty list of children.
mtree.append_child(mt2,"title");
mtree.append_child(mt3,"h1");
mtree.append_child(mt3,"h1");
tree<std::string> mtBree;
tree<std::string>::pre_order_iterator mtB1, mtB2;
mtB1=mtBree.insert(mtBree.begin(),"head");
mtB2=mtBree.append_child(mtB1,"another title");
print_tree(mtree, mtree.begin(), mtree.end());
print_tree(mtBree, mtBree.begin(), mtBree.end());
mtree.merge(mtree.begin(), mtree.end(), mtBree.begin(), mtBree.end(), true);
print_tree(mtree, mtree.begin(), mtree.end());
mtree.merge(mtree.begin(mtree.begin()), mtree.end(mtree.begin()), mtBree.begin(), mtBree.end(), true);
print_tree(mtree, mtree.begin(), mtree.end());
// Print tree in reverse (test operator--)
print_tree_rev(mtree, mtree.end(), mtree.begin());
print_tree_rev_post(mtree, mtree.end_post(), mtree.begin_post());
// Breadth-first
tree<std::string> bft;
tree<std::string>::iterator bfB,bfC,bfD;
bft.set_head("A");
bfB=bft.append_child(bft.begin(), "B");
bfC=bft.append_child(bft.begin(), "C");
bfD=bft.append_child(bft.begin(), "D");
bft.append_child(bfB, "E");
bft.append_child(bfB, "F");
bft.append_child(bfC, "G");
bft.append_child(bfC, "H");
bft.append_child(bfD, "I");
tree<std::string>::breadth_first_queued_iterator bfq=bft.begin_breadth_first();
while(bfq!=bft.end_breadth_first()) {
std::cout << *bfq << std::endl;
++bfq;
}
print_tree(bft, bft.begin(), bft.end());
bft.wrap(bfD, "wrap");
print_tree(bft, bft.begin(), bft.end());
tree<std::string>::leaf_iterator li=tr.begin_leaf(bfC);
while(li!=tr.end_leaf(bfC)) {
std::cout << *li << std::endl;
++li;
}
// tree<std::string> testfixed;
// testfixed.insert(testfixed.begin(), "one");
// testfixed.insert(testfixed.begin(), "two");
// testfixed.insert(testfixed.begin(), "three");
// tree<std::string>::fixed_depth_iterator fit=testfixed.begin();
// while(testfixed.is_valid(fit)) {
// std::cout << *fit << std::endl;
// ++fit;
// }
}
}

View file

@ -0,0 +1,311 @@
empty tree to begin with:
0
'more text' is sibling 2 in its sibling range
filled tree:
-----
extra
html
body
before h1
h1
some text
more text
-----
filled tree, post-order traversal:
-----
extra
before h1
some text
h1
more text
body
html
-----
swapped elements:
-----
extra
html
body
h1
some text
before h1
more text
-----
swapped back:
-----
extra
html
body
before h1
h1
some text
more text
-----
copied tree:
-----
h1
some text
-----
result of search for h1 and kasper:
-----
h1
some text
-----
kasper not found
replacement tree:
-----
h3
text in h3
-----
-----
extra
html
body
before h1
h1
some text
more text
-----
filled tree with replacement done:
-----
extra
html
body
before h1
h3
text in h3
more text
-----
-----
extra
html
body
before h1
<foobar>
text in h3
more text
-----
-----
extra
html
body
before h1
<foobar>
text in h3
more
more text
-----
moved content:
-----
extra
html
body
<foobar>
text in h3
before h1
more
more text
-----
children of h1:
text in h3
before h1
flattened (at h3) tree:
-----
extra
html
body
<foobar>
text in h3
before h1
more
more text
-----
children of body erased:
-----
extra
html
body
-----
h1 not found
erased tree:
-----
html
body
-----
copies still exist:
-----
extra
html
body
before h1
<foobar>
text in h3
more
more text
-----
-----
extra
html
body
before h1
<foobar>
text in h3
more
more text
-----
testing comparison functions:
1 (should be 1)
<foobar>
0 (should be 0)
0 (should be 0)
1 (should be 1)
tree flattened, test again
-----
extra
html
body
before h1
<foobar>
text in h3
more
more text
-----
0 (should be 0)
1 (should be 1)
0 (should be 0)
0 (should be 0)
unsorted subtree:
-----
extra
html
body
before h1
modified
text in h3
ccc
bbb
bbb
aaa
more
more text
-----
partially sorted subtree: (sorted from text in h3 to more text, excluding the last element)
-----
extra
html
body
before h1
modified
more
text in h3
ccc
bbb
bbb
aaa
more text
-----
sorted subtree:
-----
extra
html
body
before h1
modified
more
more text
text in h3
aaa
bbb
bbb
ccc
-----
test merge
-----
html
head
title
body
h1
h1
-----
-----
head
another title
-----
-----
html
head
title
body
h1
h1
head
another title
-----
-----
html
head
title
another title
body
h1
h1
head
another title
-----
-----
another title
head
h1
h1
body
another title
title
head
html
-----
-----
head
another title
html
body
h1
h1
head
another title
title
-----
A
B
C
D
E
F
G
H
I
-----
A
B
E
F
C
G
H
D
I
-----
-----
A
B
E
F
C
G
H
wrap
D
I
-----

2786
lib/tree-2.81/src/tree.hh Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,59 @@
/*
Cadabra: a field-theory motivated computer algebra system.
Copyright (C) 2001-2009 Kasper Peeters <kasper.peeters@aei.mpg.de>
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#include <string>
#include <iostream>
#include "tree.hh"
using namespace std;
int main(int, char **)
{
tree<string> tr;
tree<string>::iterator top, one, two, loc, banana;
top=tr.begin();
one=tr.insert(top, "one");
two=tr.append_child(one, "two");
tr.append_child(two, "apple");
banana=tr.append_child(two, "banana");
tr.append_child(banana,"cherry");
tr.append_child(two, "peach");
tr.append_child(one,"three");
loc=find(tr.begin(), tr.end(), "two");
if(loc!=tr.end()) {
tree<string>::sibling_iterator sib=tr.begin(loc);
while(sib!=tr.end(loc)) {
cout << (*sib) << endl;
++sib;
}
cout << endl;
tree<string>::iterator sib2=tr.begin(loc);
tree<string>::iterator end2=tr.end(loc);
while(sib2!=end2) {
for(int i=0; i<tr.depth(sib2)-2; ++i)
cout << " ";
cout << (*sib2) << endl;
++sib2;
}
}
}

View file

@ -0,0 +1,92 @@
/*
A collection of miscellaneous utilities that operate on the templated
tree.hh class.
Copyright (C) 2001-2009 Kasper Peeters <kasper.peeters@aei.mpg.de>
(At the moment this only contains a printing utility, thanks to Linda
Buisman <linda.buisman@studentmail.newcastle.edu.au>)
This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef tree_util_hh_
#define tree_util_hh_
#include <iostream>
#include "tree.hh"
namespace kptree {
template<class T>
void print_tree_bracketed(const tree<T>& t, std::ostream& str=std::cout);
template<class T>
void print_subtree_bracketed(const tree<T>& t, typename tree<T>::iterator iRoot,
std::ostream& str=std::cout);
// Iterate over all roots (the head) and print each one on a new line
// by calling printSingleRoot.
template<class T>
void print_tree_bracketed(const tree<T>& t, std::ostream& str)
{
int headCount = t.number_of_siblings(t.begin());
int headNum = 0;
for(typename tree<T>::sibling_iterator iRoots = t.begin(); iRoots != t.end(); ++iRoots, ++headNum) {
print_subtree_bracketed(t,iRoots,str);
if (headNum != headCount) {
str << std::endl;
}
}
}
// Print everything under this root in a flat, bracketed structure.
template<class T>
void print_subtree_bracketed(const tree<T>& t, typename tree<T>::iterator iRoot, std::ostream& str)
{
if(t.empty()) return;
if (t.number_of_children(iRoot) == 0) {
str << *iRoot;
}
else {
// parent
str << *iRoot;
str << "(";
// child1, ..., childn
int siblingCount = t.number_of_siblings(t.begin(iRoot));
int siblingNum;
typename tree<T>::sibling_iterator iChildren;
for (iChildren = t.begin(iRoot), siblingNum = 0; iChildren != t.end(iRoot); ++iChildren, ++siblingNum) {
// recursively print child
print_subtree_bracketed(t,iChildren,str);
// comma after every child except the last one
if (siblingNum != siblingCount ) {
str << ", ";
}
}
str << ")";
}
}
}
#endif

1579
lib/tree-2.81/src/xinlin.hh Normal file

File diff suppressed because it is too large Load diff

1
lib/vectorwrapper Submodule

@ -0,0 +1 @@
Subproject commit 39c58ca4aba6066de440408a2086248fdb867446

58
src/compatibility.h Normal file
View file

@ -0,0 +1,58 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id45CDD1DAEF4F42968E3C89F68FDDA9BC
#define id45CDD1DAEF4F42968E3C89F68FDDA9BC
#if defined(__GNUC__)
# if defined(__clang__)
# if !defined(__has_attribute)
//Fall back to version number comparing
# else
# if __has_attribute(flatten)
# define a_flatten __attribute__((flatten))
# else
# define a_flatten
# endif
# if __has_attribute(always_inline)
# define a_always_inline __attribute__((always_inline))
# else
# define a_always_inline
# endif
# if __has_attribute(pure)
# define a_pure __attribute__((pure))
# else
# define a_pure
# endif
# endif
# else
//Fix here if you get warnings about unsupported attributes on your compiler
# define a_flatten __attribute__((flatten))
# define a_always_inline __attribute__((always_inline))
# define a_pure __attribute__((pure))
# endif
#else
# warning "Unsupported compiler, please fill this section or file a bug"
# define a_flatten
# define a_always_inline
# define a_pure
#endif
#endif

13
src/gamescenebase.hpp Normal file
View file

@ -0,0 +1,13 @@
#pragma once
namespace curry {
class GameSceneBase {
public:
virtual ~GameSceneBase() noexcept = default;
virtual void prepare() = 0;
virtual void exec() = 0;
virtual bool wants_to_quit() const = 0;
virtual void destroy() noexcept = 0;
};
} //namespace curry

27
src/ingamescene.cpp Normal file
View file

@ -0,0 +1,27 @@
#include "ingamescene.hpp"
#include <iostream>
namespace curry {
IngameScene::IngameScene (cloonel::SDLMain* parSDLMain) :
m_sdlmain(parSDLMain)
{
}
IngameScene::~IngameScene() noexcept = default;
void IngameScene::prepare() {
std::cout << "game prepare\n";
}
void IngameScene::exec() {
std::cout << "game exec\n";
}
bool IngameScene::wants_to_quit() const {
return true;
}
void IngameScene::destroy() noexcept {
std::cout << "game destroy\n";
}
} //namespace curry

23
src/ingamescene.hpp Normal file
View file

@ -0,0 +1,23 @@
#pragma once
#include "gamescenebase.hpp"
namespace cloonel {
class SDLMain;
} //namespace cloonel
namespace curry {
class IngameScene : public GameSceneBase {
public:
explicit IngameScene (cloonel::SDLMain* parSDLMain);
virtual ~IngameScene() noexcept;
virtual void prepare() override;
virtual void exec() override;
virtual bool wants_to_quit() const override;
virtual void destroy() noexcept override;
private:
cloonel::SDLMain* m_sdlmain;
};
} //namespace curry

48
src/main.cpp Normal file
View file

@ -0,0 +1,48 @@
#include "sdlmain.hpp"
#include "gamescenebase.hpp"
#include "ingamescene.hpp"
#include <cstdint>
#include <iostream>
#include <ciso646>
namespace {
const uint16_t DEF_WIN_WIDTH = 640;
const uint16_t DEF_WIN_HEIGHT = 480;
const uint16_t REFERENCE_WIDTH = 800;
const uint16_t REFERENCE_HEIGHT = 600;
const char GameName[] = "MyCurry";
void run_main_loop (curry::GameSceneBase& parGame) {
parGame.prepare();
do {
parGame.exec();
} while (not parGame.wants_to_quit());
parGame.destroy();
}
} //unnamed namespace
int main() {
cloonel::SDLMain sdl_main(
GameName,
cloonel::ushort2(DEF_WIN_WIDTH, DEF_WIN_HEIGHT),
cloonel::ushort2(REFERENCE_WIDTH, REFERENCE_HEIGHT)
);
int ret_val = 0;
try {
sdl_main.Init();
std::cout << "Using renderer \"" << sdl_main.GetRendererName() << "\" ";
std::cout << "and video driver \"" << sdl_main.GetVideoDriverName() << "\"\n";
curry::IngameScene game(&sdl_main);
run_main_loop(game);
}
catch (const std::runtime_error& e) {
std::cerr << "Error during SDL2 initialization:\n";
std::cerr << e.what() << std::endl;
ret_val = 1;
}
std::cout << "Quitting now" << std::endl;
return ret_val;;
}

180
src/observersmanager.hpp Normal file
View file

@ -0,0 +1,180 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef idF5E41734950640CDA3C949E0D3A9A30D
#define idF5E41734950640CDA3C949E0D3A9A30D
#include <cassert>
#include <vector>
#include <algorithm>
#include <iterator>
#include <ciso646>
#include <tree.hh>
#include <boost/iterator/transform_iterator.hpp>
#include <unordered_set>
#if defined (WITH_VERBOSE_OBS_MANAGER) && defined(__GNUC__) && __GNUC__ >= 2 && !defined(NDEBUG)
# define OBS_MANAGER_LOG
#endif
#if defined(OBS_MANAGER_LOG)
# include <iostream>
#endif
namespace cloonel {
template <typename T>
class ObserversManager {
public:
typedef size_t TicketType;
private:
struct TicketedWrapper {
TicketedWrapper ( void ) = default;
TicketedWrapper ( T parItem, TicketType parTicket ) :
itm(parItem),
ticket(parTicket)
{
}
T itm;
TicketType ticket;
bool operator== ( const TicketedWrapper& parOther ) const { return parOther.ticket == ticket; }
bool operator== ( TicketType parOther ) const { return parOther == ticket; }
};
static T& TicketedWrapperToItm ( TicketedWrapper& parWrapper ) { return parWrapper.itm; }
typedef tree<TicketedWrapper> TreeType;
typedef typename tree<TicketedWrapper>::iterator TreeIteratorType;
public:
enum {
Ticket_Null = 0
};
typedef boost::transform_iterator<std::function<T&(TicketedWrapper&)>, TreeIteratorType> iterator;
ObserversManager ( void );
~ObserversManager ( void ) noexcept;
TicketType Add ( T parObserver, TicketType parParent=Ticket_Null );
void Remove ( TicketType parTicket ) noexcept;
void RemoveAll ( void ) noexcept;
void Update ( TicketType parTicket, T parObserver );
std::size_t size ( void ) const { return m_tree.size(); }
iterator begin ( void ) { return iterator(m_tree.begin(), &TicketedWrapperToItm); }
iterator end ( void ) { return iterator(m_tree.end(), &TicketedWrapperToItm); }
void CopyObservers ( std::unordered_set<T>& parOut );
private:
TreeIteratorType GetByTicket_AssertPresent ( TicketType parTicket );
TreeType m_tree;
TicketType m_nextTicket;
};
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
ObserversManager<T>::ObserversManager() :
m_nextTicket(1)
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
ObserversManager<T>::~ObserversManager() noexcept {
assert(m_tree.empty());
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
typename ObserversManager<T>::TicketType ObserversManager<T>::Add (T parObserver, TicketType parParent) {
const auto currTicket = m_nextTicket;
if (Ticket_Null == parParent)
m_tree.insert(m_tree.begin(), TicketedWrapper(parObserver, currTicket));
else
m_tree.append_child(GetByTicket_AssertPresent(parParent), TicketedWrapper(parObserver, currTicket));
#if defined(OBS_MANAGER_LOG)
std::cout << __PRETTY_FUNCTION__ << " registering " << currTicket << " as a child of " << parParent << "\n";
#endif
++m_nextTicket;
return currTicket;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
void ObserversManager<T>::Remove (TicketType parTicket) noexcept {
auto deleme = GetByTicket_AssertPresent(parTicket);
#if defined(OBS_MANAGER_LOG)
for (auto it(deleme); it != m_tree.end(); ++it) {
std::cout << __PRETTY_FUNCTION__ << " unregistering " << it->ticket << "\n";
}
#endif
m_tree.erase(deleme);
if (parTicket == m_nextTicket - 1)
--m_nextTicket;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
void ObserversManager<T>::RemoveAll() noexcept {
if (not m_tree.empty()) {
for (typename TreeType::sibling_iterator it(m_tree.begin()), itEND(m_tree.end()); it != itEND; ++it) {
const TicketType ticket = it->ticket;
this->Remove(ticket);
}
assert(m_tree.empty());
}
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
void ObserversManager<T>::Update (TicketType parTicket, T parObserver) {
std::swap(GetByTicket_AssertPresent(parTicket)->itm, parObserver);
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
typename ObserversManager<T>::TreeIteratorType ObserversManager<T>::GetByTicket_AssertPresent (TicketType parTicket) {
auto ret = std::find(m_tree.begin(), m_tree.end(), parTicket);
assert(m_tree.end() != ret);
return ret;
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
template <typename T>
void ObserversManager<T>::CopyObservers (std::unordered_set<T>& parOut) {
for (const auto& itm : m_tree) {
parOut.insert(itm.itm);
}
}
} //namespace cloonel
#if defined(OBS_MANAGER_LOG)
# undef OBS_MANAGER_LOG
#endif
#endif

236
src/sdlmain.cpp Normal file
View file

@ -0,0 +1,236 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sdlmain.hpp"
#include "observersmanager.hpp"
#include "sizenotifiable.hpp"
#include "sizeratio.hpp"
#include <SDL2/SDL.h>
#include <stdexcept>
#include <sstream>
#include <ciso646>
#include <cstring>
#include <utility>
#if defined(RASPBERRY_PI)
#include <bcm_host.h>
#endif
namespace cloonel {
namespace {
///----------------------------------------------------------------------
///----------------------------------------------------------------------
std::pair<int, std::string> GetRenderingDriver() {
typedef std::pair<int, std::string> RetPairType;
const int count = SDL_GetNumRenderDrivers();
int opengles = -1;
int opengles2 = -1;
int opengl = -1;
SDL_RendererInfo info;
for (int z = 0; z < count; ++z) {
const int ret = SDL_GetRenderDriverInfo(z, &info);
if (0 == ret) {
if (std::strcmp("opengles", info.name) == 0)
opengles = z;
else if (std::strcmp("opengles2", info.name) == 0)
opengles2 = z;
else if (std::strcmp("opengl", info.name) == 0)
opengl = z;
}
}
#if !defined(FORCE_OPENGLES)
if (opengl > -1)
return RetPairType(opengl, "opengl");
#endif
if (opengles2 > -1)
return RetPairType(opengles2, "opengles2");
if (opengles > -1)
return RetPairType(opengles, "opengles");
#if defined(FORCE_OPENGLES)
if (opengl > -1)
return RetPairType(opengl, "opengl");
#endif
return RetPairType(-1, "default");
}
} //unnamed namespace
struct SDLMain::LocalData {
SDL_Window* window;
SDL_Renderer* renderer;
SizeRatio sizeratio;
ObserversManager<SizeNotifiableBase*> resChangeNotifList;
bool initialized;
#if defined(RASPBERRY_PI)
bool bcmInitialized;
#endif
};
///------------------------------------------------------------------------
///------------------------------------------------------------------------
SDLMain::SDLMain (const char* parGameName, ushort2 parRes, ushort2 parReferenceRes) :
m_gameName(parGameName),
m_localData(new LocalData)
{
m_localData->sizeratio.SetOriginal(static_cast<float2>(parReferenceRes), static_cast<float2>(parRes));
m_localData->initialized = false;
#if defined(RASPBERRY_PI)
m_localData->bcmInitialized = false;
#endif
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
SDLMain::~SDLMain() noexcept {
ClearIFN(*m_localData);
#if defined(RASPBERRY_PI)
assert(not m_localData->bcmInitialized);
#endif
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::Init() {
if (not m_localData->initialized)
InitSDL(*m_localData);
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::InitSDL (LocalData& parInitSDL) {
#if defined(RASPBERRY_PI)
assert(not parInitSDL.bcmInitialized);
bcm_host_init();
parInitSDL.bcmInitialized = true;
#endif
parInitSDL.window = nullptr;
parInitSDL.renderer = nullptr;
parInitSDL.initialized = false;
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
throw std::runtime_error(SDL_GetError());
parInitSDL.initialized = true;
#if defined(FORCE_OPENGLES)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
#endif
const float2 wh(m_localData->sizeratio.Resolution());
SDL_Window* const win = SDL_CreateWindow(m_gameName.c_str(), 100, 100, static_cast<int>(wh.x()), static_cast<int>(wh.y()), SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if (!win)
throw std::runtime_error(SDL_GetError());
parInitSDL.window = win;
const auto rendererDriver = GetRenderingDriver();
m_rendererName = rendererDriver.second;
SDL_Renderer* const renderer = SDL_CreateRenderer(win, rendererDriver.first, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (!renderer)
throw std::runtime_error(SDL_GetError());
parInitSDL.renderer = renderer;
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::ClearIFN (LocalData& parInitSDL) noexcept {
if (parInitSDL.renderer)
SDL_DestroyRenderer(parInitSDL.renderer);
if (parInitSDL.window)
SDL_DestroyWindow(parInitSDL.window);
if (parInitSDL.initialized) {
parInitSDL.initialized = false;
SDL_Quit();
}
#if defined(RASPBERRY_PI)
if (parInitSDL.bcmInitialized) {
parInitSDL.bcmInitialized = false;
bcm_host_deinit();
}
#endif
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
SDL_Renderer* SDLMain::GetRenderer() {
if (m_localData->initialized)
return m_localData->renderer;
else
return nullptr;
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::SetResolution (ushort2 parRes) {
m_localData->sizeratio.UpdateResolution(static_cast<float2>(parRes));
{
SDL_Renderer* const renderer = GetRenderer();
assert(renderer);
const int retVal = SDL_RenderSetLogicalSize(renderer, parRes.x(), parRes.y());
if (retVal) {
std::ostringstream oss;
oss << "Error setting logical size to renderer to " << parRes.x() << "x" << parRes.y() << ": " << SDL_GetError();
throw std::runtime_error(oss.str());
}
const SDL_Rect area = { 0, 0, parRes.x(), parRes.y() };
const int retValViewport = SDL_RenderSetViewport(renderer, &area);
if (retValViewport) {
std::ostringstream oss;
oss << "Error setting viewport to renderer to " << parRes.x() << "x" << parRes.y() << ": " << SDL_GetError();
throw std::runtime_error(oss.str());
}
}
for (auto currNotifiable : m_localData->resChangeNotifList) {
currNotifiable->NotifyResChanged(m_localData->sizeratio);
}
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
size_t SDLMain::RegisterForResChange (SizeNotifiableBase* parNotif) {
parNotif->NotifyResChanged(m_localData->sizeratio);
return m_localData->resChangeNotifList.Add(parNotif);
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::UnregisterForResChange (size_t parID) noexcept {
m_localData->resChangeNotifList.Remove(parID);
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
void SDLMain::SwapRegisteredForResChange (size_t parID, SizeNotifiableBase* parNotif) {
m_localData->resChangeNotifList.Update(parID, parNotif);
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
ushort2 SDLMain::WidthHeight() const noexcept {
return static_cast<ushort2>(m_localData->sizeratio.Resolution());
}
///------------------------------------------------------------------------
///------------------------------------------------------------------------
std::string SDLMain::GetVideoDriverName() const {
return std::string(SDL_GetCurrentVideoDriver());
}
} //namespace cloonel

60
src/sdlmain.hpp Normal file
View file

@ -0,0 +1,60 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id8E7A054DAC9040B887F2620EFD229EE8
#define id8E7A054DAC9040B887F2620EFD229EE8
#include "vector.hpp"
#include <memory>
#include <string>
struct SDL_Renderer;
namespace cloonel {
class SizeNotifiableBase;
class SDLMain {
public:
SDLMain ( const char* parGameName, ushort2 parRes, ushort2 parReferenceRes );
~SDLMain ( void ) noexcept;
void Init ( void );
SDL_Renderer* GetRenderer ( void );
ushort2 WidthHeight ( void ) const noexcept;
void SetResolution ( ushort2 parRes );
size_t RegisterForResChange ( SizeNotifiableBase* parNotif );
void UnregisterForResChange ( size_t parID ) noexcept;
void SwapRegisteredForResChange ( size_t parID, SizeNotifiableBase* parNotif );
const std::string& GetRendererName ( void ) const { return m_rendererName; }
std::string GetVideoDriverName ( void ) const;
private:
struct LocalData;
void InitSDL ( LocalData& parData );
void ClearIFN ( LocalData& parData ) noexcept;
const std::string m_gameName;
std::string m_rendererName;
std::unique_ptr<LocalData> m_localData;
};
} //namespace cloonel
#endif

59
src/sizenotifiable.cpp Normal file
View file

@ -0,0 +1,59 @@
#include "sizenotifiable.hpp"
#include "sizeratio.hpp"
#include "sdlmain.hpp"
#include <cassert>
#include <ciso646>
namespace cloonel {
namespace implem {
} //namespace implem
namespace regbehaviours {
///----------------------------------------------------------------------
///----------------------------------------------------------------------
void AutoRegister::Register (SizeNotifiableBase* parNotifiable) {
assert(m_sdlmain);
#if !defined(NDEBUG)
assert(not m_registered);
m_registered = true;
#endif
m_id = m_sdlmain->RegisterForResChange(parNotifiable);
}
///----------------------------------------------------------------------
///----------------------------------------------------------------------
void AutoRegister::Unregister() noexcept {
#if !defined(NDEBUG)
assert(m_registered or not m_sdlmain);
m_registered = false;
#endif
if (m_sdlmain) {
m_sdlmain->UnregisterForResChange(m_id);
}
}
///----------------------------------------------------------------------
///----------------------------------------------------------------------
AutoRegister::AutoRegister (AutoRegister&& parOther, SizeNotifiableBase* parSwapTo) :
m_sdlmain(nullptr),
m_id(0)
#if !defined(NDEBUG)
, m_registered(false)
#endif
{
std::swap(m_sdlmain, parOther.m_sdlmain);
std::swap(m_id, parOther.m_id);
#if !defined(NDEBUG)
std::swap(m_registered, parOther.m_registered);
#endif
assert(m_sdlmain);
m_sdlmain->SwapRegisteredForResChange(m_id, parSwapTo);
}
} //namespace regbehaviours
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void SizeNotifiableBase::NotifyResChanged (const SizeRatio& parSize) {
m_scaleRatio = parSize.Ratio();
}
} //namespace cloonel

128
src/sizenotifiable.hpp Normal file
View file

@ -0,0 +1,128 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id78906DE4FB0D43219CD3F0D9C620FC06
#define id78906DE4FB0D43219CD3F0D9C620FC06
#include "vector.hpp"
#include <cstddef>
#include <algorithm>
namespace cloonel {
class SizeRatio;
class SDLMain;
class SizeNotifiableBase;
namespace regbehaviours {
class DontRegister {
public:
enum { SDLMAIN_NEEDED = false };
DontRegister ( void ) = default;
DontRegister ( DontRegister&&, SizeNotifiableBase* ) { }
~DontRegister ( void ) noexcept = default;
void Register ( SizeNotifiableBase* ) const noexcept { return; }
void Unregister ( void ) const noexcept { return; }
};
class AutoRegister {
public:
enum { SDLMAIN_NEEDED = true };
AutoRegister ( AutoRegister&& parOther, SizeNotifiableBase* parSwapTo );
explicit AutoRegister ( SDLMain* parMain ) :
m_sdlmain(parMain)
#if !defined(NDEBUG)
, m_registered(false)
#endif
{
}
~AutoRegister ( void ) noexcept = default;
void Register ( SizeNotifiableBase* parNotifiable );
void Unregister ( void ) noexcept;
private:
SDLMain* m_sdlmain;
size_t m_id;
#if !defined(NDEBUG)
bool m_registered;
#endif
};
} //namespace regbehaviours
class SizeNotifiableBase {
protected:
SizeNotifiableBase ( void ) = default;
SizeNotifiableBase ( const SizeNotifiableBase& ) = default;
virtual ~SizeNotifiableBase ( void ) noexcept = default;
SizeNotifiableBase& operator= ( const SizeNotifiableBase& ) = delete;
public:
virtual void NotifyResChanged ( const SizeRatio& parSize );
const float2& Ratio ( void ) const noexcept { return m_scaleRatio; }
private:
float2 m_scaleRatio;
};
template <class RegisterBehaviour, bool=RegisterBehaviour::SDLMAIN_NEEDED>
class SizeNotifiable;
template <class RegisterBehaviour>
class SizeNotifiable<RegisterBehaviour, false> : private RegisterBehaviour, public SizeNotifiableBase {
static_assert(RegisterBehaviour::SDLMAIN_NEEDED == false, "SdlMainNeeded mismatches expected value");
public:
SizeNotifiable ( const SizeNotifiable& ) = delete;
SizeNotifiable ( SizeNotifiable&& parOther ) :
RegisterBehaviour(std::move(parOther), this),
SizeNotifiableBase(parOther)
{
}
SizeNotifiable ( void ) {
this->Register(this);
}
virtual ~SizeNotifiable ( void ) noexcept {
this->Unregister();
}
};
template <class RegisterBehaviour>
class SizeNotifiable<RegisterBehaviour, true> : private RegisterBehaviour, public SizeNotifiableBase {
static_assert(RegisterBehaviour::SDLMAIN_NEEDED == true, "SdlMainNeeded mismatches expected value");
public:
SizeNotifiable ( const SizeNotifiable& ) = delete;
SizeNotifiable ( SizeNotifiable&& parOther ) :
RegisterBehaviour(std::move(parOther), this),
SizeNotifiableBase(parOther)
{
}
explicit SizeNotifiable ( SDLMain* parSdlMain ) :
RegisterBehaviour(parSdlMain)
{
this->Register(this);
}
virtual ~SizeNotifiable ( void ) noexcept {
this->Unregister();
}
};
} //namespace cloonel
#endif

47
src/sizeratio.cpp Normal file
View file

@ -0,0 +1,47 @@
#include "sizeratio.hpp"
#include "compatibility.h"
namespace cloonel {
namespace {
float2 CalculateRatio ( float2 parOriginal, float2 parResolution ) a_pure;
///----------------------------------------------------------------------
///----------------------------------------------------------------------
float2 CalculateRatio (float2 parOriginal, float2 parResolution) {
return parResolution / parOriginal;
}
} //unnamed namespace
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
SizeRatio::SizeRatio (const float2& parOriginal) :
m_original(parOriginal),
m_size(parOriginal),
m_ratio(1.0f)
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
SizeRatio::SizeRatio (const float2& parOriginal, const float2& parSize) :
m_original(parOriginal),
m_size(parSize),
m_ratio(CalculateRatio(parOriginal, parSize))
{
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void SizeRatio::SetOriginal (const float2& parOriginal, const float2& parRes) {
m_original = parOriginal;
m_size = parRes;
m_ratio = CalculateRatio(parOriginal, parRes);
}
///--------------------------------------------------------------------------
///--------------------------------------------------------------------------
void SizeRatio::UpdateResolution (const float2& parNewRes) {
m_size = parNewRes;
m_ratio = CalculateRatio(m_original, parNewRes);
}
} //namespace cloonel

45
src/sizeratio.hpp Normal file
View file

@ -0,0 +1,45 @@
/*
Copyright 2014 Michele "King_DuckZ" Santullo
This file is part of CloonelJump.
CloonelJump is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
CloonelJump is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef id3098F08C14B84E3C8CE169CBA05C9C86
#define id3098F08C14B84E3C8CE169CBA05C9C86
#include "vector.hpp"
namespace cloonel {
class SizeRatio {
public:
SizeRatio ( void ) = default;
explicit SizeRatio ( const float2& parOriginal );
SizeRatio ( const float2& parOriginal, const float2& parSize );
~SizeRatio ( void ) noexcept = default;
const float2& Ratio ( void ) const noexcept { return m_ratio; }
const float2& Resolution ( void ) const noexcept { return m_size; }
void SetOriginal ( const float2& parOriginal, const float2& parRes );
void UpdateResolution ( const float2& parNewRes );
private:
float2 m_original;
float2 m_size;
float2 m_ratio;
};
} //namespace cloonel
#endif

45
src/vector.hpp Normal file
View file

@ -0,0 +1,45 @@
#pragma once
#include "vectorwrapper/vectorwrapper.hpp"
#include <array>
#include <cstdint>
namespace vwr {
template <>
struct VectorWrapperInfo<std::array<float, 2>> {
enum {
dimensions = 2
};
typedef float scalar_type;
typedef std::array<scalar_type, 2> vector_type;
static scalar_type& get_at (size_t parIndex, vector_type& parVector) {
return parVector[parIndex];
}
};
template <>
struct VectorWrapperInfo<std::array<uint16_t, 2>> {
enum {
dimensions = 2
};
typedef uint16_t scalar_type;
typedef std::array<scalar_type, 2> vector_type;
static scalar_type& get_at (size_t parIndex, vector_type& parVector) {
return parVector[parIndex];
}
};
} //namespace vwr
namespace curry {
using vec2f = vwr::Vec<std::array<float, 2>>;
} //namespace curry
//make stuff from CloonelJump compile happily
namespace cloonel {
using ushort2 = vwr::Vec<std::array<uint16_t, 2>>;
using float2 = vwr::Vec<std::array<float, 2>>;
} //namespace cloonel