diff --git a/.bumpversion.cfg b/.bumpversion.cfg index ec593fdc94..8499c0131b 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.3 +current_version = 1.0.0 commit = True tag = True diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index e8c7d0e902..01d25b8246 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -7,12 +7,13 @@ on: - '**' schedule: - cron: '0 0 * * 0' + workflow_dispatch: jobs: tidy: name: Enforce Tidyness runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'recursive' - run: sudo apt-get update -qq @@ -22,12 +23,20 @@ jobs: name: Test Tidy Enforcement on macOS runs-on: macos-11 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: + # sometimes checkout action doesn't result in clean directory? + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha || github.ref }} submodules: 'recursive' + - run: git status --ignored - run: brew install coreutils findutils gnu-sed gawk grep rename sphinx-doc # adapted from https://stackoverflow.com/a/42878119 - run: brew link sphinx-doc --force + # updates PATH to use Homebrew-installed tools first + # see https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path + - run: echo "/usr/local/bin:$PATH" > $GITHUB_PATH + - run: echo $PATH - run: ./ci/test_tidy.sh test: name: Tests @@ -47,13 +56,17 @@ jobs: CXX: ${{ matrix.cxx }} TEST_SET: ${{ matrix.test-set }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'recursive' - name: Set up GCC uses: egor-tensin/setup-gcc@v1 with: version: 11 + - name: Set up clang + uses: egor-tensin/setup-clang@v1 + with: + version: 15 - run: sudo apt-get update -qq - run: sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - run: sudo apt-get update -qq @@ -68,7 +81,7 @@ jobs: name: Web Tests runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'recursive' - name: Set up GCC @@ -86,7 +99,11 @@ jobs: name: Measure Test Coverage runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 + - name: Set up clang + uses: egor-tensin/setup-clang@v1 + with: + version: 15 + - uses: actions/checkout@v3 with: submodules: 'recursive' - run: sudo apt-get update -qq @@ -96,26 +113,81 @@ jobs: - run: export CXX=clang++ && make install-coverage-dependencies - run: export CXX=clang++ && make coverage - run: curl -s https://codecov.io/bash | bash + # adapted from https://docs.github.com/en/packages/managing-github-packages-using-github-actions-workflows/publishing-and-installing-a-package-with-github-actions#publishing-a-package-using-an-action + build-container: + name: Build Docker Image + runs-on: ubuntu-22.04 + env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v2 + with: + submodules: 'recursive' + - name: Log in to GitHub Container Registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: type=raw,value=ACTIONS_BUILD_${{ github.run_number }} + - name: Push to GHCR + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} test-documentation: name: Test Documentation Build runs-on: ubuntu-22.04 + needs: build-container + container: + image: ghcr.io/devosoft/empirical:ACTIONS_BUILD_${{ github.run_number }} + # github actions requires root to access mounted volumes + options: --user root steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: submodules: 'recursive' - - uses: mmore500/actions-setup-docker@94429ebc8d9edb4e8c8afb2667bce1e89435f74f - - run: docker build -t devosoft/empirical . - - run: docker ps -a - - run: sudo docker run --name empirical devosoft/empirical /bin/bash -c "set -o pipefail && cd /opt/Empirical/doc && make html coverage | ./headtail.sh && python /opt/Empirical/doc/parse_documentation_coverage.py /opt/Empirical/doc/_build/doc-coverage.json >> /opt/Empirical/doc-coverage.json" - - run: sudo docker cp empirical:/opt/Empirical/doc-coverage.json . + - run: doxygen + - run: cd doc && python make_md.py + - run: cd doc && make html | ./headtail.sh + - run: cd doc && make coverage + - run: ls doc/ && ls doc/_build + - run: cd doc && python parse_documentation_coverage.py _build/doc-coverage.json >> doc-coverage.json + - uses: actions/upload-artifact@v2 + with: + name: doc-coverage + path: doc/doc-coverage.json + deploy-documentation-coverage: + name: Deploy Documentation Coverage + runs-on: ubuntu-22.04 + if: github.ref == 'refs/heads/master' + needs: test-documentation + steps: + - uses: actions/download-artifact@v2 + with: + name: doc-coverage + path: data - uses: sylvanld/action-storage@v1 - if: github.ref == 'refs/heads/master' with: - src: doc-coverage.json - dst: stats/doc-coverage.json - deploy-dockerhub: - name: Deploy to DockerHub + src: data/doc-coverage.json + dst: data/doc-coverage.json + deploy-container: + name: Deploy to DockerHub and ghcr.io runs-on: ubuntu-22.04 + permissions: + contents: read + packages: write if: github.ref == 'refs/heads/master' needs: - tidy diff --git a/.gitignore b/.gitignore index 0901369ed0..ac2e137bd6 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ demos/Emphatic/Emphatic demos/Emphatic/examples/ConceptTest demos/Emphatic/examples/ConceptTest.cpp demos/MABE/examples/NK +demos/MAP-Elites-Arm/web/MAP-Elites-Arm.js demos/NK.bak/ demos/NK/NK demos/NK/web/NK.js @@ -76,6 +77,13 @@ demos/NK/web/jquery-1.11.2.min.js demos/NK/web/NK.asm.js demos/NK/web/NK.html demos/NK/web/NK.js.mem +demos/utils/words/Wordle/Wordle +demos/utils/words/Wordle/web/ +demos/utils/words/annotate-length +demos/utils/words/has-only +demos/utils/words/wordlists/ +demos/utils/words/wordplay-remove +demos/utils/words/wordplay-shuffle doc/doxygen/ examples/*/* diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000..0abbb86079 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,25 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python and other tools you might need +build: + os: ubuntu-22.04 + tools: + python: "3.10" + jobs: + pre_build: + - doxygen + - cd doc && python make_md.py + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: doc/conf.py + +# Optionally declare the Python requirements required to build your docs +python: + install: + - requirements: doc/requirements.txt diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index e862e52db5..0000000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,19 +0,0 @@ -# .readthedocs.yml -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -#Required -version: 2 - -# Build documentation in the docs/ directory with Sphinx -sphinx: - configuration: doc/conf.py - -# Optionally build your docs in additional formats such as PDF -formats: [] - -# Optionally set the version of Python and requirements required to build your docs -python: - version: 3.7 - install: - - requirements: doc/requirements.txt diff --git a/Dockerfile b/Dockerfile index f6b8de411a..238d21c095 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Pull base image. -FROM ubuntu:bionic-20210416 +FROM ubuntu:focal-20230412 COPY . /opt/Empirical @@ -8,6 +8,7 @@ SHELL ["/bin/bash", "-c"] # Prevent interactive time zone config. # adapted from https://askubuntu.com/a/1013396 ENV DEBIAN_FRONTEND=noninteractive +ENV SPHINXBUILD="python3.10 -m sphinx" RUN \ echo 'Acquire::http::Timeout "60";' >> "/etc/apt/apt.conf.d/99timeout" \ @@ -23,28 +24,21 @@ RUN \ # remove -backports, -updates, -proposed, -security repositories # looks like we have to grab libxxhash0 from -updates now RUN \ - apt-get update -y \ + for n in $(seq 1 5); do apt-get update -y && sleep 5 && break; done \ && \ - apt-get install --no-install-recommends libxxhash0 \ + apt-get install --no-install-recommends -y libxxhash0 software-properties-common \ && \ - apt-get clean \ - && \ - rm -rf /var/lib/apt/lists/* \ - && \ - find /etc/apt -type f -name '*.list' -exec sed -i 's/\(^deb.*-backports.*\)/#\1/; s/\(^deb.*-updates.*\)/#\1/; s/\(^deb.*-proposed.*\)/#\1/; s/\(^deb.*-security.*\)/#\1/' {} + \ - && \ - apt-get update -y \ - && \ - apt-get install -y software-properties-common=0.96.24.32.1 \ + for n in $(seq 1 5); do add-apt-repository -y ppa:ubuntu-toolchain-r/test && sleep 5 && break; done \ && \ - add-apt-repository -y ppa:ubuntu-toolchain-r/test \ + for n in $(seq 1 5); do add-apt-repository -y ppa:deadsnakes/ppa && sleep 5 && break; done \ && \ - apt-get update -y \ + for n in $(seq 1 5); do apt-get update -y && sleep 5 && break; done \ && \ apt-get install --no-install-recommends --allow-downgrades -y \ + build-essential \ dpkg-dev \ g++-11 \ - libc6=2.27-3ubuntu1 \ + libc6 \ xvfb \ x11vnc \ x11-xkb-utils \ @@ -59,13 +53,9 @@ RUN \ lsb-release \ xdg-utils \ cmake \ - python-virtualenv \ - python-pip-whl \ - python-pip \ - python-setuptools \ - python3-setuptools \ - python3-virtualenv \ - python3-pip \ + 'python3\.10' \ + 'python3\.10-distutils' \ + 'python3\.10-venv' \ nodejs \ npm \ tar \ @@ -75,7 +65,7 @@ RUN \ doxygen \ curl \ perl \ - perl-base=5.26.1-6 \ + perl-base \ git \ htop \ man \ @@ -88,6 +78,7 @@ RUN \ ssh-client \ libasound2 \ gpg-agent \ + doxygen \ && \ apt-get clean \ && \ @@ -95,6 +86,14 @@ RUN \ && \ echo "installed apt packages" +# Set Python 3.10 as the default version of Python 3 +RUN \ + update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1 \ + && \ + update-alternatives --set python3 /usr/bin/python3.10 \ + && \ + ln -s /usr/bin/python3.10 /usr/bin/python + RUN \ echo $' \n\ XVFB=/usr/bin/Xvfb \n\ @@ -159,6 +158,8 @@ RUN \ && \ n 14.17 \ && \ + hash -r \ + && \ export python="/usr/bin/python3" \ && \ npm install source-map \ @@ -166,11 +167,19 @@ RUN \ echo "finalized set up dependency versions" RUN \ - pip install wheel==0.30.0 \ + python3.10 --version \ && \ - pip3 install wheel==0.30.0 \ + python3 --version \ && \ - pip3 install -r /opt/Empirical/doc/requirements.txt \ + curl -sS https://bootstrap.pypa.io/get-pip.py | python3.10 \ + && \ + python3.10 -m pip install --upgrade --force-reinstall pip virtualenv \ + && \ + python3.10 -m pip install wheel==0.30.0 six==1.16.0 \ + && \ + python3.10 -m pip install -r /opt/Empirical/third-party/requirements.txt \ + && \ + python3.10 -m pip install -r /opt/Empirical/doc/requirements.txt \ && \ echo "installed documentation build requirements" @@ -181,13 +190,19 @@ RUN \ && \ git submodule init \ && \ - git submodule update -f \ + echo "nameserver 8.8.8.8" > /etc/resolv.conf \ + && \ + n=0; until [ $n -ge 3 ]; do git submodule update -f && break || ((n++)); sleep 5; done; if [ $n -eq 3 ]; then echo "Update failed after 3 attempts."; else echo "Update successful!"; fi \ && \ echo "initialized submodules" RUN \ cd /opt/Empirical \ && \ + curl -sS https://bootstrap.pypa.io/get-pip.py | python3 \ + && \ + python3 -m pip install virtualenv \ + && \ make install-test-dependencies \ && \ echo "installed test dependencies" @@ -245,13 +260,6 @@ RUN \ && \ echo "installed karma-firefox-launcher" -# @mmore500 10-2021: python3 -m pip fixes UnicodeDecodeError -# when installing charset-normalizer from github -RUN \ - python3 -m pip install -r /opt/Empirical/third-party/requirements.txt \ - && \ - echo "installed documentation build requirements" - # Perform any further action as an unprivileged user. # adapted from https://stackoverflow.com/a/27703359 # and https://superuser.com/a/235398 diff --git a/Doxyfile b/Doxyfile index 8fc9188076..31abf156e7 100644 --- a/Doxyfile +++ b/Doxyfile @@ -1,4 +1,4 @@ -# Doxyfile 1.8.10 +# Doxyfile 1.9.7 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. @@ -12,16 +12,26 @@ # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 @@ -32,7 +42,7 @@ DOXYFILE_ENCODING = UTF-8 # title of most generated pages and in a few other places. # The default value is: My Project. -PROJECT_NAME = "Empirical" +PROJECT_NAME = Empirical # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version @@ -58,18 +68,30 @@ PROJECT_LOGO = # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = "doc/doxygen" +OUTPUT_DIRECTORY = doc/doxyoutput -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes -# performance problems for the file system. +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode @@ -81,14 +103,14 @@ ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English @@ -133,7 +155,7 @@ ALWAYS_DETAILED_SEC = NO # operators of the base classes will not be shown. # The default value is: NO. -INLINE_INHERITED_MEMB = YES +INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the @@ -179,6 +201,16 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO +# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus @@ -199,6 +231,14 @@ QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO +# By default Python docstrings are displayed as preformatted text and doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. @@ -222,20 +262,19 @@ TAB_SIZE = 2 # the documentation. An alias has the form: # name=value # For example adding -# "sideeffect=@par Side Effects:\n" +# "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) ALIASES = -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all @@ -264,28 +303,40 @@ OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. +# the files are not read by doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. +# documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. @@ -293,6 +344,26 @@ EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 5. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 5 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN Use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0. and GITHUB Use the lower case version of title +# with any whitespace replaced by '-' and punctations characters removed.. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or @@ -309,7 +380,7 @@ AUTOLINK_SUPPORT = YES # diagrams that involve STL classes more complete and accurate. # The default value is: NO. -BUILTIN_STL_SUPPORT = NO +BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. @@ -318,7 +389,7 @@ BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. @@ -404,6 +475,27 @@ TYPEDEF_HIDES_STRUCT = NO LOOKUP_CACHE_SIZE = 0 +# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use +# during processing. When set to 0 doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -424,6 +516,12 @@ EXTRACT_ALL = YES EXTRACT_PRIVATE = NO +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. @@ -442,7 +540,7 @@ EXTRACT_STATIC = YES # for Java sources. # The default value is: YES. -EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are @@ -461,6 +559,13 @@ EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation @@ -472,17 +577,18 @@ HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. +# declarations. If set to NO, these declarations will be included in the +# documentation. # The default value is: NO. -HIDE_FRIEND_COMPOUNDS = NO +HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these @@ -498,12 +604,20 @@ HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. +# With the correct setting of option CASE_SENSE_NAMES doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and MacOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. CASE_SENSE_NAMES = YES @@ -521,11 +635,17 @@ HIDE_SCOPE_NAMES = NO HIDE_COMPOUND_REFERENCE= NO +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. -SHOW_INCLUDE_FILES = YES +SHOW_INCLUDE_FILES = NO # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader @@ -571,7 +691,7 @@ SORT_BRIEF_DOCS = NO # detailed member documentation. # The default value is: NO. -SORT_MEMBERS_CTORS_1ST = NO +SORT_MEMBERS_CTORS_1ST = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will @@ -661,7 +781,7 @@ SHOW_FILES = YES # Folder Tree View (if specified). # The default value is: YES. -SHOW_NAMESPACES = YES +SHOW_NAMESPACES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from @@ -678,7 +798,8 @@ FILE_VERSION_FILTER = # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE @@ -689,7 +810,7 @@ LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. @@ -724,36 +845,83 @@ WARNINGS = YES WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES +# If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete +# function parameter documentation. If set to NO, doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. +# value. If set to NO, doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about +# undocumented enumeration values. If set to NO, doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the doxygen process doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = FAIL_ON_WARNINGS_PRINT + # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard -# error (stderr). +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). -WARN_LOGFILE = +WARN_LOGFILE = doxygen_warnings.txt #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -765,17 +933,28 @@ WARN_LOGFILE = # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. -INPUT = +INPUT = include # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING # The default value is: UTF-8. INPUT_ENCODING = UTF-8 +# This tag can be used to specify the character encoding of the source files +# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING) if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding +# "INPUT_ENCODING" for further information on supported encodings. + +INPUT_FILE_ENCODING = + # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. @@ -784,13 +963,20 @@ INPUT_ENCODING = UTF-8 # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, -# *.vhdl, *.ucf, *.qsf, *.as and *.js. +# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, +# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C +# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, +# *.vhdl, *.ucf, *.qsf and *.ice. -FILE_PATTERNS = *.cpp, *.cc, *.h *.hpp +FILE_PATTERNS = *.cpp \ + *.cc \ + *.h \ + *.hpp # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -821,22 +1007,25 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = */demos/* -EXCLUDE_PATTERNS += */examples/* -EXCLUDE_PATTERNS += */tests/config/* -EXCLUDE_PATTERNS += */third-party/* +EXCLUDE_PATTERNS = */demos/* \ + */examples/* \ + */tests/config/* \ + */third-party/* \ + */in_progress/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* +# ANamespace::AClass, ANamespace::*Test + +EXCLUDE_SYMBOLS = EMP_* \ + EM_* \ + internal \ + detail \ + decltypedetail \ + __* -EXCLUDE_SYMBOLS = EMP_* -EXCLUDE_SYMBOLS += EM_* # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include @@ -878,8 +1067,17 @@ IMAGE_PATH = # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. +# +# Note that doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. -INPUT_FILTER = +INPUT_FILTER = doc/filter_namespace # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the @@ -887,6 +1085,10 @@ INPUT_FILTER = # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by doxygen. FILTER_PATTERNS = @@ -912,6 +1114,15 @@ FILTER_SOURCE_PATTERNS = USE_MDFILE_AS_MAINPAGE = +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- @@ -939,7 +1150,7 @@ INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. +# entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO @@ -971,12 +1182,12 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version +# (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # @@ -996,7 +1207,7 @@ USE_HTAGS = NO # See also: Section \class. # The default value is: YES. -VERBATIM_HEADERS = YES +VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index @@ -1009,17 +1220,11 @@ VERBATIM_HEADERS = YES ALPHABETICAL_INDEX = YES -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 4 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = @@ -1098,7 +1303,12 @@ HTML_STYLESHEET = # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @@ -1113,10 +1323,23 @@ HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generate light mode output, DARK always +# generate dark mode output, AUTO_LIGHT automatically set the mode according to +# the user preference, use light mode if no preference is set (the default), +# AUTO_DARK automatically set the mode according to the user preference, use +# dark mode if no preference is set and TOGGLE allow to user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. @@ -1125,7 +1348,7 @@ HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A +# in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1143,14 +1366,16 @@ HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = NO +HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1175,13 +1400,14 @@ HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. @@ -1195,6 +1421,13 @@ GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. @@ -1220,8 +1453,12 @@ DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline the HTML help workshop was already many years +# in maintenance mode). You can download the HTML help workshop from the web +# archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML @@ -1251,7 +1488,7 @@ CHM_FILE = HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). +# (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. @@ -1278,6 +1515,16 @@ BINARY_TOC = NO TOC_EXPAND = NO +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help @@ -1296,7 +1543,8 @@ QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1304,8 +1552,8 @@ QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. @@ -1313,30 +1561,30 @@ QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to +# run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = @@ -1379,16 +1627,28 @@ DISABLE_INDEX = NO # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NO +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # @@ -1413,6 +1673,24 @@ TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO +# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML @@ -1422,19 +1700,14 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. -FORMULA_TRANSPARENT = YES +FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering +# https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path @@ -1444,11 +1717,29 @@ FORMULA_TRANSPARENT = YES USE_MATHJAX = NO +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + # When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1461,22 +1752,29 @@ MATHJAX_FORMAT = HTML-CSS # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. @@ -1504,7 +1802,7 @@ MATHJAX_CODEFILE = SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a web server instead of a web client using Javascript. There +# implemented using a web server instead of a web client using JavaScript. There # are two flavors of web server based searching depending on the EXTERNAL_SEARCH # setting. When disabled, doxygen will generate a PHP script for searching and # an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing @@ -1523,7 +1821,8 @@ SERVER_BASED_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). +# Xapian (see: +# https://xapian.org/). # # See the section "External Indexing and Searching" for details. # The default value is: NO. @@ -1536,8 +1835,9 @@ EXTERNAL_SEARCH = NO # # Doxygen ships with an example indexer (doxyindexer) and search engine # (doxysearch.cgi) which are based on the open source search engine library -# Xapian (see: http://xapian.org/). See the section "External Indexing and -# Searching" for details. +# Xapian (see: +# https://xapian.org/). See the section "External Indexing and Searching" for +# details. # This tag requires that the tag SEARCHENGINE is set to YES. SEARCHENGINE_URL = @@ -1575,7 +1875,7 @@ EXTRA_SEARCH_MAPPINGS = # If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. # The default value is: YES. -GENERATE_LATEX = YES +GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of @@ -1588,21 +1888,35 @@ LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. # -# Note that when enabling USE_PDFLATEX this option is only used for generating -# bitmaps for formulas in the HTML output, but not in the Makefile that is -# written to the output directory. -# The default file is: latex. +# Note that when not enabling USE_PDFLATEX the default is latex when enabling +# USE_PDFLATEX the default is pdflatex and when in the later case latex is +# chosen this is overwritten by pdflatex. For specific output languages the +# default can have been set differently, this depends on the implementation of +# the output language. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate # index for LaTeX. +# Note: This tag is used in the Makefile / make.bat. +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file +# (.tex). # The default file is: makeindex. # This tag requires that the tag GENERATE_LATEX is set to YES. MAKEINDEX_CMD_NAME = makeindex +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to +# generate index for LaTeX. In case there is no backslash (\) as first character +# it will be automatically added in the LaTeX code. +# Note: This tag is used in the generated output file (.tex). +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. +# The default value is: makeindex. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_MAKEINDEX_CMD = makeindex + # If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX # documents. This may be useful for small projects and may help to save some # trees in general. @@ -1632,29 +1946,31 @@ PAPER_TYPE = a4 EXTRA_PACKAGES = -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the -# generated LaTeX document. The header should contain everything until the first -# chapter. If it is left blank doxygen will generate a standard header. See -# section "Doxygen usage" for information on how to let doxygen write the -# default header to a separate file. +# The LATEX_HEADER tag can be used to specify a user-defined LaTeX header for +# the generated LaTeX document. The header should contain everything until the +# first chapter. If it is left blank doxygen will generate a standard header. It +# is highly recommended to start with a default header using +# doxygen -w latex new_header.tex new_footer.tex new_stylesheet.sty +# and then modify the file new_header.tex. See also section "Doxygen usage" for +# information on how to generate the default header that doxygen normally uses. # -# Note: Only use a user-defined header if you know what you are doing! The -# following commands have a special meaning inside the header: $title, -# $datetime, $date, $doxygenversion, $projectname, $projectnumber, -# $projectbrief, $projectlogo. Doxygen will replace $title with the empty -# string, for the replacement values of the other commands the user is referred -# to HTML_HEADER. +# Note: Only use a user-defined header if you know what you are doing! +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. The following +# commands have a special meaning inside the header (and footer): For a +# description of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_HEADER = -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the -# generated LaTeX document. The footer should contain everything after the last -# chapter. If it is left blank doxygen will generate a standard footer. See +# The LATEX_FOOTER tag can be used to specify a user-defined LaTeX footer for +# the generated LaTeX document. The footer should contain everything after the +# last chapter. If it is left blank doxygen will generate a standard footer. See # LATEX_HEADER for more information on how to generate a default footer and what -# special commands can be used inside the footer. -# -# Note: Only use a user-defined footer if you know what you are doing! +# special commands can be used inside the footer. See also section "Doxygen +# usage" for information on how to generate the default footer that doxygen +# normally uses. Note: Only use a user-defined footer if you know what you are +# doing! # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_FOOTER = @@ -1687,18 +2003,26 @@ LATEX_EXTRA_FILES = PDF_HYPERLINKS = YES -# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate -# the PDF file directly from the LaTeX files. Set this option to YES, to get a -# higher quality PDF documentation. +# If the USE_PDFLATEX tag is set to YES, doxygen will use the engine as +# specified with LATEX_CMD_NAME to generate the PDF file directly from the LaTeX +# files. Set this option to YES, to get a higher quality PDF documentation. +# +# See also section LATEX_CMD_NAME for selecting the engine. # The default value is: YES. # This tag requires that the tag GENERATE_LATEX is set to YES. USE_PDFLATEX = YES -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode -# command to the generated LaTeX files. This will instruct LaTeX to keep running -# if errors occur, instead of asking the user for help. This option is also used -# when generating formulas in HTML. +# The LATEX_BATCHMODE tag ignals the behavior of LaTeX in case of an error. +# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch +# mode nothing is printed on the terminal, errors are scrolled as if is +# hit at every error; missing files that TeX tries to input or request from +# keyboard input (\read on a not open input stream) cause the job to abort, +# NON_STOP In nonstop mode the diagnostic message will appear on the terminal, +# but there is no possibility of user interaction just like in batch mode, +# SCROLL In scroll mode, TeX will stop only for missing files to input or if +# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at +# each error, asking for user intervention. # The default value is: NO. # This tag requires that the tag GENERATE_LATEX is set to YES. @@ -1711,24 +2035,22 @@ LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO -# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source -# code with syntax highlighting in the LaTeX output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_LATEX is set to YES. - -LATEX_SOURCE_CODE = NO - # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. LATEX_BIB_STYLE = plain +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) +# path from which the emoji images will be read. If a relative path is entered, +# it will be relative to the LATEX_OUTPUT directory. If left blank the +# LATEX_OUTPUT directory will be used. +# This tag requires that the tag GENERATE_LATEX is set to YES. + +LATEX_EMOJI_DIRECTORY = + #--------------------------------------------------------------------------- # Configuration options related to the RTF output #--------------------------------------------------------------------------- @@ -1768,9 +2090,9 @@ COMPACT_RTF = NO RTF_HYPERLINKS = NO -# Load stylesheet definitions from file. Syntax is similar to doxygen's config -# file, i.e. a series of assignments. You only have to provide replacements, -# missing definitions are set to their default value. +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# configuration file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. # # See also section "Doxygen usage" for information on how to generate the # default style sheet that doxygen normally uses. @@ -1779,22 +2101,12 @@ RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an RTF document. Syntax is -# similar to doxygen's config file. A template extensions file can be generated -# using doxygen -e rtf extensionFile. +# similar to doxygen's configuration file. A template extensions file can be +# generated using doxygen -e rtf extensionFile. # This tag requires that the tag GENERATE_RTF is set to YES. RTF_EXTENSIONS_FILE = -# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code -# with syntax highlighting in the RTF output. -# -# Note that which sources are shown also depends on other settings such as -# SOURCE_BROWSER. -# The default value is: NO. -# This tag requires that the tag GENERATE_RTF is set to YES. - -RTF_SOURCE_CODE = NO - #--------------------------------------------------------------------------- # Configuration options related to the man page output #--------------------------------------------------------------------------- @@ -1866,6 +2178,13 @@ XML_OUTPUT = xml XML_PROGRAMLISTING = YES +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include +# namespace members in file scope as well, matching the HTML output. +# The default value is: NO. +# This tag requires that the tag GENERATE_XML is set to YES. + +XML_NS_MEMB_FILE_SCOPE = NO + #--------------------------------------------------------------------------- # Configuration options related to the DOCBOOK output #--------------------------------------------------------------------------- @@ -1884,23 +2203,14 @@ GENERATE_DOCBOOK = NO DOCBOOK_OUTPUT = docbook -# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the -# program listings (including syntax highlighting and cross-referencing -# information) to the DOCBOOK output. Note that enabling this will significantly -# increase the size of the DOCBOOK output. -# The default value is: NO. -# This tag requires that the tag GENERATE_DOCBOOK is set to YES. - -DOCBOOK_PROGRAMLISTING = NO - #--------------------------------------------------------------------------- # Configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an -# AutoGen Definitions (see http://autogen.sf.net) file that captures the -# structure of the code including all documentation. Note that this feature is -# still experimental and incomplete at the moment. +# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures +# the structure of the code including all documentation. Note that this feature +# is still experimental and incomplete at the moment. # The default value is: NO. GENERATE_AUTOGEN_DEF = NO @@ -1960,7 +2270,7 @@ ENABLE_PREPROCESSING = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -1979,7 +2289,8 @@ SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the -# preprocessor. +# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of +# RECURSIVE has no effect here. # This tag requires that the tag SEARCH_INCLUDES is set to YES. INCLUDE_PATH = @@ -2000,7 +2311,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = DOXYGEN_RUNNING +PREDEFINED = DOXYGEN_SHOULD_SKIP_THIS # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The @@ -2067,41 +2378,10 @@ EXTERNAL_GROUPS = YES EXTERNAL_PAGES = YES -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of 'which perl'). -# The default file (with absolute path) is: /usr/bin/perl. - -PERL_PATH = /usr/bin/perl - #--------------------------------------------------------------------------- -# Configuration options related to the dot tool +# Configuration options related to diagram generator tools #--------------------------------------------------------------------------- -# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram -# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to -# NO turns the diagrams off. Note that this option also works with HAVE_DOT -# disabled, but it is recommended to install and use dot, since it yields more -# powerful graphs. -# The default value is: YES. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see: -# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# You can include diagrams made with dia in doxygen documentation. Doxygen will -# then run dia to produce the diagram and insert it in the documentation. The -# DIA_PATH tag allows you to specify the directory where the dia binary resides. -# If left empty dia is assumed to be found in the default search path. - -DIA_PATH = - # If set to YES the inheritance and collaboration graphs will hide inheritance # and usage relations if the target is undocumented or is not a class. # The default value is: YES. @@ -2110,7 +2390,7 @@ HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz (see: -# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent +# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent # Bell Labs. The other options in this section have no effect if this option is # set to NO # The default value is: NO. @@ -2127,35 +2407,52 @@ HAVE_DOT = NO DOT_NUM_THREADS = 0 -# When you want a differently looking font in the dot files that doxygen -# generates you can specify the font name using DOT_FONTNAME. You need to make -# sure dot is able to find the font, which can be done by putting it in a -# standard location or by setting the DOTFONTPATH environment variable or by -# setting DOT_FONTPATH to the directory containing the font. -# The default value is: Helvetica. +# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of +# subgraphs. When you want a differently looking font in the dot files that +# doxygen generates you can specify fontname, fontcolor and fontsize attributes. +# For details please see Node, +# Edge and Graph Attributes specification You need to make sure dot is able +# to find the font, which can be done by putting it in a standard location or by +# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. Default graphviz fontsize is 14. +# The default value is: fontname=Helvetica,fontsize=10. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10" + +# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can +# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. Complete documentation about +# arrows shapes. +# The default value is: labelfontname=Helvetica,labelfontsize=10. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTNAME = Helvetica +DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10" -# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of -# dot graphs. -# Minimum value: 4, maximum value: 24, default value: 10. +# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes +# around nodes set 'shape=plain' or 'shape=plaintext' Shapes specification +# The default value is: shape=box,height=0.2,width=0.4. # This tag requires that the tag HAVE_DOT is set to YES. -DOT_FONTSIZE = 10 +DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4" -# By default doxygen will tell dot to use the default font as specified with -# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set -# the path where dot can find it using this tag. +# You can set the path where dot can find font specified with fontname in +# DOT_COMMON_ATTR and others dot attributes. # This tag requires that the tag HAVE_DOT is set to YES. DOT_FONTPATH = -# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for -# each documented class showing the direct and indirect inheritance relations. -# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. +# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will +# generate a graph for each documented class showing the direct and indirect +# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and +# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case +# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the +# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used. +# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance +# relations will be shown as texts / links. +# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. CLASS_GRAPH = YES @@ -2169,7 +2466,8 @@ CLASS_GRAPH = YES COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for -# groups, showing the direct groups dependencies. +# groups, showing the direct groups dependencies. See also the chapter Grouping +# in the manual. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. @@ -2192,10 +2490,32 @@ UML_LOOK = NO # but if the number exceeds 15, the total amount of fields shown is limited to # 10. # Minimum value: 0, maximum value: 100, default value: 10. -# This tag requires that the tag HAVE_DOT is set to YES. +# This tag requires that the tag UML_LOOK is set to YES. UML_LIMIT_NUM_FIELDS = 10 +# If the DOT_UML_DETAILS tag is set to NO, doxygen will show attributes and +# methods without types and arguments in the UML graphs. If the DOT_UML_DETAILS +# tag is set to YES, doxygen will add type and arguments for attributes and +# methods in the UML graphs. If the DOT_UML_DETAILS tag is set to NONE, doxygen +# will not generate fields with class member information in the UML graphs. The +# class diagrams will look similar to the default class diagrams but using UML +# notation for the relationships. +# Possible values are: NO, YES and NONE. +# The default value is: NO. +# This tag requires that the tag UML_LOOK is set to YES. + +DOT_UML_DETAILS = NO + +# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters +# to display on a single line. If the actual line length exceeds this threshold +# significantly it will wrapped across multiple lines. Some heuristics are apply +# to avoid ugly line breaks. +# Minimum value: 0, maximum value: 1000, default value: 17. +# This tag requires that the tag HAVE_DOT is set to YES. + +DOT_WRAP_THRESHOLD = 17 + # If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and # collaboration graphs will show the relations between templates and their # instances. @@ -2220,7 +2540,7 @@ INCLUDE_GRAPH = YES # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -INCLUDED_BY_GRAPH = YES +INCLUDED_BY_GRAPH = NO # If the CALL_GRAPH tag is set to YES then doxygen will generate a call # dependency graph for every global function or class method. @@ -2262,10 +2582,17 @@ GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES +# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels +# of child directories generated in directory dependency graphs by dot. +# Minimum value: 1, maximum value: 25, default value: 1. +# This tag requires that the tag DIRECTORY_GRAPH is set to YES. + +DIR_GRAPH_MAX_DEPTH = 1 + # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. For an explanation of the image formats see the section # output formats in the documentation of the dot tool (Graphviz (see: -# http://www.graphviz.org/)). +# https://www.graphviz.org/)). # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order # to make the SVG files visible in IE 9+ (other browsers do not have this # requirement). @@ -2302,11 +2629,12 @@ DOT_PATH = DOTFILE_DIRS = -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the \mscfile -# command). +# You can include diagrams made with dia in doxygen documentation. Doxygen will +# then run dia to produce the diagram and insert it in the documentation. The +# DIA_PATH tag allows you to specify the directory where the dia binary resides. +# If left empty dia is assumed to be found in the default search path. -MSCFILE_DIRS = +DIA_PATH = # The DIAFILE_DIRS tag can be used to specify one or more directories that # contain dia files that are included in the documentation (see the \diafile @@ -2315,13 +2643,18 @@ MSCFILE_DIRS = DIAFILE_DIRS = # When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the -# path where java can find the plantuml.jar file. If left blank, it is assumed -# PlantUML is not used or called during a preprocessing step. Doxygen will -# generate a warning when it encounters a \startuml command in this case and -# will not generate output for the diagram. +# path where java can find the plantuml.jar file or to the filename of jar file +# to be used. If left blank, it is assumed PlantUML is not used or called during +# a preprocessing step. Doxygen will generate a warning when it encounters a +# \startuml command in this case and will not generate output for the diagram. PLANTUML_JAR_PATH = +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a +# configuration file for plantuml. + +PLANTUML_CFG_FILE = + # When using plantuml, the specified paths are searched for files specified by # the !include statement in a plantuml block. @@ -2351,18 +2684,6 @@ DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not seem -# to support this out of the box. -# -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). -# The default value is: NO. -# This tag requires that the tag HAVE_DOT is set to YES. - -DOT_TRANSPARENT = NO - # Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) support @@ -2375,14 +2696,34 @@ DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page # explaining the meaning of the various boxes and arrows in the dot generated # graphs. +# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal +# graphical representation for inheritance and collaboration diagrams is used. # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. GENERATE_LEGEND = YES -# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate # files that are used to generate the various graphs. +# +# Note: This setting is not only used for dot files but also for msc temporary +# files. # The default value is: YES. -# This tag requires that the tag HAVE_DOT is set to YES. DOT_CLEANUP = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will +# use a built-in version of mscgen tool to produce the charts. Alternatively, +# the MSCGEN_TOOL tag can also specify the name an external tool. For instance, +# specifying prog as the value, doxygen will call the tool as prog -T +# -o . The external tool should support +# output file formats "png", "eps", "svg", and "ismap". + +MSCGEN_TOOL = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the \mscfile +# command). + +MSCFILE_DIRS = diff --git a/LICENSE.md b/LICENSE.md index 1e0fc700e9..4ad7f8c871 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -10,9 +10,13 @@ Contributors: Charles Ofria, Alex Lalejini, Robin Miller, Matthew Moreno, + Austin Ferguson, + Jose Guadalupe Hernandez, Katherine Perry, Santiago Rodriguez-Papa, Oliver Baldwin Edwards, + Sarah Boyd, + Tait Weicht, Jason Stredwick, Raheem Clemons, Anya Vostinar, diff --git a/Makefile b/Makefile index 80b57a41ae..c2c8a002f4 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,8 @@ test-cookiecutter: ../cookiecutter-empirical-project cd ../cookiecutter-empirical-project && make clean && make test doc: + doxygen + cd doc && python make_md.py cd doc && make html coverage coverage: diff --git a/Planning/NEXT_PASS b/Planning/NEXT_PASS new file mode 100644 index 0000000000..3568548ccb --- /dev/null +++ b/Planning/NEXT_PASS @@ -0,0 +1,13 @@ +Next time we do a full pass through files, we should: + +* Use notify for proper error tracking. Bias toward exceptions so developers can choose individualized responses to errors. +* Change member functions (and variables?) to begin with _ +* Cleanup Doxygen? +* Move std::string to emp::String, where possible. +* Cleanup any SFINEA or other template tricks and use constexpr instead. + + +And if implemented +* Simplify emp_asserts to assume that will disentangle tests and print values of components? +* Add in the ability to turn on "EMP_THREADED" options? +* Add in serialization capabilities? diff --git a/ci/impl/generate_boilerplate_file_docstrings.sh b/ci/impl/generate_boilerplate_file_docstrings.sh index a8fe3e8209..38f7d545b6 100755 --- a/ci/impl/generate_boilerplate_file_docstrings.sh +++ b/ci/impl/generate_boilerplate_file_docstrings.sh @@ -13,23 +13,25 @@ for filename in $(cd include && find -- * -name '*.hpp' -type f); do done # stamp in expected boilerplate line-by-line - sed -i '1s|^.*$|/**|' "include/${filename}" - sed -i '2s|^.*$| * @note This file is part of Empirical, https://github.com/devosoft/Empirical|' "include/${filename}" - sed -i '3s|^.*$| * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md|' "include/${filename}" - # only match if a @date isn't currently in place - # if we see @date, "break" (b) sed script for that line + sed -i '1s|^.*$|/*|' "include/${filename}" + sed -i '2s|^.*$| * This file is part of Empirical, https://github.com/devosoft/Empirical|' "include/${filename}" + sed -i '3s|^.*$| * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md|' "include/${filename}" + # only match if a date: isn't currently in place + # if we see date:, "break" (b) sed script for that line # adapted from https://stackoverflow.com/a/5334825 # and https://stackoverflow.com/a/12178023 # and https://stackoverflow.com/a/9053163 - sed -i "/^ \* @date /b; 4s/^.*\$/ * @date $(date +'%Y')/" "include/${filename}" - sed -i '5s/^.*$/ */' "include/${filename}" - sed -i "6s/^.*\$/ * @file $(basename "${filename}")/" "include/${filename}" + sed -i "/^ \* date: /b; 4s/^.*\$/ * date: $(date +'%Y')/" "include/${filename}" + # sed -i '5s/^.*$/ */' "include/${filename}" + sed -i '5s|^.*$|*/|' "include/${filename}" # only match if a @brief isn't currently in place # adapted from https://stackoverflow.com/a/5334825 - sed -i "/^ \* @brief /b; 7s/^.*\$/ * @brief TODO./" "include/${filename}" + sed -i '6s|^.*$|/**|' "include/${filename}" + sed -i '7s|^.*$| * @file|' "include/${filename}" + sed -i "/^ \* @brief /b; 8s/^.*\$/ * @brief TODO./" "include/${filename}" # only match empty lines # add extra * to replace later with */ when constructing fresh - sed -i '8s/^$/ */' "include/${filename}" + sed -i '9s/^$/ */' "include/${filename}" # close boilerplate file docstring # must accomodate possible additional content in docstring diff --git a/ci/impl/generate_license_notices.sh b/ci/impl/generate_license_notices.sh index 01f78eb84b..2264eca653 100755 --- a/ci/impl/generate_license_notices.sh +++ b/ci/impl/generate_license_notices.sh @@ -17,20 +17,23 @@ for filename in $(find . -name '*.cpp' -type f ! -path "./third-party/*") $(find # stamp in expected boilerplate line-by-line # just like file docstrings, but don't require a brief # stamp in expected boilerplate line-by-line - sed -i '1s|^.*$|/**|' "${filename}" - sed -i '2s|^.*$| * @note This file is part of Empirical, https://github.com/devosoft/Empirical|' "${filename}" - sed -i '3s|^.*$| * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md|' "${filename}" + sed -i '1s|^.*$|/*|' "${filename}" + sed -i '2s|^.*$| * This file is part of Empirical, https://github.com/devosoft/Empirical|' "${filename}" + sed -i '3s|^.*$| * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md|' "${filename}" # only match if a @date isn't currently in place # if we see @date, "break" (b) sed script for that line # adapted from https://stackoverflow.com/a/5334825 # and https://stackoverflow.com/a/12178023 # and https://stackoverflow.com/a/9053163 - sed -i "/^ \* @date /b; 4s/^.*\$/ * @date $(date +'%Y')/" "${filename}" - sed -i '5s/^.*$/ */' "${filename}" - sed -i "6s/^.*\$/ * @file $(basename "${filename}")/" "${filename}" + sed -i "/^ \* date: /b; 4s/^.*\$/ * date: $(date +'%Y')/" "${filename}" + sed -i '5s|^.*$|*/|' "${filename}" + # sed -i "6s/^.*\$/ * @file $(basename "${filename}")/" "${filename}" # only match empty lines # add extra * to replace later with */ when constructing fresh - sed -i '7s/^$/ */' "${filename}" + # sed -i '6s/^$/ */' "${filename}" + sed -i '6s|^.*$|/**|' "${filename}" + sed -i '7s|^.*$| * @file|' "${filename}" + sed -i "/^ \* @brief /b; 8s/^.*\$/ * @brief TODO./" "${filename}" # close boilerplate file docstring # must accomodate possible additional content in docstring diff --git a/ci/test_tidy.sh b/ci/test_tidy.sh index 71a54089c6..4dae09a885 100755 --- a/ci/test_tidy.sh +++ b/ci/test_tidy.sh @@ -8,6 +8,7 @@ set -e echo "Running tidyness enforcement tests..." echo "See https://empirical.readthedocs.io/en/latest/dev/guide-to-testing.html#tidyness-enforcement for info on tidyness enforcement." echo "(Including how to automatically generate tidyness fixes if tidyness enforcement detects tidyness issues.)" +git status --ignored ./ci/test_alphabetize_includes.sh && echo "✔ include alphabetization ok" || exit 1 ./ci/test_alphabetize_imports.sh && echo "✔ import alphabetization ok" || exit 1 diff --git a/ci/util/enforce_git_status.sh b/ci/util/enforce_git_status.sh index 488f8f7074..ea226f2084 100755 --- a/ci/util/enforce_git_status.sh +++ b/ci/util/enforce_git_status.sh @@ -8,9 +8,12 @@ if [[ "$(basename -- "$0")" == "enforce_git_status.sh" ]]; then exit 1 fi +if [ "$CI" != "true" ]; then # bypass check in CI +# because macos CI mysteriously is having dirty clones + # refuse to continue if uncommitted changes are present # adapted from https://stackoverflow.com/a/40535565 -if ! [[ -z $(git status -s) ]]; +if [ -n "$(git status --porcelain)" ]; then ./ci/util/print_uncommitted_changes_warning.sh exit 1 @@ -24,3 +27,8 @@ then ./ci/util/print_gitignored_files_warning.sh exit 1 fi + +# end CI bypass +else +echo "CI detected, bypassing git status check..." +fi # if [ "$CI" != "true" ]; then diff --git a/ci/util/print_gitignored_files_warning.sh b/ci/util/print_gitignored_files_warning.sh index 60bff93e12..b1f027a73d 100755 --- a/ci/util/print_gitignored_files_warning.sh +++ b/ci/util/print_gitignored_files_warning.sh @@ -1,6 +1,9 @@ #!/bin/bash set -e +git status --ignored +git diff + # adapted from https://stackoverflow.com/a/835561 # and https://stackoverflow.com/a/4327720 # and https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning diff --git a/ci/util/print_uncommitted_changes_warning.sh b/ci/util/print_uncommitted_changes_warning.sh index 5d5a7be3aa..52a952a7a9 100755 --- a/ci/util/print_uncommitted_changes_warning.sh +++ b/ci/util/print_uncommitted_changes_warning.sh @@ -1,6 +1,9 @@ #!/bin/bash set -e +git status --ignored +git diff + # adapted from https://stackoverflow.com/a/835561 # and https://stackoverflow.com/a/4327720 echo "=========================================================================" diff --git a/demos/EasyChair/ProcessReviews.cpp b/demos/EasyChair/ProcessReviews.cpp index 4014d101bb..47aad2e74b 100644 --- a/demos/EasyChair/ProcessReviews.cpp +++ b/demos/EasyChair/ProcessReviews.cpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ProcessReviews.cpp + * @file + * @brief TODO. */ #include diff --git a/demos/MAP-Elites-Arm/source/ArmWorld.hpp b/demos/MAP-Elites-Arm/source/ArmWorld.hpp index 8f3ef64003..54696c340a 100644 --- a/demos/MAP-Elites-Arm/source/ArmWorld.hpp +++ b/demos/MAP-Elites-Arm/source/ArmWorld.hpp @@ -1,10 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file ArmWorld.hpp - * @brief Defines the specialized world for the MAP-Elites app. + * @file */ #ifndef DEMOS_MAP_ELITES_ARM_SOURCE_ARMWORLD_HPP_INCLUDE diff --git a/demos/MAP-Elites-Arm/source/native/MAP-Elites-Arm.cpp b/demos/MAP-Elites-Arm/source/native/MAP-Elites-Arm.cpp index f70a8719bc..574f0652d3 100644 --- a/demos/MAP-Elites-Arm/source/native/MAP-Elites-Arm.cpp +++ b/demos/MAP-Elites-Arm/source/native/MAP-Elites-Arm.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file MAP-Elites-Arm.cpp + * @file * @brief Controller for NATIVE (Command Line) version of MAP-Elites app. */ diff --git a/demos/MAP-Elites-Arm/source/web/MAP-Elites-Arm-web.cpp b/demos/MAP-Elites-Arm/source/web/MAP-Elites-Arm-web.cpp index 54f1bc70c1..a8fc28f6eb 100644 --- a/demos/MAP-Elites-Arm/source/web/MAP-Elites-Arm-web.cpp +++ b/demos/MAP-Elites-Arm/source/web/MAP-Elites-Arm-web.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file MAP-Elites-Arm-web.cpp + * @file * @brief Controller for WEB version of MAP-Elites app. */ diff --git a/demos/NK/source/NKWorld.hpp b/demos/NK/source/NKWorld.hpp index c7d0c9fe7b..eb3802ced9 100644 --- a/demos/NK/source/NKWorld.hpp +++ b/demos/NK/source/NKWorld.hpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file NKWorld.hpp + * @file + * @brief TODO. * */ diff --git a/demos/NK/source/native/NK.cpp b/demos/NK/source/native/NK.cpp index e5a5506041..3229130a09 100644 --- a/demos/NK/source/native/NK.cpp +++ b/demos/NK/source/native/NK.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file NK.cpp + * @file * @brief This file explores the template defined in evo::Population.h with an NK landscape. */ diff --git a/demos/NK/source/web/NK-web.cpp b/demos/NK/source/web/NK-web.cpp index 561138faf4..85aee7373a 100644 --- a/demos/NK/source/web/NK-web.cpp +++ b/demos/NK/source/web/NK-web.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file NK-web.cpp + * @file * @brief This file contains an easy-to-manipulate NK world. */ diff --git a/demos/SelectionAnalyze/Analyze.cpp b/demos/SelectionAnalyze/Analyze.cpp index 64bd52b4c4..6423b88c79 100644 --- a/demos/SelectionAnalyze/Analyze.cpp +++ b/demos/SelectionAnalyze/Analyze.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file Analyze.cpp + * @file * @brief Analyze probabilities for selection using various selection techniques. */ diff --git a/demos/SelectionAnalyze/Lexicase.cpp b/demos/SelectionAnalyze/Lexicase.cpp index 8375fcf720..ab3c62f603 100644 --- a/demos/SelectionAnalyze/Lexicase.cpp +++ b/demos/SelectionAnalyze/Lexicase.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file Lexicase.cpp + * @file * @brief Calculate probabilities for selection using Lexicase Selection. */ diff --git a/demos/SelectionAnalyze/Roulette.cpp b/demos/SelectionAnalyze/Roulette.cpp index e859df6de9..977f88a7a0 100644 --- a/demos/SelectionAnalyze/Roulette.cpp +++ b/demos/SelectionAnalyze/Roulette.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Roulette.cpp + * @file * @brief Calculate probabilities for selection using Roulette Selection (easy!) */ diff --git a/demos/SelectionAnalyze/SelectionData.hpp b/demos/SelectionAnalyze/SelectionData.hpp index 226ccb33bf..120f0b213d 100644 --- a/demos/SelectionAnalyze/SelectionData.hpp +++ b/demos/SelectionAnalyze/SelectionData.hpp @@ -1,10 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file SelectionData.hpp - * @brief This class maintains all of the fitness data for a population of organisms. + * @file */ #ifndef DEMOS_SELECTIONANALYZE_SELECTIONDATA_HPP_INCLUDE diff --git a/demos/SelectionAnalyze/test_gen.cpp b/demos/SelectionAnalyze/test_gen.cpp index 23242bf576..f78c2a92cd 100644 --- a/demos/SelectionAnalyze/test_gen.cpp +++ b/demos/SelectionAnalyze/test_gen.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file test_gen.cpp + * @file */ #include "emp/config/command_line.hpp" diff --git a/demos/Slideshow.hpp b/demos/Slideshow.hpp index 869cdc945d..0ab0f3a8b5 100644 --- a/demos/Slideshow.hpp +++ b/demos/Slideshow.hpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Slideshow.hpp + * @file + * @brief TODO. * */ diff --git a/demos/SpatialCoop2017/source/SimplePDWorld.hpp b/demos/SpatialCoop2017/source/SimplePDWorld.hpp index c4c35b7eae..4f35de005d 100644 --- a/demos/SpatialCoop2017/source/SimplePDWorld.hpp +++ b/demos/SpatialCoop2017/source/SimplePDWorld.hpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file SimplePDWorld.hpp + * @file + * @brief TODO. */ #ifndef DEMOS_SPATIALCOOP2017_SOURCE_SIMPLEPDWORLD_HPP_INCLUDE diff --git a/demos/SpatialCoop2017/source/native/SimplePDWorld.cpp b/demos/SpatialCoop2017/source/native/SimplePDWorld.cpp index 7edabbae31..075a19b8b0 100644 --- a/demos/SpatialCoop2017/source/native/SimplePDWorld.cpp +++ b/demos/SpatialCoop2017/source/native/SimplePDWorld.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SimplePDWorld.cpp + * @file */ #include diff --git a/demos/SpatialCoop2017/source/web/SimplePDWorld-web.cpp b/demos/SpatialCoop2017/source/web/SimplePDWorld-web.cpp index 4220676634..b538ba1f58 100644 --- a/demos/SpatialCoop2017/source/web/SimplePDWorld-web.cpp +++ b/demos/SpatialCoop2017/source/web/SimplePDWorld-web.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file SimplePDWorld-web.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/demos/Sudoku/Sudoku.cpp b/demos/Sudoku/Sudoku.cpp index 4584c45c4f..3f2bc2eae5 100644 --- a/demos/Sudoku/Sudoku.cpp +++ b/demos/Sudoku/Sudoku.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Sudoku.cpp + * @file */ #include "emp/base/array.hpp" diff --git a/demos/utils/data/Histogram.cpp b/demos/utils/data/Histogram.cpp index ebced27c1d..1528f65952 100644 --- a/demos/utils/data/Histogram.cpp +++ b/demos/utils/data/Histogram.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Histogram.cpp + * @file */ #include "../../../include/emp/base/vector.hpp" diff --git a/demos/utils/data/reorder_cols.cpp b/demos/utils/data/reorder_cols.cpp index 812616da70..b53272d3a3 100644 --- a/demos/utils/data/reorder_cols.cpp +++ b/demos/utils/data/reorder_cols.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file reorder_cols.cpp + * @file * @brief This utility loads in a space-separated file and reorders the columns. * * Identify a file and a set of columns (starting with column 1). Load the diff --git a/demos/utils/data/summarize.cpp b/demos/utils/data/summarize.cpp index e2702612bf..f12a7a45d2 100644 --- a/demos/utils/data/summarize.cpp +++ b/demos/utils/data/summarize.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020 - * - * @file summarize.cpp + * @file * @brief This file takes in one or more CSV files with values and, for each, calculates the mnimium, * maximum, and average values found in each column. */ diff --git a/demos/utils/edit_dist/edit_dist.cpp b/demos/utils/edit_dist/edit_dist.cpp index c6501a80d8..4542fbbd4a 100644 --- a/demos/utils/edit_dist/edit_dist.cpp +++ b/demos/utils/edit_dist/edit_dist.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file edit_dist.cpp + * @file * @brief Load input from standard in that begins with a value "N" and then contains N pairs of strings. * * Output will be the edit distances between each string pair. diff --git a/demos/utils/edit_dist/string_gen.cpp b/demos/utils/edit_dist/string_gen.cpp index 3a73247be0..e44a1dbff9 100644 --- a/demos/utils/edit_dist/string_gen.cpp +++ b/demos/utils/edit_dist/string_gen.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file string_gen.cpp + * @file * @brief Generate a series of string pairs with a prescribed number of changes between them. */ diff --git a/demos/utils/extras/calc_log.cpp b/demos/utils/extras/calc_log.cpp index e9239bccc8..7398038256 100644 --- a/demos/utils/extras/calc_log.cpp +++ b/demos/utils/extras/calc_log.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file calc_log.cpp + * @file */ #include diff --git a/demos/utils/extras/calc_pow.cpp b/demos/utils/extras/calc_pow.cpp index 45fd5029df..29601a6a4b 100644 --- a/demos/utils/extras/calc_pow.cpp +++ b/demos/utils/extras/calc_pow.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file calc_pow.cpp + * @file */ #include diff --git a/demos/utils/graphs/make_graph.cpp b/demos/utils/graphs/make_graph.cpp index 2e0526007a..e1e58ec3dc 100644 --- a/demos/utils/graphs/make_graph.cpp +++ b/demos/utils/graphs/make_graph.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file make_graph.cpp + * @file * @brief Build graphs of various types in the standard format. * * NOTE: All questions can be answered by providing command-line arguments. diff --git a/demos/utils/graphs/vcover.cpp b/demos/utils/graphs/vcover.cpp index 0fc13cc52c..2ee18f5453 100644 --- a/demos/utils/graphs/vcover.cpp +++ b/demos/utils/graphs/vcover.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file vcover.cpp + * @file * @brief Determine the minimum vertex cover for a graph provided on standard input. */ diff --git a/demos/utils/graphs/web/vcover.cpp b/demos/utils/graphs/web/vcover.cpp index 4b63f298e2..90804a2b59 100644 --- a/demos/utils/graphs/web/vcover.cpp +++ b/demos/utils/graphs/web/vcover.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file vcover.cpp + * @file */ #include diff --git a/demos/utils/graphs/web/web_UI.cpp b/demos/utils/graphs/web/web_UI.cpp index 8a7007f0e6..165f50b014 100644 --- a/demos/utils/graphs/web/web_UI.cpp +++ b/demos/utils/graphs/web/web_UI.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file web_UI.cpp + * @file */ #include "web_UI.h" diff --git a/demos/utils/graphs/web/web_UI.hpp b/demos/utils/graphs/web/web_UI.hpp index 4641b134e8..305e90b240 100644 --- a/demos/utils/graphs/web/web_UI.hpp +++ b/demos/utils/graphs/web/web_UI.hpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file web_UI.hpp + * @file + * @brief TODO. * */ diff --git a/demos/utils/levelize/levelize.cpp b/demos/utils/levelize/levelize.cpp index fa8336fff0..5ada17b546 100644 --- a/demos/utils/levelize/levelize.cpp +++ b/demos/utils/levelize/levelize.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file levelize.cpp + * @file */ #include diff --git a/demos/utils/words/Wordle-simple.cpp b/demos/utils/words/Wordle-simple.cpp index be8c470f91..9f9c548cce 100644 --- a/demos/utils/words/Wordle-simple.cpp +++ b/demos/utils/words/Wordle-simple.cpp @@ -1,11 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file Wordle-simple.cpp - * - * This version of Wordle is a bit simpler than it should be; it does not handle double letters + * @file + * @brief version of Wordle is a bit simpler than it should be; it does not handle double letters * correctly. */ diff --git a/demos/utils/words/Wordle/Result.hpp b/demos/utils/words/Wordle/Result.hpp index efce04ed72..4a4f2eacb9 100644 --- a/demos/utils/words/Wordle/Result.hpp +++ b/demos/utils/words/Wordle/Result.hpp @@ -1,10 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file Result.hpp - * + * @file */ #ifndef DEMOS_UTILS_WORDS_WORDLE_RESULT_HPP_INCLUDE diff --git a/demos/utils/words/Wordle/Wordle.cpp b/demos/utils/words/Wordle/Wordle.cpp index 541817c273..9b387718cb 100644 --- a/demos/utils/words/Wordle/Wordle.cpp +++ b/demos/utils/words/Wordle/Wordle.cpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file Wordle.cpp + * @file + * @brief TODO. */ #include diff --git a/demos/utils/words/annotate-length.cpp b/demos/utils/words/annotate-length.cpp index d9630c3744..fa97b34369 100644 --- a/demos/utils/words/annotate-length.cpp +++ b/demos/utils/words/annotate-length.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file annotate-length.cpp + * @file * @brief Annotate all of the words in an input list with their length. */ diff --git a/demos/utils/words/has-letters.cpp b/demos/utils/words/has-letters.cpp index d103a8267b..5e3ea957fd 100644 --- a/demos/utils/words/has-letters.cpp +++ b/demos/utils/words/has-letters.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file has-letters.cpp + * @file * @brief Find all words in a dictionary with a combination of letters IN ORDER, annotated by length. */ diff --git a/demos/utils/words/wordplay-remove.cpp b/demos/utils/words/wordplay-remove.cpp index 84681ac902..d1de8119ae 100644 --- a/demos/utils/words/wordplay-remove.cpp +++ b/demos/utils/words/wordplay-remove.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file wordplay-remove.cpp + * @file * @brief Test the removal of letters through an alphabet to see if new words are formed. */ diff --git a/demos/utils/words/wordplay-rot.cpp b/demos/utils/words/wordplay-rot.cpp index 113f1c14a2..613236f4cb 100644 --- a/demos/utils/words/wordplay-rot.cpp +++ b/demos/utils/words/wordplay-rot.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file wordplay-rot.cpp + * @file * @brief Test the rotation of letters through an alphabet to see if new words are formed. * * Build graphs of various types in the standard format. diff --git a/demos/utils/words/wordplay-shuffle.cpp b/demos/utils/words/wordplay-shuffle.cpp index bbc85aa67b..c435336e1b 100644 --- a/demos/utils/words/wordplay-shuffle.cpp +++ b/demos/utils/words/wordplay-shuffle.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file wordplay-shuffle.cpp + * @file * @brief Find words that are a shuffle of another word. */ diff --git a/doc/Makefile b/doc/Makefile index 7f97453cb9..d81f3c4435 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -2,7 +2,7 @@ # # You can set these variables from the command line. -SPHINXOPTS = +SPHINXOPTS = -W --keep-going SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build @@ -177,10 +177,10 @@ doctest: "results in $(BUILDDIR)/doctest/output.txt." coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - python3 -m coverxygen --xml-dir doxyoutput/xml --src-dir .. --format json-summary --output $(BUILDDIR)/doc-coverage.json + mkdir -p $(BUILDDIR) + python3 -m coverxygen --xml-dir doxy*/xml --src-dir .. --format json-summary --output $(BUILDDIR)/doc-coverage.json @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/doc-coverage.json." + "results in $(BUILDDIR)/doc-coverage.json." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @@ -195,5 +195,5 @@ pseudoxml: .PHONY: help Makefile clean clean: - rm -rf doxyoutput/ api/ + rm -rf doxygen/ api/ @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/doc/QuickStartGuides/todos/todo.md b/doc/QuickStartGuides/todos/todo.md index 528da1f6a1..a197deb93e 100644 --- a/doc/QuickStartGuides/todos/todo.md +++ b/doc/QuickStartGuides/todos/todo.md @@ -1,7 +1,7 @@ # Work In Progress The following pages are a work in progress 🚧. -[Contributions](contribution-guidelines-and-review) are welcome! +[Contributions](../../dev/contribution-guidelines-and-review) are welcome! ```{toctree} X-CreateWorld diff --git a/doc/bibliography.bib b/doc/bibliography.bib new file mode 100644 index 0000000000..8ccc44609a --- /dev/null +++ b/doc/bibliography.bib @@ -0,0 +1,189 @@ + +@article{collessReviewPhylogeneticsTheory1982, + title = {Review of Phylogenetics: The Theory and Practice of Phylogenetic Systematics.}, + volume = {31}, + issn = {0039-7989}, + url = {https://www.jstor.org/stable/2413420}, + doi = {10.2307/2413420}, + shorttitle = {Review of Phylogenetics}, + pages = {100--104}, + number = {1}, + journal = {Systematic Zoology}, + author = {Colless, Donald H.}, + editora = {Wiley, E. O.}, + editoratype = {collaborator}, + year = {1982} +} + +@article{dolsonInterpretingTapeLife2020, + title = {Interpreting the Tape of Life: Ancestry-based Analyses Provide Insights and Intuition about Evolutionary Dynamics}, + volume = {26}, + rights = {All rights reserved}, + pages = {1--22}, + number = {1}, + journal = {Artificial Life}, + author = {Dolson, Emily and Lalejini, Alexander and Jorgensen, Steven and Ofria, Charles}, + year = {2020}, + url = {https://direct.mit.edu/artl/article/26/1/58/93272/Interpreting-the-Tape-of-Life-Ancestry-Based} +} + +@article{faithConservationEvaluationPhylogenetic1992, + title = {Conservation evaluation and phylogenetic diversity}, + volume = {61}, + issn = {0006-3207}, + url = {http://www.sciencedirect.com/science/article/pii/0006320792912013}, + doi = {10.1016/0006-3207(92)91201-3}, + pages = {1--10}, + number = {1}, + journal = {Biological Conservation}, + journaltitle = {Biological Conservation}, + shortjournal = {Biological Conservation}, + author = {Faith, Daniel P.}, + year = {1992} +} + +@article{isaacMammalsEDGEConservation2007, + title = {Mammals on the {EDGE}: Conservation Priorities Based on Threat and Phylogeny}, + volume = {2}, + issn = {1932-6203}, + url = {http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0000296}, + doi = {10.1371/journal.pone.0000296}, + shorttitle = {Mammals on the {EDGE}}, + abstract = {Conservation priority setting based on phylogenetic diversity has frequently been proposed but rarely implemented. Here, we define a simple index that measures the contribution made by different species to phylogenetic diversity and show how the index might contribute towards species-based conservation priorities. We describe procedures to control for missing species, incomplete phylogenetic resolution and uncertainty in node ages that make it possible to apply the method in poorly known clades. We also show that the index is independent of clade size in phylogenies of more than 100 species, indicating that scores from unrelated taxonomic groups are likely to be comparable. Similar scores are returned under two different species concepts, suggesting that the index is robust to taxonomic changes. The approach is applied to a near-complete species-level phylogeny of the Mammalia to generate a global priority list incorporating both phylogenetic diversity and extinction risk. The 100 highest-ranking species represent a high proportion of total mammalian diversity and include many species not usually recognised as conservation priorities. Many species that are both evolutionarily distinct and globally endangered ({EDGE} species) do not benefit from existing conservation projects or protected areas. The results suggest that global conservation priorities may have to be reassessed in order to prevent a disproportionately large amount of mammalian evolutionary history becoming extinct in the near future.}, + pages = {e296}, + number = {3}, + journal = {{PLOS} {ONE}}, + shortjournal = {{PLOS} {ONE}}, + author = {Isaac, Nick J. B. and Turvey, Samuel T. and Collen, Ben and Waterman, Carly and Baillie, Jonathan E. M.}, + urldate = {2018-01-09}, + year = {2007}, + langid = {english}, + keywords = {Animal phylogenetics, Conservation genetics, Conservation science, Endangered species, Mammals, Species diversity, Species extinction, Taxonomy} +} + +@article{mirSoundCollesslikeBalance2018, + title = {Sound Colless-like balance indices for multifurcating trees}, + volume = {13}, + issn = {1932-6203}, + url = {https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0203401}, + doi = {10.1371/journal.pone.0203401}, + abstract = {The Colless index is one of the most popular and natural balance indices for bifurcating phylogenetic trees, but it makes no sense for multifurcating trees. In this paper we propose a family of Colless-like balance indices C D , f that generalize the Colless index to multifurcating phylogenetic trees. Each C D , f is determined by the choice of a dissimilarity D and a weight function f : N → R ≥ 0. A balance index is sound when the most balanced phylogenetic trees according to it are exactly the fully symmetric ones. Unfortunately, not every Colless-like balance index is sound in this sense. We prove then that taking f(n) = ln(n + e) or f(n) = en as weight functions, the resulting index C D , f is sound for every dissimilarity D. Next, for each one of these two functions f and for three popular dissimilarities D (the variance, the standard deviation, and the mean deviation from the median), we find the most unbalanced phylogenetic trees according to C D , f with any given number n of leaves. The results show that the growth pace of the function f influences the notion of “balance” measured by the indices it defines. Finally, we introduce our R package “{CollessLike},” which, among other functionalities, allows the computation of Colless-like indices of trees and their comparison to their distribution under Chen-Ford-Winkel's α-γ-model for multifurcating phylogenetic trees. As an application, we show that the trees in {TreeBASE} do not seem to follow either the uniform model for multifurcating trees or the α-γ-model, for any values of α and γ.}, + pages = {e0203401}, + number = {9}, + journal = {{PLOS} {ONE}}, + shortjournal = {{PLOS} {ONE}}, + author = {Mir, Arnau and Rotger, Lucía and Rosselló, Francesc}, + year = {2018}, + langid = {english} +} + +@article{sackinGoodBadPhenograms1972, + title = {“Good” and “Bad” Phenograms}, + volume = {21}, + issn = {1063-5157}, + url = {https://doi.org/10.1093/sysbio/21.2.225}, + doi = {10.1093/sysbio/21.2.225}, + abstract = {“Good” and “Bad” phenograms. Syst. Zool. 21:225-226.—This paper presents a measure for characterizing a phenogram and measuring its usefulness.}, + pages = {225--226}, + number = {2}, + journal = {Systematic Biology}, + shortjournal = {Systematic Biology}, + author = {Sackin, M. J.}, + year = {1972} +} + +@article{shaoTreeBalance1990, + title = {Tree Balance}, + volume = {39}, + issn = {1063-5157}, + url = {https://academic.oup.com/sysbio/article/39/3/266/1727778}, + doi = {10.2307/2992186}, + abstract = {Abstract. Hierarchic classifications can differ with respect to tree balance—the degree to which branches divide the subtended taxa into subsets of equal size.}, + pages = {266--276}, + number = {3}, + journal = {Systematic Biology}, + shortjournal = {Syst Biol}, + author = {Shao, Kwang-Tsao}, + urldate = {2019-04-11}, + year = {1990}, + langid = {english} +} + +@article{tuckerGuidePhylogeneticMetrics2017, + title = {A guide to phylogenetic metrics for conservation, community ecology and macroecology}, + volume = {92}, + issn = {1469-185X}, + url = {http://onlinelibrary.wiley.com/doi/10.1111/brv.12252/abstract}, + doi = {10.1111/brv.12252}, + abstract = {The use of phylogenies in ecology is increasingly common and has broadened our understanding of biological diversity. Ecological sub-disciplines, particularly conservation, community ecology and macroecology, all recognize the value of evolutionary relationships but the resulting development of phylogenetic approaches has led to a proliferation of phylogenetic diversity metrics. The use of many metrics across the sub-disciplines hampers potential meta-analyses, syntheses, and generalizations of existing results. Further, there is no guide for selecting the appropriate metric for a given question, and different metrics are frequently used to address similar questions. To improve the choice, application, and interpretation of phylo-diversity metrics, we organize existing metrics by expanding on a unifying framework for phylogenetic information. Generally, questions about phylogenetic relationships within or between assemblages tend to ask three types of question: how much; how different; or how regular? We show that these questions reflect three dimensions of a phylogenetic tree: richness, divergence, and regularity. We classify 70 existing phylo-diversity metrics based on their mathematical form within these three dimensions and identify 'anchor' representatives: for α-diversity metrics these are {PD} (Faith's phylogenetic diversity), {MPD} (mean pairwise distance), and {VPD} (variation of pairwise distances). By analysing mathematical formulae and using simulations, we use this framework to identify metrics that mix dimensions, and we provide a guide to choosing and using the most appropriate metrics. We show that metric choice requires connecting the research question with the correct dimension of the framework and that there are logical approaches to selecting and interpreting metrics. The guide outlined herein will help researchers navigate the current jungle of indices.}, + pages = {698--715}, + number = {2}, + journal = {Biological Reviews}, + shortjournal = {Biol Rev}, + author = {Tucker, Caroline M. and Cadotte, Marc W. and Carvalho, Silvia B. and Davies, T. Jonathan and Ferrier, Simon and Fritz, Susanne A. and Grenyer, Rich and Helmus, Matthew R. and Jin, Lanna S. and Mooers, Arne O. and Pavoine, Sandrine and Purschke, Oliver and Redding, David W. and Rosauer, Dan F. and Winter, Marten and Mazel, Florent}, + year = {2017}, + langid = {english}, + keywords = {community assembly, biogeography, conservation, range size, biodiversity hotspots, diversity metrics, evolutionary history, phylogenetic diversity, prioritization} +} + +@article{vane-wrightWhatProtectSystematics1991, + title = {What to protect?—Systematics and the agony of choice}, + volume = {55}, + issn = {0006-3207}, + url = {https://www.sciencedirect.com/science/article/pii/000632079190030D}, + doi = {10.1016/0006-3207(91)90030-D}, + shorttitle = {What to protect?}, + abstract = {Politicians and scientists alike now agree that a priority list of global centres for preservationof biological diversity is required. Diversity has generally been measured only in terms of species richness, or in the form of indices combining richness with abundance. Such measures are considered inadequate for the task in hand. A novel index, based on the information content of cladistic classifications and giving a measure of taxonomic distinctness, is introduced. This taxic diversity measure, when coupled with detailed knowledge of distribution, can be used in modified analyses of the type previously developed as 'critical faunas analysis' or 'network analysis'. Central to all such analyses is the concept of complementarity of floras or faunas. By employing complementariry, step-wise procedures can identify optimally efficient, single-site sequences of priority areas for a group, taking existing reserves into account or not, as required. For practical planning it is concluded that two basic rounds of analysis are required: first, recognition of global priority areas by taxic diversity techniques; secondly, within any such area, analysis without taxic weighting (as being developed by Margules and his co-workers) to identify a network of reserves to contain all local taxa and ecosystems. The paper concludes with a brief discussion of some immediate prospects for development of a systematic approach to global conservation evaluation.}, + pages = {235--254}, + number = {3}, + journal = {Biological Conservation}, + shortjournal = {Biological Conservation}, + author = {Vane-Wright, R. I. and Humphries, C. J. and Williams, P. H.}, + year = {1991}, + langid = {english} +} + +@article{warwickTaxonomicDistinctnessEnvironmental1998, + title = {Taxonomic Distinctness and Environmental Assessment}, + volume = {35}, + issn = {0021-8901}, + url = {http://www.jstor.org/stable/2405168}, + abstract = {1. The objectives of this paper are to test the performance of the taxonomic distinctness index, Δ+, in a number of environmental impact scenarios, to examine its relationship with functional diversity and to examine the influence of habitat type and diversity on the index. 2. The index was applied to data on free-living marine nematodes from the coasts of Britain and Chile. 3. The taxonomic distinctness of nematodes from environmentally degraded locations was generally reduced in comparison with that of more pristine locations, often significantly so. 4. Some habitat types may have naturally lower values of taxonomic distinctness than others. However, unless the habitats are degraded in some way the Δ+ values do not generally fall below the lower 95\% confidence limit of the simulated distribution under a null hypothesis that the assemblages behave as if they are a random selection from the regional species pool. This ameliorates the problem encountered with species richness measures of biodiversity, which are much more strongly affected by habitat type and complexity, thus making comparisons difficult between data sets from different habitats or where habitat type is uncontrolled. 5. Taxonomic distinctness in marine nematodes is shown to be related to trophic diversity: a reduction in trophic diversity will lead to a reduction in taxonomic distinctness, although not necessarily to a reduction in species richness. Trophic composition itself is clearly affected by pollution, but is also strongly responsive to the major influence of habitat type. 6. These features of the taxonomic distinctness index, coupled with its lack of dependence on sampling effort or differences in taxonomic rigour between workers and a statistical framework for the assessment of the significance of departure from expectation, suggest that it may prove to be a biologically and ecologically relevant measure of biodiversity. 7. This paper demonstrates that the taxonomic distinctness index has a number of theoretical and logistical advantages over measures of species richness for the purposes of environmental assessment.}, + pages = {532--543}, + number = {4}, + journal = {Journal of Applied Ecology}, + author = {Warwick, R. M. and Clarke, K. R.}, + year = {1998} +} + +@article{webbExploringPhylogeneticStructure2000, + title = {Exploring the Phylogenetic Structure of Ecological Communities: An Example for Rain Forest Trees}, + volume = {156}, + issn = {0003-0147}, + url = {http://www.jstor.org/stable/10.1086/303378}, + doi = {10.1086/303378}, + shorttitle = {Exploring the Phylogenetic Structure of Ecological Communities}, + abstract = {abstract: Because of the correlation expected between the phylogenetic relatedness of two taxa and their net ecological similarity, a measure of the overall phylogenetic relatedness of a community of interacting organisms can be used to investigate the contemporary ecological processes that structure community composition. I describe two indices that use the number of nodes that separate taxa on a phylogeny as a measure of their phylogenetic relatedness. As an example of the use of these indices in community analysis, I compared the mean observed net relatedness of trees (≥10 cm diameter at breast height) in each of 28 plots (each 0.16 ha) in a Bornean rain forest with the net relatedness expected if species were drawn randomly from the species pool (of the 324 species in the 28 plots), using a supertree that I assembled from published sources. I found that the species in plots were more phylogenetically related than expected by chance, a result that was insensitive to various modifications to the basic methodology. I tentatively infer that variation in habitat among plots causes ecologically more similar species to co-occur within plots. Finally, I suggest a range of applications for phylogenetic relatedness measures in community analysis.}, + pages = {145--155}, + number = {2}, + journal = {The American Naturalist}, + author = {Webb, Campbell O. and Losos, Associate Editor: Jonathan B.}, + year = {2000} +} + +@article{winterPhylogeneticDiversityNature2013, + title = {Phylogenetic diversity and nature conservation: where are we?}, + volume = {28}, + issn = {0169-5347}, + url = {http://www.sciencedirect.com/science/article/pii/S0169534712002881}, + doi = {10.1016/j.tree.2012.10.015}, + shorttitle = {Phylogenetic diversity and nature conservation}, + abstract = {To date, there is little evidence that phylogenetic diversity has contributed to nature conservation. Here, we discuss the scientific justification of using phylogenetic diversity in conservation and the reasons for its neglect. We show that, apart from valuing the rarity and richness aspect, commonly quoted justifications based on the usage of phylogenetic diversity as a proxy for functional diversity or evolutionary potential are still based on uncertainties. We discuss how a missing guideline through the variety of phylogenetic diversity metrics and their relevance for conservation might be responsible for the hesitation to include phylogenetic diversity in conservation practice. We outline research routes that can help to ease uncertainties and bridge gaps between research and conservation with respect to phylogenetic diversity.}, + pages = {199--204}, + number = {4}, + journal = {Trends in Ecology \& Evolution}, + journaltitle = {Trends in Ecology \& Evolution}, + shortjournal = {Trends in Ecology \& Evolution}, + author = {Winter, Marten and Devictor, Vincent and Schweiger, Oliver}, + year = {2013} +} diff --git a/doc/bibliography.md b/doc/bibliography.md new file mode 100644 index 0000000000..f0a4db49cf --- /dev/null +++ b/doc/bibliography.md @@ -0,0 +1,4 @@ +# Bibliography + +```{bibliography} bibliography.bib +``` diff --git a/doc/conf.py b/doc/conf.py index 93843550ce..54750792f6 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Empirical documentation build configuration file, created by @@ -18,10 +18,12 @@ # relative to the documentation root, use os.path.abspath to make it # absolute, like shown here. # +import glob import os import sphinx_rtd_theme import subprocess import sys +import textwrap # -- General configuration --------------------------------------------- @@ -32,37 +34,38 @@ # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.mathjax', 'sphinx.ext.todo', 'sphinx_rtd_theme', 'breathe', - 'exhale', 'myst_parser', + 'sphinx_tippy', + 'sphinxcontrib.bibtex' ] +myst_heading_anchors = 4 + +bibtex_bibfiles = ['bibliography.bib'] +bibtex_reference_style = "author_year" +bibtex_default_style = 'unsrt' + # Setup the breathe extension breathe_projects = { "Empirical": "./doxyoutput/xml" } breathe_default_project = "Empirical" -# Setup the exhale extension -exhale_args = { - # These arguments are required - "containmentFolder": "./api", - "rootFileName": "library_root.rst", - "rootFileTitle": "Library API", - "doxygenStripFromPath": "..", - # Suggested optional arguments - "createTreeView": True, - # TIP: if using the sphinx-bootstrap-theme, you need - # "treeViewIsBootstrap": True, - "exhaleExecutesDoxygen": True, - "exhaleDoxygenStdin": "INPUT = ../include" +breathe_projects_source = { + "Empirical" : ( + "../include/emp", glob.glob("**/*.hpp") + ) } +breathe_doxygen_config_options = {'PREDEFINED': 'DOXYGEN_SHOULD_SKIP_THIS'} + +# cpp_index_common_prefix = ["emp", "emp::", "emp::web::", "web", "emp::web"] + # Tell sphinx what the primary language being documented is. primary_domain = 'cpp' @@ -82,7 +85,7 @@ # General information about the project. project = u'Empirical' -copyright = u"2015, Charles Ofria" +copyright = u"2015-2023, Charles Ofria" author = u"Charles Ofria" # The version info for the project you're documenting, acts as replacement @@ -90,15 +93,15 @@ # the built documents. # # The short X.Y version. -version = '0.0.3' +version = '1.0.0' # The full version, including alpha/beta/rc tags. -release = '0.0.3' +release = '1.0.0' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = "en" # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -111,6 +114,14 @@ # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True +nitpick_ignore = [ + ('c:identifier', 'int32_t'), + ('c:identifier', 'uint32_t'), + ('c:identifier', 'int64_t'), + ('c:identifier', 'uint64_t'), + ('c:identifier', 'size_t'), + ('c:identifier', 'bool'), +] # -- Options for HTML output ------------------------------------------- @@ -130,7 +141,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = [] html_copy_source = False # -- Options for HTMLHelp output --------------------------------------- diff --git a/doc/dev/adding-documentation.md b/doc/dev/adding-documentation.md index b6c98a47f9..df07ba4ec7 100644 --- a/doc/dev/adding-documentation.md +++ b/doc/dev/adding-documentation.md @@ -98,6 +98,7 @@ like the following: ```{eval-rst} .. doxygenfile:: potato.h :project: Empirical + :no-link: ``` ``` diff --git a/doc/dev/guide-to-testing.md b/doc/dev/guide-to-testing.md index 019b70f47c..68e80bacb8 100644 --- a/doc/dev/guide-to-testing.md +++ b/doc/dev/guide-to-testing.md @@ -122,7 +122,6 @@ which are detailed within [their documentation](https://github.com/philsquared/Catch/blob/master/docs/tutorial.md). ## Running Tests with Docker -------------------------- A [devosoft/empirical](https://hub.docker.com/r/devosoft/empirical) Docker image has been set up to make recreating a development environment on your machine easier. diff --git a/doc/filter_namespace b/doc/filter_namespace new file mode 100755 index 0000000000..97f3d09542 --- /dev/null +++ b/doc/filter_namespace @@ -0,0 +1,29 @@ +#!/usr/bin/env python + +import sys + +with open(sys.argv[1]) as infile: + open_braces = 0 + bracket_counts = [] + for line in infile: + line = line.strip() + if line.startswith("namespace emp {") or \ + line.startswith("namespace web {") or \ + line.startswith("namespace prefab {") or \ + line.startswith("namespace emp::prefab {") or \ + line.startswith("namespace evo {"): + open_braces += 1 + bracket_counts.append(open_braces) + print() + elif bracket_counts and bracket_counts[-1] == open_braces and line == "}": + print() + open_braces -= 1 + bracket_counts.pop() + else: + if bracket_counts: + open_braces += line.count("{") + open_braces -= line.count("}") + line = line.replace("emp::", "") + line = line.replace("web::", "") + line = line.replace("prefab::", "") + print(line) diff --git a/doc/index.md b/doc/index.md index 833e55e9cd..c9c98d30ac 100644 --- a/doc/index.md +++ b/doc/index.md @@ -22,13 +22,29 @@ Empirical library into their own projects. Contents: ```{toctree} -:caption: Using Empirical +:caption: Getting Started :maxdepth: 2 - BuiltWithEmpiricalGallery/index QuickStartGuides/index -library/index -api/library_root +``` + +```{toctree} +:caption: Using Empirical +:maxdepth: 4 +:glob: + +library/*/[!_]* +``` + +- {ref}`genindex` +- {ref}`search` + + +```{toctree} +:caption: Bibliography +:maxdepth: 2 + +bibliography ``` diff --git a/doc/library/base/base.md b/doc/library/base/base.md index 14e7d327fe..6ea101aa5f 100644 --- a/doc/library/base/base.md +++ b/doc/library/base/base.md @@ -36,17 +36,15 @@ emp::array array({1,2,3}); // You can treat this just like an std::array ``` -Empirical asserts ------------------ +## Empirical asserts These asserts function similarly to normal asserts, with a few important -additional features: - If compiled with Emscripten they will provide -pop-up alerts when run in a web browser. - emp_assert can take -additional arguments. If the assert is triggered, those extra arguments -will be evaluated and printed. - if NDEBUG -or- EMP_NDEBUG is defined, -the expression in emp_assert() is not evaluated. - if EMP_TDEBUG is -defined, emp_assert() goes into test mode and records failures, but -does not abort. (useful for unit tests of asserts) +additional features: + +- If compiled with Emscripten they will provide pop-up alerts when run in a web browser. +- emp_assert can take additional arguments. If the assert is triggered, those extra arguments will be evaluated and printed. +- if NDEBUG **or** EMP_NDEBUG is defined, the expression in emp_assert() is not evaluated. +- if EMP_TDEBUG is defined, emp_assert() goes into test mode and records failures, but does not abort. (useful for unit tests of asserts) Example: @@ -60,24 +58,41 @@ emp_assert(a==5, a); When compiled in debug mode (i.e. without the -DNDEBUG flag), this will trigger an assertion error and print the value of a. -### emp_assert API (base/assert.hpp) +Empirical also has an emscripten-specific assert, which will only trigger an error when the code was compiled with Emscripten: -% ```{doxygendefine} emp_assert -% :project: Empirical -% ``` +```cpp +#include "Empirical/include/emp/base/emscripten_assert.hpp" + +int a = 6; +// If compiled in with emscripten in debug mode, +// this will print a warning and the value of a +emp_emscripten_assert(a==5, a); -```{eval-rst} -.. doxygendefine:: emp_assert - :project: Empirical - :no-link: ``` -```{eval-rst} -.. doxygendefine:: emp_emscripten_assert - :project: Empirical - :no-link: +If you want your assert to be triggered outside of debug mode, you can use {c:func}`emp_always_assert`. + +## Empirical Warnings + +These work very similar to Empirical asserts, except they do not throw assertion errors. When compiled in debug mode, they will print a warning (and any desired additional information) on failure but program execution will continue. When compiled outside of debug mode they do nothing. + +```cpp +#include "Empirical/include/emp/base/assert_warning.hpp" +#include + +int a = 6; +// If compiled in debug mode, this will print a +// warning and the value of a +emp_assert_warning(a==5, a); + +// This will get printed because no assertion +// error will be triggered +std::cout << "Still running!" << std::endl; + ``` +If you want your warning to be triggered outside of debug mode, you can use {c:func}`emp_always_assert_warning`. + ## Empirical pointers Ptr objects behave as normal pointers under most conditions. However, if @@ -100,3 +115,14 @@ int_ptr.New(123456); // Store the value 123456 in int_ptr. std::cout << "*int_ptr = " << *int_ptr << std::endl; int_ptr.Delete(); ``` + +## API + + + +```{eval-rst} +.. toctree:: + :glob: + + api/* +``` diff --git a/doc/library/bits/bits.md b/doc/library/bits/bits.md index a32aa087b6..daf71df77a 100644 --- a/doc/library/bits/bits.md +++ b/doc/library/bits/bits.md @@ -1,33 +1,14 @@ # Bits -## BitMatrix +Stuff about bits -```{eval-rst} -.. doxygenfile:: emp/bits/BitMatrix.hpp - :project: Empirical - :no-link: -``` - -## BitSet - -```{eval-rst} -.. doxygenfile:: emp/bits/BitSet.hpp - :project: Empirical - :no-link: -``` - -## BitSet Utilities +## API + + ```{eval-rst} -.. doxygenfile:: emp/bits/bitset_utils.hpp - :project: Empirical - :no-link: -``` +.. toctree:: + :glob: -## BitVector - -```{eval-rst} -.. doxygenfile:: emp/bits/BitVector.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/compiler/compiler.md b/doc/library/compiler/compiler.md index 6db62d8a36..cecdbcf611 100644 --- a/doc/library/compiler/compiler.md +++ b/doc/library/compiler/compiler.md @@ -1,41 +1,12 @@ # Compiler -## Deterministic Finite Automata +## API + + ```{eval-rst} -.. doxygenfile:: emp/compiler/DFA.hpp - :project: Empirical - :no-link: -``` - -## Lexer Utilities - -```{eval-rst} -.. doxygenfile:: emp/compiler/lexer_utils.hpp - :project: Empirical - :no-link: -``` - -## Lexer +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/compiler/Lexer.hpp - :project: Empirical - :no-link: -``` - -## NonDeterministic Finite Automata - -```{eval-rst} -.. doxygenfile:: emp/compiler/NFA.hpp - :project: Empirical - :no-link: -``` - -## Regular Expressions - -```{eval-rst} -.. doxygenfile:: emp/compiler/RegEx.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/data/data.md b/doc/library/data/data.md index a3c282c8d7..9d64cea237 100644 --- a/doc/library/data/data.md +++ b/doc/library/data/data.md @@ -29,34 +29,11 @@ for collecting data over the course of a computational experiment. ## Data Tools API -### DataNodes - -```{eval-rst} -.. doxygenfile:: emp/data/DataNode.hpp - :project: Empirical - :no-link: -``` - -### DataManagers - -```{eval-rst} -.. doxygenfile:: emp/data/DataManager.hpp - :project: Empirical - :no-link: -``` - -### DataInterfaces - + + ```{eval-rst} -.. doxygenfile:: emp/data/DataInterface.hpp - :project: Empirical - :no-link: -``` - -### DataFiles +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/data/DataFile.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/datastructs/datastructs.md b/doc/library/datastructs/datastructs.md index 9323db55c5..910a7f9743 100644 --- a/doc/library/datastructs/datastructs.md +++ b/doc/library/datastructs/datastructs.md @@ -1,89 +1,12 @@ # Data structures -## Cache +## API + + ```{eval-rst} -.. doxygenfile:: emp/datastructs/Cache.hpp - :project: Empirical - :no-link: -``` - -## Dynamic Strings - -```{eval-rst} -.. doxygenfile:: emp/datastructs/DynamicString.hpp - :project: Empirical - :no-link: -``` - -## Graph Utilities - -```{eval-rst} -.. doxygenfile:: emp/datastructs/graph_utils.hpp - :project: Empirical - :no-link: -``` - -## Graphs +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/datastructs/Graph.hpp - :project: Empirical - :no-link: -``` - -## Index Map - -```{eval-rst} -.. doxygenfile:: emp/datastructs/IndexMap.hpp - :project: Empirical - :no-link: -``` - -## Map Utilities - -```{eval-rst} -.. doxygenfile:: emp/datastructs/map_utils.hpp - :project: Empirical - :no-link: -``` - -## RandomAccess Set - -```{eval-rst} -.. doxygenfile:: emp/datastructs/ra_set.hpp - :project: Empirical - :no-link: -``` - -## Set Utilities - -```{eval-rst} -.. doxygenfile:: emp/datastructs/set_utils.hpp - :project: Empirical - :no-link: -``` - -## Tuple Struct - -```{eval-rst} -.. doxygenfile:: emp/datastructs/tuple_struct.hpp - :project: Empirical - :no-link: -``` - -## Tuple Utilities - -```{eval-rst} -.. doxygenfile:: emp/datastructs/tuple_utils.hpp - :project: Empirical - :no-link: -``` - -## Vector Utilities - -```{eval-rst} -.. doxygenfile:: emp/datastructs/vector_utils.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/debug/debug.md b/doc/library/debug/debug.md index 725522d8d6..ef445593e0 100644 --- a/doc/library/debug/debug.md +++ b/doc/library/debug/debug.md @@ -1,33 +1,12 @@ # Debug -## Alert +## API + + ```{eval-rst} -.. doxygenfile:: emp/debug/alert.hpp - :project: Empirical - :no-link: -``` - -## Debugging Tools - -```{eval-rst} -.. doxygenfile:: emp/debug/debug.hpp - :project: Empirical - :no-link: -``` - -## Errors +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/debug/errors.hpp - :project: Empirical - :no-link: -``` - -## Memory Tracking - -```{eval-rst} -.. doxygenfile:: emp/debug/mem_track.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/evolve/evolve.md b/doc/library/evolve/evolve.md new file mode 100644 index 0000000000..289b837e5a --- /dev/null +++ b/doc/library/evolve/evolve.md @@ -0,0 +1,266 @@ +# Evolution tools + +## Phylotracklib (Systematics Manager) + +The systematics manager tracks phylogenetic relationships among organisms within a digital +evolution system. For asexual systems, these relationships forma phylogenetic tree +(phylogeny). Systems with recombination (i.e. sexual reproduction systems) are not +yet supported. One of the major benefits of doing *in silico* evolution experiments (instead of or in addition to laboratory or field experiments) is that they allow perfect measurement of quantities that can only be inferred in nature. Once such property is the precise phylogeny (i.e. ancestry tree) of the population. + +![An example phylogeny](../images/phylogeny.jpg) + +At face value, measuring a phylogeny in *in silico* evolution may seem very straightforward: you just need to keep track of what gives birth to what. However, multiple aspects turn out to be non-trivial (see below). The Empirical systematics manager is designed to handle these challenges in a flexible way such that it can be easily plugged into any digital evolution system. It flexibly handle all aspects of recording phylogenies in *in silico* evolution. + +Note: A python wrapper for systematics manager exists in the form of the [Phylotrackpy library](https://phylotrackpy.readthedocs.io/en/latest/). + +### Features + +#### Flexible taxon definitions + +One of the central decisions when creating a phylogeny is choosing what the taxonomic units (i.e. the nodes in the tree) are. In a traditional phylogeny, these nodes are species. However, the concept of species is so murky that it is impossible to generically apply to computational evolution systems (we'd argue that it's questionable whether it could even be applied to biological data recorded at perfect temporal resolution, but that's a separate conversation). One alternative would be to make a phylogeny in which all nodes are individuals, but these trees are usually so large that they are impractical to work with. + +Increasingly, biologists have embraced the idea of building trees in which the taxonomic units are not species. Often, these are denoted by referring to them as an "X tree", where X is the taxonomic unit of interest. A traditional phylogeny, then, is a species tree. This terminology is particularly common in cancer evolution research, in which species trees are often contrasted with "clone trees" or "gene trees", in which the taxonomic units are genotypes. + +We can generalize this concept - any phylogeny of individuals can be abstracted by lumping individuals together based on a shared feature (see figure). This feature could be something simple like a phenotypic or genotypic trait, or it could be something more complex. For example, to approximate something more like a traditional biological species concept, you could choose to define an individual as being a member of a new taxonomic unit if it fails to produce successful offspring when recombined with an individual prototypical of its parent species (although note that the stochasticity inherent in this definition could have some unexpected side effects). The broader the grouping, the smaller the phylogeny will be (e.g. a genotype tree will be larger than a phenotype tree). + +![Illustration of different ways taxonomic units could be defined](https://raw.githubusercontent.com/emilydolson/interpreting_the_tape_of_life/master/figs/dolson.lineage_metrics_cartoon.png) +(Figure from "Quantifying the tape of life: Ancestry-based metrics provide insights and intuition about evolutionary dynamics" published in the proceedings of [ALIFE 2018](http://2018.alife.org/)) + +So how does the systematics manager handle this problem? By giving you the power to define taxonomic groupings however you want! When you construct a `Systematics` object, you give it a function that it can use to determine the taxonomic unit of an organism. Later, when organisms are born, you will pass them to the `Systematics` object and it will run that function on them. If the result matches the result of calling that function on the new organism's parent, then the organism will be considered to be part of the same taxonomic unit (taxon) as its parent. If the results do not match, the new organism will be considered to be the start of a new taxon descended from the parent's taxon. + +Note that multiple taxa may evolve that are the "same" (i.e. running the function on organisms in each yields the same result); each unique evolutionary origin will be counted as a distinct taxon. For example, let's imagine we are building a phylogeny of real animals in nature and grouping them into taxa based on whether they spend more than 50% of their lives in water. Fish and whales would be parts of two different taxa. Even though they both live their whole lives in the water, there would be a "land" taxon in between them on the line of descent. + +Example: + +```cpp +#include "Systematics.hpp" + +// Assuming that the org_t class has a member variable called genotype that stores +// its genotype, this will create a phylogeny based on genotypes +// The org_t template parameter is the type of the organisms living in your world. +// The info_t template parameter is the type of the piece of information you will +// return to indicate which organisms count as the same taxon. +// e.g. here, info_t should be whatever the type of org.genotype is. +sys = emp::Systematics sys([](const org_t & org){return org.genotype;}); +``` + +#### Pruning + +Phylogenies can get very large. So large that they can cause you program to exceed its available memory. To combat this problem, phylogenies can be "pruned" so they only contain extant (i.e. not extinct) taxa and their ancestors. If the `store_outside` variable for a systematics object is set to `False` (the default), this pruning will happen automatically. If you truly want to keep track of every taxon that ever existed, you can do so by setting `store_outside` to `True`. If you want to keep track of some historical data but can't afford the memory overhead of storing every taxon that ever existed, an intermediate options is to periodically print "snapshot" files containing all taxa currently in the phylogeny. + +#### Phylostatistics calculations + +Phylogenies are very information-dense data structures, but it can sometimes be hard to know how to usefully compare them. A variety of phylogenetic summary statistics (mostly based on topology) have been developed for the purpose of usefully making high-level comparisons. The systematics manager has many of these statistics built-in and can automatically output them. It can even keep running data (mean, variance, maximum, and minimum) on each statistic over time in a highly efficient format. + +Available statistics include: + +- Mean/max/min/sum/variance pairwise distance +- Colless-like index (a variant of the Colless index adjusted for trees with multifurcations) {cite:p}`mirSoundCollesslikeBalance2018` +- Sackin index {cite:p}`sackinGoodBadPhenograms1972` +- Phylogenetic diversity {cite:p}`faithConservationEvaluationPhylogenetic1992` + +#### Efficiency + +Tracking phylogenies can be computationally expensive. We have sought to keep the computational overhead as low as possible. + +We also provide the option to remove all taxa that died before a certain time point (the {cpp:func}`Systematics::RemoveBefore` method). Use this with caution, as it will inhibit the use of many phylogenetic topology metrics. In extreme cases it may be necessary to keep your memory footprint sufficiently low, though. + +If you need substantially higher efficiency (in terms of time or memory) or are working in a distributed computing environment (where having a centralized phylogeny tracker can pose a large bottleneck), check out the [hstrat library](https://github.com/mmore500/hstrat), which lets you sacrifice some precision to achieve lower computational overhead. + +#### Flexible output options + +At any time, you can tell the systematics manager to print out the full contents of its current phylogeny in a "snapshot" file. These files will be formatted according to the [Artificial Life Phylogeny Data Standard format](https://alife-data-standards.github.io/alife-data-standards/phylogeny.html). By default they will contain the following columns for each taxon: 1) unique ID, 2) ancestor list, 3) origin time, and 4) destruction time. However, you can add additional columns with the {cpp:func}`Systematics::AddSnapshotFun` method. + +You can also print information on a single lineage. + +### Useful background information + +There are certain quirks associated with real-time phylogenies that you might not be used to thinking about if you're used to dealing with reconstructed phylogenies. Many of these discrepancies are the result of the very different temporal resolutions on which these types of phylogenies are measured, and the fact that the taxonomic units we work with are often at a finer resolution than species. We document some here so that they don't catch you off guard: + +- **Multifurcations are real**: In phylogenetic reconstructions, there is usually an assumption that any multifurcation/polytomy (i.e. a node that has more than two child nodes) is an artifact of having insufficient data. In real-time phylogenies, however, we often observe multifurcations that we know for sure actually happened. +- **Not all extant taxa are leaf nodes**: In phylogenetic reconstructions, there is usually an assumption that all extant (i.e. still living) taxa are leaf nodes in the phylogeny (i.e. none of them are parents/offspring of each other; similar taxa are descended from a shared common ancestor). In real-time phylogenies it is entirely possible that one taxon gives birth to something that we have defined as a different taxon and then continues to coexist with that child taxon. +- **Not all nodes are branch points**: In phylogenetic reconstructions, we only attempt to infer where branch points (i.e. common ancestors of multiple taxa) occurred. We do not try to infer how many taxa existed on a line of descent between a branch point and an extant taxa. In real-time phylogenies we observe exactly how many taxa exist on this line of descent and we keep a record of them. In practice there are often a lot of them, depending on you define your taxa. It is unclear whether we should include these non-branching nodes when calculating phylogenetic statistics (which is why the systematics manager lets you choose whether you want to). + +![An example of a full digital evolution phylogeny](../images/FullPhylogeny.png) + +The above image represents an actual phylogeny measured from digital evolution. Each rectangle represents a different taxon. It's position along the x axis represents the span of time it existed for. Note that there are often sections along a single branch where multiple taxa coexisted for a period of time. Circles represent extant taxa at the end of this run. + +### Glossary + +Some useful terminology that might be useful in understanding the documentation (and especially the code base) for the systematics manager, particularly in light of the fact that different sub-fields of evolutionary biology tend to use different words in many of these contexts. + +- **Taxon**: a generic word for a specific taxonomic unit. We use "taxon" as a generic term to represent a node in a phylogeny. For example, species are a common type of taxon to use when depicting portions of the phylogeny of life on earth. However, sometimes people choose to use higher-order types of taxa (e.g. genus, family, order, class, etc.) when they are trying to depict a larger swath of the whole phylogeny. +- **Taxa**: Plural of taxon. +- **Multifurcation/polytomy**: A node in a phylogeny that has more than two child nodes +- **Bifurcation**: A node in a phylogeny that has exactly two child nodes. +- **Non-branch node**: A node in a phylogeny with only one child node. +- **Leaf node**: A node in a phylogeny with no children. +- **Most Recent Common Ancestor (MRCA)**: The most recent node in a phylogeny that is a common ancestor of all nodes associated with extant taxa. If the phylogeny is pruned, there won't be any branch points before the MRCA (because any branches not leading to the MRCA would lead to taxa that are now extinct). +- **Coalescence events**: Occur when the most recent common ancestor changes (i.e. all descendants from one side of the deepest branch of the phylogeny have gone extinct). In the absence of diversity-preserving features coalescence events are expected to occur by chance with a frequency dependent on population size and spatial structure (but be careful of distributional assumptions). Observing coalescence less frequently than you would expect by chance can be an indication that ecological interactions are present (we have discussed this more [here](https://direct.mit.edu/artl/article/26/1/58/93272/Interpreting-the-Tape-of-Life-Ancestry-Based) and [here](https://direct.mit.edu/artl/article/25/1/50/2915/The-MODES-Toolbox-Measurements-of-Open-Ended)). + +### Quickstart + +#### Installation + +The Systematics manager is part of Empirical. Because Empirical is header-only, you can include whichever parts of it you want. To just use the Systematics manager, you just need to include the Systematics.hpp header. Note that the Systematics manager depends on the result of Empirical, so you will need to download the entire library. Currently, we recommend using the mabe-systematics branch: + +```bash +git clone --recursive git@github.com:devosoft/Empirical.git +cd Empirical +git checkout mabe-systematics +``` + +Then in your C++ file: + +```cpp +#include "Evolve/Systematics.hpp" +``` + +To compile your code using the systematics manager, you will need to tell you compiler where to find Systematics.hpp with the `-I` flag (the below assumes you are compiling from the directory you cloned Empirical into; if you aren't, you will need to include the full path to Empirical): + +```bash +g++ -IEmpirical/include/emp my_source_file.cc +``` + +#### Usage + +##### Creating a systematics object + +The first step in tracking a phylogeny with the systematics manager is to make a systematics object. The most important decision to make at this point is how to define taxa in your phylogeny (for more information, see the "flexible taxon definition" section under "features"). You can do so by passing a function to the systematics constructor which takes an organism object and returns a string that specifies a taxon. + +For example, to build a phylogeny based on genotypes, you could do the following: + +```cpp +#include "Evolve/Systematics.hpp" + +struct MyOrg { + std::string genotype; +}; + +// The first template argument is the type of your organisms +// The second template argument is the type of the piece of information you +// are using to differentiate taxa (here its a string because the genotype +// member variable of our organism struct is a string) +sys = emp::Systematics sys([](const MyOrg & org){return org.genotype;}); +``` + +There are a couple of other decisions that you also need to make at this point. The first is which set of taxa to store in the systematics manager. The defaults here are most likely what you want to use, but in case they aren't, the systematics manager can be told to store or not store the following sets of taxa: + +- **active**: the taxa that still currently have living members. You almost certainly want to store these (without them you don't really have a phylogeny), but can technically disable them by setting the `store_active` argument in the constructor to false. +- **ancestors**: the taxa that are ancestors of active taxa. You almost certainly want to store these too (without them you don't really have a phylogeny), but can technically disable them by setting the `store_ancestors` argument in the constructor to false. +- **outside**: the taxa that are not in either of the other two groups (i.e. taxa that have gone extinct and all of their ancestors have gone extinct). If you store these, your phylogeny will get very large very fast, so doing so is generally not recommended. It is occasionally useful, though, so you can enable storing these taxa by setting the `store_all` argument in the constructor to true. + +The second decision is slightly trickier. Once you start adding organisms to the systematics manager, it will create {cpp:class}`Taxon` objects associated with each one to keep track of which taxon it is part of. You will need to use these taxon objects when adding future organisms, to specify which taxon their parent was part of. If you have control over your organism class, it is likely that the easiest option is to add a `taxon` member variable and store the taxon there. However, if you cannot add arbitrary data to your organism class, keeping track of taxon objects can get annoying. For this reason, the systematics manager gives you the option of letting it manage them. To do so, it needs a way to map individuals to taxa (since its possible there are duplicate taxa, simply running the organism to taxon function again won't work). It achieves this mapping by keeping track of each organism's position in the population. Thus, to have the systematics manager keep track of taxon objects itself, you must set the `store_pos` argument in the constructor to true. You must also use the position-based versions of add_org and remove_org, and make sure to notify the systematics manager if any organism ever changes position during its lifetime for any reason. + +Once you have created the systematics object, you just need to do two things: 1) notify it when something is born, and 2) notify it when something dies. + +##### Notifying the systematics object of births + +You must notify the systematics manager of births using the {cpp:func}`Systematics::AddOrg` family of functions. These functions require that you provide the newly born organism as well as either the taxon object of its parent or the position of its parent (if the systematics manager is tracking positions). + +Example of tracking taxa as object attributes (assume we're building on our example above, and already have created a {cpp:class}`Systematics` manager called `sys`): + +```cpp +// Do whatever you would normally do to create your first organism +// Here, we're assuming we can just call a constructor called Organism() +MyOrg my_org; + +// Notify systematics manager of this organism's birth +// This is the first org, so it doesn't have a parent +// so we do not pass a second argument/ +// add_org will return a pointer to this organism's taxon object, which we +// store for future reference +emp::Ptr > taxon = sys.AddOrg(my_org); + +// Assume stuff happens here that leads to my_org having offspring +// Here, we'll pretend that our organism class has a Reproduce method that +// returns a new offspring organism. You should handle this however you +// normally would +MyOrg org_2 = my_org.Reproduce(); + +// Notify the systematics manager of org_2's birth. Since it has a parent, +// we pass the taxon of that parent in as the second argument +sys.AddOrg(org_2, taxon) + +``` + +An example of tracking positions is coming soon. For now, feel free to contact us with questions! + +##### Notifying the systematics object of deaths + +You must notify the systematics manager of deaths using the {cpp:func}`Systematics::RemoveOrg` family of functions. + +As an example (again, building on the previous examples): + +```cpp +// Assume stuff happens that causes my_org to die + +// We notify the systematics manager that this has happened by calling RemoveOrg +// Note that remove_org takes the taxon of the dead organism as an argument, not +// the organism itself +sys.RemoveOrg(taxon) + +``` + +### Taxon properties + +{cpp:class}`Taxon` objects maintain the following information: + +- taxon ID {cpp:func}`Taxon::GetID()` +- details of organisms in the taxon {cpp:func}`Taxon::GetInfo()` +- pointer to the parent group (will return a null pointer if the species was injected) {cpp:func}`Taxon::GetParent()` +- how many organisms currently exist in the group and how many total organisms have ever existed in the group {cpp:func}`Taxon::GetNumOrgs()` or {cpp:func}`Taxon::GetTotOrgs()` +- how many direct offspring groups exist from this group and how many total extant offspring that exist from this taxa {cpp:func}`Taxon::GetTotalOffspring()` +- how deep in the tree the node you are examining is {cpp:func}`Taxon::GetDepth()` +- when did this taxon first appear in the population {cpp:func}`Taxon::GetOriginationTime()` +- when did the taxon leave the population {cpp:func}`Taxon::GetDestructionTime()` + +### Systematics manager properties + +A {cpp:class}`Systematics` manager object maintains the following information (plus the phylogeny itself): + +- Are we tracking a synchronous population? {cpp:func}`SystematicsBase::GetTrackSynchronous` {cpp:func}`SystematicsBase::SetTrackSynchronous` +- Are we storing all taxa that are still alive in the population? {cpp:func}`SystematicsBase::GetStoreActive` {cpp:func}`SystematicsBase::SetStoreActive` +- Are we storing all taxa that are ancestors of the living organisms in the population? {cpp:func}`SystematicsBase::GetStoreAncestors()` {cpp:func}`SystematicsBase::SetStoreAncestors()` +- Are we storing all taxa that have died out, as have all of their descendants? {cpp:func}`SystematicsBase::GetStoreOutside()` {cpp:func}`SystematicsBase::SetStoreOutside()` +- Are we storing any taxa types that have died out? {cpp:func}`SystematicsBase::GetArchive()` {cpp:func}`SystematicsBase::SetArchive()` +- Are we storing the positions of taxa? {cpp:func}`SystematicsBase::GetStorePosition()` {cpp:func}`SystematicsBase::SetStorePosition()` +- How many living organisms are currently being tracked? {cpp:func}`SystematicsBase::GetTotalOrgs()` +- How many independent trees are being tracked? {cpp:func}`SystematicsBase::GetNumRoots()` +- What ID will the next taxon have? {cpp:func}`SystematicsBase::GetNextID()` +- What is the average phylogenetic depth of organisms in the population? {cpp:func}`SystematicsBase::GetAveDepth()` +- To find the most recent common ancestor (MRCA) use {cpp:func}`SystematicsBase::GetMRCA()` or {cpp:func}`SystematicsBase::GetMRCADepth()` to find the distance to the MRCA. + +### Phylogeny metrics + +Many different metrics can be used to quantify th topology of a phylogeny. For more information, see {cite:p}`winterPhylogeneticDiversityNature2013,tuckerGuidePhylogeneticMetrics2017,dolsonInterpretingTapeLife2020`. + +The Empirical systematics manager can calculate + +- Phylogenetic diversity {cite:p}`faithConservationEvaluationPhylogenetic1992` +- Taxon Distinctiveness {cite:p}`vane-wrightWhatProtectSystematics1991` +- Evolutionary Distinctiveness {cite:p}`isaacMammalsEDGEConservation2007` (mean, sum, and variance) +- Mean pairwise distance {cite:p}`webbExploringPhylogeneticStructure2000`, which is equivalent to Average Taxonomic Diversity {cite:p}`warwickTaxonomicDistinctnessEnvironmental1998,tuckerGuidePhylogeneticMetrics2017` +- Sum pairwise distance +- Variance pairwise distance +- Out-degree distribution +- Average origination time +- Colless-like Index {cite:p}`mirSoundCollesslikeBalance2018` +- Sackin Index {cite:p}`sackinGoodBadPhenograms1972` (reviewed in {cite:p}`shaoTreeBalance1990`) +- Depth of most recent common ancestor +- Phenotypic volatility {cite:p}`dolsonInterpretingTapeLife2020` +- Unique taxa on lineage {cite:p}`dolsonInterpretingTapeLife2020` +- Mutation count along lineage {cite:p}`dolsonInterpretingTapeLife2020` +- Tree size +- Maximum depth + +## API + + + +```{eval-rst} +.. toctree:: + :glob: + + api/* +``` diff --git a/doc/library/functional/functional.md b/doc/library/functional/functional.md index 3c1915a9c8..0b8ea00cc0 100644 --- a/doc/library/functional/functional.md +++ b/doc/library/functional/functional.md @@ -1,33 +1,12 @@ # Functional -## Flex Functions +## API + + ```{eval-rst} -.. doxygenfile:: tools/flex_function.hpp - :project: Empirical - :no-link: -``` - -## Function Sets - -```{eval-rst} -.. doxygenfile:: emp/functional/FunctionSet.hpp - :project: Empirical - :no-link: -``` - -## Generic Functions +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/functional/GenericFunctions.hpp - :project: Empirical - :no-link: -``` - -## Memoized Functions - -```{eval-rst} -.. doxygenfile:: emp/functional/memo_functions.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/images/FullPhylogeny.png b/doc/library/images/FullPhylogeny.png new file mode 100644 index 0000000000..af33ec5f47 Binary files /dev/null and b/doc/library/images/FullPhylogeny.png differ diff --git a/doc/library/images/phylogeny.jpg b/doc/library/images/phylogeny.jpg new file mode 100644 index 0000000000..3652ff4d6a Binary files /dev/null and b/doc/library/images/phylogeny.jpg differ diff --git a/doc/library/io/io.md b/doc/library/io/io.md index c133920b3e..5b63e70782 100644 --- a/doc/library/io/io.md +++ b/doc/library/io/io.md @@ -1,25 +1,12 @@ # IO -## Inmemory Files +## API + + ```{eval-rst} -.. doxygenfile:: emp/io/File.hpp - :project: Empirical - :no-link: -``` - -## Serialization Macros +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/io/serialize_macros.hpp - :project: Empirical - :no-link: -``` - -## Serialization Tools - -```{eval-rst} -.. doxygenfile:: emp/io/serialize.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/math/math.md b/doc/library/math/math.md index af7a163bd2..0b4365b3b7 100644 --- a/doc/library/math/math.md +++ b/doc/library/math/math.md @@ -1,73 +1,12 @@ # Math -## Combinations +## API + + ```{eval-rst} -.. doxygenfile:: emp/math/combos.hpp - :project: Empirical - :no-link: -``` - -## Constants - -```{eval-rst} -.. doxygenfile:: emp/math/constants.hpp - :project: Empirical - :no-link: -``` - -## Information Theory Tools - -```{eval-rst} -.. doxygenfile:: emp/math/info_theory.hpp - :project: Empirical - :no-link: -``` - -## Math - -```{eval-rst} -.. doxygenfile:: emp/math/math.hpp - :project: Empirical - :no-link: -``` - -## Randomness Utilites +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/math/random_utils.hpp - :project: Empirical - :no-link: -``` - -## Random Number Generator - -```{eval-rst} -.. doxygenfile:: emp/math/Random.hpp - :project: Empirical - :no-link: -``` - -## Range - -```{eval-rst} -.. doxygenfile:: emp/math/Range.hpp - :project: Empirical - :no-link: -``` - -## Sequence Utilities - -```{eval-rst} -.. doxygenfile:: emp/math/sequence_utils.hpp - :project: Empirical - :no-link: -``` - -## Statistics Tools - -```{eval-rst} -.. doxygenfile:: emp/math/stats.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/prefab/prefab.rst b/doc/library/prefab/prefab.rst deleted file mode 100644 index 554da916c1..0000000000 --- a/doc/library/prefab/prefab.rst +++ /dev/null @@ -1,355 +0,0 @@ -Prefabricated Web Tools (for use with Emscripten) -================================================= - -These prefabricated tools were created to help you quickly create interesting web applicications without being overwhelmed with the underlying HTML, CSS, and Bootstrap classes required. -These tools use Empirical's web tools to provide structure for the site, and many of the prefab tools inherit from web tools so you can add your own styling and stream them into other web components in a similar way. - -When using these prefab tools be sure to link to the Bootstrap library, jQuery, and the default style stylesheet for this class in the head section of your HTML file. -.. code-block:: html - - - - - - - - -You can view these tools in action `here `_. - -Card -~~~~ -The Card class allows you to define a Bootstrap style card into your project. -A card that is not collapsible will have its state set to :code:`STATIC`. -Cards are static by default. -A card can be collapsible if its state parameter it set to :code:`INIT_OPEN` or :code:`INIT_CLOSED`. -By default, if a card is collapsible, it will have toggle icons in the header, but this can be overridden by setting the :code:`showGlyphs` parameter to :code:`false`. - -Since this class inherits from :code:`web::Div`, you can set styling and attributes with :code:`SetCSS` and :code:`SetAttr` respectively. -You can also stream your Card into other web components with the :code:`<<` operator. - -Example: -******** -.. code-block:: c++ - - #include "web/web.h" - #include "prefab/Card.h" - - emp::web::Document doc("emp_base"); - - emp::prefab::Card my_card("STATIC"); - doc << my_card; - - my_card.AddHeaderContent("Title"); - my_card.AddBodyContent("Content for the card's body"); - // Web components can also be passed as parameters to AddHeaderContent and AddBodyContent - -**Note**: The toggle icons that are avalible for collapsible cards use the `FontAwesome`_ library. -You will need to add the CSS file for this library to the head of your HTML file: - -.. code-block:: html - - - -CodeBlock -~~~~~~~~~ -The CardBlock class provides an interface for the `HighlightJS Library`_ which allows you to display code on web pages with language specific highlighting. -You can find a list of `all languages`_ on their GitHub page. - -To use this class, you need to pass the code you want displayed and the programming language to the constructor. - -Since this class inherits from :code:`web::Element`, you can stream your CodeBlock into other web components with the :code:`<<` operator. - -Example: -******** -.. code-block:: c++ - - #include "web/web.h" - #include "prefab/CodeBlock.h" - - emp::web::Document doc("emp_base"); - - std::string code_str = - R"( - int num = 9; - std::cout << num << " is a square number" << std::endl; - )"; - emp::prefab::CodeBlock code_block(code_str, "c++"); - - doc << code_block; - -**Note**: You will also need to add the following code to the bottom of the body section of your HTML file: - -.. code-block:: html - - - - - - -.. _HighlightJS Library: https://highlightjs.org/ -.. _all languages: https://github.com/highlightjs/highlight.js/blob/master/SUPPORTED_LANGUAGES.md - -Collapse -~~~~~~~~ -The CollapseCouple maintains a group of targets and controllers. -When a controller is clicked on a web page, all the associated targets will change state (expand/collapse). - -By default, the target element will start off closed, but this can be set to open by passing :code:`true` for the :code:`expanded` parameter. - -Since the collapse controller and collapse target element will not necessarily directly neighbor eachother, call :code:`GetControllerDiv()` and :code:`GetTargetDiv()` to obtain a vector of all the asspociated controllers and targets, respectively. -To obtain just one controller or target, pass its index into a get div function call. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "web/Div.h" - #include "prefab/CommentBox.h" - - #include "prefab/Collapse.h" - - emp::web::Document doc("emp_base"); - - emp::prefab::CommentBox box1; - box1.AddContent("

Box 1

"); - emp::web::Div btn1; - btn1.SetAttr("class", "btn btn-info"); - btn1 << "Button 1: controls box 1"; - - emp::prefab::CollapseCoupling collapse1(btn1, box1, true); - - doc << collapse1.GetControllerDiv(0); - doc << collapse1.GetTargetDiv(0); - -CommentBox -~~~~~~~~~~ -A CommentBox is a simple grey comment bubble. -Content can be added to it using :code:`AddContent()`. -If there is data you only want to be visible on mobile devices, use :code:`AddMobileContent()`. - -Since this class inherits from :code:`web::Div`, you can set styling and attributes with :code:`SetCSS()` and :code:`SetAttr()` respectively. -You can also stream your CommentBox into other web components with the :code:`<<` operator. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "prefab/CommentBox.h" - - emp::web::Document doc("emp_base"); - - emp::prefab::CommentBox my_box; - doc << my_box; - - my_box.AddContent("

Content that shows on all screen sizes

"); - my_box.AddMobileContent("
Content that only shows on small screens"); - // Web components can also be passed as parameters to AddContent and AddMobileContent - -ConfigPanel -~~~~~~~~~~~ -The ConfigPanel allows developers to easily set up a user interface for their configuration options. -It allows web apps to be interactive and dynamic, allowing users to change configuration settings within the applicaiton and providing a better user experiance. - -Using the ConfigPanel class, a configuration panel is constructed when passed a Config file. -It uses other Prefabricated components to add styling and structure to the panel. -Use :code:`GetConfigPanelDiv()` to stream this component into another web component or document. - -It is important to note that ConfigPanel instances are destroyed when they go out of scope. -This causes the form to no longer respond to changes made by the user. -You will need to initialize an instance outside of :code:`main()` if you would like the user to be able to interact with the panel. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "prefab/ConfigPanel.h" - #include "config/ArgManager.h" - - #include "SampleConfig.h" // Config file - - emp::web::Document doc("emp_base"); - Config cfg; - - emp::prefab::ConfigPanel config_panel(cfg); - - // apply configuration query params and config files to Config - auto specs = emp::ArgManager::make_builtin_specs(&cfg); - emp::ArgManager am(emp::web::GetUrlParams(), specs); - // cfg.Read("config.cfg"); - am.UseCallbacks(); - if (am.HasUnused()) std::exit(EXIT_FAILURE); - - // setup configuration panel - config_panel.Setup(); - doc << config_panel.GetConfigPanelDiv(); - -FontAwesomeIcon -~~~~~~~~~~~~~~~ -`FontAwesome`_ is a free library of icons that can be used in web pages. - -To use this class: - -1. Find the icon you wish to use in the `FontAwesome library`_ -2. Pass :code:`"fa-" + *icon name*` as a parameter to the constructor. -3. Add the following CSS file to the head of your HTML document. - -.. code-block:: html - - - -Since this class inherits from :code:`web::Element`, you can set styling and attributes with :code:`SetCSS()` and :code:`SetAttr()` respectively. -You can also stream your FontAwesomeIcon into other web components with the :code:`<<` operator. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "prefab/FontAwesomeIcon.h" - - emp::web::Document doc("emp_base"); - - emp::prefab::FontAwesomeIcon my_icon("fa-paw"); - doc << my_icon; - - my_icon.AddClass("custom_class"); - -.. _FontAwesome: https://fontawesome.com/v4.7.0/ -.. _FontAwesome library: https://fontawesome.com/v4.7.0/icons/ - -LoadingIcon -~~~~~~~~~~~ -The LoadingIcon class is used to add an animated loading icon. -One possible use for this icon is to be displayed while the contents of a web page is loading. -The icon is provided by `FontAwesome`_, so you will need to add its CSS to your HTML file to use this class. - -.. code-block:: html - - - -Since this class inherits from :code:`web::Element`, you can set styling and attributes with :code:`SetCSS()` and :code:`SetAttr()` respectively. -You can also stream your LoadingIcon into other web components with the :code:`<<` operator. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "prefab/LoadingIcon.h" - - emp::web::Document doc("emp_base"); - - emp::prefab::LoadingIcon spinner; - doc << spinner; - -LoadingModal -~~~~~~~~~~~~ -The LoadingModal header file makes adding a loading modal to a web page easy. -It will appear while the content of the page is rendering and will disappear when the page has completed loading. - -This header file is slightly different from the other prefab web tools. -To place the loading modal on your web page, you must import the LoadingModal.js script into your HTML file right after the opening body tag. -To close the modal you must call the :code:`CloseLoadingModal()` function in your .cc file after loading the desired content into the doc. - -Example: -******** -.. code-block:: cpp - - // .cc file - #include "web/web.h" - #include "LoadingModal.h" - - emp::web::Document doc("emp_base"); - - // Add elements to the doc a normal - - emp::prefab::CloseLoadingModal(); - -.. code-block:: html - - - - - - - - - - - - - - - - - - - -Modal -~~~~~ -The Modal class can be used to create Bootstrap modals that pops up in the middle of the screen. - -Since this class inherits from :code:`web::Div`, you can stream your Modal into other web components with the :code:`<<` operator. -You can also set the background color of the Modal with :code:`SetBackground()` passing it a string with a color name or its hex code value. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "web/Button.h" - #include "prefab/Modal.h" - - emp::web::Document doc("emp_base"); - - emp::prefab::Modal modal; - doc << modal; - - modal.AddHeaderContent("

Modal Header Section

"); - modal.AddBodyContent("This is the content of the modal"); - - modal.AddFooterContent("Modal Footer Section"); - UI::Button close_btn([](){;}, "Close"); - close_btn.SetAttr("class", "btn btn-secondary"); - modal.AddFooterContent(close_btn); - modal.AddButton(close_btn); - - modal.AddClosingX(); - - UI::Button modal_btn([](){;}, "Show Modal"); - doc << modal_btn; - modal_btn.SetAttr("class", "btn btn-info"); - modal.AddButton(modal_btn); - -ToggleSwitch -~~~~~~~~~~~~ -The ToggleSwitch class wraps checkbox input with Bootstrap custom swtich classes. -If you need to add a CSS class to the Input, do it after the creating the ToggleSwitch instance with :code:`AddClass()`. - - -Since this class inherits from :code:`web::Element`, you can set styling and attributes with :code:`SetCSS()` and :code:`SetAttr()` respectively. -You can also stream your ToggleSwitch into other web components with the :code:`<<` operator. - -Example: -******** -.. code-block:: cpp - - #include "web/web.h" - #include "prefab/ToggleSwitch.h" - - emp::prefab::ToggleSwitch on_switch([](std::string val){}, "Switch Defult On", true, "user_defined_switch_id"); - doc << on_switch; - - doc << "
"; - - emp::prefab::ToggleSwitch off_switch([](std::string val){}, NULL, false); - doc << off_switch; - off_switch.AddLabel("Switch Defult Off"); - -Add the link to Bootstrap in the head of your HTML file: -.. code-block:: html - - diff --git a/doc/library/testing/testing.md b/doc/library/testing/testing.md index 6e1d18e9ad..1e0d9847b0 100644 --- a/doc/library/testing/testing.md +++ b/doc/library/testing/testing.md @@ -1,9 +1,12 @@ # Testing -## Unit Testing +## API + + ```{eval-rst} -.. doxygenfile:: emp/testing/unit_tests.hpp - :project: Empirical - :no-link: +.. toctree:: + :glob: + + api/* ``` diff --git a/doc/library/tools/tools.md b/doc/library/tools/tools.md index 9531d9a11e..fcf1c6eda0 100644 --- a/doc/library/tools/tools.md +++ b/doc/library/tools/tools.md @@ -1,33 +1,12 @@ # Other Tools -## Timing Functions +## API + + ```{eval-rst} -.. doxygenfile:: emp/tools/timing.hpp - :project: Empirical - :no-link: -``` - -## Branch and Bound Solution States - -```{eval-rst} -.. doxygenfile:: emp/tools/SolveState.hpp - :project: Empirical - :no-link: -``` - -## String Utilities +.. toctree:: + :glob: -```{eval-rst} -.. doxygenfile:: emp/tools/string_utils.hpp - :project: Empirical - :no-link: -``` - -## Type Tracker - -```{eval-rst} -.. doxygenfile:: emp/tools/TypeTracker.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/library/web/d3/d3-intro.md b/doc/library/web/d3/d3-intro.md index 13fb8332c4..1c512ad20b 100644 --- a/doc/library/web/d3/d3-intro.md +++ b/doc/library/web/d3/d3-intro.md @@ -1,9 +1,8 @@ -Using Empirical\'s D3.js Wrapper -================================ +# Using Empirica's D3.js Wrapper -If you\'re writing scientific code that runs on the web, you\'ll +If you're writing scientific code that runs on the web, you'll probably want to visualize the results (either as your program runs or -after it\'s done). To make this as easy as possible, Empirical includes +after it's done). To make this as easy as possible, Empirical includes a C++ wrapper for d3.js, a wildly popular and powerful Javascript data visualization library. Using the wrapper, you can create visualizations directly from C++. @@ -19,8 +18,7 @@ pre-built graph objects in an effort to help those new to Javascript visualization get started fast. This is an ongoing process and we\'re always open to suggestions! -A Minimal Example -================= +## A Minimal Example D3 visualizations run in web browsers. That means that to use this wrapper, you need to compile your C++ code to Javascript, using @@ -38,8 +36,7 @@ easiest way to make a visualization is to use one of the pre-built visualizations. Later we\'ll get into writing your own. Either way, you\'ll need: -C++ File --------- +### C++ File The C++ file that you\'ll compile to Javascript. For this example, we\'ll use the Empirical web module to build the whole web page: @@ -94,8 +91,7 @@ emcc my_program.cc -o my_program.js \ #.js extension tells Emscripten to compile #once you're done debugging) ``` -HTML File ---------- +### HTML File To tell the browser what to do with your Javascript, you need an html file: @@ -135,8 +131,7 @@ file: ``` -CSS File --------- +### CSS File Optionally, a CSS file can be used to make elements look the way you want them to. Here\'s one that includes the necessary styles to make @@ -174,8 +169,7 @@ style\_sheet.css, and is in the same directory as the html file): } ``` -Running your visualization --------------------------- +### Running your visualization Now to open up the page in a browser! Some browsers will let you open the page up directly, but some will complain about the fact that you\'re @@ -199,30 +193,29 @@ python -m http.server ![Using SimpleHTTPServer with Python3](../../images/python3HTTPserver.png){.align-center} You can now open a browser to the server (, -replacing 8000 with whatever number was after \"port\" in the output +replacing 8000 with whatever number was after "port" in the output from the command). You should see a list of file names in the directory your terminal was open to when you ran the HTTP Server command (unless -you happen to have a file named index.html, in which case you\'ll see +you happen to have a file named index.html, in which case you'll see the contents of that file). Assuming you ran this command from the -\"example\" directory in the directory structure shown above, you should +"example" directory in the directory structure shown above, you should see \"my\_html.html\" (or whatever you called your html file) on the list. Click on it. -Ta-da! There\'s your visualization. +Ta-da! There's your visualization. -It\'s convenient to have a visualization of data you\'ve already +It's convenient to have a visualization of data you've already generated, but the real power of D3 visualization objects is that they -can update in real time while your code runs. Here\'s an example C++ +can update in real time while your code runs. Here's an example C++ file that does that: > Example here -So that\'s how you use out-of-the-box D3 visualizations in Empirical. +So that's how you use out-of-the-box D3 visualizations in Empirical. Sometimes, though, you want to do something new and exciting. Which -brings us to the next section\... +brings us to the next section... -Writing Your Own Visualization -============================== +## Writing Your Own Visualization To build your own visualization, you need to understand a bit about how D3 works. Which means you need to understand a bit about how Javascript @@ -262,8 +255,8 @@ D3 C++ wrapper, you\'re doing the same thing, but from C++. Let\'s take a tour of the main components of D3: -Selections ----------- +### Selections + `Selections `{.interpreted-text role="ref"} are a way to work with groups of DOM elements. For instance, @@ -343,8 +336,7 @@ D3::Selection graph_circles = svg.SelectAll("circle"); Advanced note: You can also make selections based on classes with [D3::Select(.classname)]{.title-ref}. -Binding Data ------------- +### Binding Data In D3, you bind data to selections. Usually, you are binding that data because you to visualize it with SVG elements. So, usually the selection @@ -541,8 +533,7 @@ update.EnterAppend("circle") update.ExitRemove(); ``` -Changing Elements\' Traits --------------------------- +### Changing Elements\' Traits There are three types of traits that a DOM element might have: attributes, styles, and properties. For the most part, attributes are @@ -643,8 +634,7 @@ also select transitions, allowing you to choose to have their effects be animated, rather than occuring instantaneously (which can look choppy in many visualizations). -Scales and Axes ---------------- +### Scales and Axes Usually your data is not in units that you can directly draw on the screen. For instance, if you want to plot a variable on the Y axis that @@ -832,8 +822,7 @@ emp::JSWrap(times_two, "times_two"); s.SetAttr("r", "times_two"); ``` -- Advanced users may also wish to write functions directly in - Javascript, which is possible using Emscripten\'s macros. +- Advanced users may also wish to write functions directly in Javascript, which is possible using Emscripten's macros. ``` cpp // Put the function in global scope by adding it @@ -876,8 +865,7 @@ int get_x(JSONData d, int i, int j) {return d.x();}; s.SetAttr("cx", get_x); ``` -Under the Hood (for the curious, developers, and people trying to do weird stuff) -================================================================================= +## Under the Hood (for the curious, developers, and people trying to do weird stuff) For the most part, Empirical\'s d3 wrapper isn\'t that complicated under the hood. All C++ objects in the d3 module have a unique integer id. @@ -907,17 +895,7 @@ have not been conducted. Things to watch out for: -- D3 object creation order - be careful of the order your constructors - for d3 objects get called in. It\'s hard to make this happen, but if - you\'re constructing objects in the constructors for other objects, - it\'s possible for the ids to get mixed up. -- Errors in Javascript usually won\'t show up on compilation - you - need to actually run the code. -- Main is a function that gets run like any other. When main finishes - running, its local variables will go out of scope. This means that - everything needed for an ongoing animation needs to live in global - scope. -- Javascript is designed to work asynchronously in a lot of contexts - (especially when loading outside resources or updating the graphics - on the screen). This can change the way you need to structure your - code. +- D3 object creation order - be careful of the order your constructors for d3 objects get called in. It's hard to make this happen, but if you're constructing objects in the constructors for other objects, it's possible for the ids to get mixed up. +- Errors in Javascript usually won't show up on compilation - you need to actually run the code. +- Main is a function that gets run like any other. When main finishes running, its local variables will go out of scope. This means that everything needed for an ongoing animation needs to live in global scope. +- Javascript is designed to work asynchronously in a lot of contexts (especially when loading outside resources or updating the graphics on the screen). This can change the way you need to structure your code. diff --git a/doc/library/web/web.md b/doc/library/web/web.md index 8648f435fe..aafe7736c9 100644 --- a/doc/library/web/web.md +++ b/doc/library/web/web.md @@ -6,240 +6,13 @@ d3/d3 ``` -## Animations +## API + + ```{eval-rst} -.. doxygenfile:: emp/web/Animate.hpp - :project: Empirical - :no-link: -``` - -## Attributes - -```{eval-rst} -.. doxygenfile:: emp/web/Attributes.hpp - :project: Empirical - :no-link: -``` - -## Buttons - -```{eval-rst} -.. doxygenfile:: emp/web/Button.hpp - :project: Empirical - :no-link: -``` - -## Canvas - -```{eval-rst} -.. doxygenfile:: emp/web/Canvas.hpp - :project: Empirical - :no-link: -``` - -## Canvas Utilities - -```{eval-rst} -.. doxygenfile:: emp/web/canvas_utils.hpp - :project: Empirical - :no-link: -``` - -## Canvas Actions - -```{eval-rst} -.. doxygenfile:: emp/web/CanvasAction.hpp - :project: Empirical - :no-link: -``` - -## Canvas Shapes - -```{eval-rst} -.. doxygenfile:: emp/web/CanvasShape.hpp - :project: Empirical - :no-link: -``` - -## Color maps - -```{eval-rst} -.. doxygenfile:: emp/web/color_map.hpp - :project: Empirical - :no-link: -``` - -## Commands - -```{eval-rst} -.. doxygenfile:: emp/web/commands.hpp - :project: Empirical - :no-link: -``` - -## Divs - -```{eval-rst} -.. doxygenfile:: emp/web/Div.hpp - :project: Empirical - :no-link: -``` - -## Documents - -```{eval-rst} -.. doxygenfile:: emp/web/Document.hpp - :project: Empirical - :no-link: -``` - -## Useful functions for emscripten - -```{eval-rst} -.. doxygenfile:: emp/web/emfunctions.hpp - :project: Empirical - :no-link: -``` - -## Event Handling - -```{eval-rst} -.. doxygenfile:: emp/web/events.hpp - :project: Empirical - :no-link: -``` - -## File Input - -```{eval-rst} -.. doxygenfile:: emp/web/FileInput.hpp - :project: Empirical - :no-link: -``` - -## Font - -```{eval-rst} -.. doxygenfile:: emp/web/Font.hpp - :project: Empirical - :no-link: -``` +.. toctree:: + :glob: -## Images - -```{eval-rst} -.. doxygenfile:: emp/web/Image.hpp - :project: Empirical - :no-link: -``` - -## Initialization - -```{eval-rst} -.. doxygenfile:: emp/web/init.hpp - :project: Empirical - :no-link: -``` - -## Javascript Utilities - -```{eval-rst} -.. doxygenfile:: emp/web/js_utils.hpp - :project: Empirical - :no-link: -``` - -## JSWrap - -```{eval-rst} -.. doxygenfile:: emp/web/JSWrap.hpp - :project: Empirical - :no-link: -``` - -## Keypress Manager - -```{eval-rst} -.. doxygenfile:: emp/web/KeypressManager.hpp - :project: Empirical - :no-link: -``` - -## Listeners - -```{eval-rst} -.. doxygenfile:: emp/web/Listeners.hpp - :project: Empirical - :no-link: -``` - -## Raw Image - -```{eval-rst} -.. doxygenfile:: emp/web/RawImage.hpp - :project: Empirical - :no-link: -``` - -## Selector - -```{eval-rst} -.. doxygenfile:: emp/web/Selector.hpp - :project: Empirical - :no-link: -``` - -## Styles - -```{eval-rst} -.. doxygenfile:: emp/web/Style.hpp - :project: Empirical - :no-link: -``` - -## Tables - -```{eval-rst} -.. doxygenfile:: emp/web/Table.hpp - :project: Empirical - :no-link: -``` - -## Text - -```{eval-rst} -.. doxygenfile:: emp/web/Text.hpp - :project: Empirical - :no-link: -``` - -## Text Areas - -```{eval-rst} -.. doxygenfile:: emp/web/TextArea.hpp - :project: Empirical - :no-link: -``` - -## Tweens - -```{eval-rst} -.. doxygenfile:: emp/web/Tween.hpp - :project: Empirical - :no-link: -``` - -## Widgets - -```{eval-rst} -.. emp/web/Widget.hpp - :project: Empirical - :no-link: -``` - -```{eval-rst} -.. doxygenfile:: emp/web/WidgetExtras.hpp - :project: Empirical - :no-link: + api/* ``` diff --git a/doc/make_md.py b/doc/make_md.py new file mode 100755 index 0000000000..bb7fe3f466 --- /dev/null +++ b/doc/make_md.py @@ -0,0 +1,70 @@ +#!/usr/bin/python + +import glob +import os + +# This script performs preprocessing for the Empirical documentation +# build process, manually filling in the folder tree `library` with stub +# markdown files for the documentation of Empirical header files to be built +# onto. +# +# The script scans the "../include/emp" directory for all ".hpp" files (with +# several explicit exclusions). For each header `emp/subname/filename.hpp` +# it creates a stub `library/subname/api/file.md`. Note that the `library` +# folder already contains skeleton content (i.e., stub pages for each of +# Emprical's subdirectories. Note also that some Empirical subdirectories +# not intended for external use are explicitly excluded. + +def format_directive(filename): + """Create the breathe directive and add the options.""" + directive = f"```{{eval-rst}}\n.. doxygenfile:: {filename}\n :project: Empirical\n```\n" + return directive + + +def format_heading(level, text): + """Create a heading of [1, 2 or 3 supported].""" + symbol = ["# ", "## ", "### ", "#### "][ + level - 1 + ] + return symbol + text + "\n\n" + +# Ensure execution inside of doc/ +script_directory = os.path.dirname(os.path.abspath(__file__)) +os.chdir(script_directory) + +header_files = glob.glob("../include/emp/**/*.hpp", recursive=True) + +for h in header_files: + print(h) + h = h.removeprefix("../include/emp/") + just_dir = "/".join(h.split("/")[:-1]).lower() + last_dir = just_dir.split("/")[-1] + just_file = h.split("/")[-1] + + excluded_prefixes = [ + "_", + "in_progress", + "polyfill", + ] + if any(just_file.startswith(prefix) for prefix in excluded_prefixes): + continue + new_dir = "library/" + just_dir + "/api" + print(new_dir) + toc_text = "\n\n" + format_heading(2, "API") + "```{eval-rst}\n.. toctree::\n :glob:\n\n api/*\n```\n" + os.makedirs(new_dir, exist_ok=True) + toc_file_name = f"library/{just_dir}/{last_dir}.md" + if not os.path.exists(toc_file_name): + toc_text = format_heading(1, last_dir.capitalize()) + toc_text + with open(toc_file_name, "w") as target: + target.write(toc_text) + elif "" not in open(toc_file_name).read(): + with open(toc_file_name, "a") as target: + target.write("\n" + toc_text) + + text = format_heading(1, f"{just_file}") + text += format_directive("emp/" + h) + + filename = just_file.removesuffix(".hpp") + ".md" + + with open(new_dir + "/" + filename, "w") as target: + target.write(text) diff --git a/doc/requirements.in b/doc/requirements.in index af341d1323..f45eb3d066 100644 --- a/doc/requirements.in +++ b/doc/requirements.in @@ -1,10 +1,7 @@ -sphinx==3.2.1 -exhale==0.2.3 -sphinx-rtd-theme==0.5.0 -coverxygen==1.5.0 -breathe==4.22.1 -myst-parser==0.12.9 -# @mmore500 2021-10 -# docutils 0.18.0 crashes docs build due to exception -# AttributeError: 'Values' object has no attribute 'section_self_link' -docutils==0.17.1 +sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +coverxygen==1.8.1 +breathe==4.35.0 +myst-parser==2.0.0 +sphinx-tippy==0.4.1 +sphinxcontrib-bibtex==2.6.1 diff --git a/doc/requirements.txt b/doc/requirements.txt index ba5ca8f558..8293d91324 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,94 +1,114 @@ # -# This file is autogenerated by pip-compile -# To update, run: +# This file is autogenerated by pip-compile with Python 3.10 +# by the following command: # -# pip-compile requirements.in +# pip-compile doc/requirements.in # -alabaster==0.7.12 +alabaster==0.7.13 # via sphinx -attrs==20.3.0 - # via markdown-it-py -babel==2.9.1 +babel==2.13.1 # via sphinx -beautifulsoup4==4.10.0 - # via bs4 -breathe==4.22.1 - # via - # -r requirements.in - # exhale -bs4==0.0.1 - # via exhale -certifi==2021.10.8 +beautifulsoup4==4.12.2 + # via sphinx-tippy +breathe==4.35.0 + # via -r /tmp/requirements.in +certifi==2023.11.17 # via requests -charset-normalizer==2.0.7 +charset-normalizer==3.3.2 # via requests -coverxygen==1.5.0 - # via -r requirements.in -docutils==0.17.1 +coverxygen==1.8.1 + # via -r /tmp/requirements.in +docutils==0.20.1 # via - # -r requirements.in + # -r /tmp/requirements.in # breathe # myst-parser + # pybtex-docutils # sphinx -exhale==0.2.3 - # via -r requirements.in -idna==3.3 + # sphinx-rtd-theme + # sphinxcontrib-bibtex +idna==3.6 # via requests -imagesize==1.2.0 +imagesize==1.4.1 # via sphinx -jinja2==3.0.2 - # via sphinx -lxml==4.6.3 - # via exhale -markdown-it-py==0.5.8 - # via myst-parser -markupsafe==2.0.1 +jinja2==3.1.2 + # via + # myst-parser + # sphinx + # sphinx-tippy +latexcodec==2.0.1 + # via pybtex +markdown-it-py==3.0.0 + # via + # mdit-py-plugins + # myst-parser +markupsafe==2.1.3 # via jinja2 -myst-parser==0.12.9 - # via -r requirements.in -packaging==21.0 - # via sphinx -pygments==2.10.0 - # via sphinx -pyparsing==3.0.2 - # via packaging -pytz==2021.3 - # via babel -pyyaml==6.0 +mdit-py-plugins==0.4.0 # via myst-parser -requests==2.26.0 +mdurl==0.1.2 + # via markdown-it-py +myst-parser==2.0.0 + # via -r /tmp/requirements.in +packaging==23.2 + # via sphinx +pybtex==0.24.0 + # via + # pybtex-docutils + # sphinxcontrib-bibtex +pybtex-docutils==1.0.3 + # via sphinxcontrib-bibtex +pygments==2.17.2 # via sphinx +pyyaml==6.0.1 + # via + # myst-parser + # pybtex +requests==2.31.0 + # via + # sphinx + # sphinx-tippy six==1.16.0 # via - # breathe - # exhale -snowballstemmer==2.1.0 + # latexcodec + # pybtex +snowballstemmer==2.2.0 # via sphinx -soupsieve==2.2.1 +soupsieve==2.5 # via beautifulsoup4 -sphinx-rtd-theme==0.5.0 - # via -r requirements.in -sphinx==3.2.1 +sphinx==7.2.6 # via - # -r requirements.in + # -r /tmp/requirements.in # breathe - # exhale # myst-parser # sphinx-rtd-theme -sphinxcontrib-applehelp==1.0.2 + # sphinx-tippy + # sphinxcontrib-applehelp + # sphinxcontrib-bibtex + # sphinxcontrib-devhelp + # sphinxcontrib-htmlhelp + # sphinxcontrib-jquery + # sphinxcontrib-qthelp + # sphinxcontrib-serializinghtml +sphinx-rtd-theme==2.0.0 + # via -r /tmp/requirements.in +sphinx-tippy==0.4.1 + # via -r /tmp/requirements.in +sphinxcontrib-applehelp==1.0.7 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-bibtex==2.6.1 + # via -r /tmp/requirements.in +sphinxcontrib-devhelp==1.0.5 # via sphinx -sphinxcontrib-htmlhelp==2.0.0 +sphinxcontrib-htmlhelp==2.0.4 # via sphinx +sphinxcontrib-jquery==4.1 + # via sphinx-rtd-theme sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==1.0.6 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +sphinxcontrib-serializinghtml==1.1.9 # via sphinx -urllib3==1.26.7 +urllib3==2.1.0 # via requests - -# The following packages are considered to be unsafe in a requirements file: -# setuptools diff --git a/examples/Evolve/AvidaGP-Evo.cpp b/examples/Evolve/AvidaGP-Evo.cpp index 67146dbeb0..c5bfcdb3f5 100644 --- a/examples/Evolve/AvidaGP-Evo.cpp +++ b/examples/Evolve/AvidaGP-Evo.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Evo.cpp + * @file * @brief A test of AvidaGP with World; organisms must find squares of values. */ diff --git a/examples/Evolve/AvidaGP-Mancala.cpp b/examples/Evolve/AvidaGP-Mancala.cpp index bdd749eeaf..4f2202b8d7 100644 --- a/examples/Evolve/AvidaGP-Mancala.cpp +++ b/examples/Evolve/AvidaGP-Mancala.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Mancala.cpp + * @file */ #include diff --git a/examples/Evolve/AvidaGP-Resource.cpp b/examples/Evolve/AvidaGP-Resource.cpp index 9ab13d70eb..8aeb6fdb89 100644 --- a/examples/Evolve/AvidaGP-Resource.cpp +++ b/examples/Evolve/AvidaGP-Resource.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Resource.cpp + * @file * @brief A test of AvidaGP with World; organisms must find squares of values. */ diff --git a/examples/Evolve/AvidaGP-StateGrid.cpp b/examples/Evolve/AvidaGP-StateGrid.cpp index 47d1c0afc8..7f0488ad6f 100644 --- a/examples/Evolve/AvidaGP-StateGrid.cpp +++ b/examples/Evolve/AvidaGP-StateGrid.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-StateGrid.cpp + * @file * @brief A example of using AvidaGP evolving with a StateGrid. * * Example file of AvidaGP-based organisms (called SGOrg here) moving through a state grid, diff --git a/examples/Evolve/AvidaGP-Test.cpp b/examples/Evolve/AvidaGP-Test.cpp index 9a2b46125a..4d411fc9e8 100644 --- a/examples/Evolve/AvidaGP-Test.cpp +++ b/examples/Evolve/AvidaGP-Test.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Test.cpp + * @file * @brief A simple test of AvidaGP with World for copies and mutations. * * A few basic steps to examine AvidaGP organisms in a world. diff --git a/examples/Evolve/DiagnosticNiches.cpp b/examples/Evolve/DiagnosticNiches.cpp index 3857306c26..40aa46cfdf 100644 --- a/examples/Evolve/DiagnosticNiches.cpp +++ b/examples/Evolve/DiagnosticNiches.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file DiagnosticNiches.cpp + * @file */ #include diff --git a/examples/Evolve/EvoSorter.cpp b/examples/Evolve/EvoSorter.cpp index 44c1d2c5a7..127e0b219e 100644 --- a/examples/Evolve/EvoSorter.cpp +++ b/examples/Evolve/EvoSorter.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file EvoSorter.cpp + * @file * @brief This file explores the evolving BitSorter sorting networks. */ diff --git a/examples/Evolve/Fitness_Share_NK.cpp b/examples/Evolve/Fitness_Share_NK.cpp index d3999fc939..cf0e2ad52c 100644 --- a/examples/Evolve/Fitness_Share_NK.cpp +++ b/examples/Evolve/Fitness_Share_NK.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Fitness_Share_NK.cpp + * @file * @brief This file uses the Fitness Sharing functionality defined in evo::World.hpp */ diff --git a/examples/Evolve/Grid.cpp b/examples/Evolve/Grid.cpp index 2f3112c163..e797e787c4 100644 --- a/examples/Evolve/Grid.cpp +++ b/examples/Evolve/Grid.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Grid.cpp + * @file * @brief This file explores the grid options for emp::World.hpp */ diff --git a/examples/Evolve/MAP-Elites.cpp b/examples/Evolve/MAP-Elites.cpp index 8fad578d7d..725d839ea3 100644 --- a/examples/Evolve/MAP-Elites.cpp +++ b/examples/Evolve/MAP-Elites.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file MAP-Elites.cpp + * @file * @brief This file explores the MAP-Elites selection scheme. * * In this example, we will be evolving 4-digit integers. diff --git a/examples/Evolve/NK.cpp b/examples/Evolve/NK.cpp index e6572d8ddd..f5f00ebc94 100644 --- a/examples/Evolve/NK.cpp +++ b/examples/Evolve/NK.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file NK.cpp + * @file * @brief This file explores the template defined in evo::Population.h with an NK landscape. */ diff --git a/examples/Evolve/Pools.cpp b/examples/Evolve/Pools.cpp index 00b67665a8..aa9b5156e1 100644 --- a/examples/Evolve/Pools.cpp +++ b/examples/Evolve/Pools.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Pools.cpp + * @file * @brief This file explores the pool options for emp::World.h */ diff --git a/examples/Evolve/Roulette.cpp b/examples/Evolve/Roulette.cpp index f92bf1d539..f660038c52 100644 --- a/examples/Evolve/Roulette.cpp +++ b/examples/Evolve/Roulette.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Roulette.cpp + * @file * @brief This file explores the RouletteSelect() function */ diff --git a/examples/Evolve/ShrinkPop.cpp b/examples/Evolve/ShrinkPop.cpp index 4be742563c..c6b98e36c8 100644 --- a/examples/Evolve/ShrinkPop.cpp +++ b/examples/Evolve/ShrinkPop.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file ShrinkPop.cpp + * @file * @brief This file explores the grid options for emp::World.hpp */ diff --git a/examples/Evolve/Systematics.cpp b/examples/Evolve/Systematics.cpp index 0fa8bccac3..c0c981c498 100644 --- a/examples/Evolve/Systematics.cpp +++ b/examples/Evolve/Systematics.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Systematics.cpp + * @file * @brief This file explores the grid options for emp::World.hpp */ diff --git a/examples/Evolve/World.cpp b/examples/Evolve/World.cpp index e6454bf79f..4ec0e665b7 100644 --- a/examples/Evolve/World.cpp +++ b/examples/Evolve/World.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file World.cpp + * @file * @brief This file is an example for using the re-vamped World template. */ diff --git a/examples/Evolve/World2.cpp b/examples/Evolve/World2.cpp index 0b1fd4704d..a544c63839 100644 --- a/examples/Evolve/World2.cpp +++ b/examples/Evolve/World2.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file World2.cpp + * @file * @brief This file is an example for using the re-vamped World template. */ diff --git a/examples/OLD/Empower/Empower.cpp b/examples/OLD/Empower/Empower.cpp index 8c16e395d8..39259a77b9 100644 --- a/examples/OLD/Empower/Empower.cpp +++ b/examples/OLD/Empower/Empower.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Empower.cpp + * @file * @brief Some examples code for using emp::Empower */ diff --git a/examples/OLD/Empower/Struct.cpp b/examples/OLD/Empower/Struct.cpp index ffbbbe2f4e..d1ad900127 100644 --- a/examples/OLD/Empower/Struct.cpp +++ b/examples/OLD/Empower/Struct.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Struct.cpp + * @file * @brief Some examples code for using emp::Struct */ diff --git a/examples/OLD/Empower/Type.cpp b/examples/OLD/Empower/Type.cpp index aa0adf7449..1538c36a42 100644 --- a/examples/OLD/Empower/Type.cpp +++ b/examples/OLD/Empower/Type.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Type.cpp + * @file * @brief Some examples code for using emp::Type */ diff --git a/examples/OLD/Empower/TypeManager.cpp b/examples/OLD/Empower/TypeManager.cpp index db70574fcf..91d021b5a9 100644 --- a/examples/OLD/Empower/TypeManager.cpp +++ b/examples/OLD/Empower/TypeManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file TypeManager.cpp + * @file * @brief Some examples code for using emp::TypeManager */ diff --git a/examples/OLD/Random14.cpp b/examples/OLD/Random14.cpp index 18f901bad5..3e3fb85a31 100644 --- a/examples/OLD/Random14.cpp +++ b/examples/OLD/Random14.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Random14.cpp + * @file * @brief Some examples code for using emp::Random */ diff --git a/examples/OLD/hardware/bak/AvidaGP-AltInst.cpp b/examples/OLD/hardware/bak/AvidaGP-AltInst.cpp index c5c1afb92c..eeddb71180 100644 --- a/examples/OLD/hardware/bak/AvidaGP-AltInst.cpp +++ b/examples/OLD/hardware/bak/AvidaGP-AltInst.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-AltInst.cpp + * @file */ #include diff --git a/examples/OLD/hardware/bak/AvidaGP-Evo.cpp b/examples/OLD/hardware/bak/AvidaGP-Evo.cpp index a6b424034e..f21da32f28 100644 --- a/examples/OLD/hardware/bak/AvidaGP-Evo.cpp +++ b/examples/OLD/hardware/bak/AvidaGP-Evo.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Evo.cpp + * @file */ #include diff --git a/examples/OLD/hardware/bak/AvidaGP-Interpreter.cpp b/examples/OLD/hardware/bak/AvidaGP-Interpreter.cpp index e01b02a54b..d168483d02 100644 --- a/examples/OLD/hardware/bak/AvidaGP-Interpreter.cpp +++ b/examples/OLD/hardware/bak/AvidaGP-Interpreter.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file AvidaGP-Interpreter.cpp + * @file */ #include diff --git a/examples/OLD/hardware/bak/AvidaGP-Mancala-EcoEA.cpp b/examples/OLD/hardware/bak/AvidaGP-Mancala-EcoEA.cpp index 5dde29fe1c..ba22b74ef4 100644 --- a/examples/OLD/hardware/bak/AvidaGP-Mancala-EcoEA.cpp +++ b/examples/OLD/hardware/bak/AvidaGP-Mancala-EcoEA.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Mancala-EcoEA.cpp + * @file */ #include diff --git a/examples/OLD/hardware/bak/AvidaGP-Mancala.cpp b/examples/OLD/hardware/bak/AvidaGP-Mancala.cpp index ce7ec274bd..e3fd3ee63d 100644 --- a/examples/OLD/hardware/bak/AvidaGP-Mancala.cpp +++ b/examples/OLD/hardware/bak/AvidaGP-Mancala.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Mancala.cpp + * @file */ #include diff --git a/examples/OLD/hardware/bak/AvidaGP-Sorting.cpp b/examples/OLD/hardware/bak/AvidaGP-Sorting.cpp index 8ffec975ea..f81e8be9dc 100644 --- a/examples/OLD/hardware/bak/AvidaGP-Sorting.cpp +++ b/examples/OLD/hardware/bak/AvidaGP-Sorting.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP-Sorting.cpp + * @file * @brief This is an example file, evolving AvidaGP organisms to sort numbers. */ diff --git a/examples/OLD/hardware/bak/EventDrivenGP-ChgEnv.cpp b/examples/OLD/hardware/bak/EventDrivenGP-ChgEnv.cpp index 61b8216b43..af194778cc 100644 --- a/examples/OLD/hardware/bak/EventDrivenGP-ChgEnv.cpp +++ b/examples/OLD/hardware/bak/EventDrivenGP-ChgEnv.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file EventDrivenGP-ChgEnv.cpp + * @file */ // ------- DEPRECATED ------- diff --git a/examples/OLD/hardware/bak/EventDrivenGP-Roles.cpp b/examples/OLD/hardware/bak/EventDrivenGP-Roles.cpp index 1845b767cc..6d6848d517 100644 --- a/examples/OLD/hardware/bak/EventDrivenGP-Roles.cpp +++ b/examples/OLD/hardware/bak/EventDrivenGP-Roles.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file EventDrivenGP-Roles.cpp + * @file */ // ------- DEPRECATED ------- diff --git a/examples/OLD/hardware/bak/EventDrivenGP.cpp b/examples/OLD/hardware/bak/EventDrivenGP.cpp index b8a5e832cc..3223d4935f 100644 --- a/examples/OLD/hardware/bak/EventDrivenGP.cpp +++ b/examples/OLD/hardware/bak/EventDrivenGP.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file EventDrivenGP.cpp + * @file */ // ------- DEPRECATED ------- diff --git a/examples/OLD/hardware/bak/Play-Mancala.cpp b/examples/OLD/hardware/bak/Play-Mancala.cpp index eed77e90c3..4631ca8cde 100644 --- a/examples/OLD/hardware/bak/Play-Mancala.cpp +++ b/examples/OLD/hardware/bak/Play-Mancala.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Play-Mancala.cpp + * @file */ #include diff --git a/examples/OLD/hardware/bak/RunTournament.cpp b/examples/OLD/hardware/bak/RunTournament.cpp index 582be8e972..8f0040d3f4 100644 --- a/examples/OLD/hardware/bak/RunTournament.cpp +++ b/examples/OLD/hardware/bak/RunTournament.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file RunTournament.cpp + * @file */ #include diff --git a/examples/ProjectTemplate/source/native/project_name.cpp b/examples/ProjectTemplate/source/native/project_name.cpp index e09d1f96c5..40ad9bb919 100644 --- a/examples/ProjectTemplate/source/native/project_name.cpp +++ b/examples/ProjectTemplate/source/native/project_name.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file project_name.cpp + * @file */ // This is the main function for the NATIVE version of this project. diff --git a/examples/ProjectTemplate/source/web/project_name-web.cpp b/examples/ProjectTemplate/source/web/project_name-web.cpp index 8d3a7b0e57..ecacd71221 100644 --- a/examples/ProjectTemplate/source/web/project_name-web.cpp +++ b/examples/ProjectTemplate/source/web/project_name-web.cpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file project_name-web.cpp - * + * @file + * @brief TODO. * WARNING: the Cookiecutter Empirical Project, which you can find at * https://github.com/devosoft/cookiecutter-empirical-project, should be * preferred over ProjectTemplate diff --git a/examples/TO_REPAIR/base/array.cpp b/examples/TO_REPAIR/base/array.cpp index b1a9aff2ee..dab7f1b6ee 100644 --- a/examples/TO_REPAIR/base/array.cpp +++ b/examples/TO_REPAIR/base/array.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file array.cpp + * @file */ #include "emp/base/array.hpp" diff --git a/examples/TO_REPAIR/config/SettingConfig.cpp b/examples/TO_REPAIR/config/SettingConfig.cpp index c8d88fb857..6d2dd0706f 100644 --- a/examples/TO_REPAIR/config/SettingConfig.cpp +++ b/examples/TO_REPAIR/config/SettingConfig.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SettingConfig.cpp + * @file * @brief Some examples code for using emp::SettingConfig */ diff --git a/examples/TO_REPAIR/data/DataMap.cpp b/examples/TO_REPAIR/data/DataMap.cpp index 5dc14400ed..926d4ac92d 100644 --- a/examples/TO_REPAIR/data/DataMap.cpp +++ b/examples/TO_REPAIR/data/DataMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2020. - * - * @file DataMap.cpp + * @file * @brief An example file for using DataMaps */ diff --git a/examples/TO_REPAIR/games/Mancala.cpp b/examples/TO_REPAIR/games/Mancala.cpp index 99a7e141fe..a3379a6a2f 100644 --- a/examples/TO_REPAIR/games/Mancala.cpp +++ b/examples/TO_REPAIR/games/Mancala.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Mancala.cpp + * @file * @brief This is an example file demonstrating Manacala. */ diff --git a/examples/TO_REPAIR/games/Othello.cpp b/examples/TO_REPAIR/games/Othello.cpp index ef2ef7cf39..b11738d83d 100644 --- a/examples/TO_REPAIR/games/Othello.cpp +++ b/examples/TO_REPAIR/games/Othello.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Othello.cpp + * @file * @brief This is an example file demonstrating Othello. */ diff --git a/examples/TO_REPAIR/timing/short_strings.cpp b/examples/TO_REPAIR/timing/short_strings.cpp index 70e881bf54..92ed7ae92c 100644 --- a/examples/TO_REPAIR/timing/short_strings.cpp +++ b/examples/TO_REPAIR/timing/short_strings.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file short_strings.cpp + * @file * @brief Code comparing various methods of accessing entries in an unsorted_map. * * We are comparing the timings for accessing an unsorted map using: diff --git a/examples/base/Ptr.cpp b/examples/base/Ptr.cpp index 797ba6f111..d9a0bee5d1 100644 --- a/examples/base/Ptr.cpp +++ b/examples/base/Ptr.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file Ptr.cpp + * @file * @brief An example file for using emp::Ptr. */ diff --git a/examples/base/assert.cpp b/examples/base/assert.cpp index 854133a227..17ff725b69 100644 --- a/examples/base/assert.cpp +++ b/examples/base/assert.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2022. - * - * @file assert.cpp + * @file * @brief Some examples code demonstrating use of the error system. */ diff --git a/examples/base/errors.cpp b/examples/base/errors.cpp index f22623fc56..d88e01a0a0 100644 --- a/examples/base/errors.cpp +++ b/examples/base/errors.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file errors.cpp + * @file * @brief Some examples code demonstrating use of the error system. */ diff --git a/examples/base/map.cpp b/examples/base/map.cpp index 33e89a27ae..47907c08bc 100644 --- a/examples/base/map.cpp +++ b/examples/base/map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2020 - * - * @file map.cpp + * @file */ #include diff --git a/examples/base/unordered_map.cpp b/examples/base/unordered_map.cpp index a5793065b1..8b618532ee 100644 --- a/examples/base/unordered_map.cpp +++ b/examples/base/unordered_map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file unordered_map.cpp + * @file */ #include diff --git a/examples/base/vector.cpp b/examples/base/vector.cpp index 155bb9c10e..51de1ded9d 100644 --- a/examples/base/vector.cpp +++ b/examples/base/vector.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file vector.cpp + * @file */ #include diff --git a/examples/bits/BitSet.cpp b/examples/bits/BitSet.cpp index 1ead5b037c..6711e27b19 100644 --- a/examples/bits/BitSet.cpp +++ b/examples/bits/BitSet.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file BitSet.cpp + * @file * @brief Some example code for using emp::BitSet */ diff --git a/examples/bits/BitVector.cpp b/examples/bits/BitVector.cpp index bee2f6d069..f9325c51d8 100644 --- a/examples/bits/BitVector.cpp +++ b/examples/bits/BitVector.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file BitVector.cpp + * @file * @brief Some example code for using emp::Ptr */ diff --git a/examples/compiler/DFA.cpp b/examples/compiler/DFA.cpp index 17c25a6d1d..04ff42284b 100644 --- a/examples/compiler/DFA.cpp +++ b/examples/compiler/DFA.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file DFA.cpp + * @file * @brief Some examples code for using emp::DFA */ diff --git a/examples/compiler/Lexer.cpp b/examples/compiler/Lexer.cpp index 15c577ae14..efcac45c27 100644 --- a/examples/compiler/Lexer.cpp +++ b/examples/compiler/Lexer.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Lexer.cpp + * @file * @brief Some examples code for using emp::Lexer */ diff --git a/examples/compiler/NFA.cpp b/examples/compiler/NFA.cpp index e62a729998..abd27eed66 100644 --- a/examples/compiler/NFA.cpp +++ b/examples/compiler/NFA.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file NFA.cpp + * @file * @brief Some examples code for using emp::NFA */ diff --git a/examples/compiler/RegEx.cpp b/examples/compiler/RegEx.cpp index 8d7370b5f4..4822cb3bd3 100644 --- a/examples/compiler/RegEx.cpp +++ b/examples/compiler/RegEx.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file RegEx.cpp + * @file * @brief Some examples code for using emp::RegEx */ diff --git a/examples/compiler/lexer_utils.cpp b/examples/compiler/lexer_utils.cpp index 201cba3c33..800662778e 100644 --- a/examples/compiler/lexer_utils.cpp +++ b/examples/compiler/lexer_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file lexer_utils.cpp + * @file * @brief Example code for converting string pattern representations. */ diff --git a/examples/config/SettingCombos.cpp b/examples/config/SettingCombos.cpp index e5ad2cffcb..ef7e75a5bb 100644 --- a/examples/config/SettingCombos.cpp +++ b/examples/config/SettingCombos.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SettingCombos.cpp + * @file * @brief Some examples code for using emp::SettingCombos */ diff --git a/examples/config/config.cpp b/examples/config/config.cpp index ec69f5af17..80e1295213 100644 --- a/examples/config/config.cpp +++ b/examples/config/config.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file config.cpp + * @file */ #include diff --git a/examples/config/config_setup.hpp b/examples/config/config_setup.hpp index 915f754a2d..16a1e5ffa9 100644 --- a/examples/config/config_setup.hpp +++ b/examples/config/config_setup.hpp @@ -1,11 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file config_setup.hpp - * @brief This file provides an example of how to build a configuration class. - * + * @file + * @brief TODO. * To create a new config from scratch, the format is: * EMP_BUILD_CONFIG( CLASS_NAME, OPTIONS... ) * diff --git a/examples/config/namespaces.cpp b/examples/config/namespaces.cpp index 8a5826f9d6..04c9ff3a1f 100644 --- a/examples/config/namespaces.cpp +++ b/examples/config/namespaces.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file namespaces.cpp + * @file */ #include diff --git a/examples/config/test-macro.hpp b/examples/config/test-macro.hpp index 0f4e20a304..554c3b2251 100644 --- a/examples/config/test-macro.hpp +++ b/examples/config/test-macro.hpp @@ -1,11 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file test-macro.hpp - * @brief This is an auto-generated file that defines a set of configuration options. - * To create a new config from scratch, the format is: + * @file + * @brief TODO. * EMP_BUILD_CONFIG( CLASS_NAME, OPTIONS... ) * * To extend an existing config, simply use: diff --git a/examples/control/Action.cpp b/examples/control/Action.cpp index c8d674403d..285094b385 100644 --- a/examples/control/Action.cpp +++ b/examples/control/Action.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Action.cpp + * @file * @brief Some examples code for using emp::Action */ diff --git a/examples/control/ActionManager.cpp b/examples/control/ActionManager.cpp index 62cefe1d83..fd336a5526 100644 --- a/examples/control/ActionManager.cpp +++ b/examples/control/ActionManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file ActionManager.cpp + * @file * @brief Some examples code for using emp::ActionManager */ diff --git a/examples/control/Signal.cpp b/examples/control/Signal.cpp index d589616677..949c8de9e3 100644 --- a/examples/control/Signal.cpp +++ b/examples/control/Signal.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Signal.cpp + * @file * @brief Some examples code for using emp::Signal */ diff --git a/examples/control/SignalControl.cpp b/examples/control/SignalControl.cpp index 3bd7e0ed1f..bc13077dcc 100644 --- a/examples/control/SignalControl.cpp +++ b/examples/control/SignalControl.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file SignalControl.cpp + * @file * @brief Some examples code for using emp::Signal */ diff --git a/examples/data/DataFile.cpp b/examples/data/DataFile.cpp index c4b150eca8..e581fcf9f9 100644 --- a/examples/data/DataFile.cpp +++ b/examples/data/DataFile.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file DataFile.cpp + * @file * @brief Examples for DataFile demonstrating how to generate */ diff --git a/examples/data/DataInterface.cpp b/examples/data/DataInterface.cpp index 2b77cbc308..6c218bb921 100644 --- a/examples/data/DataInterface.cpp +++ b/examples/data/DataInterface.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file DataInterface.cpp + * @file * @brief Examples for DataInterface demonstrating how to track different types of data. */ diff --git a/examples/data/DataManager.cpp b/examples/data/DataManager.cpp index 2dcbeff148..0f30513e5c 100644 --- a/examples/data/DataManager.cpp +++ b/examples/data/DataManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file DataManager.cpp + * @file * @brief Examples for DataNode demonstrating how to track different types of data. */ diff --git a/examples/data/DataNode.cpp b/examples/data/DataNode.cpp index e390f7acdd..6448d18719 100644 --- a/examples/data/DataNode.cpp +++ b/examples/data/DataNode.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file DataNode.cpp + * @file * @brief Examples for DataNode demonstrating how to track different types of data. */ diff --git a/examples/data/Trait.cpp b/examples/data/Trait.cpp index 006fc5598e..6ca8b07262 100644 --- a/examples/data/Trait.cpp +++ b/examples/data/Trait.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Trait.cpp + * @file * @brief An example file for Trait and TraitSet classes. */ diff --git a/examples/data/VarMap.cpp b/examples/data/VarMap.cpp index 2a9ade706b..aa53503dfe 100644 --- a/examples/data/VarMap.cpp +++ b/examples/data/VarMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file VarMap.cpp + * @file * @brief An example file for using VarMap */ diff --git a/examples/datastructs/Cache.cpp b/examples/datastructs/Cache.cpp index eed0eed7cf..40fd243726 100644 --- a/examples/datastructs/Cache.cpp +++ b/examples/datastructs/Cache.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Cache.cpp + * @file * @brief Some examples code for using emp::Cache */ diff --git a/examples/datastructs/IndexMap.cpp b/examples/datastructs/IndexMap.cpp index 5c1f5060bb..e6ae66a068 100644 --- a/examples/datastructs/IndexMap.cpp +++ b/examples/datastructs/IndexMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file IndexMap.cpp + * @file */ #include diff --git a/examples/datastructs/StringMap.cpp b/examples/datastructs/StringMap.cpp index 24105954ab..3a638ceade 100644 --- a/examples/datastructs/StringMap.cpp +++ b/examples/datastructs/StringMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2021 - * - * @file StringMap.cpp + * @file * @brief Some examples code for using emp::StringMap and emp::StringID */ diff --git a/examples/datastructs/TimeQueue.cpp b/examples/datastructs/TimeQueue.cpp index cda4c0a5ed..055f00edc2 100644 --- a/examples/datastructs/TimeQueue.cpp +++ b/examples/datastructs/TimeQueue.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file TimeQueue.cpp + * @file * @brief Some examples code for using emp::TimeQueue */ diff --git a/examples/datastructs/TypeMap.cpp b/examples/datastructs/TypeMap.cpp index c828a06112..01f0bccc5a 100644 --- a/examples/datastructs/TypeMap.cpp +++ b/examples/datastructs/TypeMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file TypeMap.cpp + * @file * @brief Some example code for using emp::BitSet */ diff --git a/examples/datastructs/hash_utils.cpp b/examples/datastructs/hash_utils.cpp index 757169bad6..6489b23ff0 100644 --- a/examples/datastructs/hash_utils.cpp +++ b/examples/datastructs/hash_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file hash_utils.cpp + * @file * @brief Some examples code for using hash_utils.hpp */ diff --git a/examples/datastructs/ra_set.cpp b/examples/datastructs/ra_set.cpp index cfde12939b..c2e0d33eb9 100644 --- a/examples/datastructs/ra_set.cpp +++ b/examples/datastructs/ra_set.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file ra_set.cpp + * @file * @brief Some example code for using emp::ra_set */ diff --git a/examples/datastructs/tuple_utils.cpp b/examples/datastructs/tuple_utils.cpp index 034031223b..3870bc4a09 100644 --- a/examples/datastructs/tuple_utils.cpp +++ b/examples/datastructs/tuple_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file tuple_utils.cpp + * @file * @brief Some examples code for using tuple_utils.hpp */ diff --git a/examples/datastructs/valsort_map.cpp b/examples/datastructs/valsort_map.cpp index a539dbe4f3..bca598d74a 100644 --- a/examples/datastructs/valsort_map.cpp +++ b/examples/datastructs/valsort_map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file valsort_map.cpp + * @file * @brief Some example code for using emp::valsort_map */ diff --git a/examples/datastructs/vector_utils.cpp b/examples/datastructs/vector_utils.cpp index 0dfb1581da..1847d84b3a 100644 --- a/examples/datastructs/vector_utils.cpp +++ b/examples/datastructs/vector_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2020 - * - * @file vector_utils.cpp + * @file * @brief Some examples code for using vector_utils.hpp */ diff --git a/examples/functional/AnyFunction.cpp b/examples/functional/AnyFunction.cpp index 5b6a424606..d251ae01a0 100644 --- a/examples/functional/AnyFunction.cpp +++ b/examples/functional/AnyFunction.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file AnyFunction.cpp + * @file * @brief Some example code for using emp::AnyFunction */ diff --git a/examples/functional/GenericFunction.cpp b/examples/functional/GenericFunction.cpp index 1652eea3e3..268eb5f77c 100644 --- a/examples/functional/GenericFunction.cpp +++ b/examples/functional/GenericFunction.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file GenericFunction.cpp + * @file * @brief Some example code for using emp::GenericFunction */ diff --git a/examples/functional/flex_function.cpp b/examples/functional/flex_function.cpp index e9e705c3ed..a5b7474506 100644 --- a/examples/functional/flex_function.cpp +++ b/examples/functional/flex_function.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file flex_function.cpp + * @file * @brief Some examples code for using emp::flex_function */ diff --git a/examples/functional/memo_function.cpp b/examples/functional/memo_function.cpp index c16450cef5..129236b289 100644 --- a/examples/functional/memo_function.cpp +++ b/examples/functional/memo_function.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file memo_function.cpp + * @file * @brief Some examples code for using emp::memo_function */ diff --git a/examples/geometry/Surface.cpp b/examples/geometry/Surface.cpp index 4a5e39161c..527ec5f0a4 100644 --- a/examples/geometry/Surface.cpp +++ b/examples/geometry/Surface.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Surface.cpp + * @file */ #include diff --git a/examples/hardware/AvidaGP.cpp b/examples/hardware/AvidaGP.cpp index 044628b242..2f0728bd79 100644 --- a/examples/hardware/AvidaGP.cpp +++ b/examples/hardware/AvidaGP.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaGP.cpp + * @file * @brief This is example code for using AvidaGP. */ diff --git a/examples/hardware/BitSorter.cpp b/examples/hardware/BitSorter.cpp index 896ad6cb71..40f75c5330 100644 --- a/examples/hardware/BitSorter.cpp +++ b/examples/hardware/BitSorter.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file BitSorter.cpp + * @file * @brief This is example code for using BitSorter.h */ diff --git a/examples/hardware/LinearCode.cpp b/examples/hardware/LinearCode.cpp index e8deb1002b..a4070142f3 100644 --- a/examples/hardware/LinearCode.cpp +++ b/examples/hardware/LinearCode.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file LinearCode.cpp + * @file * @brief This is example code for using LinearCode.hpp */ diff --git a/examples/hardware/SignalGP.cpp b/examples/hardware/SignalGP.cpp index 0a48013fa7..2ee7e0d5bf 100644 --- a/examples/hardware/SignalGP.cpp +++ b/examples/hardware/SignalGP.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file SignalGP.cpp + * @file * @brief This is example code for using EventDrivenGP (SignalGP). */ diff --git a/examples/io/ContiguousStream.cpp b/examples/io/ContiguousStream.cpp index 360025810e..304b0fa37c 100644 --- a/examples/io/ContiguousStream.cpp +++ b/examples/io/ContiguousStream.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ContiguousStream.cpp + * @file */ #include diff --git a/examples/io/File.cpp b/examples/io/File.cpp index 012180b8e7..a77cfb711a 100644 --- a/examples/io/File.cpp +++ b/examples/io/File.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file File.cpp + * @file * @brief An example file for using File.hpp */ @@ -29,31 +30,31 @@ int main() spreadsheet.Write(std::cout); - emp::vector first_col = spreadsheet.ExtractCol(); + emp::vector first_col = spreadsheet.ExtractCol(); std::cout << "\nAfter column is extracted:" << std::endl; spreadsheet.Write(std::cout); - std::cout << "Extracted column: " << emp::to_string(first_col) << std::endl; + std::cout << "Extracted column: " << emp::MakeString(first_col) << std::endl; emp::vector second_col = spreadsheet.ExtractColAs(); std::cout << "\nAfter another column is extracted as size_t:" << std::endl; spreadsheet.Write(std::cout); - std::cout << "Extracted column: " << emp::to_string(second_col) << std::endl; + std::cout << "Extracted column: " << emp::MakeString(second_col) << std::endl; - emp::vector first_row = spreadsheet.ExtractRow(); + emp::vector first_row = spreadsheet.ExtractRow(); std::cout << "\nAfter a row is extracted:" << std::endl; spreadsheet.Write(std::cout); - std::cout << "Extracted row: " << emp::to_string(first_row) << std::endl; + std::cout << "Extracted row: " << emp::MakeString(first_row) << std::endl; emp::vector second_row = spreadsheet.ExtractRowAs(); std::cout << "\nAfter a row is extracted as size_t:" << std::endl; spreadsheet.Write(std::cout); - std::cout << "Extracted row: " << emp::to_string(second_row) << std::endl; + std::cout << "Extracted row: " << emp::MakeString(second_row) << std::endl; spreadsheet.Append("1000,1001,1002,1003"); auto full_data = spreadsheet.ToData(); std::cout << "\nAfter all remaining data is extracted as size_t:" << std::endl; spreadsheet.Write(std::cout); - std::cout << "Extracted data: " << emp::to_string(full_data) << std::endl; + std::cout << "Extracted data: " << emp::MakeString(full_data) << std::endl; } diff --git a/examples/io/StreamManager.cpp b/examples/io/StreamManager.cpp index 42e2b88653..67238c5d62 100644 --- a/examples/io/StreamManager.cpp +++ b/examples/io/StreamManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file StreamManager.cpp + * @file * @brief An example file for using StreamManager.hpp */ diff --git a/examples/math/CombinedBinomialDistribution.cpp b/examples/math/CombinedBinomialDistribution.cpp index f053aba8a6..3e43fab36c 100644 --- a/examples/math/CombinedBinomialDistribution.cpp +++ b/examples/math/CombinedBinomialDistribution.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022-2022 - * - * @file CombinedBinomialDistribution.cpp + * @file * @brief Some examples code for using emp::CombinedBinomialDistribution */ diff --git a/examples/math/Distribution.cpp b/examples/math/Distribution.cpp index f6fd090659..f15dda9900 100644 --- a/examples/math/Distribution.cpp +++ b/examples/math/Distribution.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2020 - * - * @file Distribution.cpp + * @file * @brief Some examples code for using emp::Distribution and derived classes. */ diff --git a/examples/math/Random.cpp b/examples/math/Random.cpp index 7e6d626159..7f99022976 100644 --- a/examples/math/Random.cpp +++ b/examples/math/Random.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Random.cpp + * @file * @brief Some examples code for using emp::Random */ diff --git a/examples/math/Range.cpp b/examples/math/Range.cpp index c9ed443b97..6a62e57987 100644 --- a/examples/math/Range.cpp +++ b/examples/math/Range.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Range.cpp + * @file */ #include @@ -18,7 +19,7 @@ int main() std::cout << "Upper = " << range.GetUpper() << std::endl; for (int i = 10; i < 40; i += 5) { - std::cout << "Value " << i << " valid = " << range.Valid(i) << std::endl; + std::cout << "Value " << i << " valid = " << range.Has(i) << std::endl; } for (size_t s = 4; s <= 8; s++) { diff --git a/examples/math/combos.cpp b/examples/math/combos.cpp index d65709a586..5731417daa 100644 --- a/examples/math/combos.cpp +++ b/examples/math/combos.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file combos.cpp + * @file * @brief Example code for emp::ComboIDs class, emp::ComboGenerator class, and emp::combos function. */ diff --git a/examples/math/constants.cpp b/examples/math/constants.cpp index 9ca1e511fb..fa13464aec 100644 --- a/examples/math/constants.cpp +++ b/examples/math/constants.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file constants.cpp + * @file */ #include diff --git a/examples/math/info_theory.cpp b/examples/math/info_theory.cpp index 02092df03b..d6df8a7190 100644 --- a/examples/math/info_theory.cpp +++ b/examples/math/info_theory.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file info_theory.cpp + * @file * @brief Some examples code for using info theory tools. */ diff --git a/examples/math/math.cpp b/examples/math/math.cpp index 3fbf096160..ab376eb444 100644 --- a/examples/math/math.cpp +++ b/examples/math/math.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file math.cpp + * @file * @brief Some examples code for using math functions. */ diff --git a/examples/math/stats.cpp b/examples/math/stats.cpp index f39fc4b941..67e754c89d 100644 --- a/examples/math/stats.cpp +++ b/examples/math/stats.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file stats.cpp + * @file */ #include diff --git a/examples/meta/ConceptWrapper.cpp b/examples/meta/ConceptWrapper.cpp index 00d11f4a07..0a9d4b3a1b 100644 --- a/examples/meta/ConceptWrapper.cpp +++ b/examples/meta/ConceptWrapper.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file ConceptWrapper.cpp + * @file * @brief Some examples code for using emp::ConceptWrapper template */ diff --git a/examples/meta/TypePack.cpp b/examples/meta/TypePack.cpp index 87b8d43ccb..134a3f0f0a 100644 --- a/examples/meta/TypePack.cpp +++ b/examples/meta/TypePack.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019 - * - * @file TypePack.cpp + * @file * @brief Some examples of code using reflection techniques. */ diff --git a/examples/meta/ValPack.cpp b/examples/meta/ValPack.cpp index ee5aaac084..3f693c4d71 100644 --- a/examples/meta/ValPack.cpp +++ b/examples/meta/ValPack.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file ValPack.cpp + * @file * @brief Some example code for using ValPack */ diff --git a/examples/meta/macros.cpp b/examples/meta/macros.cpp index a0ced5e11b..4445e24e13 100644 --- a/examples/meta/macros.cpp +++ b/examples/meta/macros.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file macros.cpp + * @file */ #include diff --git a/examples/meta/meta.cpp b/examples/meta/meta.cpp index 0061e8c6a6..ddced80d41 100644 --- a/examples/meta/meta.cpp +++ b/examples/meta/meta.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file meta.cpp + * @file */ #include diff --git a/examples/meta/reflection.cpp b/examples/meta/reflection.cpp index 1a834b459b..5988839d57 100644 --- a/examples/meta/reflection.cpp +++ b/examples/meta/reflection.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file reflection.cpp + * @file * @brief Some examples of code using reflection techniques. */ diff --git a/examples/prefab/Card.cpp b/examples/prefab/Card.cpp index ffe857cf6f..936c6905f3 100644 --- a/examples/prefab/Card.cpp +++ b/examples/prefab/Card.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Card.cpp + * @file */ #include diff --git a/examples/prefab/CodeBlock.cpp b/examples/prefab/CodeBlock.cpp index 550447de4e..86d3df46d2 100644 --- a/examples/prefab/CodeBlock.cpp +++ b/examples/prefab/CodeBlock.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file CodeBlock.cpp + * @file */ #include diff --git a/examples/prefab/Collapse.cpp b/examples/prefab/Collapse.cpp index fc75853a11..89b0a4a473 100644 --- a/examples/prefab/Collapse.cpp +++ b/examples/prefab/Collapse.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Collapse.cpp + * @file */ #include diff --git a/examples/prefab/CommentBox.cpp b/examples/prefab/CommentBox.cpp index 1bc5324c75..5b9aba862e 100644 --- a/examples/prefab/CommentBox.cpp +++ b/examples/prefab/CommentBox.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file CommentBox.cpp + * @file */ #include diff --git a/examples/prefab/ConfigPanel.cpp b/examples/prefab/ConfigPanel.cpp index 46aab2197d..b93b4cfcf7 100644 --- a/examples/prefab/ConfigPanel.cpp +++ b/examples/prefab/ConfigPanel.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file ConfigPanel.cpp + * @file */ #include diff --git a/examples/prefab/FontAwesomeIcon.cpp b/examples/prefab/FontAwesomeIcon.cpp index b8cb828d01..1ba170baa9 100644 --- a/examples/prefab/FontAwesomeIcon.cpp +++ b/examples/prefab/FontAwesomeIcon.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file FontAwesomeIcon.cpp + * @file */ #include diff --git a/examples/prefab/LoadingIcon.cpp b/examples/prefab/LoadingIcon.cpp index e6ae836fee..d1f8b2753e 100644 --- a/examples/prefab/LoadingIcon.cpp +++ b/examples/prefab/LoadingIcon.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file LoadingIcon.cpp + * @file */ #include diff --git a/examples/prefab/LoadingModal.cpp b/examples/prefab/LoadingModal.cpp index e93293c64e..7cdc3bac86 100644 --- a/examples/prefab/LoadingModal.cpp +++ b/examples/prefab/LoadingModal.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file LoadingModal.cpp + * @file */ #include diff --git a/examples/prefab/Modal.cpp b/examples/prefab/Modal.cpp index 3de710d89a..61f761217a 100644 --- a/examples/prefab/Modal.cpp +++ b/examples/prefab/Modal.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Modal.cpp + * @file */ #include diff --git a/examples/prefab/ReadoutPanel.cpp b/examples/prefab/ReadoutPanel.cpp index c34a1620a9..5da9683d1a 100644 --- a/examples/prefab/ReadoutPanel.cpp +++ b/examples/prefab/ReadoutPanel.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ReadoutPanel.cpp + * @file */ #include "emp/math/Random.hpp" diff --git a/examples/prefab/ToggleSwitch.cpp b/examples/prefab/ToggleSwitch.cpp index d0c9038a3f..332f2d6d14 100644 --- a/examples/prefab/ToggleSwitch.cpp +++ b/examples/prefab/ToggleSwitch.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: ,020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date ,020 - * - * @file ToggleSwitch.cpp + * @file */ #include diff --git a/examples/prefab/assets/SampleConfig.hpp b/examples/prefab/assets/SampleConfig.hpp index f4bfaa44b7..7789620c81 100644 --- a/examples/prefab/assets/SampleConfig.hpp +++ b/examples/prefab/assets/SampleConfig.hpp @@ -1,9 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SampleConfig.hpp + * @file + * @brief TODO. * @note Adapted from Emily's memic_model project * https://github.com/emilydolson/memic_model */ diff --git a/examples/scholar/Citation.cpp b/examples/scholar/Citation.cpp index 46a1eeda5e..df35b48f83 100644 --- a/examples/scholar/Citation.cpp +++ b/examples/scholar/Citation.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Citation.cpp + * @file */ #include diff --git a/examples/testing/ExampleFail.cpp b/examples/testing/ExampleFail.cpp index cb8f9d8b06..15f50c5d14 100644 --- a/examples/testing/ExampleFail.cpp +++ b/examples/testing/ExampleFail.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file ExampleFail.cpp + * @file * @brief An example file to show what FAILING unit tests look like, with commentary. */ diff --git a/examples/testing/ExampleFail2.cpp b/examples/testing/ExampleFail2.cpp index 27d722da48..131e62fc0d 100644 --- a/examples/testing/ExampleFail2.cpp +++ b/examples/testing/ExampleFail2.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file ExampleFail2.cpp + * @file * @brief An second example file to show what a single FAILING unit test looks like. */ diff --git a/examples/testing/ExamplePass.cpp b/examples/testing/ExamplePass.cpp index 573c156248..b6b2b6933b 100644 --- a/examples/testing/ExamplePass.cpp +++ b/examples/testing/ExamplePass.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file ExamplePass.cpp + * @file * @brief An example file to show what PASSING unit tests look like, with commentary. * * Unit tests can be built easily, with a good bit of flexibility, as described below. diff --git a/examples/testing/Template.cpp b/examples/testing/Template.cpp index 1ce482aa7c..11c49f3081 100644 --- a/examples/testing/Template.cpp +++ b/examples/testing/Template.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Template.cpp + * @file * @brief A starting point for writing unit tests. */ diff --git a/examples/timing/Binomial.cpp b/examples/timing/Binomial.cpp index f69cfa2e9e..e5e31b1bb8 100644 --- a/examples/timing/Binomial.cpp +++ b/examples/timing/Binomial.cpp @@ -1,10 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file Binomial.cpp - * + * @file */ #include diff --git a/examples/timing/IndexMap.cpp b/examples/timing/IndexMap.cpp index 3748288922..080dab3ffc 100644 --- a/examples/timing/IndexMap.cpp +++ b/examples/timing/IndexMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file IndexMap.cpp + * @file * @brief Comparing the ordered versus unordered versions of IndexMap */ diff --git a/examples/timing/Othello.cpp b/examples/timing/Othello.cpp index a89544b996..b88f18b45c 100644 --- a/examples/timing/Othello.cpp +++ b/examples/timing/Othello.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Othello.cpp + * @file * @brief Code examining the speed of an Othello board. */ diff --git a/examples/timing/Random_timings.cpp b/examples/timing/Random_timings.cpp index a56ba0808d..c768c6b221 100644 --- a/examples/timing/Random_timings.cpp +++ b/examples/timing/Random_timings.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Random_timings.cpp + * @file * @brief Some code testing the speed of random operations. */ diff --git a/examples/timing/bit_timings.cpp b/examples/timing/bit_timings.cpp index c6a62a011c..1874dfbd35 100644 --- a/examples/timing/bit_timings.cpp +++ b/examples/timing/bit_timings.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2021 - * - * @file bit_timings.cpp + * @file * @brief Some code testing the speed of operations on BitSet and BitVector. */ @@ -61,8 +62,8 @@ struct SpeedTester_impl : public SpeedTester_impl, OBJ_COUNT > bs_objs; - emp::array< emp::BitVector, OBJ_COUNT > bv_objs; + emp::array< emp::old::BitSet, OBJ_COUNT > bs_objs; + emp::array< emp::old::BitVector, OBJ_COUNT > bv_objs; using base_t = SpeedTester_impl; diff --git a/examples/timing/pointers.cpp b/examples/timing/pointers.cpp index aea6ca11c2..9f82aa9191 100644 --- a/examples/timing/pointers.cpp +++ b/examples/timing/pointers.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file pointers.cpp + * @file * @brief Some code comparing T*, emp::Ptr, and std::shared_ptr * * We are comparing the timings and code complexity for creating a series of N pointers, diff --git a/examples/tools/TypeTracker.cpp b/examples/tools/TypeTracker.cpp index 0c8255a8df..00c341b286 100644 --- a/examples/tools/TypeTracker.cpp +++ b/examples/tools/TypeTracker.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file TypeTracker.cpp + * @file * @brief Some example code for using TypeTracker */ diff --git a/examples/tools/attrs.cpp b/examples/tools/attrs.cpp index 81743fdb66..d16b25c25a 100644 --- a/examples/tools/attrs.cpp +++ b/examples/tools/attrs.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file attrs.cpp + * @file */ #include diff --git a/examples/web/Animate.cpp b/examples/web/Animate.cpp index f2d9ce8c84..de506c46e8 100644 --- a/examples/web/Animate.cpp +++ b/examples/web/Animate.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Animate.cpp + * @file */ #include "emp/math/Random.hpp" diff --git a/examples/web/Animate2.cpp b/examples/web/Animate2.cpp index cf5f6f1457..ca707d9df3 100644 --- a/examples/web/Animate2.cpp +++ b/examples/web/Animate2.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Animate2.cpp + * @file */ #include "emp/math/Random.hpp" diff --git a/examples/web/Attributes.cpp b/examples/web/Attributes.cpp index 744758e2c5..b5797e0ac0 100644 --- a/examples/web/Attributes.cpp +++ b/examples/web/Attributes.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Attributes.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/examples/web/Canvas.cpp b/examples/web/Canvas.cpp index e4cfbf14be..dcd619ef50 100644 --- a/examples/web/Canvas.cpp +++ b/examples/web/Canvas.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Canvas.cpp + * @file */ #include "emp/math/Random.hpp" diff --git a/examples/web/DP.cpp b/examples/web/DP.cpp index 044d86175e..ad2248fc44 100644 --- a/examples/web/DP.cpp +++ b/examples/web/DP.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file DP.cpp + * @file */ #include diff --git a/examples/web/Div.cpp b/examples/web/Div.cpp index e1b5d5ee7d..48a9a983c1 100644 --- a/examples/web/Div.cpp +++ b/examples/web/Div.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Div.cpp + * @file */ #include "emp/web/commands.hpp" diff --git a/examples/web/Example.cpp b/examples/web/Example.cpp index c67b8e24e8..83ad6e28e1 100644 --- a/examples/web/Example.cpp +++ b/examples/web/Example.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file Example.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/examples/web/Font.cpp b/examples/web/Font.cpp index 04b0a7befb..a324fcd3cd 100644 --- a/examples/web/Font.cpp +++ b/examples/web/Font.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Font.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/examples/web/Graph.cpp b/examples/web/Graph.cpp index dba2229b2b..23f698104a 100644 --- a/examples/web/Graph.cpp +++ b/examples/web/Graph.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Graph.cpp + * @file */ #include "emp/base/vector.hpp" diff --git a/examples/web/Hello.cpp b/examples/web/Hello.cpp index 272676a5ff..69278aeca2 100644 --- a/examples/web/Hello.cpp +++ b/examples/web/Hello.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file Hello.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/examples/web/Image.cpp b/examples/web/Image.cpp index 5d9e8da769..2d1ab1469b 100644 --- a/examples/web/Image.cpp +++ b/examples/web/Image.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Image.cpp + * @file */ #include "emp/math/Random.hpp" diff --git a/examples/web/RPS.cpp b/examples/web/RPS.cpp index 374031113f..5a848f91e1 100644 --- a/examples/web/RPS.cpp +++ b/examples/web/RPS.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file RPS.cpp + * @file */ #include "emp/geometry/Surface.hpp" diff --git a/examples/web/Sudoku.cpp b/examples/web/Sudoku.cpp index 66e29cfac3..664296e47a 100644 --- a/examples/web/Sudoku.cpp +++ b/examples/web/Sudoku.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Sudoku.cpp + * @file */ #include "emp/base/vector.hpp" diff --git a/examples/web/Table.cpp b/examples/web/Table.cpp index f1622a96fc..5df3900c90 100644 --- a/examples/web/Table.cpp +++ b/examples/web/Table.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Table.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/examples/web/TextArea.cpp b/examples/web/TextArea.cpp index 7abbc1f692..4855d6ae84 100644 --- a/examples/web/TextArea.cpp +++ b/examples/web/TextArea.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file TextArea.cpp + * @file */ #include "emp/web/web.hpp" diff --git a/examples/web/Tween.cpp b/examples/web/Tween.cpp index e60fafb468..e603ae2604 100644 --- a/examples/web/Tween.cpp +++ b/examples/web/Tween.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Tween.cpp + * @file */ #include "emp/web/Tween.hpp" diff --git a/examples/web/Web.cpp b/examples/web/Web.cpp index df55f48ec5..e4e7474664 100644 --- a/examples/web/Web.cpp +++ b/examples/web/Web.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Web.cpp + * @file */ #include "emp/debug/alert.hpp" diff --git a/examples/web/assert.cpp b/examples/web/assert.cpp index a09aacc51e..4bfc6e36f5 100644 --- a/examples/web/assert.cpp +++ b/examples/web/assert.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2022. - * - * @file assert.cpp + * @file */ #include "emp/base/assert.hpp" diff --git a/examples/web/keypress.cpp b/examples/web/keypress.cpp index 30a53ecd6e..c5528fd09b 100644 --- a/examples/web/keypress.cpp +++ b/examples/web/keypress.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file keypress.cpp + * @file */ #include "emp/web/KeypressManager.hpp" diff --git a/include/emp/Evolve/NK-const.hpp b/include/emp/Evolve/NK-const.hpp index 868116ead8..3ec437c9c4 100644 --- a/include/emp/Evolve/NK-const.hpp +++ b/include/emp/Evolve/NK-const.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file NK-const.hpp + * @file * @brief This file provides code to build NK landscapes, setup at compile time.. * * Knowing the size of N and K at compile time allow for slightly more optimized code, at the @@ -14,6 +15,7 @@ #define EMP_EVOLVE_NK_CONST_HPP_INCLUDE #include +#include #include "../base/assert.hpp" #include "../bits/BitSet.hpp" @@ -92,7 +94,7 @@ namespace evo { /// Get the fitness of a whole bitstring double GetFitness(const BitSet & genome) const { // Create a double-length genome to easily handle wrap-around. - BitSet genome2( genome.template Export() ); + BitSet genome2( genome.template ExportArray() ); genome2 |= (genome2 << N); double total = 0.0; diff --git a/include/emp/Evolve/NK.hpp b/include/emp/Evolve/NK.hpp index f205c2bd30..5a45a34335 100644 --- a/include/emp/Evolve/NK.hpp +++ b/include/emp/Evolve/NK.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file NK.hpp + * @file * @brief This file provides code to build NK-based algorithms. * * Two version of landscapes are provided. NKLandscape pre-calculates the entire landscape, for @@ -19,6 +20,7 @@ #define EMP_EVOLVE_NK_HPP_INCLUDE #include +#include #include "../base/vector.hpp" #include "../bits/BitVector.hpp" diff --git a/include/emp/Evolve/OEE.hpp b/include/emp/Evolve/OEE.hpp index ceb9f619a9..1342dedf91 100644 --- a/include/emp/Evolve/OEE.hpp +++ b/include/emp/Evolve/OEE.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file OEE.hpp + * @file * @brief TODO. */ @@ -11,6 +12,7 @@ #define EMP_EVOLVE_OEE_HPP_INCLUDE #include +#include #include "../base/Ptr.hpp" #include "../base/vector.hpp" diff --git a/include/emp/Evolve/OrgInterface.hpp b/include/emp/Evolve/OrgInterface.hpp index a7ebf9945f..513bd4bfca 100644 --- a/include/emp/Evolve/OrgInterface.hpp +++ b/include/emp/Evolve/OrgInterface.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file OrgInterface.hpp + * @file * @brief An interface between an organism and the outside world. * @note Status: PLANNING */ diff --git a/include/emp/Evolve/Resource.hpp b/include/emp/Evolve/Resource.hpp index 3d4028a504..36bd2dd031 100644 --- a/include/emp/Evolve/Resource.hpp +++ b/include/emp/Evolve/Resource.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Resource.hpp + * @file * @brief Implement resource-based selection. * * @@ -15,6 +16,7 @@ #ifndef EMP_EVOLVE_RESOURCE_HPP_INCLUDE #define EMP_EVOLVE_RESOURCE_HPP_INCLUDE +#include #include "World.hpp" diff --git a/include/emp/Evolve/StateGrid.hpp b/include/emp/Evolve/StateGrid.hpp index a779e9fbce..202e6a7a6b 100644 --- a/include/emp/Evolve/StateGrid.hpp +++ b/include/emp/Evolve/StateGrid.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018. - * - * @file StateGrid.hpp + * @file * @brief StateGrid maintains a rectilinear grid that agents can traverse. * * State grids are a matrix of values, representing states of a 2D environment that an organism @@ -21,6 +22,7 @@ #include +#include #include #include "../base/assert.hpp" diff --git a/include/emp/Evolve/SystematicsAnalysis.hpp b/include/emp/Evolve/SystematicsAnalysis.hpp index 6d0d71e16c..185a224eb7 100644 --- a/include/emp/Evolve/SystematicsAnalysis.hpp +++ b/include/emp/Evolve/SystematicsAnalysis.hpp @@ -1,10 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file SystematicsAnalysis.hpp + * @file * @brief TODO. + * */ #ifndef EMP_EVOLVE_SYSTEMATICSANALYSIS_HPP_INCLUDE @@ -12,29 +14,24 @@ #include "../base/Ptr.hpp" -// Mutation info functions. Assumes each taxon has a struct containing an unordered map -// with keys that are strings indicating types of mutations and keys that are numbers -// indicating the number of that type of mutation that occurred to make this taxon from -// the parent. - namespace emp { /// @returns the taxon with the highest fitness out of any active taxon /// in the given systematics manager. + /// @tparam systematics_t The type of the systematics manager containing the phylogeny to analyze. /// @param s the systematics manager to search in. Must have more than 0 active taxa. template Ptr FindDominant(systematics_t & s) { - emp_assert(s.GetNumActive() > 0 && "Trying to call FindDominant on empty population"); - double best = (*(s.GetActive().begin()))->GetData().GetFitness(); - Ptr best_tax = (*(s.GetActive().begin())); + double best = -999999; + Ptr best_tax = nullptr; for (Ptr tax : s.GetActive()) { double f = tax->GetData().GetFitness(); - if (f > best) { - best = f; - best_tax = tax; - } + if (f > best) { + best = f; + best_tax = tax; } - return best_tax; + } + return best_tax; } /// Returns the total number of ancestor taxa in \c taxon 's lineage. @@ -56,9 +53,13 @@ namespace emp { /// occurred along \c taxon 's lineage. (Different from CountMuts in /// that CountMuts sums them whereas CountMutSteps would count two /// simultaneous mutations of the same type as one event) + /// Assumes each taxon has a struct containing an unordered map + /// with keys that are strings indicating types of mutations and keys that are numbers + /// indicating the number of that type of mutation that occurred to make this taxon from + /// the parent. /// @param type string corresponding to a type of mutation. /// Must be in the mut_counts dictionary (i.e. the dictionary - /// passed in when \ref mut_landscape_info::RecordMutation was called) + /// passed in when datastruct::mut_landscape_info::RecordMutation was called) /// @param taxon a pointer to a taxon to count mutation steps for. /// Must have a DATA_TYPE that supports mutation tracking /// (e.g. mut_landscape_info) @@ -74,8 +75,8 @@ namespace emp { return count; } - /// Returns the total number of times a mutation of the types @param types - /// that along @param taxon 's lineage. (Different from CountMuts in + /// Returns the total number of times a mutation of the types \c types + /// that along the given taxon 's lineage. (Different from CountMuts in /// that CountMuts sums them whereas CountMutSteps would count two /// simultaneous mutations of the same type as one event) template @@ -92,8 +93,8 @@ namespace emp { return count; } - /// Returns the total number of mutations of type @param type that occurred - /// along @param taxon 's lineage. + /// Returns the total number of mutations of type \c type that occurred + /// along \c taxon 's lineage. template int CountMuts(Ptr taxon, std::string type="substitution") { int count = 0; @@ -106,8 +107,8 @@ namespace emp { return count; } - /// Returns the total number of mutations of the types @param types that occurred - /// along @param taxon 's lineage. + /// Returns the total number of mutations of the types in \c types that occurred + /// along the given taxon 's lineage. template int CountMuts(Ptr taxon, emp::vector types) { int count = 0; @@ -123,7 +124,7 @@ namespace emp { } /// Returns the total number of deleterious mutational steps that occurred - /// along @param taxon 's lineage. (a change from parent to child taxon counts + /// along the given taxon's lineage. (a change from parent to child taxon counts /// as a single step, regardless of the number of mutations that happened at /// that time point) template @@ -143,7 +144,7 @@ namespace emp { } /// Returns the total number of changes in phenotype that occurred - /// along @param taxon 's lineage. + /// along the given taxon's lineage. template int CountPhenotypeChanges(Ptr taxon) { int count = 0; // Start with current phenotype @@ -161,7 +162,7 @@ namespace emp { } /// Returns the total number of unique phenotypes that occurred - /// along @param taxon 's lineage. + /// along the given taxon's lineage. template int CountUniquePhenotypes(Ptr taxon) { std::setGetData().phenotype)> seen; diff --git a/include/emp/Evolve/World.hpp b/include/emp/Evolve/World.hpp index a4d609f086..762ddca409 100644 --- a/include/emp/Evolve/World.hpp +++ b/include/emp/Evolve/World.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file World.hpp + * @file * @brief Definition of a base class for a World template for use in evolutionary algorithms. * * A definition of the emp::World template, linking in specialized file handling, iterators, @@ -26,6 +27,7 @@ #include #include +#include #include #include "../base/Ptr.hpp" @@ -365,8 +367,8 @@ namespace emp { return *(pop[id]); } - /// Retrieve a const reference to the organsim as the specified x,y coordinates. - /// @CAO: Technically, we should set this up with any number of coordinates. + /// Retrieve a const reference to the organism as the specified x,y coordinates. + // @CAO: Technically, we should set this up with any number of coordinates. ORG & GetOrg(size_t x, size_t y) { return GetOrg(x+y*GetWidth()); } /// Retrive a pointer to the contents of a specified cell; will be nullptr if the cell is @@ -970,7 +972,7 @@ namespace emp { // Track the new systematics info for (Ptr > s : systematics) { - s->AddOrg(*new_org, pos); + s->AddOrg(*new_org, pos, (int) update); } SetupOrg(*new_org, pos, *random_ptr); @@ -994,7 +996,7 @@ namespace emp { } for (Ptr > s : systematics) { - s->RemoveOrgAfterRepro(pos); // Notify systematics about organism removal + s->RemoveOrgAfterRepro(pos, update); // Notify systematics about organism removal } } @@ -1487,13 +1489,6 @@ namespace emp { pop.resize(0); std::swap(pops[0], pops[1]); // Move next pop into place. - // Tell systematics manager to swap next population and population - // Needs to happen here so that you can refer to systematics in - // OnPlacement functions - for (Ptr> s : systematics) { - s->Update(); - } - // Update the active population. num_orgs = 0; for (size_t i = 0; i < pop.size(); i++) { @@ -1503,7 +1498,12 @@ namespace emp { } } - // 3. Handle any data files that need to be printed this update. + // 3. Handle systematics and any data files that need to be printed this update. + + // Tell systematics manager to swap next population and population + for (Ptr> s : systematics) { + s->Update(); + } for (auto file : files) file->Update(update); @@ -1734,7 +1734,6 @@ namespace emp { os << std::endl; } } - } #endif // #ifndef EMP_EVOLVE_WORLD_HPP_INCLUDE diff --git a/include/emp/Evolve/World_iterator.hpp b/include/emp/Evolve/World_iterator.hpp index 852a61f0bb..aff4cc2015 100644 --- a/include/emp/Evolve/World_iterator.hpp +++ b/include/emp/Evolve/World_iterator.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2021. - * - * @file World_iterator.hpp + * @file * @brief This file defines iterators for use with emp::World objects. * * @note Originally called PopulationIterator.h @@ -15,6 +16,8 @@ #ifndef EMP_EVOLVE_WORLD_ITERATOR_HPP_INCLUDE #define EMP_EVOLVE_WORLD_ITERATOR_HPP_INCLUDE +#include + #include "../base/Ptr.hpp" namespace emp { diff --git a/include/emp/Evolve/World_output.hpp b/include/emp/Evolve/World_output.hpp index 79b6cb1949..61ecb81364 100644 --- a/include/emp/Evolve/World_output.hpp +++ b/include/emp/Evolve/World_output.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World_output.hpp + * @file * @brief TODO. * * This file contains functions for adding additional data files to Worlds. @@ -12,6 +13,8 @@ #ifndef EMP_EVOLVE_WORLD_OUTPUT_HPP_INCLUDE #define EMP_EVOLVE_WORLD_OUTPUT_HPP_INCLUDE +#include + #include "../base/vector.hpp" #include "../data/DataFile.hpp" // Helper to determine when specific events should occur. #include "../tools/string_utils.hpp" diff --git a/include/emp/Evolve/World_reflect.hpp b/include/emp/Evolve/World_reflect.hpp index ffb76badd9..768dd1596d 100644 --- a/include/emp/Evolve/World_reflect.hpp +++ b/include/emp/Evolve/World_reflect.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file World_reflect.hpp + * @file * @brief Handle reflection on organisms to setup reasonable defaults in World. * * @note None of the functions defined here should be called from outside the world object; @@ -45,7 +46,7 @@ namespace emp { template void SetDefaultFitFun_impl(WORLD & world, ... ) { - world.SetFitFun( [](ORG & org){ + world.SetFitFun( [](ORG & /* org */){ emp_assert(false, "No default fitness function available"); return 0.0; } ); @@ -71,7 +72,7 @@ namespace emp { template void SetDefaultMutFun_impl(WORLD & world, ... ) { - world.SetMutFun( [](ORG & org, Random & random) { + world.SetMutFun( [](ORG & /* org */, Random & /* random */ ) { emp_assert(false, "No default DoMutations available"); return 0; } ); @@ -103,7 +104,7 @@ namespace emp { template void SetDefaultPrintFun_impl(WORLD & world, ... ) { - world.SetPrintFun( [](ORG & org, std::ostream & os){ + world.SetPrintFun( [](ORG & /* org */, std::ostream & /* os */){ emp_assert(false, "No default Print function available"); } ); } diff --git a/include/emp/Evolve/World_select.hpp b/include/emp/Evolve/World_select.hpp index 65214f7356..01afdfa53a 100644 --- a/include/emp/Evolve/World_select.hpp +++ b/include/emp/Evolve/World_select.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2021. - * - * @file World_select.hpp + * @file * @brief Functions for popular selection methods applied to worlds. */ @@ -12,6 +13,7 @@ #include #include +#include #include "../base/array.hpp" #include "../base/assert.hpp" @@ -186,7 +188,7 @@ namespace emp { /// EACH offspring produced. /// @param world The emp::World object with the organisms to be selected. /// @param fit_funs The set of fitness functions to shuffle for each organism reproduced. - /// @param repro_count How many rounds of repliction should we do. (default 1) + /// @param repro_count How many rounds of replication should we do. (default 1) /// @param max_funs The maximum number of fitness functions to use. (use 0 for all; default) template void LexicaseSelect(World & world, @@ -226,9 +228,9 @@ namespace emp { // Step through the functions in the proper order. cur_orgs = all_orgs; // Start with all of the organisms. - int depth = -1; +// int depth = -1; for (size_t fit_id : order) { - depth++; +// depth++; double max_fit = fitnesses[fit_id][cur_orgs[0]]; next_orgs.push_back(cur_orgs[0]); diff --git a/include/emp/Evolve/World_structure.hpp b/include/emp/Evolve/World_structure.hpp index cc97ec8144..bdf469a5d8 100644 --- a/include/emp/Evolve/World_structure.hpp +++ b/include/emp/Evolve/World_structure.hpp @@ -1,16 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2022. - * - * @file World_structure.hpp + * @file * @brief Functions for popular world structure methods. */ #ifndef EMP_EVOLVE_WORLD_STRUCTURE_HPP_INCLUDE #define EMP_EVOLVE_WORLD_STRUCTURE_HPP_INCLUDE +#include #include +#include #include "../base/array.hpp" #include "../base/assert.hpp" diff --git a/include/emp/base/MapProxy.hpp b/include/emp/base/MapProxy.hpp index 2cb39e889c..446a28ac15 100644 --- a/include/emp/base/MapProxy.hpp +++ b/include/emp/base/MapProxy.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file MapProxy.hpp + * @file * @brief A proxy for indecies returned from any map type to ensure they are initialized. * @note Status: ALPHA */ @@ -107,7 +108,7 @@ namespace emp { operator const T&() const { emp_assert(is_init); return value; } }; - + #ifndef DOXYGEN_SHOULD_SKIP_THIS // Doxygen is getting tripped up by the enable_ifs /// A type trait to determine if a class is a MapProxy template struct is_MapProxy : public std::false_type { }; @@ -115,8 +116,7 @@ namespace emp { struct is_MapProxy> : public std::true_type { }; - // Build externaly binary operators with MapProxy as the second argument. - #ifndef DOXYGEN_SHOULD_SKIP_THIS // Doxygen is getting tripped up by the enable_ifs + // Build external binary operators with MapProxy as the second argument. template () == false>::type* = nullptr> auto operator + (T1 v1, const MapProxy & v2) { return v1 + v2.emp_GetValue(); } template () == false>::type* = nullptr> @@ -158,6 +158,7 @@ namespace emp { #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ } +#ifndef DOXYGEN_SHOULD_SKIP_THIS // A crude, generic printing function for emp::MapProxy. template std::ostream & operator<<(std::ostream & out, const typename emp::MapProxy & p) { @@ -170,5 +171,6 @@ std::istream & operator>>(std::istream & is, typename emp::MapProxy & p) { is >> p.emp_GetValue(); return is; } +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_BASE_MAPPROXY_HPP_INCLUDE diff --git a/include/emp/base/Ptr.hpp b/include/emp/base/Ptr.hpp index db3ff5968b..d5af258de9 100644 --- a/include/emp/base/Ptr.hpp +++ b/include/emp/base/Ptr.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file Ptr.hpp + * @file * @brief A wrapper for pointers that does careful memory tracking (but only in debug mode). * @note Status: BETA * @@ -31,6 +32,7 @@ #define EMP_BASE_PTR_HPP_INCLUDE #include +#include #include #include "assert.hpp" @@ -607,8 +609,8 @@ namespace emp { /// Delete this pointer to an array (must be an array). void DeleteArray() { - emp_assert(id < Tracker().GetNumIDs(), id, "Trying to delete Ptr that we are not responsible for."); emp_assert(ptr, "Trying to delete null Ptr."); + emp_assert(id < Tracker().GetNumIDs(), id, "Trying to delete Ptr that we are not responsible for."); emp_assert(Tracker().IsArrayID(id), id, "Trying to delete non-array pointer as array."); emp_assert(Tracker().IsActive(ptr), id, "Trying to delete inactive pointer (already deleted!)"); if (internal::ptr_debug) std::cout << "Ptr::DeleteArray() : " << ptr << std::endl; diff --git a/include/emp/base/_assert_macros.hpp b/include/emp/base/_assert_macros.hpp index 2e0a456aab..1d24daed43 100644 --- a/include/emp/base/_assert_macros.hpp +++ b/include/emp/base/_assert_macros.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file _assert_macros.hpp + * @file * @brief Helper macros for building proper assert commands. - * @note Status: RELEASE + * Status: RELEASE * */ diff --git a/include/emp/base/_assert_trigger.hpp b/include/emp/base/_assert_trigger.hpp index aaf9316ea4..a586af1e3f 100644 --- a/include/emp/base/_assert_trigger.hpp +++ b/include/emp/base/_assert_trigger.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file _assert_trigger.hpp + * @file * @brief Assert trigger implementation selector. * @note For internal use. */ diff --git a/include/emp/base/_emscripten_assert_trigger.hpp b/include/emp/base/_emscripten_assert_trigger.hpp index 7dcfd867fa..13ed6c6696 100644 --- a/include/emp/base/_emscripten_assert_trigger.hpp +++ b/include/emp/base/_emscripten_assert_trigger.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file _emscripten_assert_trigger.hpp + * @file * @brief Assert trigger implementation. * @note For internal use. */ @@ -13,12 +14,15 @@ #include #include +#include #include #include #include "_is_streamable.hpp" +#ifndef DOXYGEN_SHOULD_SKIP_THIS + namespace emp { static int TripAssert() { @@ -63,4 +67,6 @@ namespace emp { } // namespace emp +#endif /*DOXYGEN_SHOULD_SKIP_THIS*/ + #endif // #ifndef EMP_BASE__EMSCRIPTEN_ASSERT_TRIGGER_HPP_INCLUDE diff --git a/include/emp/base/_emscripten_error_trigger.hpp b/include/emp/base/_emscripten_error_trigger.hpp index 9d6ce0a0f4..0fbc9feed3 100644 --- a/include/emp/base/_emscripten_error_trigger.hpp +++ b/include/emp/base/_emscripten_error_trigger.hpp @@ -1,18 +1,20 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file _emscripten_error_trigger.hpp + * @file * @brief Terminating error trigger implementation. * @note For internal use. - * @TODO Reflect error message to browser (e.g., as an alert) + * @todo Reflect error message to browser (e.g., as an alert) */ #ifndef EMP_BASE__EMSCRIPTEN_ERROR_TRIGGER_HPP_INCLUDE #define EMP_BASE__EMSCRIPTEN_ERROR_TRIGGER_HPP_INCLUDE #include +#include #include namespace emp { diff --git a/include/emp/base/_error_trigger.hpp b/include/emp/base/_error_trigger.hpp index 2e3ca72a1c..b0815eb83d 100644 --- a/include/emp/base/_error_trigger.hpp +++ b/include/emp/base/_error_trigger.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file _error_trigger.hpp + * @file * @brief Error trigger implementation selector * @note For internal use. */ diff --git a/include/emp/base/_is_streamable.hpp b/include/emp/base/_is_streamable.hpp index b4215cca9a..ee5aa908ac 100644 --- a/include/emp/base/_is_streamable.hpp +++ b/include/emp/base/_is_streamable.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file _is_streamable.hpp + * @file * @brief Test at compile time whether a type can be streamed. * @note This header is for internal use to preserve levelization. * Include meta/type_traits.hpp to use is_streamable. diff --git a/include/emp/base/_native_assert_trigger.hpp b/include/emp/base/_native_assert_trigger.hpp index a52c695ae6..205b767499 100644 --- a/include/emp/base/_native_assert_trigger.hpp +++ b/include/emp/base/_native_assert_trigger.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file _native_assert_trigger.hpp - * @brief Native asssert trigger implementation. + * @file + * @brief Native assert trigger implementation. * @note For internal use. */ @@ -13,6 +14,7 @@ #include #include +#include #include #include "_is_streamable.hpp" diff --git a/include/emp/base/_native_error_trigger.hpp b/include/emp/base/_native_error_trigger.hpp index d92305a9bc..0e4951076c 100644 --- a/include/emp/base/_native_error_trigger.hpp +++ b/include/emp/base/_native_error_trigger.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file _native_error_trigger.hpp + * @file * @brief Terminating error trigger implementation. * @note For internal use. */ @@ -12,6 +13,7 @@ #define EMP_BASE__NATIVE_ERROR_TRIGGER_HPP_INCLUDE +#include #include namespace emp { diff --git a/include/emp/base/_tdebug_assert_trigger.hpp b/include/emp/base/_tdebug_assert_trigger.hpp index 10233817c2..25a82aebc7 100644 --- a/include/emp/base/_tdebug_assert_trigger.hpp +++ b/include/emp/base/_tdebug_assert_trigger.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file _tdebug_assert_trigger.hpp + * @file * @brief Non-terminating assert trigger implementation for unit testing. * @note For internal use. */ @@ -11,6 +12,7 @@ #ifndef EMP_BASE__TDEBUG_ASSERT_TRIGGER_HPP_INCLUDE #define EMP_BASE__TDEBUG_ASSERT_TRIGGER_HPP_INCLUDE +#include #include namespace emp { diff --git a/include/emp/base/_tdebug_error_trigger.hpp b/include/emp/base/_tdebug_error_trigger.hpp index 3c174e60c5..b882cbaafe 100644 --- a/include/emp/base/_tdebug_error_trigger.hpp +++ b/include/emp/base/_tdebug_error_trigger.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file _tdebug_error_trigger.hpp + * @file * @brief Non-terminating error trigger implementation for unit testing. * @note For internal use. */ @@ -12,6 +13,7 @@ #define EMP_BASE__TDEBUG_ERROR_TRIGGER_HPP_INCLUDE +#include #include namespace emp { diff --git a/include/emp/base/always_assert.hpp b/include/emp/base/always_assert.hpp index 117581df2e..b77020cdbd 100644 --- a/include/emp/base/always_assert.hpp +++ b/include/emp/base/always_assert.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2021. - * - * @file always_assert.hpp + * @file * @brief A more dynamic replacement for standard library asserts. - * @note Status: RELEASE + * Status: RELEASE * * A replacement for the system-level assert.h, called "emp_always_assert" * Added functionality: @@ -21,7 +22,7 @@ * int a = 6; * emp_always_assert(a==5, a); * - * Unlinke "emp_assert", "emp_always_assert" will trigger an assertion error + * Unlike "emp_assert", "emp_always_assert" will trigger an assertion error * whether compiled in debug mode or not. * */ diff --git a/include/emp/base/always_assert_warning.hpp b/include/emp/base/always_assert_warning.hpp index a80bb1e83e..2e24bb4ff2 100644 --- a/include/emp/base/always_assert_warning.hpp +++ b/include/emp/base/always_assert_warning.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file always_assert_warning.hpp + * @file * @brief A more dynamic replacement for standard library asserts. * @note Status: RELEASE * @@ -20,7 +21,7 @@ * int a = 6; * emp_always_assert(a==5, a); * - * Unlinke "emp_assert_warning", "emp_always_assert_warning" will trigger an + * Unlike "emp_assert_warning", "emp_always_assert_warning" will trigger an * assertion error whether compiled in debug mode or not. */ diff --git a/include/emp/base/array.hpp b/include/emp/base/array.hpp index e8cfd8f482..6659165d76 100644 --- a/include/emp/base/array.hpp +++ b/include/emp/base/array.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file array.hpp + * @file * @brief A drop-in wrapper for std::array; adds on bounds checking in debug mode. - * @note Status: RELEASE + * Status: RELEASE * * If EMP_NDEBUG is set, emp::array is just an alias for std::array. * Otherwise, every time an array is accessed, tests are done to make sure that the @@ -21,6 +22,10 @@ #include #include #include +#include +#include + +#include "../../../third-party/cereal/include/cereal/cereal.hpp" #include "assert.hpp" @@ -44,6 +49,13 @@ namespace emp { using this_t = array_iterator; using array_t = ARRAY_T; + // Iterator traits + using iterator_category = typename std::iterator_traits::iterator_category; + using value_type = typename std::iterator_traits::value_type; + using difference_type = typename std::iterator_traits::difference_type; + using pointer = typename std::iterator_traits::pointer; + using reference = typename std::iterator_traits::reference; + ITERATOR_T it; const array_t * arr_ptr { nullptr }; // Which array was iterator created from? @@ -193,6 +205,9 @@ namespace emp { void emplace_back(ARGS &&... /* args */) { emp_assert(false, "invalid operation for array!"); } + + template + void serialize( Archive & ar ) { ar(_data); } }; @@ -205,7 +220,7 @@ struct std::tuple_size> : public integral_constant { #endif // NDEBUG off - +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { // A crude, generic printing function for arrays. template @@ -219,7 +234,7 @@ namespace std { for (T & x : v) is >> x; return is; } - + #endif // DOXYGEN_SHOULD_SKIP_THIS } #endif // #ifndef EMP_BASE_ARRAY_HPP_INCLUDE diff --git a/include/emp/base/assert.hpp b/include/emp/base/assert.hpp index 67508bfe7b..73e1e92bec 100644 --- a/include/emp/base/assert.hpp +++ b/include/emp/base/assert.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020. - * - * @file assert.hpp + * @file * @brief A more dynamic replacement for standard library asserts. - * @note Status: RELEASE + * Status: RELEASE * * A replacement for the system-level assert.h, called "emp_assert" * Added functionality: diff --git a/include/emp/base/assert_warning.hpp b/include/emp/base/assert_warning.hpp index bdc7363b07..92935f65f5 100644 --- a/include/emp/base/assert_warning.hpp +++ b/include/emp/base/assert_warning.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file assert_warning.hpp + * @file * @brief A non-terminating replacement for standard library asserts. * * A supplement for the system-level assert.h, called "emp_assert_warning" diff --git a/include/emp/base/emscripten_assert.hpp b/include/emp/base/emscripten_assert.hpp index a0cfd21048..6f985b42ae 100644 --- a/include/emp/base/emscripten_assert.hpp +++ b/include/emp/base/emscripten_assert.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file emscripten_assert.hpp + * @file * @brief Assert evaluated only in debug mode with Emscripten. */ @@ -19,6 +20,9 @@ /// emp_emscripten_assert() will not do anything. #define emp_emscripten_assert(...) emp_assert(__VA_ARGS__) #else + /// Require a specified condition to be true if this program was compiled to + /// Javascript with Emscripten. Note: If NDEBUG is defined, + /// emp_emscripten_assert() will not do anything. #define emp_emscripten_assert(...) #endif diff --git a/include/emp/base/error.hpp b/include/emp/base/error.hpp index e2d62f8682..d5ba39fc32 100644 --- a/include/emp/base/error.hpp +++ b/include/emp/base/error.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file error.hpp + * @file * @brief Nearly-universal error, to use in place of emp_assert(false, ...). * Aborts program in both debug and release mode, but does NOT terminate in TDEBUG for testing. */ diff --git a/include/emp/base/errors.hpp b/include/emp/base/errors.hpp index f4ab4e8461..1fa82ff0f7 100644 --- a/include/emp/base/errors.hpp +++ b/include/emp/base/errors.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file errors.hpp + * @file * @brief Tools to help manage various problems in command-line or Emscripten-based applications. * @note Status: ALPHA * @@ -42,9 +43,10 @@ #include #include #include +#include #include -/// If we are in emscripten, make sure to include the header. +// If we are in emscripten, make sure to include the header. #ifdef __EMSCRIPTEN__ #include #endif diff --git a/include/emp/base/map.hpp b/include/emp/base/map.hpp index 7d58125a8d..9c76201b0b 100644 --- a/include/emp/base/map.hpp +++ b/include/emp/base/map.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2020. - * - * @file map.hpp + * @file * @brief A drop-in wrapper for std::map and std:multimap; makes sure we create vars on access. * @note Status: ALPHA * @@ -19,6 +20,7 @@ #include #include +#include #include "assert.hpp" #include "MapProxy.hpp" diff --git a/include/emp/base/notify.hpp b/include/emp/base/notify.hpp index 4af90f1a4e..a795a66e17 100644 --- a/include/emp/base/notify.hpp +++ b/include/emp/base/notify.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file notify.hpp + * @file * @brief Tools to alert users of messages (including errors and warnings) in a consistant manner. * @note Status: ALPHA * @@ -246,10 +247,10 @@ namespace notify { /// Central call to obtain NotifyData singleton. static NotifyData & GetData() { static NotifyData data; return data; } - auto & MessageHandlers() { return GetData().GetHandler(Type::MESSAGE); } - auto & DebugHandlers() { return GetData().GetHandler(Type::DEBUG); } - auto & WarningHandlers() { return GetData().GetHandler(Type::WARNING); } - auto & ErrorHandlers() { return GetData().GetHandler(Type::ERROR); } + inline auto & MessageHandlers() { return GetData().GetHandler(Type::MESSAGE); } + inline auto & DebugHandlers() { return GetData().GetHandler(Type::DEBUG); } + inline auto & WarningHandlers() { return GetData().GetHandler(Type::WARNING); } + inline auto & ErrorHandlers() { return GetData().GetHandler(Type::ERROR); } [[maybe_unused]] static void AddExitHandler(exit_fun_t fun) { GetData().exit_funs.push_back(fun); } [[maybe_unused]] static void ClearExitHandlers() { GetData().exit_funs.resize(0); } @@ -378,7 +379,7 @@ namespace notify { } /// Turn on a particular verbosity category. - [[maybe_unused]] void SetVerbose(std::string id, bool make_active=true) { + [[maybe_unused]] static void SetVerbose(std::string id, bool make_active=true) { GetData().verbose_map[id] = make_active; } diff --git a/include/emp/base/optional.hpp b/include/emp/base/optional.hpp index e0902fb6ed..8592aab555 100644 --- a/include/emp/base/optional.hpp +++ b/include/emp/base/optional.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file optional.hpp + * @file * @brief Audited implementation of std::optional. - * @note Status: RELEASE + * Status: RELEASE * * Drop-in replacements for std::optional. * In debug mode, operator * and operator-> value accesses are checked for undefined behavior. @@ -15,6 +16,7 @@ #define EMP_BASE_OPTIONAL_HPP_INCLUDE #include +#include #include #include @@ -99,6 +101,7 @@ namespace emp { } // namespace emp +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { template @@ -109,7 +112,7 @@ namespace std { }; } // namespace std - +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif #endif // #ifndef EMP_BASE_OPTIONAL_HPP_INCLUDE diff --git a/include/emp/base/unordered_map.hpp b/include/emp/base/unordered_map.hpp index 9b4c4c664a..24142893c4 100644 --- a/include/emp/base/unordered_map.hpp +++ b/include/emp/base/unordered_map.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2020. - * - * @file unordered_map.hpp + * @file * @brief A drop-in wrapper for std::unordered_map and unordered_multi_map; makes sure we create vars on access. * @note Status: ALPHA */ @@ -12,6 +13,7 @@ #define EMP_BASE_UNORDERED_MAP_HPP_INCLUDE #include +#include #include #include "assert.hpp" diff --git a/include/emp/base/vector.hpp b/include/emp/base/vector.hpp index 3baaacad35..c131da6993 100644 --- a/include/emp/base/vector.hpp +++ b/include/emp/base/vector.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019. - * - * @file vector.hpp + * @file * @brief A drop-in wrapper for std::vector; adds on bounds checking in debug mode. * @note Status: BETA * @@ -22,6 +23,7 @@ #include #include +#include #include #include @@ -286,8 +288,13 @@ namespace emp { }; /// Build a specialized debug wrapper for emp::vector + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class vector : public std::vector { + #else + template + class vector { + #endif private: using this_t = emp::vector; using stdv_t = std::vector; diff --git a/include/emp/bits/BitArray.hpp b/include/emp/bits/BitArray.hpp index d045a6c64f..54b5e9ae3a 100644 --- a/include/emp/bits/BitArray.hpp +++ b/include/emp/bits/BitArray.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file BitArray.hpp + * @file * @brief An Array of a fixed number of bits; similar to std::bitset, but with extra bit magic. - * @note Status: RELEASE + * Status: RELEASE * * @todo Some of the functions allow a start bit and end bit; each of these should be checked * to make sure that they will work if the start and end are part of the same byte. One @@ -17,10 +18,12 @@ #include +#include #include #include #include #include +#include #include "../base/assert.hpp" #include "../base/Ptr.hpp" @@ -33,17 +36,21 @@ #include "_bitset_helpers.hpp" #include "bitset_utils.hpp" -namespace emp { +#include "Bits.hpp" // New version of BitArray is in Bits.hpp + +namespace emp::old { /// A fixed-sized (but arbitrarily large) array of bits, and optimizes operations on those bits /// to be as fast as possible. - /// @param NUM_BITS is the fixed number of bits in this BitArray. - /// @param ZERO_LEFT indicates the side that bit zero will be located. + /// @tparam NUM_BITS is the fixed number of bits in this BitArray. + /// @tparam ZERO_LEFT indicates the side that bit zero will be located. template class BitArray { + #ifndef DOXYGEN_SHOULD_SKIP_THIS // make all templated instantiations friends with each other template friend class BitArray; + #endif // DOXYGEN_SHOULD_SKIP_THIS private: using this_t = BitArray; @@ -65,7 +72,7 @@ namespace emp { // Track number of bits in the final field; use 0 if a perfect fit. static constexpr size_t NUM_END_BITS = NUM_BITS & (FIELD_BITS - 1); - /// How many EXTRA bits are leftover in the gap at the end? + // How many EXTRA bits are leftover in the gap at the end? static constexpr size_t END_GAP = NUM_END_BITS ? (FIELD_BITS - NUM_END_BITS) : 0; // Mask to use to clear out any end bits that should be zeroes. @@ -121,10 +128,10 @@ namespace emp { [[nodiscard]] emp::Ptr BytePtr() { return reinterpret_cast(bits); } - /// Helper: call SHIFT with positive number instead + // Helper: call SHIFT with positive number instead void ShiftLeft(const size_t shift_size); - /// Helper for calling SHIFT with negative number + // Helper for calling SHIFT with negative number void ShiftRight(const size_t shift_size); /// Helper: call ROTATE with negative number instead @@ -137,7 +144,7 @@ namespace emp { /// Constructor: Assume all bits set to zero. explicit BitArray(bool init_val=false) noexcept { if (init_val) SetAll(); else Clear(); } - /// Copy constructor from another BitArray + // Copy constructor from another BitArray BitArray(const this_t & _in) noexcept { Copy(_in.bits); } /// Constructor to generate a BitArray from a std::bitset. @@ -290,12 +297,14 @@ namespace emp { // ========= Comparison Operators ========== // + /// Test if two BitArray objects are identical. template [[nodiscard]] bool operator==(const BitArray & in) const; template [[nodiscard]] bool operator!=(const BitArray & in) const { return !(*this == in); } + /// Compare two BitArray objects, based on the associated binary value. template [[nodiscard]] bool operator< (const BitArray & in) const; @@ -647,7 +656,7 @@ namespace emp { /// Compound operator minus... const BitArray & operator-=(const BitArray & ar2) { return SUB_SELF(ar2); } - /// STL COMPATABILITY + /// STL COMPATIBILITY /// A set of functions to allow drop-in replacement with std::bitset. [[nodiscard]] constexpr static size_t size() { return NUM_BITS; } [[nodiscard]] inline bool all() const { return All(); } @@ -720,7 +729,7 @@ namespace emp { return *this; } - + #ifndef DOXYGEN_SHOULD_SKIP_THIS template void BitArray::ShiftLeft(const size_t shift_size) { // If we have only a single field, this operation can be quick. @@ -760,7 +769,7 @@ namespace emp { } - /// Helper for calling SHIFT with negative number + // Helper for calling SHIFT with negative number template void BitArray::ShiftRight(const size_t shift_size) { // If we have only a single field, this operation can be quick. @@ -800,7 +809,7 @@ namespace emp { } } - /// Helper: call ROTATE with negative number + // Helper: call ROTATE with negative number template void BitArray::RotateLeft(const size_t shift_size_raw) { const field_t shift_size = shift_size_raw % NUM_BITS; @@ -812,7 +821,7 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n<>( (-(c+FIELD_BITS-NUM_BITS)) & FIELD_LOG2_MASK )); @@ -884,7 +893,7 @@ namespace emp { } - /// Helper for calling ROTATE with positive number + // Helper for calling ROTATE with positive number template void BitArray::RotateRight(const size_t shift_size_raw) { @@ -898,7 +907,7 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n>>c) | (n<<( (NUM_BITS-c) & FIELD_LOG2_MASK )); @@ -959,14 +968,14 @@ namespace emp { // -------------------- Longer Constructors and bit copying --------------------- - /// Constructor to generate a BitArray from a std::bitset. + // Constructor to generate a BitArray from a std::bitset. template BitArray::BitArray(const std::bitset & bitset) { for (size_t bit{}; bit < NUM_BITS; ++bit) Set( bit, bitset[bit] ); ClearExcessBits(); } - /// Constructor to generate a BitArray from a string of '0's and '1's. + // Constructor to generate a BitArray from a string of '0's and '1's. template BitArray::BitArray(const std::string & bitstring) { @@ -994,7 +1003,7 @@ namespace emp { } } - /// Assignment operator from a std::bitset. + // Assignment operator from a std::bitset. template BitArray & BitArray::operator=(const std::bitset & bitset) & { @@ -1002,7 +1011,7 @@ namespace emp { return *this; } - /// Assignment operator from a string of '0's and '1's. + // Assignment operator from a string of '0's and '1's. template BitArray & BitArray::operator=(const std::string & bitstring) & { @@ -1018,7 +1027,7 @@ namespace emp { } - /// Assign from a BitArray of a different size. + // Assign from a BitArray of a different size. template template BitArray & BitArray::Import( @@ -1064,7 +1073,7 @@ namespace emp { } - /// Convert to a BitArray of a different size. + // Convert to a BitArray of a different size. template template BitArray BitArray::Export(size_t start_bit) const { @@ -1074,7 +1083,7 @@ namespace emp { return out_bits; } - /// For debugging: make sure that there are no obvious problems with a BitArray object. + // For debugging: make sure that there are no obvious problems with a BitArray object. template bool BitArray::OK() const { // Make sure final bits are zeroed out. @@ -1095,7 +1104,7 @@ namespace emp { return (bits[field_id] & (((field_t)1U) << pos_id)) != 0; } - /// Set the bit at a specified index. + // Set the bit at a specified index. template BitArray & BitArray::Set(size_t index, bool value) { emp_assert(index < NUM_BITS); @@ -1109,7 +1118,7 @@ namespace emp { return *this; } - /// Set all bits to one. + // Set all bits to one. template BitArray & BitArray::SetAll() noexcept { for (field_t & x : bits) x = FIELD_ALL; @@ -1118,7 +1127,7 @@ namespace emp { } - /// Flip a single bit + // Flip a single bit template BitArray & BitArray::Toggle(size_t index) { emp_assert(index < NUM_BITS); @@ -1135,7 +1144,7 @@ namespace emp { // ------------------------- Implementations Randomization functions ------------------------- - /// Set all bits randomly, with a 50% probability of being a 0 or 1. + // Set all bits randomly, with a 50% probability of being a 0 or 1. template BitArray & BitArray::Randomize(Random & random) { random.RandFill(BytePtr(), TOTAL_BYTES); @@ -1143,7 +1152,7 @@ namespace emp { return *this; } - /// Set all bits randomly, with probability specified at compile time. + // Set all bits randomly, with probability specified at compile time. template template BitArray & BitArray::RandomizeP(Random & random, @@ -1156,7 +1165,7 @@ namespace emp { } - /// Set all bits randomly, with a given probability of being on. + // Set all bits randomly, with a given probability of being on. template BitArray & BitArray::Randomize(Random & random, const double p, const size_t start_pos, const size_t stop_pos) { @@ -1168,7 +1177,7 @@ namespace emp { return *this; } - /// Set all bits randomly, with a given number of them being on. + // Set all bits randomly, with a given number of them being on. template BitArray & BitArray::ChooseRandom( @@ -1231,7 +1240,7 @@ namespace emp { return *this; } - /// Flip random bits with a given probability. + // Flip random bits with a given probability. // @CAO: Possibly faster to generate a sequence of bits and XORing with them. template BitArray & BitArray::FlipRandom(Random & random, @@ -1248,7 +1257,7 @@ namespace emp { return *this; } - /// Set random bits with a given probability (does not check if already set.) + // Set random bits with a given probability (does not check if already set.) template BitArray & BitArray::SetRandom(Random & random, const double p, @@ -1264,7 +1273,7 @@ namespace emp { return *this; } - /// Unset random bits with a given probability (does not check if already zero.) + // Unset random bits with a given probability (does not check if already zero.) template BitArray & BitArray::ClearRandom(Random & random, const double p, @@ -1280,7 +1289,7 @@ namespace emp { return *this; } - /// Flip a specified number of random bits. + // Flip a specified number of random bits. template BitArray & BitArray::FlipRandomCount(Random & random, const size_t num_bits) @@ -1290,7 +1299,7 @@ namespace emp { return *this ^= target_bits; } - /// Set a specified number of random bits (does not check if already set.) + // Set a specified number of random bits (does not check if already set.) template BitArray & BitArray::SetRandomCount(Random & random, const size_t num_bits) @@ -1300,7 +1309,7 @@ namespace emp { return *this |= target_bits; } - /// Unset a specified number of random bits (does not check if already zero.) + // Unset a specified number of random bits (does not check if already zero.) template BitArray & BitArray::ClearRandomCount(Random & random, const size_t num_bits) @@ -1313,7 +1322,7 @@ namespace emp { // ------------------------- Implementations of Comparison Operators ------------------------- - /// Test if two BitArray objects are identical. + // Test if two BitArray objects are identical. template template bool BitArray::operator==(const BitArray & in_bits) const { @@ -1325,7 +1334,7 @@ namespace emp { return true; } - /// Compare two BitArray objects, based on the associated binary value. + // Compare two BitArray objects, based on the associated binary value. template template bool BitArray::operator<(const BitArray & in_bits) const { @@ -1341,7 +1350,7 @@ namespace emp { // ------------------------- Access Groups of bits ------------------------- - /// Get the full byte starting from the bit at a specified index. + // Get the full byte starting from the bit at a specified index. template uint8_t BitArray::GetByte(size_t index) const { emp_assert(index < TOTAL_BYTES); @@ -1351,8 +1360,8 @@ namespace emp { } - /// Get a read-only view into the internal array used by BitArray. - /// @return Read-only span of BitArray's bytes. + // Get a read-only view into the internal array used by BitArray. + // @return Read-only span of BitArray's bytes. template std::span BitArray::GetBytes() const { return std::span( @@ -1362,7 +1371,7 @@ namespace emp { } - /// Set the full byte starting at the bit at the specified index. + // Set the full byte starting at the bit at the specified index. template void BitArray::SetByte(size_t index, uint8_t value) { emp_assert(index < TOTAL_BYTES); @@ -1372,8 +1381,8 @@ namespace emp { bits[field_id] = (bits[field_id] & ~(((field_t)255U) << pos_id)) | (val_uint << pos_id); } - /// Get the overall value of this BitArray, using a uint encoding, but including all bits - /// and returning the value as a double. + // Get the overall value of this BitArray, using a uint encoding, but including all bits + // and returning the value as a double. template double BitArray::GetValue() const { // If we have 64 bits or fewer, we can load the full value and return it. @@ -1398,7 +1407,7 @@ namespace emp { return out_value; } - /// Get specified type at a given index (in steps of that type size) + // Get specified type at a given index (in steps of that type size) template template T BitArray::GetValueAtIndex(const size_t index) const { @@ -1415,7 +1424,7 @@ namespace emp { } - /// Set specified type at a given index (in steps of that type size) + // Set specified type at a given index (in steps of that type size) template template void BitArray::SetValueAtIndex(const size_t index, T in_value) { @@ -1429,7 +1438,7 @@ namespace emp { } - /// Get the specified type starting from a given BIT position. + // Get the specified type starting from a given BIT position. template template T BitArray::GetValueAtBit(const size_t index) const { @@ -1443,7 +1452,7 @@ namespace emp { } - /// Set the specified type starting from a given BIT position. + // Set the specified type starting from a given BIT position. // @CAO: Can be optimized substantially, especially for long BitArrays. template template @@ -1464,10 +1473,10 @@ namespace emp { // ------------------------- Other Analyses ------------------------- - /// A simple hash function for bit vectors. + // A simple hash function for bit vectors. template std::size_t BitArray::Hash() const noexcept { - /// If we have a vector of size_t, treat it as a vector of hash values to combine. + // If we have a vector of size_t, treat it as a vector of hash values to combine. if constexpr (std::is_same_v) { return hash_combine(bits, NUM_FIELDS); } @@ -1487,7 +1496,7 @@ namespace emp { } // TODO: see https://arxiv.org/pdf/1611.07612.pdf for fast pop counts - /// Count the number of ones in the BitArray. + // Count the number of ones in the BitArray. template size_t BitArray::CountOnes() const { size_t bit_count = 0; @@ -1500,7 +1509,7 @@ namespace emp { return bit_count; } - /// Faster counting of ones for very sparse bit vectors. + // Faster counting of ones for very sparse bit vectors. template size_t BitArray::CountOnes_Sparse() const { size_t bit_count = 0; @@ -1513,7 +1522,7 @@ namespace emp { return bit_count; } - /// Return the index of the first one in the sequence; return -1 if no ones are available. + // Return the index of the first one in the sequence; return -1 if no ones are available. template int BitArray::FindOne() const { size_t field_id = 0; @@ -1522,7 +1531,7 @@ namespace emp { (int) (find_bit(bits[field_id]) + (field_id << FIELD_LOG2)) : -1; } - /// Return index of first one in sequence AFTER start_pos (or -1 if no ones) + // Return index of first one in sequence AFTER start_pos (or -1 if no ones) template int BitArray::FindOne(const size_t start_pos) const { if (start_pos >= NUM_BITS) return -1; // If we're past the end, return fail. @@ -1542,7 +1551,7 @@ namespace emp { (int) (find_bit(bits[field_id]) + (field_id * FIELD_BITS)) : -1; } - /// Find the most-significant set-bit. + // Find the most-significant set-bit. template int BitArray::FindMaxOne() const { // Find the max field with a one. @@ -1569,7 +1578,7 @@ namespace emp { return (int) (max_field * FIELD_BITS + offset); } - /// Return index of first one in sequence (or -1 if no ones); change this position to zero. + // Return index of first one in sequence (or -1 if no ones); change this position to zero. template int BitArray::PopOne() { const int out_bit = FindOne(); @@ -1577,7 +1586,7 @@ namespace emp { return out_bit; } - /// Return a vector indicating the posistions of all ones in the BitArray. + // Return a vector indicating the positions of all ones in the BitArray. template emp::vector BitArray::GetOnes() const { // @CAO -- There are better ways to do this with bit tricks. @@ -1589,7 +1598,7 @@ namespace emp { return ones; } - /// Find the length of the longest continuous series of ones. + // Find the length of the longest continuous series of ones. template size_t BitArray::LongestSegmentOnes() const { size_t length = 0; @@ -1604,14 +1613,14 @@ namespace emp { // ------------------------- Print/String Functions ------------------------- // - /// Convert this BitArray to a string (using default direction) + // Convert this BitArray to a string (using default direction) template std::string BitArray::ToString() const { if constexpr (ZERO_LEFT) return ToArrayString(); else return ToBinaryString(); } - /// Convert this BitArray to an array string [0 index on left] + // Convert this BitArray to an array string [0 index on left] template std::string BitArray::ToArrayString() const { std::string out_string; @@ -1620,7 +1629,7 @@ namespace emp { return out_string; } - /// Convert this BitArray to a numerical string [0 index on right] + // Convert this BitArray to a numerical string [0 index on right] template std::string BitArray::ToBinaryString() const { std::string out_string; @@ -1629,7 +1638,7 @@ namespace emp { return out_string; } - /// Convert this BitArray to a series of IDs + // Convert this BitArray to a series of IDs template std::string BitArray::ToIDString(const std::string & spacer) const { std::stringstream ss; @@ -1637,7 +1646,7 @@ namespace emp { return ss.str(); } - /// Convert this BitArray to a series of IDs with ranges condensed. + // Convert this BitArray to a series of IDs with ranges condensed. template std::string BitArray::ToRangeString(const std::string & spacer, const std::string & ranger) const @@ -1647,7 +1656,7 @@ namespace emp { return ss.str(); } - /// Print a space between each field (or other provided spacer) + // Print a space between each field (or other provided spacer) template void BitArray::PrintFields(std::ostream & out, const std::string & spacer) const { for (size_t i = NUM_BITS-1; i < NUM_BITS; i--) { @@ -1656,7 +1665,7 @@ namespace emp { } } - /// Print a space between each field (or other provided spacer) + // Print a space between each field (or other provided spacer) template void BitArray::PrintDebug(std::ostream & out) const { for (size_t field = 0; field < NUM_FIELDS; field++) { @@ -1672,7 +1681,7 @@ namespace emp { out << "^" << std::endl; } - /// Print the locations of all one bits, using the provided spacer (default is a single space) + // Print the locations of all one bits, using the provided spacer (default is a single space) template void BitArray::PrintOneIDs(std::ostream & out, const std::string & spacer) const { bool started = false; @@ -1685,7 +1694,7 @@ namespace emp { } } - /// Print the ones in a range format. E.g., 2-5,7,10-15 + // Print the ones in a range format. E.g., 2-5,7,10-15 template void BitArray::PrintAsRange(std::ostream & out, const std::string & spacer, @@ -1709,7 +1718,7 @@ namespace emp { // ------------------------- Whole BitArray manipulation functions ------------------------- - /// Perform a Boolean NOT on this BitArray, store result here, and return this object. + // Perform a Boolean NOT on this BitArray, store result here, and return this object. template BitArray & BitArray::NOT_SELF() { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = ~bits[i]; @@ -1717,21 +1726,21 @@ namespace emp { return *this; } - /// Perform a Boolean AND with a second BitArray, store result here, and return this object. + // Perform a Boolean AND with a second BitArray, store result here, and return this object. template BitArray & BitArray::AND_SELF(const this_t & array2) { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = bits[i] & array2.bits[i]; return *this; } - /// Perform a Boolean OR with a second BitArray, store result here, and return this object. + // Perform a Boolean OR with a second BitArray, store result here, and return this object. template BitArray & BitArray::OR_SELF(const this_t & array2) { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = bits[i] | array2.bits[i]; return *this; } - /// Perform a Boolean NAND with a second BitArray, store result here, and return this object. + // Perform a Boolean NAND with a second BitArray, store result here, and return this object. template BitArray & BitArray::NAND_SELF(const this_t & array2) { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = ~(bits[i] & array2.bits[i]); @@ -1739,7 +1748,7 @@ namespace emp { return *this; } - /// Perform a Boolean NOR with a second BitArray, store result here, and return this object. + // Perform a Boolean NOR with a second BitArray, store result here, and return this object. template BitArray & BitArray::NOR_SELF(const this_t & array2) { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = ~(bits[i] | array2.bits[i]); @@ -1747,14 +1756,14 @@ namespace emp { return *this; } - /// Perform a Boolean XOR with a second BitArray, store result here, and return this object. + // Perform a Boolean XOR with a second BitArray, store result here, and return this object. template BitArray & BitArray::XOR_SELF(const this_t & array2) { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = bits[i] ^ array2.bits[i]; return *this; } - /// Perform a Boolean EQU with a second BitArray, store result here, and return this object. + // Perform a Boolean EQU with a second BitArray, store result here, and return this object. template BitArray & BitArray::EQU_SELF(const this_t & array2) { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = ~(bits[i] ^ array2.bits[i]); @@ -1762,8 +1771,8 @@ namespace emp { return *this; } - /// Positive shifts go right and negative shifts go left (0 does nothing); - /// return result. + // Positive shifts go right and negative shifts go left (0 does nothing); + // return result. template BitArray BitArray::SHIFT(const int shift_size) const { this_t out_array(*this); @@ -1772,8 +1781,8 @@ namespace emp { return out_array; } - /// Positive shifts go right and negative shifts go left (0 does nothing); - /// store result here, and return this object. + // Positive shifts go right and negative shifts go left (0 does nothing); + // store result here, and return this object. template BitArray & BitArray::SHIFT_SELF(const int shift_size) { if (shift_size > 0) ShiftRight((field_t) shift_size); @@ -1781,7 +1790,7 @@ namespace emp { return *this; } - /// Reverse the order of bits in the BitArray + // Reverse the order of bits in the BitArray template BitArray & BitArray::REVERSE_SELF() { @@ -1807,7 +1816,7 @@ namespace emp { } - /// Reverse order of bits in the BitArray. + // Reverse order of bits in the BitArray. template BitArray BitArray::REVERSE() const { this_t out_array(*this); @@ -1815,8 +1824,8 @@ namespace emp { } - /// Positive rotates go left and negative rotates go left (0 does nothing); - /// return result. + // Positive rotates go left and negative rotates go left (0 does nothing); + // return result. template BitArray BitArray::ROTATE(const int rotate_size) const { this_t out_array(*this); @@ -1825,8 +1834,8 @@ namespace emp { return out_array; } - /// Positive rotates go right and negative rotates go left (0 does nothing); - /// store result here, and return this object. + // Positive rotates go right and negative rotates go left (0 does nothing); + // store result here, and return this object. template BitArray & BitArray::ROTATE_SELF(const int rotate_size) { if (rotate_size > 0) RotateRight((field_t) rotate_size); @@ -1834,7 +1843,7 @@ namespace emp { return *this; } - /// Helper: call ROTATE with negative number instead + // Helper: call ROTATE with negative number instead template template BitArray & BitArray::ROTL_SELF() { @@ -1846,7 +1855,7 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n<>( (-(c+FIELD_BITS-NUM_BITS)) & FIELD_LOG2_MASK )); @@ -1915,7 +1924,7 @@ namespace emp { } - /// Helper for calling ROTATE with positive number + // Helper for calling ROTATE with positive number template template BitArray & BitArray::ROTR_SELF() { @@ -1928,7 +1937,7 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n>>c) | (n<<( (NUM_BITS-c) & FIELD_LOG2_MASK )); @@ -1984,18 +1993,18 @@ namespace emp { } - /// Addition of two BitArrays. - /// Wraps if it overflows. - /// Returns result. + // Addition of two BitArrays. + // Wraps if it overflows. + // Returns result. template BitArray BitArray::ADD(const BitArray & array2) const{ this_t out_array(*this); return out_array.ADD_SELF(array2); } - /// Addition of two BitArrays. - /// Wraps if it overflows. - /// Returns this object. + // Addition of two BitArrays. + // Wraps if it overflows. + // Returns this object. template BitArray & BitArray::ADD_SELF(const this_t & array2) { bool carry = false; @@ -2021,18 +2030,18 @@ namespace emp { return *this; } - /// Subtraction of two BitArrays. - /// Wraps around if it underflows. - /// Returns result. + // Subtraction of two BitArrays. + // Wraps around if it underflows. + // Returns result. template BitArray BitArray::SUB(const this_t & array2) const{ this_t out_array(*this); return out_array.SUB_SELF(array2); } - /// Subtraction of two BitArrays. - /// Wraps if it underflows. - /// Returns this object. + // Subtraction of two BitArrays. + // Wraps if it underflows. + // Returns this object. template BitArray & BitArray::SUB_SELF(const this_t & array2){ @@ -2056,6 +2065,7 @@ namespace emp { return *this; } + #endif // DOXYGEN_SHOULD_SKIP_THIS // ------------------------- Extra Functions ------------------------- @@ -2077,17 +2087,20 @@ namespace emp { } -/// For hashing BitArrays +#ifndef DOXYGEN_SHOULD_SKIP_THIS +// For hashing BitArrays namespace std { template - struct hash> + struct hash> { - size_t operator()( const emp::BitArray & bs ) const noexcept + size_t operator()( const emp::old::BitArray & bs ) const noexcept { return bs.Hash(); } }; } +#endif // DOXYGEN_SHOULD_SKIP_THIS + #endif // #ifndef EMP_BITS_BITARRAY_HPP_INCLUDE diff --git a/include/emp/bits/BitMatrix.hpp b/include/emp/bits/BitMatrix.hpp index a15ef586ee..8c0fd3bad4 100644 --- a/include/emp/bits/BitMatrix.hpp +++ b/include/emp/bits/BitMatrix.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file BitMatrix.hpp + * @file * @brief A COL x ROW matrix of bits and provides easy indexing and manipulation * @note Status: BETA */ @@ -12,6 +13,7 @@ #define EMP_BITS_BITMATRIX_HPP_INCLUDE #include +#include #include @@ -20,10 +22,10 @@ namespace emp { - /// @brief A simple class to manage a COLS x ROWS matrix of bits. + /// A simple class to manage a COLS x ROWS matrix of bits. /// /// Bits are translated to a bitset with 0 in the upper left and moving through bits from - /// left to right and top to bottom. For example, the indecies in a 3x3 bit matrix would be + /// left to right and top to bottom. For example, the indices in a 3x3 bit matrix would be /// organized as such: /// /// 0 1 2 @@ -36,10 +38,13 @@ namespace emp { BitSet bits; ///< Actual bits in matrix. public: + + #ifndef DOXYGEN_SHOULD_SKIP_THIS template constexpr BitSet Mask() const { return BitSet(); } + #endif // DOXYGEN_SHOULD_SKIP_THIS /// Keep only a single column of values, reducing all others to zeros. template @@ -66,7 +71,6 @@ namespace emp { return mask; } -// public: BitMatrix() { ; } BitMatrix(const BitSet & in_bits) : bits(in_bits) { ; } BitMatrix(const BitMatrix & in_matrix) : bits(in_matrix.bits) { ; } @@ -111,15 +115,14 @@ namespace emp { void ClearCol(size_t col) { bits &= ~(MaskCol<0>() << col); } void ClearRow(size_t row) { bits &= ~(MaskRow<0>() << (row * COLS)); } - // Count the number of set bits in the matrix. + /// Count the number of set bits in the matrix. size_t CountOnes() const { return bits.count(); } - // Find the position of the first non-zero bit. - // size_t FindOne() const { return (~bits & (bits - 1)).count(); } - + /// Find the position of the first non-zero bit. + /// size_t FindOne() const { return (~bits & (bits - 1)).count(); } int FindOne() const { return bits.FindOne(); } - // Shift the whole matrix in the specified direction. + /// Shift the whole matrix in the specified direction. BitMatrix LeftShift() const { return ((bits & ~MaskCol<0>()) >> 1); } BitMatrix RightShift() const { return ((bits << 1) & ~MaskCol<0>()); } BitMatrix UpShift() const { return bits >> COLS; } @@ -129,10 +132,10 @@ namespace emp { BitMatrix URShift() const { return ((bits >> (COLS-1)) & ~MaskCol<0>()); } BitMatrix DRShift() const { return ((bits << (COLS+1)) & ~MaskCol<0>()); } - // Find all points within one step of the ones on this bit matrix. + /// Find all points within one step of the ones on this bit matrix. BitMatrix GetReach() const { return *this | LeftShift() | RightShift() | UpShift() | DownShift(); } - // Find all points reachable from the start position. + /// Find all points reachable from the start position. BitMatrix GetRegion(size_t start_pos) const { // Make sure we have a legal region, or else return an empty matrix. if (start_pos < 0 || start_pos >= GetSize() || bits[start_pos] == 0) return BitMatrix(); @@ -149,10 +152,10 @@ namespace emp { } BitMatrix GetRegion(size_t col, size_t row) const { return GetRegion(ToID(col,row)); } - // Does this bit matrix represent a connected set of ones? + /// Does this bit matrix represent a connected set of ones? bool IsConnected() const { return GetRegion((size_t)FindOne()) == *this; } - // Does this bit matrix have any 2x2 square of ones in it? + /// Does this bit matrix have any 2x2 square of ones in it? bool Has2x2() const { return (*this & UpShift() & LeftShift() & ULShift()).Any(); } void Print(std::ostream & os = std::cout) const { diff --git a/include/emp/bits/BitSet.hpp b/include/emp/bits/BitSet.hpp index 3904464147..f6241af02e 100644 --- a/include/emp/bits/BitSet.hpp +++ b/include/emp/bits/BitSet.hpp @@ -1,24 +1,28 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file BitSet.hpp + * @file * @brief A drop-in replacement for std::bitset, with additional bit magic features; aliases BitArray. - * @note Status: RELEASE + * Status: RELEASE * */ #ifndef EMP_BITS_BITSET_HPP_INCLUDE #define EMP_BITS_BITSET_HPP_INCLUDE +#include #include "BitArray.hpp" -namespace emp { +#include "Bits.hpp" // New version of BitSet is in Bits.hpp + +namespace emp::old { template - using BitSet = emp::BitArray; + using BitSet = emp::old::BitArray; } diff --git a/include/emp/bits/BitVector.hpp b/include/emp/bits/BitVector.hpp index f4ec6e6045..489c788272 100644 --- a/include/emp/bits/BitVector.hpp +++ b/include/emp/bits/BitVector.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file BitVector.hpp + * @file * @brief A drop-in replacement for std::vector, with additional bitwise logic features. - * @note Status: RELEASE + * Status: RELEASE * * @note Compile with -O3 and -msse4.2 for fast bit counting. * @@ -30,10 +31,12 @@ #include +#include #include #include #include #include +#include #include "../base/assert.hpp" #include "../base/Ptr.hpp" @@ -45,9 +48,11 @@ #include "_bitset_helpers.hpp" #include "bitset_utils.hpp" -namespace emp { +#include "Bits.hpp" // New version of BitVector is in Bits.hpp + +namespace emp::old { - /// @brief A drop-in replacement for std::vector, but with extra bitwise logic features. + /// A drop-in replacement for std::vector, but with extra bitwise logic features. /// /// This class stores an arbitrary number of bits in a set of "fields" (typically 32 bits or 64 /// bits per field, depending on which should be faster.) Individual bits can be extracted, @@ -84,7 +89,7 @@ namespace emp { /// A mask to cut off all of the final bits. [[nodiscard]] field_t EndMask() const { return MaskLow(NumEndBits()); } - /// How many felids do we need for the current set of bits? + /// How many fields do we need for the current set of bits? [[nodiscard]] size_t NumFields() const { return num_bits ? (1 + ((num_bits - 1) / FIELD_BITS)) : 0; } /// What is the ID of the last occupied field? @@ -110,10 +115,10 @@ namespace emp { // Assume that the size of the bits has already been adjusted to be the size of the one // being copied and only the fields need to be copied over. - void RawCopy(const Ptr in); + inline void RawCopy(const Ptr in); // Copy bits from one position in the genome to another; leave old positions unchanged. - void RawCopy(const size_t from_start, const size_t from_stop, const size_t to); + inline void RawCopy(const size_t from_start, const size_t from_stop, const size_t to); // Convert the bits to bytes (note that bits are NOT in order at the byte level!) [[nodiscard]] emp::Ptr BytePtr() { return bits.ReinterpretCast(); } @@ -131,20 +136,20 @@ namespace emp { inline BitVector & ApplyRange(const FUN_T & fun, size_t start, size_t stop); // Helper: call SHIFT with positive number - void ShiftLeft(const size_t shift_size); + inline void ShiftLeft(const size_t shift_size); // Helper for calling SHIFT with negative number - void ShiftRight(const size_t shift_size); + inline void ShiftRight(const size_t shift_size); /// Helper: call ROTATE with negative number instead - void RotateLeft(const size_t shift_size_raw); + inline void RotateLeft(const size_t shift_size_raw); /// Helper for calling ROTATE with positive number - void RotateRight(const size_t shift_size_raw); + inline void RotateRight(const size_t shift_size_raw); public: /// Build a new BitVector with specified bit count (default 0) and initialization (default 0) - BitVector(size_t in_num_bits=0, bool init_val=false); + inline BitVector(size_t in_num_bits=0, bool init_val=false); // Prevent ambiguous conversions... /// Anything not otherwise defined for first argument, convert to size_t. @@ -152,67 +157,67 @@ namespace emp { BitVector(T in_num_bits) : BitVector((size_t) in_num_bits, 0) {} /// Copy constructor of existing bit field. - BitVector(const BitVector & in); + inline BitVector(const BitVector & in); /// Move constructor of existing bit field. - BitVector(BitVector && in); + inline BitVector(BitVector && in); /// Constructor to generate a BitVector from a std::bitset. template - explicit BitVector(const std::bitset & bitset); + inline explicit BitVector(const std::bitset & bitset); /// Constructor to generate a BitVector from a string of '0's and '1's. - BitVector(const std::string & bitstring); + inline BitVector(const std::string & bitstring); /// Constructor to generate a BitVector from a literal string of '0's and '1's. BitVector(const char * bitstring) : BitVector(std::string(bitstring)) {} /// Constructor to generate a random BitVector (with equal prob of 0 or 1). - BitVector(size_t in_num_bits, Random & random); + inline BitVector(size_t in_num_bits, Random & random); /// Constructor to generate a random BitVector with provided prob of 1's. - BitVector(size_t in_num_bits, Random & random, const double p1); + inline BitVector(size_t in_num_bits, Random & random, const double p1); /// Constructor to generate a random BitVector with provided number of 1's. - BitVector(size_t in_num_bits, Random & random, const size_t target_ones); + inline BitVector(size_t in_num_bits, Random & random, const size_t target_ones); /// Constructor to generate a random BitVector with provided number of 1's. BitVector(size_t in_num_bits, Random & random, const int target_ones) : BitVector(in_num_bits, random, (size_t) target_ones) { } /// Initializer list constructor. - template BitVector(const std::initializer_list l); + template inline BitVector(const std::initializer_list l); /// Copy, but with a resize. - BitVector(const BitVector & in, size_t new_size); + inline BitVector(const BitVector & in, size_t new_size); /// Destructor - ~BitVector(); + inline ~BitVector(); /// Assignment operator. - BitVector & operator=(const BitVector & in) &; + inline BitVector & operator=(const BitVector & in) &; /// Move operator. - BitVector & operator=(BitVector && in) &; + inline BitVector & operator=(BitVector && in) &; /// Assignment operator from a std::bitset. template - BitVector & operator=(const std::bitset & bitset) &; + inline BitVector & operator=(const std::bitset & bitset) &; /// Assignment operator from a string of '0's and '1's. - BitVector & operator=(const std::string & bitstring) &; + inline BitVector & operator=(const std::string & bitstring) &; /// Assignment operator from a literal string of '0's and '1's. BitVector & operator=(const char * bitstring) & { return operator=(std::string(bitstring)); } /// Assignment from another BitVector without changing size. - BitVector & Import( const BitVector & from_bv, const size_t from_bit=0 ); + inline BitVector & Import( const BitVector & from_bv, const size_t from_bit=0 ); /// Convert to a BitVector of a different size. - BitVector Export(size_t out_size, size_t start_bit=0) const; + inline BitVector Export(size_t out_size, size_t start_bit=0) const; // Scan this bitvector to make sure that there are no internal problems. - bool OK() const; + inline bool OK() const; // ========= Accessors ========= // @@ -227,16 +232,16 @@ namespace emp { [[nodiscard]] double GetNumStates() const { return emp::Pow2(num_bits); } /// Retrieve the bit value from the specified index. - [[nodiscard]] bool Get(size_t index) const; + [[nodiscard]] inline bool Get(size_t index) const; /// A safe version of Get() for indexing out of range. Useful for representing collections. [[nodiscard]] bool Has(size_t index) const { return (index < num_bits) ? Get(index) : false; } /// Update the bit value at the specified index. - BitVector & Set(size_t index, bool value=true); + inline BitVector & Set(size_t index, bool value=true); /// Set all bits to 1. - BitVector & SetAll(); + inline BitVector & SetAll(); /// Set a range of bits to value (default one): [start, stop) BitVector & SetRange(size_t start, size_t stop, bool value=true) { @@ -245,7 +250,7 @@ namespace emp { } /// Set all bits to 0. - BitVector & Clear(); + inline BitVector & Clear(); /// Set specific bit to 0. BitVector & Clear(size_t index) { return Set(index, false); } @@ -265,14 +270,14 @@ namespace emp { BitVector & Toggle() { return NOT_SELF(); } /// Change a specified bit to the opposite value - BitVector & Toggle(size_t index); + inline BitVector & Toggle(size_t index); /// Flips all the bits in a range [start, end) BitVector & Toggle(size_t start, size_t stop) { return ApplyRange([](field_t x){ return ~x; }, start, stop); } /// Return true if ANY bits are set to 1, otherwise return false. - [[nodiscard]] bool Any() const; + [[nodiscard]] inline bool Any() const; /// Return true if NO bits are set to 1, otherwise return false. [[nodiscard]] bool None() const { return !Any(); } @@ -282,75 +287,75 @@ namespace emp { [[nodiscard]] bool All() const { return (~(*this)).None(); } /// Resize this BitVector to have the specified number of bits. - BitVector & Resize(size_t new_bits); + inline BitVector & Resize(size_t new_bits); // ========= Randomization functions ========= // /// Set all bits randomly, with a 50% probability of being a 0 or 1. - BitVector & Randomize(Random & random); + inline BitVector & Randomize(Random & random); /// Set all bits randomly, with probability specified at compile time. template - BitVector & RandomizeP(Random & random, const size_t start_pos=0, size_t stop_pos=MAX_BITS); + inline BitVector & RandomizeP(Random & random, const size_t start_pos=0, size_t stop_pos=MAX_BITS); /// Set all bits randomly, with a given probability of being a one. - BitVector & Randomize(Random & random, const double p, - const size_t start_pos=0, size_t stop_pos=MAX_BITS); + inline BitVector & Randomize(Random & random, const double p, + const size_t start_pos=0, size_t stop_pos=MAX_BITS); /// Set all bits randomly, with a given number of ones. - BitVector & ChooseRandom(Random & random, const size_t target_ones, - const size_t start_pos=0, size_t stop_pos=MAX_BITS); + inline BitVector & ChooseRandom(Random & random, const size_t target_ones, + const size_t start_pos=0, size_t stop_pos=MAX_BITS); /// Flip random bits with a given probability. - BitVector & FlipRandom(Random & random, const double p, - const size_t start_pos=0, size_t stop_pos=MAX_BITS); + inline BitVector & FlipRandom(Random & random, const double p, + const size_t start_pos=0, size_t stop_pos=MAX_BITS); /// Set random bits with a given probability (does not check if already set.) - BitVector & SetRandom(Random & random, const double p, - const size_t start_pos=0, size_t stop_pos=MAX_BITS); + inline BitVector & SetRandom(Random & random, const double p, + const size_t start_pos=0, size_t stop_pos=MAX_BITS); /// Unset random bits with a given probability (does not check if already zero.) - BitVector & ClearRandom(Random & random, const double p, - const size_t start_pos=0, size_t stop_pos=MAX_BITS); + inline BitVector & ClearRandom(Random & random, const double p, + const size_t start_pos=0, size_t stop_pos=MAX_BITS); /// Flip a specified number of random bits. - BitVector & FlipRandomCount(Random & random, const size_t target_bits); + inline BitVector & FlipRandomCount(Random & random, const size_t target_bits); /// Set a specified number of random bits (does not check if already set.) - BitVector & SetRandomCount(Random & random, const size_t target_bits); + inline BitVector & SetRandomCount(Random & random, const size_t target_bits); /// Unset a specified number of random bits (does not check if already zero.) - BitVector & ClearRandomCount(Random & random, const size_t target_bits); + inline BitVector & ClearRandomCount(Random & random, const size_t target_bits); // ========= Comparison Operators ========= // - [[nodiscard]] bool operator==(const BitVector & in) const; - [[nodiscard]] bool operator!=(const BitVector & in) const { return !(*this == in); } - [[nodiscard]] bool operator< (const BitVector & in) const; - [[nodiscard]] bool operator> (const BitVector & in) const { return in < *this; } - [[nodiscard]] bool operator<=(const BitVector & in) const { return !(in < *this); } - [[nodiscard]] bool operator>=(const BitVector & in) const { return !(*this < in); } + [[nodiscard]] inline bool operator==(const BitVector & in) const; + [[nodiscard]] inline bool operator!=(const BitVector & in) const { return !(*this == in); } + [[nodiscard]] inline bool operator< (const BitVector & in) const; + [[nodiscard]] inline bool operator> (const BitVector & in) const { return in < *this; } + [[nodiscard]] inline bool operator<=(const BitVector & in) const { return !(in < *this); } + [[nodiscard]] inline bool operator>=(const BitVector & in) const { return !(*this < in); } // ========= Conversion Operators ========= // /// Automatically convert BitVector to other vector types. - template operator emp::vector(); + template inline operator emp::vector(); /// Casting a bit array to bool identifies if ANY bits are set to 1. - explicit operator bool() const { return Any(); } + explicit inline operator bool() const { return Any(); } // ========= Access Groups of bits ========= // /// Retrieve the byte at the specified byte index. - [[nodiscard]] uint8_t GetByte(size_t index) const; + [[nodiscard]] inline uint8_t GetByte(size_t index) const; /// Get a read-only view into the internal array used by BitVector. /// @return Read-only span of BitVector's bytes. - [[nodiscard]] std::span GetBytes() const; + [[nodiscard]] inline std::span GetBytes() const; /// Get a read-only pointer to the internal array used by BitVector. /// (note that bits are NOT in order at the byte level!) @@ -358,18 +363,18 @@ namespace emp { emp::Ptr RawBytes() const { return BytePtr(); } /// Update the byte at the specified byte index. - void SetByte(size_t index, uint8_t value); + inline void SetByte(size_t index, uint8_t value); /// Get the overall value of this BitVector, using a uint encoding, but including all bits /// and returning the value as a double. - [[nodiscard]] double GetValue() const; + [[nodiscard]] inline double GetValue() const; /// Return a span with all fields in order. std::span FieldSpan() { return std::span(bits.Raw(), NumFields()); } /// Get specified type at a given index (in steps of that type size) template - [[nodiscard]] T GetValueAtIndex(const size_t index) const; + [[nodiscard]] inline T GetValueAtIndex(const size_t index) const; // Retrieve the 8-bit uint from the specified uint index. [[nodiscard]] uint8_t GetUInt8(size_t index) const { return GetValueAtIndex(index); } @@ -388,7 +393,7 @@ namespace emp { /// Set specified type at a given index (in steps of that type size) - template void SetValueAtIndex(const size_t index, T value); + template inline void SetValueAtIndex(const size_t index, T value); /// Update the 8-bit uint at the specified uint index. void SetUInt8(const size_t index, uint8_t value) { SetValueAtIndex(index, value); } @@ -408,7 +413,7 @@ namespace emp { /// Get specified type starting at a given BIT position. template - [[nodiscard]] T GetValueAtBit(const size_t index) const; + [[nodiscard]] inline T GetValueAtBit(const size_t index) const; // Retrieve the 8-bit uint from the specified uint index. [[nodiscard]] uint8_t GetUInt8AtBit(size_t index) const { return GetValueAtBit(index); } @@ -426,7 +431,7 @@ namespace emp { [[nodiscard]] uint32_t GetUIntAtBit(size_t index) const { return GetUInt32AtBit(index); } - template void SetValueAtBit(const size_t index, T value); + template inline void SetValueAtBit(const size_t index, T value); /// Update the 8-bit uint at the specified uint index. void SetUInt8AtBit(const size_t index, uint8_t value) { SetValueAtBit(index, value); } @@ -447,41 +452,41 @@ namespace emp { // ========= Other Analyses ========= // /// A simple hash function for bit vectors. - [[nodiscard]] std::size_t Hash(size_t start_field=0) const; + [[nodiscard]] inline std::size_t Hash(size_t start_field=0) const; /// Count the number of ones in the BitVector. - [[nodiscard]] size_t CountOnes() const; + [[nodiscard]] inline size_t CountOnes() const; /// Faster counting of ones for very sparse bit vectors. - [[nodiscard]] size_t CountOnes_Sparse() const; + [[nodiscard]] inline size_t CountOnes_Sparse() const; /// Count the number of zeros in the BitVector. [[nodiscard]] size_t CountZeros() const { return GetSize() - CountOnes(); } /// Pop the last bit in the vector. /// @return value of the popped bit. - bool PopBack(); + inline bool PopBack(); /// Push given bit(s) onto the back of a vector. /// @param bit value of bit to be pushed. /// @param num number of bits to be pushed. - void PushBack(const bool bit=true, const size_t num=1); + inline void PushBack(const bool bit=true, const size_t num=1); /// Insert bit(s) into any index of vector using bit magic. /// Blog post on implementation reasoning: https://devolab.org/?p=2249 /// @param index location to insert bit(s). /// @param val value of bit(s) to insert. /// @param num number of bits to insert, default 1. - void Insert(const size_t index, const bool val=true, const size_t num=1); + inline void Insert(const size_t index, const bool val=true, const size_t num=1); /// Delete bits from any index in a vector. /// TODO: consider a bit magic approach here. /// @param index location to delete bit(s). /// @param num number of bits to delete, default 1. - void Delete(const size_t index, const size_t num=1); + inline void Delete(const size_t index, const size_t num=1); /// Return the position of the first one; return -1 if no ones in vector. - [[nodiscard]] int FindOne() const; + [[nodiscard]] inline int FindOne() const; /// Deprecated: Return the position of the first one; return -1 if no ones in vector. [[deprecated("Renamed to more accurate FindOne()")]] @@ -492,7 +497,7 @@ namespace emp { /// /// for (int pos = bv.FindOne(); pos >= 0; pos = bv.FindOne(pos+1)) { ... } /// - [[nodiscard]] int FindOne(const size_t start_pos) const; + [[nodiscard]] inline int FindOne(const size_t start_pos) const; /// Special version of FindOne takes int; most common way to call. [[nodiscard]] int FindOne(int start_pos) const { @@ -504,27 +509,27 @@ namespace emp { [[nodiscard]] int FindBit(const size_t start_pos) const; /// Find the most-significant set-bit. - [[nodiscard]] int FindMaxOne() const; + [[nodiscard]] inline int FindMaxOne() const; /// Return the position of the first one and change it to a zero. Return -1 if no ones. - int PopOne(); + inline int PopOne(); /// Deprecated version of PopOne(). [[deprecated("Renamed to more accurate PopOne()")]] int PopBit() { return PopOne(); } /// Return positions of all ones. - [[nodiscard]] emp::vector GetOnes() const; + [[nodiscard]] inline emp::vector GetOnes() const; /// Collect positions of ones in the provided vector (allows id type choice) template - emp::vector & GetOnes(emp::vector & out_vals) const; + inline emp::vector & GetOnes(emp::vector & out_vals) const; /// Find the length of the longest continuous series of ones. - [[nodiscard]] size_t LongestSegmentOnes() const; + [[nodiscard]] inline size_t LongestSegmentOnes() const; /// Return true if any ones are in common with another BitVector. - [[nodiscard]] bool HasOverlap(const BitVector & in) const; + [[nodiscard]] inline bool HasOverlap(const BitVector & in) const; // ========= Print/String Functions ========= // @@ -533,17 +538,17 @@ namespace emp { [[nodiscard]] char GetAsChar(size_t id) const { return Get(id) ? '1' : '0'; } /// Convert this BitVector to a vector string [index 0 on left] - [[nodiscard]] std::string ToString() const; + [[nodiscard]] inline std::string ToString() const; /// Convert this BitVector to a numerical string [index 0 on right] - [[nodiscard]] std::string ToBinaryString() const; + [[nodiscard]] inline std::string ToBinaryString() const; /// Convert this BitVector to a series of IDs - [[nodiscard]] std::string ToIDString(const std::string & spacer=" ") const; + [[nodiscard]] inline std::string ToIDString(const std::string & spacer=" ") const; /// Convert this BitVector to a series of IDs with ranges condensed. - [[nodiscard]] std::string ToRangeString(const std::string & spacer=",", - const std::string & ranger="-") const; + [[nodiscard]] inline std::string ToRangeString(const std::string & spacer=",", + const std::string & ranger="-") const; /// Regular print function (from least significant bit to most) void Print(std::ostream & out=std::cout) const { out << ToString(); } @@ -555,18 +560,18 @@ namespace emp { void PrintArray(std::ostream & out=std::cout) const { out << ToString(); } /// Print a space between each field (or other provided spacer) - void PrintFields(std::ostream & out=std::cout, const std::string & spacer=" ") const; + void inline PrintFields(std::ostream & out=std::cout, const std::string & spacer=" ") const; /// Print out details about the internals of the BitVector. - void PrintDebug(std::ostream & out=std::cout) const; + void inline PrintDebug(std::ostream & out=std::cout) const; /// Print the positions of all one bits, spaces are the default separator. - void PrintOneIDs(std::ostream & out=std::cout, const std::string & spacer=" ") const; + void inline PrintOneIDs(std::ostream & out=std::cout, const std::string & spacer=" ") const; /// Print the ones in a range format. E.g., 2-5,7,10-15 - void PrintAsRange(std::ostream & out=std::cout, - const std::string & spacer=",", - const std::string & ranger="-") const; + void inline PrintAsRange(std::ostream & out=std::cout, + const std::string & spacer=",", + const std::string & ranger="-") const; /// Overload ostream operator to return Print. friend std::ostream& operator<<(std::ostream &out, const BitVector & bv) { @@ -578,25 +583,25 @@ namespace emp { // ========= Boolean Logic and Shifting Operations ========= // /// Perform a Boolean NOT with this BitVector, store result here, and return this object. - BitVector & NOT_SELF(); + inline BitVector & NOT_SELF(); /// Perform a Boolean AND with this BitVector, store result here, and return this object. - BitVector & AND_SELF(const BitVector & bv2); + inline BitVector & AND_SELF(const BitVector & bv2); /// Perform a Boolean OR with this BitVector, store result here, and return this object. - BitVector & OR_SELF(const BitVector & bv2); + inline BitVector & OR_SELF(const BitVector & bv2); /// Perform a Boolean NAND with this BitVector, store result here, and return this object. - BitVector & NAND_SELF(const BitVector & bv2); + inline BitVector & NAND_SELF(const BitVector & bv2); /// Perform a Boolean NOR with this BitVector, store result here, and return this object. - BitVector & NOR_SELF(const BitVector & bv2); + inline BitVector & NOR_SELF(const BitVector & bv2); /// Perform a Boolean XOR with this BitVector, store result here, and return this object. - BitVector & XOR_SELF(const BitVector & bv2); + inline BitVector & XOR_SELF(const BitVector & bv2); /// Perform a Boolean EQU with this BitVector, store result here, and return this object. - BitVector & EQU_SELF(const BitVector & bv2); + inline BitVector & EQU_SELF(const BitVector & bv2); /// Perform a Boolean NOT on this BitVector and return the result. @@ -622,52 +627,52 @@ namespace emp { /// Positive shifts go left and negative go right (0 does nothing); return result. - [[nodiscard]] BitVector SHIFT(const int shift_size) const; + [[nodiscard]] inline BitVector SHIFT(const int shift_size) const; /// Positive shifts go left and negative go right; store result here, and return this object. - BitVector & SHIFT_SELF(const int shift_size); + inline BitVector & SHIFT_SELF(const int shift_size); /// Reverse the order of bits in the bitset - BitVector & REVERSE_SELF(); + inline BitVector & REVERSE_SELF(); /// Reverse order of bits in the bitset. - [[nodiscard]] BitVector REVERSE() const; + [[nodiscard]] inline BitVector REVERSE() const; /// Positive rotates go left and negative rotates go left (0 does nothing); /// return result. - [[nodiscard]] BitVector ROTATE(const int rotate_size) const; + [[nodiscard]] inline BitVector ROTATE(const int rotate_size) const; /// Positive rotates go right and negative rotates go left (0 does nothing); /// store result here, and return this object. - BitVector & ROTATE_SELF(const int rotate_size); + inline BitVector & ROTATE_SELF(const int rotate_size); /// Helper: call ROTATE with negative number instead template - BitVector & ROTL_SELF(); + inline BitVector & ROTL_SELF(); /// Helper for calling ROTATE with positive number template - BitVector & ROTR_SELF(); + inline BitVector & ROTR_SELF(); /// Addition of two BitVectors. /// Wraps if it overflows. /// Returns result. - [[nodiscard]] BitVector ADD(const BitVector & set2) const; + [[nodiscard]] inline BitVector ADD(const BitVector & set2) const; /// Addition of two BitVectors. /// Wraps if it overflows. /// Returns this object. - BitVector & ADD_SELF(const BitVector & set2); + inline BitVector & ADD_SELF(const BitVector & set2); /// Subtraction of two BitVectors. /// Wraps around if it underflows. /// Returns result. - [[nodiscard]] BitVector SUB(const BitVector & set2) const; + [[nodiscard]] inline BitVector SUB(const BitVector & set2) const; /// Subtraction of two BitVectors. /// Wraps if it underflows. /// Returns this object. - BitVector & SUB_SELF(const BitVector & set2); + inline BitVector & SUB_SELF(const BitVector & set2); /// Operator bitwise NOT... @@ -718,7 +723,7 @@ namespace emp { /// Compound operator for shift right... BitVector & operator>>=(const size_t shift_size) { return SHIFT_SELF((int)shift_size); } - // ========= Standard Library Compatability ========= // + // ========= Standard Library Compatibility ========= // // A set of functions to allow drop-in replacement with std::bitset. [[nodiscard]] size_t size() const { return num_bits; } @@ -760,6 +765,8 @@ namespace emp { for (size_t i = 0; i < NUM_FIELDS; i++) bits[i] = in[i]; } + #ifndef DOXYGEN_SHOULD_SKIP_THIS + // Move bits from one position in the genome to another; leave old positions unchanged. // @CAO: Can speed up by focusing only on the moved fields (i.e., don't shift unused bits). void BitVector::RawCopy(const size_t from_start, const size_t from_stop, const size_t to) { @@ -781,6 +788,8 @@ namespace emp { OR_SELF(move_bits); // Merge bitstrings together. } + #endif // DOXYGEN_SHOULD_SKIP_THIS + template BitVector & BitVector::ApplyRange(const FUN_T & fun, size_t start, size_t stop) { if (start == stop) return *this; // Empty range. @@ -909,12 +918,12 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // Mask necessary to surpress shift count overflow warnings. + // Mask necessary to suppress shift count overflow warnings. c &= FIELD_LOG2_MASK; n = (n<>( (-(c+FIELD_BITS-num_bits)) & FIELD_LOG2_MASK )); } else if (NUM_FIELDS < 32) { // For small BitVectors, shifting L/R and ORing is faster. - emp::BitVector dup(*this); + BitVector dup(*this); dup.ShiftLeft(shift_size); ShiftRight(num_bits - shift_size); OR_SELF(dup); @@ -986,13 +995,13 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n>>c) | (n<<( (num_bits-c) & FIELD_LOG2_MASK )); } else if (NUM_FIELDS < 32) { // for small BitVectors, shifting L/R and ORing is faster - emp::BitVector dup(*this); + BitVector dup(*this); dup.ShiftRight(shift_size); ShiftLeft(num_bits - shift_size); OR_SELF(dup); @@ -1744,11 +1753,11 @@ namespace emp { if (bit) SetRange(num_bits-num, num_bits); } - /// Insert bit(s) into any index of vector using bit magic. - /// Blog post on implementation reasoning: https://devolab.org/?p=2249 - /// @param index location to insert bit(s). - /// @param val value of bit(s) to insert (default true) - /// @param num number of bits to insert, default 1. + // Insert bit(s) into any index of vector using bit magic. + // Blog post on implementation reasoning: https://devolab.org/?p=2249 + // @param index location to insert bit(s). + // @param val value of bit(s) to insert (default true) + // @param num number of bits to insert, default 1. void BitVector::Insert(const size_t index, const bool val, const size_t num) { Resize(num_bits + num); // Adjust to new number of bits. BitVector low_bits(*this); // Copy current bits @@ -1760,9 +1769,9 @@ namespace emp { } - /// Delete bits from any index in a vector. - /// @param index location to delete bit(s). - /// @param num number of bits to delete, default 1. + // Delete bits from any index in a vector. + // @param index location to delete bit(s). + // @param num number of bits to delete, default 1. void BitVector::Delete(const size_t index, const size_t num) { emp_assert(index+num <= GetSize()); // Make sure bits to delete actually exist! RawCopy(index+num, num_bits, index); // Shift positions AFTER delete into place. @@ -2096,7 +2105,7 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n<>( (-(c+FIELD_BITS-num_bits)) & FIELD_LOG2_MASK )); @@ -2179,7 +2188,7 @@ namespace emp { field_t & n = bits[0]; size_t c = shift_size; - // mask necessary to surpress shift count overflow warnings + // mask necessary to suppress shift count overflow warnings c &= FIELD_LOG2_MASK; n = (n>>c) | (n<<( (num_bits-c) & FIELD_LOG2_MASK )); @@ -2309,14 +2318,20 @@ namespace emp { // ---------------------- Implementations to work with standard library ---------------------- +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { - /// Hash function to allow BitVector to be used with maps and sets (must be in std). +#endif // DOXYGEN_SHOULD_SKIP_THIS + /// Hash function to allow BitVector to be used with maps and sets. + /// This is added to the std namespace so that BitVectors can be used + /// in data structures that require hashing (such as unordered_map) template <> - struct hash { - std::size_t operator()(const emp::BitVector & bv) const { + struct hash { + std::size_t operator()(const emp::old::BitVector & bv) const { return bv.Hash(); } }; +#ifndef DOXYGEN_SHOULD_SKIP_THIS } +#endif #endif // #ifndef EMP_BITS_BITVECTOR_HPP_INCLUDE diff --git a/include/emp/bits/Bits.hpp b/include/emp/bits/Bits.hpp index 9fc1ac9730..3bc9b10fd8 100644 --- a/include/emp/bits/Bits.hpp +++ b/include/emp/bits/Bits.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-23 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file Bits.hpp + * @file * @brief A generic bit-handler to replace vector, etc +additional bitwise logic features. * @note Status: RELEASE * @@ -64,6 +65,7 @@ #include "../math/constants.hpp" #include "../math/math.hpp" #include "../math/Random.hpp" +#include "../math/Range.hpp" #include "../meta/type_traits.hpp" #include "Bits_Data.hpp" @@ -284,6 +286,9 @@ namespace emp { /// @brief How many bits do we currently have? [[nodiscard]] constexpr auto GetSize() const { return _data.NumBits(); } + /// @brief How many bits are locked in a compile time? + [[nodiscard]] static constexpr auto GetCTSize() { return DATA_T::NumCTBits(); } + /// @brief How many bytes are in this Bits? (includes empty field space) [[nodiscard]] constexpr auto GetNumBytes() const { return _data.NumBytes(); } @@ -558,6 +563,11 @@ namespace emp { /// @param num number of bits to be pushed. void PushBack(const bool bit=true, const size_t num=1); + /// @brief Push given bit(s) onto the front of a vector. + /// @param bit value of bit to be pushed. + /// @param num number of bits to be pushed. + void PushFront(const bool bit=true, const size_t num=1); + /// @brief Insert bit(s) into any index of vector using bit magic. /// Blog post on implementation reasoning: https://devolab.org/?p=2249 /// @param index location to insert bit(s). @@ -574,6 +584,10 @@ namespace emp { /// @brief Return the position of the first one; return -1 if no ones in vector. [[nodiscard]] int FindOne() const; + /// @brief Return the position of the first zero; return -1 if no zeroes in vector. + [[nodiscard]] int FindZero() const; + + /// Deprecated: Return the position of the first one; return -1 if no ones in vector. [[deprecated("Renamed to more accurate FindOne()")]] [[nodiscard]] int FindBit() const { return FindOne(); } @@ -582,14 +596,26 @@ namespace emp { /// You can loop through all 1-bit positions of Bits object "bits" with: /// /// for (int pos = bits.FindOne(); pos >= 0; pos = bits.FindOne(pos+1)) { ... } - /// + [[nodiscard]] int FindOne(const size_t start_pos) const; - /// @brief Special version of FindOne takes int; most common way to call. + /// @brief Return the position of the first zero after start_pos (or -1 if none) + /// You can loop through all 0-bit positions of Bits object "bits" with: + /// + /// for (int pos = bits.FindZero(); pos >= 0; pos = bits.FindZero(pos+1)) { ... } + + [[nodiscard]] int FindZero(const size_t start_pos) const; + + /// @brief Special version of FindOne takes int; common way to call. [[nodiscard]] int FindOne(int start_pos) const { return FindOne(static_cast(start_pos)); } + /// @brief Special version of FindZero takes int; common way to call. + [[nodiscard]] int FindZero(int start_pos) const { + return FindZero(static_cast(start_pos)); + } + /// Deprecated version of FindOne(). [[deprecated("Renamed to more accurate FindOne(start_pos)")]] [[nodiscard]] int FindBit(const size_t start_pos) const; @@ -614,6 +640,10 @@ namespace emp { /// @brief Find the length of the longest continuous series of ones. [[nodiscard]] size_t LongestSegmentOnes() const; + /// @brief Find ids of all groups of ones. + /// @return A vector of ranges that identify all ids of ones. + [[nodiscard]] emp::vector> GetRanges() const; + /// @brief Return true if any ones are in common with another Bits. [[nodiscard]] bool HasOverlap(const Bits & in) const; @@ -807,7 +837,7 @@ namespace emp { const Bits & operator-=(const Bits & ar2) { return SUB_SELF(ar2); } - // ========= Cereal Compatability ========= // + // ========= Cereal Compatibility ========= // /// @brief Setup this bits object so that it can be stored in an archive and re-loaded. template @@ -1795,6 +1825,16 @@ namespace emp { if (bit) SetRange(GetSize()-num, GetSize()); } + /// Push given bit(s) onto the front of a vector. + /// @param bit value of bit to be pushed. + /// @param num number of bits to be pushed. + template + void Bits::PushFront(const bool bit, const size_t num) { + Resize(GetSize() + num); + SHIFT_SELF(num); + if (bit) SetRange(0, num); + } + /// Insert bit(s) into any index of vector using bit magic. /// Blog post on implementation reasoning: https://devolab.org/?p=2249 /// @param index location to insert bit(s). @@ -1802,11 +1842,11 @@ namespace emp { /// @param num number of bits to insert, default 1. template void Bits::Insert(const size_t index, const bool val, const size_t num) { - Resize(GetSize() + num); // Adjust to new number of bits. - Bits low_bits(*this); // Copy current bits + Resize(GetSize() + num); // Adjust to new number of bits. + Bits low_bits(*this); // Copy current bits SHIFT_SELF(-(int)num); // Shift the high bits into place. Clear(0, index+num); // Reduce current to just high bits. - low_bits.Clear(index, GetSize()); // Reduce copy to just low bits. + low_bits.Clear(index, GetSize()); // Reduce copy to just low bits. if (val) SetRange(index, index+num); // If new bits should be ones, make it so. OR_SELF(low_bits); // Put the low bits back in place. } @@ -1832,6 +1872,16 @@ namespace emp { (int) (find_bit(_data.bits[field_id]) + (field_id * FIELD_BITS)) : -1; } + /// Return the position of the first zero; return -1 if no zeros in vector. + template + int Bits::FindZero() const { + const size_t NUM_FIELDS = _data.NumFields(); + size_t field_id = 0; + while (field_id < NUM_FIELDS && _data.bits[field_id]==FIELD_ALL) field_id++; + return (field_id < NUM_FIELDS) ? + (int) (find_bit(~_data.bits[field_id]) + (field_id * FIELD_BITS)) : -1; + } + /// Return the position of the first one after start_pos; return -1 if no ones in vector. /// You can loop through all 1-bit positions in "bits" with: /// @@ -1839,9 +1889,9 @@ namespace emp { template int Bits::FindOne(const size_t start_pos) const { - if (start_pos >= GetSize()) return -1; // If we're past the end, return fail. - size_t field_id = FieldID(start_pos); // What field do we start in? - const size_t field_pos = FieldPos(start_pos); // What position in that field? + if (start_pos >= GetSize()) return -1; // If we are past the end, return fail. + size_t field_id = FieldID(start_pos); // What field do we start in? + const size_t field_pos = FieldPos(start_pos); // What position in that field? // If there's a hit in a partial first field, return it. if (field_pos && (_data.bits[field_id] & ~(MaskField(field_pos)))) { @@ -1857,6 +1907,31 @@ namespace emp { (int) (find_bit(_data.bits[field_id]) + (field_id * FIELD_BITS)) : -1; } + /// Return the position of the first zero after start_pos; return -1 if no zeroes in vector. + /// You can loop through all 0-bit positions in "bits" with: + /// + /// for (int pos = bits.FindZero(); pos >= 0; pos = bits.FindZero(pos+1)) { ... } + + template + int Bits::FindZero(const size_t start_pos) const { + if (start_pos >= GetSize()) return -1; // If we are past the end, return fail. + size_t field_id = FieldID(start_pos); // What field do we start in? + const size_t field_pos = FieldPos(start_pos); // What position in that field? + + // If there's a hit in a partial first field, return it. + if (field_pos && (~_data.bits[field_id] & ~(MaskField(field_pos)))) { + return (int) (~find_bit(_data.bits[field_id] & ~(MaskField(field_pos))) + + field_id * FIELD_BITS); + } + + // Search other fields... + const size_t NUM_FIELDS = _data.NumFields(); + if (field_pos) field_id++; + while (field_id < NUM_FIELDS && _data.bits[field_id]==FIELD_ALL) field_id++; + return (field_id < NUM_FIELDS) ? + (int) (find_bit(~_data.bits[field_id]) + (field_id * FIELD_BITS)) : -1; + } + /// Find the most-significant set-bit. template int Bits::FindMaxOne() const { @@ -1925,6 +2000,17 @@ namespace emp { return length; } + template + emp::vector> Bits::GetRanges() const { + emp::vector> out_ranges; + for (int start_pos = FindOne(); start_pos >= 0; start_pos = FindOne(start_pos+1)) { + int end_pos = FindZero(start_pos); + end_pos = (end_pos == -1) ? GetSize() - 1 : end_pos - 1; + out_ranges.emplace_back(start_pos, end_pos); + } + return out_ranges; + } + /// Return true if any ones are in common with another Bits object. template bool Bits::HasOverlap(const Bits & in) const { @@ -2257,10 +2343,10 @@ namespace emp { // ---------------------- Implementations to work with standard library ---------------------- namespace std { - /// Hash function to allow BitVector to be used with maps and sets (must be in std). - template <> - struct hash { - std::size_t operator()(const emp::BitVector & bits) const { + /// Hash function to allow Bits objects to be used with maps and sets (must be in std). + template + struct hash> { + std::size_t operator()(const emp::Bits & bits) const { return bits.Hash(); } }; diff --git a/include/emp/bits/Bits_Data.hpp b/include/emp/bits/Bits_Data.hpp index ac4c50a27a..c245822506 100644 --- a/include/emp/bits/Bits_Data.hpp +++ b/include/emp/bits/Bits_Data.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-23 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file Bits_Data.hpp + * @file * @brief Helper class to handle memory management for Bits objects. * @note Status: BETA * @@ -51,6 +52,9 @@ namespace emp { [[nodiscard]] constexpr size_t NumBits() const noexcept { return num_bits; } + // Number of bits locked in at compile time. + [[nodiscard]] static constexpr size_t NumCTBits() noexcept { return 0; } + /// Number of bits used in partial field at the end; 0 = perfect fit. [[nodiscard]] constexpr size_t NumEndBits() const noexcept { return num_bits & (NUM_FIELD_BITS - 1); @@ -107,6 +111,9 @@ namespace emp { [[nodiscard]] constexpr size_t NumBits() const noexcept { return NUM_BITS; } + // Number of bits locked in at compile time. + [[nodiscard]] static constexpr size_t NumCTBits() noexcept { return NUM_BITS; } + /// Number of bits used in partial field at the end; 0 if perfect fit. [[nodiscard]] constexpr size_t NumEndBits() const noexcept { return NUM_BITS & (NUM_FIELD_BITS - 1); @@ -140,13 +147,13 @@ namespace emp { return NumFields() * sizeof(field_t); } - Bits_Data_Size_Fixed(size_t in_size=NUM_BITS) { + Bits_Data_Size_Fixed([[maybe_unused]] size_t in_size=NUM_BITS) { emp_assert(in_size <= NUM_BITS, in_size, NUM_BITS); } Bits_Data_Size_Fixed(const Bits_Data_Size_Fixed &) = default; template - void serialize(Archive & ar) { /* Nothing to do here. */ } + void serialize(Archive & /* ar */) { /* Nothing to do here. */ } [[nodiscard]] constexpr bool OK() const { return true; } // Nothing to check yet. }; @@ -190,13 +197,8 @@ namespace emp { } } - #ifdef NDEBUG - [[nodiscard]] auto AsSpan() { return std::span(bits); } - [[nodiscard]] auto AsSpan() const { return std::span(bits); } - #else - [[nodiscard]] auto AsSpan() { return std::span(bits.data()); } - [[nodiscard]] auto AsSpan() const { return std::span(bits.data()); } - #endif + [[nodiscard]] auto AsSpan() { return std::span(bits.data(), MAX_FIELDS); } + [[nodiscard]] auto AsSpan() const { return std::span(bits.data(), MAX_FIELDS); } [[nodiscard]] bool OK() const { return true; } // Nothing to check yet. @@ -230,9 +232,9 @@ namespace emp { { if (num_bits) bits = NewArrayPtr(NumBitFields(num_bits)); } - Bits_Data_Mem_Dynamic(const Bits_Data_Mem_Dynamic & in) : bits(nullptr) { Copy(in); } + Bits_Data_Mem_Dynamic(const Bits_Data_Mem_Dynamic & in) : base_t(), bits(nullptr) { Copy(in); } Bits_Data_Mem_Dynamic(Bits_Data_Mem_Dynamic && in) : bits(nullptr) { Move(std::move(in)); } - ~Bits_Data_Mem_Dynamic() { if (bits) {bits.DeleteArray();} } + ~Bits_Data_Mem_Dynamic() { if (bits) bits.DeleteArray(); } Bits_Data_Mem_Dynamic & operator=(const Bits_Data_Mem_Dynamic & in) { Copy(in); return *this; } Bits_Data_Mem_Dynamic & operator=(Bits_Data_Mem_Dynamic && in) { Move(std::move(in)); return *this; } @@ -340,8 +342,8 @@ namespace emp { { field_capacity = base_t::NumFields(); } - Bits_Data_Mem_Watermark(const this_t & in) { Copy(in); } - Bits_Data_Mem_Watermark(this_t && in) { Move(std::move(in)); } + Bits_Data_Mem_Watermark(const this_t & in) : base_t(0) { Copy(in); } + Bits_Data_Mem_Watermark(this_t && in) : base_t(0) { Move(std::move(in)); } ~Bits_Data_Mem_Watermark() { /* cleanup in base class */ } Bits_Data_Mem_Watermark & operator=(const this_t & in) { Copy(in); return *this; } diff --git a/include/emp/bits/_bitset_helpers.hpp b/include/emp/bits/_bitset_helpers.hpp index a64bf242b0..a655b865d2 100644 --- a/include/emp/bits/_bitset_helpers.hpp +++ b/include/emp/bits/_bitset_helpers.hpp @@ -1,15 +1,17 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file _bitset_helpers.hpp + * @file * @brief An internal Empirical class with tools to build collections of bits. */ #ifndef EMP_BITS__BITSET_HELPERS_HPP_INCLUDE #define EMP_BITS__BITSET_HELPERS_HPP_INCLUDE +#include namespace emp { diff --git a/include/emp/bits/bitset_utils.hpp b/include/emp/bits/bitset_utils.hpp index 10cb0e1578..83a9641a58 100644 --- a/include/emp/bits/bitset_utils.hpp +++ b/include/emp/bits/bitset_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2023. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file bitset_utils.hpp + * @file * @brief A set of simple functions to manipulate bitsets. * @note Status: BETA */ @@ -12,8 +13,9 @@ #define EMP_BITS_BITSET_UTILS_HPP_INCLUDE #include -#include +#include // uint8_t, uint16_t, etc. #include +#include #include #include "../base/Ptr.hpp" @@ -27,13 +29,13 @@ namespace emp { static constexpr size_t NUM_FIELD_BITS = sizeof(bits_field_t)*8; /// @brief Convert a bit count to the number of fields needed to store them. - [[nodiscard]] constexpr size_t NumBitFields(size_t num_bits) noexcept { + [[nodiscard]] static constexpr size_t NumBitFields(size_t num_bits) noexcept { return num_bits ? (1 + ((num_bits - 1) / NUM_FIELD_BITS)) : 0; } /// @brief Convert a single bit field to a string. /// @param field A single bit field to convert to a string. - [[nodiscard]] std::string BitFieldToString(bits_field_t field) { + [[nodiscard]] static std::string BitFieldToString(bits_field_t field) { std::stringstream ss; ss << '[' << std::hex << field << ']'; return ss.str(); @@ -41,7 +43,7 @@ namespace emp { /// @brief Convert a series of bit fields to a string. /// @param field A single bit field to convert to a string. - [[nodiscard]] std::string BitFieldsToString(emp::Ptr bits, size_t count) { + [[nodiscard]] static std::string BitFieldsToString(emp::Ptr bits, size_t count) { std::stringstream ss; for (size_t i = 0; i < count; ++i) { if (i) ss << ' '; @@ -97,11 +99,24 @@ namespace emp { /// Return the position of the first one bit template - [[nodiscard]] inline constexpr size_t find_bit(T val) { + [[nodiscard]] inline constexpr size_t find_bit(const T val) { static_assert( std::is_unsigned_v, "Bit manipulation requires unsigned values." ); return count_bits( (~val) & (val-1) ); } + /// Return the position of the first one bit + template + [[nodiscard]] inline constexpr size_t find_last_bit(T val) { + static_assert( std::is_unsigned_v, "Bit manipulation requires unsigned values." ); + val |= val >> 1; + val |= val >> 2; + val |= val >> 4; + if constexpr (sizeof(T) > 1) val |= val >> 8; + if constexpr (sizeof(T) > 2) val |= val >> 16; + if constexpr (sizeof(T) > 4) val |= val >> 32; + return count_bits(val) - 1; + } + /// Return the position of the first one bit AND REMOVE IT. template inline size_t pop_bit(T & val) { @@ -198,7 +213,7 @@ namespace emp { size_t bit_count ) { static_assert( std::is_unsigned_v, "Bit manipulation requires unsigned values." ); - constexpr size_t FIELD_BITS = sizeof(T) * 8; + [[maybe_unused]] constexpr size_t FIELD_BITS = sizeof(T) * 8; emp_assert(bit_count <= FIELD_BITS, "Cannot have more bits than can fit in field."); rotate_size %= bit_count; // Make sure rotate is in range. const T out = (in << rotate_size) | (in >> (bit_count - rotate_size)); @@ -226,7 +241,7 @@ namespace emp { size_t bit_count ) { static_assert( std::is_unsigned_v, "Bit manipulation requires unsigned values." ); - constexpr size_t FIELD_BITS = sizeof(T) * 8; + [[maybe_unused]] constexpr size_t FIELD_BITS = sizeof(T) * 8; emp_assert(bit_count <= FIELD_BITS, "Cannot have more bits than can fit in field."); rotate_size %= bit_count; // Make sure rotate is in range. const T out = (in >> rotate_size) | (in << (bit_count - rotate_size)); @@ -234,11 +249,13 @@ namespace emp { } /// Count the number of bits ('0' or '1') found in a string. - size_t CountBits(const std::string & bitstring) { - return std::count_if( - bitstring.begin(), - bitstring.end(), - [](char i) { return i == '0' || i == '1'; } + static size_t CountBits(const std::string & bitstring) { + return static_cast( + std::count_if( + bitstring.begin(), + bitstring.end(), + [](char i) { return i == '0' || i == '1'; } + ) ); } diff --git a/include/emp/compiler/DFA.hpp b/include/emp/compiler/DFA.hpp index c9b827512f..83becd0841 100644 --- a/include/emp/compiler/DFA.hpp +++ b/include/emp/compiler/DFA.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file DFA.hpp + * @file * @brief A Deterministic Finite Automata simulator. * @note Status: BETA */ @@ -11,7 +12,9 @@ #ifndef EMP_COMPILER_DFA_HPP_INCLUDE #define EMP_COMPILER_DFA_HPP_INCLUDE +#include #include +#include #include #include "../base/array.hpp" diff --git a/include/emp/compiler/Lexer.hpp b/include/emp/compiler/Lexer.hpp index d60a935395..8ba9070f1a 100644 --- a/include/emp/compiler/Lexer.hpp +++ b/include/emp/compiler/Lexer.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2023. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file Lexer.hpp + * @file * @brief A general-purpose, fast lexer. * @note Status: BETA * @@ -30,8 +31,10 @@ #ifndef EMP_COMPILER_LEXER_HPP_INCLUDE #define EMP_COMPILER_LEXER_HPP_INCLUDE +#include #include #include +#include #include #include "../base/map.hpp" @@ -193,6 +196,13 @@ namespace emp { /// How many types of tokens can be identified in this Lexer? size_t GetNumTokens() const { return token_set.size(); } + void Reset() { + token_set.resize(0); + token_map.clear(); + cur_token_id = MAX_ID; + generate_lexer = false; + } + bool TokenOK(int id) const { return id >= 0 && id < cur_token_id; } /// Add a new token, specified by a name and the regex used to identify it. diff --git a/include/emp/compiler/NFA.hpp b/include/emp/compiler/NFA.hpp index ae3bd23dcd..ba7bbc24ab 100644 --- a/include/emp/compiler/NFA.hpp +++ b/include/emp/compiler/NFA.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file NFA.hpp + * @file * @brief A Non-deterministic Finite Automata simulator * @note Status: BETA * @@ -23,8 +24,10 @@ #define EMP_COMPILER_NFA_HPP_INCLUDE +#include #include #include +#include #include "../base/vector.hpp" #include "../bits/BitSet.hpp" diff --git a/include/emp/compiler/RegEx.hpp b/include/emp/compiler/RegEx.hpp index e605808942..dc800332b5 100644 --- a/include/emp/compiler/RegEx.hpp +++ b/include/emp/compiler/RegEx.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file RegEx.hpp + * @file * @brief Basic regular expression handler. * @note Status: BETA * @@ -42,6 +43,7 @@ #include #include +#include #include #include "../base/Ptr.hpp" diff --git a/include/emp/compiler/lexer_utils.hpp b/include/emp/compiler/lexer_utils.hpp index 458f0485d4..503b4c4673 100644 --- a/include/emp/compiler/lexer_utils.hpp +++ b/include/emp/compiler/lexer_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file lexer_utils.hpp + * @file * @brief A set of utilities to convert between NFAs and DFAs * @note Status: BETA */ @@ -13,6 +14,7 @@ #include +#include #include // std::pair #include "../base/vector.hpp" @@ -23,6 +25,10 @@ namespace emp { + /** \addtogroup + * @{ + */ + /// Converting DFA to DFA -- no change needed. static inline const DFA & to_DFA(const DFA & dfa) { return dfa; } @@ -52,7 +58,7 @@ namespace emp { std::set next_state = nfa.GetNext(sym, cur_state); if (next_state.size() == 0 && !keep_invalid) continue; // Discard invalid transitions. - // Remove NFA states with ONLY free transisions (they will all have been taken already) + // Remove NFA states with ONLY free transitions (they will all have been taken already) // @CAO do more elegantly! emp::vector remove_set; for (auto x : next_state) if (nfa.IsEmpty(x)) remove_set.push_back(x); @@ -91,7 +97,7 @@ namespace emp { } - /// Merge multiple automata into one NFA (base case, single converstion) + /// Merge multiple automata into one NFA (base case, single conversion) template static NFA MergeNFA(T1 && in) { return to_NFA(std::forward(in)); @@ -143,6 +149,9 @@ namespace emp { return ""; } + + // Close Doxygen group + /** @}*/ } #endif // #ifndef EMP_COMPILER_LEXER_UTILS_HPP_INCLUDE diff --git a/include/emp/compiler/regex_utils.hpp b/include/emp/compiler/regex_utils.hpp index 7e92b7109d..cf70984900 100644 --- a/include/emp/compiler/regex_utils.hpp +++ b/include/emp/compiler/regex_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file regex_utils.hpp + * @file * @brief Helper functions for building regular expressions. * @note Status: BETA */ diff --git a/include/emp/config/ArgManager.hpp b/include/emp/config/ArgManager.hpp index f84fce2c27..e0da716708 100644 --- a/include/emp/config/ArgManager.hpp +++ b/include/emp/config/ArgManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file ArgManager.hpp + * @file * @brief A tool for sythesizing command-line arguments, URL query params, and config files. * @note Status: BETA */ @@ -18,6 +19,7 @@ #include #include #include +#include #include #include @@ -680,11 +682,17 @@ namespace emp { }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace cl { + #endif // DOXYGEN_SHOULD_SKIP_THIS /// A simple class to manage command-line arguments that were passed in. /// Derived from emp::vector, but with added functionality for argument handling. - class ArgManager : public emp::vector { + class + #ifdef DOXYGEN_SHOULD_SKIP_THIS + cl:: + #endif + ArgManager : public emp::vector { private: using parent_t = emp::vector; emp::vector arg_names; @@ -792,8 +800,9 @@ namespace emp { }; - + #ifndef DOXYGEN_SHOULD_SKIP_THIS } + #endif // DOXYGEN_SHOULD_SKIP_THIS } #endif // #ifndef EMP_CONFIG_ARGMANAGER_HPP_INCLUDE diff --git a/include/emp/config/ConfigManager.hpp b/include/emp/config/ConfigManager.hpp index 4c760d555d..c8e8afb458 100644 --- a/include/emp/config/ConfigManager.hpp +++ b/include/emp/config/ConfigManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file ConfigManager.hpp + * @file * @brief The ConfigManager templated class handles the building and configuration of new objects * of the target type. * diff --git a/include/emp/config/FlagManager.hpp b/include/emp/config/FlagManager.hpp new file mode 100644 index 0000000000..7f93db13f5 --- /dev/null +++ b/include/emp/config/FlagManager.hpp @@ -0,0 +1,173 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + * @brief This file contains tools for dealing with command-line flags (from argv and argc). + * @note Status: ALPHA + * + * The FlagManager class will take command line arguments (either in its constructor or with + * the AddFlags() function) and process them appropriately. + * + * For setup, the user must run AddOption with the function to call. Functions to call can take + * zero, one, or two Strings as arguments OR they can take a vector of Strings and the range of + * allowed arguments should be specified. When Process() is run, the appropriate function will + * be called on each and any invalid arguments will trigger an error. + * + * Flags are expected to begin with a '-' and non-flags are expected to NOT begin with a '-'. + * + * If a single dash is followed by multiple characters, each will be processed independently. + * So, "-abc" will be the same as "-a -b -c". + * + * Extra command line arguments will be saves as a vector of strings called "extras" and must + * be processed manually. They can be retrieved with GetExtras(). + * + * + * @todo: Make variable numbers of flag arguments work. + */ + +#ifndef EMP_CONFIG_FLAGMANAGER_HPP_INCLUDE +#define EMP_CONFIG_FLAGMANAGER_HPP_INCLUDE + +#include +#include +#include +#include + +#include "../base/vector.hpp" +#include "../datastructs/map_utils.hpp" +#include "../tools/String.hpp" + +namespace emp { + + class FlagManager { + private: + emp::vector args; + emp::vector extras; + + struct FlagInfo { + String desc; + size_t min_args = 0; + size_t max_args = 0; + std::function &)> fun; + char shortcut = '\0'; + }; + + std::map flag_options; + std::map shortcuts; + + public: + FlagManager() { } + FlagManager(int argc, char* argv[]) { AddFlags(argc, argv); } + + constexpr static size_t npos = static_cast(-1); + + [[nodiscard]] String & operator[](size_t pos) { return args[pos]; } + [[nodiscard]] const String & operator[](size_t pos) const { return args[pos]; } + + emp::vector GetExtras() const { return extras; } + + [[nodiscard]] size_t Find(String pattern) const { + for (size_t i = 0; i < args.size(); ++i) if (args[i] == pattern) return i; + return npos; + } + + [[nodiscard]] bool Has(String pattern) const { return Find(pattern) != npos; } + + // Return true/false if a specific argument is present and REMOVE IT. + bool Use(String pattern) { + size_t pos = Find(pattern); + if (pos == npos) return false; + args.erase(args.begin() + pos); + return true; + } + + void AddOption(String name, String desc="") { + flag_options[name] = FlagInfo{desc, 0, 0, [](const emp::vector &){} }; + } + void AddOption(String name, std::function fun, String desc="") { + flag_options[name] = FlagInfo{desc, 0,0, [fun](const emp::vector &){fun();}}; + } + void AddOption(String name, std::function fun, String desc="") { + flag_options[name] = FlagInfo{desc, 1,1, [fun](const emp::vector & in){fun(in[0]);}}; + } + void AddOption(String name, std::function fun, String desc="") { + flag_options[name] = FlagInfo{desc, 2,2, [fun](const emp::vector & in){fun(in[0],in[1]);}}; + } + void AddOption(String name, std::function &)> fun, + size_t min_args=0, size_t max_args=npos, String desc="") { + flag_options[name] = FlagInfo{desc, min_args,max_args, fun}; + } + + // Allow an option to have a single-letter flag (e.g. "-h" is short for "--help") + template + void AddOption(char shortcut, String name, FUN_T fun, String desc="") { + AddOption(name, fun, desc); + shortcuts[shortcut] = name; + flag_options[name].shortcut = shortcut; + } + + void AddFlags(int argc, char* argv[]) { + for (size_t i = 0; i < (size_t) argc; i++) { + args.push_back(argv[i]); + } + } + + // Process an argument associated with a particular name; return num additional args used. + size_t ProcessArg(String name, size_t cur_pos=0) { + if (!emp::Has(flag_options, name)) { emp::notify::Error("Unknown flag '", name , "'."); } + auto option = flag_options[name]; + emp::vector flag_args; + for (size_t i = 1; i <= option.min_args; ++i) { + flag_args.push_back(args[cur_pos+i]); + } + option.fun(flag_args); + return option.min_args; + } + + // Process an argument associated with a particular character; return num additional args used. + size_t ProcessArg(char c, size_t cur_pos=0) { + if (!emp::Has(shortcuts, c)) { emp::notify::Error("Unknown flag '-", c , "'."); } + return ProcessArg(shortcuts[c], cur_pos); + } + + // Process the argument at a given position. Return number of additional args consumed. + size_t ProcessFlagSet(String name, size_t cur_pos=0) { + size_t offset = 0; + for (size_t i = 1; i < name.size(); ++i) { + offset += ProcessArg(name[i], cur_pos+offset); + } + return offset; + } + + // Process all of the flag data that we have. + void Process() { + for (size_t i = 1; i < args.size(); ++i) { + String & arg = args[i]; + if (arg[0] == '-') { // We have a flag! + if (arg.size() > 1 && arg[1] == '-') i += ProcessArg(arg, i); + else i += ProcessFlagSet(arg, i); + } + else extras.push_back(arg); + } + } + + void PrintOptions(std::ostream & os=std::cout) const { + for (const auto & [name, options] : flag_options) { + os << " " << name; + if (options.shortcut) { + os << " (or '-" << options.shortcut << "')"; + } + if (options.desc.size()) { + os << " : " << options.desc; + } + os << "\n"; + } + } + }; + +} + +#endif // #ifndef EMP_CONFIG_FLAGMANAGER_HPP_INCLUDE diff --git a/include/emp/config/SettingCombos.hpp b/include/emp/config/SettingCombos.hpp index 879c878946..d317b09882 100644 --- a/include/emp/config/SettingCombos.hpp +++ b/include/emp/config/SettingCombos.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SettingCombos.hpp + * @file * @brief A tool for exploring all parameter combinations * @note Status: ALPHA */ @@ -12,6 +13,7 @@ #define EMP_CONFIG_SETTINGCOMBOS_HPP_INCLUDE #include +#include #include #include #include diff --git a/include/emp/config/SettingConfig.hpp b/include/emp/config/SettingConfig.hpp index 7b059c8a4a..f307c30ef0 100644 --- a/include/emp/config/SettingConfig.hpp +++ b/include/emp/config/SettingConfig.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SettingConfig.hpp + * @file * @brief A tool for collecting settings, including from files and the command line. * @note Status: DEPRECATED! */ @@ -12,6 +13,7 @@ #define EMP_CONFIG_SETTINGCONFIG_HPP_INCLUDE #include +#include #include #include #include @@ -381,7 +383,7 @@ namespace emp { } /// Convert all of the current values into a comma-separated string. - std::string CurComboString(const std::string & separator=",", + std::string CurComboString(const std::string & separator=",", ///< Delimiter separating values in string bool use_labels=false, ///< Print name with each value? bool multi_only=false ///< Only print values that can change? ) const { diff --git a/include/emp/config/command_line.hpp b/include/emp/config/command_line.hpp index 1bc0c251e5..0ea7b1eb9b 100644 --- a/include/emp/config/command_line.hpp +++ b/include/emp/config/command_line.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file command_line.hpp + * @file * @brief This file contains tools for dealing with command-line arguments (argv and argc). * * Functions here include: @@ -34,6 +35,7 @@ #ifndef EMP_CONFIG_COMMAND_LINE_HPP_INCLUDE #define EMP_CONFIG_COMMAND_LINE_HPP_INCLUDE +#include #include #include "../base/vector.hpp" diff --git a/include/emp/config/config.hpp b/include/emp/config/config.hpp index 4f0fe3c93d..92b86c9dad 100644 --- a/include/emp/config/config.hpp +++ b/include/emp/config/config.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019. - * - * @file config.hpp + * @file * @brief Maintains a set of configuration options. * * This file defines a master configuration option Config, whose values can be loaded @@ -42,6 +43,7 @@ #include #include #include +#include #include #include @@ -402,7 +404,9 @@ namespace emp { for (auto & x : type_manager_map) delete x.second; } + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend class ConfigWebUI; + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ ConfigEntry * operator[](const std::string & name) { return var_map[name]; } auto begin() -> decltype(var_map.begin()) { return var_map.begin(); } diff --git a/include/emp/config/config_utils.hpp b/include/emp/config/config_utils.hpp index e6fb43fb7c..522ac4fc17 100644 --- a/include/emp/config/config_utils.hpp +++ b/include/emp/config/config_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file config_utils.hpp + * @file * @brief Helper functions for working with emp::Config objects. * */ diff --git a/include/emp/config/config_web_interface.hpp b/include/emp/config/config_web_interface.hpp index 647539fcd1..1ea9f4d07f 100644 --- a/include/emp/config/config_web_interface.hpp +++ b/include/emp/config/config_web_interface.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file config_web_interface.hpp + * @file * @brief TODO. */ @@ -12,6 +13,7 @@ #include #include +#include #include "../datastructs/set_utils.hpp" #include "../tools/string_utils.hpp" @@ -31,11 +33,13 @@ namespace emp { std::set exclude; std::map group_divs; std::map input_map; + #ifndef DOXYGEN_SHOULD_SKIP_THIS std::function on_change_fun = [](const std::string & val){;}; std::function format_label_fun = [](std::string name){ emp::vector sliced = slice(name, '_'); return to_titlecase(join(sliced, " ")); }; + #endif // DOXYGEN_SHOULD_SKIP_THIS public: ConfigWebUI(Config & c, const std::string & div_name = "settings_div") : config(c), settings_div(div_name) {;} diff --git a/include/emp/control/Action.hpp b/include/emp/control/Action.hpp index 2004ef2037..25896e5591 100644 --- a/include/emp/control/Action.hpp +++ b/include/emp/control/Action.hpp @@ -1,20 +1,22 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Action.hpp + * @file * @brief A mechanism to abstract functions from their underlying type and provide run-time names. * @note Status: Beta * * @todo Create an ActionDefaults class that can take fewer args than expected and fill in rest. - * @todo Allow for named arguments to facilite intepreted functions. + * @todo Allow for named arguments to facilitate interpreted functions. */ #ifndef EMP_CONTROL_ACTION_HPP_INCLUDE #define EMP_CONTROL_ACTION_HPP_INCLUDE #include +#include #include namespace emp { @@ -22,8 +24,7 @@ namespace emp { /// BaseActions abstract functions and allow for signals to be setup at runtime; they can be /// called with types specified in the call. /// - /// Actions can be a bit heavyweight, but can easily be converted to more lightweight - /// std:function objects. + /// Actions can be a bit heavyweight, but can easily be converted to std::function objects. class ActionBase { protected: @@ -59,11 +60,11 @@ namespace emp { size_t GetArgCount() const { return ARG_COUNT; } }; - /// The declaration for Action has any template types; the only definined specilizations require + /// The declaration for Action has any template types; the only defined specializations require /// a function type to be specified (with void and non-void return type variants.) template class Action; - /// This Action class specialization takes a function with a void return tyime and builds it off + /// This Action class specialization takes a function with a void return type and builds it off /// of the action base classes. template class Action : public ActionSize { @@ -95,7 +96,7 @@ namespace emp { }; - /// This Action class specialization takes a function with any non-void return tyime and builds it + /// This Action class specialization takes a function with any non-void return type and builds it /// off of the action base classes. template class Action : public ActionSize { diff --git a/include/emp/control/ActionManager.hpp b/include/emp/control/ActionManager.hpp index 32bf6df875..40c71b11f1 100644 --- a/include/emp/control/ActionManager.hpp +++ b/include/emp/control/ActionManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file ActionManager.hpp + * @file * @brief ActionManager collects sets of Actions to be looked up or manipulated later. * @note Status: Beta */ @@ -11,6 +12,7 @@ #ifndef EMP_CONTROL_ACTIONMANAGER_HPP_INCLUDE #define EMP_CONTROL_ACTIONMANAGER_HPP_INCLUDE +#include #include #include diff --git a/include/emp/control/Signal.hpp b/include/emp/control/Signal.hpp index d347df85e1..012c331893 100644 --- a/include/emp/control/Signal.hpp +++ b/include/emp/control/Signal.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file Signal.hpp + * @file * @brief Allow functions to be bundled (as Actions) and triggered enmasse. * @note Status: Beta * @@ -15,7 +16,9 @@ #define EMP_CONTROL_SIGNAL_HPP_INCLUDE +#include #include +#include #include #include "../datastructs/map_utils.hpp" @@ -75,12 +78,13 @@ namespace emp { operator bool() { return key_id > 0; } }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS // Forward declarations. class SignalBase; // ...for pointers to signals. class SignalManager; // ...for setting up as friend. // Mechanisms for Signals to report to a manager. - #ifndef DOXYGEN_SHOULD_SKIP_THIS + namespace internal { struct SignalManager_Base { virtual void NotifyConstruct(SignalBase * sig_ptr) = 0; @@ -103,7 +107,7 @@ namespace emp { std::string name; ///< What is the unique name of this signal? uint32_t signal_id; ///< What is the unique ID of this signal? - uint32_t next_link_id; ///< What ID shouild the next link have? + uint32_t next_link_id; ///< What ID should the next link have? std::map link_key_map; ///< Map unique link keys to link index for actions. emp::vector managers; ///< What manager is handling this signal? man_t * prime_manager; ///< Which manager leads deletion? (nullptr for self) @@ -111,7 +115,7 @@ namespace emp { // Helper Functions SignalKey NextSignalKey() { return SignalKey(signal_id,++next_link_id); } - // SignalBase should only be constructable from derrived classes. + // SignalBase should only be constructable from derived classes. SignalBase(const std::string & n, internal::SignalManager_Base * manager=nullptr) : name(n), signal_id(0), next_link_id(0), link_key_map(), managers(), prime_manager(nullptr) { @@ -359,9 +363,10 @@ namespace emp { }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS template inline void SignalBase::BaseTrigger(ARGS... args) { - // Make sure this base class is really of the correct derrived type (but do so in an + // Make sure this base class is really of the correct derived type (but do so in an // assert since triggers may be called frequently and should be fast!) emp_assert(dynamic_cast< Signal * >(this)); ((Signal *) this)->Trigger(args...); @@ -373,7 +378,7 @@ namespace emp { emp_assert(dynamic_cast< Signal * >(this)); return ((Signal *) this)->AddAction(in_fun); } - + #endif // DOXYGEN_SHOULD_SKIP_THIS } #endif // #ifndef EMP_CONTROL_SIGNAL_HPP_INCLUDE diff --git a/include/emp/control/SignalControl.hpp b/include/emp/control/SignalControl.hpp index 82bf0a7982..f7bd48a427 100644 --- a/include/emp/control/SignalControl.hpp +++ b/include/emp/control/SignalControl.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SignalControl.hpp + * @file * @brief The SignalControl class manages all of the signals and actions, linking them together * upon request (by name, base class, or derived class). * @@ -17,6 +18,8 @@ #ifndef EMP_CONTROL_SIGNALCONTROL_HPP_INCLUDE #define EMP_CONTROL_SIGNALCONTROL_HPP_INCLUDE +#include +#include #include #include diff --git a/include/emp/control/SignalManager.hpp b/include/emp/control/SignalManager.hpp index 570c26bd18..6ed8a76881 100644 --- a/include/emp/control/SignalManager.hpp +++ b/include/emp/control/SignalManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SignalManager.hpp + * @file * @brief This file defines the SignalManager class, which collects sets of Signals to be looked up * or manipulated later. */ @@ -11,6 +12,8 @@ #ifndef EMP_CONTROL_SIGNALMANAGER_HPP_INCLUDE #define EMP_CONTROL_SIGNALMANAGER_HPP_INCLUDE +#include +#include #include #include diff --git a/include/emp/data/AnnotatedType.hpp b/include/emp/data/AnnotatedType.hpp index 48c16030dc..073fd8152f 100644 --- a/include/emp/data/AnnotatedType.hpp +++ b/include/emp/data/AnnotatedType.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file AnnotatedType.hpp - * @brief A base class to provide a DataMap and accessors to another class. + * @file + * @brief A base class to provide a DataMap and accessors to derived classes. * @note Status: ALPHA * */ @@ -85,7 +86,6 @@ namespace emp { } }; - } #endif // #ifndef EMP_DATA_ANNOTATEDTYPE_HPP_INCLUDE diff --git a/include/emp/data/DataFile.hpp b/include/emp/data/DataFile.hpp index 86dd2496f8..6a1ecc307a 100644 --- a/include/emp/data/DataFile.hpp +++ b/include/emp/data/DataFile.hpp @@ -1,18 +1,21 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file DataFile.hpp + * @file * @brief DataFile objects use DataNode objects to dynamically fill out file contents. */ #ifndef EMP_DATA_DATAFILE_HPP_INCLUDE #define EMP_DATA_DATAFILE_HPP_INCLUDE +#include #include #include #include +#include #include #include "../base/assert.hpp" @@ -62,8 +65,11 @@ namespace emp { , line_begin(b), line_spacer(s), line_end(e) { ; } DataFile(std::ostream & in_os, const std::string & b="", const std::string & s=",", const std::string & e="\n") - : filename(), os(&in_os), funs(), pre_funs(), keys(), descs(), timing_fun([](size_t){return true;}) - , line_begin(b), line_spacer(s), line_end(e) { ; } + : filename(), os(&in_os), funs(), pre_funs(), keys(), descs(), timing_fun( + #ifndef DOXYGEN_SHOULD_SKIP_THIS + [](size_t){return true;} + #endif + ), line_begin(b), line_spacer(s), line_end(e) { ; } DataFile(const DataFile &) = default; DataFile(DataFile &&) = default; @@ -88,9 +94,10 @@ namespace emp { /// Setup this file to print only once, at the specified update. Note that this timing /// function can be replaced at any time, even after being triggered. + /// @param print_time The update the file should print at void SetTimingOnce(size_t print_time) { - timing_fun = [print_time](size_t update) { return update == print_time; }; - } + timing_fun = [print_time](size_t update) { return update == print_time; }; + } /// Setup this file to print every 'step' updates. void SetTimingRepeat(size_t step) { diff --git a/include/emp/data/DataInterface.hpp b/include/emp/data/DataInterface.hpp index 14b42e0978..a7a6434cea 100644 --- a/include/emp/data/DataInterface.hpp +++ b/include/emp/data/DataInterface.hpp @@ -1,15 +1,17 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file DataInterface.hpp + * @file * @brief DataInterface is a *generic* interface to a DataNode. */ #ifndef EMP_DATA_DATAINTERFACE_HPP_INCLUDE #define EMP_DATA_DATAINTERFACE_HPP_INCLUDE +#include #include "DataNode.hpp" @@ -21,29 +23,64 @@ namespace emp { public: virtual ~DataInterface() { ; } + /// Returns the number values added to this node since the last reset. virtual size_t GetCount() const = 0; + + /// Returns the number of times this node has been reset. virtual size_t GetResetCount() const = 0; + /// Returns the sum of values added since the last reset. + /// Requires that the data::Range or data::FullRange be added to the DataNode virtual double GetTotal() const = 0; + /// Returns the mean of the values added since the last reset. + /// Requires that the data::Range or data::FullRange be added to the DataNode virtual double GetMean() const = 0; + /// Returns the minimum of the values added since the last reset. + /// Requires that the data::Range or data::FullRange be added to the DataNode virtual double GetMin() const = 0; + /// Returns the maximum of the values added since the last reset. + /// Requires that the data::Range or data::FullRange be added to the DataNode virtual double GetMax() const = 0; + /// Returns the variance of the values added since the last reset. + /// Requires that the data::Stats or data::FullStats be added to the DataNode virtual double GetVariance() const = 0; + /// Returns the standard deviation of the values added since the last reset. + /// Requires that the data::Stats or data::FullStats be added to the DataNode virtual double GetStandardDeviation() const = 0; + /// Returns the skewness of the values added since the last reset. + /// Requires that the data::Stats or data::FullStats be added to the DataNode virtual double GetSkew() const = 0; + /// Returns the kurtosis of the values added since the last reset. + /// Requires that the data::Stats or data::FullStats be added to the DataNode virtual double GetKurtosis() const = 0; + /// Runs the Pull function for this DataNode and records the resulting values. + /// Requires that the data::Pull module was added to this DataNode, and that a pull function + /// was specified. virtual void PullData() = 0; + /// Reset this node. The exact effects of this depend on the modules that this node has, + /// but in general it prepares the node to receive a new set of data. virtual void Reset() = 0; + /// Print debug information about this node to the provided stream + /// Useful for tracking which modifiers are included. + /// @param os The stream to print debug information to virtual void PrintDebug(std::ostream & os=std::cout) = 0; + /// Returns this node's name. Requires that the data::Info module was + /// added to this DataNode, and that a name was set. virtual void GetName() = 0; + /// Returns this node's description. Requires that the data::Info module was + /// added to this DataNode, and that a description was set. virtual void GetDescription() = 0; + /// Returns this node's keyword. Requires that the data::Info module was + /// added to this DataNode, and that a keyword was set. virtual void GetKeyword() = 0; }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS + template class DataInterface_Impl : public DataInterface { public: @@ -128,6 +165,7 @@ namespace emp { }; + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ template DataInterface * MakeDataInterface() { diff --git a/include/emp/data/DataLayout.hpp b/include/emp/data/DataLayout.hpp index 5ad2ea44c3..661a29c418 100644 --- a/include/emp/data/DataLayout.hpp +++ b/include/emp/data/DataLayout.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2022. - * - * @file DataLayout.hpp + * @file * @brief A mapping of names to variables stored in a MemoryImage. * @note Status: ALPHA */ @@ -11,6 +12,7 @@ #ifndef EMP_DATA_DATALAYOUT_HPP_INCLUDE #define EMP_DATA_DATALAYOUT_HPP_INCLUDE +#include #include #include diff --git a/include/emp/data/DataLog.hpp b/include/emp/data/DataLog.hpp index 9e9b9fa276..05e56f70af 100644 --- a/include/emp/data/DataLog.hpp +++ b/include/emp/data/DataLog.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file DataLog.hpp + * @file * @brief Tools for processing a single set of data. * @note Status: ALPHA * @@ -16,6 +17,7 @@ #include #include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" diff --git a/include/emp/data/DataManager.hpp b/include/emp/data/DataManager.hpp index 3e5dbd4609..b78553f79b 100644 --- a/include/emp/data/DataManager.hpp +++ b/include/emp/data/DataManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file DataManager.hpp + * @file * @brief DataManager handles a set of DataNode objects with the same tracking settings. */ @@ -11,6 +12,7 @@ #define EMP_DATA_DATAMANAGER_HPP_INCLUDE #include +#include #include #include "../base/assert.hpp" @@ -36,22 +38,12 @@ namespace emp { } // so we can use range-based for loops - auto begin() -> decltype(std::begin(node_map)) { - return std::begin(node_map); - } - // so we can use range-based for loops - auto end() -> decltype(std::end(node_map)) { - return std::end(node_map); - } + auto begin() { return std::begin(node_map); } + auto end() { return std::end(node_map); } // so we can use range-based for loops with const - auto begin() const -> const decltype(std::begin(node_map)) { - return std::begin(node_map); - } - // so we can use range-based for loops with const - auto end() const -> const decltype(std::end(node_map)) { - return std::end(node_map); - } + auto begin() const { return std::begin(node_map); } + auto end() const { return std::end(node_map); } /// @returns the number of DataNodes in this DataManager size_t GetSize() const { return node_map.size(); } @@ -91,10 +83,10 @@ namespace emp { } /// @returns a reference to the node with the specified name - /// Throws an error if there is no node with that name in this manager /// @param name the name of the DataNode node_t & Get(const std::string & name) { - emp_assert(Has(node_map, name), name, emp::to_string(Keys(node_map))); + emp_assert(Has(node_map, name), name); + emp_assert(node_map[name] != nullptr); return *(node_map[name]); } diff --git a/include/emp/data/DataMap.hpp b/include/emp/data/DataMap.hpp index f2c2d0f6e7..baa41ae205 100644 --- a/include/emp/data/DataMap.hpp +++ b/include/emp/data/DataMap.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2022. - * - * @file DataMap.hpp + * @file * @brief A DataMap links names to arbitrary object types. * @note Status: ALPHA * @@ -46,7 +47,7 @@ * to be stored elsewhere (presumably in the memory image, but possibly in the layout.) * 5. The memory is a LOG of values, not a single value. This allows for quick identification * of when something special needs to be done. - * 6-8. Limited type information (8 types that can be handled more effectively?) + * 6-8. Limited type information (7 types that can be handled more effectively?) * * - We should be able to keep a series of values, not just a single one. This can be done with * a series of new functions: @@ -56,7 +57,7 @@ * Add GetAve() function for logs as well as GetLog() for the full series (as std::span?). * * - Settings for all entries should have more information on how they are dealt with, such as if - * they should be included in output an how. Perhaps a system of tags for dynamic use? + * they should be included in output and how. Perhaps a system of tags for dynamic use? * * - After everything else is working, build a LocalDataMap that locks in the size at * compile time, providing more localized memory. Otherwise DataMap as a whole can be built @@ -73,8 +74,9 @@ * to allow for multiple parents... * * - An OptimizeLayout() function that can reorder entries so that they are somehow more sensible? + * Does DataMap need to worry about memory alignment? * - * - A MemoryImage factory to speed up allocation, deallocation if we're using the same size + * - A MemoryImage factory to speed up allocation and deallocation if we're using the same size * images repeatedly. * * - Some way of grouping memory across DataMaps so that a particular entry for many maps has all @@ -89,6 +91,7 @@ #include // For std::memcpy #include +#include #include #include "../base/assert.hpp" diff --git a/include/emp/data/DataNode.hpp b/include/emp/data/DataNode.hpp index 6d978a2a8f..7fb9bf1413 100644 --- a/include/emp/data/DataNode.hpp +++ b/include/emp/data/DataNode.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file DataNode.hpp + * @file * @brief DataNode objects track a specific type of data over the course of a run. * * Collection: New data can be pushed or pulled. @@ -26,6 +27,7 @@ #include #include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" @@ -65,6 +67,7 @@ namespace emp { }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS /// A shortcut for converting DataNode mod ID's to ValPacks. template using ModPack = emp::ValPack<(int) MODS...>; @@ -86,13 +89,14 @@ namespace emp { using type = typename next_type::template append; }; - /// Generic form of DataNodeModule (should never be used; trigger error!) template class DataNodeModule { public: DataNodeModule() { emp_assert(false, "Unknown module used in DataNode!"); } }; + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ + /// Base form of DataNodeModule (available in ALL data nodes.) template class DataNodeModule { @@ -158,8 +162,15 @@ namespace emp { /// == data::Current == /// This module lets you track the current (i.e. most recently added) value + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Current to the template arguments on your DataNode. Do not use the + /// CurrentModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class CurrentModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: VAL_TYPE cur_val; ///< Most recent value passed to this node. @@ -186,8 +197,15 @@ namespace emp { /// == data::Info == /// This module adds information such as a name, description, and keyword for this node. + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Info to the template arguments on your DataNode. Do not use the + /// InfoModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class InfoModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: std::string name; ///< Name of this data category. std::string desc; ///< Description of this type of data. @@ -229,8 +247,15 @@ namespace emp { /// == data::Log == /// This module lets you log all of the values that have been added since the last re-set + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Log to the template arguments on your DataNode. Do not use the + /// LogModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class LogModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: emp::vector val_set; ///< All values saved since last reset. @@ -294,8 +319,15 @@ namespace emp { /// This module keeps track of historical values in addition to those added since the last re-set. /// Every time Reset() is called, all values that have been added since the previous time Reset() /// are stored in a vector in the archive. + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Archive to the template arguments on your DataNode. Do not use the + /// ArchiveModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class ArchiveModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: emp::vector> archive; ///< Data archived from before most recent reset. @@ -341,8 +373,15 @@ namespace emp { /// == data::Range == /// This module allows this DataNode to store information (min, max, mean, count, and total) about /// the distribution of the values that have been added since the last call to Reset(). + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Range to the template arguments on your DataNode. Do not use the + /// RangeModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class RangeModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: double total; ///< Total of all data since last reset. double min; ///< Smallest value passed in since last reset. @@ -395,8 +434,15 @@ namespace emp { /// This module makes the DataNode store a history of distributional information measured by /// data::Range between calls to Reset(). Series of historical values are stored in vectors /// (except mean, which is calculated from total and count). + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Histogram to the template arguments on your DataNode. Do not use the + /// FullRangeModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class FullRangeModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: emp::vector total_vals; ///< Totals from previous resets. emp::vector num_vals; ///< Value counts from previous resets. @@ -467,9 +513,15 @@ namespace emp { /// /// Note 2: Kurtosis is calculated using Snedecor and Cochran (1967)'s formula. A perfect normal /// distribution has a kurtosis of 0. - + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Stats to the template arguments on your DataNode. Do not use the + /// StatsModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class StatsModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: // Running variance, skew, and kurtosis calculations based off of this class: // https://www.johndcook.com/blog/skewness_kurtosis/ @@ -546,8 +598,16 @@ namespace emp { /// == data::Histogram == /// Make the DataNode track a histogram of values observed since the last reset. + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Histogram to the template arguments on your DataNode. Do not use the + /// HistogramModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class HistogramModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS + protected: VAL_TYPE offset; ///< Min value in first bin; others are offset by this much. VAL_TYPE width; ///< How wide is the overall histogram? @@ -586,7 +646,7 @@ namespace emp { /// upper bound on the histogram int GetOverflow() const {return overflow;} - /// Return the count of numbers added to this histogram that were belowed the + /// Return the count of numbers added to this histogram that were below the /// allowed lower bound int GetUnderflow() const {return underflow;} @@ -631,7 +691,7 @@ namespace emp { parent_t::AddDatum(val); } - /// Reset the DataNode (empties the historgram) + /// Reset the DataNode (empties the histogram) void Reset() { for (size_t & x : counts) x = 0.0; parent_t::Reset(); @@ -650,9 +710,17 @@ namespace emp { /// new values or sets of values that it will then track. These functions are called every time /// the PullData method is called on this node, and the values they return are measured as /// specified by the other modules in this node. + #ifndef DOXYGEN_SHOULD_SKIP_THIS template class DataNodeModule : public DataNodeModule { + #else + /// To use this class, add data::Pull to the template arguments on your DataNode. Do not use the + /// PullModule class directly - it is a simplification for documentation purposes and does not + /// actually exist. + class PullModule { + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: + #ifndef DOXYGEN_SHOULD_SKIP_THIS emp::FunctionSet pull_funs; ///< Functions to pull data. emp::FunctionSet()> pull_set_funs; ///< Functions to pull sets of data. @@ -669,6 +737,7 @@ namespace emp { in_vals.insert(in_vals.end(), x.begin(), x.end()); } } + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ public: DataNodeModule() : pull_funs(), pull_set_funs() { ; } @@ -682,6 +751,8 @@ namespace emp { } }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS + template class DataNode_Interface; /// Outermost interface to all DataNode modules. @@ -691,7 +762,7 @@ namespace emp { using parent_t = DataNodeModule; }; - /// A template that will determing requisites, sort, make unique the data mods provided. + /// A template that will determine requisites, sort, make unique the data mods provided. /// The final, sorted ValPack of the requisites plus originals is in 'sorted'. template struct FormatDataMods { @@ -699,6 +770,7 @@ namespace emp { using full = typename ModPack::template append; ///< Requisites + originals using sorted = pack::RUsort; ///< Unique and in order }; + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ template class DataNode : public DataNode_Interface< VAL_TYPE, typename FormatDataMods::sorted > { diff --git a/include/emp/data/Datum.hpp b/include/emp/data/Datum.hpp index 302290d83d..6abf9ce04c 100644 --- a/include/emp/data/Datum.hpp +++ b/include/emp/data/Datum.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file Datum.hpp + * @file * @brief A single piece of data, either a value or a string. * @note Status: ALPHA * @@ -31,20 +32,25 @@ namespace emp { }; bool is_num = true; - void InitString() { new (&str) std::string; } - void InitString(const std::string & in) { new (&str) auto(in); } - void FreeString() { str.~basic_string(); } + void InitString() { new (&str) std::string; is_num = false; } + template + void InitString(T && in) { new (&str) std::string(std::forward(in)); is_num = false; } + void FreeString() { if (!is_num) str.~basic_string(); } public: Datum() : num(0.0), is_num(true) { } Datum(double in) : num(in), is_num(true) { } - Datum(const std::string & in) : is_num(false) { InitString(in); } - Datum(const char * in) : is_num(false) { InitString(in); } + Datum(const std::string & in) { InitString(in); } + Datum(std::string && in) { InitString(in); } + Datum(const char * in) { InitString(in); } Datum(const Datum & in) { - is_num = in.is_num; - if (is_num) num = in.num; + if (in.is_num) num = in.num; else InitString(in.str); } - ~Datum() { if (!is_num) FreeString(); } + Datum(Datum && in) { + if (in.is_num) num = in.num; + else InitString(std::move(in.str)); + } + ~Datum() { FreeString(); } bool IsDouble() const { return is_num; } ///< Is this natively stored as a double? bool IsString() const { return !is_num; } ///< Is this natively stored as a string? @@ -78,25 +84,19 @@ namespace emp { //return std::to_string(num); } -// operator bool() const { return AsDouble() != 0.0; } operator double() const { return AsDouble(); } operator std::string() const { return AsString(); } Datum & SetDouble(double in) { // If this were previously a string, clean it up! - if (!is_num) { - FreeString(); - is_num = true; - } + FreeString(); // If there was previously a string, make sure to free it. + is_num = true; num = in; return *this; } Datum & SetString(const std::string & in) { - if (is_num) { // If this were previously a num, change to string. - InitString(in); - is_num = false; - } - else str = in; // Already a string; just change its value. + if (is_num) InitString(in); // Convert to string. + else str = in; // Already a string. return *this; } @@ -111,10 +111,11 @@ namespace emp { Datum & operator=(const Datum & in) { return Set(in); } // Unary operators + Datum operator+() const { return AsDouble(); } Datum operator-() const { return -AsDouble(); } Datum operator!() const { return AsDouble() == 0.0; } - // Binary operators + // Comparison operators int CompareNumber(double rhs) const { const double val = AsDouble(); return (val == rhs) ? 0 : ((val < rhs) ? -1 : 1); @@ -140,6 +141,24 @@ namespace emp { template bool operator> (const T & rhs) const { return Compare(rhs) == 1; } template bool operator<=(const T & rhs) const { return Compare(rhs) != 1; } + // Binary Operators + + Datum operator+(double in) const { + if (IsDouble()) return NativeDouble() + in; + return NativeString() + std::to_string(in); + } + Datum operator*(double in) const { + if (IsDouble()) return NativeDouble() * in; + std::string out_string; + const size_t count = static_cast(in); + out_string.reserve(NativeString().size() * count); + for (size_t i = 0; i < count; ++i) out_string += NativeString(); + return out_string; + } + Datum operator-(double in) const { return AsDouble() - in; } + Datum operator/(double in) const { return AsDouble() / in; } + Datum operator%(double in) const { return emp::Mod(AsDouble(), in); } + Datum operator+(const Datum & in) const { if (IsDouble()) return NativeDouble() + in.AsDouble(); return NativeString() + in.AsString(); @@ -156,6 +175,16 @@ namespace emp { Datum operator/(const Datum & in) const { return AsDouble() / in.AsDouble(); } Datum operator%(const Datum & in) const { return emp::Mod(AsDouble(), in.AsDouble()); } + template + Datum operator+=(T && in) { return *this = operator+(std::forward(in)); } + template + Datum operator-=(T && in) { return *this = operator-(std::forward(in)); } + template + Datum operator*=(T && in) { return *this = operator*(std::forward(in)); } + template + Datum operator/=(T && in) { return *this = operator/(std::forward(in)); } + template + Datum operator%=(T && in) { return *this = operator%(std::forward(in)); } }; std::ostream & operator<<(std::ostream & out, const emp::Datum & d) { @@ -165,4 +194,8 @@ namespace emp { } +emp::Datum operator%(double value1, emp::Datum value2) { + return emp::Mod(value1, value2.AsDouble()); +} + #endif // #ifndef EMP_DATA_DATUM_HPP_INCLUDE diff --git a/include/emp/data/MemoryImage.hpp b/include/emp/data/MemoryImage.hpp index 4731dfb23b..044a3f7c0c 100644 --- a/include/emp/data/MemoryImage.hpp +++ b/include/emp/data/MemoryImage.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2022. - * - * @file MemoryImage.hpp + * @file * @brief A managed set of Bytes to store any kind of data. * @note Status: ALPHA * @@ -15,6 +16,7 @@ #include // For std::memcpy #include // For placement new #include +#include #include "../base/assert.hpp" #include "../base/Ptr.hpp" diff --git a/include/emp/data/SimpleParser.hpp b/include/emp/data/SimpleParser.hpp index eb242fec90..fa8d86aafa 100644 --- a/include/emp/data/SimpleParser.hpp +++ b/include/emp/data/SimpleParser.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file SimpleParser.hpp + * @file * @brief Parser to convert function descriptions to lambdas using maps for variable lookup. * @note Status: ALPHA * diff --git a/include/emp/data/Trait.hpp b/include/emp/data/Trait.hpp index 92cf00f316..8acaab5aa0 100644 --- a/include/emp/data/Trait.hpp +++ b/include/emp/data/Trait.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Trait.hpp + * @file * @brief Directly measure a target quality about a type of object. * * These objects are able to measure a specific trait on another object. They @@ -13,6 +14,7 @@ #ifndef EMP_DATA_TRAIT_HPP_INCLUDE #define EMP_DATA_TRAIT_HPP_INCLUDE +#include #include #include "../base/assert.hpp" @@ -83,7 +85,7 @@ namespace emp { void SetMax(value_t max) { range.SetUpper(max); } value_t Eval(target_t & target) const { return fun(target); } - value_t EvalLimit(target_t & target) const { return range.Limit(fun(target)); } + value_t EvalLimit(target_t & target) const { return range.Clamp(fun(target)); } std::string EvalString(target_t & target) const { return std::to_string(EvalLimit(target)); } double EvalValue(target_t & target) const { return (double) EvalLimit(target); } diff --git a/include/emp/data/VarMap.hpp b/include/emp/data/VarMap.hpp index 30132b2ac1..48a0b25727 100644 --- a/include/emp/data/VarMap.hpp +++ b/include/emp/data/VarMap.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file VarMap.hpp + * @file * @brief VarMaps track arbitrary data by name (slow) or id (faster). * @note Status: ALPHA */ @@ -11,6 +12,7 @@ #ifndef EMP_DATA_VARMAP_HPP_INCLUDE #define EMP_DATA_VARMAP_HPP_INCLUDE +#include #include #include "../base/assert.hpp" diff --git a/include/emp/datastructs/BloomFilter.hpp b/include/emp/datastructs/BloomFilter.hpp index f699e64ae9..b4c59407d7 100644 --- a/include/emp/datastructs/BloomFilter.hpp +++ b/include/emp/datastructs/BloomFilter.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BloomFilter.hpp + * @file * @brief A Bloom filter implementation * * @note This file is included in Empirical (https://github.com/devosoft/Empirical) for convenience. @@ -15,7 +16,7 @@ #ifndef EMP_DATASTRUCTS_BLOOMFILTER_HPP_INCLUDE #define EMP_DATASTRUCTS_BLOOMFILTER_HPP_INCLUDE -/********************************************************************* +/* * Open Bloom Filter * * * * Author: Arash Partow - 2000 * @@ -53,6 +54,7 @@ static const unsigned char bit_mask[bits_per_char] = { 0x80 //10000000 }; +#ifndef DOXYGEN_SHOULD_SKIP_THIS /// This class keeps track of the parameters for a Bloom filter class BloomParameters { @@ -171,6 +173,8 @@ class BloomParameters }; +#endif // DOXYGEN_SHOULD_SKIP_THIS + /// This class implements a Bloom filter, which is a /// memory-efficient data structure for identifying /// values that have been seen before (with a tunable diff --git a/include/emp/datastructs/Bool.hpp b/include/emp/datastructs/Bool.hpp index ff5397e0fc..44ebd30afc 100644 --- a/include/emp/datastructs/Bool.hpp +++ b/include/emp/datastructs/Bool.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Bool.hpp + * @file * @brief A bool representation that doesn't trip up std::vector * @note Status: ALPHA * diff --git a/include/emp/datastructs/Cache.hpp b/include/emp/datastructs/Cache.hpp index 70e465de4e..7219b9fb45 100644 --- a/include/emp/datastructs/Cache.hpp +++ b/include/emp/datastructs/Cache.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file Cache.hpp + * @file * @brief similar to an std::unordered_map, but all lookups come with a function to generate the result should the lookup fail. * @note Status: BETA */ @@ -12,6 +13,7 @@ #define EMP_DATASTRUCTS_CACHE_HPP_INCLUDE #include +#include #include namespace emp { diff --git a/include/emp/datastructs/DynamicString.hpp b/include/emp/datastructs/DynamicString.hpp index a17457c8bf..4e30dbe90b 100644 --- a/include/emp/datastructs/DynamicString.hpp +++ b/include/emp/datastructs/DynamicString.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file DynamicString.hpp + * @file * @brief A string handler where sections update dynamically based on functions. * @note Status: BETA */ @@ -13,6 +14,7 @@ #include +#include #include #include "../base/vector.hpp" @@ -31,7 +33,7 @@ namespace emp { DynamicString() { ; } DynamicString(const DynamicString &) = default; - /// How many string components (funcations or continuous substrings) are in this DynamicString? + /// How many string components (functions or continuous substrings) are in this DynamicString? size_t GetSize() const { return fun_set.size(); } /// Index in to a specific component (not a specific character, since size is variable) @@ -83,6 +85,7 @@ namespace emp { } +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { /// Make sure that DynamicString works with with std::ostream. std::ostream & operator<<( std::ostream & os, const emp::DynamicString & strings ) @@ -93,5 +96,6 @@ namespace std { return os; } } +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_DATASTRUCTS_DYNAMICSTRING_HPP_INCLUDE diff --git a/include/emp/datastructs/Graph.hpp b/include/emp/datastructs/Graph.hpp index 2ba86b5935..8a3b02184c 100644 --- a/include/emp/datastructs/Graph.hpp +++ b/include/emp/datastructs/Graph.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file Graph.hpp - * @brief A simple, fast class for managing verticies (nodes) and edges. + * @file + * @brief A simple, fast class for managing vertices (nodes) and edges. * @note Status: BETA */ @@ -12,6 +13,7 @@ #define EMP_DATASTRUCTS_GRAPH_HPP_INCLUDE #include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" @@ -22,6 +24,7 @@ namespace emp { /// A graph class that maintains a set of vertices (nodes) and edges (connecting pairs of nodes) class Graph { public: + #ifndef DOXYGEN_SHOULD_SKIP_THIS /// Information about nodes within a graph. class Node { private: @@ -74,6 +77,7 @@ namespace emp { } }; + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: emp::vector nodes; ///< Set of vertices in this graph. @@ -188,7 +192,7 @@ namespace emp { return nodes[from].HasEdge(to) && nodes[to].HasEdge(from); } - /// Add a pair of edges between two vertieces (in both directions) + /// Add a pair of edges between two vertices (in both directions) void AddEdgePair(size_t from, size_t to) { emp_assert(from < nodes.size() && to < nodes.size()); nodes[from].AddEdge(to); diff --git a/include/emp/datastructs/IndexMap.hpp b/include/emp/datastructs/IndexMap.hpp index 853e8f5db9..a19c78c42a 100644 --- a/include/emp/datastructs/IndexMap.hpp +++ b/include/emp/datastructs/IndexMap.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022. - * - * @file IndexMap.hpp - * @brief Container that weights items and returns ID for a given weight position. + * @file + * @brief A simple class to weight items differently within a container and return the correct index. * @note Status: BETA * * An IndexMap is a container where each item has a specified weight (specified as a double). @@ -23,6 +24,8 @@ #ifndef EMP_DATASTRUCTS_INDEXMAP_HPP_INCLUDE #define EMP_DATASTRUCTS_INDEXMAP_HPP_INCLUDE +#include + #include "../base/vector.hpp" namespace emp { diff --git a/include/emp/datastructs/IndexSet.hpp b/include/emp/datastructs/IndexSet.hpp new file mode 100644 index 0000000000..4d34e72a22 --- /dev/null +++ b/include/emp/datastructs/IndexSet.hpp @@ -0,0 +1,529 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + * @brief Collection of indices, ideally optimized for memory size. + * @note Status: ALPHA + */ + +#ifndef EMP_DATASTRUCTS_INDEXSET_HPP_INCLUDE +#define EMP_DATASTRUCTS_INDEXSET_HPP_INCLUDE + +#include "../base/Ptr.hpp" +#include "../bits/BitVector.hpp" +#include "../math/constants.hpp" + +namespace emp { + + /// Index range is a simple pair of values indicating the start and end of a series of indices. + class IndexRange { + size_t start = 0; // First value in this range. + size_t end = 0; // First value after start NOT in this range; zero for empty range. + + public: + IndexRange() = default; + IndexRange(size_t val) : start(val), end(val+1) { } + IndexRange(size_t _start, size_t _end) : start(_start), end(_end) { } + IndexRange(const IndexRange &) = default; + + IndexRange & operator=(const IndexRange &) = default; + + auto operator<=>(const IndexRange &) const = default; + + size_t GetStart() const { return start; } + size_t GetEnd() const { return end; } + size_t GetSize() const { return end-start; } + + void SetStart(size_t in) { start = in; } + void SetEnd(size_t in) { end = in; } + + bool Has(size_t val) const { return val >= start && val < end; } + bool Has(IndexRange in) const { return in.start >= start && in.end < end; } + + /// Will identify if two ranges are next to each other or overlapping. + bool IsConnected(IndexRange in) const { + return (in.start >= start && in.start <= end || + start >= in.start && start <= in.end); + } + + /// Grow this range (default, by one) + void Grow(size_t count=1) { end += count; } + + /// Insert a value into a range if valid; return false if not. + bool Insert(size_t val) { + if (val == end) { end++; return true; } + if (val == start - 1) { start--; return true; } + return Has(val); + } + + /// Extend the current range with a new one. Must be perfectly adjacent! + bool Append(IndexRange in) { + if (end == in.start) { end = in.end; return true; } + return false; + } + + /// @brief Expand this range to encompass a provided value. + /// @param val Value to expand through. + /// @return Whether the range has changed due to this expansion. + bool Expand(size_t val) { + if (val < start) start = val; + else if (val > end) end = val; + else return false; + return true; + } + + /// @brief Expand this range to encompass all provided values. + /// @param vals Values to expand through + /// @return Whether the range has changed due to this expansion. + template + bool Expand(size_t val1, size_t val2, Ts... args) { + return Expand(val1) + Expand(val2, args...); + } + + + /// Merge this range with another. Must be adjacent or overlap! + bool Merge(IndexRange in) { + if (!IsConnected(in)) return false; + return Expand(in.start) + Expand(in.end); // Use + to avoid short-circuiting. + } + }; + + /// IndexRanges is a class to maintain a series of ranges of indexes. The ranges will + /// always be kept sorted and non-adjacent (i.e., there will always be at least one index + /// missing between two ranges). + class IndexRangeSet { + emp::vector range_set; + + // Helper function to find the id of an IndexRange that a value belongs in or can extend; + // returns next-higher index if none fit perfectly. + // @CAO - consider doing a binary search. + size_t _FindRange(size_t val) const { + for (size_t id = 0; id < range_set.size(); ++id) { + if (id <= range_set[id].GetEnd()) return id; + } + return range_set.size(); + } + + // Helper function to grow a range by one, possibly merging it with the next range. + void _GrowRange(size_t id) { + emp_assert(id < range_set.size()); + range_set[id].Grow(); + + // Test if we need to merge with the next range. + if (id+1 < range_set.size() && range_set[id].GetEnd() == range_set[id+1].GetStart()) { + range_set[id].SetEnd(range_set[id+1].GetEnd()); + range_set.erase(range_set.begin()+id+1); // Delete next range (now merged in) + } + } + + public: + IndexRangeSet() = default; + IndexRangeSet(const IndexRangeSet &) = default; + IndexRangeSet(IndexRangeSet &&) = default; + + IndexRangeSet & operator=(const IndexRangeSet &) = default; + IndexRangeSet & operator=(IndexRangeSet &&) = default; + + bool Has(size_t val) const { + size_t id = _FindRange(val); + if (id >= range_set.size()) return false; + return range_set[id].Has(val); + } + + size_t GetStart() const { + return range_set.size() ? range_set[0].GetStart() : emp::MAX_SIZE_T; + } + size_t GetEnd() const { + return range_set.size() ? range_set.back().GetEnd() : 0; + } + + size_t GetNumRanges() const { return range_set.size(); } + + /// @brief Calculate the total combined size of all ranges. + size_t GetSize() const { + size_t total = 0; + for (const auto & x : range_set) total += x.GetSize(); + return total; + } + + // Return all of the internal ranges. + const emp::vector & GetRanges() & { return range_set; } + + /// @brief Add a new value that belongs at the end of the sets. + /// @param val Value to add + /// @return Did the append work? If it's not at the end, returns false. + bool Append(size_t val) { + if (range_set.size() == 0 || val > GetEnd()) range_set.emplace_back(val); // New Range + else if (val == GetEnd()) range_set.back().SetEnd(val+1); // Extend range + else return false; // Not at end + + return true; + } + + /// @brief Add an entire range that belongs at the end of the sets. + /// @param val Range to add + /// @return Did the append work? If it's not at the end, returns false. + bool Append(IndexRange in) { + // Are we adding on a new range? + if (range_set.size() == 0 || in.GetStart() > GetEnd()) { + range_set.emplace_back(in); + } + + // Are we extending an existing range? + else if (in.GetEnd() > GetEnd()) { + // Are we encompassing ALL existing ranges? + if (in.GetStart() <= range_set[0].GetStart()) { + range_set.resize(1); + range_set[0] = in; + } + + // Otherwise find the start and convert from there. + else { + const size_t start_id = _FindRange(in.GetStart()); + range_set[start_id].SetEnd(in.GetEnd()); + } + } + + else return false; // Not at end + + return true; + } + + /// @brief Insert a value into this range set + /// @param val Value to insert. + /// @return Was there a change due to this insertion (or was it already there?) + bool Insert(size_t val) { + // Are we inserting a new range onto the end? + if (Append(val)) return true; + + // Do we already have the value? + size_t id = _FindRange(val); + if (range_set[id].Has(val)) return false; + + // Are we extending the range (and possibly merging)? + else if (range_set[id].GetEnd() == val) _GrowRange(id); + + // Are we extending the beginning of the next range? + else if (range_set[id].GetStart() == val+1) range_set[id].Insert(val); + + // Otherwise we must insert an entirely new range. + else range_set.emplace(id, val); + + return true; + } + + /// @brief Insert a whole range into this set, merging other ranges as needed. + /// @param in New range to include. + /// @return Was there a change due to this insertion (or were they already there?) + bool Insert(IndexRange in) { + // If the new range goes past the end, Append will take care of it. + if (Append(in)) return true; + + size_t start_id = _FindRange(in.GetStart()); + size_t end_id = _FindRange(in.GetEnd()); + emp_assert(start_id <= end_id); + + // If both are in the same range id, either insert a new range or modify an existing one. + if (start_id == end_id) { + // If the end of the new range is before the start of the found range, insert the new one! + if (in.GetEnd() < range_set[start_id].GetStart() - 1) { + range_set.insert(range_set.begin() + start_id, in); + } + + // Otherwise try to merge it into the existing range (will return false if already there) + else return range_set[start_id].Merge(in); + } + + // We are across multiple ranges. Collapse into first! + else { + if (in.GetEnd()+1 < range_set[end_id].GetStart()) --end_id; // Don't include end id. + range_set[start_id].Expand(in.GetStart(), in.GetEnd(), range_set[end_id].GetEnd()); + range_set.erase(range_set.begin()+start_id+1, range_set.begin()+end_id+1); + } + + return true; + } + + /// @brief Remove a single value from this index range. + /// @param val Value to remove + /// @return Did the range change due to this removal? + bool Remove(size_t val) { + if (!Has(val)) return false; + size_t id = _FindRange(val); + IndexRange & cur_range = range_set[id]; + if (cur_range.GetSize() == 1) range_set.erase(range_set.begin()+id); + else if (cur_range.GetStart() == val) cur_range.SetStart(cur_range.GetStart()+1); + else if (cur_range.GetEnd()-1 == val) cur_range.SetEnd(cur_range.GetEnd()-1); + else { + // Need to split the range. + range_set.insert(range_set.begin()+id+1, IndexRange{val+1,cur_range.GetEnd()}); + cur_range.SetEnd(val); + } + } + }; + + /// @brief A class to maintain a set of indices with a bit vector to represent them. + class IndexBits { + emp::BitVector bits; + size_t offset = 0; // Always a multiple of 64. + + // Figure out the best offset for a given value. + size_t _CalcOffset(size_t val) const { + return (val >> 6) << 6; + } + + /// @brief Increase the range of valid values + /// @param val Value to make sure can be set. + void _ExpandRange(size_t val) { + if (bits.GetSize() == 0) { // Must setup bits + offset = _CalcOffset(val); + bits.Resize(64); + } + else if (val < offset) { // Value is before offset... + const size_t new_offset = _CalcOffset(val); + bits.PushFront(offset - new_offset); + offset = new_offset; + } + else if (bits.GetSize() <= val-offset) { // Value is out of range... + bits.Resize(_CalcOffset(val) + 64 - offset); + } + } + public: + IndexBits() = default; + IndexBits(const IndexBits &) = default; + IndexBits(IndexBits &&) = default; + IndexBits(size_t min_val, size_t max_val) : offset(_CalcOffset(min_val)) { + bits.Resize(_CalcOffset(max_val) + 64 - offset); + } + + IndexBits & operator=(const IndexBits &) = default; + IndexBits & operator=(IndexBits &&) = default; + + bool Has(size_t val) const { return (val < offset) ? false : bits[val-offset]; } + size_t GetStart() const { return static_cast(bits.FindOne()) + offset; } + size_t GetEnd() const { return static_cast(bits.FindMaxOne()) + offset; } + size_t GetNumRanges() const { + return (bits & ~(bits >> 1)).CountOnes(); + } + size_t GetSize() const { return bits.CountOnes(); } + bool Insert(size_t val) { + _ExpandRange(val); // Make sure there is room for the new value. + bits.Set(val-offset); + } + bool Insert(IndexRange in) { + _ExpandRange(in.GetStart()); + _ExpandRange(in.GetEnd()); + bits.SetRange(in.GetStart()-offset, in.GetEnd()-offset); + } + bool Remove(size_t val) { + bits.Clear(val - offset); + } + }; + + /// @brief IndexSet maintains a collection of indices that can be easily manipulated. + /// It will try to adjust representation to maintain speed and memory efficiency + class IndexSet { + private: + // For zero to three entries, it will maintain values directly. + // For more than four entries it will use either bits or ranges based on how + // packed the values are into ranges. + enum class index_t { NONE=0, VALS1, VALS2, VALS3, RANGES, BITS }; + struct _Index_Vals { size_t id1; size_t id2; size_t id3; }; // Few values + + union { + _Index_Vals vals; + IndexRangeSet ranges; + IndexBits bits; + }; + index_t type = index_t::NONE; + + // --- Helper functions --- + + /// Free whatever type we currently have. + void _ReleaseUnion() { + if (type == index_t::BITS) bits.~IndexBits(); + else if (type == index_t::RANGES) ranges.~IndexRangeSet(); + } + + /// Convert the internal representation to use bits. + void _ToBits() { + emp_assert(type != index_t::NONE, "Cannot start IndexSet as type BITS"); + if (type == index_t::BITS) return; // Already bits! + + IndexBits new_bits(GetMin(), GetMax()); + + switch (type) { + case index_t::VALS3: new_bits.Insert(vals.id3); [[fallthrough]]; + case index_t::VALS2: new_bits.Insert(vals.id2); [[fallthrough]]; + case index_t::VALS1: new_bits.Insert(vals.id1); + break; + case index_t::RANGES: + for (const auto & range : ranges.GetRanges()) { + new_bits.Insert(range); + } + break; + } + + _ReleaseUnion(); + new (&bits) IndexBits(std::move(new_bits)); + } + + /// Convert the internal representation to use a ranges. + void _ToRanges() { + emp_assert(type != index_t::NONE, "Cannot start IndexSet as type RANGES"); + if (type == index_t::RANGES) return; // Already ranges format! + + IndexRangeSet new_ranges; + + switch (type) { + case index_t::VALS3: new_ranges.Insert(vals.id3); [[fallthrough]]; + case index_t::VALS2: new_ranges.Insert(vals.id2); [[fallthrough]]; + case index_t::VALS1: new_ranges.Insert(vals.id1); + break; + case index_t::BITS: + for (const auto & range : ranges.GetRanges()) { + new_ranges.Insert(range); + } + break; + } + + _ReleaseUnion(); + new (&bits) IndexBits(std::move(new_bits)); + + } + + public: + static constexpr const size_t npos = static_cast(-1); + + IndexSet() = default; + ~IndexSet() { + switch (type) { + case index_t::ARRAY: + ids.array.ids.DeleteArray(); + break; + case index_t::BITS: + ids.bits.bits.DeleteArray(); + break; + } + } + + size_t GetSize() const { + switch (type) { + case index_t::NONE: return 0; + case index_t::VALS1: return 1; + case index_t::VALS2: return 2; + case index_t::VALS3: return 3; + case index_t::RANGE: return ids.range.end - ids.range.start; + case index_t::ARRAY: return ids.array.num_ids; + case index_t::BITS: + size_t count = 0; + for (size_t i = 0; i < ids.bits.num_fields; ++i) { + count += emp::count_bits(ids.bits.bits[i]); + } + return count; + } + } + + bool Has(size_t id) const { + switch (type) { + case index_t::NONE: return false; + case index_t::VALS1: return ids.vals.id1 == id; + case index_t::VALS2: return ids.vals.id1 == id || ids.vals.id2 == id; + case index_t::VALS3: return ids.vals.id1 == id || ids.vals.id2 == id || ids.vals.id3 == id; + case index_t::RANGE: return id >= ids.range.start && id < ids.range.end; + case index_t::ARRAY: return ids.array.num_ids; + case index_t::BITS: { + if (id < ids.bits.offset) return false; + id = id - ids.bits.offset; + const size_t field = id / NUM_FIELD_BITS; + if (field >= ids.bits.num_fields) return false; + const size_t shift = id % NUM_FIELD_BITS; + return (ids.bits.bits[field] >> shift) & 1; + } + } + } + + size_t GetMin() const { + switch (type) { + case index_t::NONE: return npos; + case index_t::VALS1: return ids.vals.id1; + case index_t::VALS2: return ids.vals.id1; + case index_t::VALS3: return ids.vals.id1; + case index_t::RANGE: return ids.range.start; + case index_t::ARRAY: return ids.array.ids[0]; + case index_t::BITS: + return emp::find_bit(ids.bits.bits[0]) + ids.bits.offset; + } + } + + size_t GetMax() const { + switch (type) { + case index_t::NONE: return npos; + case index_t::VALS1: return ids.vals.id1; + case index_t::VALS2: return ids.vals.id2; + case index_t::VALS3: return ids.vals.id3; + case index_t::RANGE: return ids.range.end - 1; + case index_t::ARRAY: return ids.array.ids[ids.array.num_ids-1]; + case index_t::BITS: { + const size_t field_id = ids.bits.num_fields - 1; + const size_t offset = field_id * NUM_FIELD_BITS + ids.bits.offset; + return emp::find_last_bit(ids.bits.bits[field_id]) + offset; + } + } + } + + // Are all of the indicies one after the next? + bool IsConsecutive() const { + switch (type) { + case index_t::NONE: return true; + case index_t::VALS1: return true; + case index_t::VALS2: return ids.vals.id2 == ids.vals.id1+1; + case index_t::VALS3: return ids.vals.id3 == ids.vals.id2+1 && ids.vals.id2 == ids.vals.id1+1; + case index_t::RANGE: return true; + case index_t::ARRAY: + case index_t::BITS: + return GetSize() == GetMax() - GetMin() + 1; + } + } + + void Set(size_t id) { + switch (type) { + case index_t::NONE: ids.vals.id1 = id; type=index_t::VALS1; break; + case index_t::VALS1: if (!Has(id)) { ids.vals.id2 = id; type=index_t::VALS2; } break; + case index_t::VALS2: if (!Has(id)) { ids.vals.id3 = id; type=index_t::VALS3; } break; + case index_t::VALS3: + if (!Has(id)) { + // If current values are consecutive, try to make a range. + if (IsConsecutive()) { + if (id == ids.vals.id1 - 1) { + size_t max_val = ids.vals.id3; + ids.range.start = id; + ids.range.end = max_val+1; + break; + } else if (id == ids.vals.id3 + 1) { + size_t min_val = ids.vals.id1; + ids.range.start = min_val; + ids.range.end = id+1; + break; + } + } + + // If we made it here, values are not consecutive. + // For now: ASSUME we shift to BITS. + const size_t min_val = std::min(id, ids.vals.id1); + const size_t max_val = std::max(id, ids.vals.id3); + const size_t num_bits = max_val - min_val + 1; + const size_t num_fields = (num_bits / NUM_FIELD_BITS + 1) * 2; + } + case index_t::RANGE: return ids.range.end - ids.range.start; + case index_t::ARRAY: return ids.array.num_ids; + case index_t::BITS: return ids.bits.num_ids; + } + } + }; +} + +#endif // #ifndef EMP_DATASTRUCTS_INDEXSET_HPP_INCLUDE diff --git a/include/emp/datastructs/QueueCache.hpp b/include/emp/datastructs/QueueCache.hpp index 2205c73282..105484e777 100644 --- a/include/emp/datastructs/QueueCache.hpp +++ b/include/emp/datastructs/QueueCache.hpp @@ -1,11 +1,13 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-23 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file QueueCache.hpp + * @file * @brief A simple implementation of a Least-Recently Used Cache. - * It orders elements by access time and removes the stalest ones in case maximum capacity is reached. + * It orders elements by access time and removes the stalest ones in case + * maximum capacity is reached. */ #ifndef EMP_DATASTRUCTS_QUEUECACHE_HPP_INCLUDE @@ -14,12 +16,15 @@ #include #include #include +#include #include #include #include #include "../base/assert.hpp" +#include "map_utils.hpp" + namespace emp { template < class Key, @@ -40,6 +45,7 @@ // maximum number of elements the cache can hold size_t capacity; + #ifndef DOXYGEN_SHOULD_SKIP_THIS // Put the iterator at the beginning of the list, and returns its value // @param it Iterator to element to update // @return Reference to value of updated element @@ -52,6 +58,7 @@ ); return it->second; } + #endif // DOXYGEN_SHOULD_SKIP_THIS // Shrink cache to its capacity by removing elements at the end of it void Shrink() { @@ -71,8 +78,8 @@ // Delete given iterator from cache // @param it cache_map iterator to element to be deleted from cache void Delete(const typename cache_map_t::iterator it) { - cache_map.erase(it); cache_list.erase(it->second); + cache_map.erase(it); } public: @@ -103,9 +110,8 @@ /// Delete element from cache. /// @param key Key to delete from cache void Delete(const Key& key) { - Delete( - cache_map.find(key) - ); + emp_assert(emp::Has(cache_map, key)); + Delete(cache_map.find(key)); } /// Does cache contain key? @@ -120,17 +126,15 @@ /// @param val Value of element to store /// @return Iterator to newly-added element in cache queue typename cache_list_t::iterator Put(const Key& key, const Value& val) { - // try to find element in map + // If the element is already in the cache, delete it. const auto found = cache_map.find(key); if (found != cache_map.end()) { Delete(found); } - // put element into our cache - cache_list.emplace_front(key, val); - // add pointer to this element to our map - cache_map.emplace(key, cache_list.begin()); - // make sure we don't have more elements than our capacity - Shrink(); + + cache_list.emplace_front(key, val); // Put element into the cache + cache_map.emplace(key, cache_list.begin()); // Add element pointer to map + Shrink(); // Reduce if we are over capacity return cache_list.begin(); } diff --git a/include/emp/datastructs/SmallFifoMap.hpp b/include/emp/datastructs/SmallFifoMap.hpp index 7ec3d156c0..c7b75e0dd7 100644 --- a/include/emp/datastructs/SmallFifoMap.hpp +++ b/include/emp/datastructs/SmallFifoMap.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SmallFifoMap.hpp + * @file * @brief Store key value pairs in a fixed-sized array, bumping out the oldest * value when full. Optimized for small N. Requires N < 256. * @@ -13,6 +14,7 @@ #define EMP_DATASTRUCTS_SMALLFIFOMAP_HPP_INCLUDE #include +#include #include #include "../base/array.hpp" diff --git a/include/emp/datastructs/SmallVector.hpp b/include/emp/datastructs/SmallVector.hpp index 03a9e58df1..84a6929faf 100644 --- a/include/emp/datastructs/SmallVector.hpp +++ b/include/emp/datastructs/SmallVector.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SmallVector.hpp + * @file * @brief A drop-in replacement for std::vector with optimization to handle * small vector sizes without dynamic allocation. It contains some number of * elements in-place, which allows it to avoid heap allocation when the actual @@ -36,6 +37,7 @@ namespace emp { // helpers for AlignedCharArrayUnion +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace detail { template class AlignerImpl { @@ -56,6 +58,7 @@ template union SizerImpl { template union SizerImpl { char arr[sizeof(T)]; }; } // end namespace detail +#endif // DOXYGEN_SHOULD_SKIP_THIS /// A suitably aligned and sized character array member which can hold elements /// of any type. @@ -125,11 +128,13 @@ class SmallVectorBase { } }; +#ifndef DOXYGEN_SHOULD_SKIP_THIS /// Figure out the offset of the first element. template struct SmallVectorAlignmentAndSize { emp::AlignedCharArrayUnion Base; emp::AlignedCharArrayUnion FirstEl; }; +#endif // DOXYGEN_SHOULD_SKIP_THIS /// This is the part of SmallVectorTemplateBase which does not depend on whether /// the type T is a POD. The extra dummy template argument is used by ArrayRef @@ -282,6 +287,7 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon { } }; +#ifndef DOXYGEN_SHOULD_SKIP_THIS // Define this out-of-line to dissuade the C++ compiler from inlining it. template void SmallVectorTemplateBase::grow(size_t MinSize) { @@ -307,6 +313,7 @@ void SmallVectorTemplateBase::grow(size_t MinSize) { this->BeginX = NewElts; this->Capacity = NewCapacity; } +#endif // DOXYGEN_SHOULD_SKIP_THIS /// SmallVectorTemplateBase - This is where we put /// method implementations that are designed to work with POD-like T's. @@ -363,6 +370,8 @@ class SmallVectorTemplateBase : public SmallVectorTemplateCommon { void pop_back() { this->set_size(this->size() - 1); } }; +#ifndef DOXYGEN_SHOULD_SKIP_THIS + /// This class consists of common code factored out of the SmallVector class to /// reduce code duplication based on the SmallVector 'N' template parameter. template @@ -878,6 +887,8 @@ struct SmallVectorStorage { /// well-defined. template struct alignas(alignof(T)) SmallVectorStorage {}; +#endif /*DOXYGEN_SHOULD_SKIP_THIS*/ + /// This is a 'vector' (really, a variable-sized array), optimized /// for the case when the array is small. It contains some number of elements /// in-place, which allows it to avoid heap allocation when the actual number of @@ -956,6 +967,7 @@ inline size_t capacity_in_bytes(const SmallVector &X) { } // end namespace emp +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { /// Implement std::swap in terms of SmallVector swap. @@ -973,5 +985,6 @@ namespace std { } } // end namespace std +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_DATASTRUCTS_SMALLVECTOR_HPP_INCLUDE diff --git a/include/emp/datastructs/StringMap.hpp b/include/emp/datastructs/StringMap.hpp index 14fc22af87..292ef5d23f 100644 --- a/include/emp/datastructs/StringMap.hpp +++ b/include/emp/datastructs/StringMap.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2021. - * - * @file StringMap.hpp + * @file * @brief An std::unordered_map wrapper that deals smoothly with strings and fast compile-time optimizations. * @note Status: ALPHA * @@ -11,7 +12,7 @@ * desginated type. It is more powerful than std::unordered_map because it will accept strings wrapped in * the EMP_STRING_ID macro, which is hashed at compile-time instead of run-time. * - * @CO2: + * \@CO2: * StringMap = PAdictionary (PA = Perfectly accurate) * StringMap = HIDL (HIDL = having an identification of linking) * SMID = String.Map…e112th][string (SMID = StringMap identification) @@ -22,6 +23,7 @@ #ifndef EMP_DATASTRUCTS_STRINGMAP_HPP_INCLUDE #define EMP_DATASTRUCTS_STRINGMAP_HPP_INCLUDE +#include #include "../base/unordered_map.hpp" #include "../tools/string_utils.hpp" diff --git a/include/emp/datastructs/TimeQueue.hpp b/include/emp/datastructs/TimeQueue.hpp index ce2bb6e70f..72c1170eaa 100644 --- a/include/emp/datastructs/TimeQueue.hpp +++ b/include/emp/datastructs/TimeQueue.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file TimeQueue.hpp + * @file * @brief A priority queue for timings, always marching forward. * @note Status: ALPHA * @@ -49,6 +50,7 @@ #include #include +#include #include #include "../base/assert.hpp" diff --git a/include/emp/datastructs/TypeMap.hpp b/include/emp/datastructs/TypeMap.hpp index a7327dae44..f3d0915717 100644 --- a/include/emp/datastructs/TypeMap.hpp +++ b/include/emp/datastructs/TypeMap.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file TypeMap.hpp + * @file * @brief A class that will map types to values of a designated type. * @note Status: BETA */ @@ -11,6 +12,7 @@ #ifndef EMP_DATASTRUCTS_TYPEMAP_HPP_INCLUDE #define EMP_DATASTRUCTS_TYPEMAP_HPP_INCLUDE +#include #include #include "../meta/TypeID.hpp" diff --git a/include/emp/datastructs/UnorderedIndexMap.hpp b/include/emp/datastructs/UnorderedIndexMap.hpp index 9e6dbe985f..b503598e14 100644 --- a/include/emp/datastructs/UnorderedIndexMap.hpp +++ b/include/emp/datastructs/UnorderedIndexMap.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022. - * - * @file UnorderedIndexMap.hpp - * @brief Container that weights items and returns ID for a given weight position; order not guaranteed. + * @file + * @brief A simple class to weight items differently within a container and return the correct index. * @note Status: BETA * * @todo Convert to a template that acts as a glorified vector, simplifying random selection? @@ -14,6 +15,8 @@ #ifndef EMP_DATASTRUCTS_UNORDEREDINDEXMAP_HPP_INCLUDE #define EMP_DATASTRUCTS_UNORDEREDINDEXMAP_HPP_INCLUDE +#include + #include "../base/vector.hpp" namespace emp { @@ -65,11 +68,21 @@ namespace emp { } public: - /// Construct an UnorderedIndexMap where num_items is the maximum number of items that can be placed - /// into the data structure. All item weights default to zero. + /// Construct an UnorderedIndexMap where num_items is the maximum number of items that + /// can be placed into the data structure. All item weights default to zero. UnorderedIndexMap(size_t _items=0, double init_weight=0.0) - : num_items(_items), num_nodes(_items-1), needs_refresh(_items && (init_weight > 0.0)), weights(0) + : num_items(_items), num_nodes(_items-1), + needs_refresh(_items && (init_weight > 0.0)), weights(0) { if (_items > 0) weights.resize(_items*2-1, init_weight); } + /// Construct an UnorderedIndexMap with a specified initial set of weights. + UnorderedIndexMap(const emp::vector & in_weights) + : num_items(in_weights.size()), num_nodes(num_items-1), needs_refresh(true) + , weights(num_items*2 - 1) + { + emp_assert(num_items > 0, "UnorderedIndexMaps should not be initialized with empty weights"); + for (size_t i = 0; i < num_items; i++) weights[i + num_nodes] = in_weights[i]; + } + UnorderedIndexMap(const UnorderedIndexMap &) = default; UnorderedIndexMap(UnorderedIndexMap &&) = default; ~UnorderedIndexMap() = default; @@ -153,7 +166,7 @@ namespace emp { void Adjust(size_t id, const double new_weight) { RawAdjust(id + num_nodes, new_weight); } - /// Adjust all index weights to the set provided. + /// Adjust all index & new_weights) { num_items = new_weights.size(); num_nodes = num_items - 1; @@ -164,7 +177,7 @@ namespace emp { needs_refresh = true; } - /// Adjust all index weights to the set provided. + /// Adjust all index weights to the single weight provided. void AdjustAll(double new_weight) { for (size_t i = 0; i < num_items; i++) weights[i + num_nodes] = new_weight; needs_refresh = true; @@ -214,7 +227,7 @@ namespace emp { } /// Indicate that we need to adjust weights before relying on them in the future; this will - /// prevent refreshes from occuring immediately and is useful when many updates to weights are + /// prevent refreshes from occurring immediately and is useful when many updates to weights are /// likely to be done before any are accessed again. void DeferRefresh() { needs_refresh = true; diff --git a/include/emp/datastructs/graph_utils.hpp b/include/emp/datastructs/graph_utils.hpp index ab5439d01b..76fd4235b3 100644 --- a/include/emp/datastructs/graph_utils.hpp +++ b/include/emp/datastructs/graph_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file graph_utils.hpp + * @file * @brief This file provides a number of tools for manipulating graphs. * @note Status: BETA */ @@ -13,6 +14,7 @@ #include #include +#include #include #include diff --git a/include/emp/datastructs/hash_utils.hpp b/include/emp/datastructs/hash_utils.hpp index 0573b7294e..8e66f461e8 100644 --- a/include/emp/datastructs/hash_utils.hpp +++ b/include/emp/datastructs/hash_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2022. - * - * @file hash_utils.hpp + * @file * @brief This file provides tools for hashing values and containers. * @note Status: BETA */ @@ -12,6 +13,7 @@ #define EMP_DATASTRUCTS_HASH_UTILS_HPP_INCLUDE #include +#include #include #include #include diff --git a/include/emp/datastructs/map_utils.hpp b/include/emp/datastructs/map_utils.hpp index a88f40dfa3..6cd27a4dea 100644 --- a/include/emp/datastructs/map_utils.hpp +++ b/include/emp/datastructs/map_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file map_utils.hpp + * @file * @brief A set of simple functions to manipulate maps. * @note Status: BETA */ @@ -13,6 +14,8 @@ #include #include +#include +#include #include #include "../base/map.hpp" @@ -20,6 +23,18 @@ namespace emp { + template + std::string MapToString(const MAP_T & in_map) { + std::stringstream ss; + bool use_comma = false; + for (const auto & [key, value] : in_map) { + if (use_comma) ss << ","; + ss << "{" << key << ":" << value << "}"; + use_comma = true; + } + return ss.str(); + } + /// Take any map type, and run find to determine if a key is present. template inline bool Has( const MAP_T & in_map, const KEY_T & key ) { @@ -82,15 +97,12 @@ namespace emp { } template - inline auto Keys( const MAP_T & in_map) -> emp::vectorfirst)>::type> { - using KEY_T = typename std::remove_constfirst)>::type; - emp::vector keys; + inline auto Keys( const MAP_T & in_map) { + emp::vector keys; for (auto it : in_map) { keys.push_back(it.first); } - return keys; - } diff --git a/include/emp/datastructs/ra_map.hpp b/include/emp/datastructs/ra_map.hpp index 86bff50254..4702e6f662 100644 --- a/include/emp/datastructs/ra_map.hpp +++ b/include/emp/datastructs/ra_map.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file ra_map.hpp + * @file * @brief This file defines a Random Access Map template. * @note Status: ALPHA * diff --git a/include/emp/datastructs/ra_set.hpp b/include/emp/datastructs/ra_set.hpp index 62aa079b17..2bf9d60297 100644 --- a/include/emp/datastructs/ra_set.hpp +++ b/include/emp/datastructs/ra_set.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2019 - * - * @file ra_set.hpp + * @file * @brief This file defines a Random Access Set template. * @note Status: ALPHA */ @@ -12,6 +13,7 @@ #define EMP_DATASTRUCTS_RA_SET_HPP_INCLUDE #include +#include #include "../base/map.hpp" #include "../base/vector.hpp" diff --git a/include/emp/datastructs/reference_vector.hpp b/include/emp/datastructs/reference_vector.hpp index 931b272380..72958d96ee 100644 --- a/include/emp/datastructs/reference_vector.hpp +++ b/include/emp/datastructs/reference_vector.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file reference_vector.hpp + * @file * @brief A version of vector that holds only references to objects. Be careful! * @note Status: ALPHA */ @@ -11,6 +12,8 @@ #ifndef EMP_DATASTRUCTS_REFERENCE_VECTOR_HPP_INCLUDE #define EMP_DATASTRUCTS_REFERENCE_VECTOR_HPP_INCLUDE +#include + #include "../base/Ptr.hpp" #include "../base/vector.hpp" diff --git a/include/emp/datastructs/set_utils.hpp b/include/emp/datastructs/set_utils.hpp index 40e82089b9..e95a22430e 100644 --- a/include/emp/datastructs/set_utils.hpp +++ b/include/emp/datastructs/set_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file set_utils.hpp + * @file * @brief Tools to save and load data from classes. * @note Status: ALPHA */ @@ -38,7 +39,7 @@ namespace emp { template bool Has(const std::unordered_set & s, const V & val) { return s.count(val); } - /// Test if an std::unordere_multiset has a particular element without modifying the set in any way. + /// Test if an std::unordered_multiset has a particular element without modifying the set in any way. template bool Has(const std::unordered_multiset & s, const V & val) { return s.count(val); } @@ -46,7 +47,7 @@ namespace emp { // by reference and vectors are passed by value, because these functions only work // on sorted data. Therefore, vectors must be sorted first, which happens in place. - /// Compute the set difference of @param s1 and @param s2 (elements that are in S1 but no S2) + /// Compute the set difference of s1 and s2 (elements that are in S1 but no S2) template std::set difference(std::set & s1, std::set & s2) { // Based on PierreBdR's answer to https://stackoverflow.com/questions/283977/c-stl-set-difference @@ -56,7 +57,7 @@ namespace emp { return result; } - /// Compute the set difference of @param s1 and @param s2 (elements that are in S1 but no S2) + /// Compute the set difference of s1 and s2 (elements that are in S1 but no S2) template std::set difference(emp::vector s1, emp::vector s2) { // Based on PierreBdR's answer to https://stackoverflow.com/questions/283977/c-stl-set-difference @@ -69,7 +70,7 @@ namespace emp { return result; } - /// Compute the set difference of @param s1 and @param s2 (elements that are in S1 but not S2) + /// Compute the set difference of s1 and s2 (elements that are in S1 but not S2) template std::set difference(std::set & s1, emp::vector s2) { // Based on PierreBdR's answer to https://stackoverflow.com/questions/283977/c-stl-set-difference @@ -80,7 +81,7 @@ namespace emp { return result; } - /// Compute the set difference of @param s1 and @param s2 (elements that are in S1 but no S2) + /// Compute the set difference of s1 and s2 (elements that are in S1 but no S2) template std::set difference(emp::vector s1, std::set & s2) { // Based on PierreBdR's answer to https://stackoverflow.com/questions/283977/c-stl-set-difference @@ -91,7 +92,7 @@ namespace emp { return result; } - /// Compute the set intersection of @param s1 and @param s2 (elements that are in both S1 and S2) + /// Compute the set intersection of s1 and s2 (elements that are in both S1 and S2) template std::set intersection(std::set & s1, std::set & s2) { std::set result; @@ -100,7 +101,7 @@ namespace emp { return result; } - /// Compute the set intersection of @param s1 and @param s2 (elements that are in both S1 and S2) + /// Compute the set intersection of s1 and s2 (elements that are in both S1 and S2) template std::set intersection(emp::vector s1, emp::vector s2) { std::sort(s1.begin(), s1.end()); // set_intersection expects sorted things @@ -112,7 +113,7 @@ namespace emp { return result; } - /// Compute the set intersection of @param s1 and @param s2 (elements that are in both S1 and S2) + /// Compute the set intersection of s1 and s2 (elements that are in both S1 and S2) template std::set intersection(std::set & s1, emp::vector s2) { std::sort(s2.begin(), s2.end()); // set_intersection expects sorted things @@ -123,7 +124,7 @@ namespace emp { return result; } - /// Compute the set intersection of @param s1 and @param s2 (elements that are in both S1 and S2) + /// Compute the set intersection of s1 and s2 (elements that are in both S1 and S2) template std::set intersection(emp::vector s1, std::set & s2) { std::sort(s1.begin(), s1.end()); // set_intersection expects sorted things @@ -134,7 +135,7 @@ namespace emp { return result; } - /// Compute the set union of @param s1 and @param s2 (elements that are in either S1 or S2) + /// Compute the set union of s1 and s2 (elements that are in either S1 or S2) template std::set set_union(std::set & s1, std::set & s2) { std::set result; @@ -143,7 +144,7 @@ namespace emp { return result; } - /// Compute the set union of @param s1 and @param s2 (elements that are in either S1 or S2) + /// Compute the set union of s1 and s2 (elements that are in either S1 or S2) template std::set set_union(emp::vector s1, emp::vector s2) { std::sort(s1.begin(), s1.end()); // set_union expects sorted things @@ -155,7 +156,7 @@ namespace emp { return result; } - /// Compute the set union of @param s1 and @param s2 (elements that are in either S1 or S2) + /// Compute the set union of s1 and s2 (elements that are in either S1 or S2) template std::set set_union(std::set & s1, emp::vector s2) { std::sort(s2.begin(), s2.end()); // set_union expects sorted things @@ -166,7 +167,7 @@ namespace emp { return result; } - /// Compute the set union of @param s1 and @param s2 (elements that are in either S1 or S2) + /// Compute the set union of s1 and s2 (elements that are in either S1 or S2) template std::set set_union(emp::vector s1, std::set & s2) { std::sort(s1.begin(), s1.end()); // set_union expects sorted things @@ -177,7 +178,7 @@ namespace emp { return result; } - /// Compute the set symmetric_difference of @param s1 and @param s2 (elements that are in either S1 or S2 but not both) + /// Compute the set symmetric_difference of s1 and s2 (elements that are in either S1 or S2 but not both) template std::set symmetric_difference(std::set & s1, std::set & s2) { std::set result; @@ -186,7 +187,7 @@ namespace emp { return result; } - /// Compute the set symmetric_difference of @param s1 and @param s2 (elements that are in either S1 or S2 but not both) + /// Compute the set symmetric_difference of s1 and s2 (elements that are in either S1 or S2 but not both) template std::set symmetric_difference(emp::vector s1, emp::vector s2) { std::sort(s1.begin(), s1.end()); // set_symmetric_difference expects sorted things @@ -198,7 +199,7 @@ namespace emp { return result; } - /// Compute the set symmetric_difference of @param s1 and @param s2 (elements that are in either S1 or S2 but not both) + /// Compute the set symmetric_difference of s1 and s2 (elements that are in either S1 or S2 but not both) template std::set symmetric_difference(std::set & s1, emp::vector s2) { std::sort(s2.begin(), s2.end()); // set_symmetric_difference expects sorted things @@ -209,7 +210,7 @@ namespace emp { return result; } - /// Compute the set symmetric_difference of @param s1 and @param s2 (elements that are in either S1 or S2 but not both) + /// Compute the set symmetric_difference of s1 and s2 (elements that are in either S1 or S2 but not both) template std::set symmetric_difference(emp::vector s1, std::set & s2) { std::sort(s1.begin(), s1.end()); // set_symmetric_difference expects sorted things diff --git a/include/emp/datastructs/span_utils.hpp b/include/emp/datastructs/span_utils.hpp index 6130086de6..642a85aee5 100644 --- a/include/emp/datastructs/span_utils.hpp +++ b/include/emp/datastructs/span_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file span_utils.hpp + * @file * @brief A set of simple functions to manipulate std::span * @note Status: BETA * diff --git a/include/emp/datastructs/tuple_struct.hpp b/include/emp/datastructs/tuple_struct.hpp index 6906f30b79..793f5397b6 100644 --- a/include/emp/datastructs/tuple_struct.hpp +++ b/include/emp/datastructs/tuple_struct.hpp @@ -1,13 +1,14 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file tuple_struct.hpp + * @file * @brief These macros will build a tuple and accessors to that tuple's members inside of a * class definintion. * - * Status: ALPHA + * @note Status: ALPHA * * "But WHY???" you ask. Let me explain: Keeping a tuple allows us to easily track the * members in the stuct or class, and makes possible powerful types of reflection diff --git a/include/emp/datastructs/tuple_utils.hpp b/include/emp/datastructs/tuple_utils.hpp index 3f1e028009..7fe5f1a39b 100644 --- a/include/emp/datastructs/tuple_utils.hpp +++ b/include/emp/datastructs/tuple_utils.hpp @@ -1,17 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file tuple_utils.hpp + * @file * @brief Functions to simplify the use of std::tuple - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_DATASTRUCTS_TUPLE_UTILS_HPP_INCLUDE #define EMP_DATASTRUCTS_TUPLE_UTILS_HPP_INCLUDE #include +#include #include #include "../meta/ValPack.hpp" diff --git a/include/emp/datastructs/valsort_map.hpp b/include/emp/datastructs/valsort_map.hpp index 3faf29b382..d5f705db4b 100644 --- a/include/emp/datastructs/valsort_map.hpp +++ b/include/emp/datastructs/valsort_map.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file valsort_map.hpp + * @file * @brief This file defines a map that is sorted by value, not key. * @note Status: ALPHA * @@ -20,6 +21,7 @@ #include #include +#include #include "../base/vector.hpp" diff --git a/include/emp/datastructs/vector_utils.hpp b/include/emp/datastructs/vector_utils.hpp index 64e8150553..5b2cf7175a 100644 --- a/include/emp/datastructs/vector_utils.hpp +++ b/include/emp/datastructs/vector_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2021. - * - * @file vector_utils.hpp + * @file * @brief A set of simple functions to manipulate emp::vector * @note Status: BETA * @@ -21,13 +22,14 @@ #include #include #include +#include #include "../base/vector.hpp" #include "../tools/string_utils.hpp" namespace emp { - // Remove and return the first element of a vector. + /// Remove and return the first element of a vector. template T PopFront(emp::vector & v) { emp_assert(v.size()); @@ -36,11 +38,19 @@ namespace emp { return out; } + /// Insert a value at a specified position in a vector. + template + void InsertAt(emp::vector & v, size_t id, T value) { + v.insert(v.begin()+id, value); + } + + #ifndef DOXYGEN_SHOULD_SKIP_THIS /// Base case for Append; we just have a single vector with nothing to append. template emp::vector & Append(emp::vector & base) { return base; } + #endif // DOXYGEN_SHOULD_SKIP_THIS /// Append one or more vectors on to the end of an existing vector. template @@ -59,8 +69,7 @@ namespace emp { return Append(base, vs...); } - - /// Concatonate two or more vectors together, creating a new vector. + /// Concatenate two or more vectors together, creating a new vector. template emp::vector Concat(const emp::vector & v1, const Vs &... vs) { emp::vector out_v(v1); @@ -142,6 +151,29 @@ namespace emp { return true; } + /// Remove value at an index. + template + void RemoveAt(emp::vector & v, size_t id) { + v.erase(v.begin() + id); + } + + /// Remove values starting at an index. + template + void RemoveAt(emp::vector & v, size_t id, size_t count) { + if (!count) return; + v.erase(v.begin() + id, v.begin() + id + count); + } + + /// Return a new vector containing the same elements as @param v + /// with any duplicate elements removed. + /// Not guaranteed to preserve order + template + emp::vector RemoveDuplicates(const emp::vector & v) { + std::set temp_set(v.begin(), v.end()); + emp::vector new_vec(temp_set.begin(), temp_set.end()); + return new_vec; + } + /// Return whether a value exists in a vector template bool Has(const emp::vector & v, const T & val) { @@ -313,16 +345,6 @@ namespace emp { return numbers; } - /// Return a new vector containing the same elements as @param v - /// with any duplicate elements removed. - /// Not guaranteed to preserve order - template - emp::vector RemoveDuplicates(const emp::vector & v) { - std::set temp_set(v.begin(), v.end()); - emp::vector new_vec(temp_set.begin(), temp_set.end()); - return new_vec; - } - /// Build a vector with a range of values from min to max at the provided step size. template static inline emp::vector BuildRange(T min, T max, T step=1) { diff --git a/include/emp/debug/alert.hpp b/include/emp/debug/alert.hpp index 70be769cd2..3dc5e5c4a1 100644 --- a/include/emp/debug/alert.hpp +++ b/include/emp/debug/alert.hpp @@ -1,16 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file alert.hpp + * @file * @brief Define an Alert function that goes to std::cerr in c++ or to Alert() in Javascript. - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_DEBUG_ALERT_HPP_INCLUDE #define EMP_DEBUG_ALERT_HPP_INCLUDE +#include + #include "../tools/string_utils.hpp" // If we are in emscripten, make sure to include the header. diff --git a/include/emp/debug/debug.hpp b/include/emp/debug/debug.hpp index c189febb82..362c8692eb 100644 --- a/include/emp/debug/debug.hpp +++ b/include/emp/debug/debug.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022 - * - * @file debug.hpp + * @file * @brief Basic tools for use in developing high-assurance code. * @note Status: BETA */ diff --git a/include/emp/debug/mem_track.hpp b/include/emp/debug/mem_track.hpp index e2a96da6bf..802a1ec545 100644 --- a/include/emp/debug/mem_track.hpp +++ b/include/emp/debug/mem_track.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2019 - * - * @file mem_track.hpp + * @file * @brief A set of macros to track how many instances of specific classes are made. * @note Status: BETA * diff --git a/include/emp/functional/AnyFunction.hpp b/include/emp/functional/AnyFunction.hpp index 42ebffb489..52b82a451f 100644 --- a/include/emp/functional/AnyFunction.hpp +++ b/include/emp/functional/AnyFunction.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file AnyFunction.hpp + * @file * @brief Based on std::function, but with a generic base class. * @note Status: ALPHA * @@ -14,6 +15,7 @@ #define EMP_FUNCTIONAL_ANYFUNCTION_HPP_INCLUDE #include +#include #include "../base/assert.hpp" #include "../base/Ptr.hpp" @@ -197,7 +199,7 @@ namespace emp { } }; - + #ifndef DOXYGEN_SHOULD_SKIP_THIS ///////////////////////////////////// // Member function implementaions. @@ -231,6 +233,7 @@ namespace emp { template bool BaseFunction::ConvertOK() { return dynamic_cast *>(this); } + #endif // DOXYGEN_SHOULD_SKIP_THIS } diff --git a/include/emp/functional/FunctionSet.hpp b/include/emp/functional/FunctionSet.hpp index 46d5c1fce8..c2af5ba8fc 100644 --- a/include/emp/functional/FunctionSet.hpp +++ b/include/emp/functional/FunctionSet.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file FunctionSet.hpp + * @file * @brief Setup a collection of functions, all with the same signature, that can be run as a group. * @note Status: BETA */ @@ -12,6 +13,7 @@ #define EMP_FUNCTIONAL_FUNCTIONSET_HPP_INCLUDE #include +#include #include "../base/vector.hpp" diff --git a/include/emp/functional/GenericFunction.hpp b/include/emp/functional/GenericFunction.hpp index e8e3240aad..d0d62ecefa 100644 --- a/include/emp/functional/GenericFunction.hpp +++ b/include/emp/functional/GenericFunction.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2019 - * - * @file GenericFunction.hpp + * @file * @brief Based on std::function, but with a common base class. * @note Status: ALPHA * @@ -15,6 +16,7 @@ #define EMP_FUNCTIONAL_GENERICFUNCTION_HPP_INCLUDE #include +#include #include "../base/assert.hpp" @@ -83,6 +85,7 @@ namespace emp { const fun_t & GetFunction() const { return fun; } }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS ///////////////////////////////////// // Member function implementaions. @@ -116,7 +119,7 @@ namespace emp { template bool GenericFunction::ConvertOK() { return dynamic_cast *>(this); } - + #endif // DOXYGEN_SHOULD_SKIP_THIS } #endif // #ifndef EMP_FUNCTIONAL_GENERICFUNCTION_HPP_INCLUDE diff --git a/include/emp/functional/flex_function.hpp b/include/emp/functional/flex_function.hpp index 191d24273a..25a17aec60 100644 --- a/include/emp/functional/flex_function.hpp +++ b/include/emp/functional/flex_function.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file flex_function.hpp + * @file * @brief Based on std::function, but holds default parameter values for calls with fewer args. * @note Status: ALPHA */ @@ -13,6 +14,7 @@ #include +#include #include #include "../base/assert.hpp" diff --git a/include/emp/functional/memo_function.hpp b/include/emp/functional/memo_function.hpp index e802cafe54..f096c9f27c 100644 --- a/include/emp/functional/memo_function.hpp +++ b/include/emp/functional/memo_function.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019 - * - * @file memo_function.hpp + * @file * @brief A function that memorizes previous results to speed up any repeated calls. * @note Status: BETA */ @@ -11,6 +12,7 @@ #ifndef EMP_FUNCTIONAL_MEMO_FUNCTION_HPP_INCLUDE #define EMP_FUNCTIONAL_MEMO_FUNCTION_HPP_INCLUDE +#include #include #include "../base/assert.hpp" diff --git a/include/emp/games/Mancala.hpp b/include/emp/games/Mancala.hpp index cd92bc9dbc..241596cb4b 100644 --- a/include/emp/games/Mancala.hpp +++ b/include/emp/games/Mancala.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file Mancala.hpp + * @file * @brief A simple Malcala game state handler. */ @@ -13,6 +14,7 @@ #include #include #include +#include #include #include "../base/array.hpp" diff --git a/include/emp/games/Othello.hpp b/include/emp/games/Othello.hpp index a3d17530a3..c803836622 100644 --- a/include/emp/games/Othello.hpp +++ b/include/emp/games/Othello.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Othello.hpp + * @file * @brief A simple Othello game state handler. * * @todo Add Hash for boards to be able to cachce moves. @@ -16,6 +17,7 @@ #include #include #include +#include #include #include "../base/array.hpp" diff --git a/include/emp/games/Othello8.hpp b/include/emp/games/Othello8.hpp index 93d5d22574..d9b641e5de 100644 --- a/include/emp/games/Othello8.hpp +++ b/include/emp/games/Othello8.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Othello8.hpp + * @file * @brief A simple Othello game state handler limited to an 8x8 board. * * @todo Add Hash for boards to be able to cachce moves. @@ -13,9 +14,11 @@ #ifndef EMP_GAMES_OTHELLO8_HPP_INCLUDE #define EMP_GAMES_OTHELLO8_HPP_INCLUDE +#include #include #include #include +#include #include #include "../base/array.hpp" @@ -49,11 +52,11 @@ namespace emp { constexpr Index(size_t x, size_t y) : pos() { Set(x,y); } constexpr Index(const Index & _in) : pos(_in.pos) { emp_assert(pos <= NUM_CELLS); } - operator size_t() const { return pos; } - size_t x() const { return pos & 7; } - size_t y() const { return pos >> 3; } - void Set(size_t x, size_t y) { pos = (x> 3; } + constexpr void Set(size_t x, size_t y) { pos = (x #include #include "../base/array.hpp" diff --git a/include/emp/geometry/Angle2D.hpp b/include/emp/geometry/Angle2D.hpp index b0b62914ff..83c878611b 100644 --- a/include/emp/geometry/Angle2D.hpp +++ b/include/emp/geometry/Angle2D.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file Angle2D.hpp + * @file * @brief emp::Angle maintains an angle on a 2D surface. * * The internal representation uses an int to represent angles. @@ -15,6 +16,7 @@ #define EMP_GEOMETRY_ANGLE2D_HPP_INCLUDE #include +#include #include "../math/constants.hpp" diff --git a/include/emp/geometry/Body2D.hpp b/include/emp/geometry/Body2D.hpp index 553228aefa..6538b07671 100644 --- a/include/emp/geometry/Body2D.hpp +++ b/include/emp/geometry/Body2D.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file Body2D.hpp + * @file * @brief This file defines classes to represent bodies that exist on a 2D surface. * * Each class should be able to: @@ -23,6 +24,9 @@ #ifndef EMP_GEOMETRY_BODY2D_HPP_INCLUDE #define EMP_GEOMETRY_BODY2D_HPP_INCLUDE +#include +#include + #include "../base/assert.hpp" #include "../base/Ptr.hpp" #include "../base/vector.hpp" diff --git a/include/emp/geometry/Circle2D.hpp b/include/emp/geometry/Circle2D.hpp index 84801902e5..786c8f43be 100644 --- a/include/emp/geometry/Circle2D.hpp +++ b/include/emp/geometry/Circle2D.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Circle2D.hpp + * @file * @brief A class to manage circles in a 2D plane. */ diff --git a/include/emp/geometry/Physics2D.hpp b/include/emp/geometry/Physics2D.hpp index 9fe311607d..63e6eb762d 100644 --- a/include/emp/geometry/Physics2D.hpp +++ b/include/emp/geometry/Physics2D.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Physics2D.hpp + * @file * @brief Physics2D - handles movement and collissions in a simple 2D world. * */ @@ -12,6 +13,7 @@ #define EMP_GEOMETRY_PHYSICS2D_HPP_INCLUDE #include +#include #include #include "../base/Ptr.hpp" diff --git a/include/emp/geometry/Point2D.hpp b/include/emp/geometry/Point2D.hpp index cc09e0222b..bc30faf6b9 100644 --- a/include/emp/geometry/Point2D.hpp +++ b/include/emp/geometry/Point2D.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Point2D.hpp + * @file * @brief A simple class to track value pairs of any kind, optimized for points in 2D Space. * * @note For maximal efficiency, prefer SquareMagnitude() and SquareDistance() @@ -108,6 +109,7 @@ namespace emp { } +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { // Overload ostream to work with points. template std::ostream & operator<<(std::ostream & os, @@ -115,5 +117,6 @@ namespace std { return os << "(" << point.GetX() << "," << point.GetY() << ")"; } } +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_GEOMETRY_POINT2D_HPP_INCLUDE diff --git a/include/emp/geometry/Surface.hpp b/include/emp/geometry/Surface.hpp index decf6d596e..be056e5cd0 100644 --- a/include/emp/geometry/Surface.hpp +++ b/include/emp/geometry/Surface.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Surface.hpp + * @file * @brief This file defines a templated class to represent a 2D suface capable of maintaining data * about which 2D bodies are currently on that surface and rapidly identifying if they are * overlapping. @@ -20,6 +21,7 @@ #include #include +#include #include "../base/Ptr.hpp" #include "../datastructs/vector_utils.hpp" diff --git a/include/emp/geometry/Surface2D.hpp b/include/emp/geometry/Surface2D.hpp index 293ae88902..5e4d978cf0 100644 --- a/include/emp/geometry/Surface2D.hpp +++ b/include/emp/geometry/Surface2D.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Surface2D.hpp + * @file * @brief This file defines a templated class to represent a 2D suface capable of maintaining data * about which 2D bodies are currently on that surface and rapidly identifying if they are * overlapping. diff --git a/include/emp/hardware/AvidaCPU_InstLib.hpp b/include/emp/hardware/AvidaCPU_InstLib.hpp index e5c270c226..8c5e26754d 100644 --- a/include/emp/hardware/AvidaCPU_InstLib.hpp +++ b/include/emp/hardware/AvidaCPU_InstLib.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file AvidaCPU_InstLib.hpp + * @file * @brief A specialized version of InstLib to handle AvidaCPU Instructions. */ #ifndef EMP_HARDWARE_AVIDACPU_INSTLIB_HPP_INCLUDE #define EMP_HARDWARE_AVIDACPU_INSTLIB_HPP_INCLUDE +#include + #include "../math/math.hpp" #include "InstLib.hpp" diff --git a/include/emp/hardware/AvidaGP.hpp b/include/emp/hardware/AvidaGP.hpp index 1b812852d8..4a4338af41 100644 --- a/include/emp/hardware/AvidaGP.hpp +++ b/include/emp/hardware/AvidaGP.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2021. - * - * @file AvidaGP.hpp + * @file * @brief This is a simple, efficient CPU for and applied version of Avida. * * @todo Should we save a copy of the original genome? (or create a new "memory" member) @@ -22,6 +23,7 @@ #include #include #include +#include #include "../base/array.hpp" #include "../base/Ptr.hpp" @@ -69,7 +71,7 @@ namespace emp { Instruction & operator=(const Instruction &) = default; Instruction & operator=(Instruction &&) = default; bool operator<(const Instruction & in) const { - return std::tie(id, args) < std::tie(in.id, in.args); + return (id == in.id) ? (args < in.args) : (id < in.id); } bool operator==(const Instruction & in) const { return id == in.id && args == in.args; } bool operator!=(const Instruction & in) const { return !(*this == in); } @@ -488,6 +490,7 @@ namespace emp { of.close(); } + #ifndef DOXYGEN_SHOULD_SKIP_THIS template void AvidaCPU_Base::PrintSymbols(std::ostream & os) const { // Example output: t(12)u()b(A5C)m(8) @@ -504,6 +507,7 @@ namespace emp { } os << '\n'; } + #endif // DOXYGEN_SHOULD_SKIP_THIS template size_t AvidaCPU_Base::PredictNextInst() const { @@ -537,6 +541,7 @@ namespace emp { return inst_ptr; } + #ifndef DOXYGEN_SHOULD_SKIP_THIS template void AvidaCPU_Base::PrintState(std::ostream & os) const { size_t next_inst = PredictNextInst(); @@ -568,6 +573,7 @@ namespace emp { // emp::vector reg_stack; // emp::vector call_stack; } + #endif // DOXYGEN_SHOULD_SKIP_THIS class AvidaGP : public AvidaCPU_Base { public: @@ -587,6 +593,7 @@ namespace emp { }; } +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { /// operator<< to work with ostream (must be in std to work) @@ -595,5 +602,6 @@ namespace std { return out; } } +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_HARDWARE_AVIDAGP_HPP_INCLUDE diff --git a/include/emp/hardware/BitSorter.hpp b/include/emp/hardware/BitSorter.hpp index 746a4eab48..6d58c0e9f8 100644 --- a/include/emp/hardware/BitSorter.hpp +++ b/include/emp/hardware/BitSorter.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file BitSorter.hpp + * @file * @brief A quick series of comparisons intended for sorting bits. */ #ifndef EMP_HARDWARE_BITSORTER_HPP_INCLUDE #define EMP_HARDWARE_BITSORTER_HPP_INCLUDE +#include +#include #include #include "../base/vector.hpp" @@ -20,7 +23,7 @@ namespace emp { class BitSorter { public: - using bits_t = uint32_t; ///< Type used to represent pairs if posisions as bit masks. + using bits_t = uint32_t; ///< Type used to represent pairs if positions as bit masks. protected: emp::vector compare_set; ///< Comparators, in order (pairs of 1's in bitstring) @@ -183,6 +186,7 @@ namespace emp { } +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { /// operator<< to work with ostream (must be in std to work) @@ -191,5 +195,6 @@ namespace std { return out; } } +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_HARDWARE_BITSORTER_HPP_INCLUDE diff --git a/include/emp/hardware/EventDrivenGP.hpp b/include/emp/hardware/EventDrivenGP.hpp index bbaca6cdd6..43e1852531 100644 --- a/include/emp/hardware/EventDrivenGP.hpp +++ b/include/emp/hardware/EventDrivenGP.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file EventDrivenGP.hpp + * @file * @brief TODO. */ @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -393,7 +395,10 @@ namespace emp { Function( const affinity_t & _aff=affinity_t(), const inst_seq_t & _seq=inst_seq_t(), - std::function _fun_matchbin_refresh=[](){} + std::function _fun_matchbin_refresh + #ifndef DOXYGEN_SHOULD_SKIP_THIS + =[](){} + #endif // DOXYGEN_SHOULD_SKIP_THIS ) : affinity(_aff) , inst_seq(_seq) , fun_matchbin_refresh(_fun_matchbin_refresh) @@ -820,7 +825,9 @@ namespace emp { size_t exec_core_id; //< core ID of the currently executing core. bool is_executing; //< True when mid-execution of all cores. (On every CPU cycle: execute all cores). MATCHBIN_T matchBin; + #ifndef DOXYGEN_SHOULD_SKIP_THIS trait_printer_t fun_trait_print = [](std::ostream& os, TRAIT_T){os << "UNCONFIGURED TRAIT PRINT FUNCTION\n";}; + #endif // DOXYGEN_SHOULD_SKIP_THIS // TODO: disallow configuration of hardware while executing. (and any other functions that could sent things into a bad state) diff --git a/include/emp/hardware/EventLib.hpp b/include/emp/hardware/EventLib.hpp index 4fd9db33e1..47a36e2e56 100644 --- a/include/emp/hardware/EventLib.hpp +++ b/include/emp/hardware/EventLib.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file EventLib.hpp + * @file * @brief This file maintains information about events available in virtual hardware. * * This file is largely based on InstLib.h. @@ -15,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/include/emp/hardware/Genome.hpp b/include/emp/hardware/Genome.hpp index ad35313162..bc2fcd3414 100644 --- a/include/emp/hardware/Genome.hpp +++ b/include/emp/hardware/Genome.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file Genome.hpp + * @file * @brief This is a simple, container for a series of instructions. * */ @@ -11,10 +12,10 @@ #ifndef EMP_HARDWARE_GENOME_HPP_INCLUDE #define EMP_HARDWARE_GENOME_HPP_INCLUDE -#include "../base/Ptr.hpp" - +#include #include "../base/array.hpp" +#include "../base/Ptr.hpp" #include "../base/vector.hpp" #include "../datastructs/map_utils.hpp" #include "../io/File.hpp" diff --git a/include/emp/hardware/InstLib.hpp b/include/emp/hardware/InstLib.hpp index 072e14d019..c0e8116f2e 100644 --- a/include/emp/hardware/InstLib.hpp +++ b/include/emp/hardware/InstLib.hpp @@ -1,16 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2021. - * - * @file InstLib.hpp - * @brief This file maintains information about instructions available in virtual hardware. + * @file + * @brief This file maintains information about instructions availabel in virtual hardware. */ #ifndef EMP_HARDWARE_INSTLIB_HPP_INCLUDE #define EMP_HARDWARE_INSTLIB_HPP_INCLUDE #include +#include #include #include @@ -28,9 +30,9 @@ namespace emp { enum class ScopeType { NONE=0, ROOT, BASIC, LOOP, FUNCTION }; /// @brief InstLib maintains a set of instructions for use in virtual hardware. - /// @param HARDWARE_T Type of the virtual hardware class to track instructions. - /// @param ARG_T What types of arguments are associated with instructions. - /// @param ARG_COUNT Max number of arguments on an instruction. + /// @tparam HARDWARE_T Type of the virtual hardware class to track instructions. + /// @tparam ARG_T What types of arguments are associated with instructions. + /// @tparam ARG_COUNT Max number of arguments on an instruction. template class InstLib { public: @@ -121,6 +123,8 @@ namespace emp { /// Get the number of instructions in this set. size_t GetSize() const { return inst_lib.size(); } + /// Returns boolean indicating whether the given + /// string is a valid instruction. bool IsInst(const std::string name) const { return Has(name_map, name); } @@ -135,7 +139,7 @@ namespace emp { } /// Return the ID of the instruction associated with the specified symbol. - size_t GetID(char symbol) { + size_t GetIDFromSymbol(char symbol) const { emp_assert(symbol > 0); return symbol_map[(size_t) symbol]; } @@ -145,12 +149,17 @@ namespace emp { emp_assert(Has(name_map, name), name); return Find(name_map, name, (size_t) -1); } - /// Return the ID of the instruction that has the specified name. + /// Return the ID of the instruction that has the specified id. size_t GetIndex(const size_t id) const { emp_assert(Has(id_map, id), id); return Find(id_map, id, (size_t) -1); } + size_t GetIndexFromSymbol(char symbol) const { + size_t id = GetIDFromSymbol(symbol); + return GetIndex(id); + } + /// Return the argument value associated with the provided keyword. arg_t GetArg(const std::string & name) { emp_assert(Has(arg_map, name)); diff --git a/include/emp/hardware/LinearCode.hpp b/include/emp/hardware/LinearCode.hpp index 17d0f2d9bd..d41bef963c 100644 --- a/include/emp/hardware/LinearCode.hpp +++ b/include/emp/hardware/LinearCode.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file LinearCode.hpp + * @file * @brief A linear sequence of instructions. */ #ifndef EMP_HARDWARE_LINEARCODE_HPP_INCLUDE #define EMP_HARDWARE_LINEARCODE_HPP_INCLUDE +#include + #include "../base/array.hpp" #include "../base/vector.hpp" diff --git a/include/emp/hardware/VirtualCPU.hpp b/include/emp/hardware/VirtualCPU.hpp index 46fa6ba168..1f13889f21 100644 --- a/include/emp/hardware/VirtualCPU.hpp +++ b/include/emp/hardware/VirtualCPU.hpp @@ -1,11 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file VirtualCPU.hpp + * @file * @brief A simple virtual CPU styled after the original and extended Avidian architectures. - * * @TODO * - Expanded heads? * - expanded_nop_args useful? @@ -51,7 +51,7 @@ namespace emp{ struct Instruction; using derived_t = DERIVED; - using data_t = uint32_t; + using data_t = int32_t; using inst_t = Instruction; using inst_lib_t = VirtualCPU_InstLib; using genome_t = Genome; @@ -126,6 +126,8 @@ namespace emp{ ///< copy next size_t write_head; ///< Write head, signals where to copy next ///< instruction + size_t cooldown_timer = 0; ///< Do not process inst if value > 0. + ///< Decrease this value instead //////// HELPER CONSTRUCTS emp::unordered_map nop_id_map;/**< NOP inst id -> Nop index (e.g., NopA -> 0, NopB -> 1, @@ -229,6 +231,16 @@ namespace emp{ return false; } + /// Load genome from a string of characters + bool LoadFromChars(const std::string & new_genome){ + ClearGenome(); + for(size_t idx = 0; idx < new_genome.size(); ++idx){ + PushInst(new_genome[idx]); + } + nops_need_curated = true; + return true; + } + /// Add a new instruction to the end of the genome, by index in the instruction library void PushInst(size_t idx) { const size_t id = GetInstLib()->GetID(idx); @@ -237,6 +249,12 @@ namespace emp{ nops_need_curated = true; } + /// Redirect literal ints to PushInst(size_t) overload. + void PushInst(int idx) { PushInst(static_cast(idx)); } + + /// Add a new instruction to the end of the genome, by the instruction's symbol/char + void PushInst(char c) { PushInst( GetInstLib()->GetIndexFromSymbol(c) ); } + /// Add a new instruction to the end of the genome, by name void PushInst(const std::string & name) { PushInst(GetInstLib()->GetIndex(name)); @@ -318,6 +336,19 @@ namespace emp{ genome_working.erase(genome_working.begin() + idx); nops_need_curated = true; } + /// Increase the cooldown by some value, so instructions cannot be processed for longer + void IncreaseCooldown(size_t val){ + cooldown_timer += val; + } + /// Decrease the cooldown by some value, so instructions can be processed sooner + void DecreaseCooldown(size_t val){ + if(cooldown_timer >= val) cooldown_timer -= val; + else cooldown_timer = 0; + } + /// Reset the cooldown timer + void ResetCooldown(){ + cooldown_timer = 0; + } @@ -419,6 +450,7 @@ namespace emp{ ResetRH(); ResetWH(); ResetFH(); + ResetCooldown(); } /// Reset all inputs and outputs void ResetIO() { @@ -729,17 +761,23 @@ namespace emp{ //////// PROCESSING /// Process the next instruction pointed to be the instruction pointer void SingleProcess(bool verbose = true) { - emp_assert(genome_working.GetSize() > 0); // A genome must exist to be processed. - if (!are_regs_expanded) ExpandRegisters(); - if (nops_need_curated) CurateNops(); - if (verbose) { - GetInstLib()->GetName(genome_working[inst_ptr].idx); - PrintDetails(); + if(cooldown_timer > 0){ + DecreaseCooldown(1); + num_insts_executed++; + } + else{ + emp_assert(genome_working.GetSize() > 0); // A genome must exist to be processed. + if(!are_regs_expanded) ExpandRegisters(); + if(nops_need_curated) CurateNops(); + if(verbose){ + GetInstLib()->GetName(genome_working[inst_ptr].idx); + PrintDetails(); + } + genome_working[inst_ptr].has_been_executed = true; + GetInstLib()->ProcessInst(ToPtr(this), genome_working[inst_ptr]); + AdvanceIP(); + num_insts_executed++; } - genome_working[inst_ptr].has_been_executed = true; - GetInstLib()->ProcessInst(ToPtr(this), genome_working[inst_ptr]); - AdvanceIP(); - num_insts_executed++; } /// Process the next SERIES of instructions, directed by the instruction pointer. void Process(size_t num_inst = 1, bool verbose = true) { @@ -776,6 +814,19 @@ namespace emp{ } return sstr.str(); } + /// Return the original genome in string form, without the genome length. + /// + /// Each instruction is represented by a single character, dictated by the + /// instruction's ID. + std::string GetRawGenomeString() const{ + std::stringstream sstr; + for(size_t idx = 0; idx < genome.size(); idx++){ + unsigned char c = 'a' + genome[idx].id; + if(genome[idx].id > 25) c = 'A' + genome[idx].id - 26; + sstr << c; + } + return sstr.str(); + } /// Output the state of the CPU's heads and registers to the specified output stream void PrintDetails(std::ostream& os = std::cout) { os << "IP: " << inst_ptr; diff --git a/include/emp/hardware/VirtualCPU_InstLib.hpp b/include/emp/hardware/VirtualCPU_InstLib.hpp index 74d02b79a5..626543ac11 100644 --- a/include/emp/hardware/VirtualCPU_InstLib.hpp +++ b/include/emp/hardware/VirtualCPU_InstLib.hpp @@ -1,10 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022 - * - * @file VirtualCPU_InstLib.hpp + * @file * @brief A specialized version of InstLib to handle VirtualCPU instructions. + * */ #ifndef EMP_HARDWARE_VIRTUALCPU_INSTLIB_HPP_INCLUDE diff --git a/include/emp/hardware/signalgp_utils.hpp b/include/emp/hardware/signalgp_utils.hpp index 7206cb8dc7..5a2a39eb89 100644 --- a/include/emp/hardware/signalgp_utils.hpp +++ b/include/emp/hardware/signalgp_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2022. - * - * @file signalgp_utils.hpp + * @file * @brief Helper functions for working with SignalGP virtual hardware/programs. * @todo Mutator class * @todo tests @@ -13,7 +14,9 @@ #define EMP_HARDWARE_SIGNALGP_UTILS_HPP_INCLUDE #include +#include #include +#include #include #include @@ -33,6 +36,7 @@ namespace emp { /// @param unique_from - Other tags that the tag being generated should be unique with respect to. template BitSet GenRandSignalGPTag(emp::Random & rnd, const emp::vector> & unique_from=emp::vector>()) { + #ifndef DOXYGEN_SHOULD_SKIP_THIS using tag_t = BitSet; emp_assert(unique_from.size() < emp::Pow2(TAG_WIDTH), "Tag width is not large enough to be able to guarantee requested number of unique tags"); tag_t new_tag(rnd, 0.5); // Make a random tag. @@ -48,6 +52,7 @@ namespace emp { } } return new_tag; + #endif // DOXYGEN_SHOULD_SKIP_THIS } @@ -217,9 +222,8 @@ namespace emp { /// - Single-instruction substitution (applied per-instruction) /// - Single-instruction insertions and deletions (each applied per-instruction) /// - Instruction-tag bit-flips (applied per-bit) - /// - Instruction-argument substitutions (applied per-argument) - /// NOTE: could use some feedback on this! - /// - Not loving the inconsistency between rates and constraints at the moment. + /// - Instruction-argument substitutions (applied per-argument) NOTE: could use some feedback on this! + /// - Not loving the inconsistency between rates and constraints at the moment. template< size_t TAG_WIDTH, typename TRAIT_T=double, diff --git a/include/emp/in_progress/AST.hpp b/include/emp/in_progress/AST.hpp new file mode 100644 index 0000000000..f55ae94f46 --- /dev/null +++ b/include/emp/in_progress/AST.hpp @@ -0,0 +1,60 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ +/** + * @file + * @brief Tools to build an Abstract Syntax Tree. + * @note Status: ALPHA + */ + +#ifndef EMP_IN_PROGRESS_AST_HPP_INCLUDE +#define EMP_IN_PROGRESS_AST_HPP_INCLUDE + +#include + +#include "../base/assert.hpp" +#include "../base/error.hpp" +#include "../meta/TypeID.hpp" + +namespace emp { + + template + struct AST { + + // Base class for all AST nodes. + class Node { + protected: + emp::Ptr parent; + public: + Node(emp::Ptr in_parent=nullptr) : parent(in_parent) { } + virtual ~Node(); + + emp::Ptr GetParent() { return parent; } + void SetParent(emp::Ptr in_parent) { parent = in_parent; } + + virtual std::string GetName() const = 0; + virtual emp::TypeID GetType() const = 0; + + virtual bool IsLeaf() const { return false; } + virtual bool IsInternal() const { return false; } + + virtual size_t GetNumChildren() const { return 0; } + virtual emp::Ptr GetChild(size_t /* id */) { + emp_error("Calling GetChild on AST::Node with no children.")); + return nullptr; + } + + // virtual emp::Ptr GetScope() { return parent ? parent->GetScope() : nullptr; } + // virtual entry_ptr_t Process() = 0; + virtual std::function AsMathFunction() = 0; + + virtual void Write(std::ostream & /* os */=std::cout, + const std::string & /* offset */="") const { } + } + + }; +} + +#endif // #ifndef EMP_IN_PROGRESS_AST_HPP_INCLUDE diff --git a/include/emp/in_progress/BatchConfig.hpp b/include/emp/in_progress/BatchConfig.hpp index 756b897bc2..c344e4f411 100644 --- a/include/emp/in_progress/BatchConfig.hpp +++ b/include/emp/in_progress/BatchConfig.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file BatchConfig.hpp + * @file * @brief A tool to control a series of runs and keep them updated. * * Development notes: currently doesn't compile because of last line. @@ -13,6 +14,7 @@ #define EMP_IN_PROGRESS_BATCHCONFIG_HPP_INCLUDE #include +#include #include "../base/vector.hpp" diff --git a/include/emp/in_progress/ConfigLexer.hpp b/include/emp/in_progress/ConfigLexer.hpp index d7f7078e94..2af0db3542 100644 --- a/include/emp/in_progress/ConfigLexer.hpp +++ b/include/emp/in_progress/ConfigLexer.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file ConfigLexer.hpp + * @file * @brief A simple lexer for the Empirical configuration language. * * Development notes: Initially building the lexer to be language specific, but a diff --git a/include/emp/in_progress/ConfigParser.hpp b/include/emp/in_progress/ConfigParser.hpp index b81b46088f..f5b4c1db7b 100644 --- a/include/emp/in_progress/ConfigParser.hpp +++ b/include/emp/in_progress/ConfigParser.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ConfigParser.hpp + * @file * @brief A simple parser for the Empirical configuration language. * * This parser is being implemented as a pushdown automata. diff --git a/include/emp/in_progress/Empower/Empower.hpp b/include/emp/in_progress/Empower/Empower.hpp index 5e9f8ba202..4d1b763ad0 100644 --- a/include/emp/in_progress/Empower/Empower.hpp +++ b/include/emp/in_progress/Empower/Empower.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Empower.hpp + * @file * @brief A scripting language built inside of C++ * * Empower is a scripting language built inside of Empirical to simplify and the use of fast @@ -34,6 +35,7 @@ #include #include +#include #include #include "../base/Ptr.hpp" diff --git a/include/emp/in_progress/Empower/MemoryImage.hpp b/include/emp/in_progress/Empower/MemoryImage.hpp index adf3a8e80e..21c9f7a959 100644 --- a/include/emp/in_progress/Empower/MemoryImage.hpp +++ b/include/emp/in_progress/Empower/MemoryImage.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file MemoryImage.hpp + * @file * @brief A collection of arbitrary objects stored in a chunk of memory. */ #ifndef EMP_IN_PROGRESS_EMPOWER_MEMORYIMAGE_HPP_INCLUDE #define EMP_IN_PROGRESS_EMPOWER_MEMORYIMAGE_HPP_INCLUDE +#include + #include "../base/assert.hpp" #include "../base/Ptr.hpp" #include "../base/vector.hpp" diff --git a/include/emp/in_progress/Empower/Struct.hpp b/include/emp/in_progress/Empower/Struct.hpp index efacb088cc..12e31e50db 100644 --- a/include/emp/in_progress/Empower/Struct.hpp +++ b/include/emp/in_progress/Empower/Struct.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Struct.hpp + * @file * @brief Struct is a set of active variables, grouped by name (organized by a specific StructType) */ #ifndef EMP_IN_PROGRESS_EMPOWER_STRUCT_HPP_INCLUDE #define EMP_IN_PROGRESS_EMPOWER_STRUCT_HPP_INCLUDE +#include + #include "../base/assert.hpp" #include "../base/Ptr.hpp" #include "../base/vector.hpp" diff --git a/include/emp/in_progress/Empower/StructType.hpp b/include/emp/in_progress/Empower/StructType.hpp index fb3e31974d..959b215ff5 100644 --- a/include/emp/in_progress/Empower/StructType.hpp +++ b/include/emp/in_progress/Empower/StructType.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file StructType.hpp + * @file * @brief StructType maps variables to a MemoryImage; Struct is an instance of StructType * * @todo Immediately before setting a StructType to active, we can optimize variable ordering. @@ -12,6 +13,7 @@ #ifndef EMP_IN_PROGRESS_EMPOWER_STRUCTTYPE_HPP_INCLUDE #define EMP_IN_PROGRESS_EMPOWER_STRUCTTYPE_HPP_INCLUDE +#include #include #include "../base/assert.hpp" diff --git a/include/emp/in_progress/Empower/Type.hpp b/include/emp/in_progress/Empower/Type.hpp index dfaa0fafb8..26125b8a73 100644 --- a/include/emp/in_progress/Empower/Type.hpp +++ b/include/emp/in_progress/Empower/Type.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Type.hpp + * @file * @brief A collection of information about how to manage variables of a specified type. */ @@ -11,6 +12,7 @@ #define EMP_IN_PROGRESS_EMPOWER_TYPE_HPP_INCLUDE #include +#include #include #include "../base/assert.hpp" diff --git a/include/emp/in_progress/Empower/TypeManager.hpp b/include/emp/in_progress/Empower/TypeManager.hpp index 2e2b138b70..bf4e58d2dc 100644 --- a/include/emp/in_progress/Empower/TypeManager.hpp +++ b/include/emp/in_progress/Empower/TypeManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file TypeManager.hpp + * @file * @brief Handles creation or retrieval of type objects. */ @@ -11,6 +12,7 @@ #define EMP_IN_PROGRESS_EMPOWER_TYPEMANAGER_HPP_INCLUDE #include +#include #include #include diff --git a/include/emp/in_progress/Empower/Var.hpp b/include/emp/in_progress/Empower/Var.hpp index 84061f3526..2df7bb0611 100644 --- a/include/emp/in_progress/Empower/Var.hpp +++ b/include/emp/in_progress/Empower/Var.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Var.hpp + * @file * @brief A collection of information about a single, instantiated variable in Empower */ #ifndef EMP_IN_PROGRESS_EMPOWER_VAR_HPP_INCLUDE #define EMP_IN_PROGRESS_EMPOWER_VAR_HPP_INCLUDE +#include + #include "../base/assert.hpp" #include "../base/Ptr.hpp" #include "../meta/TypeID.hpp" diff --git a/include/emp/in_progress/Empower/VarInfo.hpp b/include/emp/in_progress/Empower/VarInfo.hpp index 7d0e30477d..49169e78be 100644 --- a/include/emp/in_progress/Empower/VarInfo.hpp +++ b/include/emp/in_progress/Empower/VarInfo.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file VarInfo.hpp + * @file * @brief Generic info about a single variable (across MemoryImages) */ #ifndef EMP_IN_PROGRESS_EMPOWER_VARINFO_HPP_INCLUDE #define EMP_IN_PROGRESS_EMPOWER_VARINFO_HPP_INCLUDE +#include + #include "../base/assert.hpp" #include "../base/Ptr.hpp" diff --git a/include/emp/in_progress/Empower2/Var.hpp b/include/emp/in_progress/Empower2/Var.hpp index fd9604f255..4aa176850d 100644 --- a/include/emp/in_progress/Empower2/Var.hpp +++ b/include/emp/in_progress/Empower2/Var.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Var.hpp + * @file * @brief A collection of information about a single, instantiated variable in Empower * * @@ -18,6 +19,7 @@ #ifndef EMP_IN_PROGRESS_EMPOWER2_VAR_HPP_INCLUDE #define EMP_IN_PROGRESS_EMPOWER2_VAR_HPP_INCLUDE +#include #include #include "../base/assert.hpp" diff --git a/include/emp/in_progress/Parser.hpp b/include/emp/in_progress/Parser.hpp index d681d64afa..6d3568b228 100644 --- a/include/emp/in_progress/Parser.hpp +++ b/include/emp/in_progress/Parser.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019. - * - * @file Parser.hpp + * @file * @brief A general-purpose, fast parser. * @note Status: DEVELOPMENT * @@ -27,6 +28,7 @@ #define EMP_IN_PROGRESS_PARSER_HPP_INCLUDE #include +#include #include "../base/vector.hpp" #include "../bits/BitVector.hpp" diff --git a/include/emp/in_progress/Ptr-overload-fix.hpp b/include/emp/in_progress/Ptr-overload-fix.hpp new file mode 100644 index 0000000000..d7078ad0b9 --- /dev/null +++ b/include/emp/in_progress/Ptr-overload-fix.hpp @@ -0,0 +1,1068 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022 +*/ +/** + * @file + * @brief A wrapper for pointers that does careful memory tracking (but only in debug mode). + * @note Status: BETA + * + * Ptr objects behave as normal pointers under most conditions. However, if a program is + * compiled with EMP_TRACK_MEM set, then these pointers perform extra tests to ensure that + * they point to valid memory and that memory is freed before pointers are released. + * + * If you want to prevent pointers to pointers (a common source of errors, but MAY be done + * intentionally) you can define EMP_NO_PTR_TO_PTR + * + * If you trip an assert, you can re-do the run a track a specific pointer by defining + * EMP_ABORT_PTR_NEW or EMP_ABORT_PTR_DELETE to the ID of the pointer in question. + * + * For example: -DEMP_ABORT_PTR_NEW=1691 + * + * This will allow you to track the pointer more easily in a debugger. + * + * @todo Track information about emp::vector and emp::array objects to make sure we don't + * point directly into them? (A resize() could make such pointers invalid!) Or better, warn + * it vector memory could have moved. + * @todo Get working with threads + */ + +#ifndef EMP_IN_PROGRESS_PTR_OVERLOAD_FIX_HPP_INCLUDE +#define EMP_IN_PROGRESS_PTR_OVERLOAD_FIX_HPP_INCLUDE + +#include +#include + +#include "assert.hpp" +#include "vector.hpp" + +namespace emp { + + // ------------ Pre-declare some helper types and functions -------------- + + template class Ptr; + + + template + inline void FillMemory(emp::Ptr mem_ptr, const size_t num_bytes, T fill_value); + + /// Fill an array by repeatedly calling the provided fill functions. + template + inline void FillMemoryFunction(emp::Ptr mem_ptr, const size_t num_bytes, T fill_fun); + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + namespace internal { + /// An anonymous log2 calculator for hashing below. + static constexpr size_t Log2(size_t x) { return x <= 1 ? 0 : (Log2(x/2) + 1); } + + static bool ptr_debug = false; + } + #endif // DOXYGEN_SHOULD_SKIP_THIS + inline void SetPtrDebug(bool _d = true) { internal::ptr_debug = _d; } + inline bool GetPtrDebug() { return internal::ptr_debug; } + + enum class PtrStatus { DELETED=0, ACTIVE, ARRAY }; + + class PtrInfo { + private: + const void * ptr; ///< Which pointer are we keeping data on? + int count; ///< How many of this pointer do we have? + PtrStatus status; ///< Has this pointer been deleted? (i.e., if so, don't access it!) + size_t array_bytes; ///< How big is the array pointed to (in bytes)? + + public: + PtrInfo(const void * _ptr) : ptr(_ptr), count(1), status(PtrStatus::ACTIVE), array_bytes(0) { + if (internal::ptr_debug) std::cout << "Created info for pointer: " << ptr << std::endl; + } + PtrInfo(const void * _ptr, size_t _array_bytes) + : ptr(_ptr), count(1), status(PtrStatus::ARRAY), array_bytes(_array_bytes) + { + emp_assert(_array_bytes >= 1); + if (internal::ptr_debug) { + std::cout << "Created info for array pointer (bytes=" << array_bytes << "): " + << ptr << std::endl; + } + } + PtrInfo(const PtrInfo &) = default; + PtrInfo(PtrInfo &&) = default; + PtrInfo & operator=(const PtrInfo &) & = default; + PtrInfo & operator=(PtrInfo &&) & = default; + + ~PtrInfo() { + if (internal::ptr_debug) std::cout << "Deleted info for pointer " << ptr << std::endl; + } + + /// What pointer does this one hold information about? + const void * GetPtr() const noexcept { return ptr; } + + /// How many Ptr objects point to the associated position? + int GetCount() const noexcept { return count; } + + /// If this ptr is to an array, how many bytes large is the array (may be different from size!) + size_t GetArrayBytes() const noexcept { return array_bytes; } + + /// Is this pointer currently valid to access? + bool IsActive() const noexcept { return (bool) status; } + + /// Is this pointer pointing to an array? + bool IsArray() const noexcept { return status == PtrStatus::ARRAY; } + + /// Denote that this pointer is an array. + void SetArray(size_t bytes) noexcept { array_bytes = bytes; status = PtrStatus::ARRAY; } + + /// Add one more pointer. + void Inc([[maybe_unused]] const size_t id) { + if (internal::ptr_debug) std::cout << "Inc info for pointer " << ptr << std::endl; + emp_assert(status != PtrStatus::DELETED, "Incrementing deleted pointer!", id); + count++; + } + + /// Remove a pointer. + void Dec([[maybe_unused]] const size_t id) { + if (internal::ptr_debug) std::cout << "Dec info for pointer " << ptr << std::endl; + + // Make sure that we have more than one copy, -or- we've already deleted this pointer + emp_assert(count > 1 || status == PtrStatus::DELETED, "Removing last reference to owned Ptr!", id); + count--; + } + + /// Indicate that the associated position has been deleted. + void MarkDeleted() { + if (internal::ptr_debug) std::cout << "Marked deleted for pointer " << ptr << std::endl; + status = PtrStatus::DELETED; + } + + /// Debug utility to determine if everything looks okay with this pointer's information. + bool OK() const noexcept { + if (ptr == nullptr) return false; // Should not have info for a null pointer. + if (status == PtrStatus::ARRAY) { + if (array_bytes == 0) return false; // Arrays cannot be size 0. + if (count == 0) return false; // Active arrays must have pointers to them. + } + if (status == PtrStatus::ACTIVE) { + if (array_bytes > 0) return false; // non-arrays must be array size 0. + if (count == 0) return false; // Active pointers must have references to them. + } + return true; + } + }; + + + /// Facilitate tracking of all Ptr objects in this run. + class PtrTracker { + private: + std::unordered_map ptr_id; ///< Associate raw pointers with unique IDs + emp::vector id_info; ///< Associate IDs with pointer information. + static constexpr size_t UNTRACKED_ID = (size_t) -1; + + // Make PtrTracker a singleton. + PtrTracker() : ptr_id(), id_info() { + std::cout << "EMP_TRACK_MEM: Pointer tracking is active!\n"; + } + PtrTracker(const PtrTracker &) = delete; + PtrTracker(PtrTracker &&) = delete; + PtrTracker & operator=(const PtrTracker &) = delete; + PtrTracker & operator=(PtrTracker &&) = delete; + + public: + ~PtrTracker() { + // Track stats about pointer record. + size_t total = 0; + size_t remain = 0; + emp::vector undeleted_info; + + // Scan through live pointers and make sure all have been deleted. + for (const auto & info : id_info) { + total++; + if (info.GetCount()) remain++; + + if (info.IsActive()) { + undeleted_info.push_back(info); + } + } + + if (undeleted_info.size()) { + std::cerr << undeleted_info.size() << " undeleted pointers at end of execution.\n"; + for (size_t i = 0; i < undeleted_info.size() && i < 10; ++i) { + const auto & info = undeleted_info[i]; + std::cerr << " PTR=" << info.GetPtr() + << " count=" << info.GetCount() + << " active=" << info.IsActive() + << " id=" << ptr_id[info.GetPtr()] + << std::endl; + } + if (undeleted_info.size() > 10) { + std::cerr << " ..." << std::endl; + } + abort(); + } + + std::cout << "EMP_TRACK_MEM: No memory leaks found!\n " + << total << " pointers found; "; + if (remain) { + std::cout << remain << " still exist with a non-null value (but have been properly deleted)"; + } else std::cout << "all have been cleaned up fully."; + std::cout << std::endl; + } + + /// Treat this class as a singleton with a single Get() method to retrieve it. + static PtrTracker & Get() { static PtrTracker tracker; return tracker; } + + /// Get the info associated with an existing pointer. + PtrInfo & GetInfo(const void * ptr) { return id_info[ptr_id[ptr]]; } + PtrInfo & GetInfo(size_t id) { return id_info[id]; } + + /// Determine if a pointer is being tracked. + bool HasPtr(const void * ptr) const { + if (internal::ptr_debug) std::cout << "HasPtr: " << ptr << std::endl; + return ptr_id.find(ptr) != ptr_id.end(); + } + + /// Retrieve the ID associated with a pointer. + size_t GetCurID(const void * ptr) { emp_assert(HasPtr(ptr)); return ptr_id[ptr]; } + + /// Lookup how many pointers are being tracked. + size_t GetNumIDs() const { return id_info.size(); } + + /// How big is an array associated with an ID? + size_t GetArrayBytes(size_t id) const { return id_info[id].GetArrayBytes(); } + + /// Check if an ID is for a pointer that has been deleted. + bool IsDeleted(size_t id) const { + if (id == UNTRACKED_ID) return false; // Not tracked, so not deleted. + if (internal::ptr_debug) std::cout << "IsDeleted: " << id << std::endl; + return !id_info[id].IsActive(); + } + + /// Is a pointer active and ready to be used? + bool IsActive(const void * ptr) { + if (internal::ptr_debug) std::cout << "IsActive: " << ptr << std::endl; + if (ptr_id.find(ptr) == ptr_id.end()) return false; // Not in database. + return GetInfo(ptr).IsActive(); + } + + /// Is a pointer id associated with a pointer that's active and ready to be used? + bool IsActiveID(size_t id) { + if (id == UNTRACKED_ID) return false; + if (id >= id_info.size()) return false; + return id_info[id].IsActive(); + } + + /// Is an ID associated with an array? + bool IsArrayID(size_t id) { + if (internal::ptr_debug) std::cout << "IsArrayID: " << id << std::endl; + if (id == UNTRACKED_ID) return false; + if (id >= id_info.size()) return false; + return id_info[id].IsArray(); + } + + /// How many Ptr objects are associated with an ID? + int GetIDCount(size_t id) const { + if (internal::ptr_debug) std::cout << "Count: " << id << std::endl; + return id_info[id].GetCount(); + } + + /// This pointer was just created as a Ptr! + size_t New(const void * ptr) { + emp_assert(ptr); // Cannot track a null pointer. + size_t id = id_info.size(); +#ifdef EMP_ABORT_PTR_NEW + if (id == EMP_ABORT_PTR_NEW) { + std::cerr << "Aborting at creation of Ptr id " << id << std::endl; + abort(); + } +#endif + if (internal::ptr_debug) std::cout << "New: " << id << " (" << ptr << ")" << std::endl; + // Make sure pointer is not already stored -OR- has been deleted (since re-use is possible). + emp_assert(!HasPtr(ptr) || IsDeleted(GetCurID(ptr)), id); + id_info.emplace_back(ptr); + ptr_id[ptr] = id; + return id; + } + + /// This pointer was just created as a Ptr ARRAY! + size_t NewArray(const void * ptr, size_t array_bytes) { + size_t id = New(ptr); // Build the new pointer. + if (internal::ptr_debug) std::cout << " ...Array of size " << array_bytes << std::endl; + id_info[id].SetArray(array_bytes); + return id; + } + + /// Increment the number of Pointers associated with an ID + void IncID(size_t id) { + if (id == UNTRACKED_ID) return; // Not tracked! + if (internal::ptr_debug) std::cout << "Inc: " << id << std::endl; + id_info[id].Inc(id); + } + + /// Decrement the number of Pointers associated with an ID + void DecID(size_t id) { + if (id == UNTRACKED_ID) return; // Not tracked! + auto & info = id_info[id]; + if (internal::ptr_debug) std::cout << "Dec: " << id << "(" << info.GetPtr() << ")" << std::endl; + emp_assert(info.GetCount() > 0, "Decrementing Ptr, but already zero!", + id, info.GetPtr(), info.IsActive()); + info.Dec(id); + } + + /// Mark the pointers associated with this ID as deleted. + void MarkDeleted(size_t id) { +#ifdef EMP_ABORT_PTR_DELETE + if (id == EMP_ABORT_PTR_DELETE) { + std::cerr << "Aborting at deletion of Ptr id " << id << std::endl; + abort(); + } +#endif + if (internal::ptr_debug) std::cout << "Delete: " << id << std::endl; + emp_assert(id_info[id].IsActive(), "Deleting same emp::Ptr a second time!", id); + id_info[id].MarkDeleted(); + } + }; + + +////////////////////////////////// +// +// --- Ptr implementation --- +// +////////////////////////////////// + +#ifdef EMP_TRACK_MEM + + namespace { + // Debug information provided for each pointer type. + struct PtrDebug { + size_t current; + size_t total; + PtrDebug() : current(0), total(0) { ; } + void AddPtr() { current++; total++; } + void RemovePtr() { current--; } + }; + } + + /// Base class with common functionality (that should not exist in void pointers) + template + class BasePtr { + public: + TYPE * ptr; ///< The raw pointer associated with this Ptr object. + size_t id; ///< A unique ID for this pointer type. + + static constexpr size_t UNTRACKED_ID = (size_t) -1; + + BasePtr(TYPE * in_ptr, size_t in_id) : ptr(in_ptr), id(in_id) { + #ifdef EMP_NO_PTR_TO_PTR + emp_assert(!std::is_pointer_v, "Pointers to pointers are disallowed!"); + #endif + } + + static PtrTracker & Tracker() { return PtrTracker::Get(); } // Single tracker for al Ptr types + + /// Dereference a pointer. + [[nodiscard]] TYPE & operator*() const { + // Make sure a pointer is active and non-null before we dereference it. + emp_assert(Tracker().IsDeleted(id) == false /*, typeid(TYPE).name() */, id); + emp_assert(ptr != nullptr, "Do not dereference a null pointer!"); + return *ptr; + } + + /// Follow a pointer. + TYPE * operator->() const { + // Make sure a pointer is active before we follow it. + emp_assert(Tracker().IsDeleted(id) == false /*, typeid(TYPE).name() */, id); + emp_assert(ptr != nullptr, "Do not follow a null pointer!"); + return ptr; + } + + /// Indexing into array + TYPE & operator[](size_t pos) const { + emp_assert(Tracker().IsDeleted(id) == false /*, typeid(TYPE).name() */, id); + emp_assert(id == UNTRACKED_ID || Tracker().IsArrayID(id), "Only arrays can be indexed into.", id); + emp_assert(id == UNTRACKED_ID || Tracker().GetArrayBytes(id) > (pos*sizeof(TYPE)), + "Indexing out of range.", id, ptr, pos, sizeof(TYPE), Tracker().GetArrayBytes(id)); + emp_assert(ptr != nullptr, "Do not follow a null pointer!"); + return ptr[pos]; + } + + }; + + + /// Base class with functionality only needed in void pointers. + template <> + class BasePtr { + public: + void * ptr; ///< The raw pointer associated with this Ptr object. + size_t id; ///< A unique ID for this pointer type. + + BasePtr(void * in_ptr, size_t in_id) : ptr(in_ptr), id(in_id) { } + static PtrTracker & Tracker() { return PtrTracker::Get(); } // Single tracker for al Ptr types + }; + + /// Base class with functionality only needed in void pointers. + template <> + class BasePtr { + public: + const void * ptr; ///< The raw pointer associated with this Ptr object. + size_t id; ///< A unique ID for this pointer type. + + BasePtr(const void * in_ptr, size_t in_id) : ptr(in_ptr), id(in_id) { } + static PtrTracker & Tracker() { return PtrTracker::Get(); } // Single tracker for al Ptr types + }; + + /// Main Ptr class DEBUG definition. + template + class Ptr : public BasePtr { + public: + using BasePtr::ptr; + using BasePtr::id; + using BasePtr::Tracker; + + using element_type = TYPE; ///< Type being pointed at. + + static constexpr size_t UNTRACKED_ID = (size_t) -1; + + static PtrDebug & DebugInfo() { static PtrDebug info; return info; } // Debug info for each type + + /// Construct a null Ptr by default. + Ptr() : BasePtr(nullptr, UNTRACKED_ID) { + if (internal::ptr_debug) { + std::cout << "null construct." << std::endl; + } + } + + /// Construct using copy constructor + Ptr(const Ptr & _in) : BasePtr(_in.ptr, _in.id) { + if (internal::ptr_debug) std::cout << "copy construct: " << ptr << std::endl; + Tracker().IncID(id); + } + + /// Construct from a raw pointer of compatable type. + template + Ptr(std::enable_if_t,T2*> in_ptr, + bool track=false) + : BasePtr(in_ptr, UNTRACKED_ID) + { + if (internal::ptr_debug) { + std::cout << "raw construct: " << ((void *) ptr) << ". track=" << track << std::endl; + } + + // If this pointer is already active, link to it. + if (Tracker().IsActive(ptr)) { + id = Tracker().GetCurID(ptr); + Tracker().IncID(id); + } + // If we are not already tracking this pointer, but should be, add it. + else if (track) { + id = Tracker().New(ptr); + DebugInfo().AddPtr(); + } + } + + /// Construct from a raw pointer of compatible ARRAY type. + template + Ptr(std::enable_if_t,T2*> _ptr, + size_t array_size, + bool track) + : BasePtr(_ptr, UNTRACKED_ID) + { + const size_t array_bytes = array_size * sizeof(T2); + if (internal::ptr_debug) std::cout << "raw ARRAY construct: " << ptr + << ". size=" << array_size << "(" << array_bytes + << " bytes); track=" << track << std::endl; + + // If this pointer is already active, link to it. + if (Tracker().IsActive(ptr)) { + id = Tracker().GetCurID(ptr); + Tracker().IncID(id); + emp_assert(Tracker().GetArrayBytes(id) == array_bytes); // Make sure pointer is consistent. + } + // If we are not already tracking this pointer, but should be, add it. + else if (track) { + id = Tracker().NewArray(ptr, array_bytes); + DebugInfo().AddPtr(); + } + } + + /// Construct from another Ptr<> object of compatible type. + template + Ptr(std::enable_if_t, Ptr > _in) + : BasePtr(_in.Raw(), _in.GetID()) + { + if (internal::ptr_debug) std::cout << "inexact copy construct: " << ptr << std::endl; + Tracker().IncID(id); + } + + /// Construct from nullptr. + Ptr(std::nullptr_t) : Ptr() { + if (internal::ptr_debug) std::cout << "null construct 2." << std::endl; + } + + /// Destructor. + ~Ptr() { + if (internal::ptr_debug) { + std::cout << "destructing Ptr instance "; + if (ptr) std::cout << id << " (" << ((void *) ptr) << ")\n"; + else std::cout << "(nullptr)\n"; + } + Tracker().DecID(id); + } + + /// Is this Ptr currently nullptr? + [[nodiscard]] bool IsNull() const { return ptr == nullptr; } + + /// Convert this Ptr to a raw pointer that isn't going to be tracked. + [[nodiscard]] TYPE * Raw() const { + emp_assert(Tracker().IsDeleted(id) == false, "Do not convert deleted Ptr to raw.", id); + return ptr; + } + + /// Convert this Ptr to a raw pointer of a position in an array. + [[nodiscard]] TYPE * Raw(size_t pos) const { + emp_assert(Tracker().IsDeleted(id) == false, "Do not convert deleted Ptr to array raw.", id); + return &(ptr[pos]); + } + + /// Cast this Ptr to a different type. + template + [[nodiscard]] Ptr Cast() const { + emp_assert(Tracker().IsDeleted(id) == false, "Do not cast deleted pointers.", id); + return (T2*) ptr; + } + + /// Change constness of this Ptr's target; throw an assert of the cast fails. + template + [[nodiscard]] Ptr ConstCast() const { + emp_assert(Tracker().IsDeleted(id) == false, "Do not cast deleted pointers.", id); + emp_assert( (std::is_same< std::remove_const_t , std::remove_const_t >()) ); + return const_cast(ptr); + } + + /// Dynamically cast this Ptr to another type; throw an assert of the cast fails. + template + [[nodiscard]] Ptr DynamicCast() const { + emp_assert(Tracker().IsDeleted(id) == false, "Do not cast deleted pointers.", id); + return dynamic_cast(ptr); + } + + /// Reinterpret this Ptr to another type; throw an assert of the cast fails. + template + [[nodiscard]] Ptr ReinterpretCast() const { + emp_assert(Tracker().IsDeleted(id) == false, "Do not cast deleted pointers.", id); + #ifdef EMP_NO_PTR_TO_PTR + emp_assert(!std::is_pointer_v, "Reinterpreting as pointers to pointers is disallowed!"); + #endif + return reinterpret_cast(ptr); + } + + /// Get the unique ID associated with this pointer. + size_t GetID() const { return id; } + + /// Reallocate this Ptr to a newly allocated value using arguments passed in. + template + void New(T &&... args) { + Tracker().DecID(id); // Remove a pointer to any old memory... + + ptr = new TYPE(std::forward(args)...); // Special new that uses allocated space. + // ptr = (TYPE*) malloc (sizeof(TYPE)); // Build a new raw pointer. + // emp_emscripten_assert(ptr); // No exceptions in emscripten; assert alloc! + // ptr = new (ptr) TYPE(std::forward(args)...); // Special new that uses allocated space. + + if (internal::ptr_debug) std::cout << "Ptr::New() : " << ptr << std::endl; + id = Tracker().New(ptr); // And track it! + DebugInfo().AddPtr(); + } + + /// Reallocate this Ptr to a newly allocated array using the size passed in. + // template + // void NewArray(size_t array_size, Ts &&... args) { + void NewArray(size_t array_size) { + Tracker().DecID(id); // Remove a pointer to any old memory... + + // @CAO: This next portion of code is allocating an array of the appropriate type. + // We are currently using "new", but should shift over to malloc since new throws an + // exception when there's a problem, which will trigger an abort in Emscripten mode. + // We'd rather be able to identify a more specific problem. + ptr = new TYPE[array_size]; // Build a new raw pointer to an array. + // ptr = (TYPE*) malloc (array_size * sizeof(TYPE)); // Build a new raw pointer. + // emp_emscripten_assert(ptr, array_size); // No exceptions in emscripten; assert alloc! + // for (size_t i = 0; i < array_size; i++) { + // new (ptr + i*sizeof(TYPE)) TYPE(args...); + // } + + if (internal::ptr_debug) std::cout << "Ptr::NewArray() : " << ptr << std::endl; + id = Tracker().NewArray(ptr, array_size * sizeof(TYPE)); // And track it! + DebugInfo().AddPtr(); + } + + /// Delete this pointer (must NOT be an array). + void Delete() { + emp_assert(ptr, "Trying to delete null Ptr."); + emp_assert(id < Tracker().GetNumIDs(), id, "Trying to delete Ptr that we are not responsible for."); + emp_assert(Tracker().IsArrayID(id) == false, id, "Trying to delete array pointer as non-array."); + emp_assert(Tracker().IsActive(ptr), id, "Trying to delete inactive pointer (already deleted!)"); + if (internal::ptr_debug) std::cout << "Ptr::Delete() : " << ptr << std::endl; + delete ptr; + Tracker().MarkDeleted(id); + DebugInfo().RemovePtr(); + } + + /// Delete this pointer to an array (must be an array). + void DeleteArray() { + emp_assert(id < Tracker().GetNumIDs(), id, "Trying to delete Ptr that we are not responsible for."); + emp_assert(ptr, "Trying to delete null Ptr."); + emp_assert(Tracker().IsArrayID(id), id, "Trying to delete non-array pointer as array."); + emp_assert(Tracker().IsActive(ptr), id, "Trying to delete inactive pointer (already deleted!)"); + if (internal::ptr_debug) std::cout << "Ptr::DeleteArray() : " << ptr << std::endl; + delete [] ptr; + Tracker().MarkDeleted(id); + DebugInfo().RemovePtr(); + } + + /// Convert this pointer to a hash value. + size_t Hash() const noexcept { + // Chop off useless bits of pointer... + static constexpr size_t shift = internal::Log2(1 + sizeof(TYPE)); + return (size_t)(ptr) >> shift; + } + struct hash_t { size_t operator()(const Ptr & t) const noexcept { return t.Hash(); } }; + + /// Copy assignment + Ptr & operator=(const Ptr & _in) & { + if (internal::ptr_debug) { + std::cout << "copy assignment from id " << _in.id << " to id " << id + << std::endl; + } + emp_assert(Tracker().IsDeleted(_in.id) == false, _in.id, "Do not copy deleted pointers."); + if (id != _in.id || ptr != _in.ptr) { // Assignments only need to happen if ptrs are different. + if (internal::ptr_debug) std::cout << "...pointers differ -- copying!" << std::endl; + Tracker().DecID(id); + ptr = _in.ptr; + id = _in.id; + Tracker().IncID(id); + } else { + if (internal::ptr_debug) std::cout << "...pointers same -- no copying!" << std::endl; + } + return *this; + } + + /// Assign to a raw pointer of the correct type; if this is already tracked, hooked in + /// correctly, otherwise don't track. + template + Ptr & operator=(std::enable_if_t,T2*> _in) & { + if (internal::ptr_debug) std::cout << "raw assignment" << std::endl; + + Tracker().DecID(id); // Decrement references to former pointer at this position. + ptr = _in; // Update to new pointer. + + // If this pointer is already active, link to it. + if (Tracker().IsActive(ptr)) { + id = Tracker().GetCurID(ptr); + Tracker().IncID(id); + } + // Otherwise, since this ptr was passed in as a raw pointer, we do not manage it. + else { + id = UNTRACKED_ID; + } + + return *this; + } + + /// Assign to a convertible Ptr + template + Ptr & operator=(std::enable_if_t, Ptr > _in) & { + if (internal::ptr_debug) std::cout << "convert-copy assignment" << std::endl; + emp_assert(Tracker().IsDeleted(_in.id) == false, _in.id, "Do not copy deleted pointers."); + Tracker().DecID(id); + ptr = _in.Raw(); + id = _in.GetID(); + Tracker().IncID(id); + return *this; + } + + /// Auto-cast to raw pointer type. + operator TYPE *() { + // Make sure a pointer is active before we convert it. + emp_assert(Tracker().IsDeleted(id) == false /*, typeid(TYPE).name() */, id); + + // We should not automatically convert managed pointers to raw pointers; use .Raw() + emp_assert(id != UNTRACKED_ID /*, typeid(TYPE).name() */, id, + "Use Raw() to convert to an untracked Ptr"); + return ptr; + } + + /// Does this pointer exist? + operator bool() { return ptr != nullptr; } + + /// Does this const pointer exist? + operator bool() const { return ptr != nullptr; } + + template bool operator==(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr == in_ptr.ptr; } + else { return ptr == in_ptr; } + } + template bool operator!=(const T & in_ptr) const { return !operator==(in_ptr); } + + template bool operator<(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr < in_ptr.ptr; } + else { return ptr < in_ptr; } + } + template bool operator>(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr > in_ptr.ptr; } + else { return ptr > in_ptr; } + } + template bool operator<=(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr <= in_ptr.ptr; } + else { return ptr <= in_ptr; } + } + template bool operator>=(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr >= in_ptr.ptr; } + else { return ptr >= in_ptr; } + } + + [[nodiscard]] Ptr operator+(int value) const { return ptr + value; } + [[nodiscard]] Ptr operator-(int value) const { return ptr - value; } + [[nodiscard]] Ptr operator+(size_t value) const { return ptr + value; } + [[nodiscard]] Ptr operator-(size_t value) const { return ptr - value; } + + /// Fill an array with the provided fill_value. + /// If fill_value is a function, repeatedly call function. + template + void FillMemoryFunction(const size_t num_bytes, T fill_fun) { + // Make sure a pointer is active before we write to it. + emp_assert(Tracker().IsDeleted(id) == false /*, typeid(TYPE).name() */, id); + emp_assert(id == UNTRACKED_ID || Tracker().IsArrayID(id), "Only arrays can fill memory.", id); + emp_assert(id == UNTRACKED_ID || Tracker().GetArrayBytes(id) >= num_bytes, + "Overfilling memory.", id, ptr, sizeof(TYPE), Tracker().GetArrayBytes(id)); + emp_assert(ptr != nullptr, "Do not follow a null pointer!"); + + emp::FillMemoryFunction(*this, num_bytes, fill_fun); + } + + /// Fill an array with the provided fill_value. + /// If fill_value is a function, repeatedly call function. + template + void FillMemory(const size_t num_bytes, T fill_value) { + // Make sure a pointer is active before we write to it. + emp_assert(Tracker().IsDeleted(id) == false /*, typeid(TYPE).name() */, id); + emp_assert(Tracker().IsArrayID(id) || id == UNTRACKED_ID, "Only arrays can fill memory.", id); + emp_assert(Tracker().GetArrayBytes(id) >= num_bytes, + "Overfilling memory.", id, ptr, sizeof(TYPE), Tracker().GetArrayBytes(id)); + emp_assert(ptr != nullptr, "Do not follow a null pointer!"); + + emp::FillMemory(*this, num_bytes, fill_value); + } + + /// Some debug testing functions + int DebugGetCount() const { return Tracker().GetIDCount(id); } + bool DebugIsArray() const { return Tracker().IsArrayID(id); } + size_t DebugGetArrayBytes() const { return Tracker().GetArrayBytes(id); } + bool DebugIsActive() const { return Tracker().IsActiveID(id); } + + bool OK() const { + // Untracked ID's should not have pointers in the Tracker. + if (id == UNTRACKED_ID) return !Tracker().HasPtr(ptr); + + // Make sure this pointer is linked to the correct info. + if (Tracker().GetInfo(id).GetPtr() != ptr) return false; + + // And make sure that info itself is okay. + return Tracker().GetInfo(id).OK(); + } + + // Prevent use of new and delete on Ptr + // static void* operator new(std::size_t) noexcept { + // emp_assert(false, "No Ptr::operator new; use emp::NewPtr for clarity."); + // return nullptr; + // } + // static void* operator new[](std::size_t sz) noexcept { + // emp_assert(false, "No Ptr::operator new[]; use emp::NewPtrArray for clarity."); + // return nullptr; + // } + // + // static void operator delete(void* ptr, std::size_t sz) { + // emp_assert(false, "No Ptr::operator delete; use Delete() member function for clarity."); + // } + // static void operator delete[](void* ptr, std::size_t sz) { + // emp_assert(false, "No Ptr::operator delete[]; use DeleteArray() member function for clarity."); + // } + + }; + +#else // EMP_MEM_TRACK off... + + + template + class BasePtr { + protected: + TYPE * ptr; ///< The raw pointer associated with this Ptr object. + + public: + BasePtr(TYPE * in_ptr) : ptr(in_ptr) { } + + // Dereference a pointer. + [[nodiscard]] TYPE & operator*() const { return *ptr; } + + // Follow a pointer. + TYPE * operator->() const { return ptr; } + + // Should implement operator->* to follow a pointer to a member function. + // For an example, see: + // https://stackoverflow.com/questions/27634036/overloading-operator-in-c + + // Indexing into array + TYPE & operator[](size_t pos) const { return ptr[pos]; } + }; + + /// Base class with functionality only needed in void pointers. + template <> class BasePtr { + protected: void * ptr; ///< The raw pointer associated with this Ptr object. + public: BasePtr(void * in_ptr) : ptr(in_ptr) { } + }; + + template <> class BasePtr { + protected: const void * ptr; ///< The raw pointer associated with this Ptr object. + public: BasePtr(const void * in_ptr) : ptr(in_ptr) { } + }; + + template + class Ptr : public BasePtr { + private: + using BasePtr::ptr; + + public: + using element_type = TYPE; + + /// Default constructor + Ptr() : BasePtr(nullptr) {} + + /// Copy constructor + Ptr(const Ptr & _in) : BasePtr(_in.ptr) {} + + /// Construct from raw ptr + template + Ptr(std::enable_if_t,T2*> in_ptr, bool=false) + : BasePtr(in_ptr) {} + //Ptr(TYPE * in_ptr, bool=false) : BasePtr(in_ptr) {} + + /// Construct from array + template + Ptr(std::enable_if_t,T2*> _ptr, size_t, bool) + : BasePtr(_ptr) {} + + /// From compatible Ptr + template + Ptr(Ptr _in, std::enable_if_t,bool> = true) + : BasePtr(_in.Raw()) {} + + /// From nullptr + Ptr(std::nullptr_t) : Ptr() {} + + /// Destructor + ~Ptr() { ; } + + [[nodiscard]] bool IsNull() const { return ptr == nullptr; } + [[nodiscard]] TYPE * Raw() const { return ptr; } + [[nodiscard]] TYPE * Raw(size_t pos) const { return &(ptr[pos]); } + template Ptr Cast() const { return (T2*) ptr; } + template Ptr ConstCast() const { return const_cast(ptr); } + template Ptr DynamicCast() const { return dynamic_cast(ptr); } + template Ptr ReinterpretCast() const { return reinterpret_cast(ptr); } + + template + void New(T &&... args) { ptr = new TYPE(std::forward(args)...); } // New raw pointer. + void NewArray(size_t array_size) { ptr = new TYPE[array_size]; } + void Delete() { delete ptr; } + void DeleteArray() { delete [] ptr; } + + size_t Hash() const noexcept { + static constexpr size_t shift = internal::Log2(1 + sizeof(TYPE)); // Chop off useless bits... + return (size_t)(ptr) >> shift; + } + struct hash_t { size_t operator()(const Ptr & t) const noexcept { return t.Hash(); } }; + + // Copy assignments + Ptr & operator=(const Ptr & _in) & { ptr = _in.ptr; return *this; } + + // Assign to compatible Ptr or raw (non-managed) pointer. + template Ptr & operator=(std::enable_if_t,T2*> _in) & { ptr = _in; return *this; } + template Ptr & operator=(std::enable_if_t, Ptr > _in) & { ptr = _in.Raw(); return *this; } + + // Auto-cast to raw pointer type. + operator TYPE *() { return ptr; } + + operator bool() { return ptr != nullptr; } + operator bool() const { return ptr != nullptr; } + + template bool operator==(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr == in_ptr.ptr; } + else { return ptr == in_ptr; } + } + template bool operator!=(const T & in_ptr) const { return !operator==(in_ptr); } + + template bool operator<(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr < in_ptr.ptr; } + else { return ptr < in_ptr; } + } + template bool operator>(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr > in_ptr.ptr; } + else { return ptr > in_ptr; } + } + template bool operator<=(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr <= in_ptr.ptr; } + else { return ptr <= in_ptr; } + } + template bool operator>=(const T & in_ptr) const { + if constexpr (std::is_same>()) { return ptr >= in_ptr.ptr; } + else { return ptr >= in_ptr; } + } + + [[nodiscard]] Ptr operator+(int value) const { return ptr + value; } + [[nodiscard]] Ptr operator-(int value) const { return ptr - value; } + [[nodiscard]] Ptr operator+(size_t value) const { return ptr + value; } + [[nodiscard]] Ptr operator-(size_t value) const { return ptr - value; } + + // Extra functionality (not in raw pointers) + + /// Fill an array with the provided fill_value. + /// If fill_value is a function, repeatedly call function. + template + void FillMemoryFunction(const size_t num_bytes, T fill_fun) { + emp::FillMemoryFunction(*this, num_bytes, fill_fun); + } + + /// Fill an array with the provided fill_value. + /// If fill_value is a function, repeatedly call function. + template + void FillMemory(const size_t num_bytes, T fill_value) { + emp::FillMemory(*this, num_bytes, fill_value); + } + + // Stubs for debug-related functions when outside debug mode. + int DebugGetCount() const { return -1; } + bool DebugIsArray() const { emp_assert(false); return false; } + size_t DebugGetArrayBytes() const { return 0; } + bool DebugIsActive() const { return true; } + bool OK() const { return true; } + }; + +#endif // #ifdef EMP_TRACK_MEM + + // IO + template + std::ostream & operator<<(std::ostream & out, const emp::Ptr & ptr) { + out << ptr.Raw(); + return out; + } + + // @CAO: Reading a pointer from a stream seems like a terrible idea in most situations, but I + // can imagine limited circumstances where it would be needed. + template + std::istream & operator>>(std::istream & is, emp::Ptr & ptr) { + T * val; + is >> val; + ptr = val; + return is; + } + + /// Convert a T* to a Ptr. By default, don't track. + template + [[nodiscard]] Ptr ToPtr(T * _in, bool own=false) { return Ptr(_in, own); } + + /// Convert a T* to a Ptr that we DO track. + template + [[nodiscard]] Ptr TrackPtr(T * _in, bool own=true) { return Ptr(_in, own); } + + /// Create a new Ptr of the target type; use the args in the constructor. + template + [[nodiscard]] Ptr NewPtr(ARGS &&... args) { + auto ptr = new T(std::forward(args)...); + // auto ptr = (T*) malloc (sizeof(T)); // Build a new raw pointer. + // emp_assert(ptr); // No exceptions in emscripten; assert alloc! + // new (ptr) T(std::forward(args)...); // Special new that uses allocated space. + return Ptr(ptr, true); + } + + /// Copy an object pointed to and return a Ptr to the copy. + template + [[nodiscard]] Ptr CopyPtr(Ptr in) { return NewPtr(*in); } + + /// Copy a vector of objects pointed to; return a vector of Ptrs to the new copies. + template + [[nodiscard]] emp::vector> CopyPtrs(const emp::vector> & in) { + emp::vector> out_ptrs(in.size()); + for (size_t i = 0; i < in.size(); i++) out_ptrs[i] = CopyPtr(in[i]); + return out_ptrs; + } + + /// Copy a vector of objects pointed to by using their Clone() member function; return vector. + template + [[nodiscard]] emp::vector> ClonePtrs(const emp::vector> & in) { + emp::vector> out_ptrs(in.size()); + for (size_t i = 0; i < in.size(); i++) out_ptrs[i] = in[i]->Clone(); + return out_ptrs; + } + + /// Create a pointer to an array of objects. + template + [[nodiscard]] Ptr NewArrayPtr(size_t array_size) { + auto ptr = new T[array_size]; // Build a new raw pointer. + // const size_t alloc_size = array_size * sizeof(T); + // auto ptr = (T*) malloc (alloc_size); + emp_assert(ptr, array_size); // No exceptions in emscripten; assert alloc! + // for (size_t i = 0; i < array_size; i++) { // Loop through all array elements. + // new (ptr + i*sizeof(T)) T(args...); // ...and initialize them. + // } + return Ptr(ptr, array_size, true); + } + + /// Fill an array with the provided fill_value. + /// If fill_value is a function, repeatedly call function. + template + void FillMemory(emp::Ptr mem_ptr, const size_t num_bytes, T fill_value) { + // If the fill value is a function, call that function for each memory position. + if constexpr (std::is_invocable_v) { + FillMemoryFunction(mem_ptr, num_bytes, std::forward(fill_value)); + } + + constexpr size_t FILL_SIZE = sizeof(T); + + const size_t leftover = num_bytes % FILL_SIZE; + const size_t limit = num_bytes - leftover; + unsigned char * dest = mem_ptr.Raw(); + + // Fill out random bytes in groups of FILL_SIZE. + for (size_t byte = 0; byte < limit; byte += FILL_SIZE) { + std::memcpy(dest+byte, &fill_value, FILL_SIZE); + } + + // If we don't have a multiple of FILL_SIZE, fill in part of the remaining. + if (leftover) std::memcpy(dest+limit, &fill_value, leftover); + } + + /// Fill an array by repeatedly calling the provided fill functions. + template + void FillMemoryFunction(emp::Ptr mem_ptr, const size_t num_bytes, T fill_fun) { + static_assert(std::is_invocable_v, "FillMemoryFunction requires an invocable fill_fun."); + using return_t = decltype(fill_fun()); + constexpr size_t FILL_SIZE = sizeof(return_t); + + const size_t leftover = num_bytes % FILL_SIZE; + const size_t limit = num_bytes - leftover; + unsigned char * dest = mem_ptr.Raw(); + + // Fill out random bytes in groups of FILL_SIZE. + return_t fill_value; + for (size_t byte = 0; byte < limit; byte += FILL_SIZE) { + fill_value = fill_fun(); + std::memcpy(dest+byte, &fill_value, FILL_SIZE); + } + + // If we don't have a multiple of FILL_SIZE, fill in part of the remaining. + if (leftover) { + fill_value = fill_fun(); + std::memcpy(dest+limit, &fill_value, leftover); + } + } + +} // namespace emp + +#endif // #ifndef EMP_IN_PROGRESS_PTR_OVERLOAD_FIX_HPP_INCLUDE diff --git a/include/emp/in_progress/SimpleLexer.hpp b/include/emp/in_progress/SimpleLexer.hpp new file mode 100644 index 0000000000..875602484b --- /dev/null +++ b/include/emp/in_progress/SimpleLexer.hpp @@ -0,0 +1,88 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ +/** + * @file + * @brief Lexer with common functionality already filled in. + * @note Status: ALPHA + */ + +#ifndef EMP_IN_PROGRESS_SIMPLELEXER_HPP_INCLUDE +#define EMP_IN_PROGRESS_SIMPLELEXER_HPP_INCLUDE + +#include +#include + +#include "../base/error.hpp" +#include "../compiler/Lexer.hpp" + +namespace emp { + + using namespace std::string_literals; + + class SimpleLexer : public emp::Lexer { + private: + int token_identifier; ///< Token id for identifiers + int token_number; ///< Token id for literal numbers + int token_string; ///< Token id for literal strings + int token_char; ///< Token id for literal characters + int token_external; ///< Token id for strings to be evaluated externally. + int token_symbol; ///< Token id for other symbols + + public: + SimpleLexer() { + // Whitespace and comments should always be dismissed (top priority) + IgnoreToken("Whitespace", "[ \t\n\r]+"); + IgnoreToken("//-Comments", "//.*"); + IgnoreToken("/*...*/-Comments", "/[*]([^*]|([*]+[^*/]))*[*]+/"); + + // Meaningful tokens have next priority. + + // An indentifier must begin with a letter, underscore, or dot, and followed by + // more of the same OR numbers or brackets. + token_identifier = AddToken("Identifier", "[a-zA-Z_.][a-zA-Z0-9_.[\\]]*"); + + // A literal number must begin with a digit; it can have any number of digits in it and + // optionally a decimal point. + token_number = AddToken("Literal Number", "[0-9]+(\\.[0-9]+)?"); + + // A string must begin and end with a quote and can have an escaped quote in the middle. + token_string = AddToken("Literal String", "\\\"([^\"\\\\]|\\\\.)*\\\""); + + // A literal char must begin and end with a single quote. It will always be treated as + // its ascii value. + token_char = AddToken("Literal Character", "'([^'\n\\\\]|\\\\.)+'"); + + // Setup a RegEx that can detect up to 4-deep nested parentheses. + const std::string no_parens = "[^()\n\r]*"; + const std::string open = "\"(\""; + const std::string close = "\")\""; + const std::string matched_parens = open + no_parens + close; + const std::string multi_parens = no_parens + "("s + matched_parens + no_parens + ")*"s; + const std::string nested_parens2 = open + multi_parens + close; + const std::string multi_nested2 = no_parens + "("s + nested_parens2 + no_parens + ")*"s; + const std::string nested_parens3 = open + multi_nested2 + close; + const std::string multi_nested3 = no_parens + "("s + nested_parens3 + no_parens + ")*"s; + const std::string nested_parens4 = open + multi_nested3 + close; + const std::string multi_nested4 = no_parens + "("s + nested_parens4 + no_parens + ")*"s; + + // An external value should be evaluated in a provided function. If no such function + // exists, using it will be an error. + token_external = AddToken("External Evaluation", "\"$(\""s + multi_nested4 + "\")\""s); + + // Symbols should have least priority. They include any solitary character not listed + // above, or pre-specified multi-character groups. + token_symbol = AddToken("Symbol", ".|\"==\"|\"!=\"|\"<=\"|\">=\"|\"&&\"|\"||\"|\"**\"|\"%%\""); + } + + bool IsID(const emp::Token token) const noexcept { return token.token_id == token_identifier; } + bool IsNumber(const emp::Token token) const noexcept { return token.token_id == token_number; } + bool IsString(const emp::Token token) const noexcept { return token.token_id == token_string; } + bool IsChar(const emp::Token token) const noexcept { return token.token_id == token_char; } + bool IsSymbol(const emp::Token token) const noexcept { return token.token_id == token_symbol; } + }; +} + +#endif // #ifndef EMP_IN_PROGRESS_SIMPLELEXER_HPP_INCLUDE diff --git a/include/emp/in_progress/SimpleParser.hpp b/include/emp/in_progress/SimpleParser.hpp new file mode 100644 index 0000000000..bb344d573e --- /dev/null +++ b/include/emp/in_progress/SimpleParser.hpp @@ -0,0 +1,353 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ +/** + * @file + * @brief Common praser functionality with custom plugins for variables and functions. + * @note Status: ALPHA + * + * Developer TODO: + * - Make ${ ... } actually work + * - Setup operator RegEx to be built dynamically + * - Allow new operators to be added externally + * - Setup LVALUES as a type, and allow assignment + * - Add in a type system (String, double, vectors, etc.) + */ + +#ifndef EMP_IN_PROGRESS_SIMPLEPARSER_HPP_INCLUDE +#define EMP_IN_PROGRESS_SIMPLEPARSER_HPP_INCLUDE + +#include +#include + +#include "../base/error.hpp" +#include "../compiler/Lexer.hpp" + +#include "SimpleLexer.hpp" + +namespace emp { + class SimpleParser { + + using pos_t = emp::TokenStream::Iterator; + + bool verbose = false; + + using value_fun_t = std::function; + struct ValueType { + enum type_t { ERROR=0, VALUE, FUNCTION }; + + type_t type; + double value; + value_fun_t fun; + + ValueType() : type(ERROR) {} + ValueType(const ValueType &) = default; + ValueType(double in_val) : type(VALUE), value(in_val) { } + ValueType(value_fun_t in_fun) : type(FUNCTION), fun(in_fun) { } + + ValueType & operator=(const ValueType &) = default; + ValueType & operator=(double in_val) { type = VALUE; value = in_val; return *this; } + ValueType & operator=(value_fun_t in_fun) { type = FUNCTION; fun = in_fun; return *this; } + + value_fun_t AsFun() { + if (type==FUNCTION) return fun; else return [v=value](emp::DataMap &){ return v; }; + } + }; + + struct BinaryOperator { + using fun_t = std::function; + size_t prec; + fun_t fun; + void Set(size_t in_prec, fun_t in_fun) { prec = in_prec; fun = in_fun; } + }; + + struct Function { + using fun0_t = std::function; + using fun1_t = std::function; + using fun2_t = std::function; + using fun3_t = std::function; + + size_t num_args = 0; + fun0_t fun0; fun1_t fun1; fun2_t fun2; fun3_t fun3; + + void Set0(fun0_t in_fun) { num_args = 0; fun0 = in_fun; } + void Set1(fun1_t in_fun) { num_args = 1; fun1 = in_fun; } + void Set2(fun2_t in_fun) { num_args = 2; fun2 = in_fun; } + void Set3(fun3_t in_fun) { num_args = 3; fun3 = in_fun; } + }; + + // --------- MEMBER VARIABLES ----------- + SimpleLexer lexer; + std::unordered_map> unary_ops; + std::unordered_map binary_ops; + std::unordered_map functions; + size_t error_count = 0; + + using error_fun_t = std::function; + error_fun_t error_fun = + [](const std::string & msg){ std::cerr << "ERROR: " << msg << std::endl; }; + + template + ValueType AddError(Ts &&... args) { + error_fun( emp::to_string(args...); ); + ++error_count; + return ValueType(); + } + + public: + SimpleParser(bool use_defaults=true) { + if (use_defaults) { + AddDefaultOperators(); + AddDefaultFunctions(); + } + } + + bool HasErrors() const { return error_count; } + size_t NumErrors() const { return error_count; } + + error_fun_t GetErrorFun() const { return error_fun; } + void SetErrorFun(error_fun_t in_fun) { error_fun = in_fun; } + + // Add a unary operator + void AddOp(const std::string & op, std::function fun) { + unary_ops[op] = fun; + } + + void AddDefaultOperators() { + // Setup the unary operators for the parser. + AddOp("+", [](double x) { return x; }); + AddOp("-", [](double x) { return -x; }; + AddOp("!", [](double x) { return (double) (x==0.0); }; + + // Setup the default binary operators for the parser. + size_t prec = 0; // Precedence level of each operator... + binary_ops["||"].Set( ++prec, [](double x, double y){ return (x!=0.0)||(y!=0.0); } ); + binary_ops["&&"].Set( ++prec, [](double x, double y){ return (x!=0.0)&&(y!=0.0); } ); + binary_ops["=="].Set( ++prec, [](double x, double y){ return x == y; } ); + binary_ops["!="].Set( prec, [](double x, double y){ return x != y; } ); + binary_ops["<"] .Set( ++prec, [](double x, double y){ return x < y; } ); + binary_ops["<="].Set( prec, [](double x, double y){ return x <= y; } ); + binary_ops[">"] .Set( prec, [](double x, double y){ return x > y; } ); + binary_ops[">="].Set( prec, [](double x, double y){ return x >= y; } ); + binary_ops["+"] .Set( ++prec, [](double x, double y){ return x + y; } ); + binary_ops["-"] .Set( prec, [](double x, double y){ return x - y; } ); + binary_ops["*"] .Set( ++prec, [](double x, double y){ return x * y; } ); + binary_ops["/"] .Set( prec, [](double x, double y){ return x / y; } ); + binary_ops["%"] .Set( prec, [](double x, double y){ return emp::Mod(x, y); } ); + binary_ops["**"].Set( ++prec, [](double x, double y){ return emp::Pow(x, y); } ); + binary_ops["%%"].Set( prec, [](double x, double y){ return emp::Log(x, y); } ); + } + + void AddDefaultFunctions() { + // Setup the default functions. + functions["ABS"].Set1( [](double x){ return std::abs(x); } ); + functions["EXP"].Set1( [](double x){ return emp::Pow(emp::E, x); } ); + functions["LOG"].Set1( [](double x){ return std::log(x); } ); + functions["LOG2"].Set1( [](double x){ return std::log2(x); } ); + functions["LOG10"].Set1( [](double x){ return std::log10(x); } ); + + functions["SQRT"].Set1( [](double x){ return std::sqrt(x); } ); + functions["CBRT"].Set1( [](double x){ return std::cbrt(x); } ); + + functions["SIN"].Set1( [](double x){ return std::sin(x); } ); + functions["COS"].Set1( [](double x){ return std::cos(x); } ); + functions["TAN"].Set1( [](double x){ return std::tan(x); } ); + functions["ASIN"].Set1( [](double x){ return std::asin(x); } ); + functions["ACOS"].Set1( [](double x){ return std::acos(x); } ); + functions["ATAN"].Set1( [](double x){ return std::atan(x); } ); + functions["SINH"].Set1( [](double x){ return std::sinh(x); } ); + functions["COSH"].Set1( [](double x){ return std::cosh(x); } ); + functions["TANH"].Set1( [](double x){ return std::tanh(x); } ); + functions["ASINH"].Set1( [](double x){ return std::asinh(x); } ); + functions["ACOSH"].Set1( [](double x){ return std::acosh(x); } ); + functions["ATANH"].Set1( [](double x){ return std::atanh(x); } ); + + functions["CEIL"].Set1( [](double x){ return std::ceil(x); } ); + functions["FLOOR"].Set1( [](double x){ return std::floor(x); } ); + functions["ROUND"].Set1( [](double x){ return std::round(x); } ); + + functions["ISINF"].Set1( [](double x){ return std::isinf(x); } ); + functions["ISNAN"].Set1( [](double x){ return std::isnan(x); } ); + + // Default 2-input functions + functions["HYPOT"].Set2( [](double x, double y){ return std::hypot(x,y); } ); + functions["EXP"].Set2( [](double x, double y){ return emp::Pow(x,y); } ); + functions["LOG"].Set2( [](double x, double y){ return emp::Log(x,y); } ); + functions["MIN"].Set2( [](double x, double y){ return (xy) ? x : y; } ); + functions["POW"].Set2( [](double x, double y){ return emp::Pow(x,y); } ); + + // Default 3-input functions. + functions["IF"].Set3( [](double x, double y, double z){ return (x!=0.0) ? y : z; } ); + functions["CLAMP"].Set3( [](double x, double y, double z){ return (xz) ? z : x; } ); + functions["TO_SCALE"].Set3( [](double x, double y, double z){ return (z-y)*x+y; } ); + functions["FROM_SCALE"].Set3( [](double x, double y, double z){ return (x-y) / (z-y); } ); + } + + /// Helpers for parsing. + ValueType ParseValue(const DataMap & dm, pos_t & pos) { + if constexpr (verbose) { + std::cout << "ParseValue at position " << pos.GetIndex() << " : " << pos->lexeme << std::endl; + } + + // Deal with any unary operators... + if (emp::Has(unary_ops, pos->lexeme)) { + if constexpr (verbose) std::cout << "Found UNARY OP: " << pos->lexeme << std::endl; + auto op = unary_ops[pos->lexeme]; + ++pos; + ValueType val = ParseValue(dm, pos); + if (val.type == ValueType::VALUE) { return op(val.value); } + else { return (value_fun_t) [fun=val.fun,op](emp::DataMap & dm){ return op(fun(dm)); }; } + } + + // If we have parentheses, process the contents + if (pos->lexeme == "(") { + if constexpr (verbose) std::cout << "Found: OPEN PAREN" << std::endl; + ++pos; + ValueType val = ParseMath(dm, pos); + if (pos->lexeme != ")") return AddError("Expected ')', but found '", pos->lexeme, "'."); + ++pos; + return val; + } + + // If this is a value, set it and return. + if (lexer.IsNumber(*pos)) { + double result = emp::from_string(pos->lexeme); + ++pos; + return result; + } + + // Otherwise it should be and identifier! + const std::string & name = pos->lexeme; + ++pos; + + // If it is followed by a parenthesis, it should be a function. + const bool is_fun = (pos.IsValid() && pos->lexeme == "("); + + if (is_fun) { + if (!emp::Has(functions, name)) return AddError("Call to unknown function '", name,"'."); + ++pos; + emp::vector args; + while(pos->lexeme != ")") { + args.push_back(ParseMath(dm, pos)); + if (pos->lexeme == ",") ++pos; + } + ++pos; + + // Now build the function based on its argument count. + value_fun_t out_fun; + switch (args.size()) { + case 0: + if (!functions[name].fun0) AddError("Function '", name, "' requires arguments."); + out_fun = [fun=functions[name].fun0](emp::DataMap & dm) { return fun(); }; + break; + case 1: + if (!functions[name].fun1) AddError("Function '", name, "' cannot have 1 arguments."); + out_fun = [fun=functions[name].fun1,arg0=args[0].AsFun()](emp::DataMap & dm) { + return fun(arg0(dm)); + }; + break; + case 2: + if (!functions[name].fun2) AddError("Function '", name, "' cannot have 2 arguments."); + out_fun = [fun=functions[name].fun2,arg0=args[0].AsFun(),arg1=args[1].AsFun()](emp::DataMap & dm) { + return fun(arg0(dm), arg1(dm)); + }; + break; + case 3: + if (!functions[name].fun3) AddError("Function '", name, "' cannot have 3 arguments."); + out_fun = [fun=functions[name].fun3,arg0=args[0].AsFun(),arg1=args[1].AsFun(),arg2=args[2].AsFun()](emp::DataMap & dm) { + return fun(arg0(dm), arg1(dm), arg2(dm)); + }; + break; + default: + AddError("Too many arguments for function '", name, "'."); + } + return out_fun; + } + + // This must be a DataMap entry name. + if (!dm.HasName(name)) AddError("Unknown data map entry '", name, "'."); + size_t id = dm.GetID(name); + return (value_fun_t) [id](emp::DataMap & dm){ return dm.GetAsDouble(id); }; + } + + ValueType ParseMath(const DataMap & dm, pos_t & pos, size_t prec_limit=0) { + ValueType val1 = ParseValue(dm, pos); + + if constexpr (verbose) { + if (pos.IsValid()) { + std::cout << "ParseMath at " << pos.GetIndex() << " : " << pos->lexeme << std::endl; + } else std::cout << "PROCESSED!" << std::endl; + } + + while (pos.IsValid() && pos->lexeme != ")" && pos->lexeme != ",") { + if constexpr (verbose) { std::cout << "...Scanning for op... [" << pos->lexeme << "]" << std::endl; } + + // If we have an operator, act on it! + if (Has(binary_ops, pos->lexeme)) { + const BinaryOperator & op = binary_ops[pos->lexeme]; + if (prec_limit >= op.prec) return val1; // Precedence not allowed; return currnet value. + ++pos; + ValueType val2 = ParseMath(dm, pos, op.prec); + if (val1.type == ValueType::VALUE) { + if (val2.type == ValueType::VALUE) { val1 = op.fun(val1.value, val2.value); } + else { + val1 = (value_fun_t) [val1_num=val1.value,val2_fun=val2.fun,op_fun=op.fun](emp::DataMap & dm){ + return op_fun(val1_num, val2_fun(dm)); + }; + } + } else { + if (val2.type == ValueType::VALUE) { + val1 = (value_fun_t) [val1_fun=val1.fun,val2_num=val2.value,op_fun=op.fun](emp::DataMap & dm){ + return op_fun(val1_fun(dm), val2_num); + }; + } else { + val1 = (value_fun_t) [val1_fun=val1.fun,val2_fun=val2.fun,op_fun=op.fun](emp::DataMap & dm){ + return op_fun(val1_fun(dm), val2_fun(dm)); + }; + } + } + } + + else AddError("Operator '", pos->lexeme, "' NOT found!"); + } + + // @CAO Make sure there's not a illegal lexeme here. + + return val1; + } + + /// Parse a function description that will take a DataMap and return the results. + /// For example, if the string "foo * 2 + bar" is passed in, a function will be returned + /// that takes a datamap (of the example type) loads in the values of "foo" and "bar", and + /// returns the result of the above equation. + + value_fun_t BuildMathFunction(const DataMap & dm, const std::string & expression) { + emp::TokenStream tokens = lexer.Tokenize(expression); + if constexpr (verbose) tokens.Print(); + pos_t pos = tokens.begin(); + ValueType val = ParseMath(dm, pos); + + // If this value is fixed, turn it into a function. + if (val.type == ValueType::VALUE) { + return [out=val.value](emp::DataMap &){ return out; }; + } + + // Otherwise return the function produced. + #ifdef NDEBUG + return val.fun; + #else + // If we are in debug mode, save the original datamap and double-check compatability. + return [fun=val.fun,&orig_layout=dm.GetLayout()](emp::DataMap & dm){ + emp_assert(dm.HasLayout(orig_layout)); + return fun(dm); + }; + #endif + } + + }; +} + +#endif // #ifndef EMP_IN_PROGRESS_SIMPLEPARSER_HPP_INCLUDE diff --git a/include/emp/in_progress/TrackedPtr.hpp b/include/emp/in_progress/TrackedPtr.hpp new file mode 100644 index 0000000000..bd167e2a6e --- /dev/null +++ b/include/emp/in_progress/TrackedPtr.hpp @@ -0,0 +1,57 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ +/** + * @file + * @brief Similar to Ptr, but memory is tracked and managed elsewhere, such as smart pointers. + * @note Status: ALPHA + * + */ + +#ifndef EMP_IN_PROGRESS_TRACKEDPTR_HPP_INCLUDE +#define EMP_IN_PROGRESS_TRACKEDPTR_HPP_INCLUDE + +#include "Ptr.hpp" + +namespace emp { + + class PtrManager { + public: + virtual void IncCount() = 0; + }; + + template + class TrackedPtr : public Ptr { + private: + using BasePtr::ptr; + + public: + using element_type = TYPE; + + /// Default constructor + TrackedPtr() : Ptr(nullptr) {} + + /// Copy constructor + TrackedPtr(const TrackedPtr & _in) : Ptr(_in) {} + + /// Construct from raw ptr + template Ptr(T2 * in_ptr, bool=false) : BasePtr(in_ptr) {} + + /// Construct from array + template Ptr(T2 * _ptr, size_t, bool) : BasePtr(_ptr) {} + + /// From compatible Ptr + template Ptr(Ptr _in) : BasePtr(_in.Raw()) {} + + /// From nullptr + Ptr(std::nullptr_t) : Ptr() {} + + /// Destructor + ~Ptr() { ; } + + +} + +#endif // #ifndef EMP_IN_PROGRESS_TRACKEDPTR_HPP_INCLUDE diff --git a/include/emp/in_progress/Trait.hpp b/include/emp/in_progress/Trait.hpp index 67ae5a61e9..c7b15c2f97 100644 --- a/include/emp/in_progress/Trait.hpp +++ b/include/emp/in_progress/Trait.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file Trait.hpp + * @file * @brief The TraitDef class maintains a category of measuments about another class. * * Each trait is associated with a name, a description, and a type. Instance of that diff --git a/include/emp/in_progress/class.hpp b/include/emp/in_progress/class.hpp index 4bf693c54b..8330d90d8a 100644 --- a/include/emp/in_progress/class.hpp +++ b/include/emp/in_progress/class.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file class.hpp + * @file * @brief A re-engineering of tuple_struct.h, intended to be usable throughout Empirical. * * The EMP_CLASS macro builds an inexpensive class that diff --git a/include/emp/in_progress/constexpr/ce_array.hpp b/include/emp/in_progress/constexpr/ce_array.hpp index 74d50281dd..bf7e88003e 100644 --- a/include/emp/in_progress/constexpr/ce_array.hpp +++ b/include/emp/in_progress/constexpr/ce_array.hpp @@ -1,18 +1,20 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file ce_array.hpp + * @file * @brief ce_array defines a limited array object for use within a constexpr class or function. * - * STATUS: ALPHA + * @note STATUS: ALPHA * */ #ifndef EMP_IN_PROGRESS_CONSTEXPR_CE_ARRAY_HPP_INCLUDE #define EMP_IN_PROGRESS_CONSTEXPR_CE_ARRAY_HPP_INCLUDE +#include #include #include "../base/assert.hpp" diff --git a/include/emp/in_progress/constexpr/ce_random.hpp b/include/emp/in_progress/constexpr/ce_random.hpp index 8cb0e9a673..ae5b95c93e 100644 --- a/include/emp/in_progress/constexpr/ce_random.hpp +++ b/include/emp/in_progress/constexpr/ce_random.hpp @@ -1,12 +1,13 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file ce_random.hpp + * @file * @brief A versatile and non-patterned pseudo-random-number generator. * - * Status: DESIGN + * @note Status: DESIGN * * Constructor: * Random(int _seed=-1) @@ -43,8 +44,10 @@ // #include #include #include +#include #include #include +#include #include #include "../math/math.hpp" diff --git a/include/emp/in_progress/constexpr/ce_string.hpp b/include/emp/in_progress/constexpr/ce_string.hpp index 87ff2d7e5d..3583f98d28 100644 --- a/include/emp/in_progress/constexpr/ce_string.hpp +++ b/include/emp/in_progress/constexpr/ce_string.hpp @@ -1,17 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file ce_string.hpp + * @file * @brief ce_string defines a limited string object for use within a constexpr class or function. * - * Status: DESIGN. + * @note Status: DESIGN. */ #ifndef EMP_IN_PROGRESS_CONSTEXPR_CE_STRING_HPP_INCLUDE #define EMP_IN_PROGRESS_CONSTEXPR_CE_STRING_HPP_INCLUDE +#include #include #include diff --git a/include/emp/in_progress/fixed.hpp b/include/emp/in_progress/fixed.hpp index 797c5b1108..0669123d12 100644 --- a/include/emp/in_progress/fixed.hpp +++ b/include/emp/in_progress/fixed.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file fixed.hpp + * @file * @brief A comprehensive (ideally) fixed-point number representation. * * Type-name: emp::fixed diff --git a/include/emp/in_progress/struct.hpp b/include/emp/in_progress/struct.hpp index 89d6b7a2be..d9281cb409 100644 --- a/include/emp/in_progress/struct.hpp +++ b/include/emp/in_progress/struct.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file struct.hpp + * @file * @brief A re-engineering of tuple_struct.h, intended to be usable throughout Empirical. * * The EMP_STRUCT macro builds an inexpensive struct that diff --git a/include/emp/io/ContiguousStream.hpp b/include/emp/io/ContiguousStream.hpp index 224bd45758..ab14fd42b0 100644 --- a/include/emp/io/ContiguousStream.hpp +++ b/include/emp/io/ContiguousStream.hpp @@ -1,17 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file ContiguousStream.hpp + * @file * @brief Useful for streaming data to contiguous memory. - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_IO_CONTIGUOUSSTREAM_HPP_INCLUDE #define EMP_IO_CONTIGUOUSSTREAM_HPP_INCLUDE #include +#include #include "../base/vector.hpp" diff --git a/include/emp/io/File.hpp b/include/emp/io/File.hpp index f7ac262634..70345f4106 100644 --- a/include/emp/io/File.hpp +++ b/include/emp/io/File.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2023. - * - * @file File.hpp + * @file * @brief The File object maintains a simple, in-memory file. * @note Status: BETA * @@ -19,10 +20,12 @@ #include #include #include +#include #include #include "../base/vector.hpp" #include "../meta/FunInfo.hpp" +#include "../tools/String.hpp" #include "../tools/string_utils.hpp" namespace emp { @@ -30,13 +33,13 @@ namespace emp { /// A class to maintain files for loading, writing, storing, and easy access to components. class File { protected: - emp::vector lines; - std::string file_error = ""; + emp::vector lines; + String file_error = ""; public: File() : lines() { ; } File(std::istream & input) : lines() { Load(input); } - File(const std::string & filename) : lines() { Load(filename); } + File(const String & filename) : lines() { Load(filename); } File(const File &) = default; File(File &&) = default; ~File() { ; } @@ -63,40 +66,41 @@ namespace emp { size_t size() const { return lines.size(); } /// Return entire text of the file - emp::vector GetAllLines() {return lines;} + emp::vector GetAllLines() {return lines;} /// Index into a specific line in this file. - std::string & operator[](size_t pos) { return lines[pos]; } + String & operator[](size_t pos) { return lines[pos]; } /// Const index into a specific line in this file. - const std::string & operator[](size_t pos) const { return lines[pos]; } + const String & operator[](size_t pos) const { return lines[pos]; } /// Return the first line in the file. - std::string & front() { return lines.front(); } + String & front() { return lines.front(); } /// Return a const reference to to the first line in the file. - const std::string & front() const { return lines.front(); } + const String & front() const { return lines.front(); } /// Return the last line in the file. - std::string & back() { return lines.back(); } + String & back() { return lines.back(); } /// Return a const reference to the last line in the file. - const std::string & back() const { return lines.back(); } + const String & back() const { return lines.back(); } // Was there an error working with this file? bool HasError() const { return file_error.size(); } // Text of error. - const std::string & GetError() const { return file_error; } + const String & GetError() const { return file_error; } // Remove any errors. void ClearError() { file_error.resize(0); } /// Append a new line to the end of the file. - File & Append(const std::string & line) { lines.emplace_back(line); return *this; } + File & Append(const String & line) { lines.emplace_back(line); return *this; } /// Append a vector of lines to the end of the file. - File & Append(const emp::vector & in_lines) { + template + File & Append(const emp::vector & in_lines) { size_t start_size = lines.size(); lines.resize(start_size + in_lines.size()); for (size_t pos = 0; pos < in_lines.size(); pos++) { @@ -121,8 +125,10 @@ namespace emp { /// Extract first line from file auto operator>>(std::string & out) { - out = size() ? front() : out; - lines.erase(begin()); + if (size()) { + out = front(); + lines.erase(begin()); + } } /// Test if two files are identical. @@ -153,27 +159,27 @@ namespace emp { /// Load a file from disk using the provided name. /// If file does not exist, this is a nop - File & Load(const std::string & filename) { + File & Load(const String & filename) { std::ifstream file(filename); if (file.is_open()) { Load(file); file.close(); } else { - file_error = emp::to_string("File '", filename, "' failed to open."); + file_error.Set("File '", filename, "' failed to open."); } return *this; } /// Write this file to a provided output stream. File & Write(std::ostream & output) { - for (std::string & cur_line : lines) { + for (String & cur_line : lines) { output << cur_line << '\n'; } return *this; } /// Write this file to a file of the provided name. - File & Write(const std::string & filename) { + File & Write(const String & filename) { std::ofstream file(filename); Write(file); file.close(); @@ -181,16 +187,16 @@ namespace emp { } /// Test if a substring exists on ANY line of a file. - bool Contains(const std::string & pattern) const { - for (const std::string & line : lines) { - if (line.find(pattern) != std::string::npos) return true; + bool Contains(const String & pattern) const { + for (const String & line : lines) { + if (line.find(pattern) != String::npos) return true; } return false; } /// Convert this file into an std::set of lines (loses line ordering). - std::set AsSet() const { - std::set line_set; + std::set AsSet() const { + std::set line_set; for (size_t i = 0; i < lines.size(); i++) { line_set.insert(lines[i]); } @@ -200,11 +206,11 @@ namespace emp { /// Apply a string manipulation function to all lines in the file. template File & Apply(FUN_T fun) { - for (std::string & cur_line : lines) { + for (String & cur_line : lines) { // If the function returns a string, assume that's what we're supposed to use. // Otherwise assume that the string gets modified. using return_t = typename FunInfo::return_t; - if constexpr ( std::is_same() ) { + if constexpr ( std::is_same() ) { cur_line = fun(cur_line); } else { fun(cur_line); @@ -214,9 +220,9 @@ namespace emp { } /// Purge all lines that don't the criterion function. - File & KeepIf(const std::function & fun) { - emp::vector new_lines; - for (std::string & cur_line : lines) { + File & KeepIf(const std::function & fun) { + emp::vector new_lines; + for (String & cur_line : lines) { if (fun(cur_line)) new_lines.emplace_back(cur_line); } std::swap(lines, new_lines); @@ -224,39 +230,53 @@ namespace emp { } /// Keep only strings that contain a specific substring. - File & KeepIfContains(const std::string & pattern) { + File & KeepIfContains(const String & pattern) { return KeepIf( - [&pattern](const std::string & line){ return line.find(pattern) != std::string::npos; } + [&pattern](const String & line){ return line.find(pattern) != String::npos; } ); } /// Remove all strings that contain a specific substring. - File & RemoveIfContains(const std::string & pattern) { + File & RemoveIfContains(const String & pattern) { + return KeepIf( + [&pattern](const String & line){ return line.find(pattern) == String::npos; } + ); + } + + /// Keep only strings that contain a specific substring. + File & KeepIfBegins(const String & prefix) { return KeepIf( - [&pattern](const std::string & line){ return line.find(pattern) == std::string::npos; } + [&prefix](const String & line){ return line.find(prefix) == 0; } + ); + } + + /// Remove all strings that contain a specific substring. + File & RemoveIfBegins(const String & prefix) { + return KeepIf( + [&prefix](const String & line){ return line.Find(prefix) != 0; } ); } /// Remove all lines that are empty strings. File & RemoveEmpty() { - return KeepIf( [](const std::string & str){ return (bool) str.size(); } ); + return KeepIf( [](const String & str){ return (bool) str.size(); } ); } /// Any time multiple whitespaces are next to each other, collapse to a single WS char. /// Prefer '\n' if in whitespace collapsed, otherwise use ' '. File & CompressWhitespace() { - Apply(compress_whitespace); + Apply([](String & in){ in.Compress(); }); RemoveEmpty(); return *this; } /// Delete all whitespace; by default keep newlines. File & RemoveWhitespace(bool keep_newlines=true) { - Apply(remove_whitespace); + Apply([](String & in){ in.RemoveWhitespace(); }); RemoveEmpty(); if (!keep_newlines) { - std::string all_lines; - for (const std::string & cur_line : lines){ + String all_lines; + for (const String & cur_line : lines){ all_lines += cur_line; } lines.resize(1); @@ -266,23 +286,23 @@ namespace emp { } /// A technique to remove all comments in a file. - File & RemoveComments(const std::string & marker, bool skip_quotes=true) { - Apply( [marker,skip_quotes](std::string & str) { - size_t pos = emp::find(str, marker, 0, skip_quotes); - if (pos !=std::string::npos) str.resize( pos ); + File & RemoveComments(const String & marker, bool skip_quotes=true) { + Apply( [marker,skip_quotes](String & str) { + size_t pos = str.Find(marker, 0, skip_quotes); + if (pos !=String::npos) str.resize( pos ); } ); return *this; } /// Allow remove comments to also be specified with a single character. File & RemoveComments(char marker, bool skip_quotes=true) { - return RemoveComments(emp::to_string(marker), skip_quotes); + return RemoveComments(emp::MakeString(marker), skip_quotes); } - /// Run a function on each line of a file and return the restults as a vector. + /// Run a function on each line of a file and return the results as a vector. /// Note: Function is allowed to modify string. template - emp::vector Process(const std::function & fun) { + emp::vector Process(const std::function & fun) { emp::vector results(lines.size()); for (size_t i = 0; i < lines.size(); i++) { results[i] = fun(lines[i]); @@ -291,62 +311,64 @@ namespace emp { } /// Get a series of lines. - emp::vector Read(size_t start, size_t end) const { + emp::vector Read(size_t start, size_t end) const { if (end > lines.size()) end = lines.size(); - return emp::vector(lines.begin()+start, lines.begin()+end); + auto start_it = lines.begin()+static_cast(start); + auto end_it = lines.begin()+static_cast(end); + return emp::vector(start_it, end_it); } /// Get a series of lines until a line meets a certain condition. - emp::vector ReadUntil(size_t start, auto test_fun) const { + emp::vector ReadUntil(size_t start, auto test_fun) const { size_t end = start; while (end < lines.size() && !test_fun(lines[end])) ++end; return Read(start, end); } /// Get a series of lines while lines continue to meet a certain condition. - emp::vector ReadWhile(size_t start, auto test_fun) const { + emp::vector ReadWhile(size_t start, auto test_fun) const { size_t end = start; while (end < lines.size() && test_fun(lines)) ++end; return Read(start, end); } /// Remove the first column from the file, returning it as a vector of strings. - emp::vector ExtractCol(char delim=',') { - return Process( [delim](std::string & line){ - return string_pop(line, delim); + emp::vector ExtractCol(char delim=',') { + return Process( [delim](String & line){ + return line.Pop(delim); }); } /// Remove the first column from the file, returning it as a vector of a specified type. template emp::vector ExtractColAs(char delim=',') { - return Process( [delim](std::string & line){ - return emp::from_string(string_pop(line, delim)); + return Process( [delim](String & line){ + return line.Pop(delim).As(); }); } /// Convert a row of a file to a vector of string views. - emp::vector ViewRowSlices(size_t row_id, char delim=',') { - return view_slices(lines[row_id], delim); + emp::vector ViewRowSlices(size_t row_id, String delim=",") { + return lines[row_id].ViewSlices(delim); } /// Remove the first row from the file, returning it as a vector of strings. - emp::vector ExtractRow(char delim=',') { + emp::vector ExtractRow(String delim=",") { // Identify the data as string_views emp::vector sv_row = ViewRowSlices(0, delim); // Build the array to return and copy strings into it. - emp::vector out_row(sv_row.size()); + emp::vector out_row(sv_row.size()); for (size_t i=0; i < sv_row.size(); i++) out_row[i] = sv_row[i]; - // Remove the row to be extrated and return the result. + // Remove the row to be extracted and return the result. lines.erase(begin()); return out_row; } /// Remove the first row from the file, returning it as a vector of a specified type. template - emp::vector ExtractRowAs(char delim=',') { + emp::vector ExtractRowAs(String delim=",") { // Identify the data as string_views emp::vector sv_row = ViewRowSlices(0, delim); @@ -354,18 +376,25 @@ namespace emp { emp::vector out_row(sv_row.size()); for (size_t i=0; i < sv_row.size(); i++) out_row[i] = from_string(sv_row[i]); - // Remove the row to be extrated and return the result. + // Remove the row to be extracted and return the result. lines.erase(begin()); return out_row; } + emp::vector< emp::vector > ToCSV(String delim=",") const { + emp::vector< emp::vector > out_csv(lines.size()); + for (size_t row_id = 0; row_id < lines.size(); row_id++) { + out_csv[row_id] = lines[row_id].Slice(delim); + } + return out_csv; + } + template - emp::vector< emp::vector > ToData(char delim=',') { + emp::vector< emp::vector > ToData(String delim=",") const { emp::vector< emp::vector > out_data(lines.size()); - emp::vector sv_row; for (size_t row_id = 0; row_id < lines.size(); row_id++) { - view_slices(lines[row_id], sv_row, delim); + auto sv_row = lines[row_id].ViewSlices(delim); out_data[row_id].resize(sv_row.size()); for (size_t i=0; i < sv_row.size(); i++) { out_data[row_id][i] = from_string(sv_row[i]); @@ -375,6 +404,7 @@ namespace emp { return out_data; } + // A File::Scan object allows a user to easily step through a File. class Scan { private: @@ -397,13 +427,13 @@ namespace emp { void SetEnd() { line = file.size(); } // Get the very next line. - const std::string & Read() { - if (line > file.size()) return emp::empty_string(); + const String & Read() { + if (line > file.size()) return String::Empty(); return file[line++]; } // Get a block of lines. - emp::vector ReadTo(size_t end) { + emp::vector ReadTo(size_t end) { emp_assert(end >= line); if (end > file.size()) end = file.size(); size_t start = line; @@ -412,14 +442,14 @@ namespace emp { } // Get a block of lines, ending when a condition is met. - emp::vector ReadUntil(auto test_fun) { + emp::vector ReadUntil(auto test_fun) { auto out = file.ReadUntil(line, test_fun); line += out.size(); return out; } // Get a block of lines for as lone as a condition is met. - emp::vector ReadWhile(auto test_fun) { + emp::vector ReadWhile(auto test_fun) { auto out = file.ReadWhile(line, test_fun); line += out.size(); return out; diff --git a/include/emp/io/MemoryIStream.hpp b/include/emp/io/MemoryIStream.hpp index 040b0d3c84..912023a5b5 100644 --- a/include/emp/io/MemoryIStream.hpp +++ b/include/emp/io/MemoryIStream.hpp @@ -1,17 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file MemoryIStream.hpp + * @file * @brief Useful for streaming data from contiguous memory. - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_IO_MEMORYISTREAM_HPP_INCLUDE #define EMP_IO_MEMORYISTREAM_HPP_INCLUDE #include +#include #include namespace emp { diff --git a/include/emp/io/NullStream.hpp b/include/emp/io/NullStream.hpp index 43f3d869e1..88762e0022 100644 --- a/include/emp/io/NullStream.hpp +++ b/include/emp/io/NullStream.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file NullStream.hpp + * @file * @brief A handy no-operation output stream. * @note Status: BETA */ diff --git a/include/emp/io/StreamManager.hpp b/include/emp/io/StreamManager.hpp index b4fdac2400..b7b98af5be 100644 --- a/include/emp/io/StreamManager.hpp +++ b/include/emp/io/StreamManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2021. - * - * @file StreamManager.hpp + * @file * @brief The StreamManager object links names to files or other streams. * @note Status: BETA * diff --git a/include/emp/io/ascii_utils.hpp b/include/emp/io/ascii_utils.hpp index 5e14132887..4fdad4e340 100644 --- a/include/emp/io/ascii_utils.hpp +++ b/include/emp/io/ascii_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file ascii_utils.hpp + * @file * @brief Tools for working with ascii output. * @note Status: ALPHA * @@ -14,6 +15,7 @@ #include #include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" @@ -23,7 +25,7 @@ namespace emp { /// The following function prints an ascii bar graph on to the screen (or provided stream). template - void AsciiBarGraph( emp::vector data, + void AsciiBarGraph( emp::vector data, ///< Data to graph size_t max_width=80, ///< What's the widest bars allowed? bool show_scale=true, ///< Should we show the scale at bottom. bool max_scale_1=true, ///< Should we limit scaling to 1:1? @@ -47,7 +49,7 @@ namespace emp { /// Take the input data, break it into bins, and print it as a bar graph. template - void AsciiHistogram(emp::vector data, + void AsciiHistogram(emp::vector data, ///< Data to graph size_t num_bins=40, ///< How many bins in histogram? size_t max_width=80, ///< What's the widest bars allowed? bool show_scale=true, ///< Should we show the scale at bottom? diff --git a/include/emp/io/serialize.hpp b/include/emp/io/serialize.hpp index a6b27e339a..f14be1641a 100644 --- a/include/emp/io/serialize.hpp +++ b/include/emp/io/serialize.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2021. - * - * @file serialize.hpp + * @file * @brief Tools to save and load data from classes. * @note Status: ALPHA * @@ -52,6 +53,7 @@ #ifndef EMP_IO_SERIALIZE_HPP_INCLUDE #define EMP_IO_SERIALIZE_HPP_INCLUDE +#include #include #include "../base/Ptr.hpp" diff --git a/include/emp/io/serialize_macros.hpp b/include/emp/io/serialize_macros.hpp index 1574c81289..5cc893f96b 100644 --- a/include/emp/io/serialize_macros.hpp +++ b/include/emp/io/serialize_macros.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2021. - * - * @file serialize_macros.hpp + * @file * @brief Macros for simplifying to serialization of objects. * @note Status: ALPHA */ diff --git a/include/emp/matching/MatchBin.hpp b/include/emp/matching/MatchBin.hpp index 22cb215fce..2acb717f7a 100644 --- a/include/emp/matching/MatchBin.hpp +++ b/include/emp/matching/MatchBin.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file MatchBin.hpp + * @file * @brief A container that supports flexible tag-based lookup. . * */ @@ -26,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +63,7 @@ namespace emp::internal { using query_t = Query; using tag_t = Tag; + #ifndef DOXYGEN_SHOULD_SKIP_THIS template < typename Val, typename Metric, @@ -68,7 +71,7 @@ namespace emp::internal { typename Regulator > friend class emp::MatchBin; - + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ struct LogEntry { query_t query; diff --git a/include/emp/matching/MatchDepository.hpp b/include/emp/matching/MatchDepository.hpp index 67550bae6a..816fb02a19 100644 --- a/include/emp/matching/MatchDepository.hpp +++ b/include/emp/matching/MatchDepository.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file MatchDepository.hpp + * @file * @brief A container for tag-based lookup, optimized for situations where * tags are not removed from the lookup set. * @@ -14,6 +15,7 @@ #include #include +#include #include "../datastructs/SmallFifoMap.hpp" #include "../datastructs/SmallVector.hpp" diff --git a/include/emp/matching/_DepositoryEntry.hpp b/include/emp/matching/_DepositoryEntry.hpp index df19fd3fc6..b8f5c704fa 100644 --- a/include/emp/matching/_DepositoryEntry.hpp +++ b/include/emp/matching/_DepositoryEntry.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file _DepositoryEntry.hpp + * @file * @brief Helper struct for MatchDepository. * */ diff --git a/include/emp/matching/matchbin_metrics.hpp b/include/emp/matching/matchbin_metrics.hpp index 3126f631cf..70cfde0aeb 100644 --- a/include/emp/matching/matchbin_metrics.hpp +++ b/include/emp/matching/matchbin_metrics.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2022. - * - * @file matchbin_metrics.hpp + * @file * @brief Metric structs that can be plugged into MatchBin. * */ @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -254,7 +256,7 @@ namespace emp { } inline static double calculate(const query_t& a, const tag_t& b) { - return (b - a).GetValue() / emp::BitSet::GetNumStates(); + return (b - a).GetValue() / emp::Pow2(Width); } }; @@ -281,7 +283,7 @@ namespace emp { } inline static double calculate(const query_t& a, const tag_t& b) { - constexpr double max_dist = emp::BitSet::GetNumStates(); + constexpr double max_dist = emp::Pow2(Width); return (b >= a ? (b - a).GetValue() : max_dist) / max_dist; } @@ -312,7 +314,7 @@ namespace emp { } inline static double calculate(const query_t& a, const tag_t& b) { - constexpr double max_dist = emp::BitSet::GetNumStates() / 2.0; + constexpr double max_dist = emp::Pow2(Width) / 2.0; return std::min(a - b, b - a).GetValue() / max_dist; } @@ -342,7 +344,7 @@ namespace emp { } inline static double calculate(const query_t& a, const tag_t& b) { - return (a > b ? a - b : b - a).GetValue() / emp::BitSet::GetNumStates(); + return (a > b ? a - b : b - a).GetValue() / emp::Pow2(Width); } }; @@ -714,7 +716,7 @@ namespace emp { for (size_t i = 0; i < metric_width; ++ i) { best = std::min(Metric::calculate(dup, b), best); - dup.template ROTL_SELF<1>(); + dup.ROTATE_SELF(-1); } return best; @@ -1176,22 +1178,22 @@ namespace emp { : public BaseMetric< emp::BitSet< std::tuple_size::value - * DimMetric::query_t::value_type::GetSize() + * DimMetric::query_t::value_type::GetCTSize() >, emp::BitSet< std::tuple_size::value - * DimMetric::tag_t::value_type::GetSize() + * DimMetric::tag_t::value_type::GetCTSize() > > { using query_t = emp::BitSet< std::tuple_size::value - * DimMetric::query_t::value_type::GetSize() + * DimMetric::query_t::value_type::GetCTSize() >; using tag_t = emp::BitSet< std::tuple_size::value - * DimMetric::tag_t::value_type::GetSize() + * DimMetric::tag_t::value_type::GetCTSize() >; inline static DimMetric metric{}; @@ -1214,8 +1216,8 @@ namespace emp { typename DimMetric::tag_t arr_b; for (size_t d = 0; d < metric.dim(); ++d) { - arr_a[d].Import(a, d * DimMetric::query_t::value_type::GetSize()); - arr_b[d].Import(b, d * DimMetric::tag_t::value_type::GetSize()); + arr_a[d].Import(a, d * DimMetric::query_t::value_type::GetCTSize()); + arr_b[d].Import(b, d * DimMetric::tag_t::value_type::GetCTSize()); } return DimMetric::calculate(arr_a, arr_b); diff --git a/include/emp/matching/matchbin_regulators.hpp b/include/emp/matching/matchbin_regulators.hpp index d6a9bb7398..16937b6d10 100644 --- a/include/emp/matching/matchbin_regulators.hpp +++ b/include/emp/matching/matchbin_regulators.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2020. - * - * @file matchbin_regulators.hpp + * @file * @brief Regulator structs that can be plugged into MatchBin. * */ @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/include/emp/matching/matchbin_selectors.hpp b/include/emp/matching/matchbin_selectors.hpp index 1e7057e5c5..1010bbf3bb 100644 --- a/include/emp/matching/matchbin_selectors.hpp +++ b/include/emp/matching/matchbin_selectors.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019-2021. - * - * @file matchbin_selectors.hpp + * @file * @brief Selector structs that can be plugged into MatchBin. * */ @@ -19,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/include/emp/matching/matchbin_utils.hpp b/include/emp/matching/matchbin_utils.hpp index 893b971fcf..b1e8f03631 100644 --- a/include/emp/matching/matchbin_utils.hpp +++ b/include/emp/matching/matchbin_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file matchbin_utils.hpp + * @file * @brief Metric, Selector, and Regulator structs * that can be plugged into MatchBin. * diff --git a/include/emp/matching/regulators/PlusCountdownRegulator.hpp b/include/emp/matching/regulators/PlusCountdownRegulator.hpp index daf34375c7..4434cb6260 100644 --- a/include/emp/matching/regulators/PlusCountdownRegulator.hpp +++ b/include/emp/matching/regulators/PlusCountdownRegulator.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file PlusCountdownRegulator.hpp + * @file * @brief Regulator that modifies match distance through addition * and decays to baseline with a countdown timer. * diff --git a/include/emp/matching/selectors_static/RankedSelector.hpp b/include/emp/matching/selectors_static/RankedSelector.hpp index a3d339e45d..389cddec2d 100644 --- a/include/emp/matching/selectors_static/RankedSelector.hpp +++ b/include/emp/matching/selectors_static/RankedSelector.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file RankedSelector.hpp + * @file * @brief Selector that picks the N best matches within a threshold. * */ @@ -14,6 +15,7 @@ #include #include #include +#include #include "../../base/vector.hpp" #include "../../datastructs/SmallVector.hpp" diff --git a/include/emp/math/CombinedBinomialDistribution.hpp b/include/emp/math/CombinedBinomialDistribution.hpp index a8b5786d71..b1c19fe2fa 100644 --- a/include/emp/math/CombinedBinomialDistribution.hpp +++ b/include/emp/math/CombinedBinomialDistribution.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2022. - * - * @file CombinedBinomialDistribution.hpp + * @file * @brief A means of quickly generating binomial random variables while only storing a small number of distributions. * @note Status: ALPHA * diff --git a/include/emp/math/Distribution.hpp b/include/emp/math/Distribution.hpp index 0f82d90a47..73a8d935af 100644 --- a/include/emp/math/Distribution.hpp +++ b/include/emp/math/Distribution.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2020. - * - * @file Distribution.hpp + * @file * @brief A set of pre-calculated discrete distributions that can quickly generate random values. * @note Status: ALPHA * @@ -27,6 +28,8 @@ #ifndef EMP_MATH_DISTRIBUTION_HPP_INCLUDE #define EMP_MATH_DISTRIBUTION_HPP_INCLUDE +#include + #include "../datastructs/UnorderedIndexMap.hpp" #include "Random.hpp" diff --git a/include/emp/math/DistributionSet.hpp b/include/emp/math/DistributionSet.hpp index 5fdcb0c188..7065ad8b3a 100644 --- a/include/emp/math/DistributionSet.hpp +++ b/include/emp/math/DistributionSet.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file DistributionSet.hpp + * @file * @brief Management of pre-calculated distributions with different input values. * @note Status: ALPHA * diff --git a/include/emp/math/Fraction.hpp b/include/emp/math/Fraction.hpp index d53eabbeec..f427280cf4 100644 --- a/include/emp/math/Fraction.hpp +++ b/include/emp/math/Fraction.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file Fraction.hpp + * @file * @brief Tools to maintain a more exact fraction (rather than lose precision as a double) * @note Status: ALPHA */ @@ -11,7 +12,8 @@ #ifndef EMP_MATH_FRACTION_HPP_INCLUDE #define EMP_MATH_FRACTION_HPP_INCLUDE -#include "math.hpp" +#include +#include namespace emp { @@ -20,6 +22,7 @@ namespace emp { int64_t num; // Numerator int64_t denom; // Denominator + public: void Reduce() { if (denom == 0) return; // Undefined value! if (num == 0) { denom = 1; return; } // Zero value! @@ -29,16 +32,17 @@ namespace emp { denom = -denom; num = -num; } - const uint64_t gcd = emp::GCD(num, denom); + const int64_t gcd = std::gcd(num, denom); // overflows if uint64_t num /= gcd; denom /= gcd; } - public: - Fraction(int64_t in_num=0, int64_t in_denom=1) : num=in_num, denom=in_denom { } + + Fraction(int64_t in_num=0, int64_t in_denom=1) : num(in_num), denom(in_denom) { } Fraction(const Fraction &) = default; int64_t GetNumerator() const { return num; } - int64_t GetDenomonator() const { return denom; } + int64_t GetDenominator() const { return denom; } }; +} #endif // #ifndef EMP_MATH_FRACTION_HPP_INCLUDE diff --git a/include/emp/math/Random.hpp b/include/emp/math/Random.hpp index 8b915bba4e..ef82900e61 100644 --- a/include/emp/math/Random.hpp +++ b/include/emp/math/Random.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2021. - * - * @file Random.hpp + * @file * @brief A versatile and non-patterned pseudo-random-number generator. - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_MATH_RANDOM_HPP_INCLUDE @@ -13,9 +14,11 @@ #include #include +#include #include #include #include +#include #include "../base/assert.hpp" #include "../base/Ptr.hpp" @@ -24,7 +27,9 @@ #include "Range.hpp" namespace emp { + #ifndef DOXYGEN_SHOULD_SKIP_THIS using namespace emp; + #endif // DOXYGEN_SHOULD_SKIP_THIS /// Middle Square Weyl Sequence: A versatile and non-patterned pseudo-random-number /// generator. @@ -88,6 +93,10 @@ namespace emp { weyl_state *= 2; // Make sure starting state is even. + // Reset other internal state + value = 0; + expRV = 0.0; + Get(); // Prime the new sequence by skipping the first number. } diff --git a/include/emp/math/Range.hpp b/include/emp/math/Range.hpp index 225276fc25..07934bd93b 100644 --- a/include/emp/math/Range.hpp +++ b/include/emp/math/Range.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file Range.hpp + * @file * @brief A simple way to track value ranges * @note Status: BETA */ @@ -12,71 +13,215 @@ #define EMP_MATH_RANGE_HPP_INCLUDE #include +#include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" +#include "../tools/String.hpp" namespace emp { /// A range of values from a lower limit to and upper limit, of any provided type. - template + template class Range { private: T lower = std::numeric_limits::lowest(); ///< Beginning of range, inclusive. - T upper = std::numeric_limits::max(); ///< End of range, inclusive. + T upper = std::numeric_limits::max(); ///< End of range, (included if INCLUDE_UPPER) + using this_t = Range; public: + static constexpr bool is_integral = std::is_integral(); + Range() = default; - Range(T _l, T _u) : lower(_l), upper(_u) { emp_assert(_l < _u); } + Range(T val) : lower(val), upper(val) { + if constexpr (!INCLUDE_UPPER) upper += GetEpsilon(); + } + Range(T _l, T _u) : lower(_l), upper(_u) { emp_assert(_l <= _u, _l, _u); } Range(const Range &) = default; + Range & operator=(const Range&) = default; + bool operator==(const Range& _in) const = default; + bool operator!=(const Range& _in) const = default; + T GetLower() const { return lower; } T GetUpper() const { return upper; } - - size_t CalcBin(T value, size_t num_bins) const { - return (size_t) (((double) (value - lower)) / ((double) (upper - lower)) * (double) num_bins); + T GetEpsilon() const { + if constexpr (is_integral) return 1; + else return upper * std::numeric_limits::epsilon(); + } + T GetMaxValue() const { // What is the maximum included value? + if constexpr (INCLUDE_UPPER) return upper; + else return upper - GetEpsilon(); + } + T GetSize() const { return upper - lower + (INCLUDE_UPPER && is_integral); } + [[nodiscard]] static constexpr T MaxLimit() { return std::numeric_limits::max(); } + [[nodiscard]] static constexpr T MinLimit() { return std::numeric_limits::lowest(); } + + emp::String ToString() const { + if constexpr (INCLUDE_UPPER) { + return emp::MakeString('[', lower, ',', upper, ']'); + } else { + return emp::MakeString('[', lower, ',', upper, ')'); + } } - - Range & operator=(const Range&) = default; - bool operator==(const Range& _in) const { return lower==_in.lower && upper==_in.upper; } - bool operator!=(const Range& _in) const { return lower!=_in.lower || upper!=_in.upper; } void SetLower(T l) { lower = l; } void SetUpper(T u) { upper = u; } void Set(T _l, T _u) { emp_assert(_l < _u); lower = _l; upper = _u; } + void ShiftDown(T shift) { + emp_assert(shift > 0); + emp_assert(lower <= upper, lower, upper); + // Guard against underflow + upper = (MinLimit() + shift < upper) ? (upper - shift) : MinLimit(); + lower = (MinLimit() + shift < lower) ? (lower - shift) : MinLimit(); + } + void ShiftUp(T shift) { + emp_assert(shift > 0); + emp_assert(lower <= upper, lower, upper); + // Guard against overflow + upper = (MaxLimit() - shift > upper) ? (upper + shift) : MaxLimit(); + lower = (MaxLimit() - shift > lower) ? (lower + shift) : MaxLimit(); + } + void Shift(T shift) { + if (shift > 0) ShiftUp(shift); + else ShiftDown(-shift); + } - void SetMaxLower() { lower = std::numeric_limits::min(); } + void SetMinLower() { lower = std::numeric_limits::min(); } void SetMaxUpper() { upper = std::numeric_limits::max(); } - /// Determine if a provided value is in the range. - bool Valid(T value) const { return value >= lower && value <= upper; } + void Grow(T amount=1) { + if (amount > 0) upper += amount; + else lower += amount; + } + + // Flexible lower/upper accessor that can get and set. + T & Lower() { return lower; } + T & Upper() { return upper; } + + const T & Lower() const noexcept { return lower; } + const T & Upper() const noexcept { return upper; } + + /// Determine if a provided value is in the range INCLUSIVE of the endpoints. + bool Has(T value) const { + return (value >= lower && value < upper) || (INCLUDE_UPPER && value == upper); + } + [[deprecated("Renamed to Has()")]] + bool Valid(T value) const { return Has(value); } + + bool HasRange(this_t in_range) { + return Has(in_range.lower) && Has(in_range.upper); + } + + /// Will identify if two ranges are next to each other or overlapping. + bool IsConnected(this_t in) const { + return (in.lower >= lower && in.lower <= upper) || + (lower >= in.lower && lower <= in.upper); + } + + /// Determine if there is overlap between two range. + /// Similar to IsConnected, but cannot be merely adjacent. + bool HasOverlap(this_t in) const { + return (in.lower >= lower && in.lower < upper) || + (lower >= in.lower && lower < in.upper); + } + + /// Determine the amount of overlap between two range. + T CalcOverlap(this_t in) const { + const T combo_upper = std::min(upper, in.upper); + const T combo_lower = std::max(lower, in.lower); + return (combo_upper > combo_lower) ? (combo_upper - combo_lower) : T{}; + } + + /// @brief Expand this range to encompass a provided value. + /// @param val Value to expand through. + /// @return Whether the range has changed due to this expansion. + bool Expand(T val) { + if (val < lower) lower = val; + else if (val > upper) { + upper = val; + if constexpr (INCLUDE_UPPER) upper += GetEpsilon(); + } else return false; + return true; + } + + /// @brief Expand this range to encompass all provided values. + /// @return Whether the range has changed due to this expansion. + template + bool Expand(T val1, T val2, Ts... args) { + return Expand(val1) + Expand(val2, args...); // Use + to avoid short-circuiting. + } + + /// Merge this range with another. Must be adjacent or overlap (return false if not!) + bool Merge(this_t in) { + if (!IsConnected(in)) return false; + Expand(in.lower, in.upper); + return true; + } + + /// Add a specified value to the end of a range (or return false if failed). + bool Append(T val) { + emp_assert(is_integral, "Only integral ranges can call Append() with a single value."); + if (val != upper + INCLUDE_UPPER) return false; + upper++; + return true; + } /// Force a value into range - T Limit(T _in) const { return (_in < lower) ? lower : ((_in > upper) ? upper : _in); } + T Clamp(T _in) const { + return (_in < lower) ? lower : ((_in >= upper) ? GetMaxValue() : _in); + } + [[deprecated("Renamed to Clamp()")]] + T LimitValue(T _in) const { return Clamp(_in); } + + double ToFraction(T _in) const { + emp_assert(GetSize() != 0); + return static_cast(_in - lower) / static_cast(GetSize()); + } + T FromFraction(double frac) const { return frac * GetSize() + lower; } + + // Adjust the upper or lower if provided value is more limiting. + void LimitLower(T in) { if (in > lower) lower = in; } + void LimitUpper(T in) { if (in < upper) upper = in; } + + size_t CalcBin(T value, size_t num_bins) const { + if (upper == lower) return 0; + return (size_t) (((double) (value - lower)) / ((double) (upper - lower)) * (double) num_bins); + } /// Produce a vector that spreads values evenly across the range. - emp::vector Spread(size_t s) const { + emp::vector Spread(const size_t s) const { emp_assert(s >= 1); + if (s == 1) return emp::vector(1,lower/2+upper/2); // On point is in the middle of the range. emp::vector out(s); out[0] = lower; - if (s > 1) { - T range = upper - lower; - for (size_t i = 1; i < s; i++) { - out[i] = lower + (T) ((((double) i) / (double)(s-1)) * range); - } + T range = upper - lower; + for (size_t i = 1; i < s; i++) { + double frac = static_cast(i)/static_cast(s-1); + out[i] = lower + static_cast(frac * range); } return out; } }; /// Build a new range with auto-detected type. - template Range MakeRange(T _l, T _u) { return Range(_l,_u); } + template + Range MakeRange(T _l, T _u) { + return Range(_l,_u); + } /// Build a new range of type int. - inline Range IntRange(int _l, int _u) { return Range(_l,_u); } + template + inline Range IntRange(int _l, int _u) { + return Range(_l,_u); + } /// Build a new range of type double. - inline Range DRange(double _l, double _u) { return Range(_l,_u); } + template + inline Range DRange(double _l, double _u) { + return Range(_l,_u); + } } #endif // #ifndef EMP_MATH_RANGE_HPP_INCLUDE diff --git a/include/emp/math/RangeSet.hpp b/include/emp/math/RangeSet.hpp new file mode 100644 index 0000000000..b30c43fb05 --- /dev/null +++ b/include/emp/math/RangeSet.hpp @@ -0,0 +1,500 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + * @brief A collection of ranges that can be operated on collectively. + * @note Status: BETA + */ + +#ifndef EMP_MATH_RANGESET_HPP_INCLUDE +#define EMP_MATH_RANGESET_HPP_INCLUDE + +#include + +#include "../base/vector.hpp" +#include "../datastructs/vector_utils.hpp" + +#include "Range.hpp" + +namespace emp { + + /// RangeSet maintains a collection of ranges. The ranges are exclusive of the endpoint + /// and kept sorted and non-adjacent (i.e., there is a gap between successive ranges). + template + class RangeSet { + public: + using range_t = emp::Range; + using this_t = RangeSet; + + private: + emp::vector range_set; + + // Helper function to find the id of an Range that a value belongs in or can extend; + // returns next-higher index (where a new range would be place) if none fit perfectly. + // size_t _FindRange(size_t val) const { + // for (size_t id = 0; id < range_set.size(); ++id) { + // if (id <= range_set[id].GetEnd()) return id; + // } + // return range_set.size(); + // } + size_t _FindRange(T value) const { + auto it = std::lower_bound( + range_set.begin(), + range_set.end(), + value, + [](const range_t & range, T value) { return range.GetUpper() < value; } + ); + return it - range_set.begin(); + }; + + void _InsertRange(size_t id, range_t range) { emp::InsertAt(range_set, id, range); } + void _RemoveRange(size_t id) { emp::RemoveAt(range_set, id); } + void _RemoveRanges(size_t id, size_t count) { emp::RemoveAt(range_set, id, count); } + + // Helper function to remove empty ranges at the beginning. + void _PruneEmptyFront() { + size_t count = 0; + while (count < range_set.size() && range_set[count].GetSize() == 0) ++count; + if (count) _RemoveRanges(0, count); + } + + // Helper function to remove empty ranges at the end. + void _PruneEmptyBack() { + size_t count = 0; + while (count < range_set.size() && + range_set[range_set.size()-count-1].GetSize() == 0) ++count; + if (count) range_set.resize(range_set.size() - count); + } + + // Helper function to increase the side of a range, possibly merging it with the next range. + void _CleanupMerge(size_t id) { + while (id+1 < range_set.size() && range_set[id].Merge(range_set[id+1])) { + _RemoveRange(id+1); // Delete next range (merged in to current) + } + emp_assert(OK()); + } + + // Helper function to convert a string into a RangeSet. + // Two formats are available + // bitstring: 010001110101111 + // RangeSet: [1,2),[5,8),[9,10),[11,15) + // In the bitstring format, if the final character is '+', all additional positions are + // assumed to be 1. In the RangeSet format, if the first or last element is a '*', it is + // assumed to be the limit for the type; also commas are optional. + // A star by itself is a full RangeSet. + void _FromString(emp::String in) { + if (in.size() == 0) { Clear(); } + else if (in[0] == '*') { + emp::notify::TestError(in.size() > 1, "Star indicates a full range, but must be by itself."); + SetAll(); + } + else if (in[0] == '0' || in[0] == '1') { + Clear(); + for (size_t i=0; i < in.size(); ++i) { + if (in[i] != '0') Insert((T)i); + } + } + else if (in[0] == '[') { + while (in.size()) { + emp::String segment = in.Pop(')'); + segment.PopIf(','); + emp::notify::TestError(!segment.PopIf('['), "Each segment of a RangeSet must begin with '['"); + T start = segment.PopIf('*') ? MinLimit() : segment.PopLiteral(); + emp::notify::TestError(!segment.PopIf(',') && !segment.PopIf('-'), + "Each segment of a RangeSet must be separated by ',' or '-'"); + T end = segment.PopIf('*') ? MaxLimit() : segment.PopLiteral(); + InsertRange(start, end); + } + } + } + + public: + static constexpr bool is_integral = std::is_integral(); + + RangeSet() = default; + explicit RangeSet( range_t start_range) { Insert(start_range); } + RangeSet(T start, T end) { InsertRange(start, end); } + RangeSet(const RangeSet &) = default; + RangeSet(RangeSet &&) = default; + RangeSet(const std::string & bitstring) { + emp_assert(is_integral, "RangeSets can be represented as strings only if they are integral."); + for (size_t i=0; i < bitstring.size(); ++i) { + if (bitstring[i] == '1') Insert((T)i); + } + } + + RangeSet & operator=(const RangeSet &) = default; + RangeSet & operator=(RangeSet &&) = default; + RangeSet & operator=(const std::string & bitstring) { + emp_assert(is_integral, "RangeSets can be represented as strings only if they are integral."); + Clear(); + for (size_t i=0; i < bitstring.size(); ++i) { + if (bitstring[i] == '1') Insert((T)i); + } + return *this; + } + + [[nodiscard]] bool operator<=>(const RangeSet &) const = default; + + [[nodiscard]] bool Has(T val) const { + const size_t id = _FindRange(val); + return (id < range_set.size()) ? range_set[id].Has(val) : false; + } + [[nodiscard]] bool HasRange(range_t range) const { + const size_t id = _FindRange(range.Lower()); + return (id < range_set.size()) ? range_set[id].HasRange(range) : false; + } + [[nodiscard]] bool IsEmpty() const { return !range_set.size(); } + [[nodiscard]] static constexpr T MaxLimit() { return std::numeric_limits::max(); } + [[nodiscard]] static constexpr T MinLimit() { return std::numeric_limits::lowest(); } + + /// @return Overall start of all ranges (or max value if no ranges exist.) + [[nodiscard]] T GetStart() const { return IsEmpty() ? MaxLimit() : range_set[0].Lower(); } + + /// @return Overall end of all ranges (or min value if no ranges exist.) + [[nodiscard]] T GetEnd() const { return IsEmpty() ? MinLimit() : range_set.back().Upper(); } + + [[nodiscard]] size_t GetNumRanges() const { return range_set.size(); } + + /// @brief Calculate the total combined size of all ranges. + [[nodiscard]] T GetSize() const { + T total = 0; + for (const auto & x : range_set) total += x.GetSize(); + return total; + } + + /// Present this set of ranges as a string. + [[nodiscard]] emp::String ToString() const { + emp::String out; + for (size_t i = 0; i < range_set.size(); ++i) { + if (i) out += ','; + out += range_set[i].ToString(); + } + return out; + } + + // Return all of the internal ranges (can only be called on l-values) + [[nodiscard]] const emp::vector & GetRanges() const & { return range_set; } + + // Calculate the size of the overlap with a provided range. + [[nodiscard]] bool HasOverlap(range_t range) const { + size_t low_id = _FindRange(range.GetLower()); + if (low_id >= range_set.size()) return false; // Entirely after ranges. + if (range_set[low_id].HasOverlap(range)) return true; // Overlaps at beginning. + return low_id+1 < range_set.size() && range_set[low_id+1].HasOverlap(range); + } + + // Calculate the size of the overlap with a provided range. + [[nodiscard]] T CalcOverlap(range_t range) const { + size_t low_id = _FindRange(range.GetLower()); + size_t up_id = _FindRange(range.GetUpper()); + T result = range_set[low_id].CalcOverlap(range); + if (low_id < up_id) { + for (size_t id=low_id+1; id < up_id; id++) result += range_set[id].GetSize(); + result += range_set[up_id].CalcOverlap(range); + } + return result; + } + + /// @brief Remove all ranges in the set. + RangeSet & Clear() { range_set.resize(0); return *this; } + + /// @brief Set a single range that includes all value. + RangeSet & SetAll() { InsertRange(MinLimit(), MaxLimit()); return *this; } + + /// @brief Shift all ranges by a fixed amount. + /// @param shift How much should the range be shifted by? + RangeSet & Shift(T shift) { + if (shift > 0) ShiftUp(shift); + else if (shift < 0) ShiftDown(shift); + return *this; + } + + RangeSet & ShiftUp(T shift) { + for (auto & range : range_set) range.ShiftUp(shift); + _PruneEmptyBack(); + return *this; + } + + RangeSet & ShiftDown(T shift) { + for (auto & range : range_set) range.ShiftDown(shift); + _PruneEmptyFront(); + return *this; + } + + + [[nodiscard]] this_t CalcShift(T shift) const { + this_t out(*this); + return out.Shift(shift); + } + + [[nodiscard]] this_t CalcShiftDown(T shift) const { + this_t out(*this); + return out.ShiftDown(shift); + } + + [[nodiscard]] this_t CalcShiftUp(T shift) const { + this_t out(*this); + return out.ShiftUp(shift); + } + + /// @brief Insert a value into this range set + /// @param val Value to insert. + /// @return This RangeSet after insertion. + RangeSet & Insert(T val) { + emp_assert(is_integral, "Only integral ranges can call Insert() with a single value."); + + // If empty or beyond the end, append a new range. + if (range_set.size() == 0 || val > GetEnd()) { + range_set.emplace_back(val); + } + + else { + const size_t id = _FindRange(val); + emp_assert(id < range_set.size(), id, range_set.size()); + range_t & range = range_set[id]; + + if (range.Has(val)) return *this; // Already has the value! + else if (range.Append(val)) _CleanupMerge(id); // Extending 'upper' on range + else if (range.GetLower() == val+1) range.Lower()--; // Extending 'lower' on range + else range_set.emplace(range_set.begin()+id, val); // Inserting NEW range. + } + + return *this; + } + + /// @brief Insert a whole range into this set, merging other ranges if needed. + /// @param in New range to include. + /// @return This RangeSet after insertion. + RangeSet & Insert(range_t in) { + const size_t start_id = _FindRange(in.GetLower()); + + // Are we adding a whole new range to the end? + if (start_id == range_set.size()) range_set.push_back(in); + + // Is it already included in the found range? No change! + else if (range_set[start_id].HasRange(in)) return *this; + + // Should we merge in with an existing range? + else if (range_set[start_id].IsConnected(in)) { + range_set[start_id].Merge(in); + _CleanupMerge(start_id); + } + + // Otherwise insert as a new range. + else _InsertRange(start_id, in); + + return *this; + } + + /// @brief Merge an entire range set into this one. + /// @param in_set Range set to add in. + /// @return This RangeSet after insertion. + /// @note Can be optimized to handle big set mergers more efficiently! + RangeSet & Insert(const this_t & in_set) { + for (const range_t & range : in_set.GetRanges()) Insert(range); + return *this; + } + + /// @brief Insert a range into this set, specifying the start and end points. + /// @param start Beginning of new range to include. + /// @param stop Ending of new range to include (range is not inclusive of stop) + /// @return This RangeSet after insertion. + RangeSet & InsertRange(T start, T stop) { return Insert(range_t{start, stop}); } + + /// @brief Remove a single value from this RangeSet. + /// @param val Value to remove + /// @return This RangeSet after removal. + RangeSet & Remove(T val) { + emp_assert(is_integral, "Only integral ranges can call Remove() with a single value."); + + if (!Has(val)) return *this; // Nothing to remove. + + const size_t id = _FindRange(val); + range_t & range = range_set[id]; + if (range.GetSize() == 1) _RemoveRange(id); // Remove whole range + else if (range.GetLower() == val) range.Lower()++; // Inc lower end + else if (range.GetUpper()-1 == val) range.Upper()--; // Dec upper end + else { // Split a range! + _InsertRange(id+1, range_t{val+1,range.GetUpper()}); + range_set[id].SetUpper(val); + } + return *this; + } + + /// @brief Remove all ranges (or partial range) less than a target value. + /// @param val New floor for ranges. + /// @return This RangeSet after removal. + RangeSet & RemoveTo(T val) { + if (val <= GetStart()) return *this; // Nothing to remove. + size_t id = _FindRange(val); + if (val == range_set[id].GetUpper()) ++id; + _RemoveRanges(0, id); // Remove everything before the new start. + if (range_set.size() && range_set[0].Lower() < val) range_set[0].SetLower(val); + return *this; + } + + /// @brief Remove all ranges (or partial range) greater than a target value. + /// @param val New cap for ranges. + /// @return This RangeSet after removal. + RangeSet & RemoveFrom(T val) { + if (val >= GetEnd()) return *this; // Nothing to remove. + size_t id = _FindRange(val); + if (val > range_set[id].GetLower()) ++id; // Include current range if needed. + range_set.resize(id); // Remove everything past new end. + if (GetEnd() > val) range_set.back().SetUpper(val); + return *this; + } + + /// @brief Remove a whole Range from this RangeSet. + /// @param rm_range Range to remove + /// @return This RangeSet after removal. + RangeSet & Remove(range_t rm_range) { + if (!HasOverlap(rm_range)) return *this; + if (rm_range.Lower() <= GetStart()) return RemoveTo(rm_range.Upper()); + if (rm_range.Upper() >= GetEnd()) return RemoveFrom(rm_range.Lower()); + + // Must be removing from the middle. + size_t start_id = _FindRange(rm_range.Lower()); + range_t & start_range = range_set[start_id]; + + // Fully internal to a single Range? Split it! + if (start_range.Lower() < rm_range.Lower() && start_range.Upper() > rm_range.Upper()) { + _InsertRange(start_id+1, range_t{rm_range.Upper(), start_range.Upper()}); + range_set[start_id].SetUpper(rm_range.Lower()); + return *this; + } + + // Deal with beginning of removal - cut it down if needed, and move on to next range. + if (rm_range.Lower() > start_range.Lower()) { + start_range.Upper() = rm_range.Lower(); + ++start_id; + } + + // Deal with end of removal. + size_t end_id = _FindRange(rm_range.Upper()); + if (rm_range.Upper() >= range_set[end_id].Upper()) end_id++; + else range_set[end_id].Lower() = std::max(range_set[end_id].Lower(), rm_range.Upper()); + + // Remove middle. + _RemoveRanges(start_id, end_id - start_id); + + return *this; + } + + /// @brief Remove all ranges in an entire range set from this one. + /// @param in_set Range set to remove. + /// @return This RangeSet after removal. + /// @note Can be optimized to handle big sets more efficiently! + RangeSet & Remove(const this_t & in_set) { + for (const range_t & range : in_set.GetRanges()) Remove(range); + return *this; + } + + + RangeSet & RemoveRange(T start, T stop) { return Remove(range_t{start, stop}); } + + /// @brief Remove everything outside of the provided range. + RangeSet & KeepOnly(T start, T stop) { + emp_assert(start < stop); + RemoveTo(start); + return RemoveFrom(stop); + } + + /// @brief Remove everything outside of the provided range. + RangeSet & KeepOnly(range_t keep_range) { + return KeepOnly(keep_range.GetLower(), keep_range.GetUpper()); + } + + /// @brief Remove everything outside of the provided set of ranges. + RangeSet & KeepOnly(const this_t & in_set) { return Remove(~in_set); } + + + // Some more advanced functions. + + /// @brief Calculate the inverted range set, swapping included and excluded values. + /// @return The inverted RangeSet. + [[nodiscard]] this_t CalcInverse() const { + emp_assert(OK()); + // If this is an empty set, return a full set. + if (range_set.size() == 0) return this_t(MinLimit(), MaxLimit()); + + // Determine if we need to extend the the limits on each side. + const bool add_begin = (GetStart() != MinLimit()); + const bool add_end = (GetEnd() != MaxLimit()); + this_t out; + out.range_set.reserve(range_set.size() + add_begin + add_end - 1); + if (add_begin) out.range_set.emplace_back(MinLimit(),GetStart()); + for (size_t i = 1; i < range_set.size(); ++i) { + out.range_set.emplace_back(range_set[i-1].Upper(), range_set[i].Lower()); + } + if (add_end) out.range_set.emplace_back(GetEnd(), MaxLimit()); + emp_assert(out.OK()); + return out; + } + + this_t & Invert() { *this = CalcInverse(); return *this; } + + // Simple operators: + [[nodiscard]] this_t operator~() const { return CalcInverse(); } + [[nodiscard]] this_t operator|(const this_t & in) const { + emp_assert(in.OK()); + this_t out(*this); + return out.Insert(in); + } + [[nodiscard]] this_t operator&(const this_t & in) const { + emp_assert(in.OK()); + this_t out(*this); + return out.Remove(~in); + } + [[nodiscard]] this_t operator^(const this_t & in) { + emp_assert(in.OK()); + return (*this | in) & ~(*this & in); + } + [[nodiscard]] this_t operator<<(const T shift) const { return CalcShiftUp(shift); } + [[nodiscard]] this_t operator>>(const T shift) const { return CalcShiftDown(shift); } + [[nodiscard]] bool operator[](T val) const { return Has(val); } + + this_t & operator|=(const this_t & in) { Insert(in); return *this; } + this_t & operator&=(const this_t & in) { Remove(~in); return *this; } + this_t & operator^=(const this_t & in) { emp_assert(in.OK()); *this = *this^in; return *this; } + this_t & operator<<=(const T shift) { ShiftUp(shift); return *this; } + this_t & operator>>=(const T shift) { ShiftDown(shift); return *this; } + + explicit operator bool() const { return range_set.size(); } + + + /// @brief Overload ostream operator to return Print. + friend std::ostream& operator<<(std::ostream &out, const this_t & range) { + out << range.ToString(); + return out; + } + + /// @brief Check for internal errors in this RangeSet. + bool OK() const { + // Check each range individually. + for (const auto & range : range_set) { + if (range.GetLower() > range.GetUpper()) { + emp::notify::Message("RangeSet::OK() Failed due to invalid range: ", range.ToString()); + return false; + } + } + + // Make sure ranges are in order and have gaps between them. + for (size_t i = 1; i < range_set.size(); ++i) { + if (range_set[i-1].GetUpper() >= range_set[i].GetLower()) { + emp::notify::Message("RangeSet::OK() Failed at range ", i, " of ", range_set.size(), + ". Ranges are: ", ToString()); + return false; + } + } + return true; + } + }; + +} + +#endif // #ifndef EMP_MATH_RANGESET_HPP_INCLUDE diff --git a/include/emp/math/combos.hpp b/include/emp/math/combos.hpp index 0327fff62b..35c10c1b35 100644 --- a/include/emp/math/combos.hpp +++ b/include/emp/math/combos.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017 - * - * @file combos.hpp + * @file * @brief Tools to step through combinations of items. * * Step through all combinations of size K from a set of N values. For ComboIDs just return the @@ -21,6 +22,7 @@ #define EMP_MATH_COMBOS_HPP_INCLUDE #include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" diff --git a/include/emp/math/constants.hpp b/include/emp/math/constants.hpp index d806842368..a70126a905 100644 --- a/include/emp/math/constants.hpp +++ b/include/emp/math/constants.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file constants.hpp + * @file * @brief Commonly used constant values. - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_MATH_CONSTANTS_HPP_INCLUDE diff --git a/include/emp/math/distances.hpp b/include/emp/math/distances.hpp index 3407dc83f9..dda0f34abe 100644 --- a/include/emp/math/distances.hpp +++ b/include/emp/math/distances.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file distances.hpp + * @file * @brief Library of commonly used distance functions * @note Status: BETA */ @@ -11,6 +12,8 @@ #ifndef EMP_MATH_DISTANCES_HPP_INCLUDE #define EMP_MATH_DISTANCES_HPP_INCLUDE +#include + #include "../meta/type_traits.hpp" #include "math.hpp" diff --git a/include/emp/math/info_theory.hpp b/include/emp/math/info_theory.hpp index f84131c1f7..6891158bcc 100644 --- a/include/emp/math/info_theory.hpp +++ b/include/emp/math/info_theory.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021. - * - * @file info_theory.hpp + * @file * @brief Tools to calculate Information Theory metrics. * @note Status: ALPHA * diff --git a/include/emp/math/math.hpp b/include/emp/math/math.hpp index db9ca895cb..012f1691fe 100644 --- a/include/emp/math/math.hpp +++ b/include/emp/math/math.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file math.hpp + * @file * @brief Useful mathematical functions (that are constexpr when possible.) * @note Status: BETA (though new functions are added frequently) */ @@ -14,8 +15,10 @@ #include #include +#include #include #include +#include #include "../base/assert.hpp" #include "../meta/reflection.hpp" diff --git a/include/emp/math/random_utils.hpp b/include/emp/math/random_utils.hpp index 7a8aaec4df..9a828dbe2c 100644 --- a/include/emp/math/random_utils.hpp +++ b/include/emp/math/random_utils.hpp @@ -1,17 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file random_utils.hpp + * @file * @brief Helper functions for emp::Random for common random tasks. - * @note Status: RELEASE + * Status: RELEASE */ #ifndef EMP_MATH_RANDOM_UTILS_HPP_INCLUDE #define EMP_MATH_RANDOM_UTILS_HPP_INCLUDE #include +#include #include "../base/vector.hpp" #include "../bits/BitVector.hpp" @@ -20,6 +22,12 @@ namespace emp { + /// Choose a random element from an indexable container. + template + inline auto SelectRandom(Random & random, const T & container) { + return container[random.GetUInt(container.size())]; + } + /// Randomly reorder all of the elements in a vector. /// If max_count is provided, just make sure that the first max_count entries are randomly /// drawn from entire vector. @@ -27,6 +35,7 @@ namespace emp { template inline void Shuffle(Random & random, emp::vector & v, size_t max_count) { + emp_assert(max_count <= v.size()); for (size_t i = 0; i < max_count; i++) { const size_t pos = random.GetUInt(i, v.size()); if (pos == i) continue; @@ -37,6 +46,17 @@ namespace emp { template inline void Shuffle(Random & random, emp::vector & v) { Shuffle(random, v, v.size()); } + template + inline void ShuffleRange(Random & random, emp::vector & v, size_t first, size_t last) + { + emp_assert(first <= last); + emp_assert(last <= v.size()); + for (size_t i = first; i < last; i++) { + const size_t pos = random.GetUInt(i, last); + if (pos == i) continue; + std::swap(v[i], v[pos]); + } + } /// Return an emp::vector numbered 0 through size-1 in a random order. diff --git a/include/emp/math/sequence_utils.hpp b/include/emp/math/sequence_utils.hpp index adc4dd5ba2..b6184e6cf6 100644 --- a/include/emp/math/sequence_utils.hpp +++ b/include/emp/math/sequence_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020. - * - * @file sequence_utils.hpp + * @file * @brief Functions for analyzing with generic sequence types. * @note Status: BETA * @@ -14,6 +15,8 @@ #ifndef EMP_MATH_SEQUENCE_UTILS_HPP_INCLUDE #define EMP_MATH_SEQUENCE_UTILS_HPP_INCLUDE +#include + #include "../base/notify.hpp" #include "../base/vector.hpp" #include "../tools/string_utils.hpp" diff --git a/include/emp/math/spatial_stats.hpp b/include/emp/math/spatial_stats.hpp index f471d142ff..57bd48eb50 100644 --- a/include/emp/math/spatial_stats.hpp +++ b/include/emp/math/spatial_stats.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019 - * - * @file spatial_stats.hpp + * @file * @brief Functions for calculating various spatial statistics. * @note Status: BETA */ @@ -12,6 +13,7 @@ #define EMP_MATH_SPATIAL_STATS_HPP_INCLUDE #include +#include #include "../base/vector.hpp" #include "../Evolve/World.hpp" diff --git a/include/emp/math/stats.hpp b/include/emp/math/stats.hpp index 16fac153cc..30417d9436 100644 --- a/include/emp/math/stats.hpp +++ b/include/emp/math/stats.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019 - * - * @file stats.hpp + * @file * @brief Functions for calculating various statistics about an ensemble. * @note Status: BETA */ diff --git a/include/emp/meta/ConceptWrapper.hpp b/include/emp/meta/ConceptWrapper.hpp index 2854cd9ef6..d0ea5f8d8b 100644 --- a/include/emp/meta/ConceptWrapper.hpp +++ b/include/emp/meta/ConceptWrapper.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018-2021. - * - * @file ConceptWrapper.hpp + * @file * @brief A template wrapper that will either enforce functionality or provide default functions. * * Starting in future versions of C++, a concept is a set of requirements for a class to be used @@ -97,6 +98,7 @@ #ifndef EMP_META_CONCEPTWRAPPER_HPP_INCLUDE #define EMP_META_CONCEPTWRAPPER_HPP_INCLUDE +#include #include #include diff --git a/include/emp/meta/FunInfo.hpp b/include/emp/meta/FunInfo.hpp index e0ff0c5938..a682221ad7 100644 --- a/include/emp/meta/FunInfo.hpp +++ b/include/emp/meta/FunInfo.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file FunInfo.hpp + * @file * @brief Wrap a function to provide more information about it. * @note Status: ALPHA * diff --git a/include/emp/meta/TypeID.hpp b/include/emp/meta/TypeID.hpp index fbad14a1d4..3712921b27 100644 --- a/include/emp/meta/TypeID.hpp +++ b/include/emp/meta/TypeID.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file TypeID.hpp + * @file * @brief TypeID provides an easy way to convert types to strings. * * TypeID provides an easy way to compare types, analyze them, and convert to strings. @@ -68,7 +69,9 @@ #define EMP_META_TYPEID_HPP_INCLUDE #include +#include #include +#include #include #include "../base/Ptr.hpp" @@ -283,7 +286,7 @@ namespace emp { return ptr.ReinterpretCast()->FromDouble(value); } - // If this type is convertable to a double, cast the pointer to the correct type, de-reference it, + // If this type is convertible to a double, cast the pointer to the correct type, de-reference it, // and then return the conversion. Otherwise return NaN if constexpr (std::is_convertible::value) { *ptr.ReinterpretCast() = (base_t) value; @@ -534,7 +537,7 @@ namespace emp { } } - +#ifndef DOXYGEN_SHOULD_SKIP_THIS namespace std { /// Hash function to allow TypeID to be used with maps and sets (must be in std). template <> @@ -550,5 +553,6 @@ namespace std { return out; } } +#endif // DOXYGEN_SHOULD_SKIP_THIS #endif // #ifndef EMP_META_TYPEID_HPP_INCLUDE diff --git a/include/emp/meta/TypePack.hpp b/include/emp/meta/TypePack.hpp index 74f38a8647..c5dcef61a4 100644 --- a/include/emp/meta/TypePack.hpp +++ b/include/emp/meta/TypePack.hpp @@ -1,15 +1,16 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file TypePack.hpp + * @file * @brief A set of types that can be manipulated at compile time (good for metaprogramming) * - * TypePacks are static structues that provide a large set of mechanisms to access and adjust + * TypePacks are static structures that provide a large set of mechanisms to access and adjust * the included types. * - * To create a typepack, just pass in zero or more types into the TypePack template. + * To create a TypePack, just pass in zero or more types into the TypePack template. * * using my_pack = emp::TypePack; * @@ -69,6 +70,8 @@ #ifndef EMP_META_TYPEPACK_HPP_INCLUDE #define EMP_META_TYPEPACK_HPP_INCLUDE +#include + #include "meta.hpp" namespace emp { @@ -291,7 +294,7 @@ namespace emp { /// Rearrange types in TypePack into reverse order. using reverse = typename pop::reverse::template push_back; - /// Rotate types through typepack by the specified number of steps. + /// Rotate types through TypePack by the specified number of steps. using rotate = typename pop::template push_back; /// Set the type at the specified position to the new type provided. Return as new TypePack. diff --git a/include/emp/meta/ValPack.hpp b/include/emp/meta/ValPack.hpp index a8b446be3e..060e1be0c5 100644 --- a/include/emp/meta/ValPack.hpp +++ b/include/emp/meta/ValPack.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file ValPack.hpp + * @file * @brief A set of values that can be manipulated at compile time (good for metaprogramming) * * Any built-in type can be added to ValPack to be manipulated at compile time. @@ -12,11 +13,12 @@ #ifndef EMP_META_VALPACK_HPP_INCLUDE #define EMP_META_VALPACK_HPP_INCLUDE +#include +#include +#include #include "meta.hpp" -#include -#include namespace emp { diff --git a/include/emp/meta/macro_math.hpp b/include/emp/meta/macro_math.hpp index 59ca7f3989..3d43e822be 100644 --- a/include/emp/meta/macro_math.hpp +++ b/include/emp/meta/macro_math.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file macro_math.hpp + * @file * @brief Macros to build a pre-processor calculator system. - * @note Status: RELEASE + * Status: RELEASE * * Working macros include: * EMP_INC(A) : converts to result of A+1 diff --git a/include/emp/meta/macros.hpp b/include/emp/meta/macros.hpp index e66796cd06..6dd2876dc5 100644 --- a/include/emp/meta/macros.hpp +++ b/include/emp/meta/macros.hpp @@ -1,11 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file macros.hpp + * @file * @brief Generally useful macros that can perform cools tricks. - * @note Status: RELEASE + * Status: RELEASE * * * Generally useful macros that can perform cools tricks. As with all macros, use only @@ -422,7 +423,7 @@ /// @endcond -// @cond MACROS +/// @cond MACROS // ********************** @@ -441,7 +442,6 @@ #define EMP_INTERNAL_CALL_BY_PACKS(C, F, ...) \ EMP_INTERNAL_CALL_BY_PACKS_impl(C, F, EMP_DEC_TO_PACK(EMP_COUNT_ARGS(__VA_ARGS__)), __VA_ARGS__, ~) -/// @cond MACROS // Internal helpers... // P is the pack of call counts the still need to be done diff --git a/include/emp/meta/meta.hpp b/include/emp/meta/meta.hpp index f61bec721c..ccd23cc122 100644 --- a/include/emp/meta/meta.hpp +++ b/include/emp/meta/meta.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file meta.hpp + * @file * @brief A bunch of C++ Template Meta-programming tricks. * * Developer notes: @@ -16,6 +17,7 @@ #define EMP_META_META_HPP_INCLUDE #include +#include #include #include @@ -327,6 +329,8 @@ namespace emp { static constexpr int Product() { return I; } }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS + //This bit of magic is from //http://meh.schizofreni.co/programming/magic/2013/01/23/function-pointer-from-lambda.html //and is useful for fixing lambda function woes @@ -356,6 +360,8 @@ namespace emp { return static_cast::function>(lambda); } + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ + /// Determine the size of a built-in array. template constexpr size_t GetSize(T (&)[N]) { return N; } diff --git a/include/emp/meta/reflection.hpp b/include/emp/meta/reflection.hpp index 2ed2a0d991..a51d5c4784 100644 --- a/include/emp/meta/reflection.hpp +++ b/include/emp/meta/reflection.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file reflection.hpp + * @file * @brief Macros and template utilities to help determine details about unknown classes. */ diff --git a/include/emp/meta/type_traits.hpp b/include/emp/meta/type_traits.hpp index 268053bae1..4ea71db94a 100644 --- a/include/emp/meta/type_traits.hpp +++ b/include/emp/meta/type_traits.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022. - * - * @file type_traits.hpp + * @file * @brief Extensions on the standard library type traits to handle Empirical classes (such as Ptr). */ @@ -11,8 +12,10 @@ #define EMP_META_TYPE_TRAITS_HPP_INCLUDE +#include // uint8_t, uint16_t, etc. #include #include +#include #include #include #include @@ -77,6 +80,7 @@ namespace emp { template struct HasToDouble().ToDouble())>> : std::true_type{}; + #ifndef DOXYGEN_SHOULD_SKIP_THIS // Determine if a type has a FromString() member function. template struct HasFromString : std::false_type { }; template @@ -86,6 +90,7 @@ namespace emp { template struct HasFromDouble : std::false_type { }; template struct HasFromDouble().FromDouble(0.0))>> : std::true_type{}; + #endif // DOXYGEN_SHOULD_SKIP_THIS /// Determine if a type passed in is an std::function type (vs a lambda or a raw function) template struct is_std_function : std::false_type { }; diff --git a/include/emp/polyfill/span.hpp b/include/emp/polyfill/span.hpp index 272d8a0705..cdad1951f4 100644 --- a/include/emp/polyfill/span.hpp +++ b/include/emp/polyfill/span.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file span.hpp - * @brief Polyfill for C++20 std::span. Since deprecated. + * @file + * @brief Polyfill for C++20 std::span. Since deprecated. */ #ifndef EMP_POLYFILL_SPAN_HPP_INCLUDE diff --git a/include/emp/prefab/Card.hpp b/include/emp/prefab/Card.hpp index f4ca1dd6ae..74d2f45afb 100644 --- a/include/emp/prefab/Card.hpp +++ b/include/emp/prefab/Card.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Card.hpp + * @file * @brief Wraps a Bootstrap card. */ @@ -113,7 +114,7 @@ namespace prefab { * A protected constructor for a Card. * @param state indicate whether card should be STATIC, INIT_OPEN, or INIT_CLOSED (default STATIC) * @param show_glyphs should toggle icons show in collapsible card header? (default true) - * @param info_ref a pointer to the underlying ReadoutPanelInfo object for this ReadoutPanel + * @param in_info a pointer to the underlying ReadoutPanelInfo object for this ReadoutPanel * or a pointer to a derived info object (simulating inheritance) */ Card( diff --git a/include/emp/prefab/CodeBlock.hpp b/include/emp/prefab/CodeBlock.hpp index 35dd32c844..e13527dec3 100644 --- a/include/emp/prefab/CodeBlock.hpp +++ b/include/emp/prefab/CodeBlock.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file CodeBlock.hpp + * @file * @brief Wraps a HighlightJS code block. */ @@ -35,6 +36,7 @@ namespace prefab { * * @param code_block string of the code to be placed in code block * @param lang programming language to base syntax highlighting + * @param id the id of the html element for this code block */ CodeBlock(const std::string code_block, const std::string lang, const std::string & id="") : web::Element("pre", id) { diff --git a/include/emp/prefab/Collapse.hpp b/include/emp/prefab/Collapse.hpp index c8e890f9eb..11d520e40a 100644 --- a/include/emp/prefab/Collapse.hpp +++ b/include/emp/prefab/Collapse.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Collapse.hpp + * @file * @brief Sets up a collapsable DOM element. */ @@ -31,7 +32,9 @@ namespace prefab { public: /** * @param controller web element that cause target area(s) to expand/collapse when clicked + * @param controls_class CSS class for controls * @param expanded whether or not the target(s) are initially in an expanded/open state + * @param id HTML id of div for this controller */ template CollapseController( @@ -150,7 +153,7 @@ namespace prefab { * Adds a controller to the vector of controllers for this CollapseCouple * * @param controller new controller to add to coupling is of type Widget - * @param expaned initial state of the target(s), is it expaned or not? + * @param expanded initial state of the target(s), is it expanded or not? */ void AddController(web::Widget controller, const bool expanded) { internal::CollapseController controller_widget(controller, target_class, expanded); @@ -160,7 +163,7 @@ namespace prefab { /** Adds a controller to the vector of controllers for this CollapseCouple. * * @param controller new controller to add to coupling is of type string - * @param expaned initial state of the target(s), is it expaned or not? + * @param expanded initial state of the target(s), is it expanded or not? */ /* @@ -175,7 +178,7 @@ namespace prefab { * Adds a target to the vector of targets for this CollapseCouple * * @param widget new target to add to coupling is a web element - * @param expaned initial state of the target(s), is it expaned or not? + * @param expanded initial state of the target(s), is it expanded or not? */ void AddTarget(web::internal::FacetedWidget widget, const bool expanded) { if (expanded) { @@ -190,8 +193,8 @@ namespace prefab { /** * Adds a target to the vector of targets for this CollapseCouple * - * @param widget new target to add to coupling is a string - * @param expaned initial state of the target(s), is it expaned or not? + * @param target new target to add to coupling is a string + * @param expanded initial state of the target(s), is it expanded or not? */ /* diff --git a/include/emp/prefab/CommentBox.hpp b/include/emp/prefab/CommentBox.hpp index 2d40fef221..477ee899f6 100644 --- a/include/emp/prefab/CommentBox.hpp +++ b/include/emp/prefab/CommentBox.hpp @@ -1,15 +1,16 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file CommentBox.hpp + * @file * @brief Create a light grey "comment bubble." * * TODO: When prefab tools for adding mobile only and desktop only * content are created, remove AddMobileContent(), desktop_content * and mobile_content divs, and ConfigPanel as a friend class. - * AddConent() should stream into all_content div. + * AddContent() should stream into all_content div. */ #ifndef EMP_PREFAB_COMMENTBOX_HPP_INCLUDE @@ -26,7 +27,9 @@ namespace prefab { * Optionally, it can contain text and other web elements. */ class CommentBox: public web::Div { - friend prefab::ConfigPanel; + #ifndef DOXYGEN_SHOULD_SKIP_THIS + friend ConfigPanel; + #endif DOXYGEN_SHOULD_SKIP_THIS private: // ID for the comment box Div std::string box_base = this->GetID(); diff --git a/include/emp/prefab/ConfigPanel.hpp b/include/emp/prefab/ConfigPanel.hpp index 7c6b5e3916..e7093c55f8 100644 --- a/include/emp/prefab/ConfigPanel.hpp +++ b/include/emp/prefab/ConfigPanel.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ConfigPanel.hpp + * @file * @brief Interfaces with emp::config objects to provide UI configuration. */ @@ -11,6 +12,7 @@ #define EMP_PREFAB_CONFIGPANEL_HPP_INCLUDE #include +#include #include "../datastructs/set_utils.hpp" #include "../tools/string_utils.hpp" @@ -76,7 +78,7 @@ namespace prefab { * panel to your web app. Users can interact with the config panel * by updating values. * - * The ConfigPanel is constructed using subcomponents. Groups of + * The ConfigPanel is constructed using sub-components. Groups of * settings are placed in Cards, and individual settings are represented * by ValueControls. */ @@ -110,12 +112,15 @@ namespace prefab { } inline static std::set numeric_types = {"int", "double", "float", "uint32_t", "uint64_t", "size_t"}; - // Helper function to get prety names from config values + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + // Helper function to get pretty names from config values inline static std::function format_label = []( const std::string & name ) { return to_titlecase(join(slice(name, '_'), " ")); }; + #endif // DOXYGEN_SHOULD_SKIP_THIS /** * Get current on-update callback. @@ -129,6 +134,8 @@ namespace prefab { public: /** * @param config config object used to construct this panel + * @param open Should card for displaying this config default to being open? + * @param div_name Name to use for html div id for this panel */ ConfigPanel( Config & config, @@ -310,7 +317,8 @@ namespace prefab { /** * Arranges config panel based configuration pass to constructor * @param config the config object used to create this panel - * @param id_prefix string appended to id for each setting (unusued) + * @param open should the card for the panel start open? + * @param id_prefix string appended to id for each setting (unused) * @deprecated No longer necessary for config panel to function. * This function was a work around to fix a bug. */ diff --git a/include/emp/prefab/FontAwesomeIcon.hpp b/include/emp/prefab/FontAwesomeIcon.hpp index c6cbfb945b..55441ee188 100644 --- a/include/emp/prefab/FontAwesomeIcon.hpp +++ b/include/emp/prefab/FontAwesomeIcon.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file FontAwesomeIcon.hpp + * @file * @brief Wraps Font Awesome's icons. */ diff --git a/include/emp/prefab/LoadingIcon.hpp b/include/emp/prefab/LoadingIcon.hpp index bca66d01d9..b69cd16859 100644 --- a/include/emp/prefab/LoadingIcon.hpp +++ b/include/emp/prefab/LoadingIcon.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file LoadingIcon.hpp + * @file * @brief Wraps Font Awesome's loading glyph. */ diff --git a/include/emp/prefab/LoadingModal.hpp b/include/emp/prefab/LoadingModal.hpp index 33ece8f223..8898c88631 100644 --- a/include/emp/prefab/LoadingModal.hpp +++ b/include/emp/prefab/LoadingModal.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2021 - * - * @file LoadingModal.hpp + * @file * @brief Wrapper for loading moadal * * To add a loading modal to your web page, you must diff --git a/include/emp/prefab/Modal.hpp b/include/emp/prefab/Modal.hpp index 6b3ebf78a7..5c11ade52c 100644 --- a/include/emp/prefab/Modal.hpp +++ b/include/emp/prefab/Modal.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Modal.hpp + * @file * @brief Wraps a Bootstrap modal. */ diff --git a/include/emp/prefab/ReadoutPanel.hpp b/include/emp/prefab/ReadoutPanel.hpp index 38e4fb2d86..cdd8af28cd 100644 --- a/include/emp/prefab/ReadoutPanel.hpp +++ b/include/emp/prefab/ReadoutPanel.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file ReadoutPanel.hpp + * @file * @brief UI framework for live statistic readouts. */ @@ -19,6 +20,7 @@ namespace emp::prefab { + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace internal { /** * Shared pointer held by instances of ReadoutPanel class representing @@ -54,6 +56,8 @@ namespace emp::prefab { }; } + #endif // DOXYGEN_SHOULD_SKIP_THIS + /** * Use a ReadoutPanel to display a collection of related live values * in a Card. @@ -82,8 +86,8 @@ namespace emp::prefab { public: /** * @param group_name name for this collection of values, displayed in card header - * @param refresh_time the time in milliseconds between refreshes to the live values - * @param state initial state of the card, one of STATIC, INIT_OPEN, or INIT_CLOSED + * @param refresh_milliseconds the time in milliseconds between refreshes to the live values + * @param state initial state of the card, one of STAITC, INIT_OPEN, or INIT_CLOSED * @param show_glyphs whether the underlying card should show toggle icons in card header * @param id a user defined ID for ReadoutPanel div (default is emscripten generated) */ @@ -117,7 +121,7 @@ namespace emp::prefab { * INIT_CLOSED * @param show_glyphs whether the underlying card should show toggle icons * in card header - * @param info_ref a pointer to the underlying ReadoutPanelInfo object for + * @param in_info a pointer to the underlying ReadoutPanelInfo object for * this ReadoutPanel or a pointer to a derived info object (simulating inheritance) */ ReadoutPanel(const std::string & group_name, @@ -136,7 +140,7 @@ namespace emp::prefab { auto & live_divs = Info()->GetLiveDivs(); // Animation is referenced by this component's ID AddAnimation(GetID(), [ - elapsed_milliseconds = 0, refresh_milliseconds, &live_divs + elapsed_milliseconds = 0.0, refresh_milliseconds, &live_divs ](double stepTime) mutable { // Accumulate steps, then redraw after enough time has elapsed elapsed_milliseconds += stepTime; @@ -178,7 +182,7 @@ namespace emp::prefab { * parent div to a list of divs to be redrawn at the refresh rate. * @param name the name for this value. * @param desc a description for this value. - * @param value_getter a function that will return the string for this value. + * @param value a function that will return the string for this value. * * @return the readout panel for chaining calls */ diff --git a/include/emp/prefab/ToggleSwitch.hpp b/include/emp/prefab/ToggleSwitch.hpp index 24b10bf36c..97783f91d8 100644 --- a/include/emp/prefab/ToggleSwitch.hpp +++ b/include/emp/prefab/ToggleSwitch.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ToggleSwitch.hpp + * @file * @brief Wraps Bootstrap's toggle switch. */ diff --git a/include/emp/prefab/ValueBox.hpp b/include/emp/prefab/ValueBox.hpp index 83c29c33ed..4ebb233630 100644 --- a/include/emp/prefab/ValueBox.hpp +++ b/include/emp/prefab/ValueBox.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ValueBox.hpp - * @brief UI subcomponent for ConfigPanel and ReadoutPanel. + * @file + * @brief UI sub-component for ConfigPanel and ReadoutPanel. */ #ifndef EMP_PREFAB_VALUEBOX_HPP_INCLUDE @@ -164,12 +165,12 @@ namespace emp::prefab { ValueControl( const std::string & label, const std::string & desc, - const std::string & inital_value, + const std::string & initial_value, web::Input input, const std::string & id="" ) : ValueBox(label, desc, id), mainCtrl(input) { view << mainCtrl; - mainCtrl.Value(inital_value); + mainCtrl.Value(initial_value); } }; @@ -190,7 +191,11 @@ namespace emp::prefab { const std::string & label, const std::string & desc, const std::string & value, - const std::function & onChange = [](const std::string &) { ; }, + const std::function & onChange + #ifndef DOXYGEN_SHOULD_SKIP_THIS + = [](const std::string &) { ; } + #endif // DOXYGEN_SHOULD_SKIP_THIS + , const std::string & id="" ) : ValueControl(label, desc, value, web::Input(onChange, "text", ""), id) { mainCtrl.AddAttr("class", "form-control"); @@ -206,7 +211,7 @@ namespace emp::prefab { /** * @param label name for this value * @param desc a more detailed description of what the value means - * @param value the initial value + * @param is_checked is switch initially on? * @param onChange function to be called when the user changes this value * @param id user defined ID for BoolValueControl div (default is emscripten generated) */ @@ -214,7 +219,11 @@ namespace emp::prefab { const std::string & label, const std::string & desc, const bool is_checked, - const std::function & onChange = [](const std::string &) { ; }, + const std::function & onChange + #ifndef DOXYGEN_SHOULD_SKIP_THIS + = [](const std::string & val) { ; } + #endif // DOXYGEN_SHOULD_SKIP_THIS + , const std::string & id="" ) : ValueBox(label, desc, id) { prefab::ToggleSwitch toggle(onChange, "", is_checked); @@ -236,6 +245,7 @@ namespace emp::prefab { )>; // Determine the default range by finding the next highest order of magnitude (base 10) + #ifndef DOXYGEN_SHOULD_SKIP_THIS inline static range_setter_t applyDefaultRange = []( const std::string & value, const std::string & type, @@ -259,6 +269,7 @@ namespace emp::prefab { in.Step(step); } }; + #endif // DOXYGEN_SHOULD_SKIP_THIS public: /** @@ -274,7 +285,11 @@ namespace emp::prefab { const std::string & desc, const std::string & value, const std::string & type, - const std::function & onChange = [](const std::string & val) { ; }, + const std::function & onChange + #ifndef DOXYGEN_SHOULD_SKIP_THIS + = [](const std::string & val) { ; } + #endif // DOXYGEN_SHOULD_SKIP_THIS + , const std::string & id="" ) : ValueControl(label, desc, value, web::Input([](const std::string & val){ ; }, "range", ""), id) { mainCtrl.AddAttr("class", "form-range"); diff --git a/include/emp/scholar/Author.hpp b/include/emp/scholar/Author.hpp index dd7ee5ea6d..7a1e7d5fe0 100644 --- a/include/emp/scholar/Author.hpp +++ b/include/emp/scholar/Author.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Author.hpp + * @file * @brief Basic information about an author. * * Developer notes: @@ -16,6 +17,7 @@ #ifndef EMP_SCHOLAR_AUTHOR_HPP_INCLUDE #define EMP_SCHOLAR_AUTHOR_HPP_INCLUDE +#include #include #include "../compiler/Lexer.hpp" diff --git a/include/emp/scholar/Bibliography.hpp b/include/emp/scholar/Bibliography.hpp index 6e1019d557..9a7546065f 100644 --- a/include/emp/scholar/Bibliography.hpp +++ b/include/emp/scholar/Bibliography.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file Bibliography.hpp + * @file * @brief A collection of references. */ diff --git a/include/emp/scholar/Citation.hpp b/include/emp/scholar/Citation.hpp index 15d90fcc65..35634b2fcf 100644 --- a/include/emp/scholar/Citation.hpp +++ b/include/emp/scholar/Citation.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2019 - * - * @file Citation.hpp + * @file * @brief Information about a citation for a single paper / book / etc. */ @@ -12,6 +13,7 @@ #include #include +#include #include #include "../base/map.hpp" diff --git a/include/emp/testing/unit_tests.hpp b/include/emp/testing/unit_tests.hpp index 1fd1440710..dcadb6369f 100644 --- a/include/emp/testing/unit_tests.hpp +++ b/include/emp/testing/unit_tests.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2019 - * - * @file unit_tests.hpp + * @file * @brief Macros to facilitate unit testing. * @note Status: RESURGENT (Was deprecated; now back to ALPHA) * @@ -19,6 +20,7 @@ #include #include +#include #include "../config/command_line.hpp" #include "../meta/macros.hpp" diff --git a/include/emp/text/EmphaticEncoding.hpp b/include/emp/text/EmphaticEncoding.hpp index 3244dd6fed..01b86a0806 100644 --- a/include/emp/text/EmphaticEncoding.hpp +++ b/include/emp/text/EmphaticEncoding.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file EmphaticEncoding.hpp + * @file * @brief Plugs into emp::Text, setting up inputs and output to be Emphatic encoded. * @note Status: ALPHA * @@ -16,59 +17,41 @@ #include #include -#include "../base/array.hpp" -#include "../base/assert.hpp" -#include "../base/notify.hpp" -#include "../compiler/Lexer.hpp" -#include "../tools/string_utils.hpp" - +#include "TextEncoding.hpp" #include "Text.hpp" namespace emp { class EmphaticEncoding : public emp::TextEncoding { private: - emp::array tag_map; // Maps tag characters to style names - std::map style_map; // Maps styles - emp::array escape_map; - - emp::Lexer lexer; - - enum class EmphToken { - text = 255, - escape = 254, - tag = 253, - code = 252, - comment = 251, - link = 250, - url = 249, - image = 248, - plain = 247, - exe = 246, - eval = 245, - EOL = 244, - error = 243 }; - - std::set active_styles; // Styles to use on appended text. - void SetupTags() { - tag_map['*'] = "bold"; - tag_map['`'] = "code"; - tag_map['/'] = "italic"; - tag_map['~'] = "strike"; - tag_map['.'] = "subscript"; - tag_map['^'] = "superscript"; - tag_map['_'] = "underline"; - - tag_map['#'] = "heading"; - tag_map['-'] = "bullet"; - tag_map['+'] = "ordered"; - tag_map['>'] = "indent"; - tag_map['"'] = "blockquote"; - tag_map['|'] = "continue"; // Keep previous lines setup (for set of full-line tags) - - // AVAILABLE TAGS: @&;:',?()]\ + SetupStyleTags("bold", "`*", "`*"); + SetupStyleTags("code", "``", "``"); + SetupStyleTags("italic", "`/", "`/"); + SetupStyleTags("strike", "`~", "`~"); + SetupStyleTags("subscript", "~.", "~."); + SetupStyleTags("superscript", "`^", "`^"); + SetupStyleTags("underline", "`_", "`_"); + SetupStyleTags("header:1", "`#", "`#"); + SetupStyleTags("header:2", "`##", "`##"); + SetupStyleTags("header:3", "`###", "`###"); + SetupStyleTags("header:4", "`####", "`####"); + SetupStyleTags("header:5", "`#####", "`#####"); + SetupStyleTags("header:6", "`######", "`######"); + + SetupReplaceTag("\\`", '`'); + SetupReplaceTag("\\\\", '\\'); + SetupReplaceTag("\\ ", ' ', "no_break"); + + SetupReplaceTag("`-", ' ', "bullet"); + SetupReplaceTag("`+", ' ', "ordered"); + SetupReplaceTag("`>", ' ', "indent"); + SetupReplaceTag("`\"", ' ', "blockquote"); + + // tag_map['|'] = "continue"; // Keep previous lines setup (for set of full-line tags) + + // AVAILABLE TAGS: @&;:',?()] // Start of more complex tags... // tag_map['%'] = "comment"; // `% Should be removed by the lexer. @@ -78,229 +61,24 @@ namespace emp { // tag_map['='] = "plaintext"; // `=No special `characters` should be \acknowledged. // tag_map['{'] = "execute"; // `{Code to run`} // tag_map['$'] = "eval"; // `$var_value_printed_here$ - - escape_map['\\'] = '\\'; - escape_map['`'] = '`'; - escape_map[' '] = ' '; // Plus a non-breaking style on the space. - escape_map['\n'] = '\n'; - escape_map['\t'] = '\t'; - - // Now that all of the tags are loaded, put them into the lexer. - [[maybe_unused]] int token_id; - token_id = lexer.AddToken("text","[^`\\]+"); // Non-tag or special characters. - emp_assert(token_id == (int) EmphToken::text); - token_id = lexer.AddToken("escape", "\\\\[\\\\` \n\t]"); - emp_assert(token_id == (int) EmphToken::escape); - token_id = lexer.AddToken("tag", "`[*`/~.\\^_#+>\"|-]"); // Tags - emp_assert(token_id == (int) EmphToken::tag); - - // Specialty tags... - token_id = lexer.AddToken("code", "`[a-zA-Z0-9 \n\t]"); // Single ` okay if followed by alphanumeric or whitespace. - emp_assert(token_id == (int) EmphToken::code); - token_id = lexer.AddToken("comment", "`%.*"); // Clear whole line. - emp_assert(token_id == (int) EmphToken::comment); - token_id = lexer.AddToken("link", "`\\[[^\\]\n]*\\]\\([^)\n]*\\)" ); - emp_assert(token_id == (int) EmphToken::link); - token_id = lexer.AddToken("url", "`<[^>\n]*>" ); - emp_assert(token_id == (int) EmphToken::url); - token_id = lexer.AddToken("image", "`!\\[[^\\]\n]*\\](\\([^)\n]*\\))?"); - emp_assert(token_id == (int) EmphToken::image); - token_id = lexer.AddToken("plain", "`=.*"); - emp_assert(token_id == (int) EmphToken::plain); - token_id = lexer.AddToken("exe", "`{[^`]*`}"); - emp_assert(token_id == (int) EmphToken::exe); - token_id = lexer.AddToken("eval", "`$[a-zA-Z0-1_]*$"); - emp_assert(token_id == (int) EmphToken::eval); - token_id = lexer.AddToken("EOL", "\n"); - emp_assert(token_id == (int) EmphToken::EOL); - } - - // Append a string that has already been otherwise processed. - void Append_Text(const std::string & in) { - size_t start = text.size(); - size_t end = start + in.size(); - text.Append_Raw(in); - for (const std::string & style : active_styles) { - text.SetStyle(style, start, end); - } - } - - void Append_Tag(const std::string & in) { - emp_assert(in.size() >= 2); - emp_assert(in[0] == '`'); - const std::string & style = tag_map[in[1]]; - switch (in[1]) { - // -- Tags that toggle -- - case '*': // Bold - case '`': // Code - case '/': // Italic - case '~': // Strike - case '.': // Subscript - case '^': // Superscript - case '_': // Underline - if (active_styles.count(style)) { - active_styles.erase(style); - } else { - active_styles.insert(style); - } - break; - - // -- Tags that go to the end of line -- - case '#': // Heading - case '-': // Bullet - case '+': // Number Bullet - case '>': // Indent - case '"': // Blockquote - active_styles.insert(style); - break; - - // -- Other special tags -- - case '|': // Continue previous format. - break; - } - } - - void Append_Newline() { - // Terminate any style that only goes to the end of the current line. - active_styles.erase("heading"); - active_styles.erase("bullet"); - active_styles.erase("ordered"); - active_styles.erase("indent"); - active_styles.erase("blockquote"); - - // Pass along the newline. - Append_Text("\n"); - } - - void Append_Escape(const std::string & in) { - emp_assert(in[0] == '\\'); - switch (in[1]) { - case '`': Append_Text("`"); break; - case '\\': Append_Text("\\"); break; - case ' ': Append_Text(" "); text.back().SetStyle("nobreak"); break; - case 'n': Append_Text("\n"); break; - case 't': Append_Text("\t"); break; - } } public: - EmphaticEncoding(Text & _text, const std::string _name="emphatic") - : TextEncoding(_text, _name) { SetupTags(); } - ~EmphaticEncoding() override { }; - - // Add new Emphatic encoded text into this object. - void Append(std::string in) override { -// std::cout << "APPEND: " << in << std::endl; - - auto tokens = lexer.Tokenize(in); - for (const auto & token : tokens) { - switch ((EmphToken) token.id) { - case EmphToken::text: - Append_Text(token.lexeme); - break; - case EmphToken::escape: - Append_Escape(token.lexeme); - break; - case EmphToken::tag: - Append_Tag(token.lexeme); - break; - case EmphToken::code: - Append_Tag("``"); - Append_Text(emp::to_string(token.lexeme[1])); - break; - case EmphToken::comment: - // Explicitly discard comment. - break; - case EmphToken::link: - // TODO - break; - case EmphToken::url: - // TODO - break; - case EmphToken::image: - // TODO - break; - case EmphToken::plain: - Append_Text(token.lexeme.substr(2,token.lexeme.size()-2)); - break; - case EmphToken::exe: - // TODO - break; - case EmphToken::eval: - // TODO - break; - case EmphToken::EOL: - Append_Newline(); - break; - default: - notify::Error("Unknown token: ", token.id); - } - } - } - - // Convert this to a string in Emphatic format. - std::string ToString() const override { - // Determine where tags should be placed. - std::map tag_map; - for (const auto & [style, info] : style_info) { - if (text.HasStyle(style)) AddOutputTags(tag_map, style, info.open, info.close); - } - - // Convert the string, adding tags back in as we go. - std::string out_string; - size_t output_pos = 0; - for (auto [tag_pos, tags] : tag_map) { - while (output_pos < tag_pos) { - char next_char = text.GetChar(output_pos); - switch (next_char) { - case '<': out_string += "<"; break; - case '>': out_string += ">"; break; - case '&': out_string += "&"; break; - default: - out_string += next_char; - } - ++output_pos; - } - out_string += tags; - } + EmphaticEncoding() { SetupTags(); } + ~EmphaticEncoding() = default; - // Add any final text after the last tag. - if (output_pos < text.size()) { - out_string += text.GetText().substr(output_pos, text.size()-output_pos); - } - - return out_string; - } - - private: - // ------------ Helper functions ------------ - - // A helper to add start and end tag info to tag map for insertion into - // the output string as it's created. - void AddOutputTags( - std::map & tag_map, - std::string style, - std::string start_tag, - std::string end_tag) const - { - const BitVector & sites = text.GetStyle(style); - - // Test if this style should be opened at the beginning. - if (sites.Has(0)) tag_map[0] += start_tag; - - // Loop through other site checking for shifts in style. - for (size_t i = 1; i < sites.size(); ++i) { - if (sites[i] != sites[i-1]) { - if (sites[i]) tag_map[i] += start_tag; - else tag_map[i] += end_tag; - } - } - - // Close any styles left open by the end. - if (sites.back()) tag_map[sites.size()] += end_tag; + String GetName() const override { return "emphatic"; } + emp::Ptr Clone() const override { + return emp::NewPtr(); } }; + using EmphaticText = EncodedText; + + template + emp::Text MakeEmphaticText(Ts &&... args) { + return MakeEncodedText(std::forward(args)...); + } } #endif // #ifndef EMP_TEXT_EMPHATICENCODING_HPP_INCLUDE diff --git a/include/emp/text/HTMLEncoding.hpp b/include/emp/text/HTMLEncoding.hpp index 84bfd36ddc..1707f185f6 100644 --- a/include/emp/text/HTMLEncoding.hpp +++ b/include/emp/text/HTMLEncoding.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022-23. - * - * @file HTMLEncoding.hpp + * @file * @brief Plugs into emp::Text, setting up inputs and output to be HTML encoded. * @note Status: ALPHA * @@ -16,9 +17,6 @@ #include #include -#include "../base/assert.hpp" -#include "../compiler/Lexer.hpp" - #include "TextEncoding.hpp" #include "Text.hpp" @@ -50,12 +48,21 @@ namespace emp { public: - HTMLEncoding(Text & _text, const std::string _name="html") - : TextEncoding(_text, _name) { SetupTags(); } + HTMLEncoding() { SetupTags(); } ~HTMLEncoding() = default; + String GetName() const override { return "html"; } + emp::Ptr Clone() const override { + return emp::NewPtr(); + } }; + using HTMLText = EncodedText; + + template + emp::Text MakeHTMLText(Ts &&... args) { + return MakeEncodedText(std::forward(args)...); + } } #endif // #ifndef EMP_TEXT_HTMLENCODING_HPP_INCLUDE diff --git a/include/emp/text/HTMLText.hpp b/include/emp/text/HTMLText.hpp deleted file mode 100644 index 8fa7fe81bb..0000000000 --- a/include/emp/text/HTMLText.hpp +++ /dev/null @@ -1,42 +0,0 @@ -/** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022-23. - * - * @file HTMLText.hpp - * @brief Like emp::Text, but defaults to using HTMLEncoding. - * @note Status: ALPHA - */ - -#ifndef EMP_TEXT_HTMLTEXT_HPP_INCLUDE -#define EMP_TEXT_HTMLTEXT_HPP_INCLUDE - -#include "HTMLEncoding.hpp" -#include "Text.hpp" - -namespace emp { - - class HTMLText : public emp::Text { - public: - /// @brief Create a new, default HTMLText object. - HTMLText() { AddEncoding("html"); }; - - /// @brief Copy over another Text object, but make it uses an HTML encoding. - /// @param in Already formatted Text object to load in. - HTMLText(const Text & in) : Text(in) { ActivateEncoding("html"); } - - /// @brief Create a new HTMLText object and default it to the provided string. - /// @param in Starting (html-encoded) string to use. - HTMLText(const String & in) { AppendAs("html", in); } - HTMLText(const std::string & in) { AppendAs("html", in); } - HTMLText(const char * in) { AppendAs("html", in); } - - HTMLText & operator=(const HTMLText &) = default; - HTMLText & operator=(HTMLText &&) = default; - template - HTMLText & operator=(T && in) { Text::operator=(std::forward(in)); return *this; }; - }; - -} - -#endif // #ifndef EMP_TEXT_HTMLTEXT_HPP_INCLUDE diff --git a/include/emp/text/NOTES b/include/emp/text/NOTES index 2bf43583bd..bda76da255 100644 --- a/include/emp/text/NOTES +++ b/include/emp/text/NOTES @@ -1,66 +1,135 @@ +Emphatic is an internal coding for Empirical that will try to support as many text encodings as reasonable, simplifying the conversion between them while being easy to write to in code (via the emp::Text object.) + Supported text formats: - TXT (plain text) - HTML + TXT (plain text - working) + HTML (simple tags working) LATEX MARKDOWN RTF XML + MarkBack (custom markup language; simple tags working) + +Internal encoding (Emphatic) + The Emphatic encoding maintains a string of characters, each associated with any number of styles. The standard styles are: + bold + code + comment (text that should not be shown in final output) + italic + strike (for strikethrough) + subscript + superscript + underline + + Some styles are only associated with individual special characters (usually matched with a space). This are: + no_break - non-breaking space + bullet + ordered + indent + blockquote - Marks this line as being part of a blockquote. + + Additional styles are followed by a colon and details must be provided. + header - followed by header level (e.g.: header:1) + link - text should redirect to provided URL (e.g.: link:https://google.com) + image - followed by location of image. + + + +--------------------------------------- + + +MarkBack notes: + New format is .mback, which is inspired by markdown, but uses just two types of special characters for formatting: + Backquotes (`) indicate a change in text STYLE + Backslashes (\) indicate a special CHARACTER + + The following tags toggle a formatting STYLE. + + `*Bold!`* + ``Code`` + `/Italic`/ + `_Underlined!`_ + `^Superscript`^ + `.Subscript`. + `~Strikethrough`~ + `<{URL}Linked-text goes here`> + `#{hashtag}Tagged text`# + + Color changes are placed in brackets. + + `[blue]This text would be blue + `[#FF00FF]This text would be magenta + `[]This text would be back to default color. + + You can end ALL special formatting with `! + + Code -- see below. + `{var name=value or other_code} + `?{TEST}Optional formatting -- e.g., ?{has_error}[red] or ?{important}* + + The following tags change the format for the rest of the line they are on. These should generally be the first non-whitespace on a line, but if not a newline will be assumed before them. + + `" Blockquote + `% Comment that will be removed. + `| Continues the previous line for other tags in this group. + + Anything with three backticks (```) before and after will be treated as code blocks. + Add a `= at the beginning of a line if you don't want any special formatting on that line. + + A single or double backtick indicates that everything in between is going to be inline + code. A single backtick must be followed by an alphanumeric character or whitespace, + but a double backtick can be followed by anything. + + `This would be rendered as CODE` + ``{This would also be code, _with_ the braces appearing}`` + + + Unused symbols for style: @$&()-=+;:', + ALSO unused, but less useful: ]} + + The following tags handle special CHARACTERS: + + \\ is a regular backslash ('\') + \` is a regular backtick ('`') + \#{Heading} + \##{Heading level 2} + \### etc. deeper headings. + \| is the beginning of a table line (rest of line is markdown format...?) + \_ is a non-breaking space. + \. is nothing. Use to separate other text (e.g., for unicode immediately followed by a number) + \- is a horizontal rule + \^{note} creates an footnote. This is a superscript value with the contents included at the end of the page (or end of document if no pagebreaks) + \* is a bullet which will start a list entry + \+ is a consecutive number bullet, incrementing if in a list + \={123} (or any other numbers or letters) is a specified value for a bullet (a subsequent \+, \a, or \R will continue from it) + \a is an alphabetic bullet, incrementing if in a list + \b is a page break + \d{name} creates a division with a specified name + \n is a line break (newline) + \p is a paragraph break + \t is a tab + \R is a roman numeral bullet, incrementing if in a list + \(123) (or any other number) converts to the associated unicode character. + \ or \<#hashtag> will place a link this point WITH itself as the text + \[URL] will RESOLVE a URL to an image (or somethign else?) and place it here + \:name: por \:{name} will place the emoji associated with 'name' + \&name; or \&{name} insert a character by a given name + \${var_value_printed_here} - see below + \?{TEST}{Optional text} - insert only if TEST is true. + + Unused symbols for insertions: ~!@%;'",/ plus lots of letters + ALSO technically unused, but less useful: ]>}) + + + Now for the crazy. We can EMBED CODE as needed. + + `{var name=value or other_code} + \${var_value_printed_here} + `?{TEST}Optional formatting -- e.g., ?{has_error}[red] or ?{important}* + \?{TEST}{Optional text} - insert only if TEST is true. + + + -+ Custom Empirical markup language, Emphatic - - * - * Internal format is .emp, which uses just a backquote (`) as a special character. It - * is otherwise heavily inspired from markdown, but makes special characters less tricky - * to use in your writing. - * - * The following tags toggle a formatting style. - * - * `*Bold!`* - * ``Code`` - * `/Italic`/ - * `_Underlined!`_ - * `^Superscript`^ - * `.Subscript`. - * `~Strikethrough`~ - * - * The following tags grab the rest of the line they are on. These should generally - * be the first non-whitespace on a line, but if they are not a newline will be assumed - * to be before them. - * - * `# Heading level 1 - * `## Heading level 2 - * `### etc. - * `" Blockquote - * `- Bulleted list entry - * `+ Numbered list entry - * `| Continues the previous line for other tags in this group. - * `% Comment that will be removed. - * - * `[Include a link name here](http://and.its.url.here) - * ` - * `![Link/to/image/here.jpg](with an optional URL link) - * - * Now for the crazy. We can embed code as needed. - * - * `{variable = value || other_code} - * `$var_value_printed_here$ - * - * Anything with four spaces at the beginning will be treated like indented code. - * Add a `= at the beginning of a line if you don't want special formatting. - * - * A single or double backtick indicates that everything in between is going to be inline - * code. A single backtick must be followed by an alphanumeric character or whitespace, - * but a double backtick can be followed by anything. - * - * `This would be rendered as CODE` - * ``{This would also be code}`` - * - * Escape characters do work. - * \\ is a regular backslash ('\') - * \` is a backtick in the actual string ('`') - * \ (backlash space) is a non-breaking space. - * \n is a newline - * \t is a tab Some saved notes: @@ -69,14 +138,14 @@ Some saved notes: // HTML: One word is bold. // MarkDown: One word is *bold*. // LaTeX: One word is \textbf{bold}. - // Emphatic: One word is `*bold`* + // MarkBack: One word is `*bold`* // // Some styles need to have arguments associated with them. For example, a heading needs // to have a level. A level 3 heading, for example, would be stored as style "heading:3". // HTML:

A level 3 heading

// MarkDown: ### A level 3 heading // LaTeX: \subsubsection{A level 3 heading} - // Emphatic: `### A level 3 heading + // MarkBack: `### A level 3 heading // // The patterns associated with these can either be broken up into multiple tags (for example, // in LaTeX it's easier to match a specific "\subsubsection{" open tag with "header:3" style), @@ -88,7 +157,7 @@ Some saved notes: // HTML: This is linked text. // MarkDown: This is [linked](http://www.exmaple.com/) text. // LaTeX: This is \href{http://www.exmaple.com/}{linked} text. - // Emphatic: This is `[linked](http://www.exmaple.com/) text. + // MarkBack: This is `[linked](http://www.exmaple.com/) text. // // For these patterns, HTML open would look like: // And it would be set to the style: "link:$0". @@ -110,6 +179,7 @@ For style replacements: // name of the font.) And for converting a pattern to a normal regex: +```cpp std::string AsRegEx() { std::string out; for (size_t i = 0; i < pattern.size(); ++i) { @@ -146,3 +216,4 @@ And for converting a pattern to a normal regex: } return out; } +``` diff --git a/include/emp/text/Text.hpp b/include/emp/text/Text.hpp index 2eeae67b13..fab8c922dc 100644 --- a/include/emp/text/Text.hpp +++ b/include/emp/text/Text.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022-23. - * - * @file Text.hpp + * @file * @brief Functionality similar to emp::String, but tracks text formatting for easy conversion. * @note Status: ALPHA * @@ -52,84 +53,31 @@ #include "../datastructs/map_utils.hpp" #include "../tools/String.hpp" +#include "_TextCharRef.hpp" + namespace emp { class Text; - // An individual proxy character from Text that is format aware. - template - class TextCharRef { - private: - using text_t = typename std::conditional::type; - text_t & text_ref; - size_t pos; - public: - TextCharRef(text_t & _ref, size_t _pos) : text_ref(_ref), pos(_pos) { } - TextCharRef(const TextCharRef & in) : text_ref(in.text_ref), pos(in.pos) { } - TextCharRef(const TextCharRef & in) : text_ref(in.text_ref), pos(in.pos) { } - ~TextCharRef() = default; - - // Set this character equal (with same inputs) as in parameter; don't change reference. - TextCharRef & operator=(const TextCharRef & in); - TextCharRef & operator=(const TextCharRef & in); - - // Set just this character; don't change style. - TextCharRef & operator=(char in); - - // Convert to a normal C++ char. - char AsChar() const; - operator char() const { return AsChar(); } - - // Comparison operators - auto operator<=>(const TextCharRef & in) const; - auto operator<=>(char in) const; - - text_t & GetText() const { return text_ref; } - size_t GetPos() const { return pos; } - emp::vector GetStyles() const; - - bool HasStyle(const String & style) const; - bool IsBold() { return HasStyle("bold"); } - bool IsCode() { return HasStyle("code"); } - bool IsItalic() { return HasStyle("italic"); } - bool IsStrike() { return HasStyle("strike"); } - bool IsSubscript() { return HasStyle("subscript"); } - bool IsSuperscript() { return HasStyle("superscript"); } - bool IsUnderline() { return HasStyle("underline"); } - - TextCharRef & SetStyle(const String & style); - TextCharRef & Bold() { return SetStyle("bold"); } - TextCharRef & Code() { return SetStyle("code"); } - TextCharRef & Italic() { return SetStyle("italic"); } - TextCharRef & Strike() { return SetStyle("strike"); } - TextCharRef & Subscript() { return SetStyle("subscript"); } - TextCharRef & Superscript() { return SetStyle("superscript"); } - TextCharRef & Underline() { return SetStyle("underline"); } + // A base class for any special encodings that should work with Text objects. + struct TextEncoding_Interface { + virtual ~TextEncoding_Interface() { } + + virtual String GetName() const = 0; // Return name of encoding. + virtual void Append(Text &, const String &) = 0; // Add new text. + virtual String Encode(const Text &) const = 0; // Output formatted text. + virtual emp::Ptr Clone() const = 0; // Copy encoding. + virtual void PrintDebug(std::ostream &) const = 0; }; - // A base class for any special encodings that should work with Text objects. - class TextEncoding_Base { - protected: - Text & text; // The emp::Text this encoding is associated with. - String name; // The name by which this encoding should be called. + class TextEncoding_None : public TextEncoding_Interface { public: - TextEncoding_Base(Text & _text, const String _name) : text(_text), name(_name) { } - virtual ~TextEncoding_Base() { } - - const String & GetName() const { return name; } - - // By default, append text assuming that there is no special formatting in it. - virtual void Append(const String & in); - - // By default, return text and ignore all formatting. - virtual String Encode() const; - - // Make a copy of this TextEncoding, including proper derived class. - virtual emp::Ptr Clone(Text & _text) const { - return emp::NewPtr(_text, name); - } - - virtual void PrintDebug(std::ostream &) const { }; + TextEncoding_None() { } + String GetName() const override { return "text"; } + void Append(Text & text, const String & in) override; + String Encode(const Text & text) const override; + emp::Ptr Clone() const override; + void PrintDebug(std::ostream & os) const override; }; class Text { @@ -143,10 +91,11 @@ namespace emp { std::unordered_map style_map; // A set of encodings that this Text object can handle. - std::map< String, emp::Ptr > encodings; - emp::Ptr encoding_ptr = nullptr; + using encoding_ptr_t = emp::Ptr; + encoding_ptr_t encoding_ptr = nullptr; + std::map encodings; - // Internal function to remove unused styles. + // Helper function to remove unused styles. void Cleanup() { // Scan for styles that are no longer unused. emp::vector unused_styles; @@ -159,30 +108,20 @@ namespace emp { } } - public: - Text() { - encodings["txt"] = NewPtr(*this, "txt"); - encoding_ptr = encodings["txt"]; - }; - Text(const Text & in) : text(in.text), style_map(in.style_map) { - for (const auto & [e_name, ptr] : encodings) { - encodings[e_name] = ptr->Clone(*this); - } - encoding_ptr = encodings[in.encoding_ptr->GetName()]; - } - Text(const String & in) { - encodings["txt"] = NewPtr(*this, "txt"); - encoding_ptr = encodings["txt"]; - Append(in); - } - ~Text() { - if (encoding_ptr != nullptr) { - for (auto & [e_name, ptr] : encodings) { - ptr.Delete(); - } + void CloneEncodings(const Text & in) { + for (const auto & [e_name, ptr] : in.encodings) { + encodings[e_name] = ptr->Clone(); + if (in.encoding_ptr == ptr) encoding_ptr = encodings[e_name]; } } + public: + Text() { encoding_ptr = encodings["txt"] = NewPtr(); } + Text(const Text & in) : text(in.text), style_map(in.style_map) { CloneEncodings(in); } + template + Text(Ts &&... in) : Text() { Append(std::forward(in)...); } + ~Text() { for (auto & [e_name, ptr] : encodings) ptr.Delete(); } + Text & operator=(const Text & in) { Text new_text(in); std::swap(*this, new_text); @@ -229,7 +168,12 @@ namespace emp { /// @brief Get the name of the current encoding being applied. /// @return Name of the current encoding. - const String & GetEncoding() const { return encoding_ptr->GetName(); } + String GetEncodingName() const { + for (const auto & [e_name, ptr] : encodings) { + if (encoding_ptr == ptr) return e_name; + } + return "Unknown"; + } /// @brief Change the current encoding being used to another known encoding type. /// @param name Name of the encoding type to be used. @@ -250,17 +194,22 @@ namespace emp { /// @brief Add an encoding to this Text object; new encodings automatically become active. /// @tparam ENCODING_T The type of the new encoding to use /// @tparam ...EXTRA_Ts Automatically set by variadic arguments. - /// @param name Name to be used for this new encoding. /// @param ...args Any extra arguments to configure this new encoding (passed to constructor) + /// @return Name of the encoding that was created. template - void AddEncoding(const String & name, EXTRA_Ts &&... args) { - emp_assert(!HasEncoding(name), name, "Trying to add a TextEncoding that already exists. To replace, use RemoveEncoding() first."); - encoding_ptr = NewPtr(*this, name, std::forward(args)...); - encodings[name] = encoding_ptr; + String AddEncoding(EXTRA_Ts &&... args) { + encoding_ptr = NewPtr(std::forward(args)...); + String encoding_name = encoding_ptr->GetName(); + emp_assert(!HasEncoding(encoding_name), encoding_name, + "Adding TextEncoding that already exists. To replace, RemoveEncoding() first."); + encodings[encoding_name] = encoding_ptr; + return encoding_name; } + /// @brief Remove an encoding with a provided name. + /// @param name Name of the encoding to remove. void RemoveEncoding(const String & name) { - emp_assert(HasEncoding(name), name, "Trying to remove a TextEncoding that does not exist."); + emp_assert(HasEncoding(name), name, "Trying to remove TextEncoding that does not exist."); if (HasEncoding(name)) { if (encoding_ptr == encodings[name]) encoding_ptr = nullptr; encodings[name].Delete(); @@ -268,27 +217,55 @@ namespace emp { } } - /// ActivateEncoding will add an encoding if (and only if) it doesn't exist already. + /// @brief Set an encoding as active, creating it if needed. + /// @tparam ENCODING_T The type of the new encoding to use + /// @tparam ...EXTRA_Ts Automatically set by variadic arguments. + /// @param name Name of the encoding that we want activated / added + /// @param ...args Any extra arguments to configure this new encoding (passed to constructor) + /// @return Name of the encoding that was created. template - void ActivateEncoding(const String & name, EXTRA_Ts &&... args) { - if (!HasEncoding(name)) { - AddEncoding(name, std::forward(args)...); - } else { - SetEncoding(name); + String ActivateEncoding(const String & name, EXTRA_Ts &&... args) { + if (HasEncoding(name)) encoding_ptr = encodings[name]; + else { + encoding_ptr = NewPtr(std::forward(args)...); + emp_assert(encoding_ptr->GetName() == name, encoding_ptr->GetName(), name, + "ActivateEncoding name does not match provided type."); + encodings[name] = encoding_ptr; } + return name; } - /// Append potentially-formatted text through the current encoding. - Text & Append(const String & in) { - encoding_ptr->Append(in); + template + Text & Append(T && in, EXTRA_Ts &&... in_extra) { + // If we have a Text object being fed in, merge it in. + using CleanT = typename std::remove_const_t>; + if constexpr (std::is_base_of_v) { + const size_t start_size = text.size(); + text += in.text; + for (auto & [style_name, new_bits] : in.style_map) { + style_map[style_name].Resize(start_size).Append(new_bits); + } + } + + // Otherwise, convert the input to a string and add it on. + else { + encoding_ptr->Append(*this, emp::MakeString(std::forward(in))); + } + + // If more than one argument was provided, process the remaining ones. + if constexpr (sizeof...(EXTRA_Ts) > 0) { + Append(std::forward(in_extra)...); + } + return *this; } /// Specify the encoding of a value being appended. template Text & AppendAs(const String & encode_name, IN_T && in) { - ActivateEncoding(encode_name); + if (!HasEncoding(encode_name)) AddEncoding(); + else SetEncoding(encode_name); Append(std::forward(in)); return *this; } @@ -301,19 +278,12 @@ namespace emp { } // Stream operator. - template - Text & operator<<(T && in) { - return Append(emp::MakeString(in)); - } - - template - Text & operator+=(T && in) { - return Append(emp::MakeString(in)); - } + template Text & operator<<(T && in) { return Append(std::forward(in)); } + template Text & operator+=(T && in) { return Append(std::forward(in)); } /// @brief Convert text to a string using the current encoding. /// @return The resulting string. - String Encode() const { return encoding_ptr->Encode(); } + String Encode() const { return encoding_ptr->Encode(*this); } void Resize(size_t new_size) { text.resize(new_size); @@ -440,17 +410,13 @@ namespace emp { /// Return the set of active styles in this text. /// @param pos optional position to specify only styles used at position. - emp::vector GetStyles(size_t pos=MAX_SIZE_T) { + emp::vector GetStyles(size_t pos=MAX_SIZE_T) const { emp::vector styles; - emp::vector to_clear; for (const auto & [name, bits] : style_map) { - if (bits.None()) to_clear.push_back(name); - else if (pos == MAX_SIZE_T || bits.Has(pos)) { + if (pos == MAX_SIZE_T || bits.Has(pos)) { styles.push_back(name); } } - for (const auto & name : to_clear) Clear(name); - return styles; } @@ -553,74 +519,15 @@ namespace emp { } }; - // Set this character equal (with same inputs) as in parameter; don't change reference. - template - TextCharRef & TextCharRef::operator=(const TextCharRef & in) { - text_ref.Set(pos, in); - return *this; - } - - template - TextCharRef & TextCharRef::operator=(const TextCharRef & in) { - static_assert(IS_CONST == false, - "Cannot assign a const TextCharRef to a mutatble version."); - text_ref.Set(pos, in); - return *this; + void TextEncoding_None::Append(Text & text, const String & in) { text.Append_Raw(in); } + String TextEncoding_None::Encode(const Text & text) const { return text; }; + emp::Ptr TextEncoding_None::Clone() const { + return emp::NewPtr(); } - - // Set just this character; don't change style. - template - TextCharRef & TextCharRef::operator=(char in) { - text_ref.Set(pos, in); - return *this; - } - - // Convert to a normal C++ char. - template - char TextCharRef::AsChar() const { - return text_ref.GetChar(pos); + void TextEncoding_None::PrintDebug(std::ostream & os) const { + os << "TextEncoding None."; } - template - auto TextCharRef::operator<=>(const TextCharRef & in) const { - return text_ref.GetChar(pos) <=> in.text_ref.GetChar(in.pos); - } - template - auto TextCharRef::operator<=>(char in) const { - return text_ref.GetChar(pos) <=> in; - } - - template - emp::vector TextCharRef::GetStyles() const { - return text_ref.GetStyles(pos); - } - - template - bool TextCharRef::HasStyle(const String & style) const { - return text_ref.HasStyle(style, pos); - } - - template - TextCharRef & TextCharRef::SetStyle(const String & style) { - text_ref.HasStyle(style, pos); - return *this; - } - - - // ------- TextEncoding_Base -------- - - // By default, append text assuming that there is no special formatting in it. - void TextEncoding_Base::Append(const String & in) { - text.Append_Raw(in); - } - - // By default, return text and ignore all formatting. - String TextEncoding_Base::Encode() const { - return text; - } - - } - #endif // #ifndef EMP_TEXT_TEXT_HPP_INCLUDE diff --git a/include/emp/text/TextEncoding.hpp b/include/emp/text/TextEncoding.hpp index 218a5911fc..d7704d4f8c 100644 --- a/include/emp/text/TextEncoding.hpp +++ b/include/emp/text/TextEncoding.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2023. - * - * @file TextEncoding.hpp + * @file * @brief Plugs into emp::Text with the specification of a given encoding. * @note Status: ALPHA * @@ -25,7 +26,7 @@ namespace emp { - class TextEncoding : public emp::TextEncoding_Base { + class TextEncoding : public emp::TextEncoding_Interface { protected: // Tags have three possible things they can do: @@ -176,7 +177,7 @@ namespace emp { // Append a string that has already been otherwise processed. - void Append_RawText(const String & in) { + void Append_RawText(Text & text, const String & in) { size_t start = text.size(); size_t end = start + in.size(); text.Append_Raw(in); @@ -185,7 +186,7 @@ namespace emp { } } - void Append_Tag(int token_id, const String & lexeme) { + void Append_Tag(Text & text, int token_id, const String & lexeme) { Tag & tag = tag_set[ token_to_tag_id[token_id] ]; // If this token might END a style, search for options. @@ -232,7 +233,7 @@ namespace emp { text_token = lexer.AddToken("plain text", "."); } - void _EncodeChar(String & out_string, const size_t char_pos) const { + void _EncodeChar(const Text & text, String & out_string, const size_t char_pos) const { const char c = text.GetChar(char_pos); // If there is a tag associated with this character AND the associated type (if any) use tag. if (char_tags[c]) { @@ -246,16 +247,15 @@ namespace emp { } } - void _EncodeTo(String & out_string, size_t & start, const size_t end) const { + void _EncodeTo(const Text & text, String & out_string, size_t & start, const size_t end) const { while (start < end) { - _EncodeChar(out_string, start); + _EncodeChar(text, out_string, start); ++start; } } public: - TextEncoding(Text & _text, const String & _name="html") - : TextEncoding_Base(_text, _name) { + TextEncoding() : TextEncoding_Interface() { Tag default_tag; default_tag.name = "__default_tag__"; default_tag.id = 0; @@ -270,22 +270,35 @@ namespace emp { } ~TextEncoding() = default; + // Reset the current encoding to clear all tag knowledge for this encoding. + void Reset() { + tag_set.resize(1); // Reduce down to just the default tag. + style_set.resize(0); // Reduce down to just the default style. + char_tags.fill(0); // Clear all character tags. + pattern_to_tag_id.clear(); // Remove all references to tags + token_to_tag_id.clear(); + name_to_style_id.size(); + active_styles.resize(0); // All active styles turn off on changing encodings. + text_token = -1; // Allow the lexer to reset. + lexer.Reset(); + } + // Add new text into this object, translated as needed - void Append(const String & in) override { + void Append(Text & text, const String & in) override { SetupLexer(); - auto tokens = lexer.Tokenize(in.cpp_str()); + auto tokens = lexer.Tokenize(in.str()); String raw_text; // Place to accumulate raw text. for (const auto & token : tokens) { if (token.id == text_token) raw_text += token.lexeme; else { - if (raw_text.size()) Append_RawText(raw_text.PopAll()); - Append_Tag(token.id, token.lexeme); + if (raw_text.size()) Append_RawText(text, raw_text.PopAll()); + Append_Tag(text, token.id, token.lexeme); } } - if (raw_text.size()) Append_RawText(raw_text.PopAll()); + if (raw_text.size()) Append_RawText(text, raw_text.PopAll()); } - String Encode() const override { + String Encode(const Text & text) const override { // Determine where tags should be placed. std::map tag_map; emp::vector style_list = text.GetStyles(); @@ -293,17 +306,18 @@ namespace emp { String style_name = style_desc.Pop(":"); const Style & style = style_set[ emp::Find(name_to_style_id, style_name, 0) ]; if (!style.make_open_tag) continue; // If no tags are available, assume a replacement style. - AddOutputTags(tag_map, style_name, style.make_open_tag(style_desc), style.make_close_tag(style_desc)); + AddOutputTags(text, tag_map, style_name, + style.make_open_tag(style_desc), style.make_close_tag(style_desc)); } // Convert the string, adding tags back in as we go. String out_string; size_t output_pos = 0; for (auto [tag_pos, tags] : tag_map) { - _EncodeTo(out_string, output_pos, tag_pos); + _EncodeTo(text, out_string, output_pos, tag_pos); out_string += tags; } - _EncodeTo(out_string, output_pos, text.size()); // Add final text after the last tag. + _EncodeTo(text, out_string, output_pos, text.size()); // Add final text after the last tag. return out_string; } @@ -325,6 +339,7 @@ namespace emp { // A helper to add start and end tag info to tag map for insertion into // the output string as it's created. void AddOutputTags( + const Text & text, std::map & tag_map, String style, String start_tag, @@ -348,6 +363,37 @@ namespace emp { } }; + template + emp::Text MakeEncodedText(Ts &&... args) { + Text out; // Create the text object + out.AddEncoding(); // Setup the encoding + out.Append(std::forward(args)...); // Append the inputs, if any + return out; // Return the finished product + } + + template + class EncodedText : public emp::Text { + private: + using this_t = EncodedText; + public: + /// @brief Create a new, default EncodedText object. + EncodedText() { AddEncoding(); }; + EncodedText(const this_t & in) = default; + + template + EncodedText(Ts &&... in) : EncodedText() { + Append(std::forward(in)...); + } + + this_t & operator=(const this_t &) = default; + this_t & operator=(this_t &&) = default; + template + this_t & operator=(T && in) { + Text::operator=(std::forward(in)); + return *this; + }; + }; + } #endif // #ifndef EMP_TEXT_TEXTENCODING_HPP_INCLUDE diff --git a/include/emp/text/_TextCharRef.hpp b/include/emp/text/_TextCharRef.hpp new file mode 100644 index 0000000000..820ffe7b1a --- /dev/null +++ b/include/emp/text/_TextCharRef.hpp @@ -0,0 +1,89 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + * @brief Handles a single, potentially formatted character from emp::Text. + * @note Status: ALPHA + * + */ + +#ifndef EMP_TEXT__TEXTCHARREF_HPP_INCLUDE +#define EMP_TEXT__TEXTCHARREF_HPP_INCLUDE + +#include // std::conditional + +#include "../base/assert.hpp" +#include "../base/notify.hpp" +#include "../tools/String.hpp" + +namespace emp { + + class Text; + + // An individual proxy character from Text that is format aware. + template + class TextCharRef { + private: + using text_t = typename std::conditional::type; + text_t & text_ref; + size_t pos; + public: + TextCharRef(text_t & _ref, size_t _pos) : text_ref(_ref), pos(_pos) { } + TextCharRef(const TextCharRef & in) : text_ref(in.text_ref), pos(in.pos) { } + TextCharRef(const TextCharRef & in) : text_ref(in.text_ref), pos(in.pos) { } + ~TextCharRef() = default; + + // Set this character equal (with same inputs) as in parameter; don't change reference. + TextCharRef & operator=(const TextCharRef & in) { text_ref.Set(pos, in); return *this; } + TextCharRef & operator=(const TextCharRef & in) { + static_assert(!IS_CONST, "Cannot assign a const TextCharRef to a mutatble version."); + text_ref.Set(pos, in); + return *this; + } + + // Set just this character; don't change style. + TextCharRef & operator=(char in) { text_ref.Set(pos, in); return *this; } + + // Convert to a normal C++ char. + char AsChar() const { return text_ref.GetChar(pos); } + operator char() const { return AsChar(); } + + // Comparison operators + auto operator<=>(const TextCharRef & in) const { + return text_ref.GetChar(pos) <=> in.text_ref.GetChar(in.pos); + } + auto operator<=>(char in) const { + return text_ref.GetChar(pos) <=> in; + } + + text_t & GetText() const { return text_ref; } + size_t GetPos() const { return pos; } + emp::vector GetStyles() const { return text_ref.GetStyles(pos); } + + bool HasStyle(const String & style) const { return text_ref.HasStyle(style, pos); } + bool IsBold() const { return HasStyle("bold"); } + bool IsCode() const { return HasStyle("code"); } + bool IsItalic() const { return HasStyle("italic"); } + bool IsStrike() const { return HasStyle("strike"); } + bool IsSubscript() const { return HasStyle("subscript"); } + bool IsSuperscript() const { return HasStyle("superscript"); } + bool IsUnderline() const { return HasStyle("underline"); } + + TextCharRef & SetStyle(const String & style) { + text_ref.SetStyle(style, pos); + return *this; + } + TextCharRef & Bold() { return SetStyle("bold"); } + TextCharRef & Code() { return SetStyle("code"); } + TextCharRef & Italic() { return SetStyle("italic"); } + TextCharRef & Strike() { return SetStyle("strike"); } + TextCharRef & Subscript() { return SetStyle("subscript"); } + TextCharRef & Superscript() { return SetStyle("superscript"); } + TextCharRef & Underline() { return SetStyle("underline"); } + }; +} + +#endif // #ifndef EMP_TEXT__TEXTCHARREF_HPP_INCLUDE diff --git a/include/emp/tools/MemoryFactory.hpp b/include/emp/tools/MemoryFactory.hpp index f2ba5d9909..b17b7a587c 100644 --- a/include/emp/tools/MemoryFactory.hpp +++ b/include/emp/tools/MemoryFactory.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file MemoryFactory.hpp + * @file * @brief Recycles memory of a given size rather than continuously re-allocating. * @note Status: ALPHA * diff --git a/include/emp/tools/SolveState.hpp b/include/emp/tools/SolveState.hpp index 933107a75e..346fe4a212 100644 --- a/include/emp/tools/SolveState.hpp +++ b/include/emp/tools/SolveState.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021. - * - * @file SolveState.hpp + * @file * @brief Used as part of a branching solver to keep track of the current state. * @note Status: BETA */ @@ -11,9 +12,9 @@ #ifndef EMP_TOOLS_SOLVESTATE_HPP_INCLUDE #define EMP_TOOLS_SOLVESTATE_HPP_INCLUDE +#include #include "../base/assert.hpp" - #include "../bits/BitVector.hpp" namespace emp { @@ -56,7 +57,7 @@ namespace emp { /// Test if a particular item is going to be excluded for sure in the current solve state. /// (If it has been included -OR- is yet to be decided upon, false will be returned) - bool IsOut(size_t id) const { return !(IsIn(id) | IsUnk(id)); } + bool IsOut(size_t id) const { return !(IsIn(id) || IsUnk(id)); } /// Test if all items have been decided upon (none are still in the "unknown" state) bool IsFinal() const { return unk_items.None(); } diff --git a/include/emp/tools/ShortString.hpp b/include/emp/tools/StaticString.hpp similarity index 58% rename from include/emp/tools/ShortString.hpp rename to include/emp/tools/StaticString.hpp index ff5c8dcb75..8d73a45107 100644 --- a/include/emp/tools/ShortString.hpp +++ b/include/emp/tools/StaticString.hpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file ShortString.hpp - * @brief String substitute with a max of 31 characters and always in place. + * @file + * @brief String substitute with a fixed max character count and always in place. * @note Status: ALPHA * * A fixed number of chars are reserved for the string; errors will trigger for longer attempts. @@ -13,8 +14,8 @@ * */ -#ifndef EMP_TOOLS_SHORTSTRING_HPP_INCLUDE -#define EMP_TOOLS_SHORTSTRING_HPP_INCLUDE +#ifndef EMP_TOOLS_STATICSTRING_HPP_INCLUDE +#define EMP_TOOLS_STATICSTRING_HPP_INCLUDE #include #include @@ -25,42 +26,43 @@ namespace emp { - template + template class StaticString { private: - static_assert(NUM_BYTES <= 256, "Static String currently limited to 256 bytes (255 chars)."); - static constexpr const size_t MAX_CHARS = NUM_BYTES - 1; - static constexpr const size_t SIZE_POS = NUM_BYTES - 1; // Size info stored in the last byte. - - emp::array string; + static_assert(NUM_CHARS > 0, "StaticString must have at least one char available"); + static_assert(NUM_CHARS <= 65536, "StaticString size limited to 2 bytes (65536 chars)."); + static constexpr const size_t MAX_CHARS = NUM_CHARS - 1; // Save space for final '\0' - CHAR_T & SizeByte() { return string[SIZE_POS]; } - CHAR_T SizeByte() const { return string[SIZE_POS]; } + emp::array string; + using ss_size_t = std::conditional_t<(NUM_CHARS <= 256), uint8_t, uint16_t>; + ss_size_t str_size = 0; StaticString & CopyFrom(const CHAR_T * in, size_t len) { + emp_assert(len <= MAX_CHARS, len, MAX_CHARS); resize(len); memcpy(string.data(), in, len); + string[len] = '\0'; return *this; } // Compare this string to another. // -1 means this is less, 0 means they are the same, +1 means this is greater. int Compare(const CHAR_T * in, size_t len) const { - size_t min_len = std::min(len, size()); + size_t min_len = std::min(len, str_size); for (size_t i = 0; i < min_len; ++i) { if (string[i] != in[i]) { if (string[i] < in[i]) return -1; return 1; } } - if (size() != len) { - if (size() < len) return -1; + if (str_size != len) { + if (str_size < len) return -1; return 1; } return 0; } public: - StaticString() { string[0] = '\0'; SizeByte() = MAX_CHARS; } + StaticString() : str_size(0) { string[0] = '\0'; } StaticString(const StaticString &) = default; StaticString(const std::string & in) { CopyFrom(in.data(), in.size()); } StaticString(CHAR_T const * in) { CopyFrom(in, strlen(in)); } @@ -74,23 +76,30 @@ namespace emp { CHAR_T * data() { return string.data(); } const CHAR_T * data() const { return string.data(); } - size_t size() const { return MAX_CHARS - SizeByte(); } + size_t size() const { return str_size; } void resize(size_t new_size) { emp_assert(new_size <= MAX_CHARS); - SizeByte() = MAX_CHARS - new_size; + str_size = new_size; string[new_size] = '\0'; } + void resize(size_t new_size, CHAR_T filler) { + emp_assert(new_size <= MAX_CHARS); + for (size_t i = str_size; i < new_size; ++i) string[i] = filler; + resize(new_size); + } + CHAR_T & operator[](size_t id) { - emp_assert(id < size()); + emp_assert(id < str_size); return string[id]; } CHAR_T operator[](size_t id) const { - emp_assert(id < size()); + emp_assert(id < str_size); return string[id]; } + // Comparisons template bool operator==(const T & in) const { return Compare(in.data(), in.size()) == 0; } template bool operator!=(const T & in) const { return Compare(in.data(), in.size()) != 0; } @@ -106,15 +115,48 @@ namespace emp { bool operator> (CHAR_T const * in) const { return Compare(in, strlen(in)) > 0; } bool operator>=(CHAR_T const * in) const { return Compare(in, strlen(in)) >= 0; } + // Type conversions operator CHAR_T *() { return string.data(); } operator const CHAR_T *() const { return string.data(); } operator std::string() const { return std::string(string.data()); } std::string AsString() const { return string.data(); } + + // Manipulations + StaticString & push_back(CHAR_T c) { + assert(str_size < MAX_CHARS); + string[str_size++] = c; + string[str_size] = '\0'; + return *this; + } + + StaticString & append(const CHAR_T * in_str, size_t len) { + assert(str_size + len <= MAX_CHARS); + memcpy(string.data()+str_size, in_str, len); + str_size += len; // Update the string size. + string[str_size] = '\0'; // Make sure ends in '\0' + + return *this; + } + + StaticString & append(const std::string & in_str) { + return append(in_str.data(), in_str.size()); + } + + template + StaticString & append(CHAR_T in_str[SIZE]) { + return append(in_str, SIZE); + } + + template + StaticString & append(StaticString in_str) { + return append(in_str.data(), in_str.size()); + } + }; - using ShortString = emp::StaticString<32>; + using ShortString = emp::StaticString<31>; } -#endif // #ifndef EMP_TOOLS_SHORTSTRING_HPP_INCLUDE +#endif // #ifndef EMP_TOOLS_STATICSTRING_HPP_INCLUDE diff --git a/include/emp/tools/String.hpp b/include/emp/tools/String.hpp index d9921f819c..04f4fca457 100644 --- a/include/emp/tools/String.hpp +++ b/include/emp/tools/String.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2023. - * - * @file String.hpp + * @file * @brief Simple class to facilitate string manipulations * @note Status: ALPHA * @@ -19,117 +20,119 @@ #ifndef EMP_TOOLS_STRING_HPP_INCLUDE #define EMP_TOOLS_STRING_HPP_INCLUDE -#include -#include -#include -#include +#include // std::count +#include // std::toupper and std::tolower +#include // std::function #include -#include -#include -#include -#include #include -#include -#include -#include #include #include #include -#include -#include "../base/array.hpp" #include "../base/assert.hpp" #include "../base/notify.hpp" -#include "../base/Ptr.hpp" #include "../base/vector.hpp" -#include "../meta/reflection.hpp" -#include "../meta/type_traits.hpp" +#include "../meta/type_traits.hpp" // emp::IsIterable() + +#include "char_utils.hpp" // emp::CharSet (+ functions) +#include "_StringSyntax.hpp" -#include "char_utils.hpp" namespace emp { class String; // Some stand-alone functions to generate String objects. - template [[nodiscard]] emp::String MakeString(Ts... args); - [[nodiscard]] emp::String MakeEscaped(char c); - [[nodiscard]] emp::String MakeEscaped(const emp::String & in); - [[nodiscard]] emp::String MakeWebSafe(const emp::String & in); - [[nodiscard]] emp::String MakeLiteral(char value); - [[nodiscard]] emp::String MakeLiteral(char value); - template [[nodiscard]] emp::String MakeLiteral(const T & value); - [[nodiscard]] emp::String MakeUpper(const emp::String & in); - [[nodiscard]] emp::String MakeLower(const emp::String & in); - [[nodiscard]] emp::String MakeTitleCase(emp::String in); - [[nodiscard]] emp::String MakeRoman(int val); + template [[nodiscard]] inline String MakeString(Ts &&... args); + [[nodiscard]] inline const String & MakeString(const String & in) { return in; }; + [[nodiscard]] inline String MakeEscaped(char c); + [[nodiscard]] inline String MakeEscaped(const String & in); + [[nodiscard]] inline String MakeCSVSafe(const String & in); + [[nodiscard]] inline String MakeWebSafe(const String & in); + [[nodiscard]] inline String MakeLiteral(char value); + [[nodiscard]] inline String MakeLiteral(const std::string & value); + template [[nodiscard]] inline String MakeLiteral(const T & value); + [[nodiscard]] inline char MakeFromLiteral_Char(const String & value); + [[nodiscard]] inline String MakeFromLiteral_String(const String & value); + template [[nodiscard]] inline T MakeFromLiteral(const String & value); + [[nodiscard]] inline String MakeUpper(const String & in); + [[nodiscard]] inline String MakeLower(const String & in); + [[nodiscard]] inline String MakeTitleCase(String in); + [[nodiscard]] inline String MakeCount(int val, String item, const String & plural_suffix); + [[nodiscard]] inline String MakeRoman(int val); template - [[nodiscard]] emp::String MakeEnglishList(const CONTAINER_T & container); + [[nodiscard]] inline String MakeEnglishList(const CONTAINER_T & container); template - [[nodiscard]] emp::String MakeFormatted(const emp::String& format, Args... args); + [[nodiscard]] inline String MakeFormatted(const String& format, Args... args); + [[nodiscard]] inline String MakeRepeat(String base, size_t n); + + [[nodiscard]] inline String MakeTrimFront(const String & in, const CharSet & chars=WhitespaceCharSet()); + [[nodiscard]] inline String MakeTrimBack(const String & in, const CharSet & chars=WhitespaceCharSet()); + [[nodiscard]] inline String MakeTrimmed(String in, const CharSet & chars=WhitespaceCharSet()); + [[nodiscard]] inline String MakeCompressed( + String in, const CharSet & chars=WhitespaceCharSet(), char compress_to=' ', + bool trim_start=true, bool trim_end=true); + [[nodiscard]] inline String MakeRemoveChars(String in, const CharSet & chars); + [[nodiscard]] inline String MakeSlugify(String in); template - [[nodiscard]] emp::String Join(const CONTAINER_T & container, std::string join_str="", - std::string open="", std::string close=""); + [[nodiscard]] inline String Join(const CONTAINER_T & container, std::string join_str="", + std::string open="", std::string close=""); - // ToString specialization for emp::String - const emp::String & ToString(const emp::String & in) { return in; } - - class String { + class String : public std::string { private: - std::string str; // The main string that we are manipulating. + using Syntax = StringSyntax; - enum Mask { - USE_QUOTE_SINGLE= 1, USE_QUOTE_DOUBLE= 2, USE_QUOTE_BACK = 4, USE_PAREN_ROUND = 8, - USE_PAREN_SQUARE=0x10, USE_PAREN_CURLY =0x20, USE_PAREN_ANGLE=0x40, USE_PAREN_QUOTES = 0x80 - }; + static char & NoChar() { static char no_char = '\0'; return no_char; } - struct Mode { - uint8_t val = USE_QUOTE_SINGLE + USE_QUOTE_DOUBLE + - USE_PAREN_ROUND + USE_PAREN_SQUARE + USE_PAREN_CURLY; - void Set(Mask mask, bool use) { if (use) val |= mask; else val &= ~mask; } - } mode; + // _ToString specializations + [[nodiscard]] static const String & _ToString(const String & in) { return in; } + template [[nodiscard]] static String _ToString(const std::vector & in) + { return String("{") + Join(in, ",") + '}'; } + template [[nodiscard]] static String _ToString(T && in) + { std::stringstream ss; ss << std::forward(in); return ss.str(); } // Convert objects into a streamable type using _Convert(obj) - template static decltype(std::declval().ToString()) _Convert(const T & in, bool) { return in.ToString(); } - template static auto _Convert(const T & in, int) -> decltype(emp::ToString(in)) { return emp::ToString(in); } - template static const T & _Convert(const T & in, ...) { return in; } + template static decltype(std::declval()._ToString()) _Convert(const T & in, bool) { return in._ToString(); } + template static auto _Convert(const T & in, int) -> decltype(_ToString(in)) { return _ToString(in); } - void _AssertPos([[maybe_unused]] size_t pos) const - { emp_assert(pos < str.size(), pos, str.size()); } + // Quick check to ensure a position is legal. + void _AssertPos([[maybe_unused]] size_t pos) const { emp_assert(pos < size(), pos, size()); } + + // Retrieve an iterator for a given position. + auto _Iterator(size_t pos) const { + _AssertPos(pos); + return begin() + static_cast(pos); + } public: - using value_type = std::string::value_type; - using allocator_type = std::string::allocator_type; - using size_type = std::string::size_type; - using difference_type = std::string::difference_type; - using reference = std::string::reference; - using const_reference = std::string::const_reference; - using pointer = std::string::pointer; - using const_pointer = std::string::const_pointer; - using iterator = std::string::iterator; - using const_iterator = std::string::const_iterator; - using reverse_iterator = std::string::reverse_iterator; - using const_reverse_iterator = std::string::const_reverse_iterator; - - static constexpr size_t npos = std::string::npos; + using std::string::value_type; + using std::string::allocator_type; + using std::string::size_type; + using std::string::difference_type; + using std::string::reference; + using std::string::const_reference; + using std::string::pointer; + using std::string::const_pointer; + using std::string::iterator; + using std::string::const_iterator; + using std::string::reverse_iterator; + using std::string::const_reverse_iterator; // Constructors duplicating from std::string String() = default; - String(const std::string & _str) : str(_str) { } - String(std::string && _str) : str(std::move(_str)) { } - String(const std::string & _str, Mode _mode) : str(_str), mode(_mode) { } - String(std::string && _str, Mode _mode) : str(std::move(_str)), mode(_mode) { } - String(const char * _str) : str(_str) { } - String(size_t count, char _str) : str(count, _str) { } - String(std::initializer_list _str) : str(_str) { } + String(const std::string & _str) : std::string(_str) { } + String(std::string && _str) : std::string(std::move(_str)) { } + String(const char * _str) : std::string(_str) { } + String(size_t count, char _str) : std::string(count, _str) { } + String(std::initializer_list _str) : std::string(_str) { } String(const String & _str, size_t start, size_t count=npos) - : str(_str.str, start, count), mode(_str.mode) { } + : std::string(_str, start, count) { } String(const std::string & _str, size_t start, size_t count=npos) - : str(_str, start, count) { } - String(const char * _str, size_t count) : str(_str, count) { } + : std::string(_str, start, count) { } + String(const char * _str, size_t count) : std::string(_str, count) { } template< class InputIt > - String(InputIt first, InputIt last) : str(first, last) { } + String(InputIt first, InputIt last) : std::string(first, last) { } String(std::nullptr_t) = delete; // ------ New constructors ------ @@ -139,14 +142,14 @@ namespace emp { // Allow a string to be transformed during construction, 1-to-1 String(const std::string & _str, std::function transform_fun) { - str.reserve(_str.size()); // Setup expected size. - for (auto & c : _str) { str.push_back(transform_fun(c)); } + reserve(_str.size()); // Setup expected size. + for (auto & c : _str) { push_back(transform_fun(c)); } } // Allow a string to be transformed during construction, 1-to-any - String(const std::string & _str, std::function transform_fun) { - str.reserve(_str.size()); // Setup expected size; assume size will be 1-to-1 by default. - for (auto & c : _str) { str += transform_fun(c).str; } + String(const std::string & _str, std::function transform_fun) { + reserve(_str.size()); // Setup expected size; assume size will be 1-to-1 by default. + for (auto & c : _str) { append(transform_fun(c)); } } @@ -154,526 +157,579 @@ namespace emp { String & operator=(const String &) = default; String & operator=(String &&) = default; - String & operator=(const std::string & _in) { str = _in; return *this; } - String & operator=(std::string && _in) { str = std::move(_in); return *this; } - String & operator=(const char * _in) { str = _in; return *this; } - String & operator=(char _in) { str = _in; return *this; } - String & operator=(std::initializer_list _in) { str = _in; return *this; } - String & operator=( std::nullptr_t ) = delete; + String & operator=(const std::string & _in) { std::string::operator=(_in); return *this; } + String & operator=(std::string && _in) { std::string::operator=(std::move(_in)); return *this; } + String & operator=(const char * _in) { std::string::operator=(_in); return *this; } + String & operator=(char _in) { std::string::operator=(_in); return *this; } + String & operator=(std::string_view _in) { std::string::operator=(_in); return *this; } + String & operator=(std::initializer_list _in) { std::string::operator=(_in); return *this; } + String & operator=(std::nullptr_t) = delete; template - String & assign(ARG_Ts &&... args) { - return str.assign(std::forward(args)...); - } - - // ------ Converters ------ + String & assign(ARG_Ts &&... args) + { std::string::assign(std::forward(args)...); return *this; } - operator std::string &() { return str; } - operator const std::string &() const { return str; } - - // ------ Mode Handlers ------ - [[nodiscard]] inline bool IsQuote(char c) const; - [[nodiscard]] inline bool IsParen(char c) const; - [[nodiscard]] inline static char GetMatch(char c); + // ------ Static Values ------ + [[nodiscard]] static const String & Empty() { static String empty=""; return empty; } // ------ Element Access ------ - - [[nodiscard]] char & operator[](size_t pos) { _AssertPos(pos); return str[pos]; } - [[nodiscard]] char operator[](size_t pos) const { _AssertPos(pos); return str[pos]; } - [[nodiscard]] char & front() { _AssertPos(0); return str.front(); } - [[nodiscard]] char front() const { _AssertPos(0); return str.front(); } - [[nodiscard]] char & back() { _AssertPos(0); return str.back(); } - [[nodiscard]] char back() const { _AssertPos(0); return str.back(); } - [[nodiscard]] char * data() { return str.data(); } - [[nodiscard]] const char * data() const { return str.data(); } - [[nodiscard]] const char * c_str() const { return str.c_str(); } - [[nodiscard]] std::string & cpp_str() { return str; } - [[nodiscard]] const std::string & cpp_str() const { return str; } + // Inherited functions from std::string: + // char * data(); + // const char * data() const; + // const char * c_str() const; + std::string & str() { return *this; } + const std::string & str() const { return *this; } + + [[nodiscard]] char & operator[](size_t pos) + { _AssertPos(pos); return std::string::operator[](pos); } + [[nodiscard]] char operator[](size_t pos) const + { _AssertPos(pos); return std::string::operator[](pos); } + [[nodiscard]] char & front() { _AssertPos(0); return std::string::front(); } + [[nodiscard]] char front() const { _AssertPos(0); return std::string::front(); } + [[nodiscard]] char & back() { _AssertPos(0); return std::string::back(); } + [[nodiscard]] char back() const { _AssertPos(0); return std::string::back(); } + [[nodiscard]] char & Get(size_t pos) { return (pos < size()) ? operator[](pos) : NoChar(); } + [[nodiscard]] char Get(size_t pos) const { return (pos < size()) ? operator[](pos) : '\0'; } [[nodiscard]] String substr(size_t pos=0, size_t count=npos ) const - { return String(str.substr(pos, count), mode); } + { _AssertPos(pos); return std::string::substr(pos, count); } [[nodiscard]] String GetRange(std::size_t start_pos, std::size_t end_pos) const - { return substr(start_pos, end_pos - start_pos); } + { return std::string::substr(start_pos, end_pos - start_pos); } [[nodiscard]] std::string_view View(size_t start=0, size_t out_size=npos) const { - emp_assert(start + npos <= str.size()); - return std::string_view(str.data()+start, out_size); + if (start == npos) start = size(); // Can occur w/failed find; return empty end. + if (out_size == npos) out_size = size() - start; // npos size => View to end. + emp_assert(start + out_size <= size()); + return std::string_view(data()+start, out_size); } [[nodiscard]] std::string_view ViewFront(size_t out_size) const { return View(0, out_size); } [[nodiscard]] std::string_view ViewBack(size_t out_size) const - { emp_assert(out_size <= str.size()); return View(str.size()-out_size, out_size); } + { emp_assert(out_size <= size()); return View(size()-out_size, out_size); } [[nodiscard]] std::string_view ViewRange(size_t start, size_t end) const { - emp_assert(start <= end && end <= str.size()); + emp_assert(start <= end && end <= size(), start, end, size()); return View(start, end - start); } + [[nodiscard]] std::string_view ViewTo(CharSet stop_chars, size_t start=0, + const Syntax & syntax=Syntax::None()) const + { return ViewFront(Find(stop_chars, start, syntax)); } + [[nodiscard]] std::string_view ViewBackTo(CharSet stop_chars, size_t start=npos, + const Syntax & syntax=Syntax::None()) const + { return View(RFind(stop_chars, start, syntax)); } + [[nodiscard]] std::string_view ViewWord(const Syntax & syntax=Syntax::Quotes(), size_t start=0) const + { return ViewTo(" \n\t\r", start, syntax); } + [[nodiscard]] std::string_view ViewLine(const Syntax & syntax=Syntax::Quotes(), size_t start=0) const + { return ViewTo("\n", start, syntax); } // ------ Iterators ------ - - iterator begin() { return str.begin(); } - const_iterator begin() const { return str.begin(); } - const_iterator cbegin() const { return str.cbegin(); } - reverse_iterator rbegin() { return str.rbegin(); } - const_reverse_iterator rbegin() const { return str.rbegin(); } - const_reverse_iterator crbegin() const { return str.crbegin(); } - - iterator end() { return str.end(); } - const_iterator end() const { return str.end(); } - const_iterator cend() const { return str.cend(); } - reverse_iterator rend() { return str.rend(); } - const_reverse_iterator rend() const { return str.rend(); } - const_reverse_iterator crend() const { return str.crend(); } + // Inherited functions from std::string: + // iterator begin(); + // const_iterator begin() const; + // const_iterator cbegin() const; + // reverse_iterator rbegin(); + // const_reverse_iterator rbegin() const; + // const_reverse_iterator crbegin() const; + // iterator end(); + // const_iterator end() const; + // const_iterator cend() const; + // reverse_iterator rend(); + // const_reverse_iterator rend() const; + // const_reverse_iterator crend() const; // ------ Capacity ------ - - [[nodiscard]] bool empty() const { return str.empty(); } - [[nodiscard]] size_t size() const { return str.size(); } - [[nodiscard]] size_t length() const { return str.length(); } - [[nodiscard]] size_t max_size() const { return str.max_size(); } - [[nodiscard]] size_t capacity() const { return str.capacity(); } - void reserve(size_t new_cap) { str.reserve(new_cap); } - void shrink_to_fit() { str.shrink_to_fit(); } + // Inherited functions from std::string: + // bool empty() const; + // size_t size() const; + // size_t length() const; + // size_t max_size() const; + // size_t capacity() const; + // void reserve(size_t new_cap); + // void shrink_to_fit(); // ------ Classification and Comparisons ------ + // Inherited functions from std::string: + // int compare(...); + // bool starts_with(...) const noexcept; + // bool ends_with(...) const noexcept; + // bool contains(...) const noexcept; - [[nodiscard]] int compare(const String & in) { return str.compare(in.str); } - template [[nodiscard]] int compare(ARG_Ts &&... args) - { return str.compare(std::forward(args)...); } - - [[nodiscard]] bool starts_with(const String & in) const noexcept { return str.starts_with(in.str); } - template [[nodiscard]] bool starts_with( ARG_T && in ) const noexcept - { return str.starts_with(std::forward(in)); } + [[nodiscard]] bool HasAt(const String test, size_t pos) const + { return (size() < test.size()+pos) && View(pos, test.size()) == test; } + [[nodiscard]] bool HasPrefix(const String & prefix) const { return starts_with(prefix); } + [[nodiscard]] bool HasSuffix(const String & suffix) const { return ends_with(suffix); } - [[nodiscard]] bool ends_with(const String & in) const noexcept { return str.ends_with(in.str); } - template [[nodiscard]] bool ends_with( ARG_T && in ) const noexcept - { return str.ends_with(std::forward(in)); } - - [[nodiscard]] bool contains(const String & in) const noexcept { return str.find(in.str) != npos; } - template [[nodiscard]] bool contains( ARG_T && in ) const noexcept - { return str.find(std::forward(in)) != npos; } - - [[nodiscard]] bool HasAt(const emp::String test, size_t pos) const - { return (size() < test.size()+pos) && View(pos, test.size()) == test.str; } - [[nodiscard]] bool HasPrefix(const emp::String & prefix) const { return starts_with(prefix); } - [[nodiscard]] bool HasSuffix(const emp::String & suffix) const { return ends_with(suffix); } + size_t Hash() const noexcept { return std::hash{}(*this); } // ------ Simple Analysis ------ // Count the number of occurrences of a specific character. [[nodiscard]] size_t Count(char c, size_t start=0) const - { return (size_t) std::count(str.begin()+start, str.end(), c); } + { return (size_t) std::count(_Iterator(start), end(), c); } // Count the number of occurrences of a specific character within a range. [[nodiscard]] size_t Count(char c, size_t start, size_t end) const - { return (size_t) std::count(str.begin()+start, str.begin()+end, c); } + { return (size_t) std::count(_Iterator(start), _Iterator(end), c); } /// Test if an string is formatted as a literal character. - [[nodiscard]] bool IsLiteralChar() const; + [[nodiscard]] inline bool IsLiteralChar() const; /// Test if an string is formatted as a literal string. - [[nodiscard]] bool IsLiteralString(const std::string & quote_marks="\"") const; + [[nodiscard]] inline bool IsLiteralString(const String & quote_marks="\"") const; /// Explain what string is NOT formatted as a literal string. - [[nodiscard]] std::string DiagnoseLiteralString(const std::string & quote_marks="\"") const; + [[nodiscard]] inline String DiagnoseLiteralString(const String & quote_marks="\"") const; /// Is string composed only of a set of characters (can be provided as a string) - [[nodiscard]] bool IsComposedOf(emp::CharSet char_set) const { return char_set.Has(str); } + [[nodiscard]] bool IsComposedOf(CharSet char_set) const { return char_set.Has(*this); } /// Is string a valid number (int, floating point, or scientific notation all valid) - [[nodiscard]] bool IsNumber() const; + [[nodiscard]] inline bool IsNumber() const; /// Is string a valid identifier? At least one char; cannot begin with digit, only letters, digits and `_` [[nodiscard]] bool IsIdentifier() const - { return str.size() && !is_digit(str[0]) && IDCharSet().Has(str); } - - [[nodiscard]] bool OnlyLower() const { return LowerCharSet().Has(str); } - [[nodiscard]] bool OnlyUpper() const { return UpperCharSet().Has(str); } - [[nodiscard]] bool OnlyDigits() const { return DigitCharSet().Has(str); } - [[nodiscard]] bool OnlyAlphanumeric() const { return AlphanumericCharSet().Has(str); } - [[nodiscard]] bool OnlyWhitespace() const { return WhitespaceCharSet().Has(str); } - - [[nodiscard]] bool HasOneOf(emp::CharSet char_set) const { return char_set.HasAny(str); } - [[nodiscard]] bool HasWhitespace() const { return WhitespaceCharSet().HasAny(str); } - [[nodiscard]] bool HasNonwhitespace() const { return !WhitespaceCharSet().HasOnly(str); } - [[nodiscard]] bool HasUpper() const { return UpperCharSet().HasAny(str); } - [[nodiscard]] bool HasLower() const { return LowerCharSet().HasAny(str); } - [[nodiscard]] bool HasLetter() const { return LetterCharSet().HasAny(str); } - [[nodiscard]] bool HasDigit() const { return DigitCharSet().HasAny(str); } - [[nodiscard]] bool HasAlphanumeric() const { return AlphanumericCharSet().HasAny(str); } + { return size() && !is_digit(Get(0)) && IDCharSet().Has(*this); } + + [[nodiscard]] bool OnlyLower() const { return LowerCharSet().Has(*this); } + [[nodiscard]] bool OnlyUpper() const { return UpperCharSet().Has(*this); } + [[nodiscard]] bool OnlyDigits() const { return DigitCharSet().Has(*this); } + [[nodiscard]] bool OnlyAlphanumeric() const { return AlphanumericCharSet().Has(*this); } + [[nodiscard]] bool OnlyWhitespace() const { return WhitespaceCharSet().Has(*this); } + + [[nodiscard]] bool HasOneOf(CharSet char_set) const { return char_set.HasAny(*this); } + [[nodiscard]] bool Has(char c) const { return Find(c) != npos; } + [[nodiscard]] bool HasWhitespace() const { return WhitespaceCharSet().HasAny(*this); } + [[nodiscard]] bool HasNonwhitespace() const { return !WhitespaceCharSet().HasOnly(*this); } + [[nodiscard]] bool HasUpper() const { return UpperCharSet().HasAny(*this); } + [[nodiscard]] bool HasLower() const { return LowerCharSet().HasAny(*this); } + [[nodiscard]] bool HasLetter() const { return LetterCharSet().HasAny(*this); } + [[nodiscard]] bool HasDigit() const { return DigitCharSet().HasAny(*this); } + [[nodiscard]] bool HasAlphanumeric() const { return AlphanumericCharSet().HasAny(*this); } [[nodiscard]] bool HasCharAt(char c, size_t pos) const - { return (pos < str.size()) && (str[pos] == c); } - [[nodiscard]] bool HasOneOfAt(emp::CharSet opts, size_t pos) const { return opts.HasAt(str, pos); } - [[nodiscard]] bool HasDigitAt(size_t pos) const { return DigitCharSet().HasAt(str, pos); } - [[nodiscard]] bool HasLetterAt(size_t pos) const { return LetterCharSet().HasAt(str, pos); } - + { return (pos < size()) && (Get(pos) == c); } + [[nodiscard]] bool HasOneOfAt(CharSet opts, size_t pos) const { return opts.HasAt(*this, pos); } + [[nodiscard]] bool HasDigitAt(size_t pos) const { return DigitCharSet().HasAt(*this, pos); } + [[nodiscard]] bool HasLetterAt(size_t pos) const { return LetterCharSet().HasAt(*this, pos); } + [[nodiscard]] bool HasWhitespaceAt(size_t pos) const { return WhitespaceCharSet().HasAt(*this, pos); } + + [[nodiscard]] size_t CountWhitespace() const { return WhitespaceCharSet().CountMatches(*this); } + [[nodiscard]] size_t CountNonwhitespace() const { return size() - CountWhitespace(); } + [[nodiscard]] size_t CountUpper() const { return UpperCharSet().CountMatches(*this); } + [[nodiscard]] size_t CountLower() const { return LowerCharSet().CountMatches(*this); } + [[nodiscard]] size_t CountLetters() const { return LetterCharSet().CountMatches(*this); } + [[nodiscard]] size_t CountDigits() const { return DigitCharSet().CountMatches(*this); } + [[nodiscard]] size_t CountAlphanumeric() const { return AlphanumericCharSet().CountMatches(*this); } // ------ Removals and Extractions ------ + // Inherited functions from std::string: + // void pop_back(); + + String & clear() noexcept { std::string::clear(); return *this; } + + String & erase(size_t index=0, size_t count=npos) { std::string::erase(index,count); return *this; } + iterator erase(const_iterator pos) { return std::string::erase(pos); } + iterator erase(const_iterator first, const_iterator last) { return std::string::erase(first, last); } + + String & RemoveWhitespace() { return RemoveChars(WhitespaceCharSet()); } + String & RemoveUpper() { return RemoveChars(UpperCharSet()); } + String & RemoveLower() { return RemoveChars(LowerCharSet()); } + String & RemoveLetters() { return RemoveChars(LetterCharSet()); } + String & RemoveDigits() { return RemoveChars(DigitCharSet()); } + String & RemovePunctuation() { return RemoveChars(PunctuationCharSet()); } + + inline bool PopIf(char c); + inline bool PopIf(String in); + inline String PopAll(); + inline String PopFixed(std::size_t end_pos, size_t delim_size=0); + inline String Pop(CharSet chars=" \n\t\r", const Syntax & syntax=Syntax::None()); + inline String PopTo(String delim, const Syntax & syntax=Syntax::None()); + String PopWord(const Syntax & syntax=Syntax::None()) { return Pop(" \n\t\r", syntax); } + String PopLine(const Syntax & syntax=Syntax::None()) { return Pop("\n", syntax); } + inline String PopQuote(const Syntax & syntax=Syntax::Quotes()); + inline String PopParen(const Syntax & syntax=Syntax::Parens()); + inline String PopLiteralSigned(); + long long PopSigned() { return std::stoll(PopLiteralSigned()); } + inline String PopLiteralUnsigned(); + unsigned long long PopUnsigned() { return std::stoull(PopLiteralUnsigned()); } + inline String PopLiteralFloat(); + double PopFloat() { return std::stod(PopLiteralFloat()); } + String PopLiteralChar(const Syntax & syntax=Syntax::CharQuotes()) { return PopQuote(syntax); } + char PopChar() { return PopFixed(1)[0]; } + + template inline String PopLiteral(const Syntax & syntax=Syntax::Quotes()); + template inline T PopFromLiteral(const Syntax & syntax=Syntax::Quotes()); - void clear() noexcept { str.clear(); } - - String & erase(size_t index=0, size_t count=npos) { str.erase(index,count); return *this; } - iterator erase(const_iterator pos) { return str.erase(pos); } - iterator erase(const_iterator first, const_iterator last) { return str.erase(first, last); } - - void pop_back() { str.pop_back(); } - - emp::String & RemoveChars(const CharSet & chars); - emp::String & RemoveWhitespace() { return RemoveChars(WhitespaceCharSet()); } - emp::String & RemoveUpper() { return RemoveChars(UpperCharSet()); } - emp::String & RemoveLower() { return RemoveChars(LowerCharSet()); } - emp::String & RemoveLetters() { return RemoveChars(LetterCharSet()); } - emp::String & RemoveDigits() { return RemoveChars(DigitCharSet()); } - emp::String & RemovePunctuation() { return RemoveChars(PunctuationCharSet()); } - - bool PopIf(char c); - bool PopIf(String in); - emp::String PopAll(); - emp::String PopFixed(std::size_t end_pos, size_t delim_size=0); - emp::String Pop(CharSet chars=" \n\t\r", bool skip_quotes=false, bool skip_parens=false); - emp::String PopTo(std::string delim, bool skip_quotes=false, bool skip_parens=false); - emp::String PopWord(); - emp::String PopLine(); - emp::String PopQuote(); - emp::String PopParen(bool skip_quotes=false); - size_t PopUInt(); // ------ Insertions and Additions ------ + // Inherited functions from std::string: + // void push_back(char c); - String & insert(size_t index, const String & in) { str.insert(index, in.str); return *this; } + String & insert(size_t index, const String & in) { std::string::insert(index, in); return *this; } String & insert(size_t index, const String & in, size_t pos, size_t count=npos) - { str.insert(index, in.str, pos, count); return *this; } + { std::string::insert(index, in, pos, count); return *this; } template String & insert(size_t index, ARG_Ts &&... args) - { str.insert(index, std::forward(args)...); return *this; } + { std::string::insert(index, std::forward(args)...); return *this; } template String & insert(const_iterator pos, ARG_Ts &&... args) - { return str.insert(pos, std::forward(args)...); } - - void push_back(char c) { str.push_back(c); } + { return std::string::insert(pos, std::forward(args)...); } - String & append(const String & in) { str.append(in.str); return *this; } + String & append(const String & in) { std::string::append(in); return *this; } String & append(const String & in, size_t pos, size_t count) - { str.append(in.str, pos, count); return *this; } + { std::string::append(in, pos, count); return *this; } template String & append(ARG_Ts &&... args) - { str.append(std::forward(args)...); return *this; } + { std::string::append(std::forward(args)...); return *this; } - String & operator+=(const String & in) { str += in.str; return *this; } template String & operator+=(ARG_T && arg) - { str += std::forward(arg); return *this; } + { std::string::operator+=(std::forward(arg)); return *this; } String & PadFront(char padding, size_t target_size) { - if (str.size() < target_size) str = std::string(target_size - size(), padding) + str; + if (size() < target_size) *this = std::string(target_size - size(), padding) + *this; return *this; } String & PadBack(char padding, size_t target_size) { - if (str.size() < target_size) str = str + std::string(target_size - size(), padding); + if (size() < target_size) *this += std::string(target_size - size(), padding); return *this; } // ------ Direct Modifications ------ + // Inherited functions from std::string: + // size_t copy(char * dest, size_t count, size_t pos=0) const + // void swap(String & other) template String & replace(ARG_Ts &&... args) - { str.replace(std::forward(args)...); return *this; } + { std::string::replace(std::forward(args)...); return *this; } - size_t copy(char * dest, size_t count, size_t pos=0) const { return str.copy(dest, count, pos); } + String & resize( size_t count, char c='\0') { std::string::resize(count, c); return *this; } - void resize( size_t count, char c='\0') { str.resize(count, c); } - - void swap(String & other) { str.swap(other.str); std::swap(mode, other.mode); } - - emp::String & ReplaceChar(char from, char to, size_t start=0) - { for (size_t i=start; i < str.size(); ++i) if (str[i] == from) str[i] = to; return *this; } - emp::String & ReplaceRange(size_t start, size_t end, std::string value) + String & ReplaceChar(char from, char to, size_t start=0) + { for (size_t i=start; i < size(); ++i) if (Get(i) == from) Get(i) = to; return *this; } + String & ReplaceRange(size_t start, size_t end, String value) { return replace(start, end-start, value); } - emp::String & TrimWhitespace(); - emp::String & CompressWhitespace(); - emp::String & Slugify(); // Find any instances of ${X} and replace with dictionary lookup of X. template - emp::String & ReplaceVars(const MAP_T & var_map, emp::String symbol="$", - bool skip_quotes=false, bool skip_parens=false); + String & ReplaceVars(const MAP_T & var_map, String symbol="$", + const Syntax & syntax=Syntax::Full()); // Find any instance of MACRO_NAME(ARGS) and call replace it with return from fun(ARGS). template - String & ReplaceMacro(std::string start_str, std::string end_str, FUN_T && fun, bool skip_quotes=true); + String & ReplaceMacro(String start_str, String end_str, FUN_T && fun, + const Syntax & syntax=Syntax{"\"", "()"}); // ------ Searching ------ - - [[nodiscard]] size_t find(const std::string & s, size_t pos=0) const noexcept { return str.find(s,pos); } - [[nodiscard]] size_t find(const char* s, size_t pos=0) const { return str.find(s,pos); } - [[nodiscard]] size_t find(const char* s, size_t pos, size_t count) const { return str.find(s,pos,count); } - [[nodiscard]] size_t find(char c, size_t pos=0) const noexcept { return str.find(c,pos); } - template < class SVIEW_T > [[nodiscard]] size_t find(const SVIEW_T & sv, size_t pos=0) const - { return str.find(sv,pos); } - - [[nodiscard]] size_t rfind(const std::string & s, size_t pos=0) const noexcept { return str.rfind(s,pos); } - [[nodiscard]] size_t rfind(const char* s, size_t pos=0) const { return str.rfind(s,pos); } - [[nodiscard]] size_t rfind(const char* s, size_t pos, size_t count) const { return str.rfind(s,pos,count); } - [[nodiscard]] size_t rfind(char c, size_t pos=0) const noexcept { return str.rfind(c,pos); } - template < class SVIEW_T > [[nodiscard]] size_t rfind(const SVIEW_T & sv, size_t pos=0) const - { return str.rfind(sv,pos); } - - [[nodiscard]] size_t find_first_of(const std::string & s, size_t pos=0) const noexcept - { return str.find_first_of(s,pos); } - [[nodiscard]] size_t find_first_of(const char* s, size_t pos=0) const { return str.find_first_of(s,pos); } - [[nodiscard]] size_t find_first_of(const char* s, size_t pos, size_t count) const - { return str.find_first_of(s,pos,count); } - [[nodiscard]] size_t find_first_of(char c, size_t pos=0) const noexcept { return str.find_first_of(c,pos); } - template < class SVIEW_T > [[nodiscard]] size_t find_first_of(const SVIEW_T & sv, size_t pos=0) const - { return str.find_first_of(sv,pos); } - - [[nodiscard]] size_t find_first_not_of(const std::string & s, size_t pos=0) const noexcept - { return str.find_first_not_of(s,pos); } - [[nodiscard]] size_t find_first_not_of(const char* s, size_t pos=0) const - { return str.find_first_not_of(s,pos); } - [[nodiscard]] size_t find_first_not_of(const char* s, size_t pos, size_t count) const - { return str.find_first_not_of(s,pos,count); } - [[nodiscard]] size_t find_first_not_of(char c, size_t pos=0) const noexcept - { return str.find_first_not_of(c,pos); } - template < class SVIEW_T > [[nodiscard]] size_t find_first_not_of(const SVIEW_T & sv, size_t pos=0) const - { return str.find_first_not_of(sv,pos); } - - [[nodiscard]] size_t find_last_of(const std::string & s, size_t pos=0) const noexcept - { return str.find_last_of(s,pos); } - [[nodiscard]] size_t find_last_of(const char* s, size_t pos=0) const { return str.find_last_of(s,pos); } - [[nodiscard]] size_t find_last_of(const char* s, size_t pos, size_t count) const - { return str.find_last_of(s,pos,count); } - [[nodiscard]] size_t find_last_of(char c, size_t pos=0) const noexcept { return str.find_last_of(c,pos); } - template < class SVIEW_T > [[nodiscard]] size_t find_last_of(const SVIEW_T & sv, size_t pos=0) const - { return str.find_last_of(sv,pos); } - - [[nodiscard]] size_t find_last_not_of(const std::string & s, size_t pos=0) const noexcept - { return str.find_last_not_of(s,pos); } - [[nodiscard]] size_t find_last_not_of(const char* s, size_t pos=0) const - { return str.find_last_not_of(s,pos); } - [[nodiscard]] size_t find_last_not_of(const char* s, size_t pos, size_t count) const - { return str.find_last_not_of(s,pos,count); } - [[nodiscard]] size_t find_last_not_of(char c, size_t pos=0) const noexcept - { return str.find_last_not_of(c,pos); } - template < class SVIEW_T > [[nodiscard]] size_t find_last_not_of(const SVIEW_T & sv, size_t pos=0) const - { return str.find_last_not_of(sv,pos); } - - [[nodiscard]] size_t FindQuoteMatch(size_t pos) const; - [[nodiscard]] size_t FindParenMatch(size_t pos, bool skip_quotes=true) const; - [[nodiscard]] size_t FindMatch(size_t pos) const; - [[nodiscard]] size_t Find(char target, size_t start=0, bool skip_quotes=false, bool skip_parens=false) const; - [[nodiscard]] size_t Find(std::string target, size_t start=0, bool skip_quotes=false, bool skip_parens=false) const; - [[nodiscard]] size_t Find(const CharSet & char_set, size_t start, - bool skip_quotes=false, bool skip_parens=false) const; - void FindAll(char target, emp::vector & results, - const bool skip_quotes=false, bool skip_parens=false) const; - [[nodiscard]] emp::vector FindAll(char target, bool skip_quotes=false, bool skip_parens=false) const; + // Inherited functions from std::string: + // size_t find(...) const + // size_t rfind(...) const + // size_t find_first_of(...) const + // size_t find_first_not_of(...) const + // size_t find_last_of(...) const + // size_t find_last_not_of(...) const + + [[nodiscard]] inline size_t FindQuoteMatch(size_t pos=0) const; + [[nodiscard]] inline size_t FindParenMatch(size_t pos=0, const Syntax & syntax=Syntax::Parens()) const; + [[nodiscard]] inline size_t RFindQuoteMatch(size_t pos=npos) const; + [[nodiscard]] inline size_t RFindParenMatch(size_t pos=npos, const Syntax & syntax=Syntax::RParens()) const; + [[nodiscard]] inline size_t FindMatch(size_t pos=0, const Syntax & syntax=Syntax::Full()) const; + [[nodiscard]] inline size_t RFindMatch(size_t pos=npos, const Syntax & syntax=Syntax::Full()) const; + [[nodiscard]] inline size_t Find(char target, size_t start=0, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline size_t Find(String target, size_t start=0, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline size_t Find(const CharSet & char_set, size_t start=0, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline size_t Find(const char * target, size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(String(target), start, syntax); } + [[nodiscard]] inline size_t RFind(char target, size_t start=npos, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline size_t RFind(String target, size_t start=npos, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline size_t RFind(const CharSet & char_set, size_t start=npos, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline size_t RFind(const char * target, size_t start=npos, const Syntax & syntax=Syntax::None()) const + { return RFind(String(target), start, syntax); } + inline void FindAll(char target, emp::vector & results, const Syntax & syntax=Syntax::None()) const; + [[nodiscard]] inline emp::vector FindAll(char target, const Syntax & syntax=Syntax::None()) const; template - [[nodiscard]] size_t FindAnyOfFrom(size_t start, std::string test1, Ts... tests) const; + [[nodiscard]] inline size_t FindAnyOfFrom(size_t start, String test1, Ts... tests) const; template - [[nodiscard]] size_t FindAnyOf(T test1, Ts... tests) const; - [[nodiscard]] size_t FindID(std::string target, size_t start, bool skip_quotes=true, bool skip_parens=false) const; - - [[nodiscard]] size_t FindWhitespace(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(WhitespaceCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonWhitespace(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!WhitespaceCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindUpperChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(UpperCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonUpperChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!UpperCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindLowerChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(LowerCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonLowerChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!LowerCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindLetterChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(LetterCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonLetterChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!LetterCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindDigitChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(DigitCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonDigitChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!DigitCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindAlphanumericChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(AlphanumericCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonAlphanumericChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!AlphanumericCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindIDChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(IDCharSet(), start, skip_q, skip_p); } - [[nodiscard]] size_t FindNonIDChar(size_t start=0, bool skip_q=false, bool skip_p=false) const - { return Find(!IDCharSet(), start, skip_q, skip_p); } + [[nodiscard]] inline size_t FindAnyOf(T test1, Ts... tests) const; + [[nodiscard]] inline size_t FindID(String target, size_t start, const Syntax & syntax=Syntax::Quotes()) const; + + [[nodiscard]] size_t FindWhitespace(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(WhitespaceCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonWhitespace(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!WhitespaceCharSet(), start, syntax); } + [[nodiscard]] size_t FindUpperChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(UpperCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonUpperChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!UpperCharSet(), start, syntax); } + [[nodiscard]] size_t FindLowerChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(LowerCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonLowerChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!LowerCharSet(), start, syntax); } + [[nodiscard]] size_t FindLetterChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(LetterCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonLetterChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!LetterCharSet(), start, syntax); } + [[nodiscard]] size_t FindDigitChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(DigitCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonDigitChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!DigitCharSet(), start, syntax); } + [[nodiscard]] size_t FindAlphanumericChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(AlphanumericCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonAlphanumericChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!AlphanumericCharSet(), start, syntax); } + [[nodiscard]] size_t FindIDChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(IDCharSet(), start, syntax); } + [[nodiscard]] size_t FindNonIDChar(size_t start=0, const Syntax & syntax=Syntax::None()) const + { return Find(!IDCharSet(), start, syntax); } // ------ Other Views ------ - std::string_view ViewNestedBlock(size_t start=0, bool skip_quotes=true) - { return ViewRange(start+1, FindParenMatch(start, skip_quotes) - 1); } - std::string_view ViewQuote(size_t start=0) - { return ViewRange(start, FindQuoteMatch(start)); } + [[nodiscard]] std::string_view ViewNestedBlock(size_t start=0, const Syntax & syntax=Syntax::Quotes()) const + { return ViewRange(start+1, FindParenMatch(start, syntax) - 1); } + [[nodiscard]] std::string_view ViewQuote(size_t start=0, const Syntax & syntax=Syntax::Quotes()) const + { return ViewRange(start, syntax.IsQuote(Get(start)) ? FindQuoteMatch(start) : start); } + + // Return string_view starting at a specified position, and advance that position + // Helper function for scanning. + std::string_view ScanTo(size_t & pos, size_t stop_pos) const + { const size_t start = pos; return ViewRange(start, pos=std::min(stop_pos, size())); } + std::string_view ScanWhile(size_t & pos, CharSet chars) const { + const size_t start = pos; + while (pos < size() && chars.Has(Get(pos))) ++pos; + return ViewRange(start, pos); + } + std::string_view ScanView(std::function fun, size_t & pos) const { + auto out = fun(pos); pos += out.size(); return out; + } + std::string_view ScanWord(size_t & pos) const { return ScanTo(pos, FindWhitespace(pos)); } + char ScanChar(size_t & pos) const { return Get(pos++); } + std::string_view ScanWhitespace(size_t & pos) const { return ScanWhile(pos, WhitespaceCharSet()); } + std::string_view ScanUpper(size_t & pos) const { return ScanWhile(pos, UpperCharSet()); } + std::string_view ScanLower(size_t & pos) const { return ScanWhile(pos, LowerCharSet()); } + std::string_view ScanLetters(size_t & pos) const { return ScanWhile(pos, LetterCharSet()); } + std::string_view ScanDigits(size_t & pos) const { return ScanWhile(pos, DigitCharSet()); } + std::string_view ScanAlphanumeric(size_t & pos) const { return ScanWhile(pos, AlphanumericCharSet()); } + std::string_view ScanNestedBlock(size_t & pos) const { auto out=ViewNestedBlock(pos); pos+=out.size(); return out; } + std::string_view ScanQuote(size_t & pos) const { auto out=ViewQuote(pos); pos+=out.size(); return out; } // ------ Transformations into non-Strings ------ // Note: For efficiency there are two versions of most of these: one where the output // data structure is provided and one where it must be generated. - void Slice(emp::vector & out_set, std::string delim=",", - bool keep_quotes=true, bool keep_parens=true, bool trim_whitespace=true) const; + template + T ConvertTo() { + // Is it already a string? + if constexpr (std::is_same() || std::is_same()) return *this; + + else if constexpr (std::is_same()) return std::stoi(*this); + else if constexpr (std::is_same()) return std::stol(*this); + else if constexpr (std::is_same()) return std::stoll(*this); + else if constexpr (std::is_same()) return std::stoul(*this); + else if constexpr (std::is_same()) return std::stoull(*this); + else if constexpr (std::is_same()) return std::stof(*this); + else if constexpr (std::is_same()) return std::stod(*this); + else if constexpr (std::is_same()) return std::stold(*this); + + // All other printable cases: + else { + std::stringstream ss; + ss << *this; + T out_val; + ss >> out_val; + return out_val; + } + } + + inline void Slice(emp::vector & out_set, String delim=",", + const Syntax & syntax=Syntax::Quotes(), bool trim_whitespace=false) const; [[nodiscard]] - emp::vector Slice(std::string delim=",", bool keep_quotes=true, - bool keep_parens=true, bool trim_whitespace=true) const; + inline emp::vector Slice(String delim=",", const Syntax & syntax=Syntax::Quotes(), + bool trim_whitespace=false) const; - void ViewSlices( + inline void ViewSlices( emp::vector & out_set, - std::string delim=",", - bool keep_quotes=true, bool keep_parens=true + String delim=",", + const Syntax & syntax=Syntax::Quotes() ) const; - [[nodiscard]] emp::vector ViewSlices( - std::string delim=",", - bool keep_quotes=true, bool keep_parens=true + [[nodiscard]] inline emp::vector ViewSlices( + String delim=",", + const Syntax & syntax=Syntax::Quotes() ) const; - void SliceAssign( - std::map & out_map, - std::string delim=",", std::string assign_op="=", - bool keep_quotes=true, bool keep_parens=false, bool trim_whitespace=true + inline void SliceAssign( + std::map & out_map, + String delim=",", String assign_op="=", + const Syntax & syntax=Syntax::Quotes(), bool trim_whitespace=true ) const; - [[nodiscard]] std::map SliceAssign( - std::string delim=",", std::string assign_op="=", - bool keep_quotes=true, bool keep_parens=false, bool trim_whitespace=true + [[nodiscard]] inline std::map SliceAssign( + String delim=",", String assign_op="=", + const Syntax & syntax=Syntax::Quotes(), bool trim_whitespace=true ) const; // ------ Other Operators ------ - - template [[nodiscard]] String operator+(T && in) const - { return String(str + std::forward(in), mode); } - [[nodiscard]] bool operator==(const emp::String & in) const { return str == in.str; } - [[nodiscard]] bool operator==(const std::string & in) const { return str == in; } - [[nodiscard]] bool operator==(const char * in) const { return str == in; } - - [[nodiscard]] bool operator!=(const emp::String & in) const { return str != in.str; } - [[nodiscard]] bool operator!=(const std::string & in) const { return str != in; } - [[nodiscard]] bool operator!=(const char * in) const { return str != in; } - - [[nodiscard]] bool operator<(const emp::String & in) const { return str < in.str; } - [[nodiscard]] bool operator<(const std::string & in) const { return str < in; } - [[nodiscard]] bool operator<(const char * in) const { return str < in; } - - [[nodiscard]] bool operator<=(const emp::String & in) const { return str <= in.str; } - [[nodiscard]] bool operator<=(const std::string & in) const { return str <= in; } - [[nodiscard]] bool operator<=(const char * in) const { return str <= in; } - - [[nodiscard]] bool operator>(const emp::String & in) const { return str > in.str; } - [[nodiscard]] bool operator>(const std::string & in) const { return str > in; } - [[nodiscard]] bool operator>(const char * in) const { return str > in; } - - [[nodiscard]] bool operator>=(const emp::String & in) const { return str >= in.str; } - [[nodiscard]] bool operator>=(const std::string & in) const { return str >= in; } - [[nodiscard]] bool operator>=(const char * in) const { return str >= in; } - - // auto operator<=>(const emp::String & in) const = default; - // auto operator<=>(const std::string & in) const { return str <=> in; } - // auto operator<=>(const char * in) const { return str <=> in; } - - - // ------ SPECIAL CONFIGURATION ------ - - String & UseQuoteSingle(bool use=true) { mode.Set(USE_QUOTE_SINGLE, use); return *this; } - String & UseQuoteDouble(bool use=true) { mode.Set(USE_QUOTE_DOUBLE, use); return *this; } - String & UseQuoteBack (bool use=true) { mode.Set(USE_QUOTE_BACK, use); return *this; } - String & UseParenRound (bool use=true) { mode.Set(USE_PAREN_ROUND, use); return *this; } - String & UseParenSquare(bool use=true) { mode.Set(USE_PAREN_SQUARE, use); return *this; } - String & UseParenCurly (bool use=true) { mode.Set(USE_PAREN_CURLY, use); return *this; } - String & UseParenAngle (bool use=true) { mode.Set(USE_PAREN_ANGLE, use); return *this; } - String & UseParenQuotes(bool use=true) { mode.Set(USE_PAREN_QUOTES, use); return *this; } - - [[nodiscard]] bool Get_UseQuoteSingle() const { return mode.val & USE_QUOTE_SINGLE; } - [[nodiscard]] bool Get_UseQuoteDouble() const { return mode.val & USE_QUOTE_DOUBLE; } - [[nodiscard]] bool Get_UseQuoteBack () const { return mode.val & USE_QUOTE_BACK; } - [[nodiscard]] bool Get_UseParenRound () const { return mode.val & USE_PAREN_ROUND; } - [[nodiscard]] bool Get_UseParenSquare() const { return mode.val & USE_PAREN_SQUARE; } - [[nodiscard]] bool Get_UseParenCurly () const { return mode.val & USE_PAREN_CURLY; } - [[nodiscard]] bool Get_UseParenAngle () const { return mode.val & USE_PAREN_ANGLE; } - [[nodiscard]] bool Get_UseParenQuotes() const { return mode.val & USE_PAREN_QUOTES; } + // Inherited functions from std::string: + // bool operator==(const String & in) const + // bool operator!=(const String & in) const + // bool operator<(const String & in) const + // bool operator<=(const String & in) const + // bool operator>(const String & in) const + // bool operator>=(const String & in) const + // bool operator<=>(const String & in) const + // std::string operator+(const std::string & in) const + String operator*(size_t count) const { + String out; out.reserve(size() * count); + for (size_t i = 0; i < count; ++i) out += *this; + return out; + } // ------ FORMATTING ------ - // Append* adds to the end of the current string. - // Set* replaces the current string. - // To* Converts the current string. + // Set* replaces the current string with argument OR converts the current string if no argument. // As* Returns a modified version of the current string, leaving original intact. - // Most also have stand-along Make* versions where the core implementation is found. + // Append* adds to the end of the current string. + // Most also have stand-alone Make* versions where the core implementation is found. template - String & Append(Ts... args) { return str += MakeString(std::forward(args)...);} + String & Append(Ts... args) { return *this += MakeString(std::forward(args)...);} template - String & Set(Ts... args) { return str = MakeString(std::forward(args)...); } + String & Set(Ts... args) { return *this = MakeString(std::forward(args)...); } template - T As() { std::stringstream ss; ss << str; T out; ss >> out; return out; } + T As() const { std::stringstream ss; ss << *this; T out; ss >> out; return out; } + + String & AppendEscaped(char c) { *this += MakeEscaped(c); return *this; } + String & SetEscaped(char c) { *this = MakeEscaped(c); return *this; } - String & AppendEscaped(char c) { str += MakeEscaped(c); return *this; } - String & SetEscaped(char c) { str = MakeEscaped(c); return *this; } + String & AppendEscaped(const String & in) { *this+=MakeEscaped(in); return *this; } + String & SetEscaped(const String & in) { *this = MakeEscaped(in); return *this; } + String & SetEscaped() { *this = MakeEscaped(*this); return *this; } + [[nodiscard]] String AsEscaped() const { return MakeEscaped(*this); } - String & AppendEscaped(const std::string & in) { str+=MakeEscaped(in); return *this; } - String & SetEscaped(const std::string & in) { str = MakeEscaped(in); return *this; } - String & ToEscaped() { str = MakeEscaped(str); return *this; } - [[nodiscard]] emp::String AsEscaped() { return MakeEscaped(str); } + String & AppendCSVSafe(String in) { *this+=MakeCSVSafe(in); return *this; } + String & SetCSVSafe(const String & in) { *this = MakeCSVSafe(in); return *this; } + String & SetCSVSafe() { *this = MakeCSVSafe(*this); return *this; } + [[nodiscard]] String AsCSVSafe() const { return MakeCSVSafe(*this); } - String & AppendWebSafe(std::string in) { str+=MakeWebSafe(in); return *this; } - String & SetWebSafe(const std::string & in) { str = MakeWebSafe(in); return *this; } - String & ToWebSafe() { str = MakeWebSafe(str); return *this; } - [[nodiscard]] emp::String AsWebSafe() { return MakeWebSafe(str); } + String & AppendWebSafe(String in) { *this+=MakeWebSafe(in); return *this; } + String & SetWebSafe(const String & in) { *this = MakeWebSafe(in); return *this; } + String & SetWebSafe() { *this = MakeWebSafe(*this); return *this; } + [[nodiscard]] String AsWebSafe() const { return MakeWebSafe(*this); } // <= Creating Literals => template - String & AppendLiteral(const T & in) { str+=MakeLiteral(in); return *this; } + String & AppendLiteral(const T & in) { *this+=MakeLiteral(in); return *this; } template - String & SetLiteral(const T & in) { str = MakeLiteral(in); return *this;; } - String & ToLiteral() { str = MakeLiteral(str); return *this; } - [[nodiscard]] emp::String AsLiteral() { return MakeLiteral(str); } - - String & AppendUpper(const std::string & in) { str+=MakeUpper(in); return *this; } - String & SetUpper(const std::string & in) { str = MakeUpper(in); return *this; } - String & ToUpper() { str = MakeUpper(str); return *this; } - [[nodiscard]] emp::String AsUpper() { return MakeUpper(str); } - - String & AppendLower(const std::string & in) { str+=MakeLower(in); return *this; } - String & SetLower(const std::string & in) { str = MakeLower(in); return *this; } - String & ToLower() { str = MakeLower(str); return *this; } - [[nodiscard]] emp::String AsLower() { return MakeLower(str); } - - String & AppendTitleCase(const std::string & in) { str+=MakeTitleCase(in); return *this; } - String & SetTitleCase(const std::string & in) { str = MakeTitleCase(in); return *this; } - String & ToTitleCase() { str = MakeTitleCase(str); return *this; } - [[nodiscard]] emp::String AsTitleCase() { return MakeTitleCase(str); } - - String & AppendRoman(int val) { str+=MakeRoman(val); return *this; } - String & SetRoman(int val) { str = MakeRoman(val); return *this; } + String & SetLiteral(const T & in) { *this = MakeLiteral(in); return *this;; } + String & SetLiteral() { *this = MakeLiteral(*this); return *this; } + [[nodiscard]] String AsLiteral() const { return MakeLiteral(*this); } + + String & AppendUpper(const String & in) { *this+=MakeUpper(in); return *this; } + String & SetUpper(const String & in) { *this = MakeUpper(in); return *this; } + String & SetUpper() { *this = MakeUpper(*this); return *this; } + [[nodiscard]] String AsUpper() { return MakeUpper(*this); } + + String & AppendLower(const String & in) { *this+=MakeLower(in); return *this; } + String & SetLower(const String & in) { *this = MakeLower(in); return *this; } + String & SetLower() { *this = MakeLower(*this); return *this; } + [[nodiscard]] String AsLower() { return MakeLower(*this); } + + String & AppendTitleCase(const String & in) { *this+=MakeTitleCase(in); return *this; } + String & SetTitleCase(const String & in) { *this = MakeTitleCase(in); return *this; } + String & SetTitleCase() { *this = MakeTitleCase(*this); return *this; } + [[nodiscard]] String AsTitleCase() const { return MakeTitleCase(*this); } + + String & AppendCount(int val, String item, String suffix="s") + { *this+=MakeCount(val, item, suffix); return *this; } + String & SetCount(int val, String item, String suffix="s") + { *this = MakeCount(val, item, suffix); return *this; } + String & SetAsCount(int val, String suffix="s") + { *this = MakeCount(val, *this, suffix); return *this; } + + String & AppendRoman(int val) { *this+=MakeRoman(val); return *this; } + String & SetRoman(int val) { *this = MakeRoman(val); return *this; } template String & AppendEnglishList(const CONTAINER_T & container) - { str += MakeEnglishList(container); return *this;} + { *this += MakeEnglishList(container); return *this;} template String & SetEnglishList(const CONTAINER_T & container) - { str = MakeEnglishList(container); return *this;} + { *this = MakeEnglishList(container); return *this;} template String & AppendFormatted(const std::string& format, ARG_Ts... args) - { return str += MakeFormatted(format, std::forward(args)...); } + { return *this += MakeFormatted(format, std::forward(args)...); } template String & SetFormatted(const std::string& format, ARG_Ts... args) - { return str = MakeFormatted(format, std::forward(args)...); } + { return *this = MakeFormatted(format, std::forward(args)...); } + + + String & AppendTrimFront(const String & in, const CharSet & chars=WhitespaceCharSet()) + { return *this += MakeTrimFront(in, chars); } + String & SetTrimFront(const String & in, const CharSet & chars=WhitespaceCharSet()) + { return *this = MakeTrimFront(in, chars); } + String & TrimFront(const CharSet & chars=WhitespaceCharSet()) + { return *this = MakeTrimFront(*this, chars); } + [[nodiscard]] String AsTrimFront(const CharSet & chars=WhitespaceCharSet()) const + { return MakeTrimFront(*this, chars); } + + String & AppendTrimBack(const String & in, const CharSet & chars=WhitespaceCharSet()) + { return *this += MakeTrimBack(in, chars); } + String & SetTrimBack(const String & in, const CharSet & chars=WhitespaceCharSet()) + { return *this = MakeTrimBack(in, chars); } + String & TrimBack(const CharSet & chars=WhitespaceCharSet()) + { return *this = MakeTrimBack(*this, chars); } + [[nodiscard]] String AsTrimBack(const CharSet & chars=WhitespaceCharSet()) const + { return MakeTrimBack(*this, chars); } + + String & AppendTrimmed(const String & in, const CharSet & chars=WhitespaceCharSet()) + { return *this += MakeTrimmed(in, chars); } + String & SetTrimmed(const String & in, const CharSet & chars=WhitespaceCharSet()) + { return *this = MakeTrimmed(in, chars); } + String & Trim(const CharSet & chars=WhitespaceCharSet()) + { return *this = MakeTrimmed(*this, chars); } + [[nodiscard]] String AsTrimmed(const CharSet & chars=WhitespaceCharSet()) const + { return MakeTrimmed(*this, chars); } + + String & AppendCompressed(const String & in, const CharSet & chars=WhitespaceCharSet(), + char compress_to=' ', bool trim_start=true, bool trim_end=true) + { return *this += MakeCompressed(in, chars, compress_to, trim_start, trim_end); } + String & SetCompressed(const String & in, const CharSet & chars=WhitespaceCharSet(), + char compress_to=' ', bool trim_start=true, bool trim_end=true) + { return *this = MakeCompressed(in, chars, compress_to, trim_start, trim_end); } + String & Compress(const CharSet & chars=WhitespaceCharSet(), char compress_to=' ', + bool trim_start=true, bool trim_end=true) + { return *this = MakeCompressed(*this, chars, compress_to, trim_start, trim_end); } + [[nodiscard]] String AsCompressed(const CharSet & chars=WhitespaceCharSet(), char compress_to=' ', + bool trim_start=true, bool trim_end=true) const + { return MakeCompressed(*this, chars, compress_to, trim_start, trim_end); } + + String & AppendRemoveChars(const String & in, const CharSet & chars) + { return *this += MakeRemoveChars(in, chars); } + String & SetRemoveChars(const String & in, const CharSet & chars) + { return *this = MakeRemoveChars(in, chars); } + String & RemoveChars(const CharSet & chars) + { return *this = MakeRemoveChars(*this, chars); } + [[nodiscard]] String AsRemoveChars(const CharSet & chars) const + { return MakeRemoveChars(*this, chars); } + + String & AppendSlugify(String in) { return *this += std::move(in.Slugify()); } + String & SetSlugify(String in) { return *this = std::move(in.Slugify()); } + String & Slugify() + { return SetLower().RemovePunctuation().Compress().ReplaceChar(' ', '-'); } + [[nodiscard]] String AsSlugify() const { return MakeSlugify(*this); } template - String & AppendJoin(const CONTAINER_T & container, std::string delim="", - std::string open="", std::string close="") - { str += Join(container, delim, open, close); return *this;} + String & AppendJoin(const CONTAINER_T & container, String delim="", + String open="", String close="") + { *this += Join(container, delim, open, close); return *this;} template - String & SetJoin(const CONTAINER_T & container, std::string delim="", - std::string open="", std::string close="") - { str = Join(container, delim, open, close); return *this;} + String & SetJoin(const CONTAINER_T & container, String delim="", + String open="", String close="") + { *this = Join(container, delim, open, close); return *this;} template - static emp::String Make(Ts... args) { + [[nodiscard]] static String Make(Ts... args) { std::stringstream ss; - (ss << ... << String::_Convert(std::forward(args))); + (ss << ... << String::_Convert(std::forward(args), true)); return ss.str(); } }; @@ -685,41 +741,9 @@ namespace emp { // //////////////////////////////////////////////////////////////////////////// - - inline bool String::IsQuote(char c) const { - switch (c) { - case '\'': return mode.val & USE_QUOTE_SINGLE; - case '"': return mode.val & USE_QUOTE_DOUBLE; - case '`': return mode.val & USE_QUOTE_BACK; - } - return false; - } - - inline bool String::IsParen(char c) const { - switch (c) { - case '(': return mode.val & USE_PAREN_ROUND; - case '[': return mode.val & USE_PAREN_SQUARE; - case '{': return mode.val & USE_PAREN_CURLY; - case '<': return mode.val & USE_PAREN_ANGLE; - case '`': return mode.val & USE_PAREN_QUOTES; - } - return false; - } - - inline char String::GetMatch(char c) { - switch (c) { - case '`': return '\''; - case '(': return ')'; - case '[': return ']'; - case '{': return '}'; - case '<': return '>'; - } - return '\0'; - } - /// Determine if this string represents a proper number. bool String::IsNumber() const { - if (!str.size()) return false; // If string is empty, not a number! + if (!size()) return false; // If string is empty, not a number! size_t pos = 0; if (HasOneOfAt("+-", pos)) ++pos; // Allow leading +/- while (HasDigitAt(pos)) ++pos; // Any number of digits (none is okay) @@ -735,55 +759,115 @@ namespace emp { while (HasDigitAt(pos)) ++pos; // Allow for MORE digits. } // If we've made it to the end of the string AND there was at least one digit, success! - return (pos == str.size()) && HasDigit(); + return (pos == size()) && HasDigit(); } // Given the start position of a quote, find where it ends; marks must be identical size_t String::FindQuoteMatch(size_t pos) const { - while (++pos < str.size()) { - const char mark = str[pos]; - if (str[pos] == '\\') { ++pos; continue; } // Skip escaped characters - if (str[pos] == mark) { return pos; } // Found match! + const char mark = Get(pos); + while (++pos < size()) { + if (Get(pos) == '\\') { ++pos; continue; } // Skip escaped characters in quotes + if (Get(pos) == mark) { // Found match! + return pos; + } } return npos; // Not found. } + // Given the start position of a quote, find where it ends; marks must be identical + size_t String::RFindQuoteMatch(size_t pos) const { + if (pos >= size()) pos = size() - 1; + const char mark = Get(pos); + while (--pos < size()) { + if (Get(pos) == mark) { // Found possible match! See if it is escaped... + size_t esc_count = 0; + while ((pos-esc_count) && Get(pos-esc_count-1) == '\\') esc_count++; + if (esc_count%2 == 0) return pos; + } + } + return npos; // Not found. + } + + + // Given an open parenthesis, find where it closes (including nesting). Marks must be different. + size_t String::FindParenMatch(size_t pos, const Syntax & syntax) const { + const char open = Get(pos); + if (!syntax.IsParen(open)) return npos; // Not a paren that we know! + const char close = syntax.GetMatch(open); + size_t open_count = 1; + while (++pos < size()) { + const char c = Get(pos); + if (c == open) ++open_count; + else if (c == close) { + if (--open_count == 0) return pos; + } + else if (syntax.IsQuote(c)) pos = FindQuoteMatch(pos); + } + + return npos; + } + // Given an open parenthesis, find where it closes (including nesting). Marks must be different. - size_t String::FindParenMatch(size_t pos, bool skip_quotes) const { - const char open = str[pos]; - const char close = GetMatch(open); + size_t String::RFindParenMatch(size_t pos, const Syntax & syntax) const { + if (pos >= size()) pos = size() - 1; + const char open = Get(pos); + if (!syntax.IsParen(open)) return npos; // Not a paren that we know! + const char close = syntax.GetMatch(open); size_t open_count = 1; - while (++pos < str.size()) { - if (str[pos] == open) ++open_count; - else if (str[pos] == close) { if (--open_count == 0) return pos; } - else if (skip_quotes && IsQuote(str[pos]) ) pos = FindQuoteMatch(pos); + while (--pos < size()) { + const char c = Get(pos); + if (c == open) ++open_count; + else if (c == close) { + if (--open_count == 0) return pos; + } + else if (syntax.IsQuote(c)) pos = FindQuoteMatch(pos); } return npos; } - size_t String::FindMatch(size_t pos) const { - if (IsQuote(str[pos])) return FindQuoteMatch(pos); - if (IsParen(str[pos])) return FindParenMatch(pos); + size_t String::FindMatch(size_t pos, const Syntax & syntax) const { + if (syntax.IsQuote(Get(pos))) return FindQuoteMatch(pos); + if (syntax.IsParen(Get(pos))) return FindParenMatch(pos, syntax); + return npos; + } + + size_t String::RFindMatch(size_t pos, const Syntax & syntax) const { + if (pos >= size()) pos = size() - 1; + if (syntax.IsQuote(Get(pos))) return RFindQuoteMatch(pos); + if (syntax.IsParen(Get(pos))) return RFindParenMatch(pos, syntax); return npos; } // A version of string::find() with single chars that can skip over quotes. - size_t String::Find(char target, size_t start, bool skip_quotes, bool skip_parens) const { + size_t String::Find(char target, size_t start, const Syntax & syntax) const { // Make sure found_pos is not in a quote and/or parens; adjust as needed! - for (size_t pos=start; pos < str.size(); ++pos) { - if (str[pos] == target) return pos; - else if (skip_quotes && IsQuote(str[pos])) pos = FindQuoteMatch(pos); - else if (skip_parens && IsParen(str[pos])) pos = FindParenMatch(pos); + for (size_t pos=start; pos < size(); ++pos) { + if (Get(pos) == target) return pos; + else if (syntax.IsQuote(Get(pos))) pos = FindQuoteMatch(pos); + else if (syntax.IsParen(Get(pos))) pos = FindParenMatch(pos, syntax); + } + + return npos; + } + + // A version of string::find() with single chars that can skip over quotes. + size_t String::RFind(char target, size_t start, const Syntax & syntax) const { + if (start >= size()) start = size() - 1; + // Make sure found_pos is not in a quote and/or parens; adjust as needed! + for (size_t pos=start; pos < size(); --pos) { + if (Get(pos) == target) return pos; + else if (syntax.IsQuote(Get(pos))) pos = RFindQuoteMatch(pos); + else if (syntax.IsParen(Get(pos))) pos = RFindParenMatch(pos, syntax); } return npos; } // A version of string::find() that can skip over quotes. - size_t String::Find(std::string target, size_t start, bool skip_quotes, bool skip_parens) const { - size_t found_pos = str.find(target, start); - if (!skip_quotes && !skip_parens) return found_pos; + size_t String::Find(String target, size_t start, const Syntax & syntax) const { + size_t found_pos = find(target, start); + if (syntax.GetCount() == 0) return found_pos; // Make sure found_pos is not in a quote and/or parens; adjust as needed! for (size_t scan_pos=0; @@ -791,55 +875,94 @@ namespace emp { scan_pos++) { // Skip quotes, if needed... - if (skip_quotes && IsQuote(str[scan_pos])) { + if (syntax.IsQuote(Get(scan_pos))) { scan_pos = FindQuoteMatch(scan_pos); - if (found_pos < scan_pos) found_pos = str.find(target, scan_pos); + if (found_pos < scan_pos) found_pos = find(target, scan_pos); } - else if (skip_parens && IsParen(str[scan_pos])) { - scan_pos = FindParenMatch(scan_pos); - if (found_pos < scan_pos) found_pos = str.find(target, scan_pos); + else if (syntax.IsParen(Get(scan_pos))) { + scan_pos = FindParenMatch(scan_pos, syntax); + if (found_pos < scan_pos) found_pos = find(target, scan_pos); } } return found_pos; } + + // A version of string::find() that can skip over quotes. + size_t String::RFind(String target, size_t start, const Syntax & syntax) const { + if (start >= size()) start = size() - 1; + size_t found_pos = rfind(target, start); + if (syntax.GetCount() == 0) return found_pos; + + // Make sure found_pos is not in a quote and/or parens; adjust as needed! + for (size_t scan_pos=size()-1; + scan_pos > found_pos && found_pos != npos; + scan_pos--) + { + // Skip quotes, if needed... + if (syntax.IsQuote(Get(scan_pos))) { + scan_pos = RFindQuoteMatch(scan_pos); + if (found_pos > scan_pos) found_pos = rfind(target, scan_pos); + } + else if (syntax.IsParen(Get(scan_pos))) { + scan_pos = RFindParenMatch(scan_pos); + if (found_pos > scan_pos) found_pos = rfind(target, scan_pos); + } + } + + return found_pos; + } + + // Find any of a set of characters. + size_t String::Find(const CharSet & char_set, size_t start, const Syntax & syntax) const + { + // Make sure found_pos is not in a quote and/or parens; adjust as needed! + for (size_t pos=start; pos < size(); ++pos) { + if (char_set.Has(Get(pos))) return pos; + else if (syntax.IsQuote(Get(pos))) pos = FindQuoteMatch(pos); + else if (syntax.IsParen(Get(pos))) pos = FindParenMatch(pos, syntax); + } + + return npos; + } + // Find any of a set of characters. - size_t String::Find(const CharSet & char_set, size_t start, - bool skip_quotes, bool skip_parens) const + size_t String::RFind(const CharSet & char_set, size_t start, const Syntax & syntax) const { + if (start >= size()) start = size() - 1; // Make sure found_pos is not in a quote and/or parens; adjust as needed! - for (size_t pos=start; pos < str.size(); ++pos) { - if (char_set.Has(str[pos])) return pos; - else if (skip_quotes && IsQuote(str[pos])) pos = FindQuoteMatch(pos); - else if (skip_parens && IsParen(str[pos])) pos = FindParenMatch(pos); + for (size_t pos=start; pos < size(); --pos) { + if (char_set.Has(Get(pos))) return pos; + else if (syntax.IsQuote(Get(pos))) pos = RFindQuoteMatch(pos); + else if (syntax.IsParen(Get(pos))) pos = RFindParenMatch(pos, syntax); } return npos; } - void String::FindAll(char target, emp::vector & results, - const bool skip_quotes, bool skip_parens) const { + + void String::FindAll(char target, emp::vector & results, const Syntax & syntax) const { results.resize(0); - for (size_t pos=0; pos < str.size(); pos++) { - if (str[pos] == target) results.push_back(pos); + for (size_t pos=0; pos < size(); ++pos) { + if (Get(pos) == target) results.push_back(pos); // Skip quotes, if needed... - if (skip_quotes && IsQuote(str[pos])) pos = FindQuoteMatch(pos); - else if (skip_parens && IsParen(str[pos])) pos = FindParenMatch(pos); + if (syntax.IsQuote(Get(pos))) pos = FindQuoteMatch(pos); + else if (syntax.IsParen(Get(pos))) pos = FindParenMatch(pos, syntax); } } - emp::vector String::FindAll(char target, bool skip_quotes, bool skip_parens) const { + emp::vector String::FindAll(char target, const Syntax & syntax) const { emp::vector out; - FindAll(target, out, skip_quotes, skip_parens); + FindAll(target, out, syntax); return out; } template - size_t String::FindAnyOfFrom(size_t start, std::string test1, Ts... tests) const { - if constexpr (sizeof...(Ts) == 0) return str.find(test1, start); + size_t String::FindAnyOfFrom(size_t start, String test1, Ts... tests) const { + if constexpr (sizeof...(Ts) == 0) return find(test1, start); else { - size_t pos1 = str.find(test1, start); + size_t pos1 = find(test1, start); size_t pos2 = FindAnyOfFrom(start, tests...); return std::min(pos1, pos2); } @@ -856,78 +979,27 @@ namespace emp { } // Find an whole identifier (same as find, but cannot have letter, digit or '_' before or after.) - size_t String::FindID(std::string target, size_t start, - bool skip_quotes, bool skip_parens) const + size_t String::FindID(String target, size_t start, const Syntax & syntax) const { - size_t pos = Find(target, start, skip_quotes, skip_parens); + size_t pos = Find(target, start, syntax); while (pos != npos) { - bool before_ok = (pos == 0) || !is_idchar(str[pos-1]); + bool before_ok = (pos == 0) || !is_idchar(Get(pos-1)); size_t after_pos = pos+target.size(); - bool after_ok = (after_pos == str.size()) || !is_idchar(str[after_pos]); + bool after_ok = (after_pos == size()) || !is_idchar(Get(after_pos)); if (before_ok && after_ok) return pos; - pos = Find(target, pos+target.size(), skip_quotes, skip_parens); + pos = Find(target, pos+target.size(), syntax); } return npos; } - /// Remove whitespace from the beginning or end of a string. - emp::String & String::TrimWhitespace() { - size_t start_count=0; - while (start_count < str.size() && is_whitespace(str[start_count])) ++start_count; - if (start_count) str.erase(0, start_count); - - size_t new_size = str.size(); - while (new_size > 0 && is_whitespace(str[new_size-1])) --new_size; - str.resize(new_size); - - return *this; - } - - /// Every time one or more whitespace characters appear replace them with a single space. - emp::String & String::CompressWhitespace() { - bool skip_whitespace = true; // Remove whitespace from beginning of line. - size_t pos = 0; - - for (const auto c : str) { - if (is_whitespace(c)) { // This char is whitespace - if (skip_whitespace) continue; // Already skipping... - str[pos++] = ' '; - skip_whitespace = true; - } else { // Not whitespace - str[pos++] = c; - skip_whitespace = false; - } - } - - if (pos && skip_whitespace) pos--; // If the end of the line is whitespace, remove it. - str.resize(pos); - - return *this; - } - - /// Remove all instances of specified characters from file. - emp::String & String::RemoveChars(const CharSet & chars) { - size_t cur_pos = 0; - for (const auto c : str) { - if (!chars.Has(c)) str[cur_pos++] = c; - } - str.resize(cur_pos); - return *this; - } - - /// Make a string safe(r) - emp::String & String::Slugify() { - return ToLower().RemovePunctuation().CompressWhitespace().ReplaceChar(' ', '-'); - } - // Pop functions... bool String::PopIf(char c) { - if (str.size() && str[0] == c) { str.erase(0,1); return true; } + if (size() && Get(0) == c) { erase(0,1); return true; } return false; } @@ -937,76 +1009,114 @@ namespace emp { } /// Pop the entire string. - emp::String String::PopAll() { - std::string out; - out.swap(str); + String String::PopAll() { + String out; + swap(out); return out; } /// Pop a segment from the beginning of a string as another string, shortening original. - emp::String String::PopFixed(std::size_t end_pos, size_t delim_size) + String String::PopFixed(std::size_t end_pos, size_t delim_size) { - if (!end_pos) return ""; // Not popping anything! - if (end_pos >= str.size()) return PopAll(); // Popping everything! + if (!end_pos) return ""; // Not popping anything! + if (end_pos >= size()) return PopAll(); // Popping everything! - emp::String out = str.substr(0, end_pos); // Copy up to the deliminator for ouput - str.erase(0, end_pos + delim_size); // Delete output string AND delimiter + String out = substr(0, end_pos); // Copy up to the deliminator for ouput + erase(0, end_pos + delim_size); // Delete output string AND delimiter return out; } /// Remove a prefix of the string (up to a specified delimeter) and return it. If the /// delimeter is not found, return the entire string and clear it. - emp::String String::Pop(CharSet chars, bool skip_quotes, bool skip_parens) { - size_t pop_end = Find(chars, 0, skip_quotes, skip_parens); + String String::Pop(CharSet chars, const Syntax & syntax) { + size_t pop_end = Find(chars, 0, syntax); size_t delim_size = pop_end == npos ? 0 : 1; return PopFixed(pop_end, delim_size); } /// Remove a prefix of the string (up to a specified delimeter) and return it. If the /// delimeter is not found, return the entire string and clear it. - emp::String String::PopTo(std::string delim, bool skip_quotes, bool skip_parens) { - return PopFixed(Find(delim, 0, skip_quotes, skip_parens), delim.size()); + String String::PopTo(String delim, const Syntax & syntax) { + return PopFixed(Find(delim, 0, syntax), delim.size()); } - emp::String String::PopWord() { return Pop(); } - emp::String String::PopLine() { return Pop("\n"); } - - emp::String String::PopQuote() { + String String::PopQuote(const Syntax & syntax) { + if (!syntax.IsQuote(Get(0))) return String(); const size_t end_pos = FindQuoteMatch(0); - return end_pos==std::string::npos ? "" : PopFixed(end_pos+1); + return (end_pos==std::string::npos) ? "" : PopFixed(end_pos+1); } - emp::String String::PopParen(bool skip_quotes) { - const size_t end_pos = FindParenMatch(0, skip_quotes); - return end_pos==std::string::npos ? "" : PopFixed(end_pos+1); + String String::PopParen(const Syntax & syntax) { + const size_t end_pos = FindParenMatch(0, syntax); + return (end_pos==std::string::npos) ? "" : PopFixed(end_pos+1); } - size_t String::PopUInt() { + String String::PopLiteralSigned() { + size_t int_size = 0; + if (HasCharAt(0, '-') || HasCharAt(0, '+')) ++int_size; + while (int_size < size() && isdigit(Get(int_size))) ++int_size; + return PopFixed(int_size); + } + + String String::PopLiteralUnsigned() { size_t uint_size = 0; - while (uint_size < str.size() && isdigit(str[uint_size])) ++uint_size; - std::string out_uint = PopFixed(uint_size); - return std::stoull(out_uint); + while (uint_size < size() && isdigit(Get(uint_size))) ++uint_size; + return PopFixed(uint_size); + } + + String String::PopLiteralFloat() { + if (!size()) return ""; // If string is empty, not a number! + size_t pos = 0; + if (HasOneOfAt("+-", pos)) ++pos; // Allow leading +/- + while (HasDigitAt(pos)) ++pos; // Any number of digits (none is okay) + if (HasCharAt('.', pos)) { // If there's a DECIMAL PLACE, look for more digits. + ++pos; // Skip over the dot. + if (!HasDigitAt(pos++)) return ""; // Must have at least one digit after '.' + while (HasDigitAt(pos)) ++pos; // Any number of digits is okay. + } + if (HasOneOfAt("eE", pos)) { // If there's an e... SCIENTIFIC NOTATION! + ++pos; // Skip over the e. + if (HasOneOfAt("+-", pos)) ++pos; // skip leading +/- + if (!HasDigitAt(pos++)) return ""; // Must have at least one digit after 'e' + while (HasDigitAt(pos)) ++pos; // Allow for MORE digits. + } + return PopFixed(pos); + } + + template + String String::PopLiteral(const Syntax & syntax) { + if constexpr (std::is_same_v) return PopLiteralChar(syntax); + else if constexpr (std::is_base_of_v) PopQuote(syntax); + else if constexpr (std::is_floating_point_v) return PopLiteralFloat(); + else if constexpr (std::is_unsigned_v) return PopLiteralUnsigned(); + else if constexpr (std::is_signed_v) return PopLiteralSigned(); + else static_assert(emp::dependent_false(), "Invalid conversion for PopLiteral()"); + + return ""; + } + + template + T String::PopFromLiteral(const Syntax & syntax) { + return MakeFromLiteral(PopLiteral(syntax)); } /// @brief Cut up a string based on the provided delimiter; fill them in to the provided vector. /// @param out_set destination vector /// @param delim delimiter to split on (default: ",") - /// @param keep_quotes Should quoted text be kept together? (default: true) - /// @param keep_parens Should contents of parens be kept together? (default: true) + /// @param syntax identify quotes and parens that should be kept together. /// @param trim_whitespace Should whitespace around delim or assign be ignored? (default: true) void String::Slice( - emp::vector & out_set, - std::string delim, bool keep_quotes, bool keep_parens, bool trim_whitespace + emp::vector & out_set, String delim, const Syntax & syntax, bool trim_whitespace ) const { - if (str.empty()) return; // Nothing to set! + if (empty()) return; // Nothing to set! size_t start_pos = 0; - size_t found_pos = Find(delim, 0, keep_quotes, keep_parens); - while (found_pos < str.size()) { + size_t found_pos = Find(delim, 0, syntax); + while (found_pos < size()) { out_set.push_back( GetRange(start_pos, found_pos) ); - if (trim_whitespace) out_set.back().TrimWhitespace(); + if (trim_whitespace) out_set.back().Trim(); start_pos = found_pos+delim.size(); - found_pos = Find(delim, found_pos+1, keep_quotes, keep_parens); + found_pos = Find(delim, found_pos+1, syntax); } out_set.push_back( GetRange(start_pos, found_pos) ); } @@ -1015,48 +1125,44 @@ namespace emp { /// @brief Slice a String on a delimiter; return a vector of results. /// @note May be less efficient, but easier than other version of Slice() /// @param delim delimiter to split on (default: ",") - /// @param keep_quotes Should quoted text be kept together? (default: true) - /// @param keep_parens Should contents of parens be kept together? (default: true) + /// @param syntax identify quotes and parens that should be kept together. /// @param trim_whitespace Should whitespace around delim or assign be ignored? (default: true) - emp::vector String::Slice( - std::string delim, bool keep_quotes, bool keep_parens, bool trim_whitespace + emp::vector String::Slice( + String delim, const Syntax & syntax, bool trim_whitespace ) const { - emp::vector result; - Slice(result, delim, keep_quotes, keep_parens, trim_whitespace); + emp::vector result; + Slice(result, delim, syntax, trim_whitespace); return result; } /// @brief Fill vector out_set of string_views based on the provided delimiter. /// @param out_set destination vector /// @param delim delimiter to split on (default: ",") - /// @param keep_quotes Should quoted text be kept together? (default: true) - /// @param keep_parens Should contents of parens be kept together? (default: true) + /// @param syntax identify quotes and parens that should be kept together. void String::ViewSlices( - emp::vector & out_set, - std::string delim, bool keep_quotes, bool keep_parens + emp::vector & out_set, String delim, const Syntax & syntax ) const { out_set.resize(0); - if (str.empty()) return; // Nothing to set! + if (empty()) return; // Nothing to set! size_t start_pos = 0; - size_t found_pos = Find(delim, 0, keep_quotes, keep_parens); - while (found_pos < str.size()) { + size_t found_pos = Find(delim, 0, syntax); + while (found_pos < size()) { out_set.push_back( ViewRange(start_pos, found_pos) ); start_pos = found_pos+delim.size(); - found_pos = Find(delim, found_pos+1, keep_quotes, keep_parens); + found_pos = Find(delim, found_pos+1, syntax); } - out_set.push_back( ViewRange(start_pos, found_pos) ); + out_set.push_back( View(start_pos) ); } /// @brief Generate vector of string_views based on the provided delimiter. /// @param delim delimiter to split on (default: ",") - /// @param keep_quotes Should quoted text be kept together? (default: true) - /// @param keep_parens Should contents of parens be kept together? (default: true) + /// @param syntax identify quotes and parens that should be kept together. [[nodiscard]] emp::vector String::ViewSlices( - std::string delim, bool keep_quotes, bool keep_parens + String delim, const Syntax & syntax ) const { emp::vector result; - ViewSlices(result, delim, keep_quotes, keep_parens); + ViewSlices(result, delim, syntax); return result; } @@ -1064,27 +1170,26 @@ namespace emp { /// @brief Slice a string and treat each section as an assignment; place results in provided map. /// @param delim delimiter to split on (default ',') /// @param assign_op separator for left and right side of assignment (default: "=") - /// @param keep_quotes Should quoted text be kept together? (default: yes) - /// @param keep_parens Should contents of parentheses be kept together? (default: no) + /// @param syntax identify quotes and parens that should be kept together. /// @param trim_whitespace Should whitespace around delim or assign be ignored? (default: true) void String::SliceAssign( - std::map & result_map, - std::string delim, std::string assign_op, - bool keep_quotes, bool keep_parens, bool trim_whitespace + std::map & result_map, + String delim, String assign_op, + const Syntax & syntax, bool trim_whitespace ) const { - auto assign_set = Slice(delim, keep_quotes, keep_parens, false); + auto assign_set = Slice(delim, syntax, false); for (auto setting : assign_set) { if (setting.OnlyWhitespace()) continue; // Skip blank settings (especially at the end). // Remove any extra spaces around parsed values. - emp::String var_name = setting.PopTo(assign_op); + String var_name = setting.PopTo(assign_op); if (trim_whitespace) { - var_name.TrimWhitespace(); - setting.TrimWhitespace(); + var_name.Trim(); + setting.Trim(); } if (setting.empty()) { std::stringstream msg; - msg << "No assignment found in slice_assign() for: " << var_name.str; + msg << "No assignment found in slice_assign() for: " << var_name; emp::notify::Exception("emp::string_utils::slice_assign::missing_assign", msg.str(), var_name); } @@ -1096,42 +1201,41 @@ namespace emp { /// @brief Slice a string and treat each section as an assignment; fill out a map and return it. /// @param delim delimiter to split on (default ',') /// @param assign_op separator for left and right side of assignment (default: "=") - /// @param keep_quotes Should quoted text be kept together? (default: yes) - /// @param keep_parens Should contents of parentheses be kept together? (default: no) + /// @param syntax identify quotes and parens that should be kept together. /// @param trim_whitespace Should whitespace around delim or assign be ignored? (default: true) - std::map String::SliceAssign( - std::string delim, std::string assign_op, - bool keep_quotes, bool keep_parens, bool trim_whitespace + std::map String::SliceAssign( + String delim, String assign_op, + const Syntax & syntax, bool trim_whitespace ) const { - std::map result_map; - SliceAssign(result_map, delim, assign_op, keep_quotes, keep_parens, trim_whitespace); + std::map result_map; + SliceAssign(result_map, delim, assign_op, syntax, trim_whitespace); return result_map; } /// Find any instances of ${X} and replace with dictionary lookup of X. template - emp::String & String::ReplaceVars(const MAP_T & var_map, emp::String symbol, bool skip_quotes, bool skip_parens) { - for (size_t pos = Find(symbol, 0, skip_quotes, skip_parens); + String & String::ReplaceVars(const MAP_T & var_map, String symbol, const Syntax & syntax) { + for (size_t pos = Find(symbol, 0, syntax); pos < size()-3; // Need room for a replacement tag. - pos = Find(symbol, pos+symbol.size(), skip_quotes, skip_parens)) { + pos = Find(symbol, pos+symbol.size(), syntax)) { const size_t symbol_end = pos+symbol.size(); if (HasAt(symbol, symbol_end)) { // Compress two symbols (e.g., "$$") into one (e.g. "$") - str.erase(pos,symbol.size()); + erase(pos, symbol.size()); continue; } - if (str[symbol_end] != '{') continue; // Eval must be surrounded by braces. + if (Get(symbol_end) != '{') continue; // Eval must be surrounded by braces. // If we made it this far, we have a starting match! size_t end_pos = FindParenMatch(symbol_end); if (end_pos == npos) { emp::notify::Exception("emp::string_utils::replace_vars::missing_close", "No close brace found in string_utils::replace_vars()", - str); + *this); break; } - std::string key = GetRange(symbol_end+1, end_pos); + String key = GetRange(symbol_end+1, end_pos); auto replacement_it = var_map.find(key); if (replacement_it == var_map.end()) { emp::notify::Exception("emp::string_utils::replace_vars::missing_var", @@ -1150,33 +1254,34 @@ namespace emp { /// @param start_str Initial sequence of macro to look for; for example "REPLACE(" /// @param end_str Sequence that ends the macro; for example ")" /// @param macro_fun Function to call with contents of macro. Params are macro_args (string), line_num (size_t), and hit_num (size_t) - /// @param skip_quotes Should we skip quotes when looking for macro? + /// @param syntax What values should we skip as quotes or parens? /// @return This string object, post processing. + /// @todo Separate syntax into find_start syntax and find_end (inside macro) syntax. template - emp::String & String::ReplaceMacro( - std::string start_str, - std::string end_str, + String & String::ReplaceMacro( + String start_str, + String end_str, FUN_T && macro_fun, - bool skip_quotes + const String::Syntax & syntax ) { // We need to identify the comparator and divide up arguments in macro. size_t macro_count = 0; // Count of the number of hits for this macro. size_t line_num = 0; // Line number where current macro hit was found. size_t prev_pos = 0; - for (size_t macro_pos = Find(start_str, 0, skip_quotes); + for (size_t macro_pos = Find(start_str, 0, syntax); macro_pos != npos; - macro_pos = Find(start_str, macro_pos+1, skip_quotes)) + macro_pos = Find(start_str, macro_pos+1, syntax)) { // Make sure we're not just extending a previous identifier. - if (macro_pos && is_idchar(str[macro_pos-1])) continue; + if (macro_pos && is_idchar(Get(macro_pos-1))) continue; line_num += Count('\n', prev_pos, macro_pos); // Count lines leading up to this macro. // Isolate this macro instance and call the conversion function. - size_t end_pos = Find(end_str, macro_pos+start_str.size(), skip_quotes); - const std::string macro_body = GetRange(macro_pos+start_str.size(), end_pos); + size_t end_pos = Find(end_str, macro_pos+start_str.size(), syntax); + const String macro_body = GetRange(macro_pos+start_str.size(), end_pos); - std::string new_str = macro_fun(macro_body, line_num, macro_count); + String new_str = macro_fun(macro_body, line_num, macro_count); ReplaceRange(macro_pos, end_pos+end_str.size(), new_str); prev_pos = macro_pos; macro_count++; @@ -1189,31 +1294,31 @@ namespace emp { bool String::IsLiteralChar() const { // @CAO: Need to add special types of numerical escapes here (e.g., ascii codes!) // Must contain a representation of a character, surrounded by single quotes. - if (str.size() < 3 || str.size() > 4) return false; - if (str[0] != '\'' || str.back() != '\'') return false; + if (size() < 3 || size() > 4) return false; + if (Get(0) != '\'' || back() != '\'') return false; // If there's only a single character in the quotes, it's USUALLY legal. - if (str.size() == 3) return str[1] != '\'' && str[1] != '\\'; + if (size() == 3) return Get(1) != '\'' && Get(1) != '\\'; // Multiple chars must begin with a backslash. - if (str[1] != '\\') return false; + if (Get(1) != '\\') return false; CharSet chars("nrt0\\\'"); - return chars.Has(str[2]); + return chars.Has(Get(2)); } /// Test if an input string is properly formatted as a literal string. - bool String::IsLiteralString(const std::string & quote_marks) const { + bool String::IsLiteralString(const String & quote_marks) const { // Must begin and end with proper quote marks. - if (str.size() < 2 || !is_one_of(str[0], quote_marks) || str.back() != str[0]) return false; + if (size() < 2 || !is_one_of(Get(0), quote_marks) || back() != Get(0)) return false; // Are all of the characters valid? - for (size_t pos = 1; pos < str.size() - 1; pos++) { - if (str[pos] == str[0]) return false; // Cannot have a raw quote in the middle. - if (str[pos] == '\\') { // Allow escaped characters... - if (pos == str.size()-2) return false; // Backslash must have char to escape. + for (size_t pos = 1; pos < size() - 1; pos++) { + if (Get(pos) == Get(0)) return false; // Cannot have a raw quote in the middle. + if (Get(pos) == '\\') { // Allow escaped characters... + if (pos == size()-2) return false; // Backslash must have char to escape. pos++; // Skip past escaped character. - if (!is_escape_code(str[pos])) return false; // Illegal escaped character. + if (!is_escape_code(Get(pos))) return false; // Illegal escaped character. } } @@ -1223,19 +1328,19 @@ namespace emp { } /// Test if an input string is properly formatted as a literal string. - std::string String::DiagnoseLiteralString(const std::string & quote_marks) const { + String String::DiagnoseLiteralString(const String & quote_marks) const { // A literal string must begin and end with a double quote and contain only valid characters. - if (str.size() < 2) return "Too short!"; - if (!is_one_of(str[0], quote_marks)) return "Must begin an end in quotes."; - if (str.back() != str[0]) return "Must have begin and end quotes that match."; + if (size() < 2) return "Too short!"; + if (!is_one_of(Get(0), quote_marks)) return "Must begin an end in quotes."; + if (back() != Get(0)) return "Must have begin and end quotes that match."; // Are all of the characters valid? - for (size_t pos = 1; pos < str.size() - 1; pos++) { - if (str[pos] == str[0]) return "Has a floating quote."; - if (str[pos] == '\\') { - if (pos == str.size()-2) return "Cannot escape the final quote."; // Backslash must have char to escape. + for (size_t pos = 1; pos < size() - 1; pos++) { + if (Get(pos) == Get(0)) return "Has a floating quote."; + if (Get(pos) == '\\') { + if (pos == size()-2) return "Cannot escape the final quote."; // Backslash must have char to escape. pos++; - if (!is_escape_code(str[pos])) return "Unknown escape charater."; + if (!is_escape_code(Get(pos))) return "Unknown escape charater."; } } @@ -1253,33 +1358,13 @@ namespace emp { // // ------------------------------------------------------------- - // ------ External function overrides ------ - - std::ostream & operator<<(std::ostream & os, const emp::String & in) { - return os << in.cpp_str(); - } - - std::istream & operator>>(std::istream & is, emp::String & in) { - return is >> in.cpp_str(); - } - - template - STREAM_T & getline(STREAM_T && input, emp::String str, char delim) { - return getline(std::forward(input), str.cpp_str(), delim); - } - - template - STREAM_T & getline(STREAM_T && input, emp::String str) { - return getline(std::forward(input), str.cpp_str()); - } - template - emp::String MakeString(Ts... args) { + String MakeString(Ts &&... args) { return String::Make(std::forward(args)...); } - emp::String MakeEscaped(char c) { + String MakeEscaped(char c) { // If we just append as a normal character, do so! if ( (c >= 40 && c < 91) || (c > 96 && c < 127)) return emp::MakeString(c); switch (c) { @@ -1325,21 +1410,38 @@ namespace emp { return emp::MakeString(c); } - emp::String MakeEscaped(const emp::String & in) { - return emp::String(in, [](char c){ return MakeEscaped(c); }); + String MakeEscaped(const String & in) { + return String(in, [](char c){ return MakeEscaped(c); }); + } + + String MakeCSVSafe(const String & in) { + bool needsEscape = in.find_first_of(",\"\n\r") != String::npos; + if (!needsEscape) return in; + + String out; + out.reserve(in.size() + 2); // Reserve space for quotes and the string content + + out.push_back('\"'); + for (const char c : in) { + if (c == '\"') out.push_back('\"'); // Add a backslash before quotes. + out.push_back(c); + } + out.push_back('\"'); + + return out; } /// Take a string and replace reserved HTML characters with character entities - emp::String MakeWebSafe(const emp::String & in) { - emp::String out; + String MakeWebSafe(const String & in) { + String out; out.reserve(in.size()); for (char c : in) { switch (c) { - case '&': out += "&"; break; - case '<': out += "<"; break; - case '>': out += ">"; break; - case '\'': out += "&apos"; break; - case '"': out += """; break; + case '&': out += "&"; break; + case '<': out += "<"; break; + case '>': out += ">"; break; + case '\'': out += "'"; break; + case '"': out += """; break; default: out += c; } } @@ -1347,7 +1449,7 @@ namespace emp { } /// Take a char and convert it to a C++-style literal. - [[nodiscard]] emp::String MakeLiteral(char value) { + [[nodiscard]] String MakeLiteral(char value) { std::stringstream ss; ss << "'" << MakeEscaped(value) << "'"; return ss.str(); @@ -1355,7 +1457,7 @@ namespace emp { /// Take a string or iterable and convert it to a C++-style literal. // This is the version for string. The version for an iterable is below. - [[nodiscard]] emp::String MakeLiteral(const emp::String & value) { + [[nodiscard]] String MakeLiteral(const std::string & value) { // Add quotes to the ends and convert each character. std::stringstream ss; ss << "\""; @@ -1369,16 +1471,27 @@ namespace emp { #ifndef DOXYGEN_SHOULD_SKIP_THIS /// Take a value and convert it to a C++-style literal. - template [[nodiscard]] emp::String MakeLiteral(const T & value) { + template [[nodiscard]] String MakeLiteral(const T & value) { std::stringstream ss; - if constexpr (emp::IsIterable::value) { + if constexpr (std::is_convertible_v) { + std::string str(value); + return MakeLiteral(str); + } + else if constexpr (emp::IsIterable::value) { ss << "{ "; for (auto it = std::begin( value ); it != std::end( value ); ++it) { if (it != std::begin( value )) ss << ","; - ss << MakeLiteral< std::decay_t >( *it ); + ss << MakeLiteral( *it ); } ss << " }"; } + else if constexpr (std::is_arithmetic_v) { + ss << value; + String out = ss.str(); + // If there is a decimal point, remove extra zeros at back (and point if needed) + if (out.Has('.')) out.TrimBack('0').TrimBack('.'); + return out; + } else ss << value; return ss.str(); } @@ -1387,56 +1500,63 @@ namespace emp { /// Convert a literal character representation to an actual string. /// (i.e., 'A', ';', or '\n') - [[nodiscard]] char MakeFromLiteral_Char(const emp::String & value) { + [[nodiscard]] char MakeFromLiteral_Char(const String & value) { emp_assert(value.IsLiteralChar()); // Given the assert, we can assume the string DOES contain a literal representation, // and we just need to convert it. if (value.size() == 3) return value[1]; - if (value.size() == 4) return ToEscapeChar(value[2]); + if (value.size() == 4) return emp::ToEscapeChar(value[2]); return '\0'; // Error! } /// Convert a literal string representation to an actual string. - [[nodiscard]] emp::String MakeFromLiteral_String(const emp::String & value) { + [[nodiscard]] String MakeFromLiteral_String(const String & value) { /// Convert a literal string representation to an actual string. emp_assert(value.IsLiteralString(), value, value.DiagnoseLiteralString()); // Given the assert, we can assume string DOES contain a literal string representation. - emp::String out_string; + String out_string; out_string.reserve(value.size()-2); // Make a guess on final size. for (size_t pos = 1; pos < value.size() - 1; pos++) { // If we don't have an escaped character, just move it over. if (value[pos] != '\\') out_string.push_back(value[pos]); - else out_string.push_back(ToEscapeChar(value[++pos])); + else out_string.push_back(emp::ToEscapeChar(value[++pos])); } return out_string; } - [[nodiscard]] emp::String MakeFromLiteral(const emp::String & value) { - if (value.size() == 0) return ""; - if (value[0] == '\'') return MakeString(MakeFromLiteral_Char(value)); - if (value[0] == '"') return MakeFromLiteral_String(value); - // @CAO Add conversion from numerical literals, and especially octal (0-), binary (0b-), and hex (0x-) - return value; + template + [[nodiscard]] T MakeFromLiteral(const String & value) { + if (value.size() == 0) return T{}; + + if constexpr (std::is_same_v) return MakeFromLiteral_Char(value); + else if constexpr (std::is_base_of_v) return MakeFromLiteral_String(value); + else if constexpr (std::is_floating_point_v) return static_cast(std::stold(value)); + else if constexpr (std::is_unsigned_v) return static_cast(std::stoull(value)); + else if constexpr (std::is_signed_v) return static_cast(std::stoll(value)); + else { + static_assert(emp::dependent_false(), "Invalid conversion for MakeFromLiteral()"); + return T{}; + } } /// Convert a string to all uppercase. - [[nodiscard]] emp::String MakeUpper(const emp::String & value) { - return emp::String(value, [](char c){ return std::toupper(c); }); + [[nodiscard]] String MakeUpper(const String & value) { + return String(value, [](char c){ return std::toupper(c); }); } /// Convert a string to all lowercase. - [[nodiscard]] emp::String MakeLower(const emp::String & value) { - return emp::String(value, [](char c){ return std::tolower(c); }); + [[nodiscard]] String MakeLower(const String & value) { + return String(value, [](char c){ return std::tolower(c); }); } /// Make first letter of each word upper case - [[nodiscard]] emp::String MakeTitleCase(emp::String value) { + [[nodiscard]] String MakeTitleCase(String value) { constexpr int char_shift = 'a' - 'A'; bool next_upper = true; for (size_t i = 0; i < value.size(); i++) { @@ -1451,9 +1571,18 @@ namespace emp { return value; } + /// Make a string with the correct pluralization of the item being counted. For example, + /// MakeCount(1, "cow") would produce "1 cow", but MakeCount(2, "cow") would produce "2 cows". + [[nodiscard]] String MakeCount(int val, String item, const String & plural_suffix) { + if (std::abs(val) == 1) return MakeString(val, ' ', item); + return MakeString(val, " ", item, plural_suffix); + } + + [[nodiscard]] inline String MakeCount(int val, String item) { return MakeCount(val, item, "s"); } + /// Convert an integer to a roman numeral string. - [[nodiscard]] emp::String MakeRoman(int val) { - emp::String out; + [[nodiscard]] String MakeRoman(int val) { + String out; if (val < 0) { out += "-"; val *= -1; } // If out of bounds, divide up into sections of 1000 each. @@ -1480,7 +1609,7 @@ namespace emp { } template - emp::String MakeEnglishList(const CONTAINER_T & container) { + String MakeEnglishList(const CONTAINER_T & container) { if (container.size() == 0) return ""; if (container.size() == 1) return to_string(container.front()); @@ -1504,7 +1633,7 @@ namespace emp { /// See https://en.cppreference.com/w/cpp/io/c/fprintf. /// Adapted from https://stackoverflow.com/a/26221725. template - emp::String MakeFormatted(const std::string& format, Args... args) { + String MakeFormatted(const std::string& format, Args... args) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-security" @@ -1515,19 +1644,67 @@ namespace emp { std::snprintf(buf.data(), size, format.c_str(), args...); // We don't want the '\0' inside - return emp::String( buf.data(), buf.data() + size - 1 ); + return String( buf.data(), buf.data() + size - 1 ); #pragma GCC diagnostic pop } /// Concatenate n copies of a string. - emp::String MakeRepeat(emp::String base, size_t n ) { - emp::String out; + String MakeRepeat(String base, size_t n ) { + String out; out.reserve(n * base.size()); for (size_t i=0; i < n; ++i) out += base; return out; } + String MakeTrimFront(const String & in, const CharSet & chars) + { return in.substr( chars.CountFrontMatches(in) ); } + + String MakeTrimBack(const String & in, const CharSet & chars) + { return in.substr(0, in.size() - chars.CountBackMatches(in)); } + + /// Remove chars from the beginning AND end of a string. + String MakeTrimmed(String in, const CharSet & chars) + { return in.TrimFront(chars).TrimBack(chars); } + + // Take a set of characters and compress sequences of them down to a single character. + String MakeCompressed(String in, const CharSet & chars, char compress_to, + bool trim_start, bool trim_end) + { + bool skip_next = trim_start; // Remove characters from beginning of line? + size_t pos = 0; + for (const auto c : in) { + if (chars.Has(c)) { // This char should be compressed. + if (skip_next) continue; // Already skipping... + in.Get(pos++) = compress_to; // Convert any block of chars to a single replace char. + skip_next = true; + } else { // Not a compress char. + in.Get(pos++) = c; + skip_next = false; + } + } + + if (trim_end && pos && skip_next) pos--; // Remove chars from end if needed. + in.resize(pos); + + return in; + } + + /// Remove all instances of specified characters from file. + String MakeRemoveChars(String in, const CharSet & chars) { + size_t cur_pos = 0; + for (const auto c : in) { + if (!chars.Has(c)) in.Get(cur_pos++) = c; + } + in.resize(cur_pos); + return in; + } + + /// Make a string safe(r) + String MakeSlugify(String in) { + return in.SetLower().RemovePunctuation().Compress().ReplaceChar(' ', '-'); + } + /// This function returns values from a container as a single string separated /// by a given delimeter and with optional surrounding strings. /// @param container is any standard-interface container holding objects to be joined. @@ -1536,7 +1713,7 @@ namespace emp { /// @param close string to place after each string (e.g., "]" or "'") /// @return merged string of all values template - emp::String Join(const CONTAINER_T & container, std::string join_str, + String Join(const CONTAINER_T & container, std::string join_str, std::string open, std::string close) { if (container.size() == 0) return ""; if (container.size() == 1) return MakeString(open, container.front(), close); @@ -1552,17 +1729,10 @@ namespace emp { } -// ---------------------- Implementations to work with standard library ---------------------- - -namespace std { - /// Hash function to allow String to be used with unordered maps and sets (must be in std). - template <> - struct hash { - std::size_t operator()(const emp::String & str) const { - return std::hash()(str.cpp_str()); - } - }; -} +template <> +struct std::hash { + size_t operator()(const emp::String & str) const noexcept { return str.Hash(); } +}; #endif // #ifndef EMP_TOOLS_STRING_HPP_INCLUDE diff --git a/include/emp/tools/TypeTracker.hpp b/include/emp/tools/TypeTracker.hpp index bb0b8b3dcb..8f2e0d8941 100644 --- a/include/emp/tools/TypeTracker.hpp +++ b/include/emp/tools/TypeTracker.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file TypeTracker.hpp + * @file * @brief Track class types abstractly to dynamically call correct function overloads. * @note Status: BETA * @@ -21,6 +22,7 @@ #ifndef EMP_TOOLS_TYPETRACKER_HPP_INCLUDE #define EMP_TOOLS_TYPETRACKER_HPP_INCLUDE +#include #include #include "../base/array.hpp" diff --git a/include/emp/tools/_StringSyntax.hpp b/include/emp/tools/_StringSyntax.hpp new file mode 100644 index 0000000000..b96160f078 --- /dev/null +++ b/include/emp/tools/_StringSyntax.hpp @@ -0,0 +1,96 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + * @brief String helper class to specify syntax for quotes and paren. + * @note Status: ALPHA + * + * + * @todo Set up with regular expressions to handle less trivial syntax structures. + * @todo Make constexpr + * @todo Make handle non-'char' strings (i.e., use CharT template parameter) + * + */ + +#ifndef EMP_TOOLS__STRINGSYNTAX_HPP_INCLUDE +#define EMP_TOOLS__STRINGSYNTAX_HPP_INCLUDE + + +#include +#include + +#include "../base/array.hpp" +#include "../base/assert.hpp" + + +namespace emp { + + class StringSyntax { + private: + emp::array char_matches; + uint8_t count = 0; + + public: + StringSyntax() { char_matches.fill('\0'); } + StringSyntax(std::string quotes, std::string parens="") : StringSyntax() { + emp_assert(parens.size() % 2 == 0, "String::StringSyntax must have odd number of paren chars."); + for (char c : quotes) GetMatch(c) = c; + for (size_t i=0; i < parens.size(); i+=2) GetMatch(parens[i]) = parens[i+1]; + count = static_cast(quotes.size() + parens.size()/2); + } + StringSyntax(bool match_quotes, bool match_parens=false) : StringSyntax() { + if (match_quotes) GetMatch('"') = '"'; + if (match_parens) { + GetMatch('(') = ')'; + GetMatch('[') = ']'; + GetMatch('{') = '}'; + } + } + StringSyntax(const char * quotes, const char * parens="") + : StringSyntax(std::string(quotes), std::string(parens)) { } + + StringSyntax & operator=(const StringSyntax &) = default; + StringSyntax & operator=(StringSyntax &&) = default; + + char & GetMatch(char c) { emp_assert(c >= 0); return char_matches[static_cast(c)]; } + char GetMatch(char c) const { return (c >= 0) ? char_matches[static_cast(c)] : 0; } + bool IsQuote(char c) const { return (c > 0) && GetMatch(c) && (GetMatch(c) == c); } + bool IsParen(char c) const { return (c > 0) && GetMatch(c) && (GetMatch(c) != c); } + uint8_t GetCount() const { return count; } + + std::string GetQuotes() const { + std::string out; + for (char i = 0; i < 127; ++i) { + if (GetMatch(i) == i) out+= static_cast(i); + } + return out; + } + + std::string AsString() const { + std::stringstream ss; + for (char c = 0; c < 127; ++c) { + emp_assert(static_cast(c) < 128, (int) c, static_cast(c)); + if (GetMatch(c)) { + ss << "['" << c << "'->'" << GetMatch(c) << "']"; + } + } + return ss.str(); + } + + static StringSyntax None() { return StringSyntax(); } + static StringSyntax Quotes() { return StringSyntax("\""); } + static StringSyntax CharQuotes() { return StringSyntax("'"); } + static StringSyntax AllQuotes() { return StringSyntax("\"'"); } + static StringSyntax Parens() { return StringSyntax("", "()[]{}"); } + static StringSyntax RParens() { return StringSyntax("", ")(][}{"); } + static StringSyntax Full() { return StringSyntax("\"", "()[]{}"); } + static StringSyntax Max() { return StringSyntax("\"'`", "()[]{}<>"); } + }; + +} + + +#endif // #ifndef EMP_TOOLS__STRINGSYNTAX_HPP_INCLUDE diff --git a/include/emp/tools/attrs.hpp b/include/emp/tools/attrs.hpp index b1dcbcaf17..df6b3fb63e 100644 --- a/include/emp/tools/attrs.hpp +++ b/include/emp/tools/attrs.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file attrs.hpp + * @file * @brief TODO. */ @@ -14,6 +15,7 @@ #include #include #include +#include #include #include @@ -923,6 +925,8 @@ namespace emp { return {std::forward(props)...}; } + #ifndef DOXYGEN_SHOULD_SKIP_THIS // Doxygen is getting tripped up by this + namespace __impl_attrs_merge { constexpr struct { template @@ -935,7 +939,7 @@ namespace emp { /// Creates a new attribute pack which has all the attributes of this /// pack and another pack. Values will be taken from other other pack /// preferentially. - #ifndef DOXYGEN_SHOULD_SKIP_THIS // Doxygen is getting tripped up by this + template constexpr auto Merge(U&&... packs) // This hint is required by some older compilers diff --git a/include/emp/tools/char_utils.hpp b/include/emp/tools/char_utils.hpp index 4a4b14a6fb..9edd11fa93 100644 --- a/include/emp/tools/char_utils.hpp +++ b/include/emp/tools/char_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file char_utils.hpp + * @file * @brief Simple functions and tools to manipulate individual characters. * @note Status: BETA * @@ -161,10 +162,30 @@ namespace emp { /// Count the number of matches that occur in a string. size_t CountMatches(const std::string & str) const { size_t count = 0; - for (char c : str) if (Has(c)) count++; + for (char c : str) if (Has(c)) ++count; + return count; + } + + /// Count the number of matches that occur in a sub-string. + size_t CountMatches(const std::string & str, size_t start, size_t end) const { + size_t count = 0; + for (size_t i = start; i < end; ++i) if (Has(str[i])) ++count; return count; } + /// Count the number of matches that occur at the beginning of a string. + size_t CountFrontMatches(const std::string & str, size_t start=0) const { + size_t count = 0; + while (count+start < str.size() && Has(str[count+start])) count++; + return count; + } + + size_t CountBackMatches(const std::string & str) const { + size_t end_pos = str.size(); + while (end_pos > 0 && Has(str[end_pos-1])) end_pos--; + return str.size() - end_pos; + } + /// Convert this set of characters into a regex-style character set. std::string AsString() const { std::string out("["); @@ -253,7 +274,7 @@ namespace emp { } /// Convert a char after a backslash to its escaped version. - char ToEscapeChar(char c) { + inline char ToEscapeChar(char c) { switch (c) { case 'b': return '\b'; // Backspace case 'f': return '\f'; // Form feed diff --git a/include/emp/tools/hash_namify.hpp b/include/emp/tools/hash_namify.hpp index b7a89346d4..3699d8e8b3 100644 --- a/include/emp/tools/hash_namify.hpp +++ b/include/emp/tools/hash_namify.hpp @@ -1,15 +1,17 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file hash_namify.hpp + * @file * @brief A method for mapping hash values to intuitive names. */ #ifndef EMP_TOOLS_HASH_NAMIFY_HPP_INCLUDE #define EMP_TOOLS_HASH_NAMIFY_HPP_INCLUDE +#include #include #include "../base/vector.hpp" diff --git a/include/emp/tools/keyname_utils.hpp b/include/emp/tools/keyname_utils.hpp index cac3cd69f9..f35c8e7888 100644 --- a/include/emp/tools/keyname_utils.hpp +++ b/include/emp/tools/keyname_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file keyname_utils.hpp + * @file * @brief Utility functions that support the keyname file naming convention. * * Plays nice with the Python package keyname. @@ -74,9 +75,7 @@ namespace emp::keyname { } inline unpack_t unpack(const std::string & filename) { - unpack_t res; - const auto kv_strs = emp::slice( #ifndef __EMSCRIPTEN__ std::filesystem::path(filename).filename().string(), // get basename @@ -91,7 +90,7 @@ namespace emp::keyname { std::cend(kv_strs), std::inserter(res, std::end(res)), [](const std::string & kv_str){ - const auto kv_vec = emp::slice(kv_str, '=', 1); + const auto kv_vec = emp::slice(kv_str, '=', 2); emp_assert(kv_vec.size() > 0); emp_assert(kv_vec.size() <= 2); return ( diff --git a/include/emp/tools/string_utils.hpp b/include/emp/tools/string_utils.hpp index c64be4bd42..e35d2b20ba 100644 --- a/include/emp/tools/string_utils.hpp +++ b/include/emp/tools/string_utils.hpp @@ -1,214 +1,12 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2023. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2023. - * - * @file string_utils.hpp + * @file * @brief Simple functions to manipulate strings. - * @note Status: RELEASE - * - * Available Functions - * const std::string & empty_string() - Reference to an empty string for null returns - * - * -- CLASSIFICATION -- - * size_t count(const std::string & str, char c) - Count the occurrences of c in str. - * bool is_literal_char(const std::string & value) - * bool is_literal_string(const std::string & value, type="\"") - * bool is_composed_of(const std::string & test_str, const std::string & char_set) - * bool is_digits(const std::string & test_str) - * bool is_number(const std::string & test_str) - * bool is_alphanumeric(const std::string & test_str) - * bool is_whitespace(const std::string & test_str) - * bool is_valid(const std::string & test_str, FUNS... funs) - * bool has_whitespace(const std::string & test_str) - * bool has_nonwhitespace(const std::string & test_str) - * bool has_upper_letter(const std::string & test_str) - * bool has_lower_letter(const std::string & test_str) - * bool has_letter(const std::string & test_str) - * bool has_digit(const std::string & test_str) - * bool has_alphanumeric(const std::string & test_str) - * bool has_one_of(const std::string & test_str, const std::string & char_set) - * bool has_prefix(const std::string & in_string, const std::string & prefix) - * bool has_char_at(const std::string & str, char c, size_t pos) - * bool has_one_of_at(const std::string & str, const std::string & opts, size_t pos) - * bool has_digit_at(const std::string & str, size_t pos) - * bool has_letter_at(const std::string & str, size_t pos) - * - * -- SEARCHING -- - * size_t find_quote_match(std::string_view in_string, size_t start_pos=0) - * size_t find_paren_match(std::string_view in_string, size_t start_pos=0, - * bool skip_quotes=true) - * size_t find_match(std::string_view in_string, size_t start_pos=0, bool skip_quotes=true) - * size_t find(std::string_view in_string, std::string target, size_t start_pos, - * bool skip_quotes=false, bool skip_parens=false, bool skip_braces=false, - * bool skip_brackets=false) - * void find_all(std::string_view in_string, char target, emp::vector & results, - * bool skip_quotes=false, bool skip_parens=false, bool skip_braces=false, - * bool skip_brackets=false) - * emp::vector find_all(std::string_view in_string, char target, bool skip_quotes=false - * bool skip_parens=false, bool skip_braces=false, bool skip_brackets=false) - * size_t find_any_of(const std::string & test_str, std::string... tests) - * size_t find_any_of(const std::string & test_str, size_t start_pos, std::string... tests) - * size_t find_id(std::string_view in_string, std::string target, size_t start_pos, - * bool skip_quotes=true, bool skip_parens=false, bool skip_braces=false, bool skip_brackets=false) - * size_t find_non_whitespace(std::string_view in_string, size_t start_pos) - * - * -- FORMATTING -- - * std::string to_escaped_string(char value) - * std::string to_escaped_string(const std::string & value) - * std::string to_web_safe_string(const std::string & value) - * template std::string url_encode(const std::string &value) - * template std::string url_decode(const std::string& str) - * std::string to_literal(...) - * char from_literal_char(const std::string & value) - * std::string from_literal_string(const std::string & value) - * std::string to_upper(std::string value) - * std::string to_lower(std::string value) - * std::string to_titlecase(std::string value) - * std::string to_roman_numeral(int val, const std::string & prefix="") - * void trim_whitespace(std::string & in_string) - * void compress_whitespace(std::string & in_string) - * void remove_whitespace(std::string & in_string) - * void remove_punctuation(std::string & in_string) - * std::string slugify(const std::string & in_string) - * std::string combine_strings(const string_vec_t & strings, std::string spacer=" ") - * std::string to_english_list(const string_vec_t & strings) - * string_vec_t transform_strings(const string_vec_t & in_strings, - * std::function fun) - * string_vec_t quote_strings(const string_vec_t & in_strings, const std::string quote="'") - * string_vec_t quote_strings(const string_vec_t & in_strings, const std::string open_quote, - * const std::string close_quote) - * to_quoted_list(const string_vec_t & in_strings, const std::string quote="'") - * std::string format_string( const std::string& format, Args... args ) - * std::string replace_vars( const std::string& base, const MAP_T & map ) - * std::string replace_macro( const std:string &in_string, std::string macro_name, - * string(string) fun, bool skip_quotes=true) - * - * -- EXTRACTIONS and CROPPING -- - * void remove_chars(std::string & in_string, std::string chars) - * bool string_pop_if_char(std::string & in_string, char c) - * std::string string_pop_fixed(std::string & in_string, std::size_t end_pos, - * size_t delim_size=0) - * std::string string_get_range(const std::string & in_string, std::size_t start_pos, - * std::size_t end_pos) - * std::string string_pop(std::string & in_string, const char delim=' ') - * std::string string_get(const std::string & in_string, const char delim=' ', - * size_t start_pos=0) - * std::string string_pop(std::string & in_string, const std::string & delim_set) - * std::string string_get_to(const std::string & in_string, const std::string & delim=" ") - * std::string string_pop_to(std::string & in_string, const std::string & delim=" ", - * size_t start_pos=0, bool skip_quotes=false, bool skip_parens=false, - * bool skip_braces=false, bool skip_brackets=false) - * std::string string_get(const std::string & in_string, const std::string & delim_set, - * size_t start_pos=0) - * std::string string_pop_word(std::string & in_string) - * std::string string_get_word(const std::string & in_string, size_t start_pos=0) - * std::string string_pop_line(std::string & in_string) - * std::string string_get_line(const std::string & in_string, size_t start_pos=0) - * std::string string_pop_quote(std::string & in_string) - * size_t string_pop_uint(std::string & in_string) - * size_t string_get_uint(const std::string & in_string) - * std::string left_justify(std::string & in_string) - * void right_justify(std::string & in_string) - * void justify(std::string & in_string) - * - * -- STRING_VIEW HELPERS -- - * std::string_view view_string(const std::string_view & str) - * std::string_view view_string(const std::string_view & str, size_t start) - * std::string_view view_string(const std::string_view & str, size_t start, size_t npos) - * std::string_view view_string_front(const std::string_view & str, size_t npos) - * std::string_view view_string_back(const std::string_view & str, size_t npos) - * std::string_view view_string_range(const std::string_view & str, size_t start, size_t end) - * std::string_view view_string_to(const std::string_view & in_string, const char delim, - * size_t start_pos=0) - * - * -- OTHER MANIPULATIONS -- - * std::string pad_front(const std::string & in_string, char padding, size_t target_size) - * std::string pad_back(const std::string & in_string, char padding, size_t target_size) - * std::string repeat(const std::string& value, const size_t n) - * void slice(const std::string_view & in_string, emp::vector & out_set, - * const char delim='\n', [size_t max_split], bool keep_quotes=false, - * bool keep_parens=false, bool keep_braces=false, bool kee_brackets=false) - * emp::vector - * slice(const std::string_view & in_string, const char delim='\n', [size_t max_split], - * bool keep_quotes=false, bool keep_parens=false, bool keep_braces=false, - * bool keep_brackets=false) - * void view_slices(const std::string_view & in_string, emp::vector & out_set, - * char delim='\n', bool keep_quotes=false, bool keep_parens=false, - * bool keep_braces=false, bool keep_brackets=false) - * emp::vector - * view_slices(const std::string_view & in_string, char delim='\n', - * bool keep_quotes=false, bool keep_parens=false, - * bool keep_braces=false, bool keep_brackets=false) - * std::map - * slice_assign(const std::string_view & in_string, const char delim=',', - * std::string assign="=", [size_t max_split], bool trim_whitespace=true, - * bool keep_quotes=true, bool keep_parens=true, bool keep_braces=true, - * bool keep_brackets=true) - * emp::vector ViewCSV(const std::string_view & csv_line) - * std::string_view - * ViewNestedBlock(std::string_view str, const std::string symbols="()", size_t start=0) - * std::string to_string(...) - * void from_string(const std::string & str, ...) - * std::string join(const emp::vector & v, std::string join_str) - * - * -- ANSI TOOLS -- - * char ANSI_ESC() - * std::string ANSI_Reset() - * std::string ANSI_Bold() - * std::string ANSI_Faint() - * std::string ANSI_Italic() - * std::string ANSI_Underline() - * std::string ANSI_SlowBlink() - * std::string ANSI_Blink() - * std::string ANSI_Reverse() - * std::string ANSI_Strike() - * std::string ANSI_NoBold() - * std::string ANSI_NoItalic() - * std::string ANSI_NoUnderline() - * std::string ANSI_NoBlink() - * std::string ANSI_NoReverse() - * std::string ANSI_Black() - * std::string ANSI_Red() - * std::string ANSI_Green() - * std::string ANSI_Yellow() - * std::string ANSI_Blue() - * std::string ANSI_Magenta() - * std::string ANSI_Cyan() - * std::string ANSI_White() - * std::string ANSI_DefaultColor() - * std::string ANSI_BlackBG() - * std::string ANSI_RedBG() - * std::string ANSI_GreenBG() - * std::string ANSI_YellowBG() - * std::string ANSI_BlueBG() - * std::string ANSI_MagentaBG() - * std::string ANSI_CyanBG() - * std::string ANSI_WhiteBG() - * std::string ANSI_DefaultBGColor() - * std::string ANSI_BrightBlack() - * std::string ANSI_BrightRed() - * std::string ANSI_BrightGreen() - * std::string ANSI_BrightYellow() - * std::string ANSI_BrightBlue() - * std::string ANSI_BrightMagenta() - * std::string ANSI_BrightCyan() - * std::string ANSI_BrightWhite() - * std::string ANSI_BrightBlackBG() - * std::string ANSI_BrightRedBG() - * std::string ANSI_BrightGreenBG() - * std::string ANSI_BrightYellowBG() - * std::string ANSI_BrightBlueBG() - * std::string ANSI_BrightMagentaBG() - * std::string ANSI_BrightCyanBG() - * std::string ANSI_BrightWhiteBG() - * - * to_ansi_bold(const std::string & _in) - * to_ansi_italic(const std::string & _in) - * to_ansi_underline(const std::string & _in) - * to_ansi_blink(const std::string & _in) - * to_ansi_reverse(const std::string & _in) - * + * Status: RELEASE */ #ifndef EMP_TOOLS_STRING_UTILS_HPP_INCLUDE @@ -229,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -247,7 +46,6 @@ namespace emp { /// Return a const reference to an empty string. This function is useful to implement other /// functions that need to return a const reference for efficiency, but also need a null response. - static inline const std::string & empty_string() { static std::string empty = ""; return empty; @@ -669,7 +467,7 @@ namespace emp { return ss.str(); } - #endif + #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS /// Convert a literal character representation to an actual string. @@ -1035,22 +833,23 @@ namespace emp { return end_pos ? string_pop_fixed(in_string, end_pos+1) : ""; } - inline size_t string_pop_uint(std::string & in_string) { + inline size_t string_uint_size(const std::string & in_string) { size_t uint_size = 0; for (char c : in_string) { if (is_digit(c)) uint_size++; else break; } + return uint_size; + } + + inline unsigned long long string_pop_uint(std::string & in_string) { + const size_t uint_size = string_uint_size(in_string); std::string out_uint = string_pop_fixed(in_string, uint_size); return std::stoull(out_uint); } - inline size_t string_get_uint(const std::string & in_string) { - size_t uint_size = 0; - for (char c : in_string) { - if (is_digit(c)) uint_size++; - else break; - } + inline unsigned long long string_get_uint(const std::string & in_string) { + const size_t uint_size = string_uint_size(in_string); std::string out_uint = string_get_range(in_string, 0, uint_size); return std::stoull(out_uint); } @@ -1072,11 +871,13 @@ namespace emp { right_justify(in_string); } + #ifndef DOXYGEN_SHOULD_SKIP_THIS + /// Apply sprintf-like formatting to a string. - /// See https://en.cppreference.com/w/cpp/io/c/fprintf. - /// Adapted from https://stackoverflow.com/a/26221725. template - [[nodiscard]] std::string format_string( const std::string& format, Args... args ) { + std::string format_string( const std::string& format, Args... args ) { + // See https://en.cppreference.com/w/cpp/io/c/fprintf. + // Adapted from https://stackoverflow.com/a/26221725. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-security" @@ -1094,6 +895,8 @@ namespace emp { } + #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS + /// Find any instances of ${X} and replace with dictionary lookup of X. template [[nodiscard]] std::string replace_vars( const std::string& in_string, const MAP_T & var_map ); @@ -1323,9 +1126,9 @@ namespace emp { /// View a section of a string with the properly matching nested blocks. /// For example if ((abc(de))f(ghi)) would return "(abc(de))f(ghi)" at 0, "de" at 5, or /// "" at 2 (since there is no start!) - std::string_view ViewNestedBlock(std::string_view str, - const std::string symbols="()", - size_t start=0) { + static inline std::string_view ViewNestedBlock(std::string_view str, + const std::string symbols="()", + size_t start=0) { // Test if we are not starting at the beginning of a block, return empty. if (str[start] != symbols[0]) return emp::view_string(str, 0, 0); @@ -1342,8 +1145,6 @@ namespace emp { return emp::view_string(str, start+1, stop-start-1); } - #ifndef DOXYGEN_SHOULD_SKIP_THIS - // The next functions are not efficient, but they will take any number of inputs and // dynamically convert them all into a single, concatenated string. @@ -1352,6 +1153,7 @@ namespace emp { template inline std::string ToString(const emp::vector & container); + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace internal { // If the item passed in has a ToString(), always use it. @@ -1372,7 +1174,7 @@ namespace emp { } - #endif // DOXYGEN_SHOULD_SKIP_THIS + #endif // #ifndef DOXYGEN_SHOULD_SKIP_THIS /// This function does its best to convert any type to a string. Accepts any number of @@ -1573,7 +1375,6 @@ namespace emp { return ANSI_Reverse() + _in + ANSI_NoReverse(); } - ////////////////////////////////////////////////////// // Implementations of larger functions (>25 lines) ////////////////////////////////////////////////////// @@ -1898,13 +1699,48 @@ namespace emp { return out.str(); } + /// Advance a position in a string, respecting quotes, parens, braces, and brackets as indicated + /// @param in_string string being stepped through + /// @param pos Position to advance from + /// @param keep_quotes Should quoted text be treated as a unit? + /// @param keep_parens Should parens be treated as a unit? + /// @param keep_braces Should braces be treated as a unit? + /// @param keep_brackets Should brackets be treated as a unit? + static inline size_t next_pos( + std::string_view in_string, size_t pos, + bool keep_quotes=false, bool keep_parens=false, + bool keep_braces=false, bool keep_brackets=false) + { + // See if we need to skip a whole segment + const char c = in_string[pos]; + switch (c) { + case '"': case '\'': + if (keep_quotes) pos = find_quote_match(in_string, pos, c); + break; + case '(': + if (keep_parens) pos = find_paren_match(in_string, pos, c, ')', keep_quotes); + break; + case '[': + if (keep_brackets) pos = find_paren_match(in_string, pos, c, ']', keep_quotes); + break; + case '{': + if (keep_braces) pos = find_paren_match(in_string, pos, c, '}', keep_quotes); + break; + } + + return pos + 1; + } + /// Cut up a string based on the provided delimiter; fill them in to the provided vector. /// @param in_string string to be sliced /// @param out_set destination /// @param delim delimiter to split on /// @param max_split defines the maximum number of splits - /// @param keep_quotes Should quoted text be kept together? - static inline void slice ( + /// @param keep_quotes Should quoted text be treated as a unit? + /// @param keep_parens Should parens be treated as a unit? + /// @param keep_braces Should braces be treated as a unit? + /// @param keep_brackets Should brackets be treated as a unit? + static inline void slice( const std::string_view & in_string, emp::vector & out_set, const char delim, @@ -1914,51 +1750,28 @@ namespace emp { const bool keep_braces, const bool keep_brackets ) { - const size_t test_size = in_string.size(); - if (test_size == 0) return; // Nothing to set! + out_set.resize(0); + if (in_string.empty() || max_split == 0) return; // Nothing to set! - // Count produced strings - size_t out_count = 0; - size_t pos = 0; - size_t start_pos = 0; - while (pos < test_size && out_count <= max_split) { + size_t pos = 0; // Position currently being scanned. + size_t start_pos = 0; // Start position for the next segment. + while (pos < in_string.size() && out_set.size()+1 < max_split) { // Find the end of the current segment. - while (pos < test_size && in_string[pos] != delim) { - if (keep_quotes && (in_string[pos] == '"' || in_string[pos] == '\'')) { - pos = find_quote_match(in_string, pos, in_string[pos]); - } - else if (keep_parens && in_string[pos] == '(') { - pos = find_paren_match(in_string, pos, '(', ')', keep_quotes); - } - else if (keep_braces && in_string[pos] == '{') { - pos = find_paren_match(in_string, pos, '{', '}', keep_quotes); - } - else if (keep_brackets && in_string[pos] == '[') { - pos = find_paren_match(in_string, pos, '[', ']', keep_quotes); - } - pos++; + while (pos < in_string.size() && in_string[pos] != delim) { + pos = next_pos(in_string, pos, keep_quotes, keep_parens, keep_braces, keep_brackets); } // Record the current segment. - if (out_count >= out_set.size()) { - out_set.emplace_back( in_string.substr(start_pos, pos-start_pos) ); - } else { - out_set[out_count] = in_string.substr(start_pos, pos-start_pos); - } + out_set.emplace_back( in_string.substr(start_pos, pos-start_pos) ); - // Move on to the next segment. - pos++; // Skip deliminator - start_pos = pos; // Record start of segment. - out_count++; // Keep count of segments. + start_pos = ++pos; // Skip deliminator and record next start. } - if (start_pos < in_string.size()-1) { - out_set[out_count-1] += in_string.substr(start_pos - 1, in_string.size()-1); + // If there are any segments left, put them all at the end. + if (start_pos < in_string.size()) { + out_set.emplace_back( in_string.substr(start_pos, in_string.size()-start_pos) ); } - - out_set.resize(out_count); // Shrink out_set if needed. } - } #endif // #ifndef EMP_TOOLS_STRING_UTILS_HPP_INCLUDE diff --git a/include/emp/tools/timing.hpp b/include/emp/tools/timing.hpp index 61c78b06e9..a0fedfdf18 100644 --- a/include/emp/tools/timing.hpp +++ b/include/emp/tools/timing.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020. - * - * @file timing.hpp + * @file * @brief A collection of tools to help measure timing of code. * @note Status: BETA */ diff --git a/include/emp/tools/unique.hpp b/include/emp/tools/unique.hpp index 50fbc6911f..c54c362495 100644 --- a/include/emp/tools/unique.hpp +++ b/include/emp/tools/unique.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020 - * - * @file unique.hpp + * @file * @brief Methods to generate UIDs. */ @@ -13,6 +14,7 @@ #include #include #include +#include #include #include "../base/assert.hpp" diff --git a/include/emp/tools/value_utils.hpp b/include/emp/tools/value_utils.hpp index 2b48a3b18d..7d2edc05e9 100644 --- a/include/emp/tools/value_utils.hpp +++ b/include/emp/tools/value_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file value_utils.hpp + * @file * @brief Simple functions to manipulate values. * @note Status: ALPHA */ diff --git a/include/emp/web/Animate.hpp b/include/emp/web/Animate.hpp index e45039136f..4d3d2c4968 100644 --- a/include/emp/web/Animate.hpp +++ b/include/emp/web/Animate.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Animate.hpp + * @file * @brief Manage animations on a web site. * * To build an animation, you must provide a function to be run repeatedly. When Start() @@ -15,8 +16,8 @@ #ifndef EMP_WEB_ANIMATE_HPP_INCLUDE #define EMP_WEB_ANIMATE_HPP_INCLUDE - #include +#include #include "../base/assert.hpp" #include "../base/vector.hpp" @@ -82,6 +83,7 @@ namespace web { Button step_but; ///< A button to advance this animation one step. + #ifndef DOXYGEN_SHOULD_SKIP_THIS void LoadTargets() { ; } template void LoadTargets(const web::Widget & target1, const T&... other_targets) { @@ -108,6 +110,7 @@ namespace web { frame_count++; } + #endif // DOXYGEN_SHOULD_SKIP_THIS /// DoFrame() is called by default if no animation function is provided. As such, an animation /// can be built by deriving a class from Animate and overriding this function. diff --git a/include/emp/web/Attributes.hpp b/include/emp/web/Attributes.hpp index c14e9f9e0c..5832724bf7 100644 --- a/include/emp/web/Attributes.hpp +++ b/include/emp/web/Attributes.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Attributes.hpp + * @file * @brief An Attributes class for tracking non-style features about HTML objects */ @@ -39,6 +40,7 @@ namespace web { /// Return a count of the number of attributes that have been set. int GetSize() const { return (int) settings.size(); } + /// Set the specified setting to the specified value Attributes & DoSet(const std::string & in_set, const std::string & in_val) { settings[in_set] = in_val; return *this; diff --git a/include/emp/web/Button.hpp b/include/emp/web/Button.hpp index 5919d0f9d2..6d14ca3e10 100644 --- a/include/emp/web/Button.hpp +++ b/include/emp/web/Button.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018. - * - * @file Button.hpp + * @file * @brief Create/control an HTML button and call a specified function when that button is clicked. * * Use example: @@ -30,6 +31,8 @@ #ifndef EMP_WEB_BUTTON_HPP_INCLUDE #define EMP_WEB_BUTTON_HPP_INCLUDE +#include + #include "init.hpp" #include "Widget.hpp" diff --git a/include/emp/web/Canvas.hpp b/include/emp/web/Canvas.hpp index 3c5d0f3dde..6d81745113 100644 --- a/include/emp/web/Canvas.hpp +++ b/include/emp/web/Canvas.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Canvas.hpp + * @file * @brief Manage an HTML canvas object. * */ diff --git a/include/emp/web/CanvasAction.hpp b/include/emp/web/CanvasAction.hpp index c0ad0ba657..1636c804d2 100644 --- a/include/emp/web/CanvasAction.hpp +++ b/include/emp/web/CanvasAction.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file CanvasAction.hpp + * @file * @brief Define a base class for all actions that can be done to widgets, plus simple actions. * * CanvasAction objects modify the appearance of a canvas and can be tracked to reconstruct the diff --git a/include/emp/web/CanvasShape.hpp b/include/emp/web/CanvasShape.hpp index 59d9c6ce07..feed25e064 100644 --- a/include/emp/web/CanvasShape.hpp +++ b/include/emp/web/CanvasShape.hpp @@ -1,12 +1,13 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file CanvasShape.hpp + * @file * @brief Define simple shapes to draw on a canvas. * - * Canvas shapes can be definied in detail, describing how they modify a canvas. + * Canvas shapes can be defined in detail, describing how they modify a canvas. * * Other, more specific actions defined here are: * CanvasCircle @@ -16,7 +17,7 @@ #ifndef EMP_WEB_CANVASSHAPE_HPP_INCLUDE #define EMP_WEB_CANVASSHAPE_HPP_INCLUDE - +#include #include #include "../base/vector.hpp" @@ -27,7 +28,7 @@ namespace emp { namespace web { - /// Define an arbitrary shape to draw on a canvas (base clase) + /// Define an arbitrary shape to draw on a canvas (base class) class CanvasShape : public CanvasAction { protected: Point p; ///< Anchor point for this shape. @@ -92,7 +93,7 @@ namespace web { /// Track a rectangle shape to be drawn on a canvas. class CanvasRect : public CanvasShape { - double w; ///< Rectangle widgth. + double w; ///< Rectangle width. double h; ///< Rectangle height. public: CanvasRect(Point _p, double _w, double _h, @@ -115,7 +116,7 @@ namespace web { /// Clear a rectangular area in a canvas. class CanvasClearRect : public CanvasShape { - double w; ///< Rectangle widgth. + double w; ///< Rectangle width. double h; ///< Rectangle height. public: CanvasClearRect(Point _p, double _w, double _h) @@ -132,7 +133,7 @@ namespace web { /// An arbitrary-sized polygon to be drawn on a canvas. class CanvasPolygon : public CanvasShape { private: - emp::vector points; ///< Series of points defining the perimiter of the Polygon. + emp::vector points; ///< Series of points defining the perimeter of the Polygon. public: CanvasPolygon(const std::string & fc="", const std::string & lc="") : CanvasShape(0, 0, fc, lc) { ; } diff --git a/include/emp/web/Div.hpp b/include/emp/web/Div.hpp index 8f78d6b9b9..2337aa85c6 100644 --- a/include/emp/web/Div.hpp +++ b/include/emp/web/Div.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Div.hpp + * @file * @brief Div Widgets maintain an ordered collection of other widgets in an HTML div. * * When printed to the web page, these internal widgets are presented in order. diff --git a/include/emp/web/DocuExtras.hpp b/include/emp/web/DocuExtras.hpp index 026a23157a..83aed5bb1b 100644 --- a/include/emp/web/DocuExtras.hpp +++ b/include/emp/web/DocuExtras.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2019 - * - * @file DocuExtras.hpp + * @file * @brief Control the styling and attributes of an existing div without nuking * the content inside it. * @@ -27,9 +28,9 @@ namespace web { protected: class DocuExtrasInfo : public internal::WidgetInfo { - + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend DocuExtras; - + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: DocuExtrasInfo(const std::string & in_id) @@ -61,7 +62,7 @@ namespace web { }; // end of InputInfo definition - // Get a properly cast version of indo. + // Get a properly cast version of info. DocuExtrasInfo * Info() { return (DocuExtrasInfo *) info; } const DocuExtrasInfo * Info() const { return (DocuExtrasInfo *) info; } diff --git a/include/emp/web/Document.hpp b/include/emp/web/Document.hpp index b34ef054db..e48bf90f98 100644 --- a/include/emp/web/Document.hpp +++ b/include/emp/web/Document.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Document.hpp + * @file * @brief Manage an entire document. * * The Document class is built off of Div, but initializes the EMP web framework, if diff --git a/include/emp/web/Element.hpp b/include/emp/web/Element.hpp index 1a4fec7062..4dda10ebc9 100644 --- a/include/emp/web/Element.hpp +++ b/include/emp/web/Element.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file Element.hpp + * @file * @brief Element Widgets maintain an ordered collection of other widgets * in a HTML element with any tag (e.g., div, footer, header, p, etc.) * diff --git a/include/emp/web/FileInput.hpp b/include/emp/web/FileInput.hpp index 268f7a7097..8ebc62ef6b 100644 --- a/include/emp/web/FileInput.hpp +++ b/include/emp/web/FileInput.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022. - * - * @file FileInput.hpp + * @file * @brief Specs for the FileInput widget (click on to upload a file) * * @todo Setup FileInput to work outside of web mode as well. @@ -12,6 +13,7 @@ #ifndef EMP_WEB_FILEINPUT_HPP_INCLUDE #define EMP_WEB_FILEINPUT_HPP_INCLUDE +#include #include #include diff --git a/include/emp/web/Font.hpp b/include/emp/web/Font.hpp index cadf971d4a..df85b96f52 100644 --- a/include/emp/web/Font.hpp +++ b/include/emp/web/Font.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Font.hpp + * @file * @brief Maintains basic information about a font to be used in HTML. */ diff --git a/include/emp/web/Image.hpp b/include/emp/web/Image.hpp index 0e60ad9e87..163fe2e2f4 100644 --- a/include/emp/web/Image.hpp +++ b/include/emp/web/Image.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Image.hpp + * @file * @brief Easily load an image and place it in a document. */ diff --git a/include/emp/web/Input.hpp b/include/emp/web/Input.hpp index b22d03b6b7..6255709ea7 100644 --- a/include/emp/web/Input.hpp +++ b/include/emp/web/Input.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2018 - * - * @file Input.hpp + * @file * @brief Create/control an HTML input and call a specified function when it receives input. * * Use example: @@ -30,6 +31,7 @@ #ifndef EMP_WEB_INPUT_HPP_INCLUDE #define EMP_WEB_INPUT_HPP_INCLUDE +#include #include "Widget.hpp" diff --git a/include/emp/web/JSWrap.hpp b/include/emp/web/JSWrap.hpp index 8e022d17d7..3e00a624f2 100644 --- a/include/emp/web/JSWrap.hpp +++ b/include/emp/web/JSWrap.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022. - * - * @file JSWrap.hpp + * @file * @brief Wrap a C++ function and convert it to an integer that can be called from Javascript * * To wrap a function, call: @@ -40,7 +41,9 @@ #define EMP_WEB_JSWRAP_HPP_INCLUDE #include +#include #include +#include #include #include diff --git a/include/emp/web/KeypressManager.hpp b/include/emp/web/KeypressManager.hpp index d83ec0f00d..5ff2669cb6 100644 --- a/include/emp/web/KeypressManager.hpp +++ b/include/emp/web/KeypressManager.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file KeypressManager.hpp + * @file * @brief KeypressManager is a tracker for keypresses in HTML5 pages. * * When a KeypressManager is created, it can be given functions to run in response @@ -43,6 +44,7 @@ #ifndef EMP_WEB_KEYPRESSMANAGER_HPP_INCLUDE #define EMP_WEB_KEYPRESSMANAGER_HPP_INCLUDE +#include #include #include #include diff --git a/include/emp/web/Listeners.hpp b/include/emp/web/Listeners.hpp index 43fabef042..2ba1e482cf 100644 --- a/include/emp/web/Listeners.hpp +++ b/include/emp/web/Listeners.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Listeners.hpp + * @file * @brief A class for tracking font event listeners for Widgets */ @@ -19,6 +20,7 @@ #include "../tools/string_utils.hpp" #include +#include #include namespace emp { diff --git a/include/emp/web/NodeDomShim.hpp b/include/emp/web/NodeDomShim.hpp index 01ac1e3729..9f6319baf7 100644 --- a/include/emp/web/NodeDomShim.hpp +++ b/include/emp/web/NodeDomShim.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file NodeDomShim.hpp + * @file * @brief Shim for Empirical compatibility with node.js. Mimicks the browser * document object model (DOM). */ diff --git a/include/emp/web/RawImage.hpp b/include/emp/web/RawImage.hpp index 3e4f453c68..b1cd6b0ae1 100644 --- a/include/emp/web/RawImage.hpp +++ b/include/emp/web/RawImage.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file RawImage.hpp + * @file * @brief Handle the fundamental loading of an image (without Widget tracking) */ @@ -12,6 +13,7 @@ #include #include +#include #include #include diff --git a/include/emp/web/Selector.hpp b/include/emp/web/Selector.hpp index a63fc4f838..8cc92e6a20 100644 --- a/include/emp/web/Selector.hpp +++ b/include/emp/web/Selector.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Selector.hpp + * @file * @brief Specs for the Selector widget. * * A Selector widget provides the user with a pull-down menu. It can be @@ -24,6 +25,7 @@ #ifndef EMP_WEB_SELECTOR_HPP_INCLUDE #define EMP_WEB_SELECTOR_HPP_INCLUDE +#include #include "../base/vector.hpp" diff --git a/include/emp/web/Style.hpp b/include/emp/web/Style.hpp index 73a3f032bd..58ac08b963 100644 --- a/include/emp/web/Style.hpp +++ b/include/emp/web/Style.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Style.hpp + * @file * @brief A CSS class for tracking font style, etc. */ @@ -20,6 +21,7 @@ #include #include +#include #include namespace emp { diff --git a/include/emp/web/Table.hpp b/include/emp/web/Table.hpp index 9793e50bdf..e146b028f3 100644 --- a/include/emp/web/Table.hpp +++ b/include/emp/web/Table.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Table.hpp + * @file * @brief Specs for the Table widget. * * TableInfo is the core information for a table and has two helper classes: @@ -11,7 +12,7 @@ * object. * * A Table is composed of a series of rows, each with the same number of columns. - * TableDataInfo may be muliple cells wide/tall, masking other cells. + * TableDataInfo may be multiple cells wide/tall, masking other cells. * * * @todo Tables should more directly manage internal slates rather than just adding divs and @@ -27,6 +28,8 @@ #ifndef EMP_WEB_TABLE_HPP_INCLUDE #define EMP_WEB_TABLE_HPP_INCLUDE +#include + #include "../base/vector.hpp" #include "Div.hpp" @@ -36,6 +39,7 @@ namespace emp { namespace web { + #ifndef DOXYGEN_SHOULD_SKIP_THIS class TableWidget; class Table; class TableCell; @@ -44,7 +48,6 @@ namespace web { class TableRowGroup; class TableColGroup; - #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace internal { struct TableRowInfo; @@ -59,7 +62,7 @@ namespace web { emp::vector children; ///< Widgets contained in this cell. - /// Debug function to determine if this datum is structually consistent. + /// Debug function to determine if this datum is structurally consistent. bool OK(std::stringstream & ss, bool verbose=false, const std::string & prefix="") { bool ok = true; if (verbose) ss << prefix << "Scanning: emp::TableDataInfo" << std::endl; @@ -87,7 +90,7 @@ namespace web { return *this; } - /// Debug function to determine if this row is structually consistent. + /// Debug function to determine if this row is structurally consistent. bool OK(std::stringstream & ss, bool verbose=false, const std::string & prefix="") { bool ok = true; if (verbose) { ss << prefix << "Scanning: emp::TableRowInfo" << std::endl; } @@ -106,8 +109,10 @@ namespace web { }; class TableInfo : public internal::WidgetInfo { + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend TableWidget; friend Table; friend TableCell; friend TableRow; friend TableCol; friend TableRowGroup; friend TableColGroup; + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: size_t row_count; /// How big is this table? size_t col_count; @@ -235,18 +240,18 @@ namespace web { // Tables need to facilitate recursive registrations - void RegisterChildren(internal::DivInfo * regestrar) override { + void RegisterChildren(internal::DivInfo * registrar) override { for (size_t r = 0; r < row_count; r++) { for (size_t c = 0; c < col_count; c++) { - for (Widget & child : rows[r].data[c].children) regestrar->Register(child); + for (Widget & child : rows[r].data[c].children) registrar->Register(child); } } } - void UnregisterChildren(internal::DivInfo * regestrar) override { + void UnregisterChildren(internal::DivInfo * registrar) override { for (size_t r = 0; r < row_count; r++) { for (size_t c = 0; c < col_count; c++) { - for (Widget & child : rows[r].data[c].children) regestrar->Unregister(child); + for (Widget & child : rows[r].data[c].children) registrar->Unregister(child); } } } @@ -514,7 +519,9 @@ namespace web { #endif // DOXYGEN_SHOULD_SKIP_THIS class TableWidget : public internal::WidgetFacet { + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend class internal::TableInfo; + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: size_t cur_row; // Which row/col is currently active? size_t cur_col; @@ -587,14 +594,14 @@ namespace web { void ClearCells() { Info()->ClearTableCells(); } void ClearCell(size_t r, size_t c) { Info()->ClearCell(r, c); } - TableCell GetCell(size_t r, size_t c) const; ///< Focus on a specifc cell in the table. - TableRow GetRow(size_t r) const; ///< Focus on a specifc row in the table. - TableCol GetCol(size_t c) const; ///< Focus on a specifc column in the table. - TableRowGroup GetRowGroup(size_t r) const; ///< Focus on a specifc group of rows in the table. - TableColGroup GetColGroup(size_t c) const; ///< Focus on a specifc group of columns in the table. + TableCell GetCell(size_t r, size_t c) const; ///< Focus on a specific cell in the table. + TableRow GetRow(size_t r) const; ///< Focus on a specific row in the table. + TableCol GetCol(size_t c) const; ///< Focus on a specific column in the table. + TableRowGroup GetRowGroup(size_t r) const; ///< Focus on a specific group of rows in the table. + TableColGroup GetColGroup(size_t c) const; ///< Focus on a specific group of columns in the table. Table GetTable() const; ///< Focus on a the entire table. - /// Get the TExt widget assoited with the currently active cell. + /// Get the Text widget associated with the currently active cell. web::Text GetTextWidget() { return Info()->GetTextWidget(); } /// Add text to a specified cell in the table. @@ -717,7 +724,8 @@ namespace web { return *this; } - /// Apply CSS to all rows. (@CAO: Should we use fancier jquery here?) + /// Apply CSS to all rows. + // (@CAO: Should we use fancier jquery here?) template Table & RowsCSS(const std::string & setting, SETTING_TYPE && value) { for (auto & row : Info()->rows) row.extras.style.Set(setting, emp::to_string(value)); diff --git a/include/emp/web/Text.hpp b/include/emp/web/Text.hpp index 1e28d868c9..76567ede7e 100644 --- a/include/emp/web/Text.hpp +++ b/include/emp/web/Text.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file Text.hpp + * @file * @brief Specs for the Text widget. * * A representation of text on a web page. Text Widgets can be included inside of Divs or @@ -15,6 +16,8 @@ #ifndef EMP_WEB_TEXT_HPP_INCLUDE #define EMP_WEB_TEXT_HPP_INCLUDE +#include + #include "../datastructs/DynamicString.hpp" #include "Widget.hpp" @@ -25,11 +28,15 @@ namespace web { /// A Text widget handles putting text on a web page that can be controlled and modified. class Text : public internal::WidgetFacet { + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend class TextInfo; + #endif DOXYGEN_SHOULD_SKIP_THIS protected: class TextInfo : public internal::WidgetInfo { + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend Text; + #endif DOXYGEN_SHOULD_SKIP_THIS protected: DynamicString strings; ///< All string (and functions returning strings) in Text widget. bool append_ok; ///< Can this Text widget be extended? @@ -44,10 +51,15 @@ namespace web { bool AppendOK() const override { return append_ok; } void PreventAppend() override { append_ok = false; } + /// Add new text to this string. Widget Append(const std::string & in_text) override; + /// Add a function that produces text to this widget. Every time the widget is re-drawn, the + /// function will be re-run to get the latest version of the text. When a Live() function + /// wraps a variable it simply makes sure that this version of Append is called so that the + /// value of the variable is kept live. Widget Append(const std::function & in_fun) override; - // All derived widgets must suply a mechanism for providing associated HTML code. + // All derived widgets must supply a mechanism for providing associated HTML code. virtual void GetHTML(std::stringstream & HTML) override { HTML.str(""); // Clear the current text. HTML << "" // Initial span tag to keep id. @@ -60,7 +72,7 @@ namespace web { }; // End of TextInfo - // Get a properly cast version of indo. + // Get a properly cast version of info. TextInfo * Info() { return (TextInfo *) info; } const TextInfo * Info() const { return (TextInfo *) info; } @@ -83,7 +95,9 @@ namespace web { Text & Clear() { Info()->strings.Clear(); return *this; } }; - /// Add new text to this string. + #ifndef DOXYGEN_SHOULD_SKIP_THIS + + // Add new text to this string. Widget Text::TextInfo::Append(const std::string & text) { if (!append_ok) return ForwardAppend(text); // If text widget cannot append, forward to parent. strings.Append(text); // Record the new string being added. @@ -91,10 +105,10 @@ namespace web { return web::Text(this); } - /// Add a function that produces text to this widget. Every time the widget is re-drawn, the - /// function will be re-run to get the latest version of the text. When a Live() function - /// wraps a variable it simply makes sure that this version of Append is called so that the - /// value of the variable is kept live. + // Add a function that produces text to this widget. Every time the widget is re-drawn, the + // function will be re-run to get the latest version of the text. When a Live() function + // wraps a variable it simply makes sure that this version of Append is called so that the + // value of the variable is kept live. Widget Text::TextInfo::Append(const std::function & fun) { if (!append_ok) return ForwardAppend(fun); // If text widget cannot append, forward to parent. strings.Append(fun); // Record the new function being added. @@ -102,6 +116,7 @@ namespace web { return web::Text(this); } + #endif // DOXYGEN_SHOULD_SKIP_THIS } } diff --git a/include/emp/web/TextArea.hpp b/include/emp/web/TextArea.hpp index d866ab46bc..53ca53a8f8 100644 --- a/include/emp/web/TextArea.hpp +++ b/include/emp/web/TextArea.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file TextArea.hpp + * @file * @brief Specs for the TextArea widget. * * @@ -13,6 +14,8 @@ #ifndef EMP_WEB_TEXTAREA_HPP_INCLUDE #define EMP_WEB_TEXTAREA_HPP_INCLUDE +#include + #include "Widget.hpp" namespace emp { diff --git a/include/emp/web/TextFeed.hpp b/include/emp/web/TextFeed.hpp index c26363cf39..e410f5b91a 100644 --- a/include/emp/web/TextFeed.hpp +++ b/include/emp/web/TextFeed.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file TextFeed.hpp + * @file * @brief A representation of text on a web page optimized for rapid appends. * */ @@ -24,7 +25,9 @@ namespace web { /// A TextFeed widget handles putting text on a web page that can be controlled and modified. class TextFeed : public internal::WidgetFacet { + #ifndef DOXYGEN_SHOULD_SKIP_THIS friend class TextFeedInfo; + #endif // DOXYGEN_SHOULD_SKIP_THIS protected: #ifndef DOXYGEN_SHOULD_SKIP_THIS class TextFeedInfo : public internal::WidgetInfo { @@ -56,9 +59,10 @@ namespace web { bool AppendOK() const override { return append_ok; } void PreventAppend() override { append_ok = false; } + /// Add new text to this string. Widget Append(const std::string & in_text) override; - // All derived widgets must suply a mechanism for providing associated HTML code. + // All derived widgets must supply a mechanism for providing associated HTML code. virtual void GetHTML(std::stringstream & HTML) override { HTML.str(""); // Clear the current text. HTML << ""; // Initial span tag to keep id. @@ -104,7 +108,8 @@ namespace web { TextFeed & PopBack() { Info()->strings.pop_back(); return *this; } }; - /// Add new text to this string. + #ifndef DOXYGEN_SHOULD_SKIP_THIS + // Add new text to this string. Widget TextFeed::TextFeedInfo::Append(const std::string & text) { // If text widget cannot append, forward to parent. if (!append_ok) return ForwardAppend(text); @@ -139,7 +144,7 @@ namespace web { return web::TextFeed(this); } - + #endif // DOXYGEN_SHOULD_SKIP_THIS } // namespace web } // namespace emp diff --git a/include/emp/web/Tween.hpp b/include/emp/web/Tween.hpp index b832f01960..1ba69ccc1d 100644 --- a/include/emp/web/Tween.hpp +++ b/include/emp/web/Tween.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file Tween.hpp + * @file * @brief A Tween manages the gradual shift in properties of one or more widgets over time. * * To create a Tween, a duration must be specified, along with an optional default @@ -32,9 +33,9 @@ #ifndef EMP_WEB_TWEEN_HPP_INCLUDE #define EMP_WEB_TWEEN_HPP_INCLUDE +#include #include "emfunctions.hpp" - #include "Widget.hpp" diff --git a/include/emp/web/UrlParams.hpp b/include/emp/web/UrlParams.hpp index eb537eb72b..eeabbe5531 100644 --- a/include/emp/web/UrlParams.hpp +++ b/include/emp/web/UrlParams.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2019 - * - * @file UrlParams.hpp + * @file * @brief Get an unordered_map containing url query key/value parameters. * */ diff --git a/include/emp/web/Widget.hpp b/include/emp/web/Widget.hpp index afdc243a81..0510f31f23 100644 --- a/include/emp/web/Widget.hpp +++ b/include/emp/web/Widget.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022. - * - * @file Widget.hpp + * @file * @brief Widgets maintain individual components on a web page and link to Elements * * Each HTML Widget has all of its details stored in a WidgetInfo object; Multiple Widgets can @@ -33,6 +34,7 @@ #define EMP_WEB_WIDGET_HPP_INCLUDE +#include #include #include "../base/error.hpp" @@ -83,7 +85,9 @@ namespace web { class Widget { friend internal::WidgetInfo; friend internal::DivInfo; friend internal::TableInfo; protected: + #ifndef DOXYGEN_SHOULD_SKIP_THIS using WidgetInfo = internal::WidgetInfo; + #endif /*DOXYGEN_SHOULD_SKIP_THIS*/ WidgetInfo * info; ///< Information associated with this widget. /// If an Append doesn't work with current class, forward it to the parent and try there. diff --git a/include/emp/web/WidgetExtras.hpp b/include/emp/web/WidgetExtras.hpp index 872dd7345f..a9cfd0a4ae 100644 --- a/include/emp/web/WidgetExtras.hpp +++ b/include/emp/web/WidgetExtras.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file WidgetExtras.hpp + * @file * @brief A collection of extra details about HTML Widgets (attributes, style, listerns) */ diff --git a/include/emp/web/_FacetedWidget.hpp b/include/emp/web/_FacetedWidget.hpp index c1d4260971..8f63790c47 100644 --- a/include/emp/web/_FacetedWidget.hpp +++ b/include/emp/web/_FacetedWidget.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file _FacetedWidget.hpp + * @file * @brief The FacetedWidget class is used to access the protected methods of WidgetFacet such * as SetCSS and SetAttr. An example of its use can be found in include/emp/prefab/Collapse.h * diff --git a/include/emp/web/_MochaTestRunner.hpp b/include/emp/web/_MochaTestRunner.hpp index 14449b2e36..2f65cf586b 100644 --- a/include/emp/web/_MochaTestRunner.hpp +++ b/include/emp/web/_MochaTestRunner.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file _MochaTestRunner.hpp + * @file * @brief Utility class for managing software testing for Emscripten web code using the Karma + Mocha * javascript testing framework. * @@ -15,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -104,12 +106,12 @@ namespace web { /// Utility class for managing software tests written for Emscripten web code. /// IMPORTANT: This utility assumes the Karma + Mocha javascript testing framework. - // MochaTestRunner is useful because emscripten does not play very nice with the browser event queue (i.e., - // it does not relinquish control back to the browser until it finishes executing the compiled 'C++' - // code). This interacts poorly with Mocha because Mocha's 'describe' statements do not execute when - // they are called; instead, they are added to the browser's event queue. - // The MochaTestRunner exploits Mocha's describe statements + the browser's event queue to chain together - // the tests added to the MochaTestRunner. + /// MochaTestRunner is useful because emscripten does not play very nice with the browser event queue (i.e., + /// it does not relinquish control back to the browser until it finishes executing the compiled 'C++' + /// code). This interacts poorly with Mocha because Mocha's 'describe' statements do not execute when + /// they are called; instead, they are added to the browser's event queue. + /// The MochaTestRunner exploits Mocha's describe statements + the browser's event queue to chain together + /// the tests added to the MochaTestRunner. class MochaTestRunner { protected: diff --git a/include/emp/web/_TableCell.hpp b/include/emp/web/_TableCell.hpp index 6d3f037e97..c779c48941 100644 --- a/include/emp/web/_TableCell.hpp +++ b/include/emp/web/_TableCell.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018. - * - * @file _TableCell.hpp + * @file * @brief The TableCell widget, which behaves like the Table widget, but focuses on a single cell. * * DO NOT include this file directly. All files begining with '_' are for internal use only. @@ -12,6 +13,8 @@ #ifndef EMP_WEB__TABLECELL_HPP_INCLUDE #define EMP_WEB__TABLECELL_HPP_INCLUDE +#include + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace emp { diff --git a/include/emp/web/_TableCol.hpp b/include/emp/web/_TableCol.hpp index daeaa86e93..bf1a540ac5 100644 --- a/include/emp/web/_TableCol.hpp +++ b/include/emp/web/_TableCol.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018. - * - * @file _TableCol.hpp + * @file * @brief The TableCol widget, which behaves like the Table widget, but focuses on a single column. * * DO NOT include this file directly. All files begining with '_' are for internal use only. @@ -12,6 +13,8 @@ #ifndef EMP_WEB__TABLECOL_HPP_INCLUDE #define EMP_WEB__TABLECOL_HPP_INCLUDE +#include + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace emp { diff --git a/include/emp/web/_TableColGroup.hpp b/include/emp/web/_TableColGroup.hpp index c3b4eb7d09..0d00fb52f9 100644 --- a/include/emp/web/_TableColGroup.hpp +++ b/include/emp/web/_TableColGroup.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018. - * - * @file _TableColGroup.hpp + * @file * @brief The TableColGoup widget, which behaves like the Table widget, but focuses on a group of columns. * * DO NOT include this file directly. All files begining with '_' are for internal use only. @@ -12,6 +13,8 @@ #ifndef EMP_WEB__TABLECOLGROUP_HPP_INCLUDE #define EMP_WEB__TABLECOLGROUP_HPP_INCLUDE +#include + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace emp { diff --git a/include/emp/web/_TableRow.hpp b/include/emp/web/_TableRow.hpp index 16289f02ee..aaaa8d17a3 100644 --- a/include/emp/web/_TableRow.hpp +++ b/include/emp/web/_TableRow.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018. - * - * @file _TableRow.hpp + * @file * @brief The TableRow widget, which behaves like the Table widget, but focuses on a single row. * * DO NOT include this file directly. All files begining with '_' are for internal use only. @@ -12,6 +13,8 @@ #ifndef EMP_WEB__TABLEROW_HPP_INCLUDE #define EMP_WEB__TABLEROW_HPP_INCLUDE +#include + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace emp { diff --git a/include/emp/web/_TableRowGroup.hpp b/include/emp/web/_TableRowGroup.hpp index 354299d91c..36d0003bb6 100644 --- a/include/emp/web/_TableRowGroup.hpp +++ b/include/emp/web/_TableRowGroup.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018. - * - * @file _TableRowGroup.hpp + * @file * @brief The TableRowGoup widget, which behaves like the Table widget, but focuses on a group of rows. * * DO NOT include this file directly. All files begining with '_' are for internal use only. @@ -12,6 +13,8 @@ #ifndef EMP_WEB__TABLEROWGROUP_HPP_INCLUDE #define EMP_WEB__TABLEROWGROUP_HPP_INCLUDE +#include + #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace emp { diff --git a/include/emp/web/canvas_utils.hpp b/include/emp/web/canvas_utils.hpp index d6018050f8..e09fb16392 100644 --- a/include/emp/web/canvas_utils.hpp +++ b/include/emp/web/canvas_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018 - * - * @file canvas_utils.hpp + * @file * @brief Various versions of the Draw() function to draw images onto a canvas. * * Each version of Draw() takes a canvas widget and some form of data to be drawn on the widget, @@ -13,6 +14,8 @@ #ifndef EMP_WEB_CANVAS_UTILS_HPP_INCLUDE #define EMP_WEB_CANVAS_UTILS_HPP_INCLUDE +#include + #include "../base/vector.hpp" #include "../bits/BitMatrix.hpp" #include "../Evolve/StateGrid.hpp" @@ -26,7 +29,12 @@ namespace emp { namespace web { + /// Draw a Circle onto the canvas. + /// @param canvas The Canvas to draw on. + /// @param circle The circle to draw + /// @param fill The color to fill the circle with + /// @param line The color of the circle's outline void Draw(Canvas canvas, const emp::Circle & circle, const std::string & fill="", const std::string & line="") @@ -35,8 +43,12 @@ namespace web { canvas.Draw(circle, fill, line); } - /// Draw a BitMatrix onto a canvas using black and white squares (can specify cell width and height) + /// Draw a Circle onto the canvas. + /// @param canvas The Canvas to draw on. + /// @param matrix The matrix to draw + /// @param w The width of the matrix (number of columns) + /// @param h The height of the matrix (number of rows) template void Draw(Canvas canvas, const BitMatrix & matrix, double w, double h) { @@ -54,7 +66,6 @@ namespace web { } } - /// Draw a Surface, specifying the full colormap to be used. The surface has a range of circle /// bodies, each with a color id. /// @param canvas The Canvas to draw on. @@ -305,6 +316,7 @@ namespace web { /// @param line_color The color of the liens on the grid. void DrawGridBG(Canvas canvas, size_t rows, size_t cols, const std::string & bg_color, const std::string & line_color) { + canvas.Clear(bg_color); const double canvas_x = (double) canvas.GetWidth(); diff --git a/include/emp/web/color_map.hpp b/include/emp/web/color_map.hpp index db559d58aa..1dc4260ec9 100644 --- a/include/emp/web/color_map.hpp +++ b/include/emp/web/color_map.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file color_map.hpp + * @file * @brief Tools to dynamically build (and cache) color maps. */ @@ -13,6 +14,7 @@ #include #include #include +#include #include #include diff --git a/include/emp/web/commands.hpp b/include/emp/web/commands.hpp index 8eb5f22bad..f7139e0686 100644 --- a/include/emp/web/commands.hpp +++ b/include/emp/web/commands.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file commands.hpp + * @file * @brief A set of command-defining classes that can be fed into widgets using the << operator. */ @@ -49,8 +50,10 @@ namespace web { const std::string & GetStr() const { return str; } }; + #ifndef DOXYGEN_SHOULD_SKIP_THIS /// Pre-define emp::endl to insert a "
" and thus acting like a newline. static const PrintStr endl("
"); + #endif // DOXYGEN_SHOULD_SKIP_THIS } } diff --git a/include/emp/web/d3/axis.hpp b/include/emp/web/d3/axis.hpp index 93dbfb4808..dd0126b584 100644 --- a/include/emp/web/d3/axis.hpp +++ b/include/emp/web/d3/axis.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file axis.hpp + * @file * @brief Handle drawing of axes on D3 graphts. */ #ifndef EMP_WEB_D3_AXIS_HPP_INCLUDE #define EMP_WEB_D3_AXIS_HPP_INCLUDE +#include + #include "../../tools/string_utils.hpp" #include "../js_utils.hpp" diff --git a/include/emp/web/d3/d3_init.hpp b/include/emp/web/d3/d3_init.hpp index 4b1d251035..6ce798c593 100644 --- a/include/emp/web/d3/d3_init.hpp +++ b/include/emp/web/d3/d3_init.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file d3_init.hpp + * @file * @brief TODO. */ @@ -131,8 +132,8 @@ namespace D3 { /// /// Example: /// - /// - /// `D3::FormatFunction rounded = D3::FormatFunction(".2f"); + /// @code + /// D3::FormatFunction rounded = D3::FormatFunction(".2f"); /// /// std::function tooltip_display = /// [this](double d, int i, int k) {return "Data: " + to_string(rounded(d));} @@ -141,8 +142,8 @@ namespace D3 { /// /// D3::Selection example_selection = D3::SelectAll("circle"); /// - /// example_selection.SetupToolTip(tip);' - /// + /// example_selection.SetupToolTip(tip); + /// @endcode /// /// Mousing over a circle in the example selection will display /// "Data: " followed by the value of d, rounded to two decimal points. diff --git a/include/emp/web/d3/dataset.hpp b/include/emp/web/d3/dataset.hpp index 01e31a35c5..d23856558b 100644 --- a/include/emp/web/d3/dataset.hpp +++ b/include/emp/web/d3/dataset.hpp @@ -1,16 +1,19 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file dataset.hpp + * @file * @brief Tools to maintain data in D3. */ #ifndef EMP_WEB_D3_DATASET_HPP_INCLUDE #define EMP_WEB_D3_DATASET_HPP_INCLUDE +#include #include +#include #include "d3_init.hpp" diff --git a/include/emp/web/d3/histogram.hpp b/include/emp/web/d3/histogram.hpp index 9d98995261..59ece0a739 100644 --- a/include/emp/web/d3/histogram.hpp +++ b/include/emp/web/d3/histogram.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file histogram.hpp + * @file * @brief TODO. */ #ifndef EMP_WEB_D3_HISTOGRAM_HPP_INCLUDE #define EMP_WEB_D3_HISTOGRAM_HPP_INCLUDE +#include + #include "../../base/vector.hpp" #include "d3_init.hpp" #include "dataset.hpp" diff --git a/include/emp/web/d3/layout.hpp b/include/emp/web/d3/layout.hpp index 58fec896b3..fb366c4531 100644 --- a/include/emp/web/d3/layout.hpp +++ b/include/emp/web/d3/layout.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file layout.hpp + * @file * @brief Tools for laying out nodes in D3. */ diff --git a/include/emp/web/d3/scales.hpp b/include/emp/web/d3/scales.hpp index 0b80faa2d3..4a7504728f 100644 --- a/include/emp/web/d3/scales.hpp +++ b/include/emp/web/d3/scales.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file scales.hpp + * @file * @brief Tools for scaling graph axes in D3. */ #ifndef EMP_WEB_D3_SCALES_HPP_INCLUDE #define EMP_WEB_D3_SCALES_HPP_INCLUDE +#include + #include "d3_init.hpp" #include "utils.hpp" diff --git a/include/emp/web/d3/selection.hpp b/include/emp/web/d3/selection.hpp index 588261e676..f3be0090ad 100644 --- a/include/emp/web/d3/selection.hpp +++ b/include/emp/web/d3/selection.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file selection.hpp + * @file * @brief TODO. */ @@ -15,6 +16,7 @@ #include "utils.hpp" #include +#include #include #include #include diff --git a/include/emp/web/d3/svg_shapes.hpp b/include/emp/web/d3/svg_shapes.hpp index b0860f3cc1..115682f05d 100644 --- a/include/emp/web/d3/svg_shapes.hpp +++ b/include/emp/web/d3/svg_shapes.hpp @@ -1,15 +1,18 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file svg_shapes.hpp + * @file * @brief Tools to build common SVG shapes. */ #ifndef EMP_WEB_D3_SVG_SHAPES_HPP_INCLUDE #define EMP_WEB_D3_SVG_SHAPES_HPP_INCLUDE +#include + #include "../js_utils.hpp" #include "d3_init.hpp" diff --git a/include/emp/web/d3/utils.hpp b/include/emp/web/d3/utils.hpp index b5d315dc71..f1ff8ac53e 100644 --- a/include/emp/web/d3/utils.hpp +++ b/include/emp/web/d3/utils.hpp @@ -1,15 +1,17 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file utils.hpp + * @file * @brief This file contains macros used to build Empirical's C++ wrapper for D3. */ #ifndef EMP_WEB_D3_UTILS_HPP_INCLUDE #define EMP_WEB_D3_UTILS_HPP_INCLUDE +#include #include #include diff --git a/include/emp/web/d3/visual_elements.hpp b/include/emp/web/d3/visual_elements.hpp index 6a1a5288da..7f6dbe284f 100644 --- a/include/emp/web/d3/visual_elements.hpp +++ b/include/emp/web/d3/visual_elements.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file visual_elements.hpp + * @file * @brief TODO. * */ diff --git a/include/emp/web/d3/visualizations.hpp b/include/emp/web/d3/visualizations.hpp index 59112d4652..bcaba206f8 100644 --- a/include/emp/web/d3/visualizations.hpp +++ b/include/emp/web/d3/visualizations.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2017-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2017-2018 - * - * @file visualizations.hpp + * @file * @brief Tools to build D3 visualizations. */ diff --git a/include/emp/web/emfunctions.hpp b/include/emp/web/emfunctions.hpp index 1602d8041c..4368ad0dcd 100644 --- a/include/emp/web/emfunctions.hpp +++ b/include/emp/web/emfunctions.hpp @@ -1,15 +1,17 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file emfunctions.hpp + * @file * @brief Specialized, useful function for Empirical. */ #ifndef EMP_WEB_EMFUNCTIONS_HPP_INCLUDE #define EMP_WEB_EMFUNCTIONS_HPP_INCLUDE +#include #include #include "../debug/alert.hpp" diff --git a/include/emp/web/events.hpp b/include/emp/web/events.hpp index 41450a855c..9dbb3f8b4c 100644 --- a/include/emp/web/events.hpp +++ b/include/emp/web/events.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file events.hpp + * @file * @brief Event handlers that use JQuery. * * @todo Events can be further sub-divided and built up (similar to DataNode objects) so that we @@ -18,6 +19,7 @@ #ifndef EMP_WEB_EVENTS_HPP_INCLUDE #define EMP_WEB_EVENTS_HPP_INCLUDE +#include #include #include "JSWrap.hpp" diff --git a/include/emp/web/init.hpp b/include/emp/web/init.hpp index 5e4b154a1e..3bd98d4ee5 100644 --- a/include/emp/web/init.hpp +++ b/include/emp/web/init.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2018. +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2018. - * - * @file init.hpp + * @file * @brief Define Initialize() and other functions to set up Empirical to build Emscripten projects. * * Init.hpp should always be included if you are compiling Empirical's web tools with Emscripten. It @@ -233,12 +234,6 @@ namespace emp { #endif -#else // Let doxygen document a non-confusing version of Live - -/// Take a function or variable and set it up so that it can update each time a text box is redrawn. -template -std::function emp::Live(T && val) {;} - #endif #endif // #ifndef EMP_WEB_INIT_HPP_INCLUDE diff --git a/include/emp/web/js_utils.hpp b/include/emp/web/js_utils.hpp index 0c4cd97f15..5286ad9712 100644 --- a/include/emp/web/js_utils.hpp +++ b/include/emp/web/js_utils.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2022. - * - * @file js_utils.hpp + * @file * @brief Tools for passing data between C++ and Javascript. */ @@ -11,6 +12,7 @@ #define EMP_WEB_JS_UTILS_HPP_INCLUDE #include +#include #include #include @@ -29,14 +31,18 @@ namespace emp { /// getValue() from within MAIN_THREAD_EM_ASM macros. /// /// For example, say we have a templated function that takes a pointer to type - /// T. We find out the appropriate string for type T: + /// T. We find out the appropriate string for type T : + /// @code /// std::map type_map = GetTypeToStringMap(); /// std::string type_string = type_map[typeid(T).name()]; + /// @endcode /// /// Now we can pass type_string.c_str() into MAIN_THREAD_EM_ASM: - /// `MAIN_THREAD_EM_ASM({ + /// @code + /// MAIN_THREAD_EM_ASM({ /// var value = getValue($0, $1); - /// }, pointer, type_string.c_str();` + /// }, pointer, type_string.c_str(); + /// @endcode std::map get_type_to_string_map() { // Using typeid().name() could create problems because it varies by diff --git a/include/emp/web/web.hpp b/include/emp/web/web.hpp index a7574c98d8..d885212a20 100644 --- a/include/emp/web/web.hpp +++ b/include/emp/web/web.hpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2017 - * - * @file web.hpp + * @file * @brief Main file to include the entire Empirical web framework; for now, just an alias for Document.h * */ diff --git a/tests/Evolve/NK-const.cpp b/tests/Evolve/NK-const.cpp index fde043ec96..284801496f 100644 --- a/tests/Evolve/NK-const.cpp +++ b/tests/Evolve/NK-const.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file NK-const.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/Evolve/NK.cpp b/tests/Evolve/NK.cpp index d6d36a2a18..6d89248e8c 100644 --- a/tests/Evolve/NK.cpp +++ b/tests/Evolve/NK.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file NK.cpp + * @file */ #define EMP_TDEBUG diff --git a/tests/Evolve/OEE.cpp b/tests/Evolve/OEE.cpp index b0cec6394b..c63fa646ab 100644 --- a/tests/Evolve/OEE.cpp +++ b/tests/Evolve/OEE.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file OEE.cpp + * @file */ #ifndef EMP_TRACK_MEM diff --git a/tests/Evolve/Resource.cpp b/tests/Evolve/Resource.cpp index f263485ecb..81afbaa6b3 100644 --- a/tests/Evolve/Resource.cpp +++ b/tests/Evolve/Resource.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Resource.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/Evolve/StateGrid.cpp b/tests/Evolve/StateGrid.cpp index d0e02719b8..fde3a00bc1 100644 --- a/tests/Evolve/StateGrid.cpp +++ b/tests/Evolve/StateGrid.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file StateGrid.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/Evolve/Systematics.cpp b/tests/Evolve/Systematics.cpp index 26e6cb5270..c6219da33f 100644 --- a/tests/Evolve/Systematics.cpp +++ b/tests/Evolve/Systematics.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Systematics.cpp + * @file */ #include @@ -23,37 +24,40 @@ #include "emp/Evolve/World_output.hpp" #include "emp/hardware/AvidaGP.hpp" -TEST_CASE("Test Systematics", "[Evolve]") { + +TEST_CASE("Test Systematics", "[Evolve]") +{ + // Taxon emp::Taxon tx(0, "a"); - CHECK(tx.GetID() == 0); - CHECK(tx.GetParent() == nullptr); - CHECK(tx.GetInfo() == "a"); - CHECK(tx.GetNumOrgs() == 0); - CHECK(tx.GetTotOrgs() == 0); + REQUIRE(tx.GetID() == 0); + REQUIRE(tx.GetParent() == nullptr); + REQUIRE(tx.GetInfo() == "a"); + REQUIRE(tx.GetNumOrgs() == 0); + REQUIRE(tx.GetTotOrgs() == 0); tx.AddOrg(); - CHECK(tx.GetNumOrgs() == 1); + REQUIRE(tx.GetNumOrgs() == 1); tx.RemoveOrg(); - CHECK(tx.GetNumOrgs() == 0); - CHECK(tx.GetTotOrgs() == 1); - CHECK(tx.GetTotalOffspring() == 0); + REQUIRE(tx.GetNumOrgs() == 0); + REQUIRE(tx.GetTotOrgs() == 1); + REQUIRE(tx.GetTotalOffspring() == 0); emp::Ptr< emp::Taxon > parentPtr(&tx); emp::Taxon tx_1(1, "b", parentPtr); - CHECK(tx_1.GetParent() == parentPtr); + REQUIRE(tx_1.GetParent() == parentPtr); tx_1.AddTotalOffspring(); - CHECK(tx_1.GetTotalOffspring() == 1); - CHECK(tx.GetTotalOffspring() == 1); + REQUIRE(tx_1.GetTotalOffspring() == 1); + REQUIRE(tx.GetTotalOffspring() == 1); // Systematics std::function calc_taxon = [](double & o){ return o > 50.0 ? "large" : "small"; }; emp::Systematics sys1(calc_taxon); - CHECK(sys1.GetTrackSynchronous() == false); - CHECK(sys1.GetNumAncestors() == 0); - CHECK(sys1.GetNumActive() == 0); - CHECK(sys1.GetNumOutside() == 0); - CHECK(sys1.GetTreeSize() == 0); - CHECK(sys1.GetNumTaxa() == 0); + REQUIRE(sys1.GetTrackSynchronous() == false); + REQUIRE(sys1.GetNumAncestors() == 0); + REQUIRE(sys1.GetNumActive() == 0); + REQUIRE(sys1.GetNumOutside() == 0); + REQUIRE(sys1.GetTreeSize() == 0); + REQUIRE(sys1.GetNumTaxa() == 0); sys1.SetTrackSynchronous(true); CHECK(sys1.GetTrackSynchronous() == true); @@ -68,45 +72,40 @@ TEST_CASE("Test Systematics", "[Evolve]") { CHECK(sys1.GetTaxonAt({1,1})->GetInfo() == "large"); CHECK(sys1.IsTaxonAt({1,1})); sys1.RemoveOrg({1,1}); - CHECK(!sys1.IsTaxonAt({1,1})); - CHECK(sys1.GetNumActive() == 1); - sys1.AddOrg(56.0, {1,0}); - CHECK(sys1.IsTaxonAt({1,0})); - CHECK(!sys1.RemoveOrg({1,0})); - CHECK(!sys1.IsTaxonAt({1,0})); + REQUIRE(sys1.GetNumActive() == 1); // Base setters and getters - CHECK(sys1.GetStoreActive() == true); - CHECK(sys1.GetStoreAncestors() == true); - CHECK(sys1.GetStoreOutside() == false); - CHECK(sys1.GetArchive() == true); - CHECK(sys1.GetStorePosition() == true); + REQUIRE(sys1.GetStoreActive() == true); + REQUIRE(sys1.GetStoreAncestors() == true); + REQUIRE(sys1.GetStoreOutside() == false); + REQUIRE(sys1.GetArchive() == true); + REQUIRE(sys1.GetStorePosition() == true); sys1.SetStoreActive(false); - CHECK(sys1.GetStoreActive() == false); + REQUIRE(sys1.GetStoreActive() == false); sys1.SetStoreAncestors(false); - CHECK(sys1.GetStoreAncestors() == false); + REQUIRE(sys1.GetStoreAncestors() == false); sys1.SetStoreOutside(true); - CHECK(sys1.GetStoreOutside() == true); + REQUIRE(sys1.GetStoreOutside() == true); sys1.SetArchive(false); - CHECK(sys1.GetArchive() == false); + REQUIRE(sys1.GetArchive() == false); sys1.SetStorePosition(false); - CHECK(sys1.GetStorePosition() == false); + REQUIRE(sys1.GetStorePosition() == false); #ifndef NDEBUG - sys1.AddDeleteriousStepDataNode(); - CHECK(emp::assert_last_fail); + sys1.AddDeleteriousStepDataNodeImpl(true); + REQUIRE(emp::assert_last_fail); emp::assert_clear(); - sys1.AddVolatilityDataNode(); - CHECK(emp::assert_last_fail); + sys1.AddVolatilityDataNodeImpl(true); + REQUIRE(emp::assert_last_fail); emp::assert_clear(); - sys1.AddUniqueTaxaDataNode(); - CHECK(emp::assert_last_fail); + sys1.AddUniqueTaxaDataNodeImpl(true); + REQUIRE(emp::assert_last_fail); emp::assert_clear(); - sys1.AddMutationCountDataNode(); - CHECK(emp::assert_last_fail); + sys1.AddMutationCountDataNodeImpl(true); + REQUIRE(emp::assert_last_fail); emp::assert_clear(); #endif @@ -115,65 +114,56 @@ TEST_CASE("Test Systematics", "[Evolve]") { //emp::Systematics sys2(calc_taxon) my_taxon taxon1(1, "medium"); emp::Ptr ptr1 = &taxon1; - CHECK(emp::LineageLength(ptr1) == 1); + REQUIRE(emp::LineageLength(ptr1) == 1); my_taxon taxon2(1, "medium", ptr1); emp::Ptr ptr2 = &taxon2; - CHECK(emp::LineageLength(ptr1) == 1); - CHECK(emp::LineageLength(ptr2) == 2); + REQUIRE(emp::LineageLength(ptr1) == 1); + REQUIRE(emp::LineageLength(ptr2) == 2); std::unordered_map muts; muts["short"] = 12; muts["tall"] = 3; taxon2.GetData().RecordMutation(muts); - CHECK(taxon2.GetData().mut_counts.size() == 2); - CHECK(taxon2.GetData().mut_counts["tall"] == 3); + REQUIRE(taxon2.GetData().mut_counts.size() == 2); + REQUIRE(taxon2.GetData().mut_counts["tall"] == 3); emp::vector types; types.push_back("tall"); types.push_back("short"); - CHECK(emp::CountMuts(ptr2, types) == 15); - CHECK(emp::CountMutSteps(ptr2, types) == 2); - CHECK(emp::CountMutSteps(ptr2, "short") == 1); + REQUIRE(emp::CountMuts(ptr2, types) == 15); + REQUIRE(emp::CountMutSteps(ptr2, types) == 2); + REQUIRE(emp::CountMutSteps(ptr2, "short") == 1); muts["short"] = 4; taxon1.GetData().RecordMutation(muts); - CHECK(emp::CountMuts(ptr1, "short") == 4); - CHECK(emp::CountMuts(ptr2, "short") == 16); - CHECK(emp::CountMutSteps(ptr1, "short") == 1); - CHECK(emp::CountMutSteps(ptr2, "short") == 2); - - emp::Systematics sys([](const int & i){return i;}, true, true, true, false); - - // std::cout << "\nAddOrg 25 (id1, no parent)\n"; - sys.SetUpdate(0); - auto id1 = sys.AddOrg(25, nullptr); - // std::cout << "\nAddOrg -10 (id2; parent id1)\n"; - sys.SetUpdate(6); - auto id2 = sys.AddOrg(-10, id1); - // std::cout << "\nAddOrg 26 (id3; parent id1)\n"; - sys.SetUpdate(10); - auto id3 = sys.AddOrg(26, id1); - // std::cout << "\nAddOrg 27 (id4; parent id2)\n"; - sys.SetUpdate(25); - auto id4 = sys.AddOrg(27, id2); - // std::cout << "\nAddOrg 28 (id5; parent id2)\n"; - sys.SetUpdate(32); - auto id5 = sys.AddOrg(28, id2); - // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; - sys.SetUpdate(39); - auto id6 = sys.AddOrg(29, id5); - // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; - sys.SetUpdate(6); - auto id7 = sys.AddOrg(30, id1); - - CHECK(*id1 < *id2); - CHECK(sys.Parent(id2) == id1); - - // std::cout << "\nRemoveOrg (id2)\n"; + REQUIRE(emp::CountMuts(ptr1, "short") == 4); + REQUIRE(emp::CountMuts(ptr2, "short") == 16); + REQUIRE(emp::CountMutSteps(ptr1, "short") == 1); + REQUIRE(emp::CountMutSteps(ptr2, "short") == 2); + + emp::Systematics sys([](const int & i){return i;}, true, true, true, false); + + std::cout << "\nAddOrg 25 (id1, no parent)\n"; + auto id1 = sys.AddOrg(25, nullptr, 0); + std::cout << "\nAddOrg -10 (id2; parent id1)\n"; + auto id2 = sys.AddOrg(-10, id1, 6); + std::cout << "\nAddOrg 26 (id3; parent id1)\n"; + auto id3 = sys.AddOrg(26, id1, 10); + std::cout << "\nAddOrg 27 (id4; parent id2)\n"; + auto id4 = sys.AddOrg(27, id2, 25); + std::cout << "\nAddOrg 28 (id5; parent id2)\n"; + auto id5 = sys.AddOrg(28, id2, 32); + std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + auto id6 = sys.AddOrg(29, id5, 39); + std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + auto id7 = sys.AddOrg(30, id1, 6); + + + std::cout << "\nRemoveOrg (id2)\n"; sys.RemoveOrg(id1); sys.RemoveOrg(id2); double mpd = sys.GetMeanPairwiseDistance(); - // std::cout << "MPD: " << mpd <GetNumOff() == 0); CHECK(outside_taxon->GetParent()->GetID() == 8); - CHECK(sys.GetMaxDepth() == 8); - auto active = sys.GetActive(); emp::vector>> active_vec(active.begin(), active.end()); emp::Sort(active_vec, [](emp::Ptr> & a, emp::Ptr> & b){ @@ -402,92 +382,80 @@ TEST_CASE("Test Systematics", "[Evolve]") { CHECK(active_vec[10]->GetNumOrgs() == 1); CHECK(active_vec[10]->GetNumOff() == 0); CHECK(active_vec[10]->GetParent()->GetID() == 17); + } -TEST_CASE("Test not tracking ancestors", "[Evolve]") { +TEST_CASE("Test not tracking ancestors", "[Evolve]") +{ emp::Systematics sys([](const int & i){return i;}, true, false, false, false); - // std::cout << "\nAddOrg 25 (id1, no parent)\n"; - sys.SetUpdate(0); - auto id1 = sys.AddOrg(25, nullptr); - // std::cout << "\nAddOrg -10 (id2; parent id1)\n"; - sys.SetUpdate(6); - auto id2 = sys.AddOrg(-10, id1); - // std::cout << "\nAddOrg 26 (id3; parent id1)\n"; - sys.SetUpdate(10); - auto id3 = sys.AddOrg(26, id1); - // std::cout << "\nAddOrg 27 (id4; parent id2)\n"; - sys.SetUpdate(25); - auto id4 = sys.AddOrg(27, id2); - // std::cout << "\nAddOrg 28 (id5; parent id2)\n"; - sys.SetUpdate(32); - auto id5 = sys.AddOrg(28, id2); - // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; - sys.SetUpdate(39); - auto id6 = sys.AddOrg(29, id5); - // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; - sys.SetUpdate(6); - auto id7 = sys.AddOrg(30, id1); - - - // std::cout << "\nRemoveOrg (id2)\n"; + std::cout << "\nAddOrg 25 (id1, no parent)\n"; + auto id1 = sys.AddOrg(25, nullptr, 0); + std::cout << "\nAddOrg -10 (id2; parent id1)\n"; + auto id2 = sys.AddOrg(-10, id1, 6); + std::cout << "\nAddOrg 26 (id3; parent id1)\n"; + auto id3 = sys.AddOrg(26, id1, 10); + std::cout << "\nAddOrg 27 (id4; parent id2)\n"; + auto id4 = sys.AddOrg(27, id2, 25); + std::cout << "\nAddOrg 28 (id5; parent id2)\n"; + auto id5 = sys.AddOrg(28, id2, 32); + std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + auto id6 = sys.AddOrg(29, id5, 39); + std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + auto id7 = sys.AddOrg(30, id1, 6); + + + std::cout << "\nRemoveOrg (id2)\n"; sys.RemoveOrg(id1); sys.RemoveOrg(id2); - // std::cout << "\nAddOrg 31 (id8; parent id7)\n"; - sys.SetUpdate(11); - auto id8 = sys.AddOrg(31, id7); - // std::cout << "\nAddOrg 32 (id9; parent id8)\n"; - sys.SetUpdate(19); - auto id9 = sys.AddOrg(32, id8); + double mpd = sys.GetMeanPairwiseDistance(); + std::cout << "Mean Pairwise Distance = " << mpd << "\n"; + + std::cout << "\nAddOrg 31 (id8; parent id7)\n"; + auto id8 = sys.AddOrg(31, id7, 11); + std::cout << "\nAddOrg 32 (id9; parent id8)\n"; + auto id9 = sys.AddOrg(32, id8, 19); - // std::cout << "\nAddOrg 33 (id10; parent id8)\n"; - auto id10 = sys.AddOrg(33, id8); + std::cout << "\nAddOrg 33 (id10; parent id8)\n"; + auto id10 = sys.AddOrg(33, id8, 19); sys.RemoveOrg(id7); sys.RemoveOrg(id8); sys.RemoveOrg(id10); - // std::cout << "\nAddOrg 34 (id11; parent id9)\n"; - sys.SetUpdate(22); - auto id11 = sys.AddOrg(34, id9); - // std::cout << "\nAddOrg 35 (id12; parent id10)\n"; - sys.SetUpdate(23); - auto id12 = sys.AddOrg(35, id11); + + std::cout << "\nAddOrg 34 (id11; parent id9)\n"; + auto id11 = sys.AddOrg(34, id9, 22); + std::cout << "\nAddOrg 35 (id12; parent id10)\n"; + auto id12 = sys.AddOrg(35, id11, 23); sys.RemoveOrg(id9); - // std::cout << "\nAddOrg 36 (id13; parent id12)\n"; - sys.SetUpdate(27); - auto id13 = sys.AddOrg(36, id12); - // std::cout << "\nAddOrg 37 (id14; parent id13)\n"; - sys.SetUpdate(30); - auto id14 = sys.AddOrg(37, id13); + std::cout << "\nAddOrg 36 (id13; parent id12)\n"; + auto id13 = sys.AddOrg(36, id12, 27); + std::cout << "\nAddOrg 37 (id14; parent id13)\n"; + auto id14 = sys.AddOrg(37, id13, 30); sys.RemoveOrg(id13); - // std::cout << "\nAddOrg 38 (id15; parent id14)\n"; - sys.SetUpdate(33); - auto id15 = sys.AddOrg(38, id14); + std::cout << "\nAddOrg 38 (id15; parent id14)\n"; + auto id15 = sys.AddOrg(38, id14, 33); sys.RemoveOrg(id14); - // std::cout << "\nAddOrg 39 (id16; parent id11)\n"; - sys.SetUpdate(35); - auto id16 = sys.AddOrg(39, id11); - // std::cout << "\nAddOrg 40 (id17; parent id11)\n"; - auto id17 = sys.AddOrg(40, id11); + std::cout << "\nAddOrg 39 (id16; parent id11)\n"; + auto id16 = sys.AddOrg(39, id11, 35); + std::cout << "\nAddOrg 40 (id17; parent id11)\n"; + auto id17 = sys.AddOrg(40, id11, 35); - // std::cout << "\nAddOrg 41 (id18; parent id17)\n"; - sys.SetUpdate(36); - auto id18 = sys.AddOrg(41, id17); + std::cout << "\nAddOrg 41 (id18; parent id17)\n"; + auto id18 = sys.AddOrg(41, id17, 36); std::cout << "\nAddOrg 42 (id19; parent id17)\n"; - sys.SetUpdate(37); - auto id19 = sys.AddOrg(42, id17); - - CHECK(id17->GetTotalOffspring() > 0); + auto id19 = sys.AddOrg(42, id17, 37); + REQUIRE(id17->GetTotalOffspring() > 0); std::cout << "id3 = " << id3 << std::endl; std::cout << "id4 = " << id4 << std::endl; @@ -509,7 +477,7 @@ TEST_CASE("Test not tracking ancestors", "[Evolve]") { CHECK(sys.GetNumOutside() == 0); auto active = sys.GetActive(); - emp::vector>> active_vec(active.begin(), active.end()); + emp::vector> & a, emp::Ptr> & b){ return a->GetID() < b->GetID(); }); @@ -577,14 +545,11 @@ TEST_CASE("Pointer to systematics", "[evo]") { sys.Delete(); } -TEST_CASE("Test Data Struct", "[evo]") { +TEST_CASE("Test Data Struct", "[evo]") +{ emp::Ptr >> sys; sys.New([](const int & i){return i;}, true, true, true, false); - sys->AddMutationCountDataNode(); - sys->AddVolatilityDataNode(); - sys->AddUniqueTaxaDataNode(); - auto id1 = sys->AddOrg(1, nullptr); id1->GetData().fitness.Add(2); id1->GetData().phenotype = 6; @@ -606,79 +571,36 @@ TEST_CASE("Test Data Struct", "[evo]") { id4->GetData().phenotype = 3; auto id5 = sys->AddOrg(5, id4); - std::unordered_map muts; - muts["substitution"] = 1; - id5->GetData().RecordMutation(muts); - id5->GetData().RecordFitness(2); - id5->GetData().RecordPhenotype(6); + id5->GetData().mut_counts["substitution"] = 1; + id5->GetData().fitness.Add(2); + id5->GetData().phenotype = 6; - CHECK(id5->GetData().GetPhenotype() == 6); - CHECK(id5->GetData().GetFitness() == 2); CHECK(CountMuts(id4) == 3); CHECK(CountDeleteriousSteps(id4) == 1); CHECK(CountPhenotypeChanges(id4) == 1); CHECK(CountUniquePhenotypes(id4) == 2); - CHECK(LineageLength(id4) == 3); CHECK(CountMuts(id3) == 5); CHECK(CountDeleteriousSteps(id3) == 1); CHECK(CountPhenotypeChanges(id3) == 0); CHECK(CountUniquePhenotypes(id3) == 1); - CHECK(LineageLength(id3) == 2); CHECK(CountMuts(id5) == 4); CHECK(CountDeleteriousSteps(id5) == 2); CHECK(CountPhenotypeChanges(id5) == 2); CHECK(CountUniquePhenotypes(id5) == 2); - CHECK(LineageLength(id5) == 4); - - CHECK(FindDominant(*sys) == id4); - - sys->GetDataNode("mutation_count")->PullData(); - CHECK(sys->GetDataNode("mutation_count")->GetMean() == Approx(2.8)); - - sys->GetDataNode("volatility")->PullData(); - CHECK(sys->GetDataNode("volatility")->GetMean() == Approx(0.6)); - - sys->GetDataNode("unique_taxa")->PullData(); - CHECK(sys->GetDataNode("unique_taxa")->GetMean() == Approx(1.4)); - sys.Delete(); - emp::Ptr> sys2; - sys2.New([](const int & i){return i;}, true, true, true, false); - sys2->AddDeleteriousStepDataNode(); - - auto new_tax = sys2->AddOrg(1, nullptr); - new_tax->GetData().RecordFitness(2); - CHECK(new_tax->GetData().GetFitness() == 2); - new_tax->GetData().RecordFitness(4); - CHECK(new_tax->GetData().GetFitness() == 3); - - emp::datastruct::fitness fit_data; - fit_data.RecordFitness(5); - new_tax->SetData(fit_data); - CHECK(new_tax->GetData().GetFitness() == 5); - - auto tax2 = sys2->AddOrg(2, new_tax); - tax2->GetData().RecordFitness(1); - - sys->GetDataNode("deleterious_steps")->PullData(); - CHECK(sys->GetDataNode("deleterious_steps")->GetMean() == Approx(.5)); - - - sys2.Delete(); - - } + TEST_CASE("World systematics integration", "[evo]") { - std::function, emp::datastruct::mut_landscape_info>>, emp::vector &)> setup_phenotype = [](emp::Ptr, emp::datastruct::mut_landscape_info>> tax, emp::vector & org){ - tax->GetData().phenotype = emp::Sum(tax->GetInfo()); - }; + // std::function, emp::datastruct::mut_landscape_info>>)> setup_phenotype = [](emp::Ptr, emp::datastruct::mut_landscape_info>> tax){ + // tax->GetData().phenotype = emp::Sum(tax->GetInfo()); + // }; using systematics_t = emp::Systematics< emp::vector, @@ -693,15 +615,14 @@ TEST_CASE("World systematics integration", "[evo]") { world.SetMutFun([](emp::vector & org, emp::Random & r){return 0;}); - sys->OnNew(setup_phenotype); + // world.GetSystematics().OnNew(setup_phenotype); world.InjectAt(emp::vector({1,2,3}), 0); - CHECK(sys->GetTaxonAt(0)->GetData().phenotype == 6); - sys->GetTaxonAt(0)->GetData().RecordPhenotype(10); - CHECK(sys->GetTaxonAt(0)->GetData().phenotype == 10); - + sys->GetTaxonAt(0)->GetData().RecordPhenotype(6); sys->GetTaxonAt(0)->GetData().RecordFitness(2); + REQUIRE(sys->GetTaxonAt(0)->GetData().phenotype == 6); + std::unordered_map mut_counts; mut_counts["substitution"] = 3; @@ -709,10 +630,10 @@ TEST_CASE("World systematics integration", "[evo]") { auto old_taxon = sys->GetTaxonAt(0); world.DoBirth(new_org,0); - CHECK(old_taxon->GetNumOrgs() == 0); - CHECK(old_taxon->GetNumOff() == 1); - CHECK(sys->GetTaxonAt(0)->GetParent()->GetData().phenotype == 10); - CHECK((*sys->GetActive().begin())->GetNumOrgs() == 1); + REQUIRE(old_taxon->GetNumOrgs() == 0); + REQUIRE(old_taxon->GetNumOff() == 1); + REQUIRE(sys->GetTaxonAt(0)->GetParent()->GetData().phenotype == 6); + REQUIRE((*sys->GetActive().begin())->GetNumOrgs() == 1); } @@ -721,64 +642,35 @@ emp::DataFile AddDominantFile(WORLD_TYPE & world){ using mut_count_t [[maybe_unused]] = std::unordered_map; using data_t = emp::datastruct::mut_landscape_info>; using org_t = emp::AvidaGP; - using systematics_t = emp::Systematics; + using systematics_t = emp::Systematics; - auto & file = world.SetupFile("dominant.csv"); + auto & file = world.SetupFile("dominant.csv"); - std::function get_update = [&world](){return world.GetUpdate();}; - std::function dom_mut_count = [&world](){ - emp::Ptr> sys = world.GetSystematics(0); - emp::Ptr full_sys = sys.DynamicCast(); - if (full_sys->GetNumActive() > 0) { - return emp::CountMuts(emp::FindDominant(*full_sys)); - } - return 0; - }; - std::function dom_del_step = [&world](){ - emp::Ptr> sys = world.GetSystematics(0); - emp::Ptr full_sys = sys.DynamicCast(); - if (full_sys->GetNumActive() > 0) { - return emp::CountDeleteriousSteps(emp::FindDominant(*full_sys)); - } - return 0; - }; - std::function dom_phen_vol = [&world](){ - emp::Ptr> sys = world.GetSystematics(0); - emp::Ptr full_sys = sys.DynamicCast(); - if (full_sys->GetNumActive() > 0) { - return emp::CountPhenotypeChanges(emp::FindDominant(*full_sys)); - } - return 0; - }; - std::function dom_unique_phen = [&world](){ - emp::Ptr> sys = world.GetSystematics(0); - emp::Ptr full_sys = sys.DynamicCast(); - if (full_sys->GetNumActive() > 0) { - return emp::CountUniquePhenotypes(emp::FindDominant(*full_sys)); - } - return 0; - }; - std::function lin_len = [&world](){ - emp::Ptr> sys = world.GetSystematics(0); - emp::Ptr full_sys = sys.DynamicCast(); - if (full_sys->GetNumActive() > 0) { - return emp::LineageLength(emp::FindDominant(*full_sys)); - } - return 0; - }; - - file.AddFun(get_update, "update", "Update"); - file.AddFun(dom_mut_count, "dominant_mutation_count", "sum of mutations along dominant organism's lineage"); - file.AddFun(dom_del_step, "dominant_deleterious_steps", "count of deleterious steps along dominant organism's lineage"); - file.AddFun(dom_phen_vol, "dominant_phenotypic_volatility", "count of changes in phenotype along dominant organism's lineage"); - file.AddFun(dom_unique_phen, "dominant_unique_phenotypes", "count of unique phenotypes along dominant organism's lineage"); - file.AddFun(lin_len, "lineage_length", "number of taxa dominant organism's lineage"); - file.PrintHeaderKeys(); - return file; + std::function get_update = [&world](){return world.GetUpdate();}; + std::function dom_mut_count = [&world](){ + return CountMuts(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); + }; + std::function dom_del_step = [&world](){ + return CountDeleteriousSteps(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); + }; + std::function dom_phen_vol = [&world](){ + return CountPhenotypeChanges(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); + }; + std::function dom_unique_phen = [&world](){ + return CountUniquePhenotypes(dynamic_cast>(world.GetSystematics(0))->GetTaxonAt(0)); + }; + + + file.AddFun(get_update, "update", "Update"); + file.AddFun(dom_mut_count, "dominant_mutation_count", "sum of mutations along dominant organism's lineage"); + file.AddFun(dom_del_step, "dominant_deleterious_steps", "count of deleterious steps along dominant organism's lineage"); + file.AddFun(dom_phen_vol, "dominant_phenotypic_volatility", "count of changes in phenotype along dominant organism's lineage"); + file.AddFun(dom_unique_phen, "dominant_unique_phenotypes", "count of unique phenotypes along dominant organism's lineage"); + file.PrintHeaderKeys(); + return file; } -// Integration test for using multiple systematics managers in a world and recording data TEST_CASE("Run world", "[evo]") { using mut_count_t = std::unordered_map; using data_t = emp::datastruct::mut_landscape_info>; @@ -816,32 +708,6 @@ TEST_CASE("Run world", "[evo]") { world.AddSystematics(gene_sys); world.AddSystematics(phen_sys); - std::function, emp::AvidaGP&)> check_update = [&gene_sys, &world](emp::Ptr tax, emp::AvidaGP & org){ - CHECK(tax->GetOriginationTime() == gene_sys->GetUpdate()); - CHECK(tax->GetOriginationTime() == world.GetUpdate()); - CHECK(tax->GetNumOff() == 0); - }; - - gene_sys->OnNew(check_update); - - std::function)> extinction_checks = [&gene_sys, &world](emp::Ptr tax){ - CHECK(tax->GetDestructionTime() == gene_sys->GetUpdate()); - CHECK(tax->GetDestructionTime() == world.GetUpdate()); - CHECK(tax->GetNumOrgs() == 0); - }; - - gene_sys->OnExtinct(extinction_checks); - - std::function)> prune_checks = [&world](emp::Ptr tax){ - CHECK(tax->GetNumOrgs() == 0); - CHECK(tax->GetNumOff() == 0); - CHECK(tax->GetOriginationTime() <= world.GetUpdate()); - CHECK(tax->GetDestructionTime() <= world.GetUpdate()); - }; - - gene_sys->OnPrune(prune_checks); - - emp::Signal on_mutate_sig; ///< Trigger signal before organism gives birth. emp::Signal record_fit_sig; ///< Trigger signal before organism gives birth. emp::Signal)> record_phen_sig; ///< Trigger signal before organism gives birth. @@ -858,12 +724,9 @@ TEST_CASE("Run world", "[evo]") { world.GetSystematics(1).Cast()->GetTaxonAt(pos)->GetData().RecordPhenotype(phen); }); - emp::Ptr> sys0 = world.GetSystematics(0); - emp::Ptr sys0_cast = sys0.DynamicCast(); - std::function, emp::AvidaGP&)> capture_mut_fun = [&last_mutation](emp::Ptr tax, emp::AvidaGP & org){ - tax->GetData().RecordMutation(last_mutation); - }; - sys0_cast->OnNew(capture_mut_fun); + // world.OnOrgPlacement([&last_mutation, &world](size_t pos){ + // world.GetSystematics(0).Cast()->GetTaxonAt(pos)->GetData().RecordMutation(last_mutation); + // }); world.SetupSystematicsFile().SetTimingRepeat(1); world.SetupFitnessFile().SetTimingRepeat(1); @@ -871,7 +734,7 @@ TEST_CASE("Run world", "[evo]") { emp::AddPhylodiversityFile(world, 0, "genotype_phylodiversity.csv").SetTimingRepeat(1); emp::AddPhylodiversityFile(world, 1, "phenotype_phylodiversity.csv").SetTimingRepeat(1); emp::AddLineageMutationFile(world).SetTimingRepeat(1); - AddDominantFile(world).SetTimingRepeat(1); + // AddDominantFile(world).SetTimingRepeat(1); // emp::AddMullerPlotFile(world).SetTimingOnce(1); @@ -910,7 +773,15 @@ TEST_CASE("Run world", "[evo]") { world.SetFitFun(fit_fun); - // Build a random initial population. + // emp::vector< std::function > fit_set(16); + // for (size_t out_id = 0; out_id < 16; out_id++) { + // // Setup the fitness function. + // fit_set[out_id] = [out_id](const emp::AvidaGP & org) { + // return (double) -std::abs(org.GetOutput((int)out_id) - (double) (out_id * out_id)); + // }; + // } + + // Build a random initial popoulation. for (size_t i = 0; i < 1; i++) { emp::AvidaGP cpu; cpu.PushRandom(random, 20); @@ -927,34 +798,47 @@ TEST_CASE("Run world", "[evo]") { // Update the status of all organisms. world.ResetHardware(); world.Process(200); - TournamentSelect(world, 2, 100); + double fit0 = world.CalcFitnessID(0); + std::cout << (ud+1) << " : " << 0 << " : " << fit0 << std::endl; + + // Keep the best individual. + EliteSelect(world, 1, 1); + // Run a tournament for the rest... + TournamentSelect(world, 2, 99); + // LexicaseSelect(world, fit_set, POP_SIZE-1); + // EcoSelect(world, fit_fun, fit_set, 100, 5, POP_SIZE-1); for (size_t i = 0; i < world.GetSize(); i++) { record_fit_sig.Trigger(i, world.CalcFitnessID(i)); record_phen_sig.Trigger(i, phen_fun(world.GetOrg(i))); } world.Update(); - CHECK(world.GetUpdate() == gene_sys->GetUpdate()); - CHECK(world.GetUpdate() == phen_sys->GetUpdate()); - CHECK(gene_sys->GetTaxonAt(0)->GetOriginationTime() <= world.GetUpdate()); + } + + // std::cout << std::endl; + // world[0].PrintGenome(); + // std::cout << std::endl; + // for (int i = 0; i < 16; i++) { + // std::cout << i << ":" << world[0].GetOutput(i) << " "; + // } + // std::cout << std::endl; } -TEST_CASE("Test GetCanopy", "[evo]") { + + +TEST_CASE("Test GetCanopy", "[evo]") +{ emp::Systematics sys([](const int & i){return i;}, true, true, true, false); - sys.SetUpdate(0); - auto id1 = sys.AddOrg(1, nullptr); - sys.SetUpdate(2); - auto id2 = sys.AddOrg(2, id1); - sys.SetUpdate(3); - auto id3 = sys.AddOrg(3, id1); - auto id4 = sys.AddOrg(4, id2); + auto id1 = sys.AddOrg(1, nullptr, 0); + auto id2 = sys.AddOrg(2, id1, 2); + auto id3 = sys.AddOrg(3, id1, 3); + auto id4 = sys.AddOrg(4, id2, 3); - sys.RemoveOrg(id1); - sys.SetUpdate(5); - sys.RemoveOrg(id2); + sys.RemoveOrg(id1, 3); + sys.RemoveOrg(id2, 5); auto can_set = sys.GetCanopyExtantRoots(4); @@ -971,8 +855,7 @@ TEST_CASE("Test GetCanopy", "[evo]") { CHECK(Has(can_set, id1)); CHECK(Has(can_set, id2)); - sys.SetUpdate(7); - sys.RemoveOrg(id3); + sys.RemoveOrg(id3, 7); can_set = sys.GetCanopyExtantRoots(2); @@ -982,14 +865,10 @@ TEST_CASE("Test GetCanopy", "[evo]") { CHECK(can_set.size() == 1); CHECK(Has(can_set, id2)); - sys.SetUpdate(8); - auto id5 = sys.AddOrg(5, id4); - sys.SetUpdate(9); - sys.RemoveOrg(id4); - sys.SetUpdate(10); - auto id6 = sys.AddOrg(6, id5); - sys.SetUpdate(11); - sys.RemoveOrg(id5); + auto id5 = sys.AddOrg(5, id4, 8); + sys.RemoveOrg(id4, 9); + auto id6 = sys.AddOrg(6, id5, 10); + sys.RemoveOrg(id5, 11); can_set = sys.GetCanopyExtantRoots(7); // Should only be 4 @@ -1001,20 +880,16 @@ TEST_CASE("Test GetCanopy", "[evo]") { CHECK(can_set.size() == 1); CHECK(Has(can_set, id5)); - sys.SetUpdate(12); - auto id7 = sys.AddOrg(7, id6); - sys.SetUpdate(13); - auto id8 = sys.AddOrg(8, id7); - sys.SetUpdate(14); - auto id9 = sys.AddOrg(9, id8); - sys.SetUpdate(15); - auto id10 = sys.AddOrg(10, id9); - - sys.SetUpdate(20); - sys.RemoveOrg(id6); - sys.RemoveOrg(id7); - sys.RemoveOrg(id8); - sys.RemoveOrg(id9); + + auto id7 = sys.AddOrg(7, id6, 12); + auto id8 = sys.AddOrg(8, id7, 13); + auto id9 = sys.AddOrg(9, id8, 14); + auto id10 = sys.AddOrg(10, id9, 15); + + sys.RemoveOrg(id6, 20); + sys.RemoveOrg(id7, 20); + sys.RemoveOrg(id8, 20); + sys.RemoveOrg(id9, 20); can_set = sys.GetCanopyExtantRoots(22); // Should only be 10 @@ -1043,6 +918,13 @@ TEST_CASE("Test GetCanopy", "[evo]") { CHECK(can_set.size() == 1); CHECK(Has(can_set, id5)); + + // auto id5 = sys.AddOrg(28, id2, 32); + // std::cout << "\nAddOrg 29 (id6; parent id5)\n"; + // auto id6 = sys.AddOrg(29, id5, 39); + // std::cout << "\nAddOrg 30 (id7; parent id1)\n"; + // auto id7 = sys.AddOrg(30, id1, 6); + } // Tests from Shao 1990 tree balance paper diff --git a/tests/Evolve/World.cpp b/tests/Evolve/World.cpp index c313d6f9be..d1e13af5c9 100644 --- a/tests/Evolve/World.cpp +++ b/tests/Evolve/World.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/Evolve/World_iterator.cpp b/tests/Evolve/World_iterator.cpp index 9de0153861..dde6ba555e 100644 --- a/tests/Evolve/World_iterator.cpp +++ b/tests/Evolve/World_iterator.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World_iterator.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/Evolve/World_output.cpp b/tests/Evolve/World_output.cpp index 1731738535..e61e7b67bc 100644 --- a/tests/Evolve/World_output.cpp +++ b/tests/Evolve/World_output.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World_output.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/Evolve/World_reflect.cpp b/tests/Evolve/World_reflect.cpp index 694ad9e63d..a57793e407 100644 --- a/tests/Evolve/World_reflect.cpp +++ b/tests/Evolve/World_reflect.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World_reflect.cpp + * @file */ #include diff --git a/tests/Evolve/World_select.cpp b/tests/Evolve/World_select.cpp index dbe5e2b9d8..4e2d5edeeb 100644 --- a/tests/Evolve/World_select.cpp +++ b/tests/Evolve/World_select.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World_select.cpp + * @file */ #include diff --git a/tests/Evolve/World_structure.cpp b/tests/Evolve/World_structure.cpp index 34b516eba0..4bb53bb498 100644 --- a/tests/Evolve/World_structure.cpp +++ b/tests/Evolve/World_structure.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file World_structure.cpp + * @file */ #define EMP_TDEBUG diff --git a/tests/OLD/Slideshow/Slideshow.cpp b/tests/OLD/Slideshow/Slideshow.cpp index e7007f7631..e9af79edf5 100644 --- a/tests/OLD/Slideshow/Slideshow.cpp +++ b/tests/OLD/Slideshow/Slideshow.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file Slideshow.cpp + * @file */ #include "../../UI/UI.h" diff --git a/tests/OLD/UI/Animate.cpp b/tests/OLD/UI/Animate.cpp index 9b41b2a599..77e365b22e 100644 --- a/tests/OLD/UI/Animate.cpp +++ b/tests/OLD/UI/Animate.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Animate.cpp + * @file */ #include "../../tools/Random.h" diff --git a/tests/OLD/UI/Canvas.cpp b/tests/OLD/UI/Canvas.cpp index e154abfd71..89594ed676 100644 --- a/tests/OLD/UI/Canvas.cpp +++ b/tests/OLD/UI/Canvas.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Canvas.cpp + * @file */ #include "../../UI/UI.h" diff --git a/tests/OLD/UI/Element.cpp b/tests/OLD/UI/Element.cpp index 25a8249563..628157b1f5 100644 --- a/tests/OLD/UI/Element.cpp +++ b/tests/OLD/UI/Element.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Element.cpp + * @file */ #include "../../jquery/jquery.h" diff --git a/tests/OLD/UI/ElementSlate.cpp b/tests/OLD/UI/ElementSlate.cpp index c63f860a17..835a53b709 100644 --- a/tests/OLD/UI/ElementSlate.cpp +++ b/tests/OLD/UI/ElementSlate.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ElementSlate.cpp + * @file */ #include "../../UI/UI.h" diff --git a/tests/OLD/UI/ElementTable.cpp b/tests/OLD/UI/ElementTable.cpp index e958a3fcfe..bd8ba5d846 100644 --- a/tests/OLD/UI/ElementTable.cpp +++ b/tests/OLD/UI/ElementTable.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ElementTable.cpp + * @file */ #include "../../UI/UI.h" diff --git a/tests/OLD/UI/Example.cpp b/tests/OLD/UI/Example.cpp index c11c1993f9..eafd6b880f 100644 --- a/tests/OLD/UI/Example.cpp +++ b/tests/OLD/UI/Example.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Example.cpp + * @file */ #include "../../UI/UI.h" diff --git a/tests/OLD/UI/Example2.cpp b/tests/OLD/UI/Example2.cpp index 46ea137e02..e50680699b 100644 --- a/tests/OLD/UI/Example2.cpp +++ b/tests/OLD/UI/Example2.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Example2.cpp + * @file */ #include "../../UI/UI.h" diff --git a/tests/OLD/UI/base_tests/test2.cpp b/tests/OLD/UI/base_tests/test2.cpp index 5bfbf1aa20..61a9e178e8 100644 --- a/tests/OLD/UI/base_tests/test2.cpp +++ b/tests/OLD/UI/base_tests/test2.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file test2.cpp + * @file */ #include diff --git a/tests/OLD/UI/base_tests/test3.cpp b/tests/OLD/UI/base_tests/test3.cpp index 64ffaf7d64..559434808d 100644 --- a/tests/OLD/UI/base_tests/test3.cpp +++ b/tests/OLD/UI/base_tests/test3.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file test3.cpp + * @file */ #include diff --git a/tests/OLD/UI/base_tests/test4.cpp b/tests/OLD/UI/base_tests/test4.cpp index 7ffce0ebee..d8493b06f6 100644 --- a/tests/OLD/UI/base_tests/test4.cpp +++ b/tests/OLD/UI/base_tests/test4.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file test4.cpp + * @file */ #include diff --git a/tests/OLD/UI/canvas_utils.cpp b/tests/OLD/UI/canvas_utils.cpp index 66e4807574..4069758f0d 100644 --- a/tests/OLD/UI/canvas_utils.cpp +++ b/tests/OLD/UI/canvas_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file canvas_utils.cpp + * @file */ #include "../../tools/Random.h" diff --git a/tests/OLD/UI/events.cpp b/tests/OLD/UI/events.cpp index 06c6f32a13..04e9b47853 100644 --- a/tests/OLD/UI/events.cpp +++ b/tests/OLD/UI/events.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file events.cpp + * @file */ #include diff --git a/tests/OLD/UI/mini_evoke.cpp b/tests/OLD/UI/mini_evoke.cpp index f770ae1885..301851a4c3 100644 --- a/tests/OLD/UI/mini_evoke.cpp +++ b/tests/OLD/UI/mini_evoke.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file mini_evoke.cpp + * @file */ #include diff --git a/tests/OLD/kinetic/BatchDraw.cpp b/tests/OLD/kinetic/BatchDraw.cpp index eed5a60d1c..3477894d60 100644 --- a/tests/OLD/kinetic/BatchDraw.cpp +++ b/tests/OLD/kinetic/BatchDraw.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file BatchDraw.cpp + * @file */ #include diff --git a/tests/OLD/kinetic/LayerManagement.cpp b/tests/OLD/kinetic/LayerManagement.cpp index fecd5c7191..f33e4e36da 100644 --- a/tests/OLD/kinetic/LayerManagement.cpp +++ b/tests/OLD/kinetic/LayerManagement.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file LayerManagement.cpp + * @file */ #include diff --git a/tests/OLD/kinetic/Simple.cpp b/tests/OLD/kinetic/Simple.cpp index 5a0f705a4b..6f23a8f46f 100644 --- a/tests/OLD/kinetic/Simple.cpp +++ b/tests/OLD/kinetic/Simple.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file Simple.cpp + * @file */ #include diff --git a/tests/OLD/kinetic/VaderImage.cpp b/tests/OLD/kinetic/VaderImage.cpp index 22cad574f4..edc8b787ce 100644 --- a/tests/OLD/kinetic/VaderImage.cpp +++ b/tests/OLD/kinetic/VaderImage.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file VaderImage.cpp + * @file */ #include diff --git a/tests/OLD/kinetic/test.cpp b/tests/OLD/kinetic/test.cpp index 65919eb6e8..25ac1310a1 100644 --- a/tests/OLD/kinetic/test.cpp +++ b/tests/OLD/kinetic/test.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file test.cpp + * @file */ #include diff --git a/tests/base/MapProxy.cpp b/tests/base/MapProxy.cpp index 29b4107b64..e5b387550b 100644 --- a/tests/base/MapProxy.cpp +++ b/tests/base/MapProxy.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file MapProxy.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/base/Ptr.cpp b/tests/base/Ptr.cpp index 18560a07ad..bae0b8889d 100644 --- a/tests/base/Ptr.cpp +++ b/tests/base/Ptr.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Ptr.cpp + * @file */ //#ifndef EMP_TRACK_MEM diff --git a/tests/base/always_assert.cpp b/tests/base/always_assert.cpp index 937685fd8a..942aac68ae 100644 --- a/tests/base/always_assert.cpp +++ b/tests/base/always_assert.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file always_assert.cpp + * @file */ #include diff --git a/tests/base/always_assert_warning.cpp b/tests/base/always_assert_warning.cpp index f560552371..3037774cd5 100644 --- a/tests/base/always_assert_warning.cpp +++ b/tests/base/always_assert_warning.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file always_assert_warning.cpp + * @file */ #include diff --git a/tests/base/array.cpp b/tests/base/array.cpp index 01c0656594..12d05318be 100644 --- a/tests/base/array.cpp +++ b/tests/base/array.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2022 - * - * @file array.cpp + * @file */ #include diff --git a/tests/base/assert.cpp b/tests/base/assert.cpp index d9c92fd57c..2ecd212e5c 100644 --- a/tests/base/assert.cpp +++ b/tests/base/assert.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file assert.cpp + * @file */ #undef NDEBUG diff --git a/tests/base/assert_warning.cpp b/tests/base/assert_warning.cpp index 7ef966113d..4a133b8fd7 100644 --- a/tests/base/assert_warning.cpp +++ b/tests/base/assert_warning.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file assert_warning.cpp + * @file */ #undef NDEBUG diff --git a/tests/base/error.cpp b/tests/base/error.cpp index bc0416c5fc..c0a0422555 100644 --- a/tests/base/error.cpp +++ b/tests/base/error.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2021 - * - * @file error.cpp + * @file */ #undef NDEBUG diff --git a/tests/base/errors.cpp b/tests/base/errors.cpp index 13f04d3545..8f755426c8 100644 --- a/tests/base/errors.cpp +++ b/tests/base/errors.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file errors.cpp + * @file */ #include diff --git a/tests/base/map.cpp b/tests/base/map.cpp index 5985ebf3f5..e5a68d4dda 100644 --- a/tests/base/map.cpp +++ b/tests/base/map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file map.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/base/notify.cpp b/tests/base/notify.cpp index c154295990..b459d889de 100644 --- a/tests/base/notify.cpp +++ b/tests/base/notify.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file notify.cpp + * @file */ #define CATCH_CONFIG_MAIN diff --git a/tests/base/optional.cpp b/tests/base/optional.cpp index 9485436f2c..4ee8ec247f 100644 --- a/tests/base/optional.cpp +++ b/tests/base/optional.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file optional.cpp + * @file */ #include diff --git a/tests/base/unordered_map.cpp b/tests/base/unordered_map.cpp index b0159b03f1..b2315631b2 100644 --- a/tests/base/unordered_map.cpp +++ b/tests/base/unordered_map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file unordered_map.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/base/vector.cpp b/tests/base/vector.cpp index f220c3d8ac..324351daa9 100644 --- a/tests/base/vector.cpp +++ b/tests/base/vector.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file vector.cpp + * @file */ #include diff --git a/tests/bits/BitArray.cpp b/tests/bits/BitArray.cpp index 444f2d4347..a8f90e7d17 100644 --- a/tests/bits/BitArray.cpp +++ b/tests/bits/BitArray.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-23 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BitArray.cpp + * @file */ #define EMP_DECORATE(X) [X] @@ -42,7 +43,7 @@ template struct TestBitArrayConstruct; template struct TestBitArrayConstruct { static void Run() { - emp::BitArray bit_array; + emp::old::BitArray bit_array; REQUIRE( bit_array.GetSize() == VAL1 ); REQUIRE( bit_array.CountOnes() == 0 ); for (size_t i = 0; i < VAL1; i++) bit_array[i] = true; @@ -60,13 +61,13 @@ struct TestBitArrayConstruct<> { TEST_CASE("1: Test BitArray Constructors", "[bits]"){ // Create a size 50 bit vector, default to all zeros. - emp::BitArray<50> ba1; + emp::old::BitArray<50> ba1; REQUIRE( ba1.GetSize() == 50 ); REQUIRE( ba1.CountOnes() == 0 ); REQUIRE( (~ba1).CountOnes() == 50 ); // Create a size 1000 BitArray, default to all ones. - emp::BitArray<1000> ba2(true); + emp::old::BitArray<1000> ba2(true); REQUIRE( ba2.GetSize() == 1000 ); REQUIRE( ba2.CountOnes() == 1000 ); @@ -74,45 +75,45 @@ TEST_CASE("1: Test BitArray Constructors", "[bits]"){ TestBitArrayConstruct<1,2,7,8,9,15,16,17,31,32,33,63,64,65,127,128,129,191,192,193,200>::Run(); // Build a relatively large BitArray. - emp::BitArray<1000000> ba4; + emp::old::BitArray<1000000> ba4; for (size_t i = 0; i < ba4.GetSize(); i += 100) ba4[i].Toggle(); REQUIRE( ba4.CountOnes() == 10000 ); // Try out the copy constructor. - emp::BitArray<1000000> ba5(ba4); + emp::old::BitArray<1000000> ba5(ba4); REQUIRE( ba5.GetSize() == 1000000 ); REQUIRE( ba5.CountOnes() == 10000 ); // Construct from std::bitset. std::bitset<6> bit_set; bit_set[1] = 1; bit_set[2] = 1; bit_set[4] = 1; - emp::BitArray<6> ba7(bit_set); + emp::old::BitArray<6> ba7(bit_set); REQUIRE( ba7.GetSize() == 6 ); REQUIRE( ba7.CountOnes() == 3 ); // Construct from string. std::string bit_string = "10011001010000011101"; - emp::BitArray<20> ba8(bit_string); + emp::old::BitArray<20> ba8(bit_string); REQUIRE( ba8.GetSize() == 20 ); REQUIRE( ba8.CountOnes() == 9 ); // Some random BitArrays emp::Random random; - emp::BitArray<1000> ba9(random); // 50/50 chance for each bit. + emp::old::BitArray<1000> ba9(random); // 50/50 chance for each bit. const size_t ba9_ones = ba9.CountOnes(); REQUIRE( ba9_ones >= 400 ); REQUIRE( ba9_ones <= 600 ); - emp::BitArray<1000> ba10(random, 0.8); // 80% chance of ones. + emp::old::BitArray<1000> ba10(random, 0.8); // 80% chance of ones. const size_t ba10_ones = ba10.CountOnes(); REQUIRE( ba10_ones >= 750 ); REQUIRE( ba10_ones <= 850 ); - emp::BitArray<1000> ba11(random, 117); // Exactly 117 ones, randomly placed. + emp::old::BitArray<1000> ba11(random, 117); // Exactly 117 ones, randomly placed. const size_t ba11_ones = ba11.CountOnes(); REQUIRE( ba11_ones == 117 ); - emp::BitArray<13> ba12({1,0,0,0,1,1,1,0,0,0,1,1,1}); // Construct with initializer list. + emp::old::BitArray<13> ba12({1,0,0,0,1,1,1,0,0,0,1,1,1}); // Construct with initializer list. REQUIRE( ba12.GetSize() == 13 ); REQUIRE( ba12.CountOnes() == 7 ); } @@ -123,10 +124,10 @@ template struct TestBVAssign; template struct TestBVAssign { static void Run() { - emp::BitArray ba; + emp::old::BitArray ba; // Copy to a second ba, make changes, then copy back. - emp::BitArray ba2; + emp::old::BitArray ba2; for (size_t i = 1; i < ba2.GetSize(); i += 2) { ba2[i] = 1; @@ -175,14 +176,14 @@ TEST_CASE("2: Test BitArray Assignemnts", "[bits]"){ TEST_CASE("3: Test Simple BitArray Accessors", "[bits]"){ - emp::BitArray<1> ba1(true); - emp::BitArray<8> ba8( "10001101" ); - emp::BitArray<32> ba32( "10001101100011011000110110001101" ); - emp::BitArray<64> ba64( "1000110110001101100000011000110000001101100000000000110110001101" ); - emp::BitArray<75> ba75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); + emp::old::BitArray<1> ba1(true); + emp::old::BitArray<8> ba8( "10001101" ); + emp::old::BitArray<32> ba32( "10001101100011011000110110001101" ); + emp::old::BitArray<64> ba64( "1000110110001101100000011000110000001101100000000000110110001101" ); + emp::old::BitArray<75> ba75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); emp::Random random; - emp::BitArray<1000> ba1k(random, 0.75); + emp::old::BitArray<1000> ba1k(random, 0.75); // Make sure all sizes are correct. REQUIRE( ba1.GetSize() == 1 ); @@ -267,7 +268,7 @@ TEST_CASE("3: Test Simple BitArray Accessors", "[bits]"){ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { // Now try range-based accessors on a single bit. - emp::BitArray<1> ba1(false); REQUIRE( ba1[0] == false ); REQUIRE( ba1.CountOnes() == 0 ); + emp::old::BitArray<1> ba1(false); REQUIRE( ba1[0] == false ); REQUIRE( ba1.CountOnes() == 0 ); ba1.Set(0); REQUIRE( ba1[0] == true ); REQUIRE( ba1.CountOnes() == 1 ); ba1.Clear(0); REQUIRE( ba1[0] == false ); REQUIRE( ba1.CountOnes() == 0 ); ba1.Toggle(0); REQUIRE( ba1[0] == true ); REQUIRE( ba1.CountOnes() == 1 ); @@ -282,7 +283,7 @@ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { ba1.SetRange(1,1); REQUIRE( ba1[0] == false ); REQUIRE( ba1.CountOnes() == 0 ); // Test when a full byte is used. - emp::BitArray<8> ba8( "10001101" ); REQUIRE(ba8.GetValue() == 177.0); // 10110001 + emp::old::BitArray<8> ba8( "10001101" ); REQUIRE(ba8.GetValue() == 177.0); // 10110001 ba8.Set(2); REQUIRE(ba8.GetValue() == 181.0); // 10110101 ba8.Set(0, 0); REQUIRE(ba8.GetValue() == 180.0); // 10110100 ba8.SetRange(1, 4); REQUIRE(ba8.GetValue() == 190.0); // 10111110 @@ -299,7 +300,7 @@ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { // Test a full field. constexpr double ALL_64 = (double) ((uint64_t) -1); - emp::BitArray<64> ba64( "11011000110110001101" ); + emp::old::BitArray<64> ba64( "11011000110110001101" ); REQUIRE(ba64.GetValue() == 727835.0); ba64.Set(6); REQUIRE(ba64.GetValue() == 727899.0); // ...0 010110001101101011011 ba64.Set(0, 0); REQUIRE(ba64.GetValue() == 727898.0); // ...0 010110001101101011010 @@ -315,11 +316,11 @@ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { ba64.Toggle(0,64); REQUIRE(ba64.GetValue() == 491520.0); // ...0 001111000000000000000 - emp::BitArray<75> ba75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); + emp::old::BitArray<75> ba75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); // Test a full + partial field. constexpr double ALL_88 = ((double) ((uint64_t) -1)) * emp::Pow2(24); - emp::BitArray<88> ba88( "11011000110110001101" ); REQUIRE(ba88.GetValue() == 727835.0); + emp::old::BitArray<88> ba88( "11011000110110001101" ); REQUIRE(ba88.GetValue() == 727835.0); REQUIRE(ba88.GetValue() == 727835.0); // ...0 010110001101100011011 // Start with same tests as last time... @@ -348,7 +349,7 @@ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { // A larger BitArray with lots of random tests. emp::Random random; - emp::BitArray<1000> ba1k(random, 0.65); + emp::old::BitArray<1000> ba1k(random, 0.65); size_t num_ones = ba1k.CountOnes(); REQUIRE(num_ones > 550); ba1k.Toggle(); REQUIRE(ba1k.CountOnes() == 1000 - num_ones); @@ -370,9 +371,9 @@ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { } // Test Any(), All() and None() - emp::BitArray<6> ba_empty = "000000"; - emp::BitArray<6> ba_mixed = "010101"; - emp::BitArray<6> ba_full = "111111"; + emp::old::BitArray<6> ba_empty = "000000"; + emp::old::BitArray<6> ba_mixed = "010101"; + emp::old::BitArray<6> ba_full = "111111"; REQUIRE(ba_empty.Any() == false); REQUIRE(ba_mixed.Any() == true); @@ -390,7 +391,7 @@ TEST_CASE("4: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { TEST_CASE("5: Test Randomize() and variants", "[bits]") { emp::Random random; - emp::BitArray<1000> ba; + emp::old::BitArray<1000> ba; REQUIRE(ba.None() == true); @@ -512,7 +513,7 @@ TEST_CASE("6: Test getting and setting whole chunks of bits", "[bits]") { constexpr size_t num_bits = 145; constexpr size_t num_bytes = 19; - emp::BitArray ba; + emp::old::BitArray ba; REQUIRE(ba.GetSize() == num_bits); REQUIRE(ba.GetNumBytes() == num_bytes); @@ -581,7 +582,7 @@ TEST_CASE("6: Test getting and setting whole chunks of bits", "[bits]") { TEST_CASE("7: Test functions that analyze and manipulate ones", "[bits]") { - emp::BitArray<16> ba = "0001000100001110"; + emp::old::BitArray<16> ba = "0001000100001110"; REQUIRE(ba.GetSize() == 16); REQUIRE(ba.CountOnes() == 5); @@ -642,7 +643,7 @@ TEST_CASE("7: Test functions that analyze and manipulate ones", "[bits]") { } TEST_CASE("8: Test printing and string functions.", "[bits]") { - emp::BitArray<6> ba6("000111"); + emp::old::BitArray<6> ba6("000111"); REQUIRE(ba6.ToString() == "000111"); REQUIRE(ba6.ToBinaryString() == "111000"); @@ -650,7 +651,7 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { REQUIRE(ba6.ToIDString() == "3 4 5"); REQUIRE(ba6.ToRangeString() == "3-5"); - emp::BitArray<64> ba64("0001110000000000000100000000000001000110000001000001000100000001"); + emp::old::BitArray<64> ba64("0001110000000000000100000000000001000110000001000001000100000001"); REQUIRE(ba64.ToString() == "0001110000000000000100000000000001000110000001000001000100000001"); REQUIRE(ba64.ToBinaryString() == "1000000010001000001000000110001000000000000010000000000000111000"); @@ -658,7 +659,7 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { REQUIRE(ba64.ToIDString(",") == "3,4,5,19,33,37,38,45,51,55,63"); REQUIRE(ba64.ToRangeString() == "3-5,19,33,37-38,45,51,55,63"); - emp::BitArray<65> ba65("00011110000000000001000000000000010001100000010000010001000000111"); + emp::old::BitArray<65> ba65("00011110000000000001000000000000010001100000010000010001000000111"); REQUIRE(ba65.ToString() == "00011110000000000001000000000000010001100000010000010001000000111"); REQUIRE(ba65.ToBinaryString() == "11100000010001000001000000110001000000000000010000000000001111000"); @@ -668,172 +669,172 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { } TEST_CASE("9: Test Boolean logic and shifting functions.", "[bits]") { - const emp::BitArray<8> input1 = "00001111"; - const emp::BitArray<8> input2 = "00110011"; - const emp::BitArray<8> input3 = "01010101"; + const emp::old::BitArray<8> input1 = "00001111"; + const emp::old::BitArray<8> input2 = "00110011"; + const emp::old::BitArray<8> input3 = "01010101"; // Test *_SELF() Boolean Logic functions. - emp::BitArray<8> ba; REQUIRE(ba == emp::BitArray<8>("00000000")); - ba.NOT_SELF(); REQUIRE(ba == emp::BitArray<8>("11111111")); - ba.AND_SELF(input1); REQUIRE(ba == emp::BitArray<8>("00001111")); - ba.AND_SELF(input1); REQUIRE(ba == emp::BitArray<8>("00001111")); - ba.AND_SELF(input2); REQUIRE(ba == emp::BitArray<8>("00000011")); - ba.AND_SELF(input3); REQUIRE(ba == emp::BitArray<8>("00000001")); - - ba.OR_SELF(input1); REQUIRE(ba == emp::BitArray<8>("00001111")); - ba.OR_SELF(input1); REQUIRE(ba == emp::BitArray<8>("00001111")); - ba.OR_SELF(input3); REQUIRE(ba == emp::BitArray<8>("01011111")); - ba.OR_SELF(input2); REQUIRE(ba == emp::BitArray<8>("01111111")); - - ba.NAND_SELF(input1); REQUIRE(ba == emp::BitArray<8>("11110000")); - ba.NAND_SELF(input1); REQUIRE(ba == emp::BitArray<8>("11111111")); - ba.NAND_SELF(input2); REQUIRE(ba == emp::BitArray<8>("11001100")); - ba.NAND_SELF(input3); REQUIRE(ba == emp::BitArray<8>("10111011")); - - ba.NOR_SELF(input1); REQUIRE(ba == emp::BitArray<8>("01000000")); - ba.NOR_SELF(input1); REQUIRE(ba == emp::BitArray<8>("10110000")); - ba.NOR_SELF(input2); REQUIRE(ba == emp::BitArray<8>("01001100")); - ba.NOR_SELF(input3); REQUIRE(ba == emp::BitArray<8>("10100010")); - - ba.XOR_SELF(input1); REQUIRE(ba == emp::BitArray<8>("10101101")); - ba.XOR_SELF(input1); REQUIRE(ba == emp::BitArray<8>("10100010")); - ba.XOR_SELF(input2); REQUIRE(ba == emp::BitArray<8>("10010001")); - ba.XOR_SELF(input3); REQUIRE(ba == emp::BitArray<8>("11000100")); - - ba.EQU_SELF(input1); REQUIRE(ba == emp::BitArray<8>("00110100")); - ba.EQU_SELF(input1); REQUIRE(ba == emp::BitArray<8>("11000100")); - ba.EQU_SELF(input2); REQUIRE(ba == emp::BitArray<8>("00001000")); - ba.EQU_SELF(input3); REQUIRE(ba == emp::BitArray<8>("10100010")); - - ba.NOT_SELF(); REQUIRE(ba == emp::BitArray<8>("01011101")); + emp::old::BitArray<8> ba; REQUIRE(ba == emp::old::BitArray<8>("00000000")); + ba.NOT_SELF(); REQUIRE(ba == emp::old::BitArray<8>("11111111")); + ba.AND_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba.AND_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba.AND_SELF(input2); REQUIRE(ba == emp::old::BitArray<8>("00000011")); + ba.AND_SELF(input3); REQUIRE(ba == emp::old::BitArray<8>("00000001")); + + ba.OR_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba.OR_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba.OR_SELF(input3); REQUIRE(ba == emp::old::BitArray<8>("01011111")); + ba.OR_SELF(input2); REQUIRE(ba == emp::old::BitArray<8>("01111111")); + + ba.NAND_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("11110000")); + ba.NAND_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("11111111")); + ba.NAND_SELF(input2); REQUIRE(ba == emp::old::BitArray<8>("11001100")); + ba.NAND_SELF(input3); REQUIRE(ba == emp::old::BitArray<8>("10111011")); + + ba.NOR_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("01000000")); + ba.NOR_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("10110000")); + ba.NOR_SELF(input2); REQUIRE(ba == emp::old::BitArray<8>("01001100")); + ba.NOR_SELF(input3); REQUIRE(ba == emp::old::BitArray<8>("10100010")); + + ba.XOR_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("10101101")); + ba.XOR_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("10100010")); + ba.XOR_SELF(input2); REQUIRE(ba == emp::old::BitArray<8>("10010001")); + ba.XOR_SELF(input3); REQUIRE(ba == emp::old::BitArray<8>("11000100")); + + ba.EQU_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("00110100")); + ba.EQU_SELF(input1); REQUIRE(ba == emp::old::BitArray<8>("11000100")); + ba.EQU_SELF(input2); REQUIRE(ba == emp::old::BitArray<8>("00001000")); + ba.EQU_SELF(input3); REQUIRE(ba == emp::old::BitArray<8>("10100010")); + + ba.NOT_SELF(); REQUIRE(ba == emp::old::BitArray<8>("01011101")); // Test regular Boolean Logic functions. - ba.Clear(); REQUIRE(ba == emp::BitArray<8>("00000000")); - emp::BitArray<8> ba1 = ba.NOT(); REQUIRE(ba1 == emp::BitArray<8>("11111111")); + ba.Clear(); REQUIRE(ba == emp::old::BitArray<8>("00000000")); + emp::old::BitArray<8> ba1 = ba.NOT(); REQUIRE(ba1 == emp::old::BitArray<8>("11111111")); - ba1 = ba1.AND(input1); REQUIRE(ba1 == emp::BitArray<8>("00001111")); - emp::BitArray<8> ba2 = ba1.AND(input1); REQUIRE(ba2 == emp::BitArray<8>("00001111")); - emp::BitArray<8> ba3 = ba2.AND(input2); REQUIRE(ba3 == emp::BitArray<8>("00000011")); - emp::BitArray<8> ba4 = ba3.AND(input3); REQUIRE(ba4 == emp::BitArray<8>("00000001")); + ba1 = ba1.AND(input1); REQUIRE(ba1 == emp::old::BitArray<8>("00001111")); + emp::old::BitArray<8> ba2 = ba1.AND(input1); REQUIRE(ba2 == emp::old::BitArray<8>("00001111")); + emp::old::BitArray<8> ba3 = ba2.AND(input2); REQUIRE(ba3 == emp::old::BitArray<8>("00000011")); + emp::old::BitArray<8> ba4 = ba3.AND(input3); REQUIRE(ba4 == emp::old::BitArray<8>("00000001")); - ba1 = ba4.OR(input1); REQUIRE(ba1 == emp::BitArray<8>("00001111")); - ba2 = ba1.OR(input1); REQUIRE(ba2 == emp::BitArray<8>("00001111")); - ba3 = ba2.OR(input3); REQUIRE(ba3 == emp::BitArray<8>("01011111")); - ba4 = ba3.OR(input2); REQUIRE(ba4 == emp::BitArray<8>("01111111")); + ba1 = ba4.OR(input1); REQUIRE(ba1 == emp::old::BitArray<8>("00001111")); + ba2 = ba1.OR(input1); REQUIRE(ba2 == emp::old::BitArray<8>("00001111")); + ba3 = ba2.OR(input3); REQUIRE(ba3 == emp::old::BitArray<8>("01011111")); + ba4 = ba3.OR(input2); REQUIRE(ba4 == emp::old::BitArray<8>("01111111")); - ba1 = ba4.NAND(input1); REQUIRE(ba1 == emp::BitArray<8>("11110000")); - ba2 = ba1.NAND(input1); REQUIRE(ba2 == emp::BitArray<8>("11111111")); - ba3 = ba2.NAND(input2); REQUIRE(ba3 == emp::BitArray<8>("11001100")); - ba4 = ba3.NAND(input3); REQUIRE(ba4 == emp::BitArray<8>("10111011")); + ba1 = ba4.NAND(input1); REQUIRE(ba1 == emp::old::BitArray<8>("11110000")); + ba2 = ba1.NAND(input1); REQUIRE(ba2 == emp::old::BitArray<8>("11111111")); + ba3 = ba2.NAND(input2); REQUIRE(ba3 == emp::old::BitArray<8>("11001100")); + ba4 = ba3.NAND(input3); REQUIRE(ba4 == emp::old::BitArray<8>("10111011")); - ba1 = ba4.NOR(input1); REQUIRE(ba1 == emp::BitArray<8>("01000000")); - ba2 = ba1.NOR(input1); REQUIRE(ba2 == emp::BitArray<8>("10110000")); - ba3 = ba2.NOR(input2); REQUIRE(ba3 == emp::BitArray<8>("01001100")); - ba4 = ba3.NOR(input3); REQUIRE(ba4 == emp::BitArray<8>("10100010")); + ba1 = ba4.NOR(input1); REQUIRE(ba1 == emp::old::BitArray<8>("01000000")); + ba2 = ba1.NOR(input1); REQUIRE(ba2 == emp::old::BitArray<8>("10110000")); + ba3 = ba2.NOR(input2); REQUIRE(ba3 == emp::old::BitArray<8>("01001100")); + ba4 = ba3.NOR(input3); REQUIRE(ba4 == emp::old::BitArray<8>("10100010")); - ba1 = ba4.XOR(input1); REQUIRE(ba1 == emp::BitArray<8>("10101101")); - ba2 = ba1.XOR(input1); REQUIRE(ba2 == emp::BitArray<8>("10100010")); - ba3 = ba2.XOR(input2); REQUIRE(ba3 == emp::BitArray<8>("10010001")); - ba4 = ba3.XOR(input3); REQUIRE(ba4 == emp::BitArray<8>("11000100")); + ba1 = ba4.XOR(input1); REQUIRE(ba1 == emp::old::BitArray<8>("10101101")); + ba2 = ba1.XOR(input1); REQUIRE(ba2 == emp::old::BitArray<8>("10100010")); + ba3 = ba2.XOR(input2); REQUIRE(ba3 == emp::old::BitArray<8>("10010001")); + ba4 = ba3.XOR(input3); REQUIRE(ba4 == emp::old::BitArray<8>("11000100")); - ba1 = ba4.EQU(input1); REQUIRE(ba1 == emp::BitArray<8>("00110100")); - ba2 = ba1.EQU(input1); REQUIRE(ba2 == emp::BitArray<8>("11000100")); - ba3 = ba2.EQU(input2); REQUIRE(ba3 == emp::BitArray<8>("00001000")); - ba4 = ba3.EQU(input3); REQUIRE(ba4 == emp::BitArray<8>("10100010")); + ba1 = ba4.EQU(input1); REQUIRE(ba1 == emp::old::BitArray<8>("00110100")); + ba2 = ba1.EQU(input1); REQUIRE(ba2 == emp::old::BitArray<8>("11000100")); + ba3 = ba2.EQU(input2); REQUIRE(ba3 == emp::old::BitArray<8>("00001000")); + ba4 = ba3.EQU(input3); REQUIRE(ba4 == emp::old::BitArray<8>("10100010")); - ba = ba4.NOT(); REQUIRE(ba == emp::BitArray<8>("01011101")); + ba = ba4.NOT(); REQUIRE(ba == emp::old::BitArray<8>("01011101")); // Test Boolean Logic operators. - ba.Clear(); REQUIRE(ba == emp::BitArray<8>("00000000")); - ba1 = ~ba; REQUIRE(ba1 == emp::BitArray<8>("11111111")); + ba.Clear(); REQUIRE(ba == emp::old::BitArray<8>("00000000")); + ba1 = ~ba; REQUIRE(ba1 == emp::old::BitArray<8>("11111111")); - ba1 = ba1 & input1; REQUIRE(ba1 == emp::BitArray<8>("00001111")); - ba2 = ba1 & input1; REQUIRE(ba2 == emp::BitArray<8>("00001111")); - ba3 = ba2 & input2; REQUIRE(ba3 == emp::BitArray<8>("00000011")); - ba4 = ba3 & input3; REQUIRE(ba4 == emp::BitArray<8>("00000001")); + ba1 = ba1 & input1; REQUIRE(ba1 == emp::old::BitArray<8>("00001111")); + ba2 = ba1 & input1; REQUIRE(ba2 == emp::old::BitArray<8>("00001111")); + ba3 = ba2 & input2; REQUIRE(ba3 == emp::old::BitArray<8>("00000011")); + ba4 = ba3 & input3; REQUIRE(ba4 == emp::old::BitArray<8>("00000001")); - ba1 = ba4 | input1; REQUIRE(ba1 == emp::BitArray<8>("00001111")); - ba2 = ba1 | input1; REQUIRE(ba2 == emp::BitArray<8>("00001111")); - ba3 = ba2 | input3; REQUIRE(ba3 == emp::BitArray<8>("01011111")); - ba4 = ba3 | input2; REQUIRE(ba4 == emp::BitArray<8>("01111111")); + ba1 = ba4 | input1; REQUIRE(ba1 == emp::old::BitArray<8>("00001111")); + ba2 = ba1 | input1; REQUIRE(ba2 == emp::old::BitArray<8>("00001111")); + ba3 = ba2 | input3; REQUIRE(ba3 == emp::old::BitArray<8>("01011111")); + ba4 = ba3 | input2; REQUIRE(ba4 == emp::old::BitArray<8>("01111111")); - ba1 = ~(ba4 & input1); REQUIRE(ba1 == emp::BitArray<8>("11110000")); - ba2 = ~(ba1 & input1); REQUIRE(ba2 == emp::BitArray<8>("11111111")); - ba3 = ~(ba2 & input2); REQUIRE(ba3 == emp::BitArray<8>("11001100")); - ba4 = ~(ba3 & input3); REQUIRE(ba4 == emp::BitArray<8>("10111011")); + ba1 = ~(ba4 & input1); REQUIRE(ba1 == emp::old::BitArray<8>("11110000")); + ba2 = ~(ba1 & input1); REQUIRE(ba2 == emp::old::BitArray<8>("11111111")); + ba3 = ~(ba2 & input2); REQUIRE(ba3 == emp::old::BitArray<8>("11001100")); + ba4 = ~(ba3 & input3); REQUIRE(ba4 == emp::old::BitArray<8>("10111011")); - ba1 = ~(ba4 | input1); REQUIRE(ba1 == emp::BitArray<8>("01000000")); - ba2 = ~(ba1 | input1); REQUIRE(ba2 == emp::BitArray<8>("10110000")); - ba3 = ~(ba2 | input2); REQUIRE(ba3 == emp::BitArray<8>("01001100")); - ba4 = ~(ba3 | input3); REQUIRE(ba4 == emp::BitArray<8>("10100010")); + ba1 = ~(ba4 | input1); REQUIRE(ba1 == emp::old::BitArray<8>("01000000")); + ba2 = ~(ba1 | input1); REQUIRE(ba2 == emp::old::BitArray<8>("10110000")); + ba3 = ~(ba2 | input2); REQUIRE(ba3 == emp::old::BitArray<8>("01001100")); + ba4 = ~(ba3 | input3); REQUIRE(ba4 == emp::old::BitArray<8>("10100010")); - ba1 = ba4 ^ input1; REQUIRE(ba1 == emp::BitArray<8>("10101101")); - ba2 = ba1 ^ input1; REQUIRE(ba2 == emp::BitArray<8>("10100010")); - ba3 = ba2 ^ input2; REQUIRE(ba3 == emp::BitArray<8>("10010001")); - ba4 = ba3 ^ input3; REQUIRE(ba4 == emp::BitArray<8>("11000100")); + ba1 = ba4 ^ input1; REQUIRE(ba1 == emp::old::BitArray<8>("10101101")); + ba2 = ba1 ^ input1; REQUIRE(ba2 == emp::old::BitArray<8>("10100010")); + ba3 = ba2 ^ input2; REQUIRE(ba3 == emp::old::BitArray<8>("10010001")); + ba4 = ba3 ^ input3; REQUIRE(ba4 == emp::old::BitArray<8>("11000100")); - ba1 = ~(ba4 ^ input1); REQUIRE(ba1 == emp::BitArray<8>("00110100")); - ba2 = ~(ba1 ^ input1); REQUIRE(ba2 == emp::BitArray<8>("11000100")); - ba3 = ~(ba2 ^ input2); REQUIRE(ba3 == emp::BitArray<8>("00001000")); - ba4 = ~(ba3 ^ input3); REQUIRE(ba4 == emp::BitArray<8>("10100010")); + ba1 = ~(ba4 ^ input1); REQUIRE(ba1 == emp::old::BitArray<8>("00110100")); + ba2 = ~(ba1 ^ input1); REQUIRE(ba2 == emp::old::BitArray<8>("11000100")); + ba3 = ~(ba2 ^ input2); REQUIRE(ba3 == emp::old::BitArray<8>("00001000")); + ba4 = ~(ba3 ^ input3); REQUIRE(ba4 == emp::old::BitArray<8>("10100010")); - ba = ~ba4; REQUIRE(ba == emp::BitArray<8>("01011101")); + ba = ~ba4; REQUIRE(ba == emp::old::BitArray<8>("01011101")); // Test COMPOUND Boolean Logic operators. - ba = "11111111"; REQUIRE(ba == emp::BitArray<8>("11111111")); + ba = "11111111"; REQUIRE(ba == emp::old::BitArray<8>("11111111")); - ba &= input1; REQUIRE(ba == emp::BitArray<8>("00001111")); - ba &= input1; REQUIRE(ba == emp::BitArray<8>("00001111")); - ba &= input2; REQUIRE(ba == emp::BitArray<8>("00000011")); - ba &= input3; REQUIRE(ba == emp::BitArray<8>("00000001")); + ba &= input1; REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba &= input1; REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba &= input2; REQUIRE(ba == emp::old::BitArray<8>("00000011")); + ba &= input3; REQUIRE(ba == emp::old::BitArray<8>("00000001")); - ba |= input1; REQUIRE(ba == emp::BitArray<8>("00001111")); - ba |= input1; REQUIRE(ba == emp::BitArray<8>("00001111")); - ba |= input3; REQUIRE(ba == emp::BitArray<8>("01011111")); - ba |= input2; REQUIRE(ba == emp::BitArray<8>("01111111")); + ba |= input1; REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba |= input1; REQUIRE(ba == emp::old::BitArray<8>("00001111")); + ba |= input3; REQUIRE(ba == emp::old::BitArray<8>("01011111")); + ba |= input2; REQUIRE(ba == emp::old::BitArray<8>("01111111")); - ba ^= input1; REQUIRE(ba == emp::BitArray<8>("01110000")); - ba ^= input1; REQUIRE(ba == emp::BitArray<8>("01111111")); - ba ^= input2; REQUIRE(ba == emp::BitArray<8>("01001100")); - ba ^= input3; REQUIRE(ba == emp::BitArray<8>("00011001")); + ba ^= input1; REQUIRE(ba == emp::old::BitArray<8>("01110000")); + ba ^= input1; REQUIRE(ba == emp::old::BitArray<8>("01111111")); + ba ^= input2; REQUIRE(ba == emp::old::BitArray<8>("01001100")); + ba ^= input3; REQUIRE(ba == emp::old::BitArray<8>("00011001")); // Now some tests with BitArrays longer than one field. - const emp::BitArray<80> bal80 = + const emp::old::BitArray<80> bal80 = "00110111000101110001011100010111000101110001011100010111000101110001011100010111"; REQUIRE( bal80.GetSize() == 80 ); REQUIRE( bal80.CountOnes() == 41 ); REQUIRE( (bal80 << 1) == - emp::BitArray<80>("00011011100010111000101110001011100010111000101110001011100010111000101110001011") + emp::old::BitArray<80>("00011011100010111000101110001011100010111000101110001011100010111000101110001011") ); REQUIRE( (bal80 << 2) == - emp::BitArray<80>("00001101110001011100010111000101110001011100010111000101110001011100010111000101") + emp::old::BitArray<80>("00001101110001011100010111000101110001011100010111000101110001011100010111000101") ); REQUIRE( (bal80 << 63) == - emp::BitArray<80>("00000000000000000000000000000000000000000000000000000000000000000110111000101110") + emp::old::BitArray<80>("00000000000000000000000000000000000000000000000000000000000000000110111000101110") ); REQUIRE( (bal80 << 64) == - emp::BitArray<80>("00000000000000000000000000000000000000000000000000000000000000000011011100010111") + emp::old::BitArray<80>("00000000000000000000000000000000000000000000000000000000000000000011011100010111") ); REQUIRE( (bal80 << 65) == - emp::BitArray<80>("00000000000000000000000000000000000000000000000000000000000000000001101110001011") + emp::old::BitArray<80>("00000000000000000000000000000000000000000000000000000000000000000001101110001011") ); REQUIRE( (bal80 >> 1) == - emp::BitArray<80>("01101110001011100010111000101110001011100010111000101110001011100010111000101110") + emp::old::BitArray<80>("01101110001011100010111000101110001011100010111000101110001011100010111000101110") ); REQUIRE( (bal80 >> 2) == - emp::BitArray<80>("11011100010111000101110001011100010111000101110001011100010111000101110001011100") + emp::old::BitArray<80>("11011100010111000101110001011100010111000101110001011100010111000101110001011100") ); REQUIRE( (bal80 >> 63) == - emp::BitArray<80>("10001011100010111000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitArray<80>("10001011100010111000000000000000000000000000000000000000000000000000000000000000") ); REQUIRE( (bal80 >> 64) == - emp::BitArray<80>("00010111000101110000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitArray<80>("00010111000101110000000000000000000000000000000000000000000000000000000000000000") ); REQUIRE( (bal80 >> 65) == - emp::BitArray<80>("00101110001011100000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitArray<80>("00101110001011100000000000000000000000000000000000000000000000000000000000000000") ); } @@ -856,7 +857,7 @@ TEST_CASE("9: Test Boolean logic and shifting functions.", "[bits]") { * as well as Clear and SetAll */ void test_status(){ - emp::BitArray<10> ba10; + emp::old::BitArray<10> ba10; REQUIRE(!ba10.any()); REQUIRE(ba10.none()); REQUIRE(!ba10.all()); @@ -870,13 +871,13 @@ void test_status(){ * GetSize */ void test_size(){ - emp::BitArray<42> ba42; + emp::old::BitArray<42> ba42; REQUIRE(ba42.size() == 42); - emp::BitArray<35> ba35; + emp::old::BitArray<35> ba35; REQUIRE(ba35.GetSize() == 35); - emp::BitArray<1> ba1; + emp::old::BitArray<1> ba1; REQUIRE(ba1.size() == 1); } @@ -884,11 +885,11 @@ void test_size(){ * Flip and Toggle */ void test_flip(){ - emp::BitArray<2> ba2; // ba2 = 00 + emp::old::BitArray<2> ba2; // ba2 = 00 ba2.flip(0); // ba2 = 01 REQUIRE(ba2[0]); - emp::BitArray<8> ba8; // ba8 = 00000000 + emp::old::BitArray<8> ba8; // ba8 = 00000000 ba8.flip(0,4); // ba8 = 00001111 REQUIRE(ba8[0]); REQUIRE(ba8[1]); @@ -899,7 +900,7 @@ void test_flip(){ ba8[0].Toggle(); // ba8 = 00001110 REQUIRE(!ba8[0]); - emp::BitArray<4> ba4; // ba4 = 0000 + emp::old::BitArray<4> ba4; // ba4 = 0000 ba4.flip(); // ba4 = 1111 REQUIRE(ba4.all()); } @@ -908,7 +909,7 @@ void test_flip(){ * FindOne and PopOne */ void test_find(){ - emp::BitArray<10> ba10; // ba10 = 00 00000000 + emp::old::BitArray<10> ba10; // ba10 = 00 00000000 ba10.flip(3); // ba10 = 00 00001000 REQUIRE(ba10.FindOne() == 3); ba10.PopOne(); // ba10 = 00 00000000 @@ -923,7 +924,7 @@ void test_find(){ * GetByte and SetByte */ void test_byte(){ - emp::BitArray<10> ba10; + emp::old::BitArray<10> ba10; ba10.SetByte(0, 10); REQUIRE(ba10.GetByte(0) == 10); @@ -939,7 +940,7 @@ void test_byte(){ // actual testing function template void do_byte_test() { - emp::BitArray ba; + emp::old::BitArray ba; for (size_t i = 0; i < Bits / 8; ++i) { ba.SetByte(i, 10 * i); @@ -969,12 +970,12 @@ void test_bytes() { * Left and Right shifts */ void test_shift(){ - emp::BitArray<40> ba40; + emp::old::BitArray<40> ba40; ba40.SetByte(0, 1); ba40 <<= 34; REQUIRE(ba40.GetByte(4) == 4); - emp::BitArray<10> ba10; + emp::old::BitArray<10> ba10; ba10.SetByte(0, 10); ba10 >>= 2; REQUIRE(ba10.GetByte(0) == 2); @@ -984,7 +985,7 @@ void test_shift(){ * Count ones */ void test_count(){ - emp::BitArray<12> ba12; + emp::old::BitArray<12> ba12; ba12.SetAll(); REQUIRE(ba12.count() == 12); REQUIRE(ba12.CountOnes_Sparse() == 12); @@ -996,7 +997,7 @@ void test_count(){ * Get ones */ void test_get_ones(){ - emp::BitArray<5> ba5; + emp::old::BitArray<5> ba5; ba5.flip(2); // 00100 emp::vector ones = ba5.GetOnes(); REQUIRE(ones.size() == 1); @@ -1008,7 +1009,7 @@ void test_get_ones(){ * Get and Set bits */ void test_bit(){ - emp::BitArray<8> ba8; + emp::old::BitArray<8> ba8; ba8.Set(0, 1); // ba8 = 00000001 REQUIRE(ba8.Get(0)); @@ -1022,9 +1023,9 @@ void test_bit(){ * Bitwise XOR ^ */ void test_bitwise_xor(){ - emp::BitArray<4> ba4; + emp::old::BitArray<4> ba4; ba4.Set(0, 1); - emp::BitArray<4> ba4_1; + emp::old::BitArray<4> ba4_1; ba4_1.SetByte(0,3); ba4 ^= ba4_1; // ba4 = 0001 ^ 0011 = 0010 REQUIRE(ba4.GetByte(0) == 2); // 0010 = 2 @@ -1037,8 +1038,8 @@ void test_bitwise_xor(){ * Bitwise OR | */ void test_bitwise_or(){ - emp::BitArray<10> ba10; - emp::BitArray<10> ba10_1; + emp::old::BitArray<10> ba10; + emp::old::BitArray<10> ba10_1; ba10.Set(1,1); // ba10 = 00 0000 0010 ba10_1.Set(3,1); ba10_1.SetByte(1,3); @@ -1052,8 +1053,8 @@ void test_bitwise_or(){ * Bitwise AND & */ void test_bitwise_and(){ - emp::BitArray<8> ba8; - emp::BitArray<8> ba8_1; + emp::old::BitArray<8> ba8; + emp::old::BitArray<8> ba8_1; ba8.SetByte(0,13); // ba8 = 00001101 ba8_1.SetByte(0,10); // ba8_1 = 00001010 ba8_1 &= ba8; // ba8_1 = 00001010 & 00001101 = 00001000 @@ -1065,8 +1066,8 @@ void test_bitwise_and(){ */ void test_more_comparators(){ // NAND - emp::BitArray<8> ba8_1; - emp::BitArray<8> ba8_2; + emp::old::BitArray<8> ba8_1; + emp::old::BitArray<8> ba8_2; ba8_1.SetAll(); REQUIRE(ba8_1.NAND(ba8_2).All()); ba8_2.flip(1); @@ -1096,7 +1097,7 @@ void test_more_comparators(){ */ void test_random(){ emp::Random random; - emp::BitArray<8> ba8(random); + emp::old::BitArray<8> ba8(random); ba8.Randomize(random, 1.0); REQUIRE(ba8.all()); ba8.Randomize(random, 0.0); @@ -1107,11 +1108,11 @@ void test_random(){ * Copy */ void test_copy(){ - emp::BitArray<10> ba10; + emp::old::BitArray<10> ba10; ba10.SetAll(); ba10.flip(0,5); - emp::BitArray<10> ba10_1; + emp::old::BitArray<10> ba10_1; ba10_1 = ba10; REQUIRE(ba10 == ba10_1); } @@ -1120,8 +1121,8 @@ void test_copy(){ * Comparators (>=,>,==,!=,<,<=) */ void test_comparators(){ - emp::BitArray<10> ba10; - emp::BitArray<10> ba10_1; + emp::old::BitArray<10> ba10; + emp::old::BitArray<10> ba10_1; ba10_1.SetAll(); REQUIRE(ba10_1 != ba10); REQUIRE(ba10_1 > ba10); @@ -1138,10 +1139,10 @@ void test_comparators(){ * Export */ void test_export(){ - emp::BitArray<8> ba8; + emp::old::BitArray<8> ba8; ba8.SetAll(); REQUIRE(ba8.count() == 8); - emp::BitArray<10> ba10 = ba8.Export<10>(); + emp::old::BitArray<10> ba10 = ba8.Export<10>(); REQUIRE(ba10.size() == 10); REQUIRE(ba10.GetByte(0) == 255); REQUIRE(ba10.GetByte(1) == 0); @@ -1151,14 +1152,14 @@ void test_export(){ * Import */ void test_import(){ - emp::BitArray<8> ba8; - emp::BitArray<20> ba20; + emp::old::BitArray<8> ba8; + emp::old::BitArray<20> ba20; ba20[5] = 1; ba8.Import(ba20); REQUIRE(ba8[5]); - emp::BitArray<10> ba10; + emp::old::BitArray<10> ba10; ba10.SetAll(); ba20.Import(ba10); REQUIRE(ba20.count() == 10); @@ -1198,8 +1199,8 @@ struct ImportExportTester { emp::Random rand(1); // using default parameter - emp::BitArray source(rand); - emp::BitArray dest(rand); + emp::old::BitArray source(rand); + emp::old::BitArray dest(rand); dest.template Import(source); @@ -1265,7 +1266,7 @@ struct MultiTester2 { emp::Random rand(1); constexpr int W = N - 2; - emp::BitArray ba; + emp::old::BitArray ba; for (int j = 0; j < W; ++j) { ba.Clear(); ba.Set(j); @@ -1332,8 +1333,8 @@ struct MultiTester { constexpr int STEP = (I <= 200) ? 1 : I/100; emp::Random rand(1); - emp::BitArray ba(rand); - const emp::BitArray ba_orig(ba); + emp::old::BitArray ba(rand); + const emp::old::BitArray ba_orig(ba); const size_t num_ones = ba.CountOnes(); // Rotations should not change the number of ones. @@ -1389,130 +1390,130 @@ struct MultiTester { }; -template class emp::BitArray<5>; +template class emp::old::BitArray<5>; TEST_CASE("Another Test BitArray", "[bits]") { // test BitArray GetSize, GetNumBytes { - REQUIRE(emp::BitArray<2>{}.GetSize() == 2); - REQUIRE(emp::BitArray<2>{}.GetNumBytes() == 1); + REQUIRE(emp::old::BitArray<2>{}.GetSize() == 2); + REQUIRE(emp::old::BitArray<2>{}.GetNumBytes() == 1); - REQUIRE(emp::BitArray<7>{}.GetSize() == 7); - REQUIRE(emp::BitArray<7>{}.GetNumBytes() == 1); + REQUIRE(emp::old::BitArray<7>{}.GetSize() == 7); + REQUIRE(emp::old::BitArray<7>{}.GetNumBytes() == 1); - REQUIRE(emp::BitArray<8>{}.GetSize() == 8); - REQUIRE(emp::BitArray<8>{}.GetNumBytes() == 1); + REQUIRE(emp::old::BitArray<8>{}.GetSize() == 8); + REQUIRE(emp::old::BitArray<8>{}.GetNumBytes() == 1); - REQUIRE(emp::BitArray<9>{}.GetSize() == 9); - REQUIRE(emp::BitArray<9>{}.GetNumBytes() == 2); + REQUIRE(emp::old::BitArray<9>{}.GetSize() == 9); + REQUIRE(emp::old::BitArray<9>{}.GetNumBytes() == 2); - REQUIRE(emp::BitArray<16>{}.GetSize() == 16); - REQUIRE(emp::BitArray<16>{}.GetNumBytes() == 2); + REQUIRE(emp::old::BitArray<16>{}.GetSize() == 16); + REQUIRE(emp::old::BitArray<16>{}.GetNumBytes() == 2); - REQUIRE(emp::BitArray<24>{}.GetSize() == 24); - REQUIRE(emp::BitArray<24>{}.GetNumBytes() == 3); + REQUIRE(emp::old::BitArray<24>{}.GetSize() == 24); + REQUIRE(emp::old::BitArray<24>{}.GetNumBytes() == 3); } // test BitArray reverse { - REQUIRE(emp::BitArray<1>{0}.REVERSE_SELF() == emp::BitArray<1>{0}); - REQUIRE(emp::BitArray<1>{0}.REVERSE_SELF().CountOnes() == 0); - REQUIRE(emp::BitArray<1>{1}.REVERSE_SELF() == emp::BitArray<1>{1}); - REQUIRE(emp::BitArray<1>{1}.REVERSE_SELF().CountOnes() == 1); + REQUIRE(emp::old::BitArray<1>{0}.REVERSE_SELF() == emp::old::BitArray<1>{0}); + REQUIRE(emp::old::BitArray<1>{0}.REVERSE_SELF().CountOnes() == 0); + REQUIRE(emp::old::BitArray<1>{1}.REVERSE_SELF() == emp::old::BitArray<1>{1}); + REQUIRE(emp::old::BitArray<1>{1}.REVERSE_SELF().CountOnes() == 1); REQUIRE( - (emp::BitArray<2>{1,1}.REVERSE_SELF()) + (emp::old::BitArray<2>{1,1}.REVERSE_SELF()) == - (emp::BitArray<2>{1,1}) + (emp::old::BitArray<2>{1,1}) ); - REQUIRE((emp::BitArray<2>{1,1}.REVERSE_SELF().CountOnes()) == 2); + REQUIRE((emp::old::BitArray<2>{1,1}.REVERSE_SELF().CountOnes()) == 2); REQUIRE( - (emp::BitArray<2>{0,1}.REVERSE_SELF()) + (emp::old::BitArray<2>{0,1}.REVERSE_SELF()) == - (emp::BitArray<2>{1,0}) + (emp::old::BitArray<2>{1,0}) ); - REQUIRE((emp::BitArray<2>{0,1}.REVERSE_SELF().CountOnes()) == 1); + REQUIRE((emp::old::BitArray<2>{0,1}.REVERSE_SELF().CountOnes()) == 1); REQUIRE( - (emp::BitArray<2>{0,0}.REVERSE_SELF()) + (emp::old::BitArray<2>{0,0}.REVERSE_SELF()) == - (emp::BitArray<2>{0,0}) + (emp::old::BitArray<2>{0,0}) ); - REQUIRE((emp::BitArray<2>{0,0}.REVERSE_SELF().CountOnes()) == 0); + REQUIRE((emp::old::BitArray<2>{0,0}.REVERSE_SELF().CountOnes()) == 0); REQUIRE( - (emp::BitArray<7>{1,1,0,0,0,0,1}.REVERSE_SELF()) + (emp::old::BitArray<7>{1,1,0,0,0,0,1}.REVERSE_SELF()) == - (emp::BitArray<7>{1,0,0,0,0,1,1}) + (emp::old::BitArray<7>{1,0,0,0,0,1,1}) ); - REQUIRE((emp::BitArray<7>{1,1,0,0,0,0,1}.REVERSE_SELF().CountOnes()) == 3); + REQUIRE((emp::old::BitArray<7>{1,1,0,0,0,0,1}.REVERSE_SELF().CountOnes()) == 3); REQUIRE( - (emp::BitArray<7>{1,0,1,0,1,0,1}.REVERSE_SELF()) + (emp::old::BitArray<7>{1,0,1,0,1,0,1}.REVERSE_SELF()) == - (emp::BitArray<7>{1,0,1,0,1,0,1}) + (emp::old::BitArray<7>{1,0,1,0,1,0,1}) ); - REQUIRE((emp::BitArray<7>{1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); + REQUIRE((emp::old::BitArray<7>{1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); REQUIRE( - (emp::BitArray<7>{1,1,1,1,1,0,1}.REVERSE_SELF()) + (emp::old::BitArray<7>{1,1,1,1,1,0,1}.REVERSE_SELF()) == - (emp::BitArray<7>{1,0,1,1,1,1,1}) + (emp::old::BitArray<7>{1,0,1,1,1,1,1}) ); - REQUIRE((emp::BitArray<7>{1,1,1,1,1,0,1}.REVERSE_SELF().CountOnes()) == 6); + REQUIRE((emp::old::BitArray<7>{1,1,1,1,1,0,1}.REVERSE_SELF().CountOnes()) == 6); REQUIRE( - (emp::BitArray<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF()) + (emp::old::BitArray<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF()) == - (emp::BitArray<8>{0,1,0,0,0,0,1,1}) + (emp::old::BitArray<8>{0,1,0,0,0,0,1,1}) ); - REQUIRE((emp::BitArray<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF().CountOnes()) == 3); + REQUIRE((emp::old::BitArray<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF().CountOnes()) == 3); REQUIRE( - (emp::BitArray<8>{1,0,1,0,1,0,1,0}.REVERSE_SELF()) + (emp::old::BitArray<8>{1,0,1,0,1,0,1,0}.REVERSE_SELF()) == - (emp::BitArray<8>{0,1,0,1,0,1,0,1}) + (emp::old::BitArray<8>{0,1,0,1,0,1,0,1}) ); - REQUIRE((emp::BitArray<8>{0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); + REQUIRE((emp::old::BitArray<8>{0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); REQUIRE( - (emp::BitArray<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF()) + (emp::old::BitArray<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF()) == - (emp::BitArray<8>{0,1,0,1,1,1,1,1}) + (emp::old::BitArray<8>{0,1,0,1,1,1,1,1}) ); - REQUIRE((emp::BitArray<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF().CountOnes()) == 6); + REQUIRE((emp::old::BitArray<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF().CountOnes()) == 6); REQUIRE( - (emp::BitArray<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF()) + (emp::old::BitArray<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF()) == - (emp::BitArray<9>{0,0,1,0,0,0,0,1,1}) + (emp::old::BitArray<9>{0,0,1,0,0,0,0,1,1}) ); REQUIRE( - (emp::BitArray<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF().CountOnes()) + (emp::old::BitArray<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF().CountOnes()) == 3 ); REQUIRE( - (emp::BitArray<9>{1,0,1,0,1,0,1,0,0}.REVERSE_SELF()) + (emp::old::BitArray<9>{1,0,1,0,1,0,1,0,0}.REVERSE_SELF()) == - (emp::BitArray<9>{0,0,1,0,1,0,1,0,1}) + (emp::old::BitArray<9>{0,0,1,0,1,0,1,0,1}) ); REQUIRE( - (emp::BitArray<9>{0,0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) + (emp::old::BitArray<9>{0,0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4 ); REQUIRE( - (emp::BitArray<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF()) + (emp::old::BitArray<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF()) == - (emp::BitArray<9>{0,0,1,0,1,1,1,1,1}) + (emp::old::BitArray<9>{0,0,1,0,1,1,1,1,1}) ); REQUIRE( - (emp::BitArray<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF().CountOnes()) + (emp::old::BitArray<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF().CountOnes()) == 6 ); emp::Random rand(1); for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<15> ba(rand); + emp::old::BitArray<15> ba(rand); ba[0] = 0; ba[15-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1521,7 +1522,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<16> ba(rand); + emp::old::BitArray<16> ba(rand); ba[0] = 0; ba[16-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1530,7 +1531,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<17> ba(rand); + emp::old::BitArray<17> ba(rand); ba[0] = 0; ba[17-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1539,7 +1540,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<31> ba(rand); + emp::old::BitArray<31> ba(rand); ba[0] = 0; ba[31-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1548,7 +1549,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<32> ba(rand); + emp::old::BitArray<32> ba(rand); ba[0] = 0; ba[32-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1557,7 +1558,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<33> ba(rand); + emp::old::BitArray<33> ba(rand); ba[0] = 0; ba[33-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1566,7 +1567,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<63> ba(rand); + emp::old::BitArray<63> ba(rand); ba[0] = 0; ba[63-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1575,7 +1576,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<64> ba(rand); + emp::old::BitArray<64> ba(rand); ba[0] = 0; ba[64-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1584,7 +1585,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<65> ba(rand); + emp::old::BitArray<65> ba(rand); ba[0] = 0; ba[65-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1593,7 +1594,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<127> ba(rand); + emp::old::BitArray<127> ba(rand); ba[0] = 0; ba[127-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1602,7 +1603,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<128> ba(rand); + emp::old::BitArray<128> ba(rand); ba[0] = 0; ba[128-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1611,7 +1612,7 @@ TEST_CASE("Another Test BitArray", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitArray<129> ba(rand); + emp::old::BitArray<129> ba(rand); ba[0] = 0; ba[129-1] = 1; REQUIRE(ba.REVERSE() != ba); @@ -1623,24 +1624,24 @@ TEST_CASE("Another Test BitArray", "[bits]") // test BitArray addition { - emp::BitArray<32> ba0; + emp::old::BitArray<32> ba0; ba0.SetUInt(0, std::numeric_limits::max() - 1); - emp::BitArray<32> ba1; + emp::old::BitArray<32> ba1; ba1.SetUInt(0,1); ba0+=ba1; REQUIRE (ba0.GetUInt(0) == 4294967295); REQUIRE ((ba0+ba1).GetUInt(0) == 0); REQUIRE ((ba0+ba0).GetUInt(0) == 4294967294); - emp::BitArray<8> ba2; + emp::old::BitArray<8> ba2; ba2.SetUInt(0, emp::IntPow(2UL, 8UL)-1); - emp::BitArray<8> ba3; + emp::old::BitArray<8> ba3; ba3.SetUInt(0, 1); REQUIRE((ba2+ba3).GetUInt(0) == 0); - emp::BitArray<64> ba4; + emp::old::BitArray<64> ba4; ba4.SetUInt(0, std::numeric_limits::max()-1); ba4.SetUInt(1, std::numeric_limits::max()); - emp::BitArray<64> ba5; + emp::old::BitArray<64> ba5; ba5.SetUInt(0, 1); ba4+=ba5; REQUIRE(ba4.GetUInt(0) == pow((size_t)2, (size_t)32)-1); @@ -1652,28 +1653,28 @@ TEST_CASE("Another Test BitArray", "[bits]") // test BitArray subtraction { - emp::BitArray<32> ba0; + emp::old::BitArray<32> ba0; ba0.SetUInt(0, 1); - emp::BitArray<32> ba1; + emp::old::BitArray<32> ba1; ba1.SetUInt(0, 1); ba0 = ba0 - ba1; REQUIRE (ba0.GetUInt(0) == 0); REQUIRE ((ba0-ba1).GetUInt(0) == std::numeric_limits::max()); - emp::BitArray<8> ba2; + emp::old::BitArray<8> ba2; ba2.SetUInt(0, 1); - emp::BitArray<8> ba3; + emp::old::BitArray<8> ba3; ba3.SetUInt(0, 1); ba2-=ba3; REQUIRE (ba2.GetUInt(0) == 0); REQUIRE((ba2-ba3).GetUInt(0) == emp::IntPow(2UL,8UL)-1); - emp::BitArray<64> ba4; + emp::old::BitArray<64> ba4; ba4.SetUInt(0, 1); ba4.SetUInt(1, 0); - emp::BitArray<64> ba5; + emp::old::BitArray<64> ba5; ba5.SetUInt(0, 1); ba4-=ba5; @@ -1690,8 +1691,8 @@ TEST_CASE("Another Test BitArray", "[bits]") // test addition and subtraction with multiple fields { - emp::BitArray<65> ba1; - emp::BitArray<65> ba2; + emp::old::BitArray<65> ba1; + emp::old::BitArray<65> ba2; /* PART 1 */ ba1.Clear(); @@ -1755,37 +1756,37 @@ TEST_CASE("Another Test BitArray", "[bits]") } { - emp::BitArray<3> ba0{0,0,0}; + emp::old::BitArray<3> ba0{0,0,0}; REQUIRE(ba0.GetUInt8(0) == 0); REQUIRE(ba0.GetUInt16(0) == 0); REQUIRE(ba0.GetUInt32(0) == 0); REQUIRE(ba0.GetUInt64(0) == 0); REQUIRE(ba0.GetNumStates() == 8); - emp::BitArray<3> ba1{1,0,0}; + emp::old::BitArray<3> ba1{1,0,0}; REQUIRE(ba1.GetUInt8(0) == 1); REQUIRE(ba1.GetUInt16(0) == 1); REQUIRE(ba1.GetUInt32(0) == 1); REQUIRE(ba1.GetUInt64(0) == 1); - emp::BitArray<3> ba2{1,1,0}; + emp::old::BitArray<3> ba2{1,1,0}; REQUIRE(ba2.GetUInt8(0) == 3); REQUIRE(ba2.GetUInt16(0) == 3); REQUIRE(ba2.GetUInt32(0) == 3); REQUIRE(ba2.GetUInt64(0) == 3); - emp::BitArray<3> ba3{1,1,1}; + emp::old::BitArray<3> ba3{1,1,1}; REQUIRE(ba3.GetUInt8(0) == 7); - emp::BitArray<3> ba4{0,1,1}; + emp::old::BitArray<3> ba4{0,1,1}; REQUIRE(ba4.GetUInt8(0) == 6); - emp::BitArray<32> ba5; + emp::old::BitArray<32> ba5; ba5.SetUInt(0, 1789156UL); REQUIRE(ba5.GetUInt64(0) == 1789156ULL); REQUIRE(ba5.GetNumStates() == 4294967296ULL); - emp::BitArray<63> ba6; + emp::old::BitArray<63> ba6; ba6.SetUInt64(0, 789156816848ULL); REQUIRE(ba6.GetUInt64(0) == 789156816848ULL); REQUIRE(ba6.GetNumStates() == 9223372036854775808ULL); @@ -1793,13 +1794,13 @@ TEST_CASE("Another Test BitArray", "[bits]") // @CAO: Removed GetDouble() due to confusing name (GetUInt64() gives the same answer, but with // the correct encoding. - // emp::BitArray<65> ba7; + // emp::old::BitArray<65> ba7; // ba7.SetUInt64(0, 1789156816848ULL); // ba7.Set(64); // REQUIRE(ba7.GetDouble() == 1789156816848.0 + emp::Pow2(64.0)); // REQUIRE(ba7.MaxDouble() == 36893488147419103231.0); - // emp::BitArray<1027> ba8; + // emp::old::BitArray<1027> ba8; // ba8.Set(1026); // REQUIRE(std::isinf(ba8.GetDouble())); // REQUIRE(std::isinf(ba8.MaxDouble())); @@ -1807,10 +1808,10 @@ TEST_CASE("Another Test BitArray", "[bits]") // test list initializer { - emp::BitArray<3> ba_empty{0,0,0}; - emp::BitArray<3> ba_first{1,0,0}; - emp::BitArray<3> ba_last{0,0,1}; - emp::BitArray<3> ba_full{1,1,1}; + emp::old::BitArray<3> ba_empty{0,0,0}; + emp::old::BitArray<3> ba_first{1,0,0}; + emp::old::BitArray<3> ba_last{0,0,1}; + emp::old::BitArray<3> ba_full{1,1,1}; REQUIRE(ba_empty.CountOnes() == 0); REQUIRE(ba_first.CountOnes() == 1); @@ -1823,14 +1824,14 @@ TEST_CASE("Another Test BitArray", "[bits]") emp::Random rand(1); - emp::BitArray<32> orig(rand); + emp::old::BitArray<32> orig(rand); - emp::array, 1> d1; - emp::array, 2> d2; - emp::array, 4> d4; - emp::array, 8> d8; - emp::array, 16> d16; - emp::array, 32> d32; + emp::array, 1> d1; + emp::array, 2> d2; + emp::array, 4> d4; + emp::array, 8> d8; + emp::array, 16> d16; + emp::array, 32> d32; // Import @@ -1984,19 +1985,19 @@ TEST_CASE("Another Test BitArray", "[bits]") } - emp::BitArray<10> ba10; - emp::BitArray<25> ba25; - emp::BitArray<32> ba32; - emp::BitArray<50> ba50; - emp::BitArray<64> ba64; - emp::BitArray<80> ba80; + emp::old::BitArray<10> ba10; + emp::old::BitArray<25> ba25; + emp::old::BitArray<32> ba32; + emp::old::BitArray<50> ba50; + emp::old::BitArray<64> ba64; + emp::old::BitArray<80> ba80; ba80[70] = 1; ba80 <<= 1; - emp::BitArray<80> ba80c(ba80); + emp::old::BitArray<80> ba80c(ba80); for (size_t i = 0; i < 75; i++) { - emp::BitArray<80> shift_set = ba80 >> i; + emp::old::BitArray<80> shift_set = ba80 >> i; REQUIRE((shift_set.CountOnes() == 1) == (i <= 71)); } @@ -2056,7 +2057,7 @@ TEST_CASE("Another Test BitArray", "[bits]") REQUIRE(ba80.GetUInt32AtBit(64) == 130); REQUIRE(ba80.GetUInt8AtBit(64) == 130); - emp::BitArray<96> ba; + emp::old::BitArray<96> ba; REQUIRE (ba.LongestSegmentOnes() == 0); ba.SetUInt(2, 1); @@ -2157,11 +2158,11 @@ TEST_CASE("Another Test BitArray", "[bits]") // tests for RandomizeFixed { emp::Random random(1); - emp::BitArray<25> ba_25; - emp::BitArray<32> ba_32; - emp::BitArray<50> ba_50; - emp::BitArray<64> ba_64; - emp::BitArray<80> ba_80; + emp::old::BitArray<25> ba_25; + emp::old::BitArray<32> ba_32; + emp::old::BitArray<50> ba_50; + emp::old::BitArray<64> ba_64; + emp::old::BitArray<80> ba_80; ba_25.FlipRandomCount(random, 0); REQUIRE(!ba_25.CountOnes()); @@ -2256,19 +2257,19 @@ TEST_CASE("Another Test BitArray", "[bits]") // set up emp::Random rand(1); - emp::BitArray<10> ba10(rand); - emp::BitArray<25> ba25(rand); - emp::BitArray<32> ba32(rand); - emp::BitArray<50> ba50(rand); - emp::BitArray<64> ba64(rand); - emp::BitArray<80> ba80(rand); - - emp::BitArray<10> ba10_deser; - emp::BitArray<25> ba25_deser; - emp::BitArray<32> ba32_deser; - emp::BitArray<50> ba50_deser; - emp::BitArray<64> ba64_deser; - emp::BitArray<80> ba80_deser; + emp::old::BitArray<10> ba10(rand); + emp::old::BitArray<25> ba25(rand); + emp::old::BitArray<32> ba32(rand); + emp::old::BitArray<50> ba50(rand); + emp::old::BitArray<64> ba64(rand); + emp::old::BitArray<80> ba80(rand); + + emp::old::BitArray<10> ba10_deser; + emp::old::BitArray<25> ba25_deser; + emp::old::BitArray<32> ba32_deser; + emp::old::BitArray<50> ba50_deser; + emp::old::BitArray<64> ba64_deser; + emp::old::BitArray<80> ba80_deser; std::stringstream ss; @@ -2316,19 +2317,19 @@ TEST_CASE("Another Test BitArray", "[bits]") // set up emp::Random rand(1); - emp::BitArray<10> ba10(rand); - emp::BitArray<25> ba25(rand); - emp::BitArray<32> ba32(rand); - emp::BitArray<50> ba50(rand); - emp::BitArray<64> ba64(rand); - emp::BitArray<80> ba80(rand); - - emp::BitArray<10> ba10_deser; - emp::BitArray<25> ba25_deser; - emp::BitArray<32> ba32_deser; - emp::BitArray<50> ba50_deser; - emp::BitArray<64> ba64_deser; - emp::BitArray<80> ba80_deser; + emp::old::BitArray<10> ba10(rand); + emp::old::BitArray<25> ba25(rand); + emp::old::BitArray<32> ba32(rand); + emp::old::BitArray<50> ba50(rand); + emp::old::BitArray<64> ba64(rand); + emp::old::BitArray<80> ba80(rand); + + emp::old::BitArray<10> ba10_deser; + emp::old::BitArray<25> ba25_deser; + emp::old::BitArray<32> ba32_deser; + emp::old::BitArray<50> ba50_deser; + emp::old::BitArray<64> ba64_deser; + emp::old::BitArray<80> ba80_deser; std::stringstream ss; @@ -2377,12 +2378,12 @@ TEST_CASE("Another Test BitArray", "[bits]") TEST_CASE("Test BitArray string construction", "[tools]") { - REQUIRE( emp::BitArray<5>( "01001" ) == emp::BitArray<5>{0, 1, 0, 0, 1} ); + REQUIRE( emp::old::BitArray<5>( "01001" ) == emp::old::BitArray<5>{0, 1, 0, 0, 1} ); - // std::bitset treats bits in the opposite direction of emp::BitArray. + // std::bitset treats bits in the opposite direction of emp::old::BitArray. REQUIRE( - emp::BitArray<5>( std::bitset<5>( "01001" ) ) - == emp::BitArray<5>{1, 0, 0, 1, 0} + emp::old::BitArray<5>( std::bitset<5>( "01001" ) ) + == emp::old::BitArray<5>{1, 0, 0, 1, 0} ); } diff --git a/tests/bits/BitMatrix.cpp b/tests/bits/BitMatrix.cpp index 7eb7a1595d..4da1506719 100644 --- a/tests/bits/BitMatrix.cpp +++ b/tests/bits/BitMatrix.cpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BitMatrix.cpp - * + * @file + * @brief TODO. */ #include diff --git a/tests/bits/BitSet.cpp b/tests/bits/BitSet.cpp index ce1513e146..9f20ba9d76 100644 --- a/tests/bits/BitSet.cpp +++ b/tests/bits/BitSet.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BitSet.cpp + * @file */ #define EMP_DECORATE(X) [X] @@ -42,7 +43,7 @@ template struct TestBVConstruct; template struct TestBVConstruct { static void Run() { - emp::BitSet bs; + emp::old::BitSet bs; REQUIRE( bs.GetSize() == VAL1 ); REQUIRE( bs.CountOnes() == 0 ); for (size_t i = 0; i < VAL1; i++) bs[i] = true; @@ -60,13 +61,13 @@ struct TestBVConstruct<> { TEST_CASE("1: Test BitSet Constructors", "[bits]"){ // Create a size 50 bit vector, default to all zeros. - emp::BitSet<50> bs1; + emp::old::BitSet<50> bs1; REQUIRE( bs1.GetSize() == 50 ); REQUIRE( bs1.CountOnes() == 0 ); REQUIRE( (~bs1).CountOnes() == 50 ); // Create a size 1000 BitSet, default to all ones. - emp::BitSet<1000> bs2(true); + emp::old::BitSet<1000> bs2(true); REQUIRE( bs2.GetSize() == 1000 ); REQUIRE( bs2.CountOnes() == 1000 ); @@ -74,45 +75,45 @@ TEST_CASE("1: Test BitSet Constructors", "[bits]"){ TestBVConstruct<1,2,7,8,9,15,16,17,31,32,33,63,64,65,127,128,129,191,192,193,200>::Run(); // Build a relatively large BitSet. - emp::BitSet<1000000> bs4; + emp::old::BitSet<1000000> bs4; for (size_t i = 0; i < bs4.GetSize(); i += 100) bs4[i].Toggle(); REQUIRE( bs4.CountOnes() == 10000 ); // Try out the copy constructor. - emp::BitSet<1000000> bs5(bs4); + emp::old::BitSet<1000000> bs5(bs4); REQUIRE( bs5.GetSize() == 1000000 ); REQUIRE( bs5.CountOnes() == 10000 ); // Construct from std::bitset. std::bitset<6> bit_set; bit_set[1] = 1; bit_set[2] = 1; bit_set[4] = 1; - emp::BitSet<6> bs7(bit_set); + emp::old::BitSet<6> bs7(bit_set); REQUIRE( bs7.GetSize() == 6 ); REQUIRE( bs7.CountOnes() == 3 ); // Construct from string. std::string bit_string = "10011001010000011101"; - emp::BitSet<20> bs8(bit_string); + emp::old::BitSet<20> bs8(bit_string); REQUIRE( bs8.GetSize() == 20 ); REQUIRE( bs8.CountOnes() == 9 ); // Some random BitSets emp::Random random; - emp::BitSet<1000> bs9(random); // 50/50 chance for each bit. + emp::old::BitSet<1000> bs9(random); // 50/50 chance for each bit. const size_t bs9_ones = bs9.CountOnes(); REQUIRE( bs9_ones >= 400 ); REQUIRE( bs9_ones <= 600 ); - emp::BitSet<1000> bs10(random, 0.8); // 80% chance of ones. + emp::old::BitSet<1000> bs10(random, 0.8); // 80% chance of ones. const size_t bs10_ones = bs10.CountOnes(); REQUIRE( bs10_ones >= 750 ); REQUIRE( bs10_ones <= 850 ); - emp::BitSet<1000> bs11(random, 117); // Exactly 117 ones, randomly placed. + emp::old::BitSet<1000> bs11(random, 117); // Exactly 117 ones, randomly placed. const size_t bs11_ones = bs11.CountOnes(); REQUIRE( bs11_ones == 117 ); - emp::BitSet<13> bs12({1,0,0,0,1,1,1,0,0,0,1,1,1}); // Construct with initializer list. + emp::old::BitSet<13> bs12({1,0,0,0,1,1,1,0,0,0,1,1,1}); // Construct with initializer list. REQUIRE( bs12.GetSize() == 13 ); REQUIRE( bs12.CountOnes() == 7 ); } @@ -123,10 +124,10 @@ template struct TestBVAssign; template struct TestBVAssign { static void Run() { - emp::BitSet bs; + emp::old::BitSet bs; // Copy to a second bs, make changes, then copy back. - emp::BitSet bs2; + emp::old::BitSet bs2; for (size_t i = 1; i < bs2.GetSize(); i += 2) { bs2[i] = 1; @@ -175,14 +176,14 @@ TEST_CASE("2: Test BitSet Assignemnts", "[bits]"){ TEST_CASE("3: Test Simple BitSet Accessors", "[bits]"){ - emp::BitSet<1> bs1(true); - emp::BitSet<8> bs8( "10001101" ); - emp::BitSet<32> bs32( "10001101100011011000110110001101" ); - emp::BitSet<64> bs64( "1000110110001101100000011000110000001101100000000000110110001101" ); - emp::BitSet<75> bs75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); + emp::old::BitSet<1> bs1(true); + emp::old::BitSet<8> bs8( "10001101" ); + emp::old::BitSet<32> bs32( "10001101100011011000110110001101" ); + emp::old::BitSet<64> bs64( "1000110110001101100000011000110000001101100000000000110110001101" ); + emp::old::BitSet<75> bs75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); emp::Random random(1); - emp::BitSet<1000> bs1k(random, 0.75); + emp::old::BitSet<1000> bs1k(random, 0.75); // Make sure all sizes are correct. REQUIRE( bs1.GetSize() == 1 ); @@ -269,7 +270,7 @@ TEST_CASE("3: Test Simple BitSet Accessors", "[bits]"){ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { // Now try range-based accessors on a single bit. - emp::BitSet<1> bs1(false); REQUIRE( bs1[0] == false ); REQUIRE( bs1.CountOnes() == 0 ); + emp::old::BitSet<1> bs1(false); REQUIRE( bs1[0] == false ); REQUIRE( bs1.CountOnes() == 0 ); bs1.Set(0); REQUIRE( bs1[0] == true ); REQUIRE( bs1.CountOnes() == 1 ); bs1.Clear(0); REQUIRE( bs1[0] == false ); REQUIRE( bs1.CountOnes() == 0 ); bs1.Toggle(0); REQUIRE( bs1[0] == true ); REQUIRE( bs1.CountOnes() == 1 ); @@ -284,7 +285,7 @@ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { bs1.SetRange(1,1); REQUIRE( bs1[0] == false ); REQUIRE( bs1.CountOnes() == 0 ); // Test when a full byte is used. - emp::BitSet<8> bs8( "10110001" ); REQUIRE(bs8.GetValue() == 177.0); // 10110001 + emp::old::BitSet<8> bs8( "10110001" ); REQUIRE(bs8.GetValue() == 177.0); // 10110001 bs8.Set(2); REQUIRE(bs8.GetValue() == 181.0); // 10110101 bs8.Set(0, 0); REQUIRE(bs8.GetValue() == 180.0); // 10110100 bs8.SetRange(1, 4); REQUIRE(bs8.GetValue() == 190.0); // 10111110 @@ -301,7 +302,7 @@ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { // Test a full field. constexpr double ALL_64 = (double) ((uint64_t) -1); - emp::BitSet<64> bs64( "10110001101100011011" ); + emp::old::BitSet<64> bs64( "10110001101100011011" ); REQUIRE(bs64.GetValue() == 727835.0); bs64.Set(6); REQUIRE(bs64.GetValue() == 727899.0); // ...0 010110001101101011011 bs64.Set(0, 0); REQUIRE(bs64.GetValue() == 727898.0); // ...0 010110001101101011010 @@ -317,11 +318,11 @@ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { bs64.Toggle(0,64); REQUIRE(bs64.GetValue() == 491520.0); // ...0 001111000000000000000 - emp::BitSet<75> bs75( "110000111110010011111000001011100000111110001011110000011111010001110100010" ); + emp::old::BitSet<75> bs75( "110000111110010011111000001011100000111110001011110000011111010001110100010" ); // Test a full + partial field. constexpr double ALL_88 = ((double) ((uint64_t) -1)) * emp::Pow2(24); - emp::BitSet<88> bs88( "11011000110110001101" ); + emp::old::BitSet<88> bs88( "11011000110110001101" ); REQUIRE(bs88.GetValue() == 888205.0); // ...0 010110001101100011011 // Start with same tests as last time... @@ -350,7 +351,7 @@ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { // A larger BitSet with lots of random tests. emp::Random random(1); - emp::BitSet<1000> bs1k(random, 0.65); + emp::old::BitSet<1000> bs1k(random, 0.65); size_t num_ones = bs1k.CountOnes(); REQUIRE(num_ones > 550); bs1k.Toggle(); REQUIRE(bs1k.CountOnes() == 1000 - num_ones); @@ -372,9 +373,9 @@ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { } // Test Any(), All() and None() - emp::BitSet<6> bs_empty = "000000"; - emp::BitSet<6> bs_mixed = "010101"; - emp::BitSet<6> bs_full = "111111"; + emp::old::BitSet<6> bs_empty = "000000"; + emp::old::BitSet<6> bs_mixed = "010101"; + emp::old::BitSet<6> bs_full = "111111"; REQUIRE(bs_empty.Any() == false); REQUIRE(bs_mixed.Any() == true); @@ -392,7 +393,7 @@ TEST_CASE("4: Test BitSet Set*, Clear* and Toggle* Accessors", "[bits]") { TEST_CASE("5: Test Randomize() and variants", "[bits]") { emp::Random random(1); - emp::BitSet<1000> bs; + emp::old::BitSet<1000> bs; REQUIRE(bs.None() == true); @@ -513,7 +514,7 @@ TEST_CASE("6: Test getting and setting whole chunks of bits", "[bits]") { constexpr size_t num_bits = 145; constexpr size_t num_bytes = 19; - emp::BitSet bs; + emp::old::BitSet bs; REQUIRE(bs.GetSize() == num_bits); REQUIRE(bs.GetNumBytes() == num_bytes); @@ -582,7 +583,7 @@ TEST_CASE("6: Test getting and setting whole chunks of bits", "[bits]") { TEST_CASE("7: Test functions that analyze and manipulate ones", "[bits]") { - emp::BitSet<16> bs = "0111000010001000"; + emp::old::BitSet<16> bs = "0111000010001000"; REQUIRE(bs.GetSize() == 16); REQUIRE(bs.CountOnes() == 5); @@ -643,7 +644,7 @@ TEST_CASE("7: Test functions that analyze and manipulate ones", "[bits]") { } TEST_CASE("8: Test printing and string functions.", "[bits]") { - emp::BitSet<6> bs6("111000"); + emp::old::BitSet<6> bs6("111000"); REQUIRE(bs6.ToString() == "111000"); REQUIRE(bs6.ToBinaryString() == "111000"); @@ -652,7 +653,7 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { REQUIRE(bs6.ToIDString() == "3 4 5"); REQUIRE(bs6.ToRangeString() == "3-5"); - emp::BitSet<64> bs64("1000000010001000001000000110001000000000000010000000000000111000"); + emp::old::BitSet<64> bs64("1000000010001000001000000110001000000000000010000000000000111000"); REQUIRE(bs64.ToArrayString() == "0001110000000000000100000000000001000110000001000001000100000001"); REQUIRE(bs64.ToBinaryString() == "1000000010001000001000000110001000000000000010000000000000111000"); @@ -660,8 +661,8 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { REQUIRE(bs64.ToIDString(",") == "3,4,5,19,33,37,38,45,51,55,63"); REQUIRE(bs64.ToRangeString() == "3-5,19,33,37-38,45,51,55,63"); -// emp::BitSet<65> bs65("00011110000000000001000000000000010001100000010000010001000000111"); - emp::BitSet<65> bs65("11100000010001000001000000110001000000000000010000000000001111000"); +// emp::old::BitSet<65> bs65("00011110000000000001000000000000010001100000010000010001000000111"); + emp::old::BitSet<65> bs65("11100000010001000001000000110001000000000000010000000000001111000"); REQUIRE(bs65.ToArrayString() == "00011110000000000001000000000000010001100000010000010001000000111"); REQUIRE(bs65.ToBinaryString() == "11100000010001000001000000110001000000000000010000000000001111000"); @@ -671,172 +672,172 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { } TEST_CASE("9: Test Boolean logic and shifting functions.", "[bits]") { - const emp::BitSet<8> input1 = "00001111"; - const emp::BitSet<8> input2 = "00110011"; - const emp::BitSet<8> input3 = "01010101"; + const emp::old::BitSet<8> input1 = "00001111"; + const emp::old::BitSet<8> input2 = "00110011"; + const emp::old::BitSet<8> input3 = "01010101"; // Test *_SELF() Boolean Logic functions. - emp::BitSet<8> bs; REQUIRE(bs == emp::BitSet<8>("00000000")); - bs.NOT_SELF(); REQUIRE(bs == emp::BitSet<8>("11111111")); - bs.AND_SELF(input1); REQUIRE(bs == emp::BitSet<8>("00001111")); - bs.AND_SELF(input1); REQUIRE(bs == emp::BitSet<8>("00001111")); - bs.AND_SELF(input2); REQUIRE(bs == emp::BitSet<8>("00000011")); - bs.AND_SELF(input3); REQUIRE(bs == emp::BitSet<8>("00000001")); - - bs.OR_SELF(input1); REQUIRE(bs == emp::BitSet<8>("00001111")); - bs.OR_SELF(input1); REQUIRE(bs == emp::BitSet<8>("00001111")); - bs.OR_SELF(input3); REQUIRE(bs == emp::BitSet<8>("01011111")); - bs.OR_SELF(input2); REQUIRE(bs == emp::BitSet<8>("01111111")); - - bs.NAND_SELF(input1); REQUIRE(bs == emp::BitSet<8>("11110000")); - bs.NAND_SELF(input1); REQUIRE(bs == emp::BitSet<8>("11111111")); - bs.NAND_SELF(input2); REQUIRE(bs == emp::BitSet<8>("11001100")); - bs.NAND_SELF(input3); REQUIRE(bs == emp::BitSet<8>("10111011")); - - bs.NOR_SELF(input1); REQUIRE(bs == emp::BitSet<8>("01000000")); - bs.NOR_SELF(input1); REQUIRE(bs == emp::BitSet<8>("10110000")); - bs.NOR_SELF(input2); REQUIRE(bs == emp::BitSet<8>("01001100")); - bs.NOR_SELF(input3); REQUIRE(bs == emp::BitSet<8>("10100010")); - - bs.XOR_SELF(input1); REQUIRE(bs == emp::BitSet<8>("10101101")); - bs.XOR_SELF(input1); REQUIRE(bs == emp::BitSet<8>("10100010")); - bs.XOR_SELF(input2); REQUIRE(bs == emp::BitSet<8>("10010001")); - bs.XOR_SELF(input3); REQUIRE(bs == emp::BitSet<8>("11000100")); - - bs.EQU_SELF(input1); REQUIRE(bs == emp::BitSet<8>("00110100")); - bs.EQU_SELF(input1); REQUIRE(bs == emp::BitSet<8>("11000100")); - bs.EQU_SELF(input2); REQUIRE(bs == emp::BitSet<8>("00001000")); - bs.EQU_SELF(input3); REQUIRE(bs == emp::BitSet<8>("10100010")); - - bs.NOT_SELF(); REQUIRE(bs == emp::BitSet<8>("01011101")); + emp::old::BitSet<8> bs; REQUIRE(bs == emp::old::BitSet<8>("00000000")); + bs.NOT_SELF(); REQUIRE(bs == emp::old::BitSet<8>("11111111")); + bs.AND_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs.AND_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs.AND_SELF(input2); REQUIRE(bs == emp::old::BitSet<8>("00000011")); + bs.AND_SELF(input3); REQUIRE(bs == emp::old::BitSet<8>("00000001")); + + bs.OR_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs.OR_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs.OR_SELF(input3); REQUIRE(bs == emp::old::BitSet<8>("01011111")); + bs.OR_SELF(input2); REQUIRE(bs == emp::old::BitSet<8>("01111111")); + + bs.NAND_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("11110000")); + bs.NAND_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("11111111")); + bs.NAND_SELF(input2); REQUIRE(bs == emp::old::BitSet<8>("11001100")); + bs.NAND_SELF(input3); REQUIRE(bs == emp::old::BitSet<8>("10111011")); + + bs.NOR_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("01000000")); + bs.NOR_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("10110000")); + bs.NOR_SELF(input2); REQUIRE(bs == emp::old::BitSet<8>("01001100")); + bs.NOR_SELF(input3); REQUIRE(bs == emp::old::BitSet<8>("10100010")); + + bs.XOR_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("10101101")); + bs.XOR_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("10100010")); + bs.XOR_SELF(input2); REQUIRE(bs == emp::old::BitSet<8>("10010001")); + bs.XOR_SELF(input3); REQUIRE(bs == emp::old::BitSet<8>("11000100")); + + bs.EQU_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("00110100")); + bs.EQU_SELF(input1); REQUIRE(bs == emp::old::BitSet<8>("11000100")); + bs.EQU_SELF(input2); REQUIRE(bs == emp::old::BitSet<8>("00001000")); + bs.EQU_SELF(input3); REQUIRE(bs == emp::old::BitSet<8>("10100010")); + + bs.NOT_SELF(); REQUIRE(bs == emp::old::BitSet<8>("01011101")); // Test regular Boolean Logic functions. - bs.Clear(); REQUIRE(bs == emp::BitSet<8>("00000000")); - emp::BitSet<8> bs1 = bs.NOT(); REQUIRE(bs1 == emp::BitSet<8>("11111111")); + bs.Clear(); REQUIRE(bs == emp::old::BitSet<8>("00000000")); + emp::old::BitSet<8> bs1 = bs.NOT(); REQUIRE(bs1 == emp::old::BitSet<8>("11111111")); - bs1 = bs1.AND(input1); REQUIRE(bs1 == emp::BitSet<8>("00001111")); - emp::BitSet<8> bs2 = bs1.AND(input1); REQUIRE(bs2 == emp::BitSet<8>("00001111")); - emp::BitSet<8> bs3 = bs2.AND(input2); REQUIRE(bs3 == emp::BitSet<8>("00000011")); - emp::BitSet<8> bs4 = bs3.AND(input3); REQUIRE(bs4 == emp::BitSet<8>("00000001")); + bs1 = bs1.AND(input1); REQUIRE(bs1 == emp::old::BitSet<8>("00001111")); + emp::old::BitSet<8> bs2 = bs1.AND(input1); REQUIRE(bs2 == emp::old::BitSet<8>("00001111")); + emp::old::BitSet<8> bs3 = bs2.AND(input2); REQUIRE(bs3 == emp::old::BitSet<8>("00000011")); + emp::old::BitSet<8> bs4 = bs3.AND(input3); REQUIRE(bs4 == emp::old::BitSet<8>("00000001")); - bs1 = bs4.OR(input1); REQUIRE(bs1 == emp::BitSet<8>("00001111")); - bs2 = bs1.OR(input1); REQUIRE(bs2 == emp::BitSet<8>("00001111")); - bs3 = bs2.OR(input3); REQUIRE(bs3 == emp::BitSet<8>("01011111")); - bs4 = bs3.OR(input2); REQUIRE(bs4 == emp::BitSet<8>("01111111")); + bs1 = bs4.OR(input1); REQUIRE(bs1 == emp::old::BitSet<8>("00001111")); + bs2 = bs1.OR(input1); REQUIRE(bs2 == emp::old::BitSet<8>("00001111")); + bs3 = bs2.OR(input3); REQUIRE(bs3 == emp::old::BitSet<8>("01011111")); + bs4 = bs3.OR(input2); REQUIRE(bs4 == emp::old::BitSet<8>("01111111")); - bs1 = bs4.NAND(input1); REQUIRE(bs1 == emp::BitSet<8>("11110000")); - bs2 = bs1.NAND(input1); REQUIRE(bs2 == emp::BitSet<8>("11111111")); - bs3 = bs2.NAND(input2); REQUIRE(bs3 == emp::BitSet<8>("11001100")); - bs4 = bs3.NAND(input3); REQUIRE(bs4 == emp::BitSet<8>("10111011")); + bs1 = bs4.NAND(input1); REQUIRE(bs1 == emp::old::BitSet<8>("11110000")); + bs2 = bs1.NAND(input1); REQUIRE(bs2 == emp::old::BitSet<8>("11111111")); + bs3 = bs2.NAND(input2); REQUIRE(bs3 == emp::old::BitSet<8>("11001100")); + bs4 = bs3.NAND(input3); REQUIRE(bs4 == emp::old::BitSet<8>("10111011")); - bs1 = bs4.NOR(input1); REQUIRE(bs1 == emp::BitSet<8>("01000000")); - bs2 = bs1.NOR(input1); REQUIRE(bs2 == emp::BitSet<8>("10110000")); - bs3 = bs2.NOR(input2); REQUIRE(bs3 == emp::BitSet<8>("01001100")); - bs4 = bs3.NOR(input3); REQUIRE(bs4 == emp::BitSet<8>("10100010")); + bs1 = bs4.NOR(input1); REQUIRE(bs1 == emp::old::BitSet<8>("01000000")); + bs2 = bs1.NOR(input1); REQUIRE(bs2 == emp::old::BitSet<8>("10110000")); + bs3 = bs2.NOR(input2); REQUIRE(bs3 == emp::old::BitSet<8>("01001100")); + bs4 = bs3.NOR(input3); REQUIRE(bs4 == emp::old::BitSet<8>("10100010")); - bs1 = bs4.XOR(input1); REQUIRE(bs1 == emp::BitSet<8>("10101101")); - bs2 = bs1.XOR(input1); REQUIRE(bs2 == emp::BitSet<8>("10100010")); - bs3 = bs2.XOR(input2); REQUIRE(bs3 == emp::BitSet<8>("10010001")); - bs4 = bs3.XOR(input3); REQUIRE(bs4 == emp::BitSet<8>("11000100")); + bs1 = bs4.XOR(input1); REQUIRE(bs1 == emp::old::BitSet<8>("10101101")); + bs2 = bs1.XOR(input1); REQUIRE(bs2 == emp::old::BitSet<8>("10100010")); + bs3 = bs2.XOR(input2); REQUIRE(bs3 == emp::old::BitSet<8>("10010001")); + bs4 = bs3.XOR(input3); REQUIRE(bs4 == emp::old::BitSet<8>("11000100")); - bs1 = bs4.EQU(input1); REQUIRE(bs1 == emp::BitSet<8>("00110100")); - bs2 = bs1.EQU(input1); REQUIRE(bs2 == emp::BitSet<8>("11000100")); - bs3 = bs2.EQU(input2); REQUIRE(bs3 == emp::BitSet<8>("00001000")); - bs4 = bs3.EQU(input3); REQUIRE(bs4 == emp::BitSet<8>("10100010")); + bs1 = bs4.EQU(input1); REQUIRE(bs1 == emp::old::BitSet<8>("00110100")); + bs2 = bs1.EQU(input1); REQUIRE(bs2 == emp::old::BitSet<8>("11000100")); + bs3 = bs2.EQU(input2); REQUIRE(bs3 == emp::old::BitSet<8>("00001000")); + bs4 = bs3.EQU(input3); REQUIRE(bs4 == emp::old::BitSet<8>("10100010")); - bs = bs4.NOT(); REQUIRE(bs == emp::BitSet<8>("01011101")); + bs = bs4.NOT(); REQUIRE(bs == emp::old::BitSet<8>("01011101")); // Test Boolean Logic operators. - bs.Clear(); REQUIRE(bs == emp::BitSet<8>("00000000")); - bs1 = ~bs; REQUIRE(bs1 == emp::BitSet<8>("11111111")); + bs.Clear(); REQUIRE(bs == emp::old::BitSet<8>("00000000")); + bs1 = ~bs; REQUIRE(bs1 == emp::old::BitSet<8>("11111111")); - bs1 = bs1 & input1; REQUIRE(bs1 == emp::BitSet<8>("00001111")); - bs2 = bs1 & input1; REQUIRE(bs2 == emp::BitSet<8>("00001111")); - bs3 = bs2 & input2; REQUIRE(bs3 == emp::BitSet<8>("00000011")); - bs4 = bs3 & input3; REQUIRE(bs4 == emp::BitSet<8>("00000001")); + bs1 = bs1 & input1; REQUIRE(bs1 == emp::old::BitSet<8>("00001111")); + bs2 = bs1 & input1; REQUIRE(bs2 == emp::old::BitSet<8>("00001111")); + bs3 = bs2 & input2; REQUIRE(bs3 == emp::old::BitSet<8>("00000011")); + bs4 = bs3 & input3; REQUIRE(bs4 == emp::old::BitSet<8>("00000001")); - bs1 = bs4 | input1; REQUIRE(bs1 == emp::BitSet<8>("00001111")); - bs2 = bs1 | input1; REQUIRE(bs2 == emp::BitSet<8>("00001111")); - bs3 = bs2 | input3; REQUIRE(bs3 == emp::BitSet<8>("01011111")); - bs4 = bs3 | input2; REQUIRE(bs4 == emp::BitSet<8>("01111111")); + bs1 = bs4 | input1; REQUIRE(bs1 == emp::old::BitSet<8>("00001111")); + bs2 = bs1 | input1; REQUIRE(bs2 == emp::old::BitSet<8>("00001111")); + bs3 = bs2 | input3; REQUIRE(bs3 == emp::old::BitSet<8>("01011111")); + bs4 = bs3 | input2; REQUIRE(bs4 == emp::old::BitSet<8>("01111111")); - bs1 = ~(bs4 & input1); REQUIRE(bs1 == emp::BitSet<8>("11110000")); - bs2 = ~(bs1 & input1); REQUIRE(bs2 == emp::BitSet<8>("11111111")); - bs3 = ~(bs2 & input2); REQUIRE(bs3 == emp::BitSet<8>("11001100")); - bs4 = ~(bs3 & input3); REQUIRE(bs4 == emp::BitSet<8>("10111011")); + bs1 = ~(bs4 & input1); REQUIRE(bs1 == emp::old::BitSet<8>("11110000")); + bs2 = ~(bs1 & input1); REQUIRE(bs2 == emp::old::BitSet<8>("11111111")); + bs3 = ~(bs2 & input2); REQUIRE(bs3 == emp::old::BitSet<8>("11001100")); + bs4 = ~(bs3 & input3); REQUIRE(bs4 == emp::old::BitSet<8>("10111011")); - bs1 = ~(bs4 | input1); REQUIRE(bs1 == emp::BitSet<8>("01000000")); - bs2 = ~(bs1 | input1); REQUIRE(bs2 == emp::BitSet<8>("10110000")); - bs3 = ~(bs2 | input2); REQUIRE(bs3 == emp::BitSet<8>("01001100")); - bs4 = ~(bs3 | input3); REQUIRE(bs4 == emp::BitSet<8>("10100010")); + bs1 = ~(bs4 | input1); REQUIRE(bs1 == emp::old::BitSet<8>("01000000")); + bs2 = ~(bs1 | input1); REQUIRE(bs2 == emp::old::BitSet<8>("10110000")); + bs3 = ~(bs2 | input2); REQUIRE(bs3 == emp::old::BitSet<8>("01001100")); + bs4 = ~(bs3 | input3); REQUIRE(bs4 == emp::old::BitSet<8>("10100010")); - bs1 = bs4 ^ input1; REQUIRE(bs1 == emp::BitSet<8>("10101101")); - bs2 = bs1 ^ input1; REQUIRE(bs2 == emp::BitSet<8>("10100010")); - bs3 = bs2 ^ input2; REQUIRE(bs3 == emp::BitSet<8>("10010001")); - bs4 = bs3 ^ input3; REQUIRE(bs4 == emp::BitSet<8>("11000100")); + bs1 = bs4 ^ input1; REQUIRE(bs1 == emp::old::BitSet<8>("10101101")); + bs2 = bs1 ^ input1; REQUIRE(bs2 == emp::old::BitSet<8>("10100010")); + bs3 = bs2 ^ input2; REQUIRE(bs3 == emp::old::BitSet<8>("10010001")); + bs4 = bs3 ^ input3; REQUIRE(bs4 == emp::old::BitSet<8>("11000100")); - bs1 = ~(bs4 ^ input1); REQUIRE(bs1 == emp::BitSet<8>("00110100")); - bs2 = ~(bs1 ^ input1); REQUIRE(bs2 == emp::BitSet<8>("11000100")); - bs3 = ~(bs2 ^ input2); REQUIRE(bs3 == emp::BitSet<8>("00001000")); - bs4 = ~(bs3 ^ input3); REQUIRE(bs4 == emp::BitSet<8>("10100010")); + bs1 = ~(bs4 ^ input1); REQUIRE(bs1 == emp::old::BitSet<8>("00110100")); + bs2 = ~(bs1 ^ input1); REQUIRE(bs2 == emp::old::BitSet<8>("11000100")); + bs3 = ~(bs2 ^ input2); REQUIRE(bs3 == emp::old::BitSet<8>("00001000")); + bs4 = ~(bs3 ^ input3); REQUIRE(bs4 == emp::old::BitSet<8>("10100010")); - bs = ~bs4; REQUIRE(bs == emp::BitSet<8>("01011101")); + bs = ~bs4; REQUIRE(bs == emp::old::BitSet<8>("01011101")); // Test COMPOUND Boolean Logic operators. - bs = "11111111"; REQUIRE(bs == emp::BitSet<8>("11111111")); + bs = "11111111"; REQUIRE(bs == emp::old::BitSet<8>("11111111")); - bs &= input1; REQUIRE(bs == emp::BitSet<8>("00001111")); - bs &= input1; REQUIRE(bs == emp::BitSet<8>("00001111")); - bs &= input2; REQUIRE(bs == emp::BitSet<8>("00000011")); - bs &= input3; REQUIRE(bs == emp::BitSet<8>("00000001")); + bs &= input1; REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs &= input1; REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs &= input2; REQUIRE(bs == emp::old::BitSet<8>("00000011")); + bs &= input3; REQUIRE(bs == emp::old::BitSet<8>("00000001")); - bs |= input1; REQUIRE(bs == emp::BitSet<8>("00001111")); - bs |= input1; REQUIRE(bs == emp::BitSet<8>("00001111")); - bs |= input3; REQUIRE(bs == emp::BitSet<8>("01011111")); - bs |= input2; REQUIRE(bs == emp::BitSet<8>("01111111")); + bs |= input1; REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs |= input1; REQUIRE(bs == emp::old::BitSet<8>("00001111")); + bs |= input3; REQUIRE(bs == emp::old::BitSet<8>("01011111")); + bs |= input2; REQUIRE(bs == emp::old::BitSet<8>("01111111")); - bs ^= input1; REQUIRE(bs == emp::BitSet<8>("01110000")); - bs ^= input1; REQUIRE(bs == emp::BitSet<8>("01111111")); - bs ^= input2; REQUIRE(bs == emp::BitSet<8>("01001100")); - bs ^= input3; REQUIRE(bs == emp::BitSet<8>("00011001")); + bs ^= input1; REQUIRE(bs == emp::old::BitSet<8>("01110000")); + bs ^= input1; REQUIRE(bs == emp::old::BitSet<8>("01111111")); + bs ^= input2; REQUIRE(bs == emp::old::BitSet<8>("01001100")); + bs ^= input3; REQUIRE(bs == emp::old::BitSet<8>("00011001")); // Now some tests with BitSets longer than one field. - const emp::BitSet<80> bsl80 = + const emp::old::BitSet<80> bsl80 = "00110111000101110001011100010111000101110001011100010111000101110001011100010111"; REQUIRE( bsl80.GetSize() == 80 ); REQUIRE( bsl80.CountOnes() == 41 ); REQUIRE( (bsl80 >> 1) == - emp::BitSet<80>("00011011100010111000101110001011100010111000101110001011100010111000101110001011") + emp::old::BitSet<80>("00011011100010111000101110001011100010111000101110001011100010111000101110001011") ); REQUIRE( (bsl80 >> 2) == - emp::BitSet<80>("00001101110001011100010111000101110001011100010111000101110001011100010111000101") + emp::old::BitSet<80>("00001101110001011100010111000101110001011100010111000101110001011100010111000101") ); REQUIRE( (bsl80 >> 63) == - emp::BitSet<80>("00000000000000000000000000000000000000000000000000000000000000000110111000101110") + emp::old::BitSet<80>("00000000000000000000000000000000000000000000000000000000000000000110111000101110") ); REQUIRE( (bsl80 >> 64) == - emp::BitSet<80>("00000000000000000000000000000000000000000000000000000000000000000011011100010111") + emp::old::BitSet<80>("00000000000000000000000000000000000000000000000000000000000000000011011100010111") ); REQUIRE( (bsl80 >> 65) == - emp::BitSet<80>("00000000000000000000000000000000000000000000000000000000000000000001101110001011") + emp::old::BitSet<80>("00000000000000000000000000000000000000000000000000000000000000000001101110001011") ); REQUIRE( (bsl80 << 1) == - emp::BitSet<80>("01101110001011100010111000101110001011100010111000101110001011100010111000101110") + emp::old::BitSet<80>("01101110001011100010111000101110001011100010111000101110001011100010111000101110") ); REQUIRE( (bsl80 << 2) == - emp::BitSet<80>("11011100010111000101110001011100010111000101110001011100010111000101110001011100") + emp::old::BitSet<80>("11011100010111000101110001011100010111000101110001011100010111000101110001011100") ); REQUIRE( (bsl80 << 63) == - emp::BitSet<80>("10001011100010111000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitSet<80>("10001011100010111000000000000000000000000000000000000000000000000000000000000000") ); REQUIRE( (bsl80 << 64) == - emp::BitSet<80>("00010111000101110000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitSet<80>("00010111000101110000000000000000000000000000000000000000000000000000000000000000") ); REQUIRE( (bsl80 << 65) == - emp::BitSet<80>("00101110001011100000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitSet<80>("00101110001011100000000000000000000000000000000000000000000000000000000000000000") ); } @@ -859,7 +860,7 @@ TEST_CASE("9: Test Boolean logic and shifting functions.", "[bits]") { * as well as Clear and SetAll */ void test_status(){ - emp::BitSet<10> bs10; + emp::old::BitSet<10> bs10; REQUIRE(!bs10.any()); REQUIRE(bs10.none()); REQUIRE(!bs10.all()); @@ -873,13 +874,13 @@ void test_status(){ * GetSize */ void test_size(){ - emp::BitSet<42> bs42; + emp::old::BitSet<42> bs42; REQUIRE(bs42.size() == 42); - emp::BitSet<35> bs35; + emp::old::BitSet<35> bs35; REQUIRE(bs35.GetSize() == 35); - emp::BitSet<1> bs1; + emp::old::BitSet<1> bs1; REQUIRE(bs1.size() == 1); } @@ -887,11 +888,11 @@ void test_size(){ * Flip and Toggle */ void test_flip(){ - emp::BitSet<2> bs2; // bs2 = 00 + emp::old::BitSet<2> bs2; // bs2 = 00 bs2.flip(0); // bs2 = 01 REQUIRE(bs2[0]); - emp::BitSet<8> bs8; // bs8 = 00000000 + emp::old::BitSet<8> bs8; // bs8 = 00000000 bs8.flip(0,4); // bs8 = 00001111 REQUIRE(bs8[0]); REQUIRE(bs8[1]); @@ -902,7 +903,7 @@ void test_flip(){ bs8[0].Toggle(); // bs8 = 00001110 REQUIRE(!bs8[0]); - emp::BitSet<4> bs4; // bs4 = 0000 + emp::old::BitSet<4> bs4; // bs4 = 0000 bs4.flip(); // bs4 = 1111 REQUIRE(bs4.all()); } @@ -911,7 +912,7 @@ void test_flip(){ * FindOne and PopOne */ void test_find(){ - emp::BitSet<10> bs10; // bs10 = 00 00000000 + emp::old::BitSet<10> bs10; // bs10 = 00 00000000 bs10.flip(3); // bs10 = 00 00001000 REQUIRE(bs10.FindOne() == 3); bs10.PopOne(); // bs10 = 00 00000000 @@ -926,7 +927,7 @@ void test_find(){ * GetByte and SetByte */ void test_byte(){ - emp::BitSet<10> bs10; + emp::old::BitSet<10> bs10; bs10.SetByte(0, 10); REQUIRE(bs10.GetByte(0) == 10); @@ -942,7 +943,7 @@ void test_byte(){ // actual testing function template void do_byte_test() { - emp::BitSet bs; + emp::old::BitSet bs; for (size_t i = 0; i < Bits / 8; ++i) { bs.SetByte(i, 10 * i); @@ -972,12 +973,12 @@ void test_bytes() { * Left and Right shifts */ void test_shift(){ - emp::BitSet<40> bs40; + emp::old::BitSet<40> bs40; bs40.SetByte(0, 1); bs40 <<= 34; REQUIRE(bs40.GetByte(4) == 4); - emp::BitSet<10> bs10; + emp::old::BitSet<10> bs10; bs10.SetByte(0, 10); bs10 >>= 2; REQUIRE(bs10.GetByte(0) == 2); @@ -987,7 +988,7 @@ void test_shift(){ * Count ones */ void test_count(){ - emp::BitSet<12> bs12; + emp::old::BitSet<12> bs12; bs12.SetAll(); REQUIRE(bs12.count() == 12); REQUIRE(bs12.CountOnes_Sparse() == 12); @@ -999,7 +1000,7 @@ void test_count(){ * Get ones */ void test_get_ones(){ - emp::BitSet<5> bs5; + emp::old::BitSet<5> bs5; bs5.flip(2); // 00100 emp::vector ones = bs5.GetOnes(); REQUIRE(ones.size() == 1); @@ -1011,7 +1012,7 @@ void test_get_ones(){ * Get and Set bits */ void test_bit(){ - emp::BitSet<8> bs8; + emp::old::BitSet<8> bs8; bs8.Set(0, 1); // bs8 = 00000001 REQUIRE(bs8.Get(0)); @@ -1025,9 +1026,9 @@ void test_bit(){ * Bitwise XOR ^ */ void test_bitwise_xor(){ - emp::BitSet<4> bs4; + emp::old::BitSet<4> bs4; bs4.Set(0, 1); - emp::BitSet<4> bs4_1; + emp::old::BitSet<4> bs4_1; bs4_1.SetByte(0,3); bs4 ^= bs4_1; // bs4 = 0001 ^ 0011 = 0010 REQUIRE(bs4.GetByte(0) == 2); // 0010 = 2 @@ -1040,8 +1041,8 @@ void test_bitwise_xor(){ * Bitwise OR | */ void test_bitwise_or(){ - emp::BitSet<10> bs10; - emp::BitSet<10> bs10_1; + emp::old::BitSet<10> bs10; + emp::old::BitSet<10> bs10_1; bs10.Set(1,1); // bs10 = 00 0000 0010 bs10_1.Set(3,1); bs10_1.SetByte(1,3); @@ -1055,8 +1056,8 @@ void test_bitwise_or(){ * Bitwise AND & */ void test_bitwise_and(){ - emp::BitSet<8> bs8; - emp::BitSet<8> bs8_1; + emp::old::BitSet<8> bs8; + emp::old::BitSet<8> bs8_1; bs8.SetByte(0,13); // bs8 = 00001101 bs8_1.SetByte(0,10); // bs8_1 = 00001010 bs8_1 &= bs8; // bs8_1 = 00001010 & 00001101 = 00001000 @@ -1068,8 +1069,8 @@ void test_bitwise_and(){ */ void test_more_comparators(){ // NAND - emp::BitSet<8> bs8_1; - emp::BitSet<8> bs8_2; + emp::old::BitSet<8> bs8_1; + emp::old::BitSet<8> bs8_2; bs8_1.SetAll(); REQUIRE(bs8_1.NAND(bs8_2).All()); bs8_2.flip(1); @@ -1099,7 +1100,7 @@ void test_more_comparators(){ */ void test_random(){ emp::Random random(1); - emp::BitSet<8> bs8(random); + emp::old::BitSet<8> bs8(random); bs8.Randomize(random, 1.0); REQUIRE(bs8.all()); bs8.Randomize(random, 0.0); @@ -1110,11 +1111,11 @@ void test_random(){ * Copy */ void test_copy(){ - emp::BitSet<10> bs10; + emp::old::BitSet<10> bs10; bs10.SetAll(); bs10.flip(0,5); - emp::BitSet<10> bs10_1; + emp::old::BitSet<10> bs10_1; bs10_1 = bs10; REQUIRE(bs10 == bs10_1); } @@ -1123,8 +1124,8 @@ void test_copy(){ * Comparators (>=,>,==,!=,<,<=) */ void test_comparators(){ - emp::BitSet<10> bs10; - emp::BitSet<10> bs10_1; + emp::old::BitSet<10> bs10; + emp::old::BitSet<10> bs10_1; bs10_1.SetAll(); REQUIRE(bs10_1 != bs10); REQUIRE(bs10_1 > bs10); @@ -1141,10 +1142,10 @@ void test_comparators(){ * Export */ void test_export(){ - emp::BitSet<8> bs8; + emp::old::BitSet<8> bs8; bs8.SetAll(); REQUIRE(bs8.count() == 8); - emp::BitSet<10> bs10 = bs8.Export<10>(); + emp::old::BitSet<10> bs10 = bs8.Export<10>(); REQUIRE(bs10.size() == 10); REQUIRE(bs10.GetByte(0) == 255); REQUIRE(bs10.GetByte(1) == 0); @@ -1154,14 +1155,14 @@ void test_export(){ * Import */ void test_import(){ - emp::BitSet<8> bs8; - emp::BitSet<20> bs20; + emp::old::BitSet<8> bs8; + emp::old::BitSet<20> bs20; bs20[5] = 1; bs8.Import(bs20); REQUIRE(bs8[5]); - emp::BitSet<10> bs10; + emp::old::BitSet<10> bs10; bs10.SetAll(); bs20.Import(bs10); REQUIRE(bs20.count() == 10); @@ -1201,8 +1202,8 @@ struct ImportExportTester { emp::Random rand(1); // using default parameter - emp::BitSet source(rand); - emp::BitSet dest(rand); + emp::old::BitSet source(rand); + emp::old::BitSet dest(rand); dest.template Import(source); @@ -1268,7 +1269,7 @@ struct MultiTester2 { emp::Random rand(1); constexpr int W = N - 2; - emp::BitSet bs; + emp::old::BitSet bs; for (int j = 0; j < W; ++j) { bs.Clear(); bs.Set(j); @@ -1334,8 +1335,8 @@ struct MultiTester { constexpr int width = I; emp::Random rand(1); - emp::BitSet bs(rand); - const emp::BitSet bs_orig(bs); + emp::old::BitSet bs(rand); + const emp::old::BitSet bs_orig(bs); const size_t num_ones = bs.CountOnes(); for (int i = -width - 1; i <= width + 1; ++i) { @@ -1394,124 +1395,124 @@ TEST_CASE("Another Test BitSet", "[bits]") // test BitSet GetSize, GetNumBytes { - REQUIRE(emp::BitSet<2>{}.GetSize() == 2); - REQUIRE(emp::BitSet<2>{}.GetNumBytes() == 1); + REQUIRE(emp::old::BitSet<2>{}.GetSize() == 2); + REQUIRE(emp::old::BitSet<2>{}.GetNumBytes() == 1); - REQUIRE(emp::BitSet<7>{}.GetSize() == 7); - REQUIRE(emp::BitSet<7>{}.GetNumBytes() == 1); + REQUIRE(emp::old::BitSet<7>{}.GetSize() == 7); + REQUIRE(emp::old::BitSet<7>{}.GetNumBytes() == 1); - REQUIRE(emp::BitSet<8>{}.GetSize() == 8); - REQUIRE(emp::BitSet<8>{}.GetNumBytes() == 1); + REQUIRE(emp::old::BitSet<8>{}.GetSize() == 8); + REQUIRE(emp::old::BitSet<8>{}.GetNumBytes() == 1); - REQUIRE(emp::BitSet<9>{}.GetSize() == 9); - REQUIRE(emp::BitSet<9>{}.GetNumBytes() == 2); + REQUIRE(emp::old::BitSet<9>{}.GetSize() == 9); + REQUIRE(emp::old::BitSet<9>{}.GetNumBytes() == 2); - REQUIRE(emp::BitSet<16>{}.GetSize() == 16); - REQUIRE(emp::BitSet<16>{}.GetNumBytes() == 2); + REQUIRE(emp::old::BitSet<16>{}.GetSize() == 16); + REQUIRE(emp::old::BitSet<16>{}.GetNumBytes() == 2); - REQUIRE(emp::BitSet<24>{}.GetSize() == 24); - REQUIRE(emp::BitSet<24>{}.GetNumBytes() == 3); + REQUIRE(emp::old::BitSet<24>{}.GetSize() == 24); + REQUIRE(emp::old::BitSet<24>{}.GetNumBytes() == 3); } // test BitSet reverse { - REQUIRE(emp::BitSet<1>{0}.REVERSE_SELF() == emp::BitSet<1>{0}); - REQUIRE(emp::BitSet<1>{0}.REVERSE_SELF().CountOnes() == 0); - REQUIRE(emp::BitSet<1>{1}.REVERSE_SELF() == emp::BitSet<1>{1}); - REQUIRE(emp::BitSet<1>{1}.REVERSE_SELF().CountOnes() == 1); + REQUIRE(emp::old::BitSet<1>{0}.REVERSE_SELF() == emp::old::BitSet<1>{0}); + REQUIRE(emp::old::BitSet<1>{0}.REVERSE_SELF().CountOnes() == 0); + REQUIRE(emp::old::BitSet<1>{1}.REVERSE_SELF() == emp::old::BitSet<1>{1}); + REQUIRE(emp::old::BitSet<1>{1}.REVERSE_SELF().CountOnes() == 1); REQUIRE( - (emp::BitSet<2>{1,1}.REVERSE_SELF()) + (emp::old::BitSet<2>{1,1}.REVERSE_SELF()) == - (emp::BitSet<2>{1,1}) + (emp::old::BitSet<2>{1,1}) ); - REQUIRE((emp::BitSet<2>{1,1}.REVERSE_SELF().CountOnes()) == 2); + REQUIRE((emp::old::BitSet<2>{1,1}.REVERSE_SELF().CountOnes()) == 2); REQUIRE( - (emp::BitSet<2>{0,1}.REVERSE_SELF()) + (emp::old::BitSet<2>{0,1}.REVERSE_SELF()) == - (emp::BitSet<2>{1,0}) + (emp::old::BitSet<2>{1,0}) ); - REQUIRE((emp::BitSet<2>{0,1}.REVERSE_SELF().CountOnes()) == 1); + REQUIRE((emp::old::BitSet<2>{0,1}.REVERSE_SELF().CountOnes()) == 1); REQUIRE( - (emp::BitSet<2>{0,0}.REVERSE_SELF()) + (emp::old::BitSet<2>{0,0}.REVERSE_SELF()) == - (emp::BitSet<2>{0,0}) + (emp::old::BitSet<2>{0,0}) ); - REQUIRE((emp::BitSet<2>{0,0}.REVERSE_SELF().CountOnes()) == 0); + REQUIRE((emp::old::BitSet<2>{0,0}.REVERSE_SELF().CountOnes()) == 0); REQUIRE( - (emp::BitSet<7>{1,1,0,0,0,0,1}.REVERSE_SELF()) + (emp::old::BitSet<7>{1,1,0,0,0,0,1}.REVERSE_SELF()) == - (emp::BitSet<7>{1,0,0,0,0,1,1}) + (emp::old::BitSet<7>{1,0,0,0,0,1,1}) ); - REQUIRE((emp::BitSet<7>{1,1,0,0,0,0,1}.REVERSE_SELF().CountOnes()) == 3); + REQUIRE((emp::old::BitSet<7>{1,1,0,0,0,0,1}.REVERSE_SELF().CountOnes()) == 3); REQUIRE( - (emp::BitSet<7>{1,0,1,0,1,0,1}.REVERSE_SELF()) + (emp::old::BitSet<7>{1,0,1,0,1,0,1}.REVERSE_SELF()) == - (emp::BitSet<7>{1,0,1,0,1,0,1}) + (emp::old::BitSet<7>{1,0,1,0,1,0,1}) ); - REQUIRE((emp::BitSet<7>{1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); + REQUIRE((emp::old::BitSet<7>{1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); REQUIRE( - (emp::BitSet<7>{1,1,1,1,1,0,1}.REVERSE_SELF()) + (emp::old::BitSet<7>{1,1,1,1,1,0,1}.REVERSE_SELF()) == - (emp::BitSet<7>{1,0,1,1,1,1,1}) + (emp::old::BitSet<7>{1,0,1,1,1,1,1}) ); - REQUIRE((emp::BitSet<7>{1,1,1,1,1,0,1}.REVERSE_SELF().CountOnes()) == 6); + REQUIRE((emp::old::BitSet<7>{1,1,1,1,1,0,1}.REVERSE_SELF().CountOnes()) == 6); REQUIRE( - (emp::BitSet<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF()) + (emp::old::BitSet<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF()) == - (emp::BitSet<8>{0,1,0,0,0,0,1,1}) + (emp::old::BitSet<8>{0,1,0,0,0,0,1,1}) ); - REQUIRE((emp::BitSet<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF().CountOnes()) == 3); + REQUIRE((emp::old::BitSet<8>{1,1,0,0,0,0,1,0}.REVERSE_SELF().CountOnes()) == 3); REQUIRE( - (emp::BitSet<8>{1,0,1,0,1,0,1,0}.REVERSE_SELF()) + (emp::old::BitSet<8>{1,0,1,0,1,0,1,0}.REVERSE_SELF()) == - (emp::BitSet<8>{0,1,0,1,0,1,0,1}) + (emp::old::BitSet<8>{0,1,0,1,0,1,0,1}) ); - REQUIRE((emp::BitSet<8>{0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); + REQUIRE((emp::old::BitSet<8>{0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4); REQUIRE( - (emp::BitSet<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF()) + (emp::old::BitSet<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF()) == - (emp::BitSet<8>{0,1,0,1,1,1,1,1}) + (emp::old::BitSet<8>{0,1,0,1,1,1,1,1}) ); - REQUIRE((emp::BitSet<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF().CountOnes()) == 6); + REQUIRE((emp::old::BitSet<8>{1,1,1,1,1,0,1,0}.REVERSE_SELF().CountOnes()) == 6); REQUIRE( - (emp::BitSet<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF()) + (emp::old::BitSet<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF()) == - (emp::BitSet<9>{0,0,1,0,0,0,0,1,1}) + (emp::old::BitSet<9>{0,0,1,0,0,0,0,1,1}) ); REQUIRE( - (emp::BitSet<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF().CountOnes()) + (emp::old::BitSet<9>{1,1,0,0,0,0,1,0,0}.REVERSE_SELF().CountOnes()) == 3 ); REQUIRE( - (emp::BitSet<9>{1,0,1,0,1,0,1,0,0}.REVERSE_SELF()) + (emp::old::BitSet<9>{1,0,1,0,1,0,1,0,0}.REVERSE_SELF()) == - (emp::BitSet<9>{0,0,1,0,1,0,1,0,1}) + (emp::old::BitSet<9>{0,0,1,0,1,0,1,0,1}) ); REQUIRE( - (emp::BitSet<9>{0,0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) + (emp::old::BitSet<9>{0,0,1,0,1,0,1,0,1}.REVERSE_SELF().CountOnes()) == 4 ); REQUIRE( - (emp::BitSet<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF()) + (emp::old::BitSet<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF()) == - (emp::BitSet<9>{0,0,1,0,1,1,1,1,1}) + (emp::old::BitSet<9>{0,0,1,0,1,1,1,1,1}) ); REQUIRE( - (emp::BitSet<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF().CountOnes()) + (emp::old::BitSet<9>{1,1,1,1,1,0,1,0,0}.REVERSE_SELF().CountOnes()) == 6 ); emp::Random rand(1); for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<15> bs(rand); + emp::old::BitSet<15> bs(rand); bs[0] = 0; bs[15-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1520,7 +1521,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<16> bs(rand); + emp::old::BitSet<16> bs(rand); bs[0] = 0; bs[16-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1529,7 +1530,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<17> bs(rand); + emp::old::BitSet<17> bs(rand); bs[0] = 0; bs[17-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1538,7 +1539,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<31> bs(rand); + emp::old::BitSet<31> bs(rand); bs[0] = 0; bs[31-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1547,7 +1548,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<32> bs(rand); + emp::old::BitSet<32> bs(rand); bs[0] = 0; bs[32-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1556,7 +1557,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<33> bs(rand); + emp::old::BitSet<33> bs(rand); bs[0] = 0; bs[33-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1565,7 +1566,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<63> bs(rand); + emp::old::BitSet<63> bs(rand); bs[0] = 0; bs[63-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1574,7 +1575,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<64> bs(rand); + emp::old::BitSet<64> bs(rand); bs[0] = 0; bs[64-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1583,7 +1584,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<65> bs(rand); + emp::old::BitSet<65> bs(rand); bs[0] = 0; bs[65-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1592,7 +1593,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<127> bs(rand); + emp::old::BitSet<127> bs(rand); bs[0] = 0; bs[127-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1601,7 +1602,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<128> bs(rand); + emp::old::BitSet<128> bs(rand); bs[0] = 0; bs[128-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1610,7 +1611,7 @@ TEST_CASE("Another Test BitSet", "[bits]") } for (size_t rep = 0; rep < 100; ++rep) { - emp::BitSet<129> bs(rand); + emp::old::BitSet<129> bs(rand); bs[0] = 0; bs[129-1] = 1; REQUIRE(bs.REVERSE() != bs); @@ -1622,24 +1623,24 @@ TEST_CASE("Another Test BitSet", "[bits]") // test BitSet addition { - emp::BitSet<32> bs0; + emp::old::BitSet<32> bs0; bs0.SetUInt(0, std::numeric_limits::max() - 1); - emp::BitSet<32> bs1; + emp::old::BitSet<32> bs1; bs1.SetUInt(0,1); bs0+=bs1; REQUIRE (bs0.GetUInt(0) == 4294967295); REQUIRE ((bs0+bs1).GetUInt(0) == 0); REQUIRE ((bs0+bs0).GetUInt(0) == 4294967294); - emp::BitSet<8> bs2; + emp::old::BitSet<8> bs2; bs2.SetUInt(0, emp::IntPow(2UL, 8UL)-1); - emp::BitSet<8> bs3; + emp::old::BitSet<8> bs3; bs3.SetUInt(0, 1); REQUIRE((bs2+bs3).GetUInt(0) == 0); - emp::BitSet<64> bs4; + emp::old::BitSet<64> bs4; bs4.SetUInt(0, std::numeric_limits::max()-1); bs4.SetUInt(1, std::numeric_limits::max()); - emp::BitSet<64> bs5; + emp::old::BitSet<64> bs5; bs5.SetUInt(0, 1); bs4+=bs5; REQUIRE(bs4.GetUInt(0) == pow((size_t)2, (size_t)32)-1); @@ -1651,28 +1652,28 @@ TEST_CASE("Another Test BitSet", "[bits]") // test BitSet subtraction { - emp::BitSet<32> bs0; + emp::old::BitSet<32> bs0; bs0.SetUInt(0, 1); - emp::BitSet<32> bs1; + emp::old::BitSet<32> bs1; bs1.SetUInt(0, 1); bs0 = bs0 - bs1; REQUIRE (bs0.GetUInt(0) == 0); REQUIRE ((bs0-bs1).GetUInt(0) == std::numeric_limits::max()); - emp::BitSet<8> bs2; + emp::old::BitSet<8> bs2; bs2.SetUInt(0, 1); - emp::BitSet<8> bs3; + emp::old::BitSet<8> bs3; bs3.SetUInt(0, 1); bs2-=bs3; REQUIRE (bs2.GetUInt(0) == 0); REQUIRE((bs2-bs3).GetUInt(0) == emp::IntPow(2UL,8UL)-1); - emp::BitSet<64> bs4; + emp::old::BitSet<64> bs4; bs4.SetUInt(0, 1); bs4.SetUInt(1, 0); - emp::BitSet<64> bs5; + emp::old::BitSet<64> bs5; bs5.SetUInt(0, 1); bs4-=bs5; @@ -1689,8 +1690,8 @@ TEST_CASE("Another Test BitSet", "[bits]") // test addition and subtraction with multiple fields { - emp::BitSet<65> bs1; - emp::BitSet<65> bs2; + emp::old::BitSet<65> bs1; + emp::old::BitSet<65> bs2; /* PART 1 */ bs1.Clear(); @@ -1754,37 +1755,37 @@ TEST_CASE("Another Test BitSet", "[bits]") } { - emp::BitSet<3> bs0{0,0,0}; + emp::old::BitSet<3> bs0{0,0,0}; REQUIRE(bs0.GetUInt8(0) == 0); REQUIRE(bs0.GetUInt16(0) == 0); REQUIRE(bs0.GetUInt32(0) == 0); REQUIRE(bs0.GetUInt64(0) == 0); REQUIRE(bs0.GetNumStates() == 8); - emp::BitSet<3> bs1{0,0,1}; + emp::old::BitSet<3> bs1{0,0,1}; REQUIRE(bs1.GetUInt8(0) == 1); REQUIRE(bs1.GetUInt16(0) == 1); REQUIRE(bs1.GetUInt32(0) == 1); REQUIRE(bs1.GetUInt64(0) == 1); - emp::BitSet<3> bs2{0,1,1}; + emp::old::BitSet<3> bs2{0,1,1}; REQUIRE(bs2.GetUInt8(0) == 3); REQUIRE(bs2.GetUInt16(0) == 3); REQUIRE(bs2.GetUInt32(0) == 3); REQUIRE(bs2.GetUInt64(0) == 3); - emp::BitSet<3> bs3{1,1,1}; + emp::old::BitSet<3> bs3{1,1,1}; REQUIRE(bs3.GetUInt8(0) == 7); - emp::BitSet<3> bs4{1,1,0}; + emp::old::BitSet<3> bs4{1,1,0}; REQUIRE(bs4.GetUInt8(0) == 6); - emp::BitSet<32> bs5; + emp::old::BitSet<32> bs5; bs5.SetUInt(0, 1789156UL); REQUIRE(bs5.GetUInt64(0) == 1789156ULL); REQUIRE(bs5.GetNumStates() == 4294967296ULL); - emp::BitSet<63> bs6; + emp::old::BitSet<63> bs6; bs6.SetUInt64(0, 789156816848ULL); REQUIRE(bs6.GetUInt64(0) == 789156816848ULL); REQUIRE(bs6.GetNumStates() == 9223372036854775808ULL); @@ -1792,13 +1793,13 @@ TEST_CASE("Another Test BitSet", "[bits]") // @CAO: Removed GetDouble() due to confusing name (GetUInt64() gives the same answer, but with // the correct encoding. - // emp::BitSet<65> bs7; + // emp::old::BitSet<65> bs7; // bs7.SetUInt64(0, 1789156816848ULL); // bs7.Set(64); // REQUIRE(bs7.GetDouble() == 1789156816848.0 + emp::Pow2(64.0)); // REQUIRE(bs7.MaxDouble() == 36893488147419103231.0); - // emp::BitSet<1027> bs8; + // emp::old::BitSet<1027> bs8; // bs8.Set(1026); // REQUIRE(std::isinf(bs8.GetDouble())); // REQUIRE(std::isinf(bs8.MaxDouble())); @@ -1806,10 +1807,10 @@ TEST_CASE("Another Test BitSet", "[bits]") // test list initializer { - emp::BitSet<3> bs_empty{0,0,0}; - emp::BitSet<3> bs_first{1,0,0}; - emp::BitSet<3> bs_last{0,0,1}; - emp::BitSet<3> bs_full{1,1,1}; + emp::old::BitSet<3> bs_empty{0,0,0}; + emp::old::BitSet<3> bs_first{1,0,0}; + emp::old::BitSet<3> bs_last{0,0,1}; + emp::old::BitSet<3> bs_full{1,1,1}; REQUIRE(bs_empty.CountOnes() == 0); REQUIRE(bs_first.CountOnes() == 1); @@ -1822,14 +1823,14 @@ TEST_CASE("Another Test BitSet", "[bits]") emp::Random rand(1); - emp::BitSet<32> orig(rand); + emp::old::BitSet<32> orig(rand); - emp::array, 1> d1; - emp::array, 2> d2; - emp::array, 4> d4; - emp::array, 8> d8; - emp::array, 16> d16; - emp::array, 32> d32; + emp::array, 1> d1; + emp::array, 2> d2; + emp::array, 4> d4; + emp::array, 8> d8; + emp::array, 16> d16; + emp::array, 32> d32; // Import @@ -1983,19 +1984,19 @@ TEST_CASE("Another Test BitSet", "[bits]") } - emp::BitSet<10> bs10; - emp::BitSet<25> bs25; - emp::BitSet<32> bs32; - emp::BitSet<50> bs50; - emp::BitSet<64> bs64; - emp::BitSet<80> bs80; + emp::old::BitSet<10> bs10; + emp::old::BitSet<25> bs25; + emp::old::BitSet<32> bs32; + emp::old::BitSet<50> bs50; + emp::old::BitSet<64> bs64; + emp::old::BitSet<80> bs80; bs80[70] = 1; bs80 <<= 1; - emp::BitSet<80> bs80c(bs80); + emp::old::BitSet<80> bs80c(bs80); for (size_t i = 0; i < 75; i++) { - emp::BitSet<80> shift_set = bs80 >> i; + emp::old::BitSet<80> shift_set = bs80 >> i; REQUIRE((shift_set.CountOnes() == 1) == (i <= 71)); } @@ -2055,7 +2056,7 @@ TEST_CASE("Another Test BitSet", "[bits]") REQUIRE(bs80.GetUInt32AtBit(64) == 130); REQUIRE(bs80.GetUInt8AtBit(64) == 130); - emp::BitSet<96> bs; + emp::old::BitSet<96> bs; REQUIRE (bs.LongestSegmentOnes() == 0); bs.SetUInt(2, 1); @@ -2156,11 +2157,11 @@ TEST_CASE("Another Test BitSet", "[bits]") // tests for RandomizeFixed { emp::Random random(1); - emp::BitSet<25> bs_25; - emp::BitSet<32> bs_32; - emp::BitSet<50> bs_50; - emp::BitSet<64> bs_64; - emp::BitSet<80> bs_80; + emp::old::BitSet<25> bs_25; + emp::old::BitSet<32> bs_32; + emp::old::BitSet<50> bs_50; + emp::old::BitSet<64> bs_64; + emp::old::BitSet<80> bs_80; bs_25.FlipRandomCount(random, 0); REQUIRE(!bs_25.CountOnes()); @@ -2255,19 +2256,19 @@ TEST_CASE("Another Test BitSet", "[bits]") // set up emp::Random rand(1); - emp::BitSet<10> bs10(rand); - emp::BitSet<25> bs25(rand); - emp::BitSet<32> bs32(rand); - emp::BitSet<50> bs50(rand); - emp::BitSet<64> bs64(rand); - emp::BitSet<80> bs80(rand); - - emp::BitSet<10> bs10_deser; - emp::BitSet<25> bs25_deser; - emp::BitSet<32> bs32_deser; - emp::BitSet<50> bs50_deser; - emp::BitSet<64> bs64_deser; - emp::BitSet<80> bs80_deser; + emp::old::BitSet<10> bs10(rand); + emp::old::BitSet<25> bs25(rand); + emp::old::BitSet<32> bs32(rand); + emp::old::BitSet<50> bs50(rand); + emp::old::BitSet<64> bs64(rand); + emp::old::BitSet<80> bs80(rand); + + emp::old::BitSet<10> bs10_deser; + emp::old::BitSet<25> bs25_deser; + emp::old::BitSet<32> bs32_deser; + emp::old::BitSet<50> bs50_deser; + emp::old::BitSet<64> bs64_deser; + emp::old::BitSet<80> bs80_deser; std::stringstream ss; @@ -2315,19 +2316,19 @@ TEST_CASE("Another Test BitSet", "[bits]") // set up emp::Random rand(1); - emp::BitSet<10> bs10(rand); - emp::BitSet<25> bs25(rand); - emp::BitSet<32> bs32(rand); - emp::BitSet<50> bs50(rand); - emp::BitSet<64> bs64(rand); - emp::BitSet<80> bs80(rand); - - emp::BitSet<10> bs10_deser; - emp::BitSet<25> bs25_deser; - emp::BitSet<32> bs32_deser; - emp::BitSet<50> bs50_deser; - emp::BitSet<64> bs64_deser; - emp::BitSet<80> bs80_deser; + emp::old::BitSet<10> bs10(rand); + emp::old::BitSet<25> bs25(rand); + emp::old::BitSet<32> bs32(rand); + emp::old::BitSet<50> bs50(rand); + emp::old::BitSet<64> bs64(rand); + emp::old::BitSet<80> bs80(rand); + + emp::old::BitSet<10> bs10_deser; + emp::old::BitSet<25> bs25_deser; + emp::old::BitSet<32> bs32_deser; + emp::old::BitSet<50> bs50_deser; + emp::old::BitSet<64> bs64_deser; + emp::old::BitSet<80> bs80_deser; std::stringstream ss; @@ -2376,12 +2377,12 @@ TEST_CASE("Another Test BitSet", "[bits]") TEST_CASE("Test BitSet string construction", "[tools]") { - REQUIRE( emp::BitSet<5>( "01001" ) == emp::BitSet<5>{0, 1, 0, 0, 1} ); + REQUIRE( emp::old::BitSet<5>( "01001" ) == emp::old::BitSet<5>{0, 1, 0, 0, 1} ); - // std::bitset treats bits in the opposite direction of emp::BitSet. + // std::bitset treats bits in the opposite direction of emp::old::BitSet. REQUIRE( - emp::BitSet<5>( std::bitset<5>( "10010" ) ) - == emp::BitSet<5>{1, 0, 0, 1, 0} + emp::old::BitSet<5>( std::bitset<5>( "10010" ) ) + == emp::old::BitSet<5>{1, 0, 0, 1, 0} ); } diff --git a/tests/bits/BitVector.cpp b/tests/bits/BitVector.cpp index 03dc2eddef..b60085bdc6 100644 --- a/tests/bits/BitVector.cpp +++ b/tests/bits/BitVector.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-23 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BitVector.cpp + * @file */ #include @@ -19,19 +20,19 @@ TEST_CASE("1: Test BitVector Constructors", "[bits]"){ // Create a size 50 bit vector, default to all zeros. - emp::BitVector bv1(50); + emp::old::BitVector bv1(50); REQUIRE( bv1.GetSize() == 50 ); REQUIRE( bv1.CountOnes() == 0 ); REQUIRE( (~bv1).CountOnes() == 50 ); // Create a size 1000 BitVector, default to all ones. - emp::BitVector bv2(1000, true); + emp::old::BitVector bv2(1000, true); REQUIRE( bv2.GetSize() == 1000 ); REQUIRE( bv2.CountOnes() == 1000 ); // Try a range of BitVector sizes, from 0 to 200. for (size_t bv_size = 0; bv_size <= 200; bv_size++) { - emp::BitVector bv3(bv_size); + emp::old::BitVector bv3(bv_size); REQUIRE( bv3.GetSize() == bv_size ); REQUIRE( bv3.CountOnes() == 0 ); for (size_t i = 0; i < bv_size; i++) bv3[i] = true; @@ -39,62 +40,62 @@ TEST_CASE("1: Test BitVector Constructors", "[bits]"){ } // Build a relatively large BitVector. - emp::BitVector bv4(1000000); + emp::old::BitVector bv4(1000000); for (size_t i = 0; i < bv4.GetSize(); i += 100) bv4[i].Toggle(); REQUIRE( bv4.CountOnes() == 10000 ); // Try out the copy constructor. - emp::BitVector bv5(bv4); + emp::old::BitVector bv5(bv4); REQUIRE( bv5.GetSize() == 1000000 ); REQUIRE( bv5.CountOnes() == 10000 ); // And the move constructor. auto old_ptr = bv5.RawBytes(); // Grab a pointer to where bv5 currently has its bytes. - emp::BitVector bv6( std::move(bv5) ); // Move bv5 bytes into bv6. + emp::old::BitVector bv6( std::move(bv5) ); // Move bv5 bytes into bv6. REQUIRE( bv6.RawBytes() == old_ptr ); REQUIRE( bv5.RawBytes() == nullptr ); // Construct from std::bitset. std::bitset<6> bit_set; bit_set[1] = 1; bit_set[2] = 1; bit_set[4] = 1; - emp::BitVector bv7(bit_set); + emp::old::BitVector bv7(bit_set); REQUIRE( bv7.GetSize() == 6 ); REQUIRE( bv7.CountOnes() == 3 ); // Construct from string. std::string bit_string = "10011001010000011101"; - emp::BitVector bv8(bit_string); + emp::old::BitVector bv8(bit_string); REQUIRE( bv8.GetSize() == 20 ); REQUIRE( bv8.CountOnes() == 9 ); // Some random BitVectors emp::Random random(1); - emp::BitVector bv9(1000, random); // 50/50 chance for each bit. + emp::old::BitVector bv9(1000, random); // 50/50 chance for each bit. const size_t bv9_ones = bv9.CountOnes(); REQUIRE( bv9_ones >= 400 ); REQUIRE( bv9_ones <= 600 ); - emp::BitVector bv10(1000, random, 0.8); // 80% chance of ones. + emp::old::BitVector bv10(1000, random, 0.8); // 80% chance of ones. const size_t bv10_ones = bv10.CountOnes(); REQUIRE( bv10_ones >= 750 ); REQUIRE( bv10_ones <= 850 ); - emp::BitVector bv11(1000, random, 117); // Exactly 117 ones, randomly placed. + emp::old::BitVector bv11(1000, random, 117); // Exactly 117 ones, randomly placed. const size_t bv11_ones = bv11.CountOnes(); REQUIRE( bv11_ones == 117 ); - emp::BitVector bv12(bv11, 500); // Construct with just first half of bv11. + emp::old::BitVector bv12(bv11, 500); // Construct with just first half of bv11. const size_t bv12_ones = bv12.CountOnes(); REQUIRE( bv12_ones >= 20 ); REQUIRE( bv12_ones <= 90 ); - emp::BitVector bv13({1,0,0,0,1,1,1,0,0,0,1,1,1}); // Construct with initializer list. + emp::old::BitVector bv13({1,0,0,0,1,1,1,0,0,0,1,1,1}); // Construct with initializer list. REQUIRE( bv13.GetSize() == 13 ); REQUIRE( bv13.CountOnes() == 7 ); } TEST_CASE("2: Test BitVector Assignemnts", "[bits]"){ - emp::vector< emp::BitVector > v; + emp::vector< emp::old::BitVector > v; // Try all BitVector sizes from 0 to 128. // Lot's of move operators will trigger as vector grows. @@ -109,8 +110,8 @@ TEST_CASE("2: Test BitVector Assignemnts", "[bits]"){ v.emplace_back(1000000); // Copy each BitVector into bv2 and do some manipulations then copy back. - for (emp::BitVector & bv : v) { - emp::BitVector bv2 = bv; + for (emp::old::BitVector & bv : v) { + emp::old::BitVector bv2 = bv; for (size_t i = 1; i < bv2.GetSize(); i += 2) { bv2[i] = 1; } @@ -118,12 +119,12 @@ TEST_CASE("2: Test BitVector Assignemnts", "[bits]"){ } // Now make sure the we constructed bits correctly! - for (const emp::BitVector & bv : v) { + for (const emp::old::BitVector & bv : v) { REQUIRE( bv.CountOnes() == bv.GetSize()/2 ); } - emp::vector< emp::BitVector > v2; - v2.push_back( emp::BitVector({0,1,0,1,0,1}) ); + emp::vector< emp::old::BitVector > v2; + v2.push_back( emp::old::BitVector({0,1,0,1,0,1}) ); v2 = v; // Copy over all BitVectors. @@ -146,15 +147,15 @@ TEST_CASE("2: Test BitVector Assignemnts", "[bits]"){ TEST_CASE("3: Test Simple BitVector Accessors", "[bits]"){ - emp::BitVector bv0(0); - emp::BitVector bv1(1, true); - emp::BitVector bv8( "10001101" ); - emp::BitVector bv32( "10001101100011011000110110001101" ); - emp::BitVector bv64( "1000110110001101100000011000110000001101100000000000110110001101" ); - emp::BitVector bv75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); + emp::old::BitVector bv0(0); + emp::old::BitVector bv1(1, true); + emp::old::BitVector bv8( "10001101" ); + emp::old::BitVector bv32( "10001101100011011000110110001101" ); + emp::old::BitVector bv64( "1000110110001101100000011000110000001101100000000000110110001101" ); + emp::old::BitVector bv75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); emp::Random random(1); - emp::BitVector bv1k(1000, random, 0.75); + emp::old::BitVector bv1k(1000, random, 0.75); // Make sure all sizes are correct. REQUIRE( bv0.GetSize() == 0 ); @@ -244,7 +245,7 @@ TEST_CASE("3: Test Simple BitVector Accessors", "[bits]"){ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { // Make sure range-based accessors still work when there are no bits. - emp::BitVector bv0(0); + emp::old::BitVector bv0(0); bv0.SetRange(0,0); bv0.SetAll(); bv0.Clear(); @@ -254,7 +255,7 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { REQUIRE( bv0.GetSize() == 0 ); // Now try range-based accessors on a single bit. - emp::BitVector bv1(1, false); REQUIRE( bv1[0] == false ); REQUIRE( bv1.CountOnes() == 0 ); + emp::old::BitVector bv1(1, false); REQUIRE( bv1[0] == false ); REQUIRE( bv1.CountOnes() == 0 ); bv1.Set(0); REQUIRE( bv1[0] == true ); REQUIRE( bv1.CountOnes() == 1 ); bv1.Clear(0); REQUIRE( bv1[0] == false ); REQUIRE( bv1.CountOnes() == 0 ); bv1.Toggle(0); REQUIRE( bv1[0] == true ); REQUIRE( bv1.CountOnes() == 1 ); @@ -269,7 +270,7 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { bv1.SetRange(1,1); REQUIRE( bv1[0] == false ); REQUIRE( bv1.CountOnes() == 0 ); // Test when a full byte is used. - emp::BitVector bv8( "10001101" ); REQUIRE(bv8.GetValue() == 177.0); // 10110001 + emp::old::BitVector bv8( "10001101" ); REQUIRE(bv8.GetValue() == 177.0); // 10110001 bv8.Set(2); REQUIRE(bv8.GetValue() == 181.0); // 10110101 bv8.Set(0, 0); REQUIRE(bv8.GetValue() == 180.0); // 10110100 bv8.SetRange(1, 4); REQUIRE(bv8.GetValue() == 190.0); // 10111110 @@ -286,7 +287,7 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { // Test a full field. constexpr double ALL_64 = (double) ((uint64_t) -1); - emp::BitVector bv64( "11011000110110001101" ); REQUIRE(bv64.GetValue() == 727835.0); + emp::old::BitVector bv64( "11011000110110001101" ); REQUIRE(bv64.GetValue() == 727835.0); bv64.Resize(64); REQUIRE(bv64.GetValue() == 727835.0); // ...0 010110001101100011011 bv64.Set(6); REQUIRE(bv64.GetValue() == 727899.0); // ...0 010110001101101011011 bv64.Set(0, 0); REQUIRE(bv64.GetValue() == 727898.0); // ...0 010110001101101011010 @@ -302,11 +303,11 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { bv64.Toggle(0,64); REQUIRE(bv64.GetValue() == 491520.0); // ...0 001111000000000000000 - emp::BitVector bv75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); + emp::old::BitVector bv75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); // Test a full + partial field. constexpr double ALL_88 = ((double) ((uint64_t) -1)) * emp::Pow2(24); - emp::BitVector bv88( "11011000110110001101" ); REQUIRE(bv88.GetValue() == 727835.0); + emp::old::BitVector bv88( "11011000110110001101" ); REQUIRE(bv88.GetValue() == 727835.0); bv88.Resize(88); REQUIRE(bv88.GetValue() == 727835.0); // ...0 010110001101100011011 // Start with same tests as last time... @@ -335,7 +336,7 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { // A larger BitVector with lots of random tests. emp::Random random(1); - emp::BitVector bv1k(1000, random, 0.65); + emp::old::BitVector bv1k(1000, random, 0.65); size_t num_ones = bv1k.CountOnes(); REQUIRE(num_ones > 550); bv1k.Toggle(); REQUIRE(bv1k.CountOnes() == 1000 - num_ones); @@ -357,9 +358,9 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { } // Test Any(), All() and None() - emp::BitVector bv_empty("000000"); - emp::BitVector bv_mixed("010101"); - emp::BitVector bv_full ("111111"); + emp::old::BitVector bv_empty("000000"); + emp::old::BitVector bv_mixed("010101"); + emp::old::BitVector bv_full ("111111"); REQUIRE(bv_empty.Any() == false); REQUIRE(bv_mixed.Any() == true); @@ -376,7 +377,7 @@ TEST_CASE("4: Test BitVector Set*, Clear* and Toggle* Accessors", "[bits]") { TEST_CASE("5: Test Randomize() and variants", "[bits]") { emp::Random random(1); - emp::BitVector bv(1000); + emp::old::BitVector bv(1000); REQUIRE(bv.None() == true); @@ -498,7 +499,7 @@ TEST_CASE("6: Test getting and setting whole chunks of bits", "[bits]") { constexpr size_t num_bits = 145; constexpr size_t num_bytes = 19; - emp::BitVector bv(num_bits); + emp::old::BitVector bv(num_bits); REQUIRE(bv.GetSize() == num_bits); REQUIRE(bv.GetNumBytes() == num_bytes); @@ -567,7 +568,7 @@ TEST_CASE("6: Test getting and setting whole chunks of bits", "[bits]") { TEST_CASE("7: Test functions that analyze and manipulate ones", "[bits]") { - emp::BitVector bv = "0001000100001110"; + emp::old::BitVector bv = "0001000100001110"; REQUIRE(bv.GetSize() == 16); REQUIRE(bv.CountOnes() == 5); @@ -627,7 +628,7 @@ TEST_CASE("7: Test functions that analyze and manipulate ones", "[bits]") { } TEST_CASE("8: Test printing and string functions.", "[bits]") { - emp::BitVector bv6("000111"); + emp::old::BitVector bv6("000111"); REQUIRE(bv6.ToString() == "000111"); REQUIRE(bv6.ToBinaryString() == "111000"); @@ -635,7 +636,7 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { REQUIRE(bv6.ToIDString() == "3 4 5"); REQUIRE(bv6.ToRangeString() == "3-5"); - emp::BitVector bv64("0001110000000000000100000000000001000110000001000001000100000001"); + emp::old::BitVector bv64("0001110000000000000100000000000001000110000001000001000100000001"); REQUIRE(bv64.ToString() == "0001110000000000000100000000000001000110000001000001000100000001"); REQUIRE(bv64.ToBinaryString() == "1000000010001000001000000110001000000000000010000000000000111000"); @@ -643,7 +644,7 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { REQUIRE(bv64.ToIDString(",") == "3,4,5,19,33,37,38,45,51,55,63"); REQUIRE(bv64.ToRangeString() == "3-5,19,33,37-38,45,51,55,63"); - emp::BitVector bv65("00011110000000000001000000000000010001100000010000010001000000111"); + emp::old::BitVector bv65("00011110000000000001000000000000010001100000010000010001000000111"); REQUIRE(bv65.ToString() == "00011110000000000001000000000000010001100000010000010001000000111"); REQUIRE(bv65.ToBinaryString() == "11100000010001000001000000110001000000000000010000000000001111000"); @@ -653,188 +654,188 @@ TEST_CASE("8: Test printing and string functions.", "[bits]") { } TEST_CASE("9: Test Boolean logic and shifting functions.", "[bits]") { - const emp::BitVector input1 = "00001111"; - const emp::BitVector input2 = "00110011"; - const emp::BitVector input3 = "01010101"; + const emp::old::BitVector input1 = "00001111"; + const emp::old::BitVector input2 = "00110011"; + const emp::old::BitVector input3 = "01010101"; // Test *_SELF() Boolean Logic functions. - emp::BitVector bv(8); REQUIRE(bv == emp::BitVector("00000000")); - bv.NOT_SELF(); REQUIRE(bv == emp::BitVector("11111111")); - bv.AND_SELF(input1); REQUIRE(bv == emp::BitVector("00001111")); - bv.AND_SELF(input1); REQUIRE(bv == emp::BitVector("00001111")); - bv.AND_SELF(input2); REQUIRE(bv == emp::BitVector("00000011")); - bv.AND_SELF(input3); REQUIRE(bv == emp::BitVector("00000001")); - - bv.OR_SELF(input1); REQUIRE(bv == emp::BitVector("00001111")); - bv.OR_SELF(input1); REQUIRE(bv == emp::BitVector("00001111")); - bv.OR_SELF(input3); REQUIRE(bv == emp::BitVector("01011111")); - bv.OR_SELF(input2); REQUIRE(bv == emp::BitVector("01111111")); - - bv.NAND_SELF(input1); REQUIRE(bv == emp::BitVector("11110000")); - bv.NAND_SELF(input1); REQUIRE(bv == emp::BitVector("11111111")); - bv.NAND_SELF(input2); REQUIRE(bv == emp::BitVector("11001100")); - bv.NAND_SELF(input3); REQUIRE(bv == emp::BitVector("10111011")); - - bv.NOR_SELF(input1); REQUIRE(bv == emp::BitVector("01000000")); - bv.NOR_SELF(input1); REQUIRE(bv == emp::BitVector("10110000")); - bv.NOR_SELF(input2); REQUIRE(bv == emp::BitVector("01001100")); - bv.NOR_SELF(input3); REQUIRE(bv == emp::BitVector("10100010")); - - bv.XOR_SELF(input1); REQUIRE(bv == emp::BitVector("10101101")); - bv.XOR_SELF(input1); REQUIRE(bv == emp::BitVector("10100010")); - bv.XOR_SELF(input2); REQUIRE(bv == emp::BitVector("10010001")); - bv.XOR_SELF(input3); REQUIRE(bv == emp::BitVector("11000100")); - - bv.EQU_SELF(input1); REQUIRE(bv == emp::BitVector("00110100")); - bv.EQU_SELF(input1); REQUIRE(bv == emp::BitVector("11000100")); - bv.EQU_SELF(input2); REQUIRE(bv == emp::BitVector("00001000")); - bv.EQU_SELF(input3); REQUIRE(bv == emp::BitVector("10100010")); - - bv.NOT_SELF(); REQUIRE(bv == emp::BitVector("01011101")); + emp::old::BitVector bv(8); REQUIRE(bv == emp::old::BitVector("00000000")); + bv.NOT_SELF(); REQUIRE(bv == emp::old::BitVector("11111111")); + bv.AND_SELF(input1); REQUIRE(bv == emp::old::BitVector("00001111")); + bv.AND_SELF(input1); REQUIRE(bv == emp::old::BitVector("00001111")); + bv.AND_SELF(input2); REQUIRE(bv == emp::old::BitVector("00000011")); + bv.AND_SELF(input3); REQUIRE(bv == emp::old::BitVector("00000001")); + + bv.OR_SELF(input1); REQUIRE(bv == emp::old::BitVector("00001111")); + bv.OR_SELF(input1); REQUIRE(bv == emp::old::BitVector("00001111")); + bv.OR_SELF(input3); REQUIRE(bv == emp::old::BitVector("01011111")); + bv.OR_SELF(input2); REQUIRE(bv == emp::old::BitVector("01111111")); + + bv.NAND_SELF(input1); REQUIRE(bv == emp::old::BitVector("11110000")); + bv.NAND_SELF(input1); REQUIRE(bv == emp::old::BitVector("11111111")); + bv.NAND_SELF(input2); REQUIRE(bv == emp::old::BitVector("11001100")); + bv.NAND_SELF(input3); REQUIRE(bv == emp::old::BitVector("10111011")); + + bv.NOR_SELF(input1); REQUIRE(bv == emp::old::BitVector("01000000")); + bv.NOR_SELF(input1); REQUIRE(bv == emp::old::BitVector("10110000")); + bv.NOR_SELF(input2); REQUIRE(bv == emp::old::BitVector("01001100")); + bv.NOR_SELF(input3); REQUIRE(bv == emp::old::BitVector("10100010")); + + bv.XOR_SELF(input1); REQUIRE(bv == emp::old::BitVector("10101101")); + bv.XOR_SELF(input1); REQUIRE(bv == emp::old::BitVector("10100010")); + bv.XOR_SELF(input2); REQUIRE(bv == emp::old::BitVector("10010001")); + bv.XOR_SELF(input3); REQUIRE(bv == emp::old::BitVector("11000100")); + + bv.EQU_SELF(input1); REQUIRE(bv == emp::old::BitVector("00110100")); + bv.EQU_SELF(input1); REQUIRE(bv == emp::old::BitVector("11000100")); + bv.EQU_SELF(input2); REQUIRE(bv == emp::old::BitVector("00001000")); + bv.EQU_SELF(input3); REQUIRE(bv == emp::old::BitVector("10100010")); + + bv.NOT_SELF(); REQUIRE(bv == emp::old::BitVector("01011101")); // Test regular Boolean Logic functions. - bv.Clear(); REQUIRE(bv == emp::BitVector("00000000")); - emp::BitVector bv1 = bv.NOT(); REQUIRE(bv1 == emp::BitVector("11111111")); + bv.Clear(); REQUIRE(bv == emp::old::BitVector("00000000")); + emp::old::BitVector bv1 = bv.NOT(); REQUIRE(bv1 == emp::old::BitVector("11111111")); - bv1 = bv1.AND(input1); REQUIRE(bv1 == emp::BitVector("00001111")); - emp::BitVector bv2 = bv1.AND(input1); REQUIRE(bv2 == emp::BitVector("00001111")); - emp::BitVector bv3 = bv2.AND(input2); REQUIRE(bv3 == emp::BitVector("00000011")); - emp::BitVector bv4 = bv3.AND(input3); REQUIRE(bv4 == emp::BitVector("00000001")); + bv1 = bv1.AND(input1); REQUIRE(bv1 == emp::old::BitVector("00001111")); + emp::old::BitVector bv2 = bv1.AND(input1); REQUIRE(bv2 == emp::old::BitVector("00001111")); + emp::old::BitVector bv3 = bv2.AND(input2); REQUIRE(bv3 == emp::old::BitVector("00000011")); + emp::old::BitVector bv4 = bv3.AND(input3); REQUIRE(bv4 == emp::old::BitVector("00000001")); - bv1 = bv4.OR(input1); REQUIRE(bv1 == emp::BitVector("00001111")); - bv2 = bv1.OR(input1); REQUIRE(bv2 == emp::BitVector("00001111")); - bv3 = bv2.OR(input3); REQUIRE(bv3 == emp::BitVector("01011111")); - bv4 = bv3.OR(input2); REQUIRE(bv4 == emp::BitVector("01111111")); + bv1 = bv4.OR(input1); REQUIRE(bv1 == emp::old::BitVector("00001111")); + bv2 = bv1.OR(input1); REQUIRE(bv2 == emp::old::BitVector("00001111")); + bv3 = bv2.OR(input3); REQUIRE(bv3 == emp::old::BitVector("01011111")); + bv4 = bv3.OR(input2); REQUIRE(bv4 == emp::old::BitVector("01111111")); - bv1 = bv4.NAND(input1); REQUIRE(bv1 == emp::BitVector("11110000")); - bv2 = bv1.NAND(input1); REQUIRE(bv2 == emp::BitVector("11111111")); - bv3 = bv2.NAND(input2); REQUIRE(bv3 == emp::BitVector("11001100")); - bv4 = bv3.NAND(input3); REQUIRE(bv4 == emp::BitVector("10111011")); + bv1 = bv4.NAND(input1); REQUIRE(bv1 == emp::old::BitVector("11110000")); + bv2 = bv1.NAND(input1); REQUIRE(bv2 == emp::old::BitVector("11111111")); + bv3 = bv2.NAND(input2); REQUIRE(bv3 == emp::old::BitVector("11001100")); + bv4 = bv3.NAND(input3); REQUIRE(bv4 == emp::old::BitVector("10111011")); - bv1 = bv4.NOR(input1); REQUIRE(bv1 == emp::BitVector("01000000")); - bv2 = bv1.NOR(input1); REQUIRE(bv2 == emp::BitVector("10110000")); - bv3 = bv2.NOR(input2); REQUIRE(bv3 == emp::BitVector("01001100")); - bv4 = bv3.NOR(input3); REQUIRE(bv4 == emp::BitVector("10100010")); + bv1 = bv4.NOR(input1); REQUIRE(bv1 == emp::old::BitVector("01000000")); + bv2 = bv1.NOR(input1); REQUIRE(bv2 == emp::old::BitVector("10110000")); + bv3 = bv2.NOR(input2); REQUIRE(bv3 == emp::old::BitVector("01001100")); + bv4 = bv3.NOR(input3); REQUIRE(bv4 == emp::old::BitVector("10100010")); - bv1 = bv4.XOR(input1); REQUIRE(bv1 == emp::BitVector("10101101")); - bv2 = bv1.XOR(input1); REQUIRE(bv2 == emp::BitVector("10100010")); - bv3 = bv2.XOR(input2); REQUIRE(bv3 == emp::BitVector("10010001")); - bv4 = bv3.XOR(input3); REQUIRE(bv4 == emp::BitVector("11000100")); + bv1 = bv4.XOR(input1); REQUIRE(bv1 == emp::old::BitVector("10101101")); + bv2 = bv1.XOR(input1); REQUIRE(bv2 == emp::old::BitVector("10100010")); + bv3 = bv2.XOR(input2); REQUIRE(bv3 == emp::old::BitVector("10010001")); + bv4 = bv3.XOR(input3); REQUIRE(bv4 == emp::old::BitVector("11000100")); - bv1 = bv4.EQU(input1); REQUIRE(bv1 == emp::BitVector("00110100")); - bv2 = bv1.EQU(input1); REQUIRE(bv2 == emp::BitVector("11000100")); - bv3 = bv2.EQU(input2); REQUIRE(bv3 == emp::BitVector("00001000")); - bv4 = bv3.EQU(input3); REQUIRE(bv4 == emp::BitVector("10100010")); + bv1 = bv4.EQU(input1); REQUIRE(bv1 == emp::old::BitVector("00110100")); + bv2 = bv1.EQU(input1); REQUIRE(bv2 == emp::old::BitVector("11000100")); + bv3 = bv2.EQU(input2); REQUIRE(bv3 == emp::old::BitVector("00001000")); + bv4 = bv3.EQU(input3); REQUIRE(bv4 == emp::old::BitVector("10100010")); - bv = bv4.NOT(); REQUIRE(bv == emp::BitVector("01011101")); + bv = bv4.NOT(); REQUIRE(bv == emp::old::BitVector("01011101")); // Test Boolean Logic operators. - bv.Clear(); REQUIRE(bv == emp::BitVector("00000000")); - bv1 = ~bv; REQUIRE(bv1 == emp::BitVector("11111111")); + bv.Clear(); REQUIRE(bv == emp::old::BitVector("00000000")); + bv1 = ~bv; REQUIRE(bv1 == emp::old::BitVector("11111111")); - bv1 = bv1 & input1; REQUIRE(bv1 == emp::BitVector("00001111")); - bv2 = bv1 & input1; REQUIRE(bv2 == emp::BitVector("00001111")); - bv3 = bv2 & input2; REQUIRE(bv3 == emp::BitVector("00000011")); - bv4 = bv3 & input3; REQUIRE(bv4 == emp::BitVector("00000001")); + bv1 = bv1 & input1; REQUIRE(bv1 == emp::old::BitVector("00001111")); + bv2 = bv1 & input1; REQUIRE(bv2 == emp::old::BitVector("00001111")); + bv3 = bv2 & input2; REQUIRE(bv3 == emp::old::BitVector("00000011")); + bv4 = bv3 & input3; REQUIRE(bv4 == emp::old::BitVector("00000001")); - bv1 = bv4 | input1; REQUIRE(bv1 == emp::BitVector("00001111")); - bv2 = bv1 | input1; REQUIRE(bv2 == emp::BitVector("00001111")); - bv3 = bv2 | input3; REQUIRE(bv3 == emp::BitVector("01011111")); - bv4 = bv3 | input2; REQUIRE(bv4 == emp::BitVector("01111111")); + bv1 = bv4 | input1; REQUIRE(bv1 == emp::old::BitVector("00001111")); + bv2 = bv1 | input1; REQUIRE(bv2 == emp::old::BitVector("00001111")); + bv3 = bv2 | input3; REQUIRE(bv3 == emp::old::BitVector("01011111")); + bv4 = bv3 | input2; REQUIRE(bv4 == emp::old::BitVector("01111111")); - bv1 = ~(bv4 & input1); REQUIRE(bv1 == emp::BitVector("11110000")); - bv2 = ~(bv1 & input1); REQUIRE(bv2 == emp::BitVector("11111111")); - bv3 = ~(bv2 & input2); REQUIRE(bv3 == emp::BitVector("11001100")); - bv4 = ~(bv3 & input3); REQUIRE(bv4 == emp::BitVector("10111011")); + bv1 = ~(bv4 & input1); REQUIRE(bv1 == emp::old::BitVector("11110000")); + bv2 = ~(bv1 & input1); REQUIRE(bv2 == emp::old::BitVector("11111111")); + bv3 = ~(bv2 & input2); REQUIRE(bv3 == emp::old::BitVector("11001100")); + bv4 = ~(bv3 & input3); REQUIRE(bv4 == emp::old::BitVector("10111011")); - bv1 = ~(bv4 | input1); REQUIRE(bv1 == emp::BitVector("01000000")); - bv2 = ~(bv1 | input1); REQUIRE(bv2 == emp::BitVector("10110000")); - bv3 = ~(bv2 | input2); REQUIRE(bv3 == emp::BitVector("01001100")); - bv4 = ~(bv3 | input3); REQUIRE(bv4 == emp::BitVector("10100010")); + bv1 = ~(bv4 | input1); REQUIRE(bv1 == emp::old::BitVector("01000000")); + bv2 = ~(bv1 | input1); REQUIRE(bv2 == emp::old::BitVector("10110000")); + bv3 = ~(bv2 | input2); REQUIRE(bv3 == emp::old::BitVector("01001100")); + bv4 = ~(bv3 | input3); REQUIRE(bv4 == emp::old::BitVector("10100010")); - bv1 = bv4 ^ input1; REQUIRE(bv1 == emp::BitVector("10101101")); - bv2 = bv1 ^ input1; REQUIRE(bv2 == emp::BitVector("10100010")); - bv3 = bv2 ^ input2; REQUIRE(bv3 == emp::BitVector("10010001")); - bv4 = bv3 ^ input3; REQUIRE(bv4 == emp::BitVector("11000100")); + bv1 = bv4 ^ input1; REQUIRE(bv1 == emp::old::BitVector("10101101")); + bv2 = bv1 ^ input1; REQUIRE(bv2 == emp::old::BitVector("10100010")); + bv3 = bv2 ^ input2; REQUIRE(bv3 == emp::old::BitVector("10010001")); + bv4 = bv3 ^ input3; REQUIRE(bv4 == emp::old::BitVector("11000100")); - bv1 = ~(bv4 ^ input1); REQUIRE(bv1 == emp::BitVector("00110100")); - bv2 = ~(bv1 ^ input1); REQUIRE(bv2 == emp::BitVector("11000100")); - bv3 = ~(bv2 ^ input2); REQUIRE(bv3 == emp::BitVector("00001000")); - bv4 = ~(bv3 ^ input3); REQUIRE(bv4 == emp::BitVector("10100010")); + bv1 = ~(bv4 ^ input1); REQUIRE(bv1 == emp::old::BitVector("00110100")); + bv2 = ~(bv1 ^ input1); REQUIRE(bv2 == emp::old::BitVector("11000100")); + bv3 = ~(bv2 ^ input2); REQUIRE(bv3 == emp::old::BitVector("00001000")); + bv4 = ~(bv3 ^ input3); REQUIRE(bv4 == emp::old::BitVector("10100010")); - bv = ~bv4; REQUIRE(bv == emp::BitVector("01011101")); + bv = ~bv4; REQUIRE(bv == emp::old::BitVector("01011101")); // Test COMPOUND Boolean Logic operators. - bv = "11111111"; REQUIRE(bv == emp::BitVector("11111111")); + bv = "11111111"; REQUIRE(bv == emp::old::BitVector("11111111")); - bv &= input1; REQUIRE(bv == emp::BitVector("00001111")); - bv &= input1; REQUIRE(bv == emp::BitVector("00001111")); - bv &= input2; REQUIRE(bv == emp::BitVector("00000011")); - bv &= input3; REQUIRE(bv == emp::BitVector("00000001")); + bv &= input1; REQUIRE(bv == emp::old::BitVector("00001111")); + bv &= input1; REQUIRE(bv == emp::old::BitVector("00001111")); + bv &= input2; REQUIRE(bv == emp::old::BitVector("00000011")); + bv &= input3; REQUIRE(bv == emp::old::BitVector("00000001")); - bv |= input1; REQUIRE(bv == emp::BitVector("00001111")); - bv |= input1; REQUIRE(bv == emp::BitVector("00001111")); - bv |= input3; REQUIRE(bv == emp::BitVector("01011111")); - bv |= input2; REQUIRE(bv == emp::BitVector("01111111")); + bv |= input1; REQUIRE(bv == emp::old::BitVector("00001111")); + bv |= input1; REQUIRE(bv == emp::old::BitVector("00001111")); + bv |= input3; REQUIRE(bv == emp::old::BitVector("01011111")); + bv |= input2; REQUIRE(bv == emp::old::BitVector("01111111")); - bv ^= input1; REQUIRE(bv == emp::BitVector("01110000")); - bv ^= input1; REQUIRE(bv == emp::BitVector("01111111")); - bv ^= input2; REQUIRE(bv == emp::BitVector("01001100")); - bv ^= input3; REQUIRE(bv == emp::BitVector("00011001")); + bv ^= input1; REQUIRE(bv == emp::old::BitVector("01110000")); + bv ^= input1; REQUIRE(bv == emp::old::BitVector("01111111")); + bv ^= input2; REQUIRE(bv == emp::old::BitVector("01001100")); + bv ^= input3; REQUIRE(bv == emp::old::BitVector("00011001")); // Shifting tests. - REQUIRE( (bv << 1) == emp::BitVector("00001100")); - REQUIRE( (bv << 2) == emp::BitVector("00000110")); - REQUIRE( (bv << 3) == emp::BitVector("00000011")); - REQUIRE( (bv << 4) == emp::BitVector("00000001")); + REQUIRE( (bv << 1) == emp::old::BitVector("00001100")); + REQUIRE( (bv << 2) == emp::old::BitVector("00000110")); + REQUIRE( (bv << 3) == emp::old::BitVector("00000011")); + REQUIRE( (bv << 4) == emp::old::BitVector("00000001")); - REQUIRE( (bv >> 1) == emp::BitVector("00110010")); - REQUIRE( (bv >> 2) == emp::BitVector("01100100")); - REQUIRE( (bv >> 3) == emp::BitVector("11001000")); - REQUIRE( (bv >> 4) == emp::BitVector("10010000")); + REQUIRE( (bv >> 1) == emp::old::BitVector("00110010")); + REQUIRE( (bv >> 2) == emp::old::BitVector("01100100")); + REQUIRE( (bv >> 3) == emp::old::BitVector("11001000")); + REQUIRE( (bv >> 4) == emp::old::BitVector("10010000")); // Now some tests with bitvectors longer than one field. - const emp::BitVector bvl80 = + const emp::old::BitVector bvl80 = "00110111000101110001011100010111000101110001011100010111000101110001011100010111"; REQUIRE( bvl80.GetSize() == 80 ); REQUIRE( bvl80.CountOnes() == 41 ); REQUIRE( bvl80 << 1 == - emp::BitVector("00011011100010111000101110001011100010111000101110001011100010111000101110001011") + emp::old::BitVector("00011011100010111000101110001011100010111000101110001011100010111000101110001011") ); REQUIRE( bvl80 << 2 == - emp::BitVector("00001101110001011100010111000101110001011100010111000101110001011100010111000101") + emp::old::BitVector("00001101110001011100010111000101110001011100010111000101110001011100010111000101") ); REQUIRE( bvl80 << 63 == - emp::BitVector("00000000000000000000000000000000000000000000000000000000000000000110111000101110") + emp::old::BitVector("00000000000000000000000000000000000000000000000000000000000000000110111000101110") ); REQUIRE( bvl80 << 64 == - emp::BitVector("00000000000000000000000000000000000000000000000000000000000000000011011100010111") + emp::old::BitVector("00000000000000000000000000000000000000000000000000000000000000000011011100010111") ); REQUIRE( bvl80 << 65 == - emp::BitVector("00000000000000000000000000000000000000000000000000000000000000000001101110001011") + emp::old::BitVector("00000000000000000000000000000000000000000000000000000000000000000001101110001011") ); REQUIRE( bvl80 >> 1 == - emp::BitVector("01101110001011100010111000101110001011100010111000101110001011100010111000101110") + emp::old::BitVector("01101110001011100010111000101110001011100010111000101110001011100010111000101110") ); REQUIRE( bvl80 >> 2 == - emp::BitVector("11011100010111000101110001011100010111000101110001011100010111000101110001011100") + emp::old::BitVector("11011100010111000101110001011100010111000101110001011100010111000101110001011100") ); REQUIRE( bvl80 >> 63 == - emp::BitVector("10001011100010111000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitVector("10001011100010111000000000000000000000000000000000000000000000000000000000000000") ); REQUIRE( bvl80 >> 64 == - emp::BitVector("00010111000101110000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitVector("00010111000101110000000000000000000000000000000000000000000000000000000000000000") ); REQUIRE( bvl80 >> 65 == - emp::BitVector("00101110001011100000000000000000000000000000000000000000000000000000000000000000") + emp::old::BitVector("00101110001011100000000000000000000000000000000000000000000000000000000000000000") ); } TEST_CASE("10: Test functions that trigger size changes", "[bits]") { - emp::BitVector bv(10); + emp::old::BitVector bv(10); REQUIRE(bv.GetSize() == 10); REQUIRE(bv.CountOnes() == 0); REQUIRE(bv.CountZeros() == 10); @@ -900,7 +901,7 @@ TEST_CASE("Test BitVector", "[bits]") { // Constructor - emp::BitVector bv(10); + emp::old::BitVector bv(10); // Get Size REQUIRE( (bv.GetSize() == 10) ); @@ -913,12 +914,12 @@ TEST_CASE("Test BitVector", "[bits]") REQUIRE(!bv.Get(1)); // Assignment operator - emp::BitVector bv1(10); + emp::old::BitVector bv1(10); bv1 = bv; REQUIRE(bv1 == bv); REQUIRE(bv1.Get(0)); - emp::BitVector bv20(20); - emp::BitVector bv30(30); + emp::old::BitVector bv20(20); + emp::old::BitVector bv30(30); bv20.Set(1); REQUIRE(bv20.Get(1)); bv20 = bv; @@ -949,7 +950,7 @@ TEST_CASE("Test BitVector", "[bits]") REQUIRE((bv >= bv1)); // Set & Get Byte - emp::BitVector bv2(32); + emp::old::BitVector bv2(32); bv2.SetByte(0, 128); bv2.SetByte(1, 255); REQUIRE((bv2.GetByte(0) == 128)); @@ -975,7 +976,7 @@ TEST_CASE("Test BitVector", "[bits]") // Prints std::stringstream ss; - emp::BitVector bv3(8); + emp::old::BitVector bv3(8); bv3.SetByte(0,255); bv3.Print(ss); REQUIRE((ss.str() == "11111111")); @@ -1016,7 +1017,7 @@ TEST_CASE("Test BitVector", "[bits]") REQUIRE((ones[1] == 3)); // Larger BitVector - emp::BitVector bv4(96); + emp::old::BitVector bv4(96); bv4.SetByte(1,1); bv4.PrintFields(ss); REQUIRE(ss.str() == "00000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000100000000"); @@ -1066,7 +1067,7 @@ TEST_CASE("Test BitVector", "[bits]") // Logic operators - emp::BitVector bv5(8); + emp::old::BitVector bv5(8); bv5.SetByte(0,28); REQUIRE((bv3.CountOnes() == 8-((~bv3).CountOnes()))); REQUIRE(((bv3 & bv5).GetByte(0) == 8)); @@ -1088,9 +1089,9 @@ TEST_CASE("Test BitVector", "[bits]") REQUIRE((bv3.GetByte(0) == 32)); // Hash - emp::BitVector bv_a(2); + emp::old::BitVector bv_a(2); bv_a.Set(0); - emp::BitVector bv_b(2); + emp::old::BitVector bv_b(2); bv_b.Set(0); REQUIRE(bv_a.Hash() == bv_b.Hash()); bv_b.Set(0, false); @@ -1121,9 +1122,9 @@ TEST_CASE("Test BitVector", "[bits]") REQUIRE(bv_a.NOT_SELF().all()); // EQU - emp::BitVector bv_c(3); + emp::old::BitVector bv_c(3); bv_c.SetByte(0,2); - emp::BitVector bv_d(3); + emp::old::BitVector bv_d(3); bv_d.SetByte(0,2); REQUIRE(bv_c.EQU(bv_d).all()); REQUIRE(bv_c.GetByte(0) == 2); @@ -1178,12 +1179,12 @@ TEST_CASE("Test BitVector", "[bits]") REQUIRE(bv_c[0] == 0); // GetUInt SetUInt - emp::BitVector bv_e(5); + emp::old::BitVector bv_e(5); bv_e.SetUInt(0, 16); REQUIRE(bv_e.GetUInt(0) == 16); // Shift Left - emp::BitVector bv_f(128); + emp::old::BitVector bv_f(128); bv_f.SetAll(); REQUIRE(bv_f.all()); bv_f <<= 127; @@ -1204,7 +1205,7 @@ TEST_CASE("Test MaskHigh, MaskLow", "[bits]") { // #endif // Test MaskHigh, MaskLow - emp::BitVector a(0); + emp::old::BitVector a(0); a.Insert(0,true, 7); REQUIRE(a.Get(0)); REQUIRE(a.Get(1)); @@ -1223,7 +1224,7 @@ TEST_CASE("Test PopBack, PushBack, Insert, Delete", "[bits]") { // #endif // Pop Back and Push Back - emp::BitVector bv_g(0); // Empty BitVector + emp::old::BitVector bv_g(0); // Empty BitVector bv_g.PushBack(true); // 1 bv_g.PushBack(true); // 11 bv_g.PushBack(false); // 110 @@ -1271,19 +1272,19 @@ TEST_CASE("Another Test BitVector", "[bits]") { // REQUIRE(emp::assert_last_fail == 0); // #endif - emp::BitVector bv10(10); - emp::BitVector bv32(32); - emp::BitVector bv50(50); - emp::BitVector bv64(64); - emp::BitVector bv80(80); + emp::old::BitVector bv10(10); + emp::old::BitVector bv32(32); + emp::old::BitVector bv50(50); + emp::old::BitVector bv64(64); + emp::old::BitVector bv80(80); bv80[70] = 1; - emp::BitVector bv80c(bv80); + emp::old::BitVector bv80c(bv80); bv80 <<= 1; for (size_t i = 0; i < 75; i += 2) { - emp::BitVector shift_vector = bv80 >> i; + emp::old::BitVector shift_vector = bv80 >> i; REQUIRE((shift_vector.CountOnes() == 1) == (i <= 71)); } @@ -1304,11 +1305,11 @@ TEST_CASE("Another Test BitVector", "[bits]") { TEST_CASE("Test range of BitVector constructors.", "[bits]") // test list initializer { - emp::BitVector bs_empty{0,0,0}; - emp::BitVector bs_first{1,0,0}; - emp::BitVector bs_last{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; - emp::BitVector bs_two{0,0,1,0,0,0,0,0,0,0,1,0,0}; - emp::BitVector bs_full{1,1,1,1,1,1,1,1}; + emp::old::BitVector bs_empty{0,0,0}; + emp::old::BitVector bs_first{1,0,0}; + emp::old::BitVector bs_last{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}; + emp::old::BitVector bs_two{0,0,1,0,0,0,0,0,0,0,1,0,0}; + emp::old::BitVector bs_full{1,1,1,1,1,1,1,1}; REQUIRE(bs_empty.CountOnes() == 0); REQUIRE(bs_first.CountOnes() == 1); @@ -1330,7 +1331,7 @@ TEST_CASE("Test range of BitVector constructors.", "[bits]") // for (size_t i = 1; i < 32; ++i) { -// emp::BitVector vec(i); +// emp::old::BitVector vec(i); // REQUIRE(emp::assert_last_fail == 0); // vec.SetUInt(0, std::numeric_limits::max()); // REQUIRE(emp::assert_last_fail); @@ -1340,7 +1341,7 @@ TEST_CASE("Test range of BitVector constructors.", "[bits]") // REQUIRE(emp::assert_last_fail == 0); -// emp::BitVector vec(32); +// emp::old::BitVector vec(32); // vec.SetUInt(0, std::numeric_limits::max()); // REQUIRE(emp::assert_last_fail == 0); @@ -1353,8 +1354,8 @@ TEST_CASE("BitVector regression test for #277", "[bits]") { // REQUIRE(emp::assert_last_fail == 0); // #endif - emp::BitVector vec1(4); - emp::BitVector vec2(4); + emp::old::BitVector vec1(4); + emp::old::BitVector vec2(4); for (size_t i = 0; i < 4; ++i) REQUIRE(!vec1[i]); for (size_t i = 0; i < 4; ++i) REQUIRE(!vec2[i]); diff --git a/tests/bits/Bits.cpp b/tests/bits/Bits.cpp index 2c10d4ed77..b07df1c140 100644 --- a/tests/bits/Bits.cpp +++ b/tests/bits/Bits.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file Bits.cpp + * @file */ #include @@ -1576,7 +1577,7 @@ TEST_CASE("17: Test BitArray Constructors", "[bits]"){ REQUIRE( ba8.CountOnes() == 9 ); // Some random BitArrays - emp::Random random; + emp::Random random(1); emp::BitArray<1000> ba9(random); // 50/50 chance for each bit. const size_t ba9_ones = ba9.CountOnes(); REQUIRE( ba9_ones >= 400 ); @@ -1660,7 +1661,7 @@ TEST_CASE("19: Test Simple BitArray Accessors", "[bits]"){ emp::BitArray<64> ba64( "1000110110001101100000011000110000001101100000000000110110001101" ); emp::BitArray<75> ba75( "010001011100010111110000011110100011111000001110100000111110010011111000011" ); - emp::Random random; + emp::Random random(1); emp::BitArray<1000> ba1k(random, 0.75); // Make sure all sizes are correct. @@ -1826,7 +1827,7 @@ TEST_CASE("20: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { ba88.SetRange(64,66); REQUIRE(ba88.CountOnes() == 6); // Set two more 1s, just into 2nd field. // A larger BitArray with lots of random tests. - emp::Random random; + emp::Random random(1); emp::BitArray<40> ba40(random, 0.65); size_t num_ones = ba40.CountOnes(); REQUIRE(num_ones >= 14); REQUIRE(num_ones < 39); @@ -1873,7 +1874,7 @@ TEST_CASE("20: Test BitArray Set*, Clear* and Toggle* Accessors", "[bits]") { TEST_CASE("21: Test Randomize() and variants", "[bits]") { - emp::Random random; + emp::Random random(1); emp::BitArray<1000> ba; REQUIRE(ba.None() == true); @@ -2117,7 +2118,7 @@ TEST_CASE("23: Test functions that analyze and manipulate ones", "[bits]") { REQUIRE(ba.LongestSegmentOnes() == 7); // Try again with Find, this time with a random sequence of ones. - emp::Random random; + emp::Random random(1); ba.Randomize(random); size_t count = 0; for (int i = ba.FindOne(); i != -1; i = ba.FindOne(i+1)) count++; @@ -2438,7 +2439,7 @@ void do_byte_test() { // unpack the integer sequence of bits to test // and then call the actual testing function with each as a template arg template -void do_byte_tests(const std::integer_sequence& sequence) { +void do_byte_tests(const std::integer_sequence& /* sequence */) { ((do_byte_test()),...); } // function that holds what number of bits to test, and then calls @@ -2579,7 +2580,7 @@ void test_more_comparators(){ * Random bitset */ void test_random(){ - emp::Random random; + emp::Random random(1); emp::BitArray<8> ba8(random); ba8.Randomize(random, 1.0); REQUIRE(ba8.all()); diff --git a/tests/bits/Makefile b/tests/bits/Makefile index db92f92058..c166dca83a 100644 --- a/tests/bits/Makefile +++ b/tests/bits/Makefile @@ -1,4 +1,4 @@ -TEST_NAMES = Bits BitArray BitSet BitMatrix bitset_utils BitVector +TEST_NAMES = Bits BitMatrix bitset_utils # BitArray BitVector BitSet # -O3 -Wl,--stack,8388608 -ftrack-macro-expansion=0 FLAGS = -std=c++20 -g -pthread -Wall -Wno-unused-function -Wno-unused-private-field -I../../include/ -I../../ -I../../third-party/cereal/include/ -DCATCH_CONFIG_MAIN diff --git a/tests/bits/bitset_utils.cpp b/tests/bits/bitset_utils.cpp index c04b000734..8b2e4f6a26 100644 --- a/tests/bits/bitset_utils.cpp +++ b/tests/bits/bitset_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file bitset_utils.cpp + * @file */ #include diff --git a/tests/compiler/DFA.cpp b/tests/compiler/DFA.cpp index 0c3f3607f4..77f5a4d04a 100644 --- a/tests/compiler/DFA.cpp +++ b/tests/compiler/DFA.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DFA.cpp + * @file */ #include diff --git a/tests/compiler/Lexer.cpp b/tests/compiler/Lexer.cpp index c14da58979..6500374a8a 100644 --- a/tests/compiler/Lexer.cpp +++ b/tests/compiler/Lexer.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Lexer.cpp + * @file */ #include diff --git a/tests/compiler/NFA.cpp b/tests/compiler/NFA.cpp index d673797787..f9cf4c0077 100644 --- a/tests/compiler/NFA.cpp +++ b/tests/compiler/NFA.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file NFA.cpp + * @file */ #include diff --git a/tests/compiler/RegEx.cpp b/tests/compiler/RegEx.cpp index 74b5752a50..ec940cea0e 100644 --- a/tests/compiler/RegEx.cpp +++ b/tests/compiler/RegEx.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file RegEx.cpp + * @file */ #include diff --git a/tests/compiler/lexer_utils.cpp b/tests/compiler/lexer_utils.cpp index f16eb83ef2..3dc98ce6ed 100644 --- a/tests/compiler/lexer_utils.cpp +++ b/tests/compiler/lexer_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file lexer_utils.cpp + * @file */ #include diff --git a/tests/config/ArgManager.cpp b/tests/config/ArgManager.cpp index de14f922c0..27e75750cf 100644 --- a/tests/config/ArgManager.cpp +++ b/tests/config/ArgManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file ArgManager.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/config/ConfigManager.cpp b/tests/config/ConfigManager.cpp index dd27d1f8d9..9ed2922cc4 100644 --- a/tests/config/ConfigManager.cpp +++ b/tests/config/ConfigManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ConfigManager.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/config/SettingCombos.cpp b/tests/config/SettingCombos.cpp index 165fb79128..66b004320f 100644 --- a/tests/config/SettingCombos.cpp +++ b/tests/config/SettingCombos.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SettingCombos.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/config/SettingConfig.cpp b/tests/config/SettingConfig.cpp index 679f641bba..85e4c15026 100644 --- a/tests/config/SettingConfig.cpp +++ b/tests/config/SettingConfig.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SettingConfig.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/config/assets/config_setup.hpp b/tests/config/assets/config_setup.hpp index 84075af730..4c4380972d 100644 --- a/tests/config/assets/config_setup.hpp +++ b/tests/config/assets/config_setup.hpp @@ -1,11 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016 - * - * @file config_setup.hpp - * @brief This file provides an example of how to build a configuration class. - * + * @file + * @brief TODO. * To create a new config from scratch, the format is: * EMP_BUILD_CONFIG( CLASS_NAME, OPTIONS... ) * diff --git a/tests/config/command_line.cpp b/tests/config/command_line.cpp index 8b36e42ff5..df5fae03e0 100644 --- a/tests/config/command_line.cpp +++ b/tests/config/command_line.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file command_line.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/config/config.cpp b/tests/config/config.cpp index d0be0bc547..d6bd9949ce 100644 --- a/tests/config/config.cpp +++ b/tests/config/config.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015 - * - * @file config.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/config/config_utils.cpp b/tests/config/config_utils.cpp index f4a65d6e40..159be8049b 100644 --- a/tests/config/config_utils.cpp +++ b/tests/config/config_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file config_utils.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/control/Action.cpp b/tests/control/Action.cpp index 63ca00b990..259a3d771c 100644 --- a/tests/control/Action.cpp +++ b/tests/control/Action.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Action.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/control/ActionManager.cpp b/tests/control/ActionManager.cpp index c309caf2bc..c231bd5ee7 100644 --- a/tests/control/ActionManager.cpp +++ b/tests/control/ActionManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ActionManager.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/control/Signal.cpp b/tests/control/Signal.cpp index 76b9383c4e..673714580b 100644 --- a/tests/control/Signal.cpp +++ b/tests/control/Signal.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Signal.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/control/SignalControl.cpp b/tests/control/SignalControl.cpp index 0a2f554edd..3b9016c06c 100644 --- a/tests/control/SignalControl.cpp +++ b/tests/control/SignalControl.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SignalControl.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/control/SignalManager.cpp b/tests/control/SignalManager.cpp index c28f1b52ed..972692272a 100644 --- a/tests/control/SignalManager.cpp +++ b/tests/control/SignalManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SignalManager.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/data/DataFile.cpp b/tests/data/DataFile.cpp index d7a00ac796..c4b2051be7 100644 --- a/tests/data/DataFile.cpp +++ b/tests/data/DataFile.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2022 - * - * @file DataFile.cpp + * @file */ #define CATCH_CONFIG_MAIN diff --git a/tests/data/DataInterface.cpp b/tests/data/DataInterface.cpp index 19f834d9bb..80fe8cf956 100644 --- a/tests/data/DataInterface.cpp +++ b/tests/data/DataInterface.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DataInterface.cpp + * @file */ #ifndef EMP_TRACK_MEM diff --git a/tests/data/DataLayout.cpp b/tests/data/DataLayout.cpp index 4e6266be2e..ca28d1906d 100644 --- a/tests/data/DataLayout.cpp +++ b/tests/data/DataLayout.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DataLayout.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/data/DataLog.cpp b/tests/data/DataLog.cpp index e0636ad4ac..18f87c5e80 100644 --- a/tests/data/DataLog.cpp +++ b/tests/data/DataLog.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DataLog.cpp + * @file */ #ifndef EMP_TRACK_MEM diff --git a/tests/data/DataManager.cpp b/tests/data/DataManager.cpp index b2fffcc650..fc968c4d3a 100644 --- a/tests/data/DataManager.cpp +++ b/tests/data/DataManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DataManager.cpp + * @file */ #ifndef EMP_TRACK_MEM diff --git a/tests/data/DataMap.cpp b/tests/data/DataMap.cpp index 2edccb1883..af38d64ad5 100644 --- a/tests/data/DataMap.cpp +++ b/tests/data/DataMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DataMap.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/data/DataNode.cpp b/tests/data/DataNode.cpp index 56191ef5e5..1f83b36a9a 100644 --- a/tests/data/DataNode.cpp +++ b/tests/data/DataNode.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DataNode.cpp + * @file */ #ifndef EMP_TRACK_MEM diff --git a/tests/data/Datum.cpp b/tests/data/Datum.cpp index dd2d710a29..c7825b08af 100644 --- a/tests/data/Datum.cpp +++ b/tests/data/Datum.cpp @@ -1,12 +1,15 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file Datum.cpp + * @file */ +#ifndef CATCH_CONFIG_MAIN #define CATCH_CONFIG_MAIN +#endif #ifndef EMP_TRACK_MEM #define EMP_TRACK_MEM @@ -123,3 +126,59 @@ TEST_CASE("Test Datum", "[data]") CHECK(y == "123"); } + +TEST_CASE("Test Datum Math", "[data]") +{ + emp::Datum d2(2.0); + emp::Datum d3(3.0); + emp::Datum ds("Num:"); + + CHECK(d2 + 1.0 == d3); + CHECK(d2 + d3 == 5.0); + CHECK(d3 + 3.0 == 6.0); + CHECK(ds + 1.5 == "Num:1.500000"); + + CHECK(d2 * 2.0 == 4.0); + CHECK(d3 * 3.0 == 9.0); + CHECK(ds * 4.0 == "Num:Num:Num:Num:"); + + CHECK(d2 - 1.0 == 1.0); + CHECK(d3 - 1.0 == 2.0); + + CHECK(d2 / 2.0 == 1.0); + CHECK(d3 / 2.0 == 1.5); + + CHECK(d3 % 2.0 == 1.0); + + CHECK(1.0 + d2 == d3); + CHECK(3.0 + d3 == 6.0); + CHECK(2.0 * d2 == 4.0); + CHECK(5.0 - d2 == 3.0); + CHECK(12.0 / d3 == 4.0); + CHECK(13.0 % d3 == 1.0); + + d2 += d3; + CHECK(d2 == 5.0); + d2 += 2.0; + CHECK(d2 == 7.0); + d2 -= 4.0; + CHECK(d2 == 3.0); + d2 *= 10.0; + CHECK(d2 == 30.0); + d2 /= 6.0; + CHECK(d2 == 5.0); + d2 %= 3.0; + CHECK(d2 == 2.0); + + CHECK(+d2 == 2.0); + CHECK(-d2 == -2.0); + CHECK(!d2 == false); + + ds += "string"; + CHECK(ds == "Num:string"); + + double dval = d2; + std::string sval = ds; + CHECK(dval == 2.0); + CHECK(sval == "Num:string"); +} diff --git a/tests/data/MemoryImage.cpp b/tests/data/MemoryImage.cpp index a905ae830f..768b091a39 100644 --- a/tests/data/MemoryImage.cpp +++ b/tests/data/MemoryImage.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file MemoryImage.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/data/SimpleParser.cpp b/tests/data/SimpleParser.cpp index 460c28b71b..aa13902df1 100644 --- a/tests/data/SimpleParser.cpp +++ b/tests/data/SimpleParser.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file SimpleParser.cpp + * @file */ #define CATCH_CONFIG_MAIN diff --git a/tests/data/Trait.cpp b/tests/data/Trait.cpp index a1cf3e73d2..029994526b 100644 --- a/tests/data/Trait.cpp +++ b/tests/data/Trait.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Trait.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/data/VarMap.cpp b/tests/data/VarMap.cpp index 66489df240..d2f2c6d1cb 100644 --- a/tests/data/VarMap.cpp +++ b/tests/data/VarMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file VarMap.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/BloomFilter.cpp b/tests/datastructs/BloomFilter.cpp index d1be1338f8..c90c28d951 100644 --- a/tests/datastructs/BloomFilter.cpp +++ b/tests/datastructs/BloomFilter.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BloomFilter.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/Bool.cpp b/tests/datastructs/Bool.cpp index ed03f2600a..5dd6e966e7 100644 --- a/tests/datastructs/Bool.cpp +++ b/tests/datastructs/Bool.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Bool.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/Cache.cpp b/tests/datastructs/Cache.cpp index 82e832af1c..e04ed1552b 100644 --- a/tests/datastructs/Cache.cpp +++ b/tests/datastructs/Cache.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Cache.cpp + * @file */ #include diff --git a/tests/datastructs/DynamicString.cpp b/tests/datastructs/DynamicString.cpp index ece941d08a..a1e4de8bf7 100644 --- a/tests/datastructs/DynamicString.cpp +++ b/tests/datastructs/DynamicString.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file DynamicString.cpp + * @file */ #include diff --git a/tests/datastructs/Graph.cpp b/tests/datastructs/Graph.cpp index 20a57744b5..5bd31f671e 100644 --- a/tests/datastructs/Graph.cpp +++ b/tests/datastructs/Graph.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Graph.cpp + * @file */ #include diff --git a/tests/datastructs/IndexMap.cpp b/tests/datastructs/IndexMap.cpp index 18c2c92547..548ea7fb51 100644 --- a/tests/datastructs/IndexMap.cpp +++ b/tests/datastructs/IndexMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file IndexMap.cpp + * @file */ #include diff --git a/tests/datastructs/QueueCache.cpp b/tests/datastructs/QueueCache.cpp index 2d1f7262e8..3699608c23 100644 --- a/tests/datastructs/QueueCache.cpp +++ b/tests/datastructs/QueueCache.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file QueueCache.cpp + * @file */ #include diff --git a/tests/datastructs/SmallFifoMap.cpp b/tests/datastructs/SmallFifoMap.cpp index 2b79f69e17..dc295ba55d 100644 --- a/tests/datastructs/SmallFifoMap.cpp +++ b/tests/datastructs/SmallFifoMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SmallFifoMap.cpp + * @file */ #include diff --git a/tests/datastructs/SmallVector.cpp b/tests/datastructs/SmallVector.cpp index da95b0bb19..6b434747c0 100644 --- a/tests/datastructs/SmallVector.cpp +++ b/tests/datastructs/SmallVector.cpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file SmallVector.cpp - * + * @file + * @brief TODO. * Adapted in part from the LLVM Project, under the Apache License v2.0 with * LLVM Exceptions. See https://llvm.org/LICENSE.txt for license information. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception diff --git a/tests/datastructs/StringMap.cpp b/tests/datastructs/StringMap.cpp index 06775485b4..ffc636f6da 100644 --- a/tests/datastructs/StringMap.cpp +++ b/tests/datastructs/StringMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file StringMap.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/TimeQueue.cpp b/tests/datastructs/TimeQueue.cpp index b3d4306f4d..3969d78218 100644 --- a/tests/datastructs/TimeQueue.cpp +++ b/tests/datastructs/TimeQueue.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file TimeQueue.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/TypeMap.cpp b/tests/datastructs/TypeMap.cpp index 171b8280d6..b6849f7a6a 100644 --- a/tests/datastructs/TypeMap.cpp +++ b/tests/datastructs/TypeMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file TypeMap.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/UnorderedIndexMap.cpp b/tests/datastructs/UnorderedIndexMap.cpp index abc75eaae5..28a28f6277 100644 --- a/tests/datastructs/UnorderedIndexMap.cpp +++ b/tests/datastructs/UnorderedIndexMap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file UnorderedIndexMap.cpp + * @file */ #include diff --git a/tests/datastructs/graph_utils.cpp b/tests/datastructs/graph_utils.cpp index f5ad309d80..003a799839 100644 --- a/tests/datastructs/graph_utils.cpp +++ b/tests/datastructs/graph_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file graph_utils.cpp + * @file */ #include diff --git a/tests/datastructs/hash_utils.cpp b/tests/datastructs/hash_utils.cpp index b6bc415f45..de6fd748e5 100644 --- a/tests/datastructs/hash_utils.cpp +++ b/tests/datastructs/hash_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file hash_utils.cpp + * @file */ #include diff --git a/tests/datastructs/map_utils.cpp b/tests/datastructs/map_utils.cpp index 6ef82eb21f..252a7c67cb 100644 --- a/tests/datastructs/map_utils.cpp +++ b/tests/datastructs/map_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file map_utils.cpp + * @file */ #include diff --git a/tests/datastructs/ra_map.cpp b/tests/datastructs/ra_map.cpp index da99192861..50ebff8268 100644 --- a/tests/datastructs/ra_map.cpp +++ b/tests/datastructs/ra_map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file ra_map.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/ra_set.cpp b/tests/datastructs/ra_set.cpp index 3f5fb43c8f..9fbcb03fa6 100644 --- a/tests/datastructs/ra_set.cpp +++ b/tests/datastructs/ra_set.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ra_set.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/reference_vector.cpp b/tests/datastructs/reference_vector.cpp index ced9d670aa..0333c1e68b 100644 --- a/tests/datastructs/reference_vector.cpp +++ b/tests/datastructs/reference_vector.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file reference_vector.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/set_utils.cpp b/tests/datastructs/set_utils.cpp index ea5ae64f97..17b1ea0409 100644 --- a/tests/datastructs/set_utils.cpp +++ b/tests/datastructs/set_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file set_utils.cpp + * @file */ #include diff --git a/tests/datastructs/tuple_struct.cpp b/tests/datastructs/tuple_struct.cpp index 86839c8c87..308c5ca094 100644 --- a/tests/datastructs/tuple_struct.cpp +++ b/tests/datastructs/tuple_struct.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file tuple_struct.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/tuple_utils.cpp b/tests/datastructs/tuple_utils.cpp index daa5cf256a..6435239898 100644 --- a/tests/datastructs/tuple_utils.cpp +++ b/tests/datastructs/tuple_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file tuple_utils.cpp + * @file */ #include diff --git a/tests/datastructs/valsort_map.cpp b/tests/datastructs/valsort_map.cpp index a5addda7f3..e7b3554867 100644 --- a/tests/datastructs/valsort_map.cpp +++ b/tests/datastructs/valsort_map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file valsort_map.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/datastructs/vector_utils.cpp b/tests/datastructs/vector_utils.cpp index 4665b2db84..2b4c9c23ec 100644 --- a/tests/datastructs/vector_utils.cpp +++ b/tests/datastructs/vector_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file vector_utils.cpp + * @file */ #include diff --git a/tests/debug/alert.cpp b/tests/debug/alert.cpp index bf628aa887..648b2dc9c7 100644 --- a/tests/debug/alert.cpp +++ b/tests/debug/alert.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file alert.cpp + * @file */ #include diff --git a/tests/debug/debug.cpp b/tests/debug/debug.cpp index 84f8ffd870..1db0f28c63 100644 --- a/tests/debug/debug.cpp +++ b/tests/debug/debug.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file debug.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/debug/mem_track.cpp b/tests/debug/mem_track.cpp index 8ee0a7d09b..65f19b3f7f 100644 --- a/tests/debug/mem_track.cpp +++ b/tests/debug/mem_track.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file mem_track.cpp + * @file */ #define EMP_TRACK_MEM diff --git a/tests/functional/AnyFunction.cpp b/tests/functional/AnyFunction.cpp index cf3acda126..f5fcd6bb4b 100644 --- a/tests/functional/AnyFunction.cpp +++ b/tests/functional/AnyFunction.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file AnyFunction.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/functional/FunctionSet.cpp b/tests/functional/FunctionSet.cpp index 0ecee6ea0d..cb5d3c3a64 100644 --- a/tests/functional/FunctionSet.cpp +++ b/tests/functional/FunctionSet.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file FunctionSet.cpp + * @file */ #include diff --git a/tests/functional/GenericFunction.cpp b/tests/functional/GenericFunction.cpp index 7b40edfe51..79780d3cee 100644 --- a/tests/functional/GenericFunction.cpp +++ b/tests/functional/GenericFunction.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file GenericFunction.cpp + * @file */ #include diff --git a/tests/functional/flex_function.cpp b/tests/functional/flex_function.cpp index f48874fc38..a905301630 100644 --- a/tests/functional/flex_function.cpp +++ b/tests/functional/flex_function.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file flex_function.cpp + * @file */ #include diff --git a/tests/functional/memo_function.cpp b/tests/functional/memo_function.cpp index 3eca1ea7e3..e3e0f52e3e 100644 --- a/tests/functional/memo_function.cpp +++ b/tests/functional/memo_function.cpp @@ -1,10 +1,11 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file memo_function.cpp - * @note doing any sort of copying of memo_functions seems to give my terminal a stack overflow error (using mingw on windows 10) + * @file + * @brief TODO. * @MAM not sure who left this comment about stack overflow on mingw... */ diff --git a/tests/games/Mancala.cpp b/tests/games/Mancala.cpp index 39d490e2fb..f450a4aede 100644 --- a/tests/games/Mancala.cpp +++ b/tests/games/Mancala.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Mancala.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/games/Othello.cpp b/tests/games/Othello.cpp index c5a30a785b..717042fa67 100644 --- a/tests/games/Othello.cpp +++ b/tests/games/Othello.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Othello.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/games/Othello8.cpp b/tests/games/Othello8.cpp index d848fe6a7f..a68697c810 100644 --- a/tests/games/Othello8.cpp +++ b/tests/games/Othello8.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Othello8.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/games/PayoffMatrix.cpp b/tests/games/PayoffMatrix.cpp index a5945968e4..571ac60010 100644 --- a/tests/games/PayoffMatrix.cpp +++ b/tests/games/PayoffMatrix.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file PayoffMatrix.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/geometry/Angle2D.cpp b/tests/geometry/Angle2D.cpp index b1f996164d..d7e55b6797 100644 --- a/tests/geometry/Angle2D.cpp +++ b/tests/geometry/Angle2D.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Angle2D.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/geometry/Body2D.cpp b/tests/geometry/Body2D.cpp index 29cd561d28..6ff906b7a7 100644 --- a/tests/geometry/Body2D.cpp +++ b/tests/geometry/Body2D.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Body2D.cpp + * @file */ #include diff --git a/tests/geometry/Circle2D.cpp b/tests/geometry/Circle2D.cpp index 4a8a84b2f1..695bba7bcf 100644 --- a/tests/geometry/Circle2D.cpp +++ b/tests/geometry/Circle2D.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Circle2D.cpp + * @file */ #include diff --git a/tests/geometry/Physics2D.cpp b/tests/geometry/Physics2D.cpp index bf2a70faa0..dce7f9992a 100644 --- a/tests/geometry/Physics2D.cpp +++ b/tests/geometry/Physics2D.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Physics2D.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/geometry/Point2D.cpp b/tests/geometry/Point2D.cpp index 093217a53b..2fa934fb60 100644 --- a/tests/geometry/Point2D.cpp +++ b/tests/geometry/Point2D.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Point2D.cpp + * @file */ #include diff --git a/tests/geometry/Surface.cpp b/tests/geometry/Surface.cpp index 8bdca2af0c..a8d3b879b7 100644 --- a/tests/geometry/Surface.cpp +++ b/tests/geometry/Surface.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Surface.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/geometry/Surface2D.cpp b/tests/geometry/Surface2D.cpp index a20d0b559f..0bc570d599 100644 --- a/tests/geometry/Surface2D.cpp +++ b/tests/geometry/Surface2D.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Surface2D.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/hardware/BitSorter.cpp b/tests/hardware/BitSorter.cpp index 82f9dd0355..e276aa8b9d 100644 --- a/tests/hardware/BitSorter.cpp +++ b/tests/hardware/BitSorter.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file BitSorter.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/hardware/LinearCode.cpp b/tests/hardware/LinearCode.cpp index 89382af20b..8a870606e6 100644 --- a/tests/hardware/LinearCode.cpp +++ b/tests/hardware/LinearCode.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file LinearCode.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/hardware/VirtualCPU.cpp b/tests/hardware/VirtualCPU.cpp index 810d1b81e7..b784e37823 100644 --- a/tests/hardware/VirtualCPU.cpp +++ b/tests/hardware/VirtualCPU.cpp @@ -1,10 +1,13 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022 - * - * @file VirtualCPU.cpp - * + * @file + */ + +/* * TODO * [ ] *INSTRUCTIONS struct * [ ] Constructors assign values correctly @@ -1589,7 +1592,7 @@ TEST_CASE("VirtualCPU_String_Methods", "[Hardware]") { CHECK(string_vec[1] == "[0] 0"); CHECK(string_vec[2] == "[1] 1"); CHECK(string_vec[3] == "[2] 2"); - CHECK(string_vec[4] == "[3] 3"); // last line gets to keep its newline character + CHECK(string_vec[4] == "[3] 3"); /* [X] GetWorkingGenomeString returns a string representation of the working genome [X] GetGenomeString returns a string representation of the (non-working) genome diff --git a/tests/hardware/avida_gp.cpp b/tests/hardware/avida_gp.cpp index 46bc354692..0ab65e322d 100644 --- a/tests/hardware/avida_gp.cpp +++ b/tests/hardware/avida_gp.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file avida_gp.cpp + * @file */ #include diff --git a/tests/hardware/event_driven_gp.cpp b/tests/hardware/event_driven_gp.cpp index 60d2551c61..2152bf362c 100644 --- a/tests/hardware/event_driven_gp.cpp +++ b/tests/hardware/event_driven_gp.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file event_driven_gp.cpp + * @file */ #include @@ -164,7 +165,7 @@ TEST_CASE("Test Event Driven GP", "[Hardware]") // New Random gp.NewRandom(150); - (gp.GetRandom().GetSeed() == 150); + REQUIRE(gp.GetRandom().GetSeed() == 150); // Events emp::EventDrivenGP::Event ev(0); // event 0 in event lib is message @@ -540,7 +541,9 @@ TEST_CASE("Test SignalGP ('EventDrivenGP.h') utility: GenRandSignalGPTag", "[har std::unordered_set uset; // Will be used to double-check uniqueness. // Generate a bunch of big random tags. No uniqueness guarantees. - for (size_t i = 0; i < 100; ++i) auto tag = emp::GenRandSignalGPTag<1024>(random); + for (size_t i = 0; i < 100; ++i) { + [[maybe_unused]] auto tag = emp::GenRandSignalGPTag<1024>(random); + } // Enumerate all 2-bit tags emp::vector> tags2; @@ -885,8 +888,8 @@ TEST_CASE("Test SignalGP ('EventDrivenGP.h') utility: SignalGPMutator struct", " // Check parameter adding. size_t default_param_cnt = mutator.GetParamCnt(); size_t param1_id = mutator.AddParam("test1", 1.0, "Test parameter one!"); - size_t param2_id = mutator.AddParam("test2", 2.0, "Test parameter two!"); - size_t param3_id = mutator.AddParam("test3", 3.0, "Test parameter three!"); + [[maybe_unused]] size_t param2_id = mutator.AddParam("test2", 2.0, "Test parameter two!"); + [[maybe_unused]] size_t param3_id = mutator.AddParam("test3", 3.0, "Test parameter three!"); REQUIRE(mutator.GetParamCnt() == default_param_cnt+3); REQUIRE(mutator.GetParam(param1_id) == 1.0); REQUIRE(mutator.GetParam(param1_id) == mutator.GetParam("test1")); diff --git a/tests/io/ContiguousStream.cpp b/tests/io/ContiguousStream.cpp index e1e0877629..c80044c25b 100644 --- a/tests/io/ContiguousStream.cpp +++ b/tests/io/ContiguousStream.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ContiguousStream.cpp + * @file */ #include diff --git a/tests/io/File.cpp b/tests/io/File.cpp index 20c9e0a82d..6360e737bf 100644 --- a/tests/io/File.cpp +++ b/tests/io/File.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file File.cpp + * @file */ #include @@ -97,7 +98,7 @@ TEST_CASE("Test File", "[io]") fp2 << "Line3"; fp2 << "Line3"; fp2 << "Line3"; - std::set setOfLines = fp2.AsSet(); + std::set setOfLines = fp2.AsSet(); REQUIRE(setOfLines.size() == 3); REQUIRE(fp2.GetNumLines() == 9); @@ -143,14 +144,14 @@ TEST_CASE("Test File", "[io]") REQUIRE(fp3.back() == "int x = 13;"); // Process - std::function fun = [](std::string& s)-> std::string { return (s+"2");}; - emp::vector v = fp2.Process(fun); + std::function fun = [](emp::String& s)-> emp::String { return (s+"2");}; + emp::vector v = fp2.Process(fun); // ExtractCol fp3 >> line; //clear fp3 fp3 << "red,1,1990"; fp3 << "green,2,1995"; - emp::vector column = fp3.ExtractCol(); + emp::vector column = fp3.ExtractCol(); REQUIRE(column[0] == "red"); REQUIRE(column[1] == "green"); diff --git a/tests/io/MemoryIStream.cpp b/tests/io/MemoryIStream.cpp index 789b22ff97..56ebbcdc1e 100644 --- a/tests/io/MemoryIStream.cpp +++ b/tests/io/MemoryIStream.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file MemoryIStream.cpp + * @file */ #include diff --git a/tests/io/NullStream.cpp b/tests/io/NullStream.cpp index 97a405198f..4da0292fe7 100644 --- a/tests/io/NullStream.cpp +++ b/tests/io/NullStream.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file NullStream.cpp + * @file */ #include diff --git a/tests/io/StreamManager.cpp b/tests/io/StreamManager.cpp index 0f6bb3e0f4..7a58c012ac 100644 --- a/tests/io/StreamManager.cpp +++ b/tests/io/StreamManager.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file StreamManager.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/io/ascii_utils.cpp b/tests/io/ascii_utils.cpp index 82d9580da5..e43c3d7226 100644 --- a/tests/io/ascii_utils.cpp +++ b/tests/io/ascii_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ascii_utils.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/io/serialize.cpp b/tests/io/serialize.cpp index 5499a1e89f..8ba3ccd494 100644 --- a/tests/io/serialize.cpp +++ b/tests/io/serialize.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file serialize.cpp + * @file */ #include diff --git a/tests/matching/MatchBin.cpp b/tests/matching/MatchBin.cpp index d0f46b3d08..db89662ef6 100644 --- a/tests/matching/MatchBin.cpp +++ b/tests/matching/MatchBin.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file MatchBin.cpp + * @file */ #include @@ -819,8 +820,8 @@ TEST_CASE("Test MatchBin", "[matchbin]") REQUIRE(bitBin64.GetVals(bitBin64.Match(bs9, std::numeric_limits::max())) == (emp::vector {"nine"})); REQUIRE(bitBin64.GetTags(bitBin64.Match(bs9, std::numeric_limits::max())) == (emp::vector> {bs9})); - REQUIRE(bitBin64.GetVals(bitBin64.Match(bs9, 5)) == (emp::vector {"nine","one","seven"})); - REQUIRE(bitBin64.GetTags(bitBin64.Match(bs9, 5)) == (emp::vector> {bs9, bs1, bs7})); + REQUIRE(bitBin64.GetVals(bitBin64.Match(bs9, 5)) == (emp::vector {"nine","seven","one"})); + REQUIRE(bitBin64.GetTags(bitBin64.Match(bs9, 5)) == (emp::vector> {bs9, bs7, bs1})); } // test ImprintRegulators diff --git a/tests/matching/MatchBin_logging.cpp b/tests/matching/MatchBin_logging.cpp index b3f634eeaf..2ef8c8188e 100644 --- a/tests/matching/MatchBin_logging.cpp +++ b/tests/matching/MatchBin_logging.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020 - * - * @file MatchBin_logging.cpp + * @file */ #define EMP_DECORATE(X) [X] @@ -236,7 +237,7 @@ TEST_CASE("Test MatchBin", "[matchbin]") emp::File file(ss); - auto data = file.ToData(); + auto data = file.ToData(); // buffer should be empty, so must only have a header REQUIRE(data.size() == 1); @@ -247,7 +248,7 @@ TEST_CASE("Test MatchBin", "[matchbin]") // test flush log buffer bin.log.FlushLogBuffer(); - data = file.ToData(); + data = file.ToData(); REQUIRE(data.size() == 1); REQUIRE(bin.log.GetLogBuffer().empty()); @@ -328,8 +329,8 @@ TEST_CASE("Test MatchBin", "[matchbin]") auto data = file.ToData(); - // data must be equal to 3n, given that for each matchbin we have - // 1 header and 2 matches + // data must be equal to 3n + 1, given that for each matchbin we have + // 1 header and 2 matches, and at the end an EOF newline REQUIRE(data.size() == 3 * n); } // test logging misses @@ -357,9 +358,9 @@ TEST_CASE("Test MatchBin", "[matchbin]") emp::File file(ss); // extract header - std::vector header{file.ExtractRow()}; - std::vector regulated_row{file.ExtractRow()}; - std::vector raw_row{file.ExtractRow()}; + emp::vector header{file.ExtractRow()}; + emp::vector regulated_row{file.ExtractRow()}; + emp::vector raw_row{file.ExtractRow()}; // find the index of the tag // if a future change moves it, this test won't break diff --git a/tests/matching/MatchDepository.cpp b/tests/matching/MatchDepository.cpp index 815c332c12..d17a6f9ca7 100644 --- a/tests/matching/MatchDepository.cpp +++ b/tests/matching/MatchDepository.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file MatchDepository.cpp + * @file */ #include diff --git a/tests/matching/RankedSelector.cpp b/tests/matching/RankedSelector.cpp index 7592f86739..958dc9d3f6 100644 --- a/tests/matching/RankedSelector.cpp +++ b/tests/matching/RankedSelector.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file RankedSelector.cpp + * @file */ #include diff --git a/tests/matching/_DepositoryEntry.cpp b/tests/matching/_DepositoryEntry.cpp index e03023909a..44f606d250 100644 --- a/tests/matching/_DepositoryEntry.cpp +++ b/tests/matching/_DepositoryEntry.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file _DepositoryEntry.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/matching/matchbin_utils.cpp b/tests/matching/matchbin_utils.cpp index aaf329efb1..7e04a7f407 100644 --- a/tests/matching/matchbin_utils.cpp +++ b/tests/matching/matchbin_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2021 - * - * @file matchbin_utils.cpp + * @file */ #include diff --git a/tests/math/Distribution.cpp b/tests/math/Distribution.cpp index 0720fe6571..9730d34dd7 100644 --- a/tests/math/Distribution.cpp +++ b/tests/math/Distribution.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Distribution.cpp + * @file */ #include diff --git a/tests/math/Fraction.cpp b/tests/math/Fraction.cpp new file mode 100644 index 0000000000..2223c3faff --- /dev/null +++ b/tests/math/Fraction.cpp @@ -0,0 +1,66 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + */ + +#include "third-party/Catch/single_include/catch2/catch.hpp" + +#include "emp/math/Fraction.hpp" + +TEST_CASE("Test Fraction Constructor", "[math]") { + emp::Fraction frac1; + REQUIRE(frac1.GetNumerator() == 0); + REQUIRE(frac1.GetDenominator() == 1); + frac1.Reduce(); + REQUIRE(frac1.GetNumerator() == 0); + REQUIRE(frac1.GetDenominator() == 1); + + emp::Fraction frac2(5, 10); + REQUIRE(frac2.GetNumerator() == 5); + REQUIRE(frac2.GetDenominator() == 10); + frac2.Reduce(); + REQUIRE(frac2.GetNumerator() == 1); + REQUIRE(frac2.GetDenominator() == 2); + + emp::Fraction frac3(0, 10); + REQUIRE(frac3.GetNumerator() == 0); + REQUIRE(frac3.GetDenominator() == 10); // Zero numerator + frac3.Reduce(); + REQUIRE(frac3.GetNumerator() == 0); + REQUIRE(frac3.GetDenominator() == 1); + + emp::Fraction frac4(10, -5); + REQUIRE(frac4.GetNumerator() == 10); // Negative handling + REQUIRE(frac4.GetDenominator() == -5); + frac4.Reduce(); + REQUIRE(frac4.GetNumerator() == -2); + REQUIRE(frac4.GetDenominator() == 1); + + emp::Fraction frac5(-10, 5); + REQUIRE(frac5.GetNumerator() == -10); // Negative handling + REQUIRE(frac5.GetDenominator() == 5); + frac5.Reduce(); + REQUIRE(frac5.GetNumerator() == -2); + REQUIRE(frac5.GetDenominator() == 1); + + emp::Fraction frac6(-10, -5); + REQUIRE(frac6.GetNumerator() == -10); // Negative handling + REQUIRE(frac6.GetDenominator() == -5); + frac6.Reduce(); + REQUIRE(frac6.GetNumerator() == 2); + REQUIRE(frac6.GetDenominator() == 1); + +} + +TEST_CASE("Test Zero Denominator", "[math]") { + emp::Fraction frac(10, 0); + REQUIRE(frac.GetNumerator() == 10); + REQUIRE(frac.GetDenominator() == 0); + frac.Reduce(); + REQUIRE(frac.GetNumerator() == 10); + REQUIRE(frac.GetDenominator() == 0); // Expect no change for zero denominator +} diff --git a/tests/math/Makefile b/tests/math/Makefile index b4ead88458..fda1a0daa0 100644 --- a/tests/math/Makefile +++ b/tests/math/Makefile @@ -1,4 +1,4 @@ -TEST_NAMES = combos distances Distribution info_theory math random_utils Random sequence_utils spatial_stats stats Range +TEST_NAMES = combos distances Distribution Fraction info_theory math random_utils Random sequence_utils spatial_stats stats Range RangeSet # -O3 -Wl,--stack,8388608 -ftrack-macro-expansion=0 FLAGS = -std=c++20 -g -pthread -Wall -Wno-unused-function -Wno-unused-private-field -I../../include/ -I../../ -I../../third-party/cereal/include/ -DCATCH_CONFIG_MAIN diff --git a/tests/math/Random.cpp b/tests/math/Random.cpp index eb10e91691..fec41ba775 100644 --- a/tests/math/Random.cpp +++ b/tests/math/Random.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Random.cpp + * @file */ #include @@ -89,7 +90,7 @@ TEST_CASE("Test Random", "[math]") REQUIRE(b2_result < 50); emp::RandomStdAdaptor randomStd(rnd); - REQUIRE(randomStd(4) == 1); + REQUIRE(randomStd(4) < 4); REQUIRE(rnd.GetGeometric(1) == 1); // REQUIRE(rnd.GetGeometric(0) == std::numeric_limits::infinity()); @@ -312,3 +313,48 @@ TEST_CASE("Another Test random", "[math]") REQUIRE(v.first + v.second == 0); } } + +TEST_CASE("Calling ResetSeed should reset all generator internal state", "[math]") { + + SECTION("Test internal 'value'") { + // Get Seed + emp::Random rnd(-1); // Initialize without a seed + rnd.ResetSeed(5); + REQUIRE(rnd.GetSeed() == 5); + + emp::vector sequence_a; + for (size_t i = 0; i < 10; ++i) { + sequence_a.emplace_back(rnd.GetInt(10000)); + } + + rnd.ResetSeed(5); + emp::vector sequence_b; + for (size_t i = 0; i < 10; ++i) { + sequence_b.emplace_back(rnd.GetInt(10000)); + } + + // Tests internal 'value' + REQUIRE(sequence_a == sequence_b); + } + + SECTION("Test internal expV") { + emp::Random rnd(10); + rnd.GetNormal(); // Adjusts expV with time-based seed generator + + rnd.ResetSeed(4); // Should reset expV + emp::vector norm_seq_a; + for (size_t i = 0; i < 1000; ++i) { + norm_seq_a.emplace_back(rnd.GetNormal()); + } + + rnd.ResetSeed(4); + emp::vector norm_seq_b; + for (size_t i = 0; i < 1000; ++i) { + norm_seq_b.emplace_back(rnd.GetNormal()); + } + + // Tests internal expV + REQUIRE(norm_seq_a == norm_seq_b); + } + +} diff --git a/tests/math/Range.cpp b/tests/math/Range.cpp index 5bf8efe8a2..a3ffd151c9 100644 --- a/tests/math/Range.cpp +++ b/tests/math/Range.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-23 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Range.cpp + * @file */ #include @@ -13,7 +14,7 @@ #include "emp/math/Range.hpp" -TEST_CASE("Test Range", "[math]") +TEST_CASE("Test integral Ranges", "[math]") { // Basic constructor [[maybe_unused]] emp::Range rng; @@ -22,6 +23,13 @@ TEST_CASE("Test Range", "[math]") emp::Range r(0,10); REQUIRE(r.GetLower() == 0); REQUIRE(r.GetUpper() == 10); + REQUIRE(r.GetSize() == 11); // 0 through 10 inclusive. + REQUIRE(r.Has(0) == true); + REQUIRE(r.Has(10) == true); + REQUIRE(r.Has(5) == true); + REQUIRE(r.Has(-1) == false); + REQUIRE(r.Has(11) == false); + REQUIRE(r.Has(100000) == false); // CalcBin REQUIRE(r.CalcBin(5,10) == 5); @@ -34,8 +42,8 @@ TEST_CASE("Test Range", "[math]") REQUIRE(r1 != r); // Valid Limit - REQUIRE(!r1.Valid(0)); - REQUIRE(r1.Limit(0) == 5); + REQUIRE(!r1.Has(0)); + REQUIRE(r1.Clamp(0) == 5); // Spread emp::vector s = r.Spread(6); @@ -53,8 +61,8 @@ TEST_CASE("Test Range", "[math]") REQUIRE(r.GetLower() == 0); REQUIRE(r.GetUpper() == 15); - // SetMaxLower SetMaxUpper - r.SetMaxLower(); + // SetMinLower SetMaxUpper + r.SetMinLower(); r.SetMaxUpper(); REQUIRE(r.GetLower() == -2147483648); REQUIRE(r.GetUpper() == 2147483647); @@ -63,19 +71,173 @@ TEST_CASE("Test Range", "[math]") emp::Range r2 = emp::MakeRange('a','z'); REQUIRE(r2.GetLower() == 'a'); REQUIRE(r2.GetUpper() == 'z'); + REQUIRE(r2.GetSize() == 26); REQUIRE(r2.CalcBin('g',26) == 6); + REQUIRE(r2.Has('a') == true); + REQUIRE(r2.Has('j') == true); + REQUIRE(r2.Has('z') == true); + REQUIRE(r2.Has('A') == false); + REQUIRE(r2.Has('-') == false); + REQUIRE(r2.Has('\n') == false); // IntRange emp::Range r3 = emp::IntRange(-5,5); REQUIRE(r3.GetLower() == -5); REQUIRE(r3.GetUpper() == 5); - REQUIRE(r3.Limit(100) == 5); + REQUIRE(r3.GetSize() == 11); + REQUIRE(r3.Clamp(100) == 5); +} + +TEST_CASE("Test Range with non-inclusive endpoint", "[math]") +{ + // Basic constructor + [[maybe_unused]] emp::Range rng; + + // GetLower GetUpper + emp::Range r(0,10); + REQUIRE(r.GetLower() == 0); + REQUIRE(r.GetUpper() == 10); + REQUIRE(r.GetSize() == 10); // 0 through 10 exclusive. + REQUIRE(r.Has(0) == true); + REQUIRE(r.Has(10) == false); + REQUIRE(r.Has(5) == true); + REQUIRE(r.Has(-1) == false); + REQUIRE(r.Has(11) == false); + REQUIRE(r.Has(100000) == false); + + // CalcBin + REQUIRE(r.CalcBin(5,10) == 5); + REQUIRE(r.CalcBin(1,4) == 0); + + // Comparison + emp::Range r1 = r; + REQUIRE(r1 == r); + r1.SetLower(5); + REQUIRE(r1 != r); + + // Valid Limit + REQUIRE(!r1.Has(0)); + REQUIRE(r1.Clamp(0) == 5); + + // Spread + emp::vector s = r.Spread(6); + int j=0; + for(int i=0;i<6;i++){ + REQUIRE(s[i] == j); + j+=2; + } + + // SetLower SetUpper Set + r1.SetLower(0); + r1.SetUpper(15); + r.Set(0,15); + REQUIRE(r1 == r); + REQUIRE(r.GetLower() == 0); + REQUIRE(r.GetUpper() == 15); + + // SetMinLower SetMaxUpper + r.SetMinLower(); + r.SetMaxUpper(); + REQUIRE(r.GetLower() == -2147483648); + REQUIRE(r.GetUpper() == 2147483647); + + // MakeRange + emp::Range r2 = emp::MakeRange('a','z'); + REQUIRE(r2.GetLower() == 'a'); + REQUIRE(r2.GetUpper() == 'z'); + REQUIRE(r2.GetSize() == 25); // 'z' is excluded. + REQUIRE(r2.CalcBin('g',26) == 6); + REQUIRE(r2.Has('a') == true); + REQUIRE(r2.Has('j') == true); + REQUIRE(r2.Has('z') == false); + REQUIRE(r2.Has('A') == false); + REQUIRE(r2.Has('-') == false); + REQUIRE(r2.Has('\n') == false); + // IntRange + emp::Range r3 = emp::IntRange(-5,5); + REQUIRE(r3.GetLower() == -5); + REQUIRE(r3.GetUpper() == 5); + REQUIRE(r3.GetSize() == 10); + REQUIRE(r3.Clamp(100) == 4); +} + +TEST_CASE("Test continuous ranges", "[math]") +{ // DRange - emp::Range r4 = emp::DRange(0.1,23.5); - REQUIRE(r4.GetLower() == 0.1); - REQUIRE(r4.GetUpper() == 23.5); - REQUIRE(!r4.Valid(0.0)); - REQUIRE(r4.CalcBin(4.7,5) == 0); - REQUIRE(r4.CalcBin(4.8,5) == 1); + emp::Range dr = emp::DRange(0.1,23.5); + REQUIRE(dr.GetLower() == 0.1); + REQUIRE(dr.GetUpper() == 23.5); + REQUIRE(dr.GetSize() > 23.3999); REQUIRE(dr.GetSize() < 23.4001); + REQUIRE(!dr.Has(0.0)); + REQUIRE(dr.CalcBin(4.7,5) == 0); + REQUIRE(dr.CalcBin(4.8,5) == 1); + REQUIRE(dr.Has(0.1) == true); + REQUIRE(dr.Has(23.5) == true); + REQUIRE(dr.Has(10.0) == true); + REQUIRE(dr.Has(0.09) == false); + REQUIRE(dr.Has(23.6) == false); + REQUIRE(dr.Has(0.000000001) == false); + REQUIRE(dr.Clamp(23.6) == 23.5); + + // DRange with excluded endpoint. + emp::Range dr2 = emp::DRange(0.1,23.5); + REQUIRE(dr2.GetLower() == 0.1); + REQUIRE(dr2.GetUpper() == 23.5); + REQUIRE(dr2.GetSize() > 23.3999); REQUIRE(dr2.GetSize() < 23.4001); + REQUIRE(!dr2.Has(0.0)); + REQUIRE(dr2.CalcBin(4.7,5) == 0); + REQUIRE(dr2.CalcBin(4.8,5) == 1); + REQUIRE(dr2.Has(0.1) == true); + REQUIRE(dr2.Has(23.5) == false); + REQUIRE(dr2.Has(10.0) == true); + REQUIRE(dr2.Has(0.09) == false); + REQUIRE(dr2.Has(23.6) == false); + REQUIRE(dr2.Has(0.000000001) == false); + REQUIRE(dr2.Clamp(23.6) < 23.5); +} + +TEST_CASE("Test Range constructors", "[math]") +{ + // Base constructor. + emp::Range r1; + REQUIRE(r1.Has(100000) == true); // Should have a large range. + REQUIRE(r1.Has(-100000) == true); // Should have a large negative range too. + r1.Set(-100, 200000); + REQUIRE(r1.Has(100000) == true); + REQUIRE(r1.Has(-100000) == false); + r1.Set(-100, 200); + REQUIRE(r1.Has(100000) == false); + REQUIRE(r1.Has(-100000) == false); + + // Single-value constructor. + emp::Range r2('j'); + REQUIRE(r2.Has('i') == false); + REQUIRE(r2.Has('j') == true); + REQUIRE(r2.Has('k') == false); + REQUIRE(r2.GetLower() == 'j'); + REQUIRE(r2.GetUpper() == 'j'); + + // Single-value constructor exclusive of limit. + emp::Range r3('j'); + REQUIRE(r3.Has('i') == false); + REQUIRE(r3.Has('j') == true); + REQUIRE(r3.Has('k') == false); + REQUIRE(r3.GetLower() == 'j'); + REQUIRE(r3.GetUpper() == 'k'); + + // Single-value constructor with continuous value, exclusive of limit. + emp::Range r4(12345.67); + REQUIRE(r4.Has(12345.66) == false); + REQUIRE(r4.Has(12345.67) == true); + REQUIRE(r4.Has(12345.68) == false); + REQUIRE(r4.GetLower() == 12345.67); + REQUIRE(r4.GetUpper() > 12345.67); + + // Let's try a string-base range. + emp::Range r5("abc", "def"); + REQUIRE(r5.Has("aardvark") == false); + REQUIRE(r5.Has("beta") == true); + REQUIRE(r5.Has("central") == true); + REQUIRE(r5.Has("divided") == false); } diff --git a/tests/math/RangeSet.cpp b/tests/math/RangeSet.cpp new file mode 100644 index 0000000000..e29feb75b5 --- /dev/null +++ b/tests/math/RangeSet.cpp @@ -0,0 +1,486 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ +/** + * @file + */ + +#include +#include + +#include "third-party/Catch/single_include/catch2/catch.hpp" + +#include "emp/math/RangeSet.hpp" + +TEST_CASE("Test integral RangeSets", "[math]") +{ + emp::RangeSet rs1; + + CHECK(rs1.Has(27) == false); + CHECK(rs1.Has(-1003) == false); + CHECK(rs1.Has(0) == false); + CHECK(rs1.GetNumRanges() == 0); + CHECK(rs1.GetSize() == 0); + + rs1.Insert(27); + + CHECK(rs1.Has(26) == false); + CHECK(rs1.Has(27) == true); + CHECK(rs1.Has(28) == false); + CHECK(rs1.Has(-1003) == false); + CHECK(rs1.Has(0) == false); + CHECK(rs1.GetStart() == 27); + CHECK(rs1.GetEnd() == 28); + CHECK(rs1.GetNumRanges() == 1); + CHECK(rs1.GetSize() == 1); + + rs1.Insert(28); + + CHECK(rs1.Has(26) == false); + CHECK(rs1.Has(27) == true); + CHECK(rs1.Has(28) == true); + CHECK(rs1.Has(29) == false); + CHECK(rs1.Has(-1003) == false); + CHECK(rs1.Has(0) == false); + CHECK(rs1.GetStart() == 27); + CHECK(rs1.GetEnd() == 29); + CHECK(rs1.GetNumRanges() == 1); + CHECK(rs1.GetSize() == 2); + + rs1.Insert(26); + + CHECK(rs1.Has(25) == false); + CHECK(rs1.Has(26) == true); + CHECK(rs1.Has(27) == true); + CHECK(rs1.Has(28) == true); + CHECK(rs1.Has(29) == false); + CHECK(rs1.Has(-1003) == false); + CHECK(rs1.Has(0) == false); + CHECK(rs1.GetStart() == 26); + CHECK(rs1.GetEnd() == 29); + CHECK(rs1.GetNumRanges() == 1); + CHECK(rs1.GetSize() == 3); + + rs1.Insert(emp::Range(23,26)); + + // Make sure RangeSets are identified as equal, even if constructed differently. + emp::RangeSet rs2(emp::Range{23,29}); + CHECK(rs1 == rs2); + CHECK(rs1.GetStart() == 23); + CHECK(rs1.GetEnd() == 29); + CHECK(rs1.GetNumRanges() == 1); + CHECK(rs1.GetSize() == 6); + + // Make sure Remove works... + CHECK(rs1.Has(26) == true); + rs1.Remove(26); + CHECK(rs1.Has(23) == true); + CHECK(rs1.Has(24) == true); + CHECK(rs1.Has(25) == true); + CHECK(rs1.Has(26) == false); + CHECK(rs1.Has(27) == true); + CHECK(rs1.Has(28) == true); + CHECK(rs1.Has(29) == false); + CHECK(rs1.Has(-1003) == false); + CHECK(rs1.Has(0) == false); + CHECK(rs1 != rs2); + CHECK(rs1.GetStart() == 23); + CHECK(rs1.GetEnd() == 29); + CHECK(rs1.GetNumRanges() == 2); + CHECK(rs1.GetSize() == 5); + + // And the re-Insertion and merging. + rs1.Insert(26); + CHECK(rs1 == rs2); + CHECK(rs1.GetNumRanges() == 1); + CHECK(rs1.GetSize() == 6); + + rs2.Insert(-1); + rs2.Insert(1000); + CHECK(rs1 != rs2); + CHECK(rs1.GetNumRanges() == 1); + CHECK(rs2.GetNumRanges() == 3); + CHECK(rs1.GetSize() == 6); + CHECK(rs2.GetSize() == 8); + + CHECK(rs1.OK() == true); + CHECK(rs2.OK() == true); +} + +TEST_CASE("Test continuous RangeSets", "[math]") +{ + emp::RangeSet rs1; + using range_t = emp::RangeSet::range_t; + range_t range(0.4, 0.9); + + rs1.InsertRange(0.0, 100.0); + CHECK(rs1.GetSize() == Approx(100.0)); + + CHECK(rs1.HasOverlap(range) == true); + rs1.Remove(range); + CHECK(rs1.HasOverlap(range) == false); + CHECK(rs1.GetSize() == Approx(99.5)); + rs1.Remove(range); + CHECK(rs1.HasOverlap(range) == false); + CHECK(rs1.GetSize() == Approx(99.5)); + + for (size_t i = 0; i < 100; ++i) { + range.Shift(1.0); + rs1.Remove(range); // Only the first 99 should matter -- then we're out of range.) + } + // From 0.0 to 100.0 we should have gaps from every *.4 to *.9 + + CHECK(rs1.GetSize() == Approx(50.0)); + CHECK(rs1.GetNumRanges() == 101); + + // Remove exact range. + CHECK(rs1.HasOverlap(range_t(1.9, 2.4)) == true); + rs1.RemoveRange(1.9, 2.4); + CHECK(rs1.HasOverlap(range_t(1.9, 2.4)) == false); + CHECK(rs1.GetSize() == Approx(49.5)); + CHECK(rs1.GetNumRanges() == 100); + + // Remove range + gap before + CHECK(rs1.HasOverlap(range_t(3.4, 4.4)) == true); + rs1.RemoveRange(3.4, 4.4); + CHECK(rs1.HasOverlap(range_t(3.4, 4.4)) == false); + CHECK(rs1.GetSize() == Approx(49.0)); + CHECK(rs1.GetNumRanges() == 99); + + // Remove range + gap after + CHECK(rs1.HasOverlap(range_t(5.9, 6.9)) == true); + rs1.RemoveRange(5.9, 6.9); + CHECK(rs1.HasOverlap(range_t(5.9, 6.9)) == false); + CHECK(rs1.GetSize() == Approx(48.5)); + CHECK(rs1.GetNumRanges() == 98); + + // Remove range + both gaps + CHECK(rs1.HasOverlap(range_t(7.4, 8.9)) == true); + rs1.RemoveRange(7.4, 8.9); + CHECK(rs1.HasOverlap(range_t(7.4, 8.9)) == false); + CHECK(rs1.GetSize() == Approx(48.0)); + CHECK(rs1.GetNumRanges() == 97); + + // Remove range + to middle of both gaps + CHECK(rs1.HasOverlap(range_t(10.6, 11.7)) == true); + rs1.RemoveRange(10.6, 11.7); + CHECK(rs1.HasOverlap(range_t(10.6, 11.7)) == false); + CHECK(rs1.GetSize() == Approx(47.5)); + CHECK(rs1.GetNumRanges() == 96); + + // Try a bunch of failed removals. + const emp::RangeSet rs1_bak(rs1); + rs1.RemoveRange(13.4, 13.9); // Remove full gap. + rs1.RemoveRange(13.7, 13.9); // Remove middle to end of gap. + rs1.RemoveRange(13.4, 13.6); // Remove beginning to middle of gap. + rs1.RemoveRange(13.5, 13.8); // Remove chunk in middle of gap. + CHECK(rs1 == rs1_bak); // Nothing should have changed from removals. + + CHECK(rs1.GetSize() == Approx(47.5)); + CHECK(rs1.GetNumRanges() == 96); + + // Remove middle of one range through middle of next. + CHECK(rs1.HasOverlap(range_t(14.15,15.15)) == true); + rs1.RemoveRange(14.15,15.15); + CHECK(rs1.HasOverlap(range_t(14.15,15.15)) == false); + CHECK(rs1.GetSize() == Approx(47.0)); + CHECK(rs1.GetNumRanges() == 96); + + // Remove middle of one range through end of next. + CHECK(rs1.HasOverlap(range_t(16.15,17.4)) == true); + rs1.RemoveRange(16.15,17.4); + CHECK(rs1.HasOverlap(range_t(16.15,17.4)) == false); + CHECK(rs1.GetSize() == Approx(46.25)); + CHECK(rs1.GetNumRanges() == 95); + + // Remove beginning of one range through middle of next. + CHECK(rs1.HasOverlap(range_t(18.9,20.15)) == true); + rs1.RemoveRange(18.9,20.15); + CHECK(rs1.HasOverlap(range_t(18.9,20.15)) == false); + CHECK(rs1.GetSize() == Approx(45.5)); + CHECK(rs1.GetNumRanges() == 94); + + // Remove beginning of one range through end of next. + CHECK(rs1.HasOverlap(range_t(21.9,23.4)) == true); + rs1.RemoveRange(21.9,23.4); + CHECK(rs1.HasOverlap(range_t(21.9,23.4)) == false); + CHECK(rs1.GetSize() == Approx(44.5)); + CHECK(rs1.GetNumRanges() == 92); + + // Remove middle section of one range only + CHECK(rs1.HasOverlap(range_t(26.0,26.25)) == true); + rs1.RemoveRange(26.0,26.25); + CHECK(rs1.HasOverlap(range_t(26.0,26.25)) == false); + CHECK(rs1.GetSize() == Approx(44.25)); + CHECK(rs1.GetNumRanges() == 93); + + // Remove middle of one range through middle of two later. + CHECK(rs1.HasOverlap(range_t(29.0,31.0)) == true); + rs1.RemoveRange(29.0,31.0); + CHECK(rs1.HasOverlap(range_t(29.0,31.0)) == false); + CHECK(rs1.GetSize() == Approx(43.25)); + CHECK(rs1.GetNumRanges() == 92); + + // Remove middle of one range through middle of four later. + CHECK(rs1.HasOverlap(range_t(34.0,38.0)) == true); + rs1.RemoveRange(34.0,38.0); + CHECK(rs1.HasOverlap(range_t(34.0,38.0)) == false); + CHECK(rs1.GetSize() == Approx(41.25)); + CHECK(rs1.GetNumRanges() == 89); + + CHECK(rs1.OK() == true); +} + +TEST_CASE("Test RangeSet Inversion calculations", "[math]") +{ + emp::RangeSet rsd(10.5, 20.5); + + CHECK(rsd.GetNumRanges() == 1); + CHECK(rsd.Has(std::numeric_limits::lowest()) == false); + CHECK(rsd.Has(0.0) == false); + CHECK(rsd.Has(10.0) == false); + CHECK(rsd.Has(10.5) == true); + CHECK(rsd.Has(15.0) == true); + CHECK(rsd.Has(20.0) == true); + CHECK(rsd.Has(20.5) == false); + CHECK(rsd.Has(100.0) == false); + CHECK(rsd.Has(150.0) == false); + CHECK(rsd.Has(1000.0) == false); + + rsd.Invert(); + + CHECK(rsd.GetNumRanges() == 2); + CHECK(rsd.Has(std::numeric_limits::lowest()) == true); + CHECK(rsd.Has(0.0) == true); + CHECK(rsd.Has(10.0) == true); + CHECK(rsd.Has(10.5) == false); + CHECK(rsd.Has(15.0) == false); + CHECK(rsd.Has(20.0) == false); + CHECK(rsd.Has(20.5) == true); + CHECK(rsd.Has(100.0) == true); + CHECK(rsd.Has(150.0) == true); + CHECK(rsd.Has(1000.0) == true); + + rsd.RemoveRange(100.5, 200.5); + CHECK(rsd.GetNumRanges() == 3); + CHECK(rsd.Has(0.0) == true); + CHECK(rsd.Has(10.0) == true); + CHECK(rsd.Has(10.5) == false); + CHECK(rsd.Has(15.0) == false); + CHECK(rsd.Has(20.0) == false); + CHECK(rsd.Has(20.5) == true); + CHECK(rsd.Has(100.0) == true); + CHECK(rsd.Has(150.0) == false); + CHECK(rsd.Has(1000.0) == true); + + rsd.Invert(); + CHECK(rsd.GetNumRanges() == 2); + CHECK(rsd.Has(0.0) == false); + CHECK(rsd.Has(10.0) == false); + CHECK(rsd.Has(10.5) == true); + CHECK(rsd.Has(15.0) == true); + CHECK(rsd.Has(20.0) == true); + CHECK(rsd.Has(20.5) == false); + CHECK(rsd.Has(100.0) == false); + CHECK(rsd.Has(150.0) == true); + CHECK(rsd.Has(1000.0) == false); + + CHECK(rsd.OK() == true); +} + +TEST_CASE("Test RangeSet operators to behave like Bits", "[math]") +{ + using set_t = emp::RangeSet; + const set_t input1("00001111"); + const set_t input2("00110011"); + const set_t input3("01010101"); + + // Test *_SELF() Boolean Logic functions. + set_t bv; CHECK(bv.KeepOnly(0,8) == set_t("00000000")); + CHECK(bv.OK() == true); + bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("11111111")); + CHECK(bv.OK() == true); + bv &= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv &= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv &= input2; CHECK(bv.KeepOnly(0,8) == set_t("00000011")); + bv &= input3; CHECK(bv.KeepOnly(0,8) == set_t("00000001")); + + bv |= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv |= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv |= input3; CHECK(bv.KeepOnly(0,8) == set_t("01011111")); + bv |= input2; CHECK(bv.KeepOnly(0,8) == set_t("01111111")); + + bv &= input1; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("11110000")); + bv &= input1; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("11111111")); + bv &= input2; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("11001100")); + bv &= input3; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("10111011")); + + CHECK(bv.OK()); + CHECK(input1.OK()); + bv |= input1; + CHECK(bv.OK()); + bv.Invert(); + CHECK(bv.KeepOnly(0,8) == set_t("01000000")); + bv |= input1; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("10110000")); + bv |= input2; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("01001100")); + bv |= input3; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("10100010")); + + bv ^= input1; CHECK(bv.KeepOnly(0,8) == set_t("10101101")); + bv ^= input1; CHECK(bv.KeepOnly(0,8) == set_t("10100010")); + bv ^= input2; CHECK(bv.KeepOnly(0,8) == set_t("10010001")); + bv ^= input3; CHECK(bv.KeepOnly(0,8) == set_t("11000100")); + + bv ^= input1; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("00110100")); + bv ^= input1; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("11000100")); + bv ^= input2; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("00001000")); + bv ^= input3; bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("10100010")); + + CHECK(bv.OK() == true); + bv.Invert(); CHECK(bv.KeepOnly(0,8) == set_t("01011101")); + CHECK(bv.OK() == true); + + // Test regular Boolean Logic functions. + bv.Clear(); CHECK(bv.KeepOnly(0,8) == set_t("00000000")); + set_t bv1 = ~bv; CHECK(bv1.KeepOnly(0,8) == set_t("11111111")); + + bv1 = bv1 & input1; CHECK(bv1.KeepOnly(0,8) == set_t("00001111")); + set_t bv2 = bv1 & input1; CHECK(bv2.KeepOnly(0,8) == set_t("00001111")); + set_t bv3 = bv2 & input2; CHECK(bv3.KeepOnly(0,8) == set_t("00000011")); + set_t bv4 = bv3 & input3; CHECK(bv4.KeepOnly(0,8) == set_t("00000001")); + + bv1 = bv4 | input1; CHECK(bv1.KeepOnly(0,8) == set_t("00001111")); + bv2 = bv1 | input1; CHECK(bv2.KeepOnly(0,8) == set_t("00001111")); + bv3 = bv2 | input3; CHECK(bv3.KeepOnly(0,8) == set_t("01011111")); + bv4 = bv3 | input2; CHECK(bv4.KeepOnly(0,8) == set_t("01111111")); + + bv1 = bv4 & input1; bv1.Invert(); CHECK(bv1.KeepOnly(0,8) == set_t("11110000")); + bv2 = bv1 & input1; bv2.Invert(); CHECK(bv2.KeepOnly(0,8) == set_t("11111111")); + bv3 = bv2 & input2; bv3.Invert(); CHECK(bv3.KeepOnly(0,8) == set_t("11001100")); + bv4 = bv3 & input3; bv4.Invert(); CHECK(bv4.KeepOnly(0,8) == set_t("10111011")); + + bv1 = bv4 | input1; bv1.Invert(); CHECK(bv1.KeepOnly(0,8) == set_t("01000000")); + bv2 = bv1 | input1; bv2.Invert(); CHECK(bv2.KeepOnly(0,8) == set_t("10110000")); + bv3 = bv2 | input2; bv3.Invert(); CHECK(bv3.KeepOnly(0,8) == set_t("01001100")); + bv4 = bv3 | input3; bv4.Invert(); CHECK(bv4.KeepOnly(0,8) == set_t("10100010")); + + bv1 = bv4 ^ input1; CHECK(bv1.KeepOnly(0,8) == set_t("10101101")); + bv2 = bv1 ^ input1; CHECK(bv2.KeepOnly(0,8) == set_t("10100010")); + bv3 = bv2 ^ input2; CHECK(bv3.KeepOnly(0,8) == set_t("10010001")); + bv4 = bv3 ^ input3; CHECK(bv4.KeepOnly(0,8) == set_t("11000100")); + + bv1 = bv4 ^ input1; bv1.Invert(); CHECK(bv1.KeepOnly(0,8) == set_t("00110100")); + bv2 = bv1 ^ input1; bv2.Invert(); CHECK(bv2.KeepOnly(0,8) == set_t("11000100")); + bv3 = bv2 ^ input2; bv3.Invert(); CHECK(bv3.KeepOnly(0,8) == set_t("00001000")); + bv4 = bv3 ^ input3; bv4.Invert(); CHECK(bv4.KeepOnly(0,8) == set_t("10100010")); + + bv = ~bv4; CHECK(bv.KeepOnly(0,8) == set_t("01011101")); + + + // Test Boolean Logic operators. + bv.Clear(); CHECK(bv.KeepOnly(0,8) == set_t("00000000")); + bv1 = ~bv; CHECK(bv1.KeepOnly(0,8) == set_t("11111111")); + + bv1 = bv1 & input1; CHECK(bv1.KeepOnly(0,8) == set_t("00001111")); + bv2 = bv1 & input1; CHECK(bv2.KeepOnly(0,8) == set_t("00001111")); + bv3 = bv2 & input2; CHECK(bv3.KeepOnly(0,8) == set_t("00000011")); + bv4 = bv3 & input3; CHECK(bv4.KeepOnly(0,8) == set_t("00000001")); + + bv1 = bv4 | input1; CHECK(bv1.KeepOnly(0,8) == set_t("00001111")); + bv2 = bv1 | input1; CHECK(bv2.KeepOnly(0,8) == set_t("00001111")); + bv3 = bv2 | input3; CHECK(bv3.KeepOnly(0,8) == set_t("01011111")); + bv4 = bv3 | input2; CHECK(bv4.KeepOnly(0,8) == set_t("01111111")); + + bv1 = ~(bv4 & input1); CHECK(bv1.KeepOnly(0,8) == set_t("11110000")); + bv2 = ~(bv1 & input1); CHECK(bv2.KeepOnly(0,8) == set_t("11111111")); + bv3 = ~(bv2 & input2); CHECK(bv3.KeepOnly(0,8) == set_t("11001100")); + bv4 = ~(bv3 & input3); CHECK(bv4.KeepOnly(0,8) == set_t("10111011")); + + bv1 = ~(bv4 | input1); CHECK(bv1.KeepOnly(0,8) == set_t("01000000")); + bv2 = ~(bv1 | input1); CHECK(bv2.KeepOnly(0,8) == set_t("10110000")); + bv3 = ~(bv2 | input2); CHECK(bv3.KeepOnly(0,8) == set_t("01001100")); + bv4 = ~(bv3 | input3); CHECK(bv4.KeepOnly(0,8) == set_t("10100010")); + + bv1 = bv4 ^ input1; CHECK(bv1.KeepOnly(0,8) == set_t("10101101")); + bv2 = bv1 ^ input1; CHECK(bv2.KeepOnly(0,8) == set_t("10100010")); + bv3 = bv2 ^ input2; CHECK(bv3.KeepOnly(0,8) == set_t("10010001")); + bv4 = bv3 ^ input3; CHECK(bv4.KeepOnly(0,8) == set_t("11000100")); + + bv1 = ~(bv4 ^ input1); CHECK(bv1.KeepOnly(0,8) == set_t("00110100")); + bv2 = ~(bv1 ^ input1); CHECK(bv2.KeepOnly(0,8) == set_t("11000100")); + bv3 = ~(bv2 ^ input2); CHECK(bv3.KeepOnly(0,8) == set_t("00001000")); + bv4 = ~(bv3 ^ input3); CHECK(bv4.KeepOnly(0,8) == set_t("10100010")); + + bv = ~bv4; CHECK(bv.KeepOnly(0,8) == set_t("01011101")); + + CHECK(bv1.OK() == true); + CHECK(bv2.OK() == true); + CHECK(bv3.OK() == true); + CHECK(bv4.OK() == true); + + // Test COMPOUND Boolean Logic operators. + bv = std::string("11111111"); CHECK(bv.KeepOnly(0,8) == set_t("11111111")); + + bv &= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv &= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv &= input2; CHECK(bv.KeepOnly(0,8) == set_t("00000011")); + bv &= input3; CHECK(bv.KeepOnly(0,8) == set_t("00000001")); + + bv |= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv |= input1; CHECK(bv.KeepOnly(0,8) == set_t("00001111")); + bv |= input3; CHECK(bv.KeepOnly(0,8) == set_t("01011111")); + bv |= input2; CHECK(bv.KeepOnly(0,8) == set_t("01111111")); + + bv ^= input1; CHECK(bv.KeepOnly(0,8) == set_t("01110000")); + bv ^= input1; CHECK(bv.KeepOnly(0,8) == set_t("01111111")); + bv ^= input2; CHECK(bv.KeepOnly(0,8) == set_t("01001100")); + bv ^= input3; CHECK(bv.KeepOnly(0,8) == set_t("00011001")); + + // Shifting tests. + CHECK( (bv << 1).KeepOnly(0,8) == set_t("00001100")); + CHECK( (bv << 2).KeepOnly(0,8) == set_t("00000110")); + CHECK( (bv << 3).KeepOnly(0,8) == set_t("00000011")); + CHECK( (bv << 4).KeepOnly(0,8) == set_t("00000001")); + + CHECK( (bv >> 1).KeepOnly(0,8) == set_t("00110010")); + CHECK( (bv >> 2).KeepOnly(0,8) == set_t("01100100")); + CHECK( (bv >> 3).KeepOnly(0,8) == set_t("11001000")); + CHECK(bv.OK()); + CHECK((bv >> 4).OK()); + CHECK((bv >> 4).KeepOnly(0,8).OK()); + CHECK( (bv >> 4).KeepOnly(0,8) == set_t("10010000")); + + CHECK(bv.OK() == true); + + // Now some tests with bitvectors longer than one field. + const set_t bvl80("00110111000101110001011100010111000101110001011100010111000101110001011100010111"); + CHECK( bvl80.GetSize() == 41 ); + CHECK( bvl80 << 1 == + set_t("000110111000101110001011100010111000101110001011100010111000101110001011100010111") + ); + CHECK( bvl80 << 2 == + set_t("0000110111000101110001011100010111000101110001011100010111000101110001011100010111") + ); + CHECK( bvl80 << 63 == + set_t("00000000000000000000000000000000000000000000000000000000000000000110111000101110001011100010111000101110001011100010111000101110001011100010111") + ); + CHECK( bvl80 << 64 == + set_t("000000000000000000000000000000000000000000000000000000000000000000110111000101110001011100010111000101110001011100010111000101110001011100010111") + ); + CHECK( bvl80 << 65 == + set_t("0000000000000000000000000000000000000000000000000000000000000000000110111000101110001011100010111000101110001011100010111000101110001011100010111") + ); + + CHECK( bvl80 >> 1 == + set_t("01101110001011100010111000101110001011100010111000101110001011100010111000101110") + ); + CHECK( bvl80 >> 2 == + set_t("11011100010111000101110001011100010111000101110001011100010111000101110001011100") + ); + CHECK( bvl80 >> 63 == + set_t("10001011100010111000000000000000000000000000000000000000000000000000000000000000") + ); + + CHECK(bvl80.OK() == true); +} diff --git a/tests/math/combos.cpp b/tests/math/combos.cpp index cff03349f2..eaf5b5d5ef 100644 --- a/tests/math/combos.cpp +++ b/tests/math/combos.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file combos.cpp + * @file */ #include diff --git a/tests/math/distances.cpp b/tests/math/distances.cpp index 32ce90acc4..145f3fac54 100644 --- a/tests/math/distances.cpp +++ b/tests/math/distances.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file distances.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/math/info_theory.cpp b/tests/math/info_theory.cpp index bd1851ee17..e849cdc1cf 100644 --- a/tests/math/info_theory.cpp +++ b/tests/math/info_theory.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file info_theory.cpp + * @file */ #include diff --git a/tests/math/math.cpp b/tests/math/math.cpp index bfe00db7b3..21262bd563 100644 --- a/tests/math/math.cpp +++ b/tests/math/math.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file math.cpp + * @file */ #include @@ -32,8 +33,8 @@ TEST_CASE("Test Math", "[math]") REQUIRE( emp::Abs(emp::Ln(emp::Exp(5)) - 5) < 0.01); REQUIRE(emp::IntLog2(10) == 3); - // REQUIRE(emp::CountOnes(15) == 4); - // REQUIRE(emp::CountOnes(255) == 8); + REQUIRE(emp::CountOnes(15) == 4); + REQUIRE(emp::CountOnes(255) == 8); unsigned long long large = 0x8000000000000000; REQUIRE(emp::MaskHigh(1) == large); diff --git a/tests/math/random_utils.cpp b/tests/math/random_utils.cpp index 6fa3c938e7..5aa63b0dd6 100644 --- a/tests/math/random_utils.cpp +++ b/tests/math/random_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file random_utils.cpp + * @file */ #include diff --git a/tests/math/sequence_utils.cpp b/tests/math/sequence_utils.cpp index 36efc653cf..e936f6e126 100644 --- a/tests/math/sequence_utils.cpp +++ b/tests/math/sequence_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file sequence_utils.cpp + * @file */ #include diff --git a/tests/math/spatial_stats.cpp b/tests/math/spatial_stats.cpp index 782623368b..8a95b702b9 100644 --- a/tests/math/spatial_stats.cpp +++ b/tests/math/spatial_stats.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file spatial_stats.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/math/stats.cpp b/tests/math/stats.cpp index aa3ffbbab6..5527657569 100644 --- a/tests/math/stats.cpp +++ b/tests/math/stats.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file stats.cpp + * @file */ #include diff --git a/tests/meta/ConceptWrapper.cpp b/tests/meta/ConceptWrapper.cpp index 979499fa01..0d4574c0e1 100644 --- a/tests/meta/ConceptWrapper.cpp +++ b/tests/meta/ConceptWrapper.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ConceptWrapper.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/meta/FunInfo.cpp b/tests/meta/FunInfo.cpp index 13400dc538..3d770ede29 100644 --- a/tests/meta/FunInfo.cpp +++ b/tests/meta/FunInfo.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file FunInfo.cpp + * @file */ #define CATCH_CONFIG_MAIN diff --git a/tests/meta/TypeID.cpp b/tests/meta/TypeID.cpp index e5200e4edd..6302411970 100644 --- a/tests/meta/TypeID.cpp +++ b/tests/meta/TypeID.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file TypeID.cpp + * @file */ #include diff --git a/tests/meta/TypePack.cpp b/tests/meta/TypePack.cpp index 276f584b7b..a2adec16c8 100644 --- a/tests/meta/TypePack.cpp +++ b/tests/meta/TypePack.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file TypePack.cpp + * @file */ #include diff --git a/tests/meta/ValPack.cpp b/tests/meta/ValPack.cpp index 260a9ee242..e8000176b0 100644 --- a/tests/meta/ValPack.cpp +++ b/tests/meta/ValPack.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ValPack.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/meta/macro_math.cpp b/tests/meta/macro_math.cpp index 5885e5d233..b8ed348a5f 100644 --- a/tests/meta/macro_math.cpp +++ b/tests/meta/macro_math.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2018 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2018 - * - * @file macro_math.cpp + * @file */ #include diff --git a/tests/meta/macros.cpp b/tests/meta/macros.cpp index da217fc8f7..1526546bc0 100644 --- a/tests/meta/macros.cpp +++ b/tests/meta/macros.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020 - * - * @file macros.cpp + * @file */ #include diff --git a/tests/meta/meta.cpp b/tests/meta/meta.cpp index 4b48702182..dfd983e923 100644 --- a/tests/meta/meta.cpp +++ b/tests/meta/meta.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file meta.cpp + * @file */ #include diff --git a/tests/meta/reflection.cpp b/tests/meta/reflection.cpp index bf149e871d..ee2262331c 100644 --- a/tests/meta/reflection.cpp +++ b/tests/meta/reflection.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file reflection.cpp + * @file */ #include diff --git a/tests/meta/type_traits.cpp b/tests/meta/type_traits.cpp index 92ad1a6bd1..221b5ed1b9 100644 --- a/tests/meta/type_traits.cpp +++ b/tests/meta/type_traits.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file type_traits.cpp + * @file */ #include diff --git a/tests/scholar/Author.cpp b/tests/scholar/Author.cpp index 679aca915a..ca8791d9d2 100644 --- a/tests/scholar/Author.cpp +++ b/tests/scholar/Author.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Author.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/scholar/Bibliography.cpp b/tests/scholar/Bibliography.cpp index f3c8c41746..1047d7d498 100644 --- a/tests/scholar/Bibliography.cpp +++ b/tests/scholar/Bibliography.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Bibliography.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/scholar/Citation.cpp b/tests/scholar/Citation.cpp index 7de72a1c4e..c986168991 100644 --- a/tests/scholar/Citation.cpp +++ b/tests/scholar/Citation.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Citation.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/testing/unit_tests.cpp b/tests/testing/unit_tests.cpp index f7cc7fe056..ecfa034eb8 100644 --- a/tests/testing/unit_tests.cpp +++ b/tests/testing/unit_tests.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file unit_tests.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/text/EmphaticText.cpp b/tests/text/EmphaticText.cpp new file mode 100644 index 0000000000..c8ebd23770 --- /dev/null +++ b/tests/text/EmphaticText.cpp @@ -0,0 +1,77 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ +/** + * @file + */ + +#include +#include + +#include "third-party/Catch/single_include/catch2/catch.hpp" + +#include "emp/text/EmphaticEncoding.hpp" + +TEST_CASE("Testing EmphaticText", "[text]") { + emp::EmphaticText text("Test Text"); + REQUIRE(text.GetSize() == 9); + REQUIRE(text.GetText() == "Test Text"); + REQUIRE(text.Encode() == "Test Text"); + + // Try adding style. + text.Bold(5,9); + REQUIRE(text.GetSize() == 9); + REQUIRE(text.GetText() == "Test Text"); + REQUIRE(text.Encode() == "Test `*Text`*"); + + // Try appending. + text << " and more Text."; + REQUIRE(text.GetSize() == 24); + REQUIRE(text.GetText() == "Test Text and more Text."); + REQUIRE(text.Encode() == "Test `*Text`* and more Text."); + + // Try changing letters. + text[21] = 's'; + text[23] = 's'; + REQUIRE(text.GetSize() == 24); + REQUIRE(text.GetText() == "Test Text and more Tests"); + REQUIRE(text.Encode() == "Test `*Text`* and more Tests"); + + // Try making a change that involves style. + text[19] = text[5]; + REQUIRE(text.GetSize() == 24); + REQUIRE(text.GetText() == "Test Text and more Tests"); + REQUIRE(text.Encode() == "Test `*Text`* and more `*T`*ests"); + + // Try erasing the text. + text.Resize(0); + REQUIRE(text.GetSize() == 0); + REQUIRE(text.GetText() == ""); + REQUIRE(text.Encode() == ""); + REQUIRE(text.GetStyles().size() == 0); + + text << "This is `/`*Pre-`/formatted`* text."; + // REQUIRE(text.GetSize() == 27); + REQUIRE(text.GetText() == "This is Pre-formatted text."); + REQUIRE(text.Encode() == "This is `*`/Pre-`/formatted`* text."); + + emp::Text plain_text("The `* and `* here should not be converted."); + REQUIRE(plain_text.Encode() == "The `* and `* here should not be converted."); + + // Now let's bold the word "not". + plain_text.Bold(26,29); + + // Should not change the output of Encode(), just internal style. + REQUIRE(plain_text.Encode() == "The `* and `* here should not be converted."); + REQUIRE(plain_text[25].IsBold() == false); + REQUIRE(plain_text[26].IsBold() == true); + REQUIRE(plain_text[28].IsBold() == true); + REQUIRE(plain_text[29].IsBold() == false); + + // But if we put it into an HTML object, the style should be reflected. + emp::EmphaticText emphatic_text(plain_text); + REQUIRE(emphatic_text.GetText() == "The `* and `* here should not be converted."); + REQUIRE(emphatic_text.Encode() == "The \\`* and \\`* here should `*not`* be converted."); +} diff --git a/tests/text/HTMLText.cpp b/tests/text/HTMLText.cpp index 9bf9be02ee..f0b143e4c6 100644 --- a/tests/text/HTMLText.cpp +++ b/tests/text/HTMLText.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022-23. - * - * @file HTMLText.cpp + * @file */ #include @@ -11,7 +12,7 @@ #include "third-party/Catch/single_include/catch2/catch.hpp" -#include "emp/text/HTMLText.hpp" +#include "emp/text/HTMLEncoding.hpp" TEST_CASE("Testing HTMLText", "[text]") { emp::HTMLText text("Test Text"); @@ -83,4 +84,15 @@ TEST_CASE("Testing HTMLText", "[text]") { emp::HTMLText text2 = "Now let's try something with a non-breaking space."; REQUIRE(text2.GetText() == "Now let's try something with a non-breaking space."); REQUIRE(text2.Encode() == "Now let's try something with a non-breaking space."); + + // Play with merging and converting. + emp::HTMLText part1 = "Part 1 of text;"; + emp::HTMLText part2 = "And now part 2 of text."; + part1.Bold(5,6); + part2.Bold(13,14); + part2.Italic(18,22); + + emp::Text merged = emp::MakeHTMLText(part1, " ", part2); + REQUIRE(merged.GetText() == "Part 1 of text; And now part 2 of text."); + REQUIRE(merged.Encode() == "Part 1 of text; And now part 2 of text."); } diff --git a/tests/text/Text.cpp b/tests/text/Text.cpp index d874d7ad6e..e2ed21c048 100644 --- a/tests/text/Text.cpp +++ b/tests/text/Text.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022 - * - * @file Text.cpp + * @file */ #include diff --git a/tests/tools/Makefile b/tests/tools/Makefile index f3c2ecc844..654a1166cc 100644 --- a/tests/tools/Makefile +++ b/tests/tools/Makefile @@ -1,4 +1,4 @@ -TEST_NAMES = attrs char_utils hash_namify keyname_utils MemoryFactory ShortString SolveState String string_utils timing TypeTracker unique value_utils +TEST_NAMES = attrs char_utils hash_namify keyname_utils MemoryFactory StaticString SolveState String string_utils timing TypeTracker unique value_utils # -O3 -Wl,--stack,8388608 -ftrack-macro-expansion=0 FLAGS = -std=c++20 -g -pthread -Wall -Wextra -Wno-unused-function -Wno-unused-private-field -I../../include/ -I../../ -I../../third-party/cereal/include/ -DCATCH_CONFIG_MAIN diff --git a/tests/tools/MemoryFactory.cpp b/tests/tools/MemoryFactory.cpp index aabfb5e773..d841f8f102 100644 --- a/tests/tools/MemoryFactory.cpp +++ b/tests/tools/MemoryFactory.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file MemoryFactory.cpp + * @file */ #include "../third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/tools/ShortString.cpp b/tests/tools/ShortString.cpp deleted file mode 100644 index 30f0685e78..0000000000 --- a/tests/tools/ShortString.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2022. - * - * @file ShortString.cpp - */ - -#include "../third-party/Catch/single_include/catch2/catch.hpp" - -#include "emp/tools/ShortString.hpp" - -TEST_CASE("Test ShortString", "[tools]") -{ - emp::ShortString str1 = "ABC"; - CHECK( str1.size() == 3 ); - CHECK( str1[0] == 'A' ); - CHECK( str1[1] == 'B' ); - CHECK( str1[2] == 'C' ); - - CHECK( str1 == "ABC" ); - - std::string std_str = "DEFGH"; - - CHECK( str1 != std_str ); - CHECK( str1 < std_str ); - CHECK( str1 <= std_str ); - - CHECK( std_str != str1.AsString() ); - CHECK( std_str > str1.AsString() ); - CHECK( std_str >= str1.AsString() ); - - emp::ShortString str2(std_str); - - CHECK( str1 != str2 ); - CHECK( str1 < str2 ); - CHECK( str2 > str1 ); - CHECK( str1 <= str2 ); - CHECK( str2 >= str1 ); - - str1 = str2; - - CHECK( str1 == str2 ); - CHECK( str1 <= str2); - CHECK( str1 >= str2); -} diff --git a/tests/tools/SolveState.cpp b/tests/tools/SolveState.cpp index 4567fdd2ef..9344bd0c7d 100644 --- a/tests/tools/SolveState.cpp +++ b/tests/tools/SolveState.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file SolveState.cpp + * @file */ #include diff --git a/tests/tools/StaticString.cpp b/tests/tools/StaticString.cpp new file mode 100644 index 0000000000..bd6d5f3b0e --- /dev/null +++ b/tests/tools/StaticString.cpp @@ -0,0 +1,76 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2022 +*/ +/** + * @file + */ + +#include "../third-party/Catch/single_include/catch2/catch.hpp" + +#include "emp/tools/StaticString.hpp" + +TEST_CASE("ShortString comparisons", "[tools]") +{ + emp::ShortString str1 = "ABC"; + CHECK( str1.size() == 3 ); + CHECK( str1[0] == 'A' ); + CHECK( str1[1] == 'B' ); + CHECK( str1[2] == 'C' ); + + CHECK( str1 == "ABC" ); + + std::string std_str = "DEFGH"; + + CHECK( str1 != std_str ); + CHECK( str1 < std_str ); + CHECK( str1 <= std_str ); + + CHECK( std_str != str1.AsString() ); + CHECK( std_str > str1.AsString() ); + CHECK( std_str >= str1.AsString() ); + + emp::ShortString str2(std_str); + + CHECK( str1 != str2 ); + CHECK( str1 < str2 ); + CHECK( str2 > str1 ); + CHECK( str1 <= str2 ); + CHECK( str2 >= str1 ); + + str1 = str2; + + CHECK( str1 == str2 ); + CHECK( str1 <= str2); + CHECK( str1 >= str2); +} + +TEST_CASE("ShortString manipulations", "[tools]") +{ + emp::ShortString str1 = "ABC"; + CHECK(str1 == "ABC"); + str1[0] = 'D'; + CHECK(str1 == "DBC"); + str1[1] = 'E'; + CHECK(str1 == "DEC"); + str1[2] = 'F'; + CHECK(str1 == "DEF"); + + str1.push_back('G'); + CHECK(str1 == "DEFG"); + str1.push_back('H').push_back('I'); + CHECK(str1 == "DEFGHI"); + + str1 = "test:"; + str1.append("123"); + CHECK(str1 == "test:123"); + + std::string str456 = "456"; + str1.append(str456); + CHECK(str1 == "test:123456"); + + emp::ShortString str789 = "789"; + str1.append(str789); + CHECK(str1 == "test:123456789"); +} diff --git a/tests/tools/String.cpp b/tests/tools/String.cpp index d66b6becbc..02b2d203d3 100644 --- a/tests/tools/String.cpp +++ b/tests/tools/String.cpp @@ -1,15 +1,21 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2023. - * - * @file String.cpp + * @file */ -#include "../third-party/Catch/single_include/catch2/catch.hpp" +#include +#include +#include + +#include "third-party/Catch/single_include/catch2/catch.hpp" #include "emp/tools/String.hpp" + TEST_CASE("Test String Constructors", "[tools]") { const emp::String empty_str; @@ -31,8 +37,8 @@ TEST_CASE("Test String Constructors", "[tools]") CHECK(emp::MakeLiteral('\\') == "'\\\\'"); emp::String up = "A String!"; - CHECK(up.ToUpper() == "A STRING!"); - CHECK(up.ToLower() == "a string!"); + CHECK(up.AsUpper() == "A STRING!"); + CHECK(up.AsLower() == "a string!"); CHECK(emp::MakeRoman(50) == "L"); CHECK(emp::MakeRoman(562) == "DLXII"); @@ -42,7 +48,10 @@ TEST_CASE("Test String Constructors", "[tools]") CHECK(emp::MakeRoman(500000) == "D|"); CHECK(emp::MakeRoman(500000000) == "D||"); CHECK(emp::MakeRoman(500500500) == "D|D|D"); +} +TEST_CASE("Test String Composition-ID Functions", "[tools]") +{ emp::String abc = "aabcccabbcccabcbca"; CHECK(abc.IsComposedOf("abc")); CHECK(!abc.IsComposedOf("abx")); @@ -61,188 +70,288 @@ TEST_CASE("Test String Constructors", "[tools]") CHECK(emp::String("!@#$%^&*()0987654321").HasDigit()); CHECK(!emp::String("!@#$%^&*()abcdefg").HasDigit()); -/* - CHECK(emp::has_alphanumeric("all letters")); - CHECK(emp::has_alphanumeric("12345")); - CHECK(emp::has_alphanumeric("s0m3 l3tt3r5 @nd num83r5")); - CHECK(!emp::has_alphanumeric(")(!*#@&#^%&!")); - - CHECK(emp::has_one_of("abcdefghijklmnopqrstuvwxyz","aeiou")); - CHECK(emp::has_one_of("abcdefghijklmnopqrstuvwxyz","abc123")); - CHECK(!emp::has_one_of("abcdefghijklmnopqrstuvwxyz","12345")); - + CHECK(emp::String("all letters").HasAlphanumeric()); + CHECK(emp::String("12345").HasAlphanumeric()); + CHECK(emp::String("s0m3 l3tt3r5 @nd num83r5").HasAlphanumeric()); + CHECK(!emp::String(")(!*#@&#^%&!").HasAlphanumeric()); + + CHECK(emp::String("abcdefghijklmnopqrstuvwxyz").HasOneOf("aeiou")); + CHECK(emp::String("abcdefghijklmnopqrstuvwxyz").HasOneOf("abc123")); + CHECK(!emp::String("abcdefghijklmnopqrstuvwxyz").HasOneOf("12345")); + + CHECK(emp::String("391830581734").OnlyDigits()); + CHECK(!emp::String("3h91830581734").OnlyDigits()); + CHECK(!emp::String("3.14").OnlyDigits()); + CHECK(!emp::String("8.5e-6").OnlyDigits()); + CHECK(!emp::String("9e27").OnlyDigits()); + + CHECK(emp::String("391830581734").IsNumber()); + CHECK(!emp::String("3h91830581734").IsNumber()); + CHECK(emp::String("3.14").IsNumber()); + CHECK(emp::String("8.5e-6").IsNumber()); + CHECK(emp::String("9e27").IsNumber()); + CHECK(!emp::String("e").IsNumber()); + CHECK(!emp::String("-.e").IsNumber()); + CHECK(!emp::String("-4.5e").IsNumber()); + CHECK(emp::String("-4.5e+4").IsNumber()); + CHECK(!emp::String(".").IsNumber()); + CHECK(emp::String(".1").IsNumber()); + CHECK(!emp::String("1.").IsNumber()); + + CHECK(emp::String("39adg18af3tj05ykty81734").OnlyAlphanumeric()); + CHECK(!emp::String("39adg18af?3tj05ykty81734").OnlyAlphanumeric()); + + CHECK(emp::String("'f'").IsLiteralChar()); + CHECK(emp::String("' '").IsLiteralChar()); + CHECK(!emp::String("f").IsLiteralChar()); + CHECK(emp::String("'\n'").IsLiteralChar()); + CHECK(!emp::String("'\\'").IsLiteralChar()); + CHECK(emp::MakeFromLiteral_Char("'f'") == 'f'); + CHECK(emp::MakeFromLiteral_Char("'\n'") == '\n'); + + CHECK(emp::String("\"He llo!\"").IsLiteralString()); + CHECK(!emp::String("\"\\\\He\"llo!\"").IsLiteralString()); + CHECK(emp::String("\"Hel\n\t\r\\\'lo!\"").IsLiteralString()); + CHECK(emp::String("\"Hel\n \t \r \'lo!\"").IsLiteralString()); + CHECK(emp::MakeFromLiteral_String("\"Hello!\"") == "Hello!"); + CHECK(emp::MakeFromLiteral_String("\"Hel\n \t \r \'lo!\"") == "Hel\n \t \r \'lo!"); + + // Make sure that we can properly identify different types of characters. + const emp::String special_string = "This\t5tr1ng\nis\non THREE (3) \"lines\"."; + + CHECK(special_string.CountWhitespace() == 6); + CHECK(special_string.CountUpper() == 6); + CHECK(special_string.CountLower() == 16); + CHECK(special_string.CountLetters() == 22); + CHECK(special_string.CountDigits() == 3); + CHECK(special_string.CountAlphanumeric() == 25); + CHECK(special_string.CountNonwhitespace() == 30); + + /* CHECK(emp::is_valid("aaaaaaaaa", [](char x) { return (x == 'a'); } )); CHECK( !(emp::is_valid("aaaabaaaa", [](char x) { return (x == 'a'); })) ); +*/ +} - std::string start = "a string."; - CHECK(emp::string_pop_fixed(start, 9) == "a string."); - CHECK(start == ""); +TEST_CASE("Test String Find Functions", "[tools]") +{ + emp::String pal = "able was I ere I saw Elba"; + // Search for single characters. + CHECK(pal.Find('a') == 0); + CHECK(pal.Find('b') == 1); + CHECK(pal.Find('c') == std::string::npos); + CHECK(pal.Find('e') == 3); + CHECK(pal.Find('I') == 9); + CHECK(pal.Find('E') == 21); + + // Try with offset + CHECK(pal.Find('a', 10) == 18); + CHECK(pal.Find('b', 10) == 23); + CHECK(pal.Find('c', 10) == std::string::npos); + CHECK(pal.Find('e', 10) == 11); + CHECK(pal.Find('I', 10) == 15); + CHECK(pal.Find('E', 10) == 21); + + // Try reversed. + CHECK(pal.RFind('a') == 24); + CHECK(pal.RFind('b') == 23); + CHECK(pal.RFind('c') == std::string::npos); + CHECK(pal.RFind('e') == 13); + CHECK(pal.RFind('I') == 15); + CHECK(pal.RFind('E') == 21); + + // Try reversed with offset. + CHECK(pal.RFind('a', 20) == 18); + CHECK(pal.RFind('b', 20) == 1); + CHECK(pal.RFind('c', 20) == std::string::npos); + CHECK(pal.RFind('e', 20) == 13); + CHECK(pal.RFind('I', 20) == 15); + CHECK(pal.RFind('E', 20) == std::string::npos); + + // Try string Find. + CHECK(pal.Find("able") == 0); + CHECK(pal.Find("was") == 5); + CHECK(pal.Find("I") == 9); + CHECK(pal.Find("able", 5) == std::string::npos); + CHECK(pal.Find("was", 5) == 5); + CHECK(pal.Find("I", 10) == 15); + CHECK(pal.RFind("able") == 0); + CHECK(pal.RFind("was") == 5); + CHECK(pal.RFind("I") == 15); + + // Try CharSet Find. + CHECK(pal.Find(emp::LowerCharSet()) == 0); + CHECK(pal.Find(emp::WhitespaceCharSet()) == 4); + CHECK(pal.Find(emp::UpperCharSet()) == 9); + CHECK(pal.Find(emp::UpperCharSet(), 10) == 15); + CHECK(pal.Find(emp::UpperCharSet(), 16) == 21); + CHECK(pal.RFind(emp::UpperCharSet()) == 21); + CHECK(pal.RFind(emp::UpperCharSet(), 20) == 15); + CHECK(pal.RFind(emp::UpperCharSet(), 10) == 9); + CHECK(pal.RFind(emp::UpperCharSet(), 5) == std::string::npos); - CHECK(emp::string_get("John Doe"," ") == "John"); - CHECK(emp::string_get_line("Line1\nLine2\nLine3") == "Line1"); + // Do some tests on quotes in strings... + emp::String quotes = "\"abc\"\"def\"123 \"\"\"long\\\"er\""; // "abc""def"123 """long\"er" + CHECK( quotes.FindQuoteMatch() == 4 ); + CHECK( quotes.FindQuoteMatch(1) == std::string::npos ); + CHECK( quotes.FindQuoteMatch(5) == 9 ); + CHECK( quotes.FindQuoteMatch(10) == std::string::npos ); + CHECK( quotes.FindQuoteMatch(14) == 15 ); + CHECK( quotes.FindQuoteMatch(16) == 25 ); + + CHECK( quotes.RFindQuoteMatch(4) == 0 ); + CHECK( quotes.RFindQuoteMatch(9) == 5 ); + CHECK( quotes.RFindQuoteMatch(15) == 14 ); + CHECK( quotes.RFindQuoteMatch(25) == 16 ); - std::string hello = "!!h&&e#l!!&l###o&!!"; - emp::remove_chars(hello, "!&#"); - CHECK(hello == "hello"); + // Do some tests on parentheses matching... + emp::String parens = "(()(()()))((())\")))))()\")"; + CHECK( parens.FindParenMatch() == 9 ); + CHECK( parens.FindParenMatch(0) == 9 ); + CHECK( parens.FindParenMatch(1) == 2 ); + CHECK( parens.FindParenMatch(2) == std::string::npos ); + CHECK( parens.FindParenMatch(3) == 8 ); + CHECK( parens.FindParenMatch(10) == 16 ); + CHECK( parens.FindParenMatch(11) == 14 ); + CHECK( parens.FindParenMatch(21) == 22 ); // Works inside a quote if start there. + CHECK( parens.FindParenMatch(10,{"","()"}) == 16 ); // Specify parens and show works. + CHECK( parens.FindParenMatch(10,{"\"","()"}) == 24 ); // Do not ignore quotes. + CHECK( parens.FindParenMatch(10,{"","ab"}) == std::string::npos ); // Using non-parens works. + CHECK( quotes.FindParenMatch(1,{"","ab"}) == 2 ); // Using non-parens works. + + CHECK( parens.RFindParenMatch(9) == 0 ); + CHECK( parens.RFindParenMatch(2) == 1 ); + CHECK( parens.RFindParenMatch(8) == 3 ); + CHECK( parens.RFindParenMatch(16) == 10 ); + CHECK( parens.RFindParenMatch(14) == 11 ); + CHECK( parens.RFindParenMatch(22) == 21 ); // Works inside a quote if start there. - std::string email = "you@example.com"; - emp::remove_punctuation(email); - CHECK(email == "youexamplecom"); + // Extra tests with braces and single quotes. + emp::String braces = "{{}{}}{'{}}'}"; + CHECK( braces.FindParenMatch(0) == 5 ); + CHECK( braces.FindParenMatch(0,{"","{}"}) == 5 ); + CHECK( braces.FindParenMatch(1,{"","{}"}) == 2 ); + CHECK( braces.FindParenMatch(2,{"","{}"}) == std::string::npos ); + CHECK( braces.FindParenMatch(3,{"","{}"}) == 4 ); + CHECK( braces.FindParenMatch(6,{"","{}"}) == 10 ); // Across single quotes + CHECK( braces.FindParenMatch(6,{"'","{}"}) == 12 ); // Don't ignore quotes. - emp::vector numbers; - numbers.push_back("1"); - numbers.push_back("2"); - numbers.push_back("3"); - emp::vector int_numbers = emp::from_strings(numbers); - CHECK(int_numbers[0] == 1); - CHECK(int_numbers[1] == 2); - CHECK(int_numbers[2] == 3); - - CHECK(emp::is_digits("391830581734")); - CHECK(!emp::is_digits("3h91830581734")); - CHECK(!emp::is_digits("3.14")); - CHECK(!emp::is_digits("8.5e-6")); - CHECK(!emp::is_digits("9e27")); - - CHECK(emp::is_number("391830581734")); - CHECK(!emp::is_number("3h91830581734")); - CHECK(emp::is_number("3.14")); - CHECK(emp::is_number("8.5e-6")); - CHECK(emp::is_number("9e27")); - CHECK(!emp::is_number("e")); - CHECK(!emp::is_number("-.e")); - CHECK(!emp::is_number("-4.5e")); - CHECK(emp::is_number("-4.5e+4")); - CHECK(!emp::is_number(".")); - CHECK(emp::is_number(".1")); - CHECK(!emp::is_number("1.")); - - CHECK(emp::is_alphanumeric("39adg18af3tj05ykty81734")); - CHECK(!emp::is_alphanumeric("39adg18af?3tj05ykty81734")); - - CHECK(emp::is_literal_char("'f'")); - CHECK(emp::is_literal_char("' '")); - CHECK(!emp::is_literal_char("f")); - CHECK(emp::is_literal_char("'\n'")); - CHECK(!emp::is_literal_char("'\\'")); - CHECK(emp::from_literal_char("'f'") == 'f'); - CHECK(emp::from_literal_char("'\n'") == '\n'); - CHECK(emp::is_literal_string("\"He llo!\"")); - CHECK(!emp::is_literal_string("\"\\\\He\"llo!\"")); - CHECK(emp::is_literal_string("\"Hel\n\t\r\\\'lo!\"")); - CHECK(emp::is_literal_string("\"Hel\n \t \r \'lo!\"")); - CHECK(emp::from_literal_string("\"Hello!\"") == "Hello!"); - CHECK(emp::from_literal_string("\"Hel\n \t \r \'lo!\"") == "Hel\n \t \r \'lo!"); - - // TODO: try this with more arguments - int one; - emp::from_string("1", one); - CHECK(one == 1); - */ + // Test a multi-find. + emp::String test_str = "This is my best test!"; + emp::vector found = test_str.FindAll(' '); + CHECK( found == emp::vector{4,7,10,15} ); + test_str.FindAll('i', found); + CHECK( found == emp::vector{2,5} ); + parens.FindAll(')', found); + CHECK( found == emp::vector{2,5,7,8,9,13,14,16,17,18,19,20,22,24} ); + parens.FindAll(')', found, "\""); // Ignore items in quotes. + CHECK( found == emp::vector{2,5,7,8,9,13,14,24} ); } -/* -TEST_CASE("Another Test string_utils", "[tools]") +TEST_CASE("Test String Pop and Slice Functions", "[tools]") { + emp::String start = "a string."; + CHECK(start.PopFixed(9) == "a string."); + CHECK(start == ""); - // TEST1: lets test our conversion to an escaped string. - const std::string special_string = "This\t5tr1ng\nis\non THREE (3) \"lines\"."; - std::string escaped_string = emp::to_escaped_string(special_string); + start = "This is a slightly longer string"; + auto split = start.Slice(" "); + CHECK(split.size() == 6); + CHECK(split[0] == "This"); + CHECK(split[5] == "string"); + + start = "This string has \"internal quotes\" that shouldn't be split."; + split = start.Slice(" ", {"\""}); // Slice, but keep quotes as one unit. + for (auto x : split) { std::cout << ":" << x << ": "; } std::cout << std::endl; + CHECK(split.size() == 8); + CHECK(split[0] == "This"); + CHECK(split[3] == "\"internal quotes\""); + CHECK(split[5] == "shouldn't"); +} - // note: we had to double-escape the test to make sure this worked. - CHECK(escaped_string == "This\\t5tr1ng\\nis\\non THREE (3) \\\"lines\\\"."); +TEST_CASE("Test String Removal Functions", "[tools]") +{ - // TEST2: Test more general conversion to literals. - CHECK(emp::to_literal(42) == "42"); - CHECK(emp::to_literal('a') == "'a'"); - CHECK(emp::to_literal('\t') == "'\\t'"); - CHECK(emp::to_literal(1.234) == "1.234000"); - - // TEST3: Make sure that we can properly identify different types of characters. - int num_ws = 0; - int num_cap = 0; - int num_lower = 0; - int num_let = 0; - int num_num = 0; - int num_alphanum = 0; - int num_i = 0; - int num_vowel = 0; - for (char cur_char : special_string) { - if (emp::is_whitespace(cur_char)) num_ws++; - if (emp::is_upper_letter(cur_char)) num_cap++; - if (emp::is_lower_letter(cur_char)) num_lower++; - if (emp::is_letter(cur_char)) num_let++; - if (emp::is_digit(cur_char)) num_num++; - if (emp::is_alphanumeric(cur_char)) num_alphanum++; - if (emp::is_valid(cur_char, [](char c){ return c=='i'; })) num_i++; - if (emp::is_valid(cur_char, [](char c){return c=='a' || c=='A';}, - [](char c){return c=='e' || c=='E';}, - [](char c){return c=='i' || c=='I';}, - [](char c){return c=='o' || c=='O';}, - [](char c){return c=='u' || c=='U';}, - [](char c){return c=='y';} - )) num_vowel++; - } - int num_other = ((int) special_string.size()) - num_alphanum - num_ws; - - - CHECK(num_ws == 6); - CHECK(num_cap == 6); - CHECK(num_lower == 16); - CHECK(num_let == 22); - CHECK(num_num == 3); - CHECK(num_alphanum == 25); - CHECK(num_other == 5); - CHECK(num_i == 3); - CHECK(num_vowel == 7); - - std::string base_string = "This is an okay string.\n \tThis\nis -MY- very best string!!!! "; + emp::String hello = "!!h&&e#l!!&l###o&!!"; + hello.RemoveChars("!&#"); + CHECK(hello == "hello"); - CHECK( - emp::slugify(base_string) - == "this-is-an-okay-string-this-is-my-very-best-string" - ); + emp::String email = "you@example.com"; + email.RemovePunctuation(); + CHECK(email == "youexamplecom"); +} - std::string first_line = emp::string_pop_line(base_string); +TEST_CASE("Test String Conversion Functions", "[tools]") +{ + // Test conversion to an escaped string. + const emp::String special_string = "This\t5tr1ng\nis\non THREE (3) \"lines\"."; + emp::String escaped_string = emp::MakeEscaped(special_string); - CHECK(first_line == "This is an okay string."); - CHECK(emp::string_get_word(first_line) == "This"); + // note: we had to double-escape the test to make sure this worked. + CHECK(escaped_string == "This\\t5tr1ng\\nis\\non THREE (3) \\\"lines\\\"."); - emp::string_pop_word(first_line); + // Test more general conversion to literals. + CHECK(emp::MakeLiteral(42) == "42"); + CHECK(emp::MakeLiteral('a') == "'a'"); + CHECK(emp::MakeLiteral('\t') == "'\\t'"); + CHECK(emp::MakeLiteral(1.234) == "1.234"); - CHECK(first_line == "is an okay string."); + CHECK(special_string.AsEscaped() == escaped_string); + CHECK(special_string.AsEscaped() == escaped_string); - emp::remove_whitespace(first_line); + emp::String base_string = "This is an okay string.\n \tThis\nis -MY- very best string!!!! "; - CHECK(first_line == "isanokaystring."); + CHECK(emp::MakeSlugify(base_string) == "this-is-an-okay-string-this-is-my-very-best-string"); - std::string popped_str = emp::string_pop(first_line, "ns"); + emp::String first_line = base_string.PopLine(); - CHECK(popped_str == "i"); - CHECK(first_line == "anokaystring."); + CHECK(first_line == "This is an okay string."); + CHECK(first_line.ViewWord() == "This"); + CHECK(first_line.PopWord() == "This"); + CHECK(first_line == "is an okay string."); - popped_str = emp::string_pop(first_line, "ns"); + CHECK(first_line.RemoveWhitespace() == "isanokaystring."); + CHECK(first_line.Pop("ns") == "i"); + CHECK(first_line == "anokaystring."); + emp::String popped_str = first_line.Pop("ns"); CHECK(popped_str == "a"); CHECK(first_line == "okaystring."); - - popped_str = emp::string_pop(first_line, 'y'); - + popped_str = first_line.Pop('y'); CHECK(popped_str == "oka"); CHECK(first_line == "string."); - emp::left_justify(base_string); - CHECK(base_string == "This\nis -MY- very best string!!!! "); + CHECK(base_string.TrimFront() == "This\nis -MY- very best string!!!! "); + CHECK(base_string.TrimBack() == "This\nis -MY- very best string!!!!"); + CHECK(base_string.Compress() == "This is -MY- very best string!!!!"); +} - emp::right_justify(base_string); - CHECK(base_string == "This\nis -MY- very best string!!!!"); - emp::compress_whitespace(base_string); - CHECK(base_string == "This is -MY- very best string!!!!"); +TEST_CASE("Test Stirng assign and Macro functions", "[tools]") +{ + emp::String test = "TIMES(abc,3) + TIMES(def,2) + TIMES(g, 8)"; + test.ReplaceMacro("TIMES(", ")", + [](emp::String check_body, size_t, size_t) { + emp::String pattern = check_body.Pop(','); + size_t count = check_body.As(); + return pattern * count; + }); + + CHECK(test == "abcabcabc + defdef + gggggggg"); + + test = "MACRO(ABC);\n MACRO(\"DEF\");\n MACRO( \"([{\");\n and normal;"; + test.ReplaceMacro("MACRO(", ")", + [](emp::String check_body, size_t, size_t) { return emp::MakeString("[[[", check_body, "]]]"); } + ); + CHECK(test == "[[[ABC]]];\n [[[\"DEF\"]]];\n [[[ \"([{\"]]];\n and normal;"); +} +/* +TEST_CASE("Another Test string_utils", "[tools]") +{ std::string view_test = "This is my view test!"; CHECK( emp::view_string(view_test) == "This is my view test!" ); @@ -254,15 +363,6 @@ TEST_CASE("Another Test string_utils", "[tools]") CHECK( emp::view_string_to(view_test, ' ') == "This" ); CHECK( emp::view_string_to(view_test, ' ', 5) == "is" ); - // Do some tests on quotes in strings... - std::string quotes = "\"abc\"\"def\"123 \"\"\"long\\\"er\""; // "abc""def"123 """long\"er" - CHECK( emp::find_quote_match(quotes) == 4 ); - CHECK( emp::find_quote_match(quotes, 1) == 1 ); - CHECK( emp::find_quote_match(quotes, 5) == 9 ); - CHECK( emp::find_quote_match(quotes, 10) == 10 ); - CHECK( emp::find_quote_match(quotes, 14) == 15 ); - CHECK( emp::find_quote_match(quotes, 16) == 25 ); - CHECK( emp::string_pop_quote(quotes) == "\"abc\""); CHECK( emp::string_pop_quote(quotes) == "\"def\""); CHECK( emp::string_pop_quote(quotes) == ""); @@ -271,39 +371,6 @@ TEST_CASE("Another Test string_utils", "[tools]") CHECK( emp::string_pop_quote(quotes) == "\"long\\\"er\""); CHECK( emp::string_pop_quote(quotes) == ""); - // Do some tests on parentheses matching... - std::string parens = "(()(()()))((())\")))))()\")"; - CHECK( emp::find_paren_match(parens) == 9 ); - CHECK( emp::find_paren_match(parens, 0) == 9 ); - CHECK( emp::find_paren_match(parens, 1) == 2 ); - CHECK( emp::find_paren_match(parens, 2) == 2 ); - CHECK( emp::find_paren_match(parens, 3) == 8 ); - CHECK( emp::find_paren_match(parens, 3) == 8 ); - CHECK( emp::find_paren_match(parens, 10) == 24 ); - CHECK( emp::find_paren_match(parens, 11) == 14 ); - CHECK( emp::find_paren_match(parens, 21) == 22 ); // Works inside a quote if start there. - CHECK( emp::find_paren_match(parens, 10,'(',')',true) == 24 ); // Specify parens and show works. - CHECK( emp::find_paren_match(parens, 10,'(',')',false) == 16 ); // Do no ignore quotes. - CHECK( emp::find_paren_match(parens, 10,'a','b',false) == 10 ); // Using non-parens works. - - // Extra tests with braces and single quotes. - std::string braces = "{{}{}}{'{}}'}"; - CHECK( emp::find_paren_match(braces, 0) == 0 ); - CHECK( emp::find_paren_match(braces, 0, '{', '}') == 5 ); - CHECK( emp::find_paren_match(braces, 1, '{', '}') == 2 ); - CHECK( emp::find_paren_match(braces, 3, '{', '}') == 4 ); - CHECK( emp::find_paren_match(braces, 6, '{', '}') == 12 ); // Across single quotes - CHECK( emp::find_paren_match(braces, 6, '{', '}', false) == 10 ); // Don't ignore quotes. - - // Test a multi-find. - emp::vector found = emp::find_all(view_test, ' '); - CHECK( found == emp::vector{4,7,10,15} ); - emp::find_all(view_test, 'i', found); - CHECK( found == emp::vector{2,5,12} ); - emp::find_all(parens, ')', found); - CHECK( found == emp::vector{2,5,7,8,9,13,14,16,17,18,19,20,22,24} ); - emp::find_all(parens, ')', found, true); // Ignore items in quotes. - CHECK( found == emp::vector{2,5,7,8,9,13,14,24} ); emp::vector slice_view = emp::view_slices(view_test, ' '); CHECK( slice_view.size() == 5 ); diff --git a/tests/tools/TypeTracker.cpp b/tests/tools/TypeTracker.cpp index 81b302d40b..f758c88149 100644 --- a/tests/tools/TypeTracker.cpp +++ b/tests/tools/TypeTracker.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file TypeTracker.cpp + * @file */ #include diff --git a/tests/tools/attrs.cpp b/tests/tools/attrs.cpp index c6918090ab..71779add50 100644 --- a/tests/tools/attrs.cpp +++ b/tests/tools/attrs.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file attrs.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/tools/char_utils.cpp b/tests/tools/char_utils.cpp index 0b236d3651..f3437ff519 100644 --- a/tests/tools/char_utils.cpp +++ b/tests/tools/char_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2022 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021-2022. - * - * @file char_utils.cpp + * @file */ #include "../third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/tools/hash_namify.cpp b/tests/tools/hash_namify.cpp index d5f3cec7be..d0c9e24727 100644 --- a/tests/tools/hash_namify.cpp +++ b/tests/tools/hash_namify.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file hash_namify.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/tools/keyname_utils.cpp b/tests/tools/keyname_utils.cpp index 729b7c2376..923fd5804d 100644 --- a/tests/tools/keyname_utils.cpp +++ b/tests/tools/keyname_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file keyname_utils.cpp + * @file */ #include @@ -30,58 +31,53 @@ TEST_CASE("Test keyname_utils", "[tools]") name = "seed=100+foobar=20+_hash=asdf+ext=.txt"; goal["_"] = name; - REQUIRE( emp::keyname::unpack(name) == goal ); + CHECK( emp::keyname::unpack(name) == goal ); // reorderings name = "foobar=20+seed=100+_hash=asdf+ext=.txt"; goal["_"] = name; - REQUIRE( emp::keyname::unpack(name) == goal ); + CHECK( emp::keyname::unpack(name) == goal ); name = "_hash=asdf+foobar=20+seed=100+ext=.txt"; goal["_"] = name; - REQUIRE( emp::keyname::unpack(name) == goal ); + CHECK( emp::keyname::unpack(name) == goal ); // should ignore path name = "path/seed=100+foobar=20+_hash=asdf+ext=.txt"; goal["_"] = name; - REQUIRE( emp::keyname::unpack(name) == goal ); + CHECK( emp::keyname::unpack(name) == goal ); name = "~/more=path/+blah/seed=100+foobar=20+_hash=asdf+ext=.txt"; goal["_"] = name; - REQUIRE( emp::keyname::unpack(name) == goal ); + CHECK( emp::keyname::unpack(name) == goal ); name = "just/a/regular/file.pdf"; - REQUIRE( emp::keyname::unpack(name) == (emp::keyname::unpack_t{ + CHECK( emp::keyname::unpack(name) == (emp::keyname::unpack_t{ {"file.pdf", ""}, {"_", "just/a/regular/file.pdf"} })); name = "key/with/no+=value/file+ext=.pdf"; - REQUIRE( emp::keyname::unpack(name) == (emp::keyname::unpack_t{ + CHECK( emp::keyname::unpack(name) == (emp::keyname::unpack_t{ {"file", ""}, {"ext", ".pdf"}, {"_", "key/with/no+=value/file+ext=.pdf"} })); name = "multiple/=s/file=biz=blah+ext=.pdf"; - auto res = emp::keyname::unpack(name); - std::cout << res["file"] << std::endl; - std::cout << res["ext"] << std::endl; - std::cout << res["_"] << std::endl; - REQUIRE( res == (emp::keyname::unpack_t{ + CHECK( emp::keyname::unpack(name) == (emp::keyname::unpack_t{ {"file", "biz=blah"}, {"ext", ".pdf"}, {"_", "multiple/=s/file=biz=blah+ext=.pdf"} })); - // test pack - // reorderings - REQUIRE( (emp::keyname::pack({ + // test pack reorderings + CHECK( (emp::keyname::pack({ {"seed", "100"}, {"foobar", "20"}, {"_hash", "asdf"}, @@ -89,7 +85,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=20+seed=100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"_hash", "asdf"}, {"seed", "100"}, {"foobar", "20"}, @@ -97,7 +93,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=20+seed=100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"_hash", "asdf"}, {"foobar", "20"}, {"ext", ".txt"}, @@ -106,7 +102,7 @@ TEST_CASE("Test keyname_utils", "[tools]") ); // different values - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"seed", "100"}, {"foobar", "blip"}, {"_hash", "asdf"}, @@ -114,7 +110,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=blip+seed=100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"seed", "a100"}, {"foobar", "blip"}, {"_hash", "asdf"}, @@ -122,7 +118,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=blip+seed=a100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"aseed", "a100"}, {"foobar", "blip"}, {"_hash", "asdf"}, @@ -131,7 +127,7 @@ TEST_CASE("Test keyname_utils", "[tools]") ); // should ignore "_" key - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"seed", "100"}, {"foobar", "20"}, {"_hash", "asdf"}, @@ -140,7 +136,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=20+seed=100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"seed", "100"}, {"foobar", "20"}, {"_hash", "asdf"}, @@ -149,7 +145,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=20+seed=100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"seed", "100"}, {"foobar", "20"}, {"_hash", "asdf"}, @@ -158,7 +154,7 @@ TEST_CASE("Test keyname_utils", "[tools]") })) == "foobar=20+seed=100+_hash=asdf+ext=.txt" ); - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"seed", "100"}, {"foobar", "20"}, {"_hash", "asdf"}, @@ -168,7 +164,7 @@ TEST_CASE("Test keyname_utils", "[tools]") ); // missing extension - REQUIRE( (emp::keyname::pack({ + CHECK( (emp::keyname::pack({ {"_hash", "asdf"}, {"foobar", "20"}, {"seed", "100"} diff --git a/tests/tools/string_utils.cpp b/tests/tools/string_utils.cpp index 2f3e408ac9..161ee4b718 100644 --- a/tests/tools/string_utils.cpp +++ b/tests/tools/string_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020-2023 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020-2023. - * - * @file string_utils.cpp + * @file */ #include "../third-party/Catch/single_include/catch2/catch.hpp" @@ -384,7 +385,7 @@ TEST_CASE("Another Test string_utils", "[tools]") slices = emp::slice( "This is a test.", ' ', - 0 + 1 ); CHECK(slices.size() == 1); CHECK(slices[0] == "This is a test."); @@ -393,7 +394,7 @@ TEST_CASE("Another Test string_utils", "[tools]") slices = emp::slice( "This is a test.", ' ', - 1 + 2 ); CHECK(slices.size() == 2); CHECK(slices[0] == "This"); @@ -403,7 +404,7 @@ TEST_CASE("Another Test string_utils", "[tools]") slices = emp::slice( "This is a test.", ' ', - 2 + 3 ); CHECK(slices.size() == 3); CHECK(slices[0] == "This"); diff --git a/tests/tools/timing.cpp b/tests/tools/timing.cpp index f0fa91d43a..5f24037602 100644 --- a/tests/tools/timing.cpp +++ b/tests/tools/timing.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file timing.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/tools/unique.cpp b/tests/tools/unique.cpp index 9bf98b57c0..4300557e31 100644 --- a/tests/tools/unique.cpp +++ b/tests/tools/unique.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file unique.cpp + * @file */ #include diff --git a/tests/tools/value_utils.cpp b/tests/tools/value_utils.cpp index f61b0094c6..b6d63d08ea 100644 --- a/tests/tools/value_utils.cpp +++ b/tests/tools/value_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file value_utils.cpp + * @file */ #include "third-party/Catch/single_include/catch2/catch.hpp" diff --git a/tests/web/Card.cpp b/tests/web/Card.cpp index d759516406..60d05b15d6 100644 --- a/tests/web/Card.cpp +++ b/tests/web/Card.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Card.cpp + * @file */ #include diff --git a/tests/web/ClickCollapseDemo.cpp b/tests/web/ClickCollapseDemo.cpp index 3b525c060f..48425c02c1 100644 --- a/tests/web/ClickCollapseDemo.cpp +++ b/tests/web/ClickCollapseDemo.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file ClickCollapseDemo.cpp + * @file * @brief This file can be used to test triggering a mouse click by the user. * * It appears that .click() can be used to trigger a click. diff --git a/tests/web/ClickCounterDemo.cpp b/tests/web/ClickCounterDemo.cpp index 1c0896b8b6..56cc7b6a14 100644 --- a/tests/web/ClickCounterDemo.cpp +++ b/tests/web/ClickCounterDemo.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file ClickCounterDemo.cpp + * @file * @brief This file provides a simple example of clicking a web * element at multiple points within a test. * diff --git a/tests/web/CodeBlock.cpp b/tests/web/CodeBlock.cpp index b3b38695b3..70ec4c0f74 100644 --- a/tests/web/CodeBlock.cpp +++ b/tests/web/CodeBlock.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file CodeBlock.cpp + * @file */ #include diff --git a/tests/web/Collapse.cpp b/tests/web/Collapse.cpp index 5b6392eadc..76ab33d5c0 100644 --- a/tests/web/Collapse.cpp +++ b/tests/web/Collapse.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Collapse.cpp + * @file */ #include diff --git a/tests/web/CommentBox.cpp b/tests/web/CommentBox.cpp index 13c143e6d5..eaddb47544 100644 --- a/tests/web/CommentBox.cpp +++ b/tests/web/CommentBox.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file CommentBox.cpp + * @file */ #include diff --git a/tests/web/ConfigPanel.cpp b/tests/web/ConfigPanel.cpp index 00cced7825..72460a5ffd 100644 --- a/tests/web/ConfigPanel.cpp +++ b/tests/web/ConfigPanel.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file ConfigPanel.cpp + * @file */ #include diff --git a/tests/web/Element.cpp b/tests/web/Element.cpp index 2f5670a05f..3d0ffeea66 100644 --- a/tests/web/Element.cpp +++ b/tests/web/Element.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Element.cpp + * @file */ #include diff --git a/tests/web/FontAwesomeIcon.cpp b/tests/web/FontAwesomeIcon.cpp index a4ecb76640..d44703bea8 100644 --- a/tests/web/FontAwesomeIcon.cpp +++ b/tests/web/FontAwesomeIcon.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file FontAwesomeIcon.cpp + * @file */ #include diff --git a/tests/web/GetUrlParams.cpp b/tests/web/GetUrlParams.cpp index 7ef5ce7880..4716af77db 100644 --- a/tests/web/GetUrlParams.cpp +++ b/tests/web/GetUrlParams.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2019 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2019 - * - * @file GetUrlParams.cpp + * @file */ #include diff --git a/tests/web/JSWrap.cpp b/tests/web/JSWrap.cpp index ce41ca2d29..96d9114f3a 100644 --- a/tests/web/JSWrap.cpp +++ b/tests/web/JSWrap.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2015-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2015-2020 - * - * @file JSWrap.cpp + * @file */ #include diff --git a/tests/web/LoadingIcon.cpp b/tests/web/LoadingIcon.cpp index 70cc1067ec..e375f2eba6 100644 --- a/tests/web/LoadingIcon.cpp +++ b/tests/web/LoadingIcon.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file LoadingIcon.cpp + * @file */ #include diff --git a/tests/web/LoadingModal.cpp b/tests/web/LoadingModal.cpp index c0104b7d9a..afd0058dc6 100644 --- a/tests/web/LoadingModal.cpp +++ b/tests/web/LoadingModal.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file LoadingModal.cpp + * @file */ #include diff --git a/tests/web/Modal.cpp b/tests/web/Modal.cpp index 6f08c6451e..d1b522d029 100644 --- a/tests/web/Modal.cpp +++ b/tests/web/Modal.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Modal.cpp + * @file */ #include diff --git a/tests/web/ReadoutPanel.cpp b/tests/web/ReadoutPanel.cpp index d86e31b159..539c4ef947 100644 --- a/tests/web/ReadoutPanel.cpp +++ b/tests/web/ReadoutPanel.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ReadoutPanel.cpp + * @file */ #include "emp/base/assert.hpp" diff --git a/tests/web/TextFeed.cpp b/tests/web/TextFeed.cpp index cbc8b1a08c..e101cca855 100644 --- a/tests/web/TextFeed.cpp +++ b/tests/web/TextFeed.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file TextFeed.cpp + * @file */ #include diff --git a/tests/web/ToggleSwitch.cpp b/tests/web/ToggleSwitch.cpp index 7a80e8b12c..dca48c8734 100644 --- a/tests/web/ToggleSwitch.cpp +++ b/tests/web/ToggleSwitch.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file ToggleSwitch.cpp + * @file */ #include diff --git a/tests/web/ValueBox.cpp b/tests/web/ValueBox.cpp index d3b89581de..17f9da80ec 100644 --- a/tests/web/ValueBox.cpp +++ b/tests/web/ValueBox.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file ValueBox.cpp + * @file */ #include diff --git a/tests/web/Widget.cpp b/tests/web/Widget.cpp index 90a7d72983..46de3ae1ea 100644 --- a/tests/web/Widget.cpp +++ b/tests/web/Widget.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2020 - * - * @file Widget.cpp + * @file */ #include diff --git a/tests/web/assets/Config.hpp b/tests/web/assets/Config.hpp index da638e16da..b53752d986 100644 --- a/tests/web/assets/Config.hpp +++ b/tests/web/assets/Config.hpp @@ -1,10 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file Config.hpp - * + * @file */ #ifndef TESTS_WEB_ASSETS_CONFIG_HPP_INCLUDE diff --git a/tests/web/color_map.cpp b/tests/web/color_map.cpp index 9571263a98..3caaebdd79 100644 --- a/tests/web/color_map.cpp +++ b/tests/web/color_map.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2017 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2017 - * - * @file color_map.cpp + * @file */ #include diff --git a/tests/web/js_utils.cpp b/tests/web/js_utils.cpp index cc7b850d29..013a7cba24 100644 --- a/tests/web/js_utils.cpp +++ b/tests/web/js_utils.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2016-2020 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2016-2020 - * - * @file js_utils.cpp + * @file */ #include diff --git a/tests/web/visualizations.cpp b/tests/web/visualizations.cpp index d29d5af727..42269656a6 100644 --- a/tests/web/visualizations.cpp +++ b/tests/web/visualizations.cpp @@ -1,9 +1,10 @@ +/* + * This file is part of Empirical, https://github.com/devosoft/Empirical + * Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md + * date: 2021 +*/ /** - * @note This file is part of Empirical, https://github.com/devosoft/Empirical - * @copyright Copyright (C) Michigan State University, MIT Software license; see doc/LICENSE.md - * @date 2021 - * - * @file visualizations.cpp + * @file */ // This file is a monstrosity, because including multiple emscripten-generated diff --git a/third-party/Makefile b/third-party/Makefile index 4200e208c8..8b913cb6c8 100644 --- a/third-party/Makefile +++ b/third-party/Makefile @@ -15,7 +15,7 @@ download-doxygen: bash download_doxygen.sh build-doxygen: download-doxygen - mkdir -p doxygen/build && cd doxygen/build && cmake -g "Unix makefiles" .. && make + mkdir -p doxygen/build && cd doxygen/build && cmake -G "Unix Makefiles" .. && make prepare-virtualenv: python3 -m virtualenv env diff --git a/third-party/download_doxygen.sh b/third-party/download_doxygen.sh index a49a4ba072..f8ba1505cd 100755 --- a/third-party/download_doxygen.sh +++ b/third-party/download_doxygen.sh @@ -1,8 +1,8 @@ if [ -d doxygen ]; then echo "doxygen directory exists!" else - curl -O -L https://sourceforge.net/projects/doxygen/files/rel-1.8.11/doxygen-1.8.11.src.tar.gz/download + curl -O -L https://sourceforge.net/projects/doxygen/files/rel-1.9.7/doxygen-1.9.7.src.tar.gz/download tar -xvf download rm download - mv doxygen-1.8.11 doxygen; + mv doxygen-1.9.7 doxygen; fi diff --git a/third-party/package.json b/third-party/package.json index 8517fcacb6..b61443a207 100644 --- a/third-party/package.json +++ b/third-party/package.json @@ -1,6 +1,6 @@ { "name": "empirical-dev-dependencies", - "version": "0.0.3", + "version": "1.0.0", "description": "Dev dependencies for Empirical", "main": "index.js", "devDependencies": {