From dcb555c324781ea996f7af0400bdf2bbbbd39bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 6 Dec 2020 17:44:19 +0000 Subject: [PATCH 01/47] Merge from actions-subtree --- .github/workflows/push-on-change.yaml | 47 +++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 .github/workflows/push-on-change.yaml diff --git a/.github/workflows/push-on-change.yaml b/.github/workflows/push-on-change.yaml new file mode 100644 index 000000000..fbd20c73b --- /dev/null +++ b/.github/workflows/push-on-change.yaml @@ -0,0 +1,47 @@ +# DO NOT edit this file +# Delete and create a new file with a different name instead +on: + push: + branches: + - '*/*' + +name: Push on change + +jobs: + create_key: + runs-on: ubuntu-18.04 + + name: Push on change + + steps: + - name: Check out our repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: Configure Git identity + run: | + git log HEAD^.. --pretty=format:"git config --global user.name '%an' && git config --global user.email '%ae'" | tee /dev/stderr | sh + + - name: Get branch name + id: remote_repo + run: | + echo "::set-output name=slug::$(echo $GITHUB_REF | sed 's#refs/heads/##')" + shell: bash + + - name: Check out remote repository + uses: actions/checkout@v2 + with: + repository: ${{ steps.remote_repo.outputs.slug }} + path: remote/${{ steps.remote_repo.outputs.slug }} + fetch-depth: 0 + token: ${{ secrets.TOKEN_KEYS }} + + - name: Merge subtree + run: | + set -x + cd remote/${{ steps.remote_repo.outputs.slug }} + git subtree pull -m "Merge from actions-subtree" --prefix=.github/workflows ../../.. ${{ steps.remote_repo.outputs.slug }} + git rm -rf .github/workflows/.github + git commit --amend --no-edit || true + git push From e10f0e96758389978e02060cee0edcce642cda56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 6 Dec 2020 21:17:32 +0000 Subject: [PATCH 02/47] Merge from actions-subtree # Conflicts: # .github/workflows/.github/workflows/push-on-change.yaml --- .github/workflows/push-on-change.yaml | 47 --------------------------- 1 file changed, 47 deletions(-) delete mode 100644 .github/workflows/push-on-change.yaml diff --git a/.github/workflows/push-on-change.yaml b/.github/workflows/push-on-change.yaml deleted file mode 100644 index fbd20c73b..000000000 --- a/.github/workflows/push-on-change.yaml +++ /dev/null @@ -1,47 +0,0 @@ -# DO NOT edit this file -# Delete and create a new file with a different name instead -on: - push: - branches: - - '*/*' - -name: Push on change - -jobs: - create_key: - runs-on: ubuntu-18.04 - - name: Push on change - - steps: - - name: Check out our repository - uses: actions/checkout@v2 - with: - fetch-depth: 0 - - - name: Configure Git identity - run: | - git log HEAD^.. --pretty=format:"git config --global user.name '%an' && git config --global user.email '%ae'" | tee /dev/stderr | sh - - - name: Get branch name - id: remote_repo - run: | - echo "::set-output name=slug::$(echo $GITHUB_REF | sed 's#refs/heads/##')" - shell: bash - - - name: Check out remote repository - uses: actions/checkout@v2 - with: - repository: ${{ steps.remote_repo.outputs.slug }} - path: remote/${{ steps.remote_repo.outputs.slug }} - fetch-depth: 0 - token: ${{ secrets.TOKEN_KEYS }} - - - name: Merge subtree - run: | - set -x - cd remote/${{ steps.remote_repo.outputs.slug }} - git subtree pull -m "Merge from actions-subtree" --prefix=.github/workflows ../../.. ${{ steps.remote_repo.outputs.slug }} - git rm -rf .github/workflows/.github - git commit --amend --no-edit || true - git push From da4d93d38ad7f0242c242e756be4e458a1cb8dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 18 Mar 2021 04:38:07 +0100 Subject: [PATCH 03/47] Sync --- .github/workflows/revdep.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/revdep.yaml b/.github/workflows/revdep.yaml index 4cee12cf0..993a2cc63 100644 --- a/.github/workflows/revdep.yaml +++ b/.github/workflows/revdep.yaml @@ -155,7 +155,7 @@ jobs: - name: Install local package run: | - remotes::install_local(".") + remotes::install_local(".", force = TRUE) shell: Rscript {0} - name: Session info new From 3fb29f11e157005f733020fef2d2e78843f5970e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Fri, 19 Mar 2021 09:00:29 +0100 Subject: [PATCH 04/47] Abort explicitly if busy handler fails On Solaris Rcpp or sqlite crashes if the busy handler does not return, so now we catch errors in the busy handler, and throw a warning and abort the transaction. Closes #348. --- R/SQLiteConnection.R | 7 +++---- man/sqliteSetBusyHandler.Rd | 7 +++---- src/DbConnection.cpp | 11 ++++++++--- tests/testthat/test-dbConnect.R | 5 ++++- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/R/SQLiteConnection.R b/R/SQLiteConnection.R index 20e4338f3..bca0ddbd3 100644 --- a/R/SQLiteConnection.R +++ b/R/SQLiteConnection.R @@ -215,10 +215,9 @@ setMethod("dbGetInfo", "SQLiteConnection", function(dbObj, ...) { #' #' Handler callbacks are useful for debugging concurrent behavior, or to #' implement a more sophisticated busy algorithm. The latter is currently -#' considered experimental in RSQLite, especially with respect to errors and -#' interruption in the handler function. According to our current tests, -#' after the handler function fails or is interrupted, the database -#' connection is still functional, but this might not be always the case. +#' considered experimental in RSQLite. If the callback function fails, then +#' RSQLite will print a warning, and the transaction is aborted with a +#' "database is locked" error. #' #' Note that every database connection has its own busy timeout or handler #' function. diff --git a/man/sqliteSetBusyHandler.Rd b/man/sqliteSetBusyHandler.Rd index a6dd7cd62..870204563 100644 --- a/man/sqliteSetBusyHandler.Rd +++ b/man/sqliteSetBusyHandler.Rd @@ -57,10 +57,9 @@ database and the cycle repeats. Handler callbacks are useful for debugging concurrent behavior, or to implement a more sophisticated busy algorithm. The latter is currently -considered experimental in RSQLite, especially with respect to errors and -interruption in the handler function. According to our current tests, -after the handler function fails or is interrupted, the database -connection is still functional, but this might not be always the case. +considered experimental in RSQLite. If the callback function fails, then +RSQLite will print a warning, and the transaction is aborted with a +"database is locked" error. Note that every database connection has its own busy timeout or handler function. diff --git a/src/DbConnection.cpp b/src/DbConnection.cpp index 205160b30..b6067b2b0 100644 --- a/src/DbConnection.cpp +++ b/src/DbConnection.cpp @@ -109,7 +109,12 @@ void DbConnection::release_callback_data() { int DbConnection::busy_callback_helper(void *data, int num) { SEXP r_callback = reinterpret_cast (data); - Function rfun = r_callback; - IntegerVector ret = rfun(num); - return as(ret); + try { + Function rfun = r_callback; + IntegerVector ret = rfun(num); + return as(ret); + } catch(...) { + Rcpp::warning("Busy callback failed, aborting transaction"); + return 0; + } } diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index b50882721..d0e92599b 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -123,7 +123,10 @@ test_that("error in busy handler", { sqliteSetBusyHandler(con2, cb) dbExecute(con1, "BEGIN IMMEDIATE") - expect_error(dbExecute(con2, "BEGIN IMMEDIATE"), "oops") + expect_error( + expect_warning(dbExecute(con2, "BEGIN IMMEDIATE"), "aborting"), + "database is locked" + ) # con1 is still fine of course dbWriteTable(con1, "mtcars", mtcars) From d91aa8c84a8fbc71287789e4b683562d7b0ca322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Cs=C3=A1rdi?= Date: Fri, 19 Mar 2021 09:24:57 +0100 Subject: [PATCH 05/47] Keep error message when busy callback fails --- src/DbConnection.cpp | 10 ++++++++++ tests/testthat/test-dbConnect.R | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/DbConnection.cpp b/src/DbConnection.cpp index b6067b2b0..52715cbc2 100644 --- a/src/DbConnection.cpp +++ b/src/DbConnection.cpp @@ -109,10 +109,20 @@ void DbConnection::release_callback_data() { int DbConnection::busy_callback_helper(void *data, int num) { SEXP r_callback = reinterpret_cast (data); + try { Function rfun = r_callback; IntegerVector ret = rfun(num); return as(ret); + + } catch(eval_error &e) { + Rcpp::warning("Busy callback failed, aborting transaction: %s", e.what()); + return 0; + + } catch(Rcpp::internal::InterruptedException &e) { + // Not warning on explicit interrupt + return 0; + } catch(...) { Rcpp::warning("Busy callback failed, aborting transaction"); return 0; diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index d0e92599b..30de4a8f6 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -124,7 +124,10 @@ test_that("error in busy handler", { dbExecute(con1, "BEGIN IMMEDIATE") expect_error( - expect_warning(dbExecute(con2, "BEGIN IMMEDIATE"), "aborting"), + expect_warning( + dbExecute(con2, "BEGIN IMMEDIATE"), + "Busy callback failed, aborting.*oops" + ), "database is locked" ) From 7924d0ece410c0452cd0ba2b4f8ec148d1bb832e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 05:42:38 +0100 Subject: [PATCH 06/47] Remove unused workaround file --- src/connection.cpp | 1 - src/extensions.cpp | 1 - src/result.cpp | 1 - src/workarounds/XPtr.h | 43 ------------------------------------------ 4 files changed, 46 deletions(-) delete mode 100644 src/workarounds/XPtr.h diff --git a/src/connection.cpp b/src/connection.cpp index 6cd158ac7..9a01522d8 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -1,5 +1,4 @@ #include "pch.h" -#include #include "DbConnection.h" extern "C" { diff --git a/src/extensions.cpp b/src/extensions.cpp index 6ccefdb8f..682a3e6e5 100644 --- a/src/extensions.cpp +++ b/src/extensions.cpp @@ -1,6 +1,5 @@ #include "pch.h" #include "DbConnection.h" -#include "workarounds/XPtr.h" // [[Rcpp::export]] diff --git a/src/result.cpp b/src/result.cpp index cb9487334..2e9418b5b 100644 --- a/src/result.cpp +++ b/src/result.cpp @@ -1,5 +1,4 @@ #include "pch.h" -#include "workarounds/XPtr.h" #include "RSQLite_types.h" //#include "DbResult.h" diff --git a/src/workarounds/XPtr.h b/src/workarounds/XPtr.h deleted file mode 100644 index 2f651505d..000000000 --- a/src/workarounds/XPtr.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef RSQLite_workarounds_XPtr_h -#define RSQLite_workarounds_XPtr_h - - -#ifdef __CLION__ - -namespace Rcpp{ - - template < - typename T> - class XPtr - { - public: - explicit XPtr(SEXP x, SEXP tag = R_NilValue, SEXP prot = R_NilValue); - explicit XPtr(T* p, bool set_delete_finalizer = true, SEXP tag = R_NilValue, SEXP prot = R_NilValue); - XPtr( const XPtr& other ); - XPtr& operator=(const XPtr& other); - - inline T* get() const; - - typedef void (*unspecified_bool_type)(); - static void unspecified_bool_true(); - operator unspecified_bool_type() const; - bool operator!() const; - - inline T* checked_get() const; - - T& operator*() const; - - T* operator->() const; - - void release(); - - inline operator T*(); - - void update(SEXP); - }; - -} // namespace Rcpp - -#endif // #ifdef __CLION__ - -#endif // #ifndef RSQLite_workarounds_XPtr_h From 4248176ff03e361b53c94e63d2d0890c92d888c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 05:53:46 +0100 Subject: [PATCH 07/47] Support no-op --- data-raw/upgrade.R | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 03ccf4817..9a2821048 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -32,7 +32,8 @@ download.file( url = "https://sqlite.org/src/raw?filename=ext/misc/regexp.c&ci=trunk", destfile = "src/vendor/sqlite3/regexp.c", quiet = TRUE, - mode = "w") + mode = "w" +) stopifnot(system2("patch", "-p1", stdin = "data-raw/regexp.patch") == 0) @@ -45,9 +46,18 @@ if (any(grepl("^src/", gert::git_status()$file))) { old_branch <- gert::git_branch() message("Old branch: ", old_branch) - gert::git_branch_create(branch) + tryCatch( + gert::git_branch_checkout(branch), + error = function(e) { + gert::git_branch_create(branch) + } + ) gert::git_add("src") + if (NROW(gert::git_status(staged = TRUE)) == 0) { + message("No changes, exiting") + } + title <- paste0("Upgrade bundled SQLite to ", version) message("Commit message: ", title) gert::git_commit(title) @@ -57,7 +67,8 @@ if (any(grepl("^src/", gert::git_status()$file))) { message("Opening PR") pr <- gh::gh( - "/repos/r-dbi/RSQLite/pulls", head = branch, base = old_branch, + "/repos/r-dbi/RSQLite/pulls", + head = branch, base = old_branch, title = title, body = ".", .method = "POST" ) From b76617f31d01bb6c520a7a53cb222f1932993be2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 06:24:53 +0100 Subject: [PATCH 08/47] Switch branch early --- data-raw/upgrade.R | 48 +++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 9a2821048..0703357e3 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -1,5 +1,7 @@ library(magrittr) +do_upgrade <- function() { + html <- xml2::read_html("https://www.sqlite.org/download.html") latest_name <- html %>% @@ -9,6 +11,22 @@ latest_name <- html %>% grep("amalgamation", ., value = TRUE) %>% .[1] +old_branch <- gert::git_branch() +message("Old branch: ", old_branch) + +stopifnot(NROW(gert::git_status()) == 0) + +message("Branch name: ", branch) +tryCatch( + gert::git_branch_checkout(branch), + error = function(e) { + message("Creating new branch ", branch) + gert::git_branch_create(branch) + } +) + +withr::defer(gert::git_branch_checkout(old_branch)) + tmp <- tempfile() year <- as.integer(strftime(Sys.Date(), "%Y")) @@ -37,27 +55,14 @@ download.file( stopifnot(system2("patch", "-p1", stdin = "data-raw/regexp.patch") == 0) -if (any(grepl("^src/", gert::git_status()$file))) { - branch <- paste0("f-", sub("[.][^.]*$", "", latest_name)) - message("Changes detected, creating branch: ", branch) +gert::git_add("src") +if (NROW(gert::git_status(staged = TRUE)) == 0) { + message("No changes detected") +} else { + message("Changes detected") version <- sub("^.*-([0-9])([0-9][0-9])(?:0([0-9])|([1-9][0-9]))[0-9]+[.].*$", "\\1.\\2.\\3\\4", latest_name) - old_branch <- gert::git_branch() - message("Old branch: ", old_branch) - - tryCatch( - gert::git_branch_checkout(branch), - error = function(e) { - gert::git_branch_create(branch) - } - ) - gert::git_add("src") - - if (NROW(gert::git_status(staged = TRUE)) == 0) { - message("No changes, exiting") - } - title <- paste0("Upgrade bundled SQLite to ", version) message("Commit message: ", title) gert::git_commit(title) @@ -65,6 +70,9 @@ if (any(grepl("^src/", gert::git_status()$file))) { message("Pushing branch") gert::git_push() + # PR will fail to open if an existing branch is pushed to, + # this is a feature + message("Opening PR") pr <- gh::gh( "/repos/r-dbi/RSQLite/pulls", @@ -82,3 +90,7 @@ if (any(grepl("^src/", gert::git_status()$file))) { .method = "PATCH" ) } + +} + +do_upgrade() From 3c308693e8be2cc3315342f392a36023768f5723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 06:27:39 +0100 Subject: [PATCH 09/47] Revert "Switch branch early" This reverts commit b76617f31d01bb6c520a7a53cb222f1932993be2. --- data-raw/upgrade.R | 48 +++++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 0703357e3..9a2821048 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -1,7 +1,5 @@ library(magrittr) -do_upgrade <- function() { - html <- xml2::read_html("https://www.sqlite.org/download.html") latest_name <- html %>% @@ -11,22 +9,6 @@ latest_name <- html %>% grep("amalgamation", ., value = TRUE) %>% .[1] -old_branch <- gert::git_branch() -message("Old branch: ", old_branch) - -stopifnot(NROW(gert::git_status()) == 0) - -message("Branch name: ", branch) -tryCatch( - gert::git_branch_checkout(branch), - error = function(e) { - message("Creating new branch ", branch) - gert::git_branch_create(branch) - } -) - -withr::defer(gert::git_branch_checkout(old_branch)) - tmp <- tempfile() year <- as.integer(strftime(Sys.Date(), "%Y")) @@ -55,14 +37,27 @@ download.file( stopifnot(system2("patch", "-p1", stdin = "data-raw/regexp.patch") == 0) -gert::git_add("src") -if (NROW(gert::git_status(staged = TRUE)) == 0) { - message("No changes detected") -} else { - message("Changes detected") +if (any(grepl("^src/", gert::git_status()$file))) { + branch <- paste0("f-", sub("[.][^.]*$", "", latest_name)) + message("Changes detected, creating branch: ", branch) version <- sub("^.*-([0-9])([0-9][0-9])(?:0([0-9])|([1-9][0-9]))[0-9]+[.].*$", "\\1.\\2.\\3\\4", latest_name) + old_branch <- gert::git_branch() + message("Old branch: ", old_branch) + + tryCatch( + gert::git_branch_checkout(branch), + error = function(e) { + gert::git_branch_create(branch) + } + ) + gert::git_add("src") + + if (NROW(gert::git_status(staged = TRUE)) == 0) { + message("No changes, exiting") + } + title <- paste0("Upgrade bundled SQLite to ", version) message("Commit message: ", title) gert::git_commit(title) @@ -70,9 +65,6 @@ if (NROW(gert::git_status(staged = TRUE)) == 0) { message("Pushing branch") gert::git_push() - # PR will fail to open if an existing branch is pushed to, - # this is a feature - message("Opening PR") pr <- gh::gh( "/repos/r-dbi/RSQLite/pulls", @@ -90,7 +82,3 @@ if (NROW(gert::git_status(staged = TRUE)) == 0) { .method = "PATCH" ) } - -} - -do_upgrade() From 6d1b3cd1707db51c36f360e96b6c4ce97de71544 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 06:27:43 +0100 Subject: [PATCH 10/47] Revert "Support no-op" This reverts commit 4248176ff03e361b53c94e63d2d0890c92d888c8. --- data-raw/upgrade.R | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 9a2821048..03ccf4817 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -32,8 +32,7 @@ download.file( url = "https://sqlite.org/src/raw?filename=ext/misc/regexp.c&ci=trunk", destfile = "src/vendor/sqlite3/regexp.c", quiet = TRUE, - mode = "w" -) + mode = "w") stopifnot(system2("patch", "-p1", stdin = "data-raw/regexp.patch") == 0) @@ -46,18 +45,9 @@ if (any(grepl("^src/", gert::git_status()$file))) { old_branch <- gert::git_branch() message("Old branch: ", old_branch) - tryCatch( - gert::git_branch_checkout(branch), - error = function(e) { - gert::git_branch_create(branch) - } - ) + gert::git_branch_create(branch) gert::git_add("src") - if (NROW(gert::git_status(staged = TRUE)) == 0) { - message("No changes, exiting") - } - title <- paste0("Upgrade bundled SQLite to ", version) message("Commit message: ", title) gert::git_commit(title) @@ -67,8 +57,7 @@ if (any(grepl("^src/", gert::git_status()$file))) { message("Opening PR") pr <- gh::gh( - "/repos/r-dbi/RSQLite/pulls", - head = branch, base = old_branch, + "/repos/r-dbi/RSQLite/pulls", head = branch, base = old_branch, title = title, body = ".", .method = "POST" ) From 42a2d9f3eb41c40306b5771571622aadbf8ad264 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 06:28:28 +0100 Subject: [PATCH 11/47] Force-push instead --- data-raw/upgrade.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 03ccf4817..d183f7893 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -52,8 +52,10 @@ if (any(grepl("^src/", gert::git_status()$file))) { message("Commit message: ", title) gert::git_commit(title) + # Force-pushing: this job is run daily, will give a daily notification + # and still succeed message("Pushing branch") - gert::git_push() + gert::git_push(force = TRUE) message("Opening PR") pr <- gh::gh( From e7a0328d8c06b9db70f11355db69306cc06a3066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 06:42:34 +0100 Subject: [PATCH 12/47] Check if PR exists --- data-raw/upgrade.R | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index d183f7893..1dc064446 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -57,6 +57,17 @@ if (any(grepl("^src/", gert::git_status()$file))) { message("Pushing branch") gert::git_push(force = TRUE) + message("Checking if PR exists") + existing_pr <- gh::gh( + "/repos/r-dbi/RSQLite/pulls", + head = paste0("r-dbi:", branch), base = old_branch, + state = "open" + ) + + if (length(existing_pr) > 0) { + message("Open PR already exists, leaving") + } + message("Opening PR") pr <- gh::gh( "/repos/r-dbi/RSQLite/pulls", head = branch, base = old_branch, From 5436e5c74a8c72cc1cf215dfab0ae992c4dbb797 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 07:19:15 +0100 Subject: [PATCH 13/47] Get out --- data-raw/upgrade.R | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 1dc064446..361bf4742 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -32,7 +32,8 @@ download.file( url = "https://sqlite.org/src/raw?filename=ext/misc/regexp.c&ci=trunk", destfile = "src/vendor/sqlite3/regexp.c", quiet = TRUE, - mode = "w") + mode = "w" +) stopifnot(system2("patch", "-p1", stdin = "data-raw/regexp.patch") == 0) @@ -66,11 +67,13 @@ if (any(grepl("^src/", gert::git_status()$file))) { if (length(existing_pr) > 0) { message("Open PR already exists, leaving") + return() } message("Opening PR") pr <- gh::gh( - "/repos/r-dbi/RSQLite/pulls", head = branch, base = old_branch, + "/repos/r-dbi/RSQLite/pulls", + head = branch, base = old_branch, title = title, body = ".", .method = "POST" ) From 280ee68e52e88dfb3dd141872c04c4c38ae52485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 07:24:26 +0100 Subject: [PATCH 14/47] Need nesting --- data-raw/upgrade.R | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index 361bf4742..f7dc69a57 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -67,23 +67,22 @@ if (any(grepl("^src/", gert::git_status()$file))) { if (length(existing_pr) > 0) { message("Open PR already exists, leaving") - return() + } else { + message("Opening PR") + pr <- gh::gh( + "/repos/r-dbi/RSQLite/pulls", + head = branch, base = old_branch, + title = title, body = ".", + .method = "POST" + ) + + message("Tweaking PR body") + body <- paste0("NEWS entry:\n\n```\n- Upgrade bundled SQLite to version ", version, " (#", pr$number, ").\n```") + + gh::gh( + paste0("/repos/r-dbi/RSQLite/pulls/", pr$number), + body = body, + .method = "PATCH" + ) } - - message("Opening PR") - pr <- gh::gh( - "/repos/r-dbi/RSQLite/pulls", - head = branch, base = old_branch, - title = title, body = ".", - .method = "POST" - ) - - message("Tweaking PR body") - body <- paste0("NEWS entry:\n\n```\n- Upgrade bundled SQLite to version ", version, " (#", pr$number, ").\n```") - - gh::gh( - paste0("/repos/r-dbi/RSQLite/pulls/", pr$number), - body = body, - .method = "PATCH" - ) } From 20e92499dde077c8857b66b1972602effa284369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Sun, 21 Mar 2021 07:37:20 +0100 Subject: [PATCH 15/47] Manually nudge --- data-raw/upgrade.R | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/data-raw/upgrade.R b/data-raw/upgrade.R index f7dc69a57..7eb2fb279 100644 --- a/data-raw/upgrade.R +++ b/data-raw/upgrade.R @@ -66,7 +66,12 @@ if (any(grepl("^src/", gert::git_status()$file))) { ) if (length(existing_pr) > 0) { - message("Open PR already exists, leaving") + message("Nudging") + gh::gh( + paste0("/repos/r-dbi/RSQLite/issues/", existing_pr[[1]]$number, "/comments"), + body = "PR updated.", + .method = "POST" + ) } else { message("Opening PR") pr <- gh::gh( From ed53c1046186f7e91c6f6dd1fc414173a8f6be77 Mon Sep 17 00:00:00 2001 From: upgrade Date: Thu, 25 Mar 2021 08:06:56 +0000 Subject: [PATCH 16/47] Upgrade bundled SQLite to 3.35.2 --- src/vendor/sqlite3/sqlite3.c | 11548 ++++++++++++++++++++------------- src/vendor/sqlite3/sqlite3.h | 59 +- 2 files changed, 7013 insertions(+), 4594 deletions(-) diff --git a/src/vendor/sqlite3/sqlite3.c b/src/vendor/sqlite3/sqlite3.c index 38874ce40..54f8277a7 100644 --- a/src/vendor/sqlite3/sqlite3.c +++ b/src/vendor/sqlite3/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.34.1. By combining all the individual C code files into this +** version 3.35.2. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -284,6 +284,9 @@ static const char * const sqlite3azCompileOpt[] = { #ifdef SQLITE_ENABLE_LOCKING_STYLE "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE), #endif +#if SQLITE_ENABLE_MATH_FUNCTIONS + "ENABLE_MATH_FUNCTIONS", +#endif #if SQLITE_ENABLE_MEMORY_MANAGEMENT "ENABLE_MEMORY_MANAGEMENT", #endif @@ -990,6 +993,18 @@ SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ # define MSVC_VERSION 0 #endif +/* +** Some C99 functions in "math.h" are only present for MSVC when its version +** is associated with Visual Studio 2013 or higher. +*/ +#ifndef SQLITE_HAVE_C99_MATH_FUNCS +# if MSVC_VERSION==0 || MSVC_VERSION>=1800 +# define SQLITE_HAVE_C99_MATH_FUNCS (1) +# else +# define SQLITE_HAVE_C99_MATH_FUNCS (0) +# endif +#endif + /* Needed for various definitions... */ #if defined(__GNUC__) && !defined(_GNU_SOURCE) # define _GNU_SOURCE @@ -1171,9 +1186,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.34.1" -#define SQLITE_VERSION_NUMBER 3034001 -#define SQLITE_SOURCE_ID "2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f" +#define SQLITE_VERSION "3.35.2" +#define SQLITE_VERSION_NUMBER 3035002 +#define SQLITE_SOURCE_ID "2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50c3827" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -3163,7 +3178,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back. +** which case the trigger setting is not reported back. +** +**

Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] **

SQLITE_DBCONFIG_ENABLE_VIEW
@@ -3174,7 +3195,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the view setting is not reported back. +** which case the view setting is not reported back. +** +**

Originally this option disabled all views. ^(However, since +** SQLite version 3.35.0, TEMP views are still allowed even if +** this option is off. So, in other words, this option now only disables +** views in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **

SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
@@ -4547,6 +4574,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. ** file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". ** ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -8813,7 +8841,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -11486,6 +11515,14 @@ SQLITE_API int sqlite3session_patchset( */ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); +/* +** CAPI3REF: Query for the amount of heap memory used by a session object. +** +** This API returns the total amount of heap memory in bytes currently +** used by the session object passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + /* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** CONSTRUCTOR: sqlite3_changeset_iter @@ -11588,18 +11625,23 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this ** is not the case, this function returns [SQLITE_MISUSE]. ** -** If argument pzTab is not NULL, then *pzTab is set to point to a -** nul-terminated utf-8 encoded string containing the name of the table -** affected by the current change. The buffer remains valid until either -** sqlite3changeset_next() is called on the iterator or until the -** conflict-handler function returns. If pnCol is not NULL, then *pnCol is -** set to the number of columns in the table affected by the change. If -** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change +** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three +** outputs are set through these pointers: +** +** *pOp is set to one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], +** depending on the type of change that the iterator currently points to; +** +** *pnCol is set to the number of columns in the table affected by the change; and +** +** *pzTab is set to point to a nul-terminated utf-8 encoded string containing +** the name of the table affected by the current change. The buffer remains +** valid until either sqlite3changeset_next() is called on the iterator +** or until the conflict-handler function returns. +** +** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for ** [sqlite3session_indirect()] for a description of direct and indirect -** changes. Finally, if pOp is not NULL, then *pOp is set to one of -** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the -** type of change that the iterator currently points to. +** changes. ** ** If no error occurs, SQLITE_OK is returned. If an error does occur, an ** SQLite error code is returned. The values of the output variables may not @@ -13528,7 +13570,8 @@ struct fts5_api { #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +#if GCC_VERSION>=4007000 || \ + (__has_extension(c_atomic) && __has_extension(c_atomic_store_n)) # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) #else @@ -14095,90 +14138,92 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_TIES 94 #define TK_GENERATED 95 #define TK_ALWAYS 96 -#define TK_REINDEX 97 -#define TK_RENAME 98 -#define TK_CTIME_KW 99 -#define TK_ANY 100 -#define TK_BITAND 101 -#define TK_BITOR 102 -#define TK_LSHIFT 103 -#define TK_RSHIFT 104 -#define TK_PLUS 105 -#define TK_MINUS 106 -#define TK_STAR 107 -#define TK_SLASH 108 -#define TK_REM 109 -#define TK_CONCAT 110 -#define TK_COLLATE 111 -#define TK_BITNOT 112 -#define TK_ON 113 -#define TK_INDEXED 114 -#define TK_STRING 115 -#define TK_JOIN_KW 116 -#define TK_CONSTRAINT 117 -#define TK_DEFAULT 118 -#define TK_NULL 119 -#define TK_PRIMARY 120 -#define TK_UNIQUE 121 -#define TK_CHECK 122 -#define TK_REFERENCES 123 -#define TK_AUTOINCR 124 -#define TK_INSERT 125 -#define TK_DELETE 126 -#define TK_UPDATE 127 -#define TK_SET 128 -#define TK_DEFERRABLE 129 -#define TK_FOREIGN 130 -#define TK_DROP 131 -#define TK_UNION 132 -#define TK_ALL 133 -#define TK_EXCEPT 134 -#define TK_INTERSECT 135 -#define TK_SELECT 136 -#define TK_VALUES 137 -#define TK_DISTINCT 138 -#define TK_DOT 139 -#define TK_FROM 140 -#define TK_JOIN 141 -#define TK_USING 142 -#define TK_ORDER 143 -#define TK_GROUP 144 -#define TK_HAVING 145 -#define TK_LIMIT 146 -#define TK_WHERE 147 -#define TK_INTO 148 -#define TK_NOTHING 149 -#define TK_FLOAT 150 -#define TK_BLOB 151 -#define TK_INTEGER 152 -#define TK_VARIABLE 153 -#define TK_CASE 154 -#define TK_WHEN 155 -#define TK_THEN 156 -#define TK_ELSE 157 -#define TK_INDEX 158 -#define TK_ALTER 159 -#define TK_ADD 160 -#define TK_WINDOW 161 -#define TK_OVER 162 -#define TK_FILTER 163 -#define TK_COLUMN 164 -#define TK_AGG_FUNCTION 165 -#define TK_AGG_COLUMN 166 -#define TK_TRUEFALSE 167 -#define TK_ISNOT 168 -#define TK_FUNCTION 169 -#define TK_UMINUS 170 -#define TK_UPLUS 171 -#define TK_TRUTH 172 -#define TK_REGISTER 173 -#define TK_VECTOR 174 -#define TK_SELECT_COLUMN 175 -#define TK_IF_NULL_ROW 176 -#define TK_ASTERISK 177 -#define TK_SPAN 178 -#define TK_SPACE 179 -#define TK_ILLEGAL 180 +#define TK_MATERIALIZED 97 +#define TK_REINDEX 98 +#define TK_RENAME 99 +#define TK_CTIME_KW 100 +#define TK_ANY 101 +#define TK_BITAND 102 +#define TK_BITOR 103 +#define TK_LSHIFT 104 +#define TK_RSHIFT 105 +#define TK_PLUS 106 +#define TK_MINUS 107 +#define TK_STAR 108 +#define TK_SLASH 109 +#define TK_REM 110 +#define TK_CONCAT 111 +#define TK_COLLATE 112 +#define TK_BITNOT 113 +#define TK_ON 114 +#define TK_INDEXED 115 +#define TK_STRING 116 +#define TK_JOIN_KW 117 +#define TK_CONSTRAINT 118 +#define TK_DEFAULT 119 +#define TK_NULL 120 +#define TK_PRIMARY 121 +#define TK_UNIQUE 122 +#define TK_CHECK 123 +#define TK_REFERENCES 124 +#define TK_AUTOINCR 125 +#define TK_INSERT 126 +#define TK_DELETE 127 +#define TK_UPDATE 128 +#define TK_SET 129 +#define TK_DEFERRABLE 130 +#define TK_FOREIGN 131 +#define TK_DROP 132 +#define TK_UNION 133 +#define TK_ALL 134 +#define TK_EXCEPT 135 +#define TK_INTERSECT 136 +#define TK_SELECT 137 +#define TK_VALUES 138 +#define TK_DISTINCT 139 +#define TK_DOT 140 +#define TK_FROM 141 +#define TK_JOIN 142 +#define TK_USING 143 +#define TK_ORDER 144 +#define TK_GROUP 145 +#define TK_HAVING 146 +#define TK_LIMIT 147 +#define TK_WHERE 148 +#define TK_RETURNING 149 +#define TK_INTO 150 +#define TK_NOTHING 151 +#define TK_FLOAT 152 +#define TK_BLOB 153 +#define TK_INTEGER 154 +#define TK_VARIABLE 155 +#define TK_CASE 156 +#define TK_WHEN 157 +#define TK_THEN 158 +#define TK_ELSE 159 +#define TK_INDEX 160 +#define TK_ALTER 161 +#define TK_ADD 162 +#define TK_WINDOW 163 +#define TK_OVER 164 +#define TK_FILTER 165 +#define TK_COLUMN 166 +#define TK_AGG_FUNCTION 167 +#define TK_AGG_COLUMN 168 +#define TK_TRUEFALSE 169 +#define TK_ISNOT 170 +#define TK_FUNCTION 171 +#define TK_UMINUS 172 +#define TK_UPLUS 173 +#define TK_TRUTH 174 +#define TK_REGISTER 175 +#define TK_VECTOR 176 +#define TK_SELECT_COLUMN 177 +#define TK_IF_NULL_ROW 178 +#define TK_ASTERISK 179 +#define TK_SPAN 180 +#define TK_SPACE 181 +#define TK_ILLEGAL 182 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -14594,15 +14639,14 @@ typedef INT16_TYPE LogEst; ** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not ** the Select query generator tracing logic is turned on. */ -#if defined(SQLITE_ENABLE_SELECTTRACE) -# define SELECTTRACE_ENABLED 1 -#else -# define SELECTTRACE_ENABLED 0 +#if !defined(SQLITE_AMALGAMATION) +SQLITE_PRIVATE u32 sqlite3SelectTrace; #endif -#if defined(SQLITE_ENABLE_SELECTTRACE) +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_SELECTTRACE)) # define SELECTTRACE_ENABLED 1 # define SELECTTRACE(K,P,S,X) \ - if(sqlite3_unsupported_selecttrace&(K)) \ + if(sqlite3SelectTrace&(K)) \ sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ sqlite3DebugPrintf X #else @@ -14610,6 +14654,19 @@ typedef INT16_TYPE LogEst; # define SELECTTRACE_ENABLED 0 #endif +/* +** Macros for "wheretrace" +*/ +SQLITE_PRIVATE u32 sqlite3WhereTrace; +#if defined(SQLITE_DEBUG) \ + && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) +# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X +# define WHERETRACE_ENABLED 1 +#else +# define WHERETRACE(K,X) +#endif + + /* ** An instance of the following structure is used to store the busy-handler ** callback for a given sqlite handle. @@ -14721,7 +14778,10 @@ typedef struct AutoincInfo AutoincInfo; typedef struct Bitvec Bitvec; typedef struct CollSeq CollSeq; typedef struct Column Column; +typedef struct Cte Cte; +typedef struct CteUse CteUse; typedef struct Db Db; +typedef struct DbFixer DbFixer; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; @@ -14739,14 +14799,17 @@ typedef struct LookasideSlot LookasideSlot; typedef struct Module Module; typedef struct NameContext NameContext; typedef struct Parse Parse; +typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; typedef struct RenameToken RenameToken; +typedef struct Returning Returning; typedef struct RowSet RowSet; typedef struct Savepoint Savepoint; typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; +typedef struct SrcItem SrcItem; typedef struct SrcList SrcList; typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; @@ -15318,6 +15381,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ +#define BTREE_PREFORMAT 0x80 /* Inserted data is a preformated cell */ /* An instance of the BtreePayload object describes the content of a single ** entry in either an index or table btree. @@ -15417,6 +15481,8 @@ SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor*, BtCursor*, i64); + /* ** If we are not using shared cache, then there is no need to ** use mutexes to access the BtShared structures. So make the @@ -15716,103 +15782,105 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Copy 77 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */ #define OP_SCopy 78 /* synopsis: r[P2]=r[P1] */ #define OP_IntCopy 79 /* synopsis: r[P2]=r[P1] */ -#define OP_ResultRow 80 /* synopsis: output=r[P1@P2] */ -#define OP_CollSeq 81 -#define OP_AddImm 82 /* synopsis: r[P1]=r[P1]+P2 */ -#define OP_RealAffinity 83 -#define OP_Cast 84 /* synopsis: affinity(r[P1]) */ -#define OP_Permutation 85 -#define OP_Compare 86 /* synopsis: r[P1@P3] <-> r[P2@P3] */ -#define OP_IsTrue 87 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ -#define OP_Offset 88 /* synopsis: r[P3] = sqlite_offset(P1) */ -#define OP_Column 89 /* synopsis: r[P3]=PX */ -#define OP_Affinity 90 /* synopsis: affinity(r[P1@P2]) */ -#define OP_MakeRecord 91 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ -#define OP_Count 92 /* synopsis: r[P2]=count() */ -#define OP_ReadCookie 93 -#define OP_SetCookie 94 -#define OP_ReopenIdx 95 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenRead 96 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenWrite 97 /* synopsis: root=P2 iDb=P3 */ -#define OP_OpenDup 98 -#define OP_OpenAutoindex 99 /* synopsis: nColumn=P2 */ -#define OP_OpenEphemeral 100 /* synopsis: nColumn=P2 */ -#define OP_BitAnd 101 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ -#define OP_BitOr 102 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ -#define OP_ShiftLeft 103 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ -#define OP_Add 105 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ -#define OP_Subtract 106 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ -#define OP_Multiply 107 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ -#define OP_Divide 108 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ -#define OP_Remainder 109 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ -#define OP_Concat 110 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ -#define OP_SorterOpen 111 -#define OP_BitNot 112 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ -#define OP_SequenceTest 113 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ -#define OP_OpenPseudo 114 /* synopsis: P3 columns in r[P2] */ -#define OP_String8 115 /* same as TK_STRING, synopsis: r[P2]='P4' */ -#define OP_Close 116 -#define OP_ColumnsUsed 117 -#define OP_SeekScan 118 /* synopsis: Scan-ahead up to P1 rows */ -#define OP_SeekHit 119 /* synopsis: set P2<=seekHit<=P3 */ -#define OP_Sequence 120 /* synopsis: r[P2]=cursor[P1].ctr++ */ -#define OP_NewRowid 121 /* synopsis: r[P2]=rowid */ -#define OP_Insert 122 /* synopsis: intkey=r[P3] data=r[P2] */ -#define OP_Delete 123 -#define OP_ResetCount 124 -#define OP_SorterCompare 125 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ -#define OP_SorterData 126 /* synopsis: r[P2]=data */ -#define OP_RowData 127 /* synopsis: r[P2]=data */ -#define OP_Rowid 128 /* synopsis: r[P2]=rowid */ -#define OP_NullRow 129 -#define OP_SeekEnd 130 -#define OP_IdxInsert 131 /* synopsis: key=r[P2] */ -#define OP_SorterInsert 132 /* synopsis: key=r[P2] */ -#define OP_IdxDelete 133 /* synopsis: key=r[P2@P3] */ -#define OP_DeferredSeek 134 /* synopsis: Move P3 to P1.rowid if needed */ -#define OP_IdxRowid 135 /* synopsis: r[P2]=rowid */ -#define OP_FinishSeek 136 -#define OP_Destroy 137 -#define OP_Clear 138 -#define OP_ResetSorter 139 -#define OP_CreateBtree 140 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ -#define OP_SqlExec 141 -#define OP_ParseSchema 142 -#define OP_LoadAnalysis 143 -#define OP_DropTable 144 -#define OP_DropIndex 145 -#define OP_DropTrigger 146 -#define OP_IntegrityCk 147 -#define OP_RowSetAdd 148 /* synopsis: rowset(P1)=r[P2] */ -#define OP_Param 149 -#define OP_Real 150 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ -#define OP_FkCounter 151 /* synopsis: fkctr[P1]+=P2 */ -#define OP_MemMax 152 /* synopsis: r[P1]=max(r[P1],r[P2]) */ -#define OP_OffsetLimit 153 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ -#define OP_AggInverse 154 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ -#define OP_AggStep 155 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggStep1 156 /* synopsis: accum=r[P3] step(r[P2@P5]) */ -#define OP_AggValue 157 /* synopsis: r[P3]=value N=P2 */ -#define OP_AggFinal 158 /* synopsis: accum=r[P1] N=P2 */ -#define OP_Expire 159 -#define OP_CursorLock 160 -#define OP_CursorUnlock 161 -#define OP_TableLock 162 /* synopsis: iDb=P1 root=P2 write=P3 */ -#define OP_VBegin 163 -#define OP_VCreate 164 -#define OP_VDestroy 165 -#define OP_VOpen 166 -#define OP_VColumn 167 /* synopsis: r[P3]=vcolumn(P2) */ -#define OP_VRename 168 -#define OP_Pagecount 169 -#define OP_MaxPgcnt 170 -#define OP_Trace 171 -#define OP_CursorHint 172 -#define OP_ReleaseReg 173 /* synopsis: release r[P1@P2] mask P3 */ -#define OP_Noop 174 -#define OP_Explain 175 -#define OP_Abortable 176 +#define OP_ChngCntRow 80 /* synopsis: output=r[P1] */ +#define OP_ResultRow 81 /* synopsis: output=r[P1@P2] */ +#define OP_CollSeq 82 +#define OP_AddImm 83 /* synopsis: r[P1]=r[P1]+P2 */ +#define OP_RealAffinity 84 +#define OP_Cast 85 /* synopsis: affinity(r[P1]) */ +#define OP_Permutation 86 +#define OP_Compare 87 /* synopsis: r[P1@P3] <-> r[P2@P3] */ +#define OP_IsTrue 88 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */ +#define OP_Offset 89 /* synopsis: r[P3] = sqlite_offset(P1) */ +#define OP_Column 90 /* synopsis: r[P3]=PX */ +#define OP_Affinity 91 /* synopsis: affinity(r[P1@P2]) */ +#define OP_MakeRecord 92 /* synopsis: r[P3]=mkrec(r[P1@P2]) */ +#define OP_Count 93 /* synopsis: r[P2]=count() */ +#define OP_ReadCookie 94 +#define OP_SetCookie 95 +#define OP_ReopenIdx 96 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenRead 97 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenWrite 98 /* synopsis: root=P2 iDb=P3 */ +#define OP_OpenDup 99 +#define OP_OpenAutoindex 100 /* synopsis: nColumn=P2 */ +#define OP_OpenEphemeral 101 /* synopsis: nColumn=P2 */ +#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */ +#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */ +#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<>r[P1] */ +#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */ +#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */ +#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */ +#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */ +#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */ +#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */ +#define OP_SorterOpen 112 +#define OP_BitNot 113 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */ +#define OP_SequenceTest 114 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */ +#define OP_OpenPseudo 115 /* synopsis: P3 columns in r[P2] */ +#define OP_String8 116 /* same as TK_STRING, synopsis: r[P2]='P4' */ +#define OP_Close 117 +#define OP_ColumnsUsed 118 +#define OP_SeekScan 119 /* synopsis: Scan-ahead up to P1 rows */ +#define OP_SeekHit 120 /* synopsis: set P2<=seekHit<=P3 */ +#define OP_Sequence 121 /* synopsis: r[P2]=cursor[P1].ctr++ */ +#define OP_NewRowid 122 /* synopsis: r[P2]=rowid */ +#define OP_Insert 123 /* synopsis: intkey=r[P3] data=r[P2] */ +#define OP_RowCell 124 +#define OP_Delete 125 +#define OP_ResetCount 126 +#define OP_SorterCompare 127 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */ +#define OP_SorterData 128 /* synopsis: r[P2]=data */ +#define OP_RowData 129 /* synopsis: r[P2]=data */ +#define OP_Rowid 130 /* synopsis: r[P2]=rowid */ +#define OP_NullRow 131 +#define OP_SeekEnd 132 +#define OP_IdxInsert 133 /* synopsis: key=r[P2] */ +#define OP_SorterInsert 134 /* synopsis: key=r[P2] */ +#define OP_IdxDelete 135 /* synopsis: key=r[P2@P3] */ +#define OP_DeferredSeek 136 /* synopsis: Move P3 to P1.rowid if needed */ +#define OP_IdxRowid 137 /* synopsis: r[P2]=rowid */ +#define OP_FinishSeek 138 +#define OP_Destroy 139 +#define OP_Clear 140 +#define OP_ResetSorter 141 +#define OP_CreateBtree 142 /* synopsis: r[P2]=root iDb=P1 flags=P3 */ +#define OP_SqlExec 143 +#define OP_ParseSchema 144 +#define OP_LoadAnalysis 145 +#define OP_DropTable 146 +#define OP_DropIndex 147 +#define OP_DropTrigger 148 +#define OP_IntegrityCk 149 +#define OP_RowSetAdd 150 /* synopsis: rowset(P1)=r[P2] */ +#define OP_Param 151 +#define OP_Real 152 /* same as TK_FLOAT, synopsis: r[P2]=P4 */ +#define OP_FkCounter 153 /* synopsis: fkctr[P1]+=P2 */ +#define OP_MemMax 154 /* synopsis: r[P1]=max(r[P1],r[P2]) */ +#define OP_OffsetLimit 155 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */ +#define OP_AggInverse 156 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */ +#define OP_AggStep 157 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggStep1 158 /* synopsis: accum=r[P3] step(r[P2@P5]) */ +#define OP_AggValue 159 /* synopsis: r[P3]=value N=P2 */ +#define OP_AggFinal 160 /* synopsis: accum=r[P1] N=P2 */ +#define OP_Expire 161 +#define OP_CursorLock 162 +#define OP_CursorUnlock 163 +#define OP_TableLock 164 /* synopsis: iDb=P1 root=P2 write=P3 */ +#define OP_VBegin 165 +#define OP_VCreate 166 +#define OP_VDestroy 167 +#define OP_VOpen 168 +#define OP_VColumn 169 /* synopsis: r[P3]=vcolumn(P2) */ +#define OP_VRename 170 +#define OP_Pagecount 171 +#define OP_MaxPgcnt 172 +#define OP_Trace 173 +#define OP_CursorHint 174 +#define OP_ReleaseReg 175 /* synopsis: release r[P1@P2] mask P3 */ +#define OP_Noop 176 +#define OP_Explain 177 +#define OP_Abortable 178 /* Properties such as "out2" or "jump" that are specified in ** comments following the "case" for each opcode in the vdbe.c @@ -15835,19 +15903,19 @@ typedef struct VdbeOpList VdbeOpList; /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x01, 0x01, 0x01, 0x00,\ /* 64 */ 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10, 0x10,\ /* 72 */ 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x10,\ -/* 80 */ 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00, 0x12,\ -/* 88 */ 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\ -/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26, 0x26,\ -/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\ -/* 112 */ 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,\ -/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 128 */ 0x10, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x10,\ -/* 136 */ 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ -/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x06, 0x10, 0x10, 0x00,\ -/* 152 */ 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 80 */ 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00, 0x00,\ +/* 88 */ 0x12, 0x20, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\ +/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26,\ +/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\ +/* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\ +/* 120 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ +/* 128 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x04, 0x04, 0x00,\ +/* 136 */ 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00,\ +/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x10,\ +/* 152 */ 0x10, 0x00, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00,\ /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 168 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\ -/* 176 */ 0x00,} +/* 168 */ 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00,\ +/* 176 */ 0x00, 0x00, 0x00,} /* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum @@ -15915,7 +15983,7 @@ SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*); #else # define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif -SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*, int, char*, u16); SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); @@ -16887,6 +16955,11 @@ SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); #endif /* SQLITE_OMIT_DEPRECATED */ #define SQLITE_TRACE_NONLEGACY_MASK 0x0f /* Normal flags */ +/* +** Maximum number of sqlite3.aDb[] entries. This is the number of attached +** databases plus 2 for "main" and "temp". +*/ +#define SQLITE_MAX_DB (SQLITE_MAX_ATTACHED+2) /* ** Each database connection is an instance of the following structure. @@ -16907,7 +16980,7 @@ struct sqlite3 { int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ int iSysErrno; /* Errno value from last system error */ - u16 dbOptFlags; /* Flags to enable/disable optimizations */ + u32 dbOptFlags; /* Flags to enable/disable optimizations */ u8 enc; /* Text encoding */ u8 autoCommit; /* The auto-commit flag. */ u8 temp_store; /* 1: file 2: memory 0: default */ @@ -16934,7 +17007,10 @@ struct sqlite3 { unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */ unsigned imposterTable : 1; /* Building an imposter table */ unsigned reopenMemdb : 1; /* ATTACH is really a reopen using MemDB */ + unsigned bDropColumn : 1; /* Doing schema check after DROP COLUMN */ char **azInit; /* "type", "name", and "tbl_name" columns */ + /* or if bDropColumn, then azInit[0] is the */ + /* name of the column being dropped */ } init; int nVdbeActive; /* Number of VDBEs currently running */ int nVdbeRead; /* Number of active VDBEs that read or write */ @@ -17114,24 +17190,26 @@ struct sqlite3 { ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ -#define SQLITE_QueryFlattener 0x0001 /* Query flattening */ -#define SQLITE_WindowFunc 0x0002 /* Use xInverse for window functions */ -#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */ -#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */ -#define SQLITE_DistinctOpt 0x0010 /* DISTINCT using indexes */ -#define SQLITE_CoverIdxScan 0x0020 /* Covering index scans */ -#define SQLITE_OrderByIdxJoin 0x0040 /* ORDER BY of joins via index */ -#define SQLITE_Transitive 0x0080 /* Transitive constraints */ -#define SQLITE_OmitNoopJoin 0x0100 /* Omit unused tables in joins */ -#define SQLITE_CountOfView 0x0200 /* The count-of-view optimization */ -#define SQLITE_CursorHints 0x0400 /* Add OP_CursorHint opcodes */ -#define SQLITE_Stat4 0x0800 /* Use STAT4 data */ - /* TH3 expects the Stat4 ^^^^^^ value to be 0x0800. Don't change it */ -#define SQLITE_PushDown 0x1000 /* The push-down optimization */ -#define SQLITE_SimplifyJoin 0x2000 /* Convert LEFT JOIN to JOIN */ -#define SQLITE_SkipScan 0x4000 /* Skip-scans */ -#define SQLITE_PropagateConst 0x8000 /* The constant propagation opt */ -#define SQLITE_AllOpts 0xffff /* All optimizations */ +#define SQLITE_QueryFlattener 0x00000001 /* Query flattening */ +#define SQLITE_WindowFunc 0x00000002 /* Use xInverse for window functions */ +#define SQLITE_GroupByOrder 0x00000004 /* GROUPBY cover of ORDERBY */ +#define SQLITE_FactorOutConst 0x00000008 /* Constant factoring */ +#define SQLITE_DistinctOpt 0x00000010 /* DISTINCT using indexes */ +#define SQLITE_CoverIdxScan 0x00000020 /* Covering index scans */ +#define SQLITE_OrderByIdxJoin 0x00000040 /* ORDER BY of joins via index */ +#define SQLITE_Transitive 0x00000080 /* Transitive constraints */ +#define SQLITE_OmitNoopJoin 0x00000100 /* Omit unused tables in joins */ +#define SQLITE_CountOfView 0x00000200 /* The count-of-view optimization */ +#define SQLITE_CursorHints 0x00000400 /* Add OP_CursorHint opcodes */ +#define SQLITE_Stat4 0x00000800 /* Use STAT4 data */ + /* TH3 expects this value ^^^^^^^^^^ to be 0x0000800. Don't change it */ +#define SQLITE_PushDown 0x00001000 /* The push-down optimization */ +#define SQLITE_SimplifyJoin 0x00002000 /* Convert LEFT JOIN to JOIN */ +#define SQLITE_SkipScan 0x00004000 /* Skip-scans */ +#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */ +#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */ +#define SQLITE_ExistsToIN 0x00020000 /* The EXISTS-to-IN optimization */ +#define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* ** Macros for testing whether or not optimizations are enabled or disabled. @@ -17287,6 +17365,9 @@ struct FuncDestructor { ** a single query. The iArg is ignored. The user-data is always set ** to a NULL pointer. The bNC parameter is not used. ** +** MFUNCTION(zName, nArg, xPtr, xFunc) +** For math-library functions. xPtr is an arbitrary pointer. +** ** PURE_DATE(zName, nArg, iArg, bNC, xFunc) ** Used for "pure" date/time functions, this macro is like DFUNCTION ** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is @@ -17322,6 +17403,9 @@ struct FuncDestructor { #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } +#define MFUNCTION(zName, nArg, xPtr, xFunc) \ + {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \ + xPtr, 0, xFunc, 0, 0, 0, #zName, {0} } #define INLINE_FUNC(zName, nArg, iArg, mFlags) \ {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \ SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} } @@ -17416,7 +17500,12 @@ struct Column { u16 colFlags; /* Boolean properties. See COLFLAG_ defines below */ }; -/* Allowed values for Column.colFlags: +/* Allowed values for Column.colFlags. +** +** Constraints: +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define COLFLAG_PRIMKEY 0x0001 /* Column is part of the primary key */ #define COLFLAG_HIDDEN 0x0002 /* A hidden column in a virtual table */ @@ -17592,7 +17681,6 @@ struct Table { #endif Trigger *pTrigger; /* List of triggers stored in pSchema */ Schema *pSchema; /* Schema that contains this table */ - Table *pNextZombie; /* Next on the Parse.pZombieTab list */ }; /* @@ -17606,11 +17694,12 @@ struct Table { ** ** Constraints: ** -** TF_HasVirtual == COLFLAG_Virtual -** TF_HasStored == COLFLAG_Stored +** TF_HasVirtual == COLFLAG_VIRTUAL +** TF_HasStored == COLFLAG_STORED +** TF_HasHidden == COLFLAG_HIDDEN */ #define TF_Readonly 0x0001 /* Read-only system table */ -#define TF_Ephemeral 0x0002 /* An ephemeral table */ +#define TF_HasHidden 0x0002 /* Has one or more hidden columns */ #define TF_HasPrimaryKey 0x0004 /* Table has a primary key */ #define TF_Autoincrement 0x0008 /* Integer primary key is autoincrement */ #define TF_HasStat1 0x0010 /* nRowLogEst set from sqlite_stat1 */ @@ -17625,6 +17714,7 @@ struct Table { #define TF_HasNotNull 0x0800 /* Contains NOT NULL constraints */ #define TF_Shadow 0x1000 /* True for a shadow table */ #define TF_HasStat4 0x2000 /* STAT4 info available for this table */ +#define TF_Ephemeral 0x4000 /* An ephemeral table */ /* ** Test to see whether or not a table is a virtual table. This is @@ -17721,16 +17811,22 @@ struct FKey { ** is returned. REPLACE means that preexisting database rows that caused ** a UNIQUE constraint violation are removed so that the new insert or ** update can proceed. Processing continues and no error is reported. +** UPDATE applies to insert operations only and means that the insert +** is omitted and the DO UPDATE clause of an upsert is run instead. ** -** RESTRICT, SETNULL, and CASCADE actions apply only to foreign keys. +** RESTRICT, SETNULL, SETDFLT, and CASCADE actions apply only to foreign keys. ** RESTRICT is the same as ABORT for IMMEDIATE foreign keys and the ** same as ROLLBACK for DEFERRED keys. SETNULL means that the foreign -** key is set to NULL. CASCADE means that a DELETE or UPDATE of the +** key is set to NULL. SETDFLT means that the foreign key is set +** to its default value. CASCADE means that a DELETE or UPDATE of the ** referenced table row is propagated into the row that holds the ** foreign key. ** +** The OE_Default value is a place holder that means to use whatever +** conflict resolution algorthm is required from context. +** ** The following symbolic values are used to record which type -** of action to take. +** of conflict resolution action to take. */ #define OE_None 0 /* There is no constraint to check */ #define OE_Rollback 1 /* Fail the operation and rollback the transaction */ @@ -17987,7 +18083,6 @@ struct AggInfo { } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ - AggInfo *pNext; /* Next in list of them all */ }; /* @@ -18116,7 +18211,7 @@ struct Expr { ** TK_VARIABLE: variable number (always >= 1). ** TK_SELECT_COLUMN: column of the result vector */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ - i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ + int iRightJoinTable; /* If EP_FromJoin, the right table of the join */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ union { Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL @@ -18158,7 +18253,7 @@ struct Expr { #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ #define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ -#define EP_Alias 0x400000 /* Is an alias for a result set column */ + /* 0x400000 // Available */ #define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ #define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ #define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ @@ -18306,6 +18401,45 @@ struct IdList { int nId; /* Number of identifiers on the list */ }; +/* +** The SrcItem object represents a single term in the FROM clause of a query. +** The SrcList object is mostly an array of SrcItems. +*/ +struct SrcItem { + Schema *pSchema; /* Schema to which this item is fixed */ + char *zDatabase; /* Name of database holding this table */ + char *zName; /* Name of the table */ + char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ + Table *pTab; /* An SQL table corresponding to zName */ + Select *pSelect; /* A SELECT statement used in place of a table name */ + int addrFillSub; /* Address of subroutine to manifest a subquery */ + int regReturn; /* Register holding return address of addrFillSub */ + int regResult; /* Registers holding results of a co-routine */ + struct { + u8 jointype; /* Type of join between this table and the previous */ + unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ + unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ + unsigned isTabFunc :1; /* True if table-valued-function syntax */ + unsigned isCorrelated :1; /* True if sub-query is correlated */ + unsigned viaCoroutine :1; /* Implemented as a co-routine */ + unsigned isRecursive :1; /* True for recursive reference in WITH */ + unsigned fromDDL :1; /* Comes from sqlite_schema */ + unsigned isCte :1; /* This is a CTE */ + } fg; + int iCursor; /* The VDBE cursor number used to access this table */ + Expr *pOn; /* The ON clause of a join */ + IdList *pUsing; /* The USING clause of a join */ + Bitmask colUsed; /* Bit N (1<" clause */ + ExprList *pFuncArg; /* Arguments to table-valued-function */ + } u1; + union { + Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ + CteUse *pCteUse; /* CTE Usage info info fg.isCte is true */ + } u2; +}; + /* ** The following structure describes the FROM clause of a SELECT statement. ** Each table or subquery in the FROM clause is a separate element of @@ -18328,36 +18462,7 @@ struct IdList { struct SrcList { int nSrc; /* Number of tables or subqueries in the FROM clause */ u32 nAlloc; /* Number of entries allocated in a[] below */ - struct SrcList_item { - Schema *pSchema; /* Schema to which this item is fixed */ - char *zDatabase; /* Name of database holding this table */ - char *zName; /* Name of the table */ - char *zAlias; /* The "B" part of a "A AS B" phrase. zName is the "A" */ - Table *pTab; /* An SQL table corresponding to zName */ - Select *pSelect; /* A SELECT statement used in place of a table name */ - int addrFillSub; /* Address of subroutine to manifest a subquery */ - int regReturn; /* Register holding return address of addrFillSub */ - int regResult; /* Registers holding results of a co-routine */ - struct { - u8 jointype; /* Type of join between this table and the previous */ - unsigned notIndexed :1; /* True if there is a NOT INDEXED clause */ - unsigned isIndexedBy :1; /* True if there is an INDEXED BY clause */ - unsigned isTabFunc :1; /* True if table-valued-function syntax */ - unsigned isCorrelated :1; /* True if sub-query is correlated */ - unsigned viaCoroutine :1; /* Implemented as a co-routine */ - unsigned isRecursive :1; /* True for recursive reference in WITH */ - unsigned fromDDL :1; /* Comes from sqlite_schema */ - } fg; - int iCursor; /* The VDBE cursor number used to access this table */ - Expr *pOn; /* The ON clause of a join */ - IdList *pUsing; /* The USING clause of a join */ - Bitmask colUsed; /* Bit N (1<" clause */ - ExprList *pFuncArg; /* Arguments to table-valued-function */ - } u1; - Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */ - } a[1]; /* One entry for each identifier on the list */ + SrcItem a[1]; /* One entry for each identifier on the list */ }; /* @@ -18433,6 +18538,7 @@ struct NameContext { ExprList *pEList; /* Optional list of result-set columns */ AggInfo *pAggInfo; /* Information about aggregates at this level */ Upsert *pUpsert; /* ON CONFLICT clause information from an upsert */ + int iBaseReg; /* For TK_REGISTER when parsing RETURNING */ } uNC; NameContext *pNext; /* Next outer name context. NULL for outermost */ int nRef; /* Number of names resolved by this context */ @@ -18461,6 +18567,7 @@ struct NameContext { #define NC_UEList 0x00080 /* True if uNC.pEList is used */ #define NC_UAggInfo 0x00100 /* True if uNC.pAggInfo is used */ #define NC_UUpsert 0x00200 /* True if uNC.pUpsert is used */ +#define NC_UBaseReg 0x00400 /* True if uNC.iBaseReg is used */ #define NC_MinMaxAgg 0x01000 /* min/max aggregates seen. See note above */ #define NC_Complex 0x02000 /* True if a function or subquery seen */ #define NC_AllowWin 0x04000 /* Window functions are allowed here */ @@ -18484,15 +18591,21 @@ struct NameContext { ** WHERE clause is omitted. */ struct Upsert { - ExprList *pUpsertTarget; /* Optional description of conflicting index */ + ExprList *pUpsertTarget; /* Optional description of conflict target */ Expr *pUpsertTargetWhere; /* WHERE clause for partial index targets */ ExprList *pUpsertSet; /* The SET clause from an ON CONFLICT UPDATE */ Expr *pUpsertWhere; /* WHERE clause for the ON CONFLICT UPDATE */ - /* The fields above comprise the parse tree for the upsert clause. - ** The fields below are used to transfer information from the INSERT - ** processing down into the UPDATE processing while generating code. - ** Upsert owns the memory allocated above, but not the memory below. */ - Index *pUpsertIdx; /* Constraint that pUpsertTarget identifies */ + Upsert *pNextUpsert; /* Next ON CONFLICT clause in the list */ + u8 isDoUpdate; /* True for DO UPDATE. False for DO NOTHING */ + /* Above this point is the parse tree for the ON CONFLICT clauses. + ** The next group of fields stores intermediate data. */ + void *pToFree; /* Free memory when deleting the Upsert object */ + /* All fields above are owned by the Upsert object and must be freed + ** when the Upsert is destroyed. The fields below are used to transfer + ** information from the INSERT processing down into the UPDATE processing + ** while generating code. The fields below are owned by the INSERT + ** statement and will be freed by INSERT processing. */ + Index *pUpsertIdx; /* UNIQUE constraint specified by pUpsertTarget */ SrcList *pUpsertSrc; /* Table to be updated */ int regData; /* First register holding array of VALUES */ int iDataCur; /* Index of the data cursor */ @@ -18572,6 +18685,8 @@ struct Select { #define SF_View 0x0200000 /* SELECT statement is a view */ #define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */ #define SF_UpdateFrom 0x0800000 /* Statement is an UPDATE...FROM */ +#define SF_PushDown 0x1000000 /* SELECT has be modified by push-down opt */ +#define SF_MultiPart 0x2000000 /* Has multiple incompatible PARTITIONs */ /* ** The results of a SELECT can be distributed in several ways, as defined @@ -18742,6 +18857,17 @@ struct TriggerPrg { # define DbMaskNonZero(M) (M)!=0 #endif +/* +** An instance of the ParseCleanup object specifies an operation that +** should be performed after parsing to deallocation resources obtained +** during the parse and which are no longer needed. +*/ +struct ParseCleanup { + ParseCleanup *pNext; /* Next cleanup task */ + void *pPtr; /* Pointer to object to deallocate */ + void (*xCleanup)(sqlite3*,void*); /* Deallocation routine */ +}; + /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to @@ -18773,6 +18899,9 @@ struct Parse { u8 okConstFactor; /* OK to factor out constants */ u8 disableLookaside; /* Number of times lookaside has been disabled */ u8 disableVtab; /* Disable all virtual tables for this parse */ +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */ +#endif int nRangeReg; /* Size of the temporary register block */ int iRangeReg; /* First register in temporary register block */ int nErr; /* Number of errors seen */ @@ -18800,12 +18929,15 @@ struct Parse { Parse *pToplevel; /* Parse structure for main program (or NULL) */ Table *pTriggerTab; /* Table triggers are being coded for */ Parse *pParentParse; /* Parent parser if this parser is nested */ - AggInfo *pAggList; /* List of all AggInfo objects */ - int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */ + union { + int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ + Returning *pReturning; /* The RETURNING clause */ + } u1; u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ u8 disableTriggers; /* True to disable triggers */ @@ -18851,10 +18983,9 @@ struct Parse { Token sArg; /* Complete text of a module argument */ Table **apVtabLock; /* Pointer to virtual tables needing locking */ #endif - Table *pZombieTab; /* List of Table objects to delete after code gen */ TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ With *pWith; /* Current WITH clause, or NULL */ - With *pWithToFree; /* Free this WITH object at the end of the parse */ + ParseCleanup *pCleanup; /* List of cleanup operations to run after parse */ #ifndef SQLITE_OMIT_ALTERTABLE RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */ #endif @@ -18934,6 +19065,7 @@ struct AuthContext { #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ +#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ /* * Each trigger present in the database schema is stored as an instance of @@ -18955,6 +19087,7 @@ struct Trigger { char *table; /* The table or view to which the trigger applies */ u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ + u8 bReturning; /* This trigger implements a RETURNING clause */ Expr *pWhen; /* The WHEN clause of the expression (may be NULL) */ IdList *pColumns; /* If this is an UPDATE OF trigger, the is stored here */ @@ -19013,14 +19146,15 @@ struct Trigger { * */ struct TriggerStep { - u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT, + ** or TK_RETURNING */ u8 orconf; /* OE_Rollback etc. */ Trigger *pTrig; /* The trigger that this step is a part of */ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */ char *zTarget; /* Target table for DELETE, UPDATE, INSERT */ SrcList *pFrom; /* FROM clause for UPDATE statement (if any) */ Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ - ExprList *pExprList; /* SET clause for UPDATE */ + ExprList *pExprList; /* SET clause for UPDATE, or RETURNING clause */ IdList *pIdList; /* Column names for INSERT */ Upsert *pUpsert; /* Upsert clauses on an INSERT */ char *zSpan; /* Original SQL text of this command */ @@ -19029,18 +19163,16 @@ struct TriggerStep { }; /* -** The following structure contains information used by the sqliteFix... -** routines as they walk the parse tree to make database references -** explicit. +** Information about a RETURNING clause */ -typedef struct DbFixer DbFixer; -struct DbFixer { - Parse *pParse; /* The parsing context. Error messages written here */ - Schema *pSchema; /* Fix items to this schema */ - u8 bTemp; /* True for TEMP schema entries */ - const char *zDb; /* Make sure all objects are contained in this database */ - const char *zType; /* Type of the container - used for error messages */ - const Token *pName; /* Name of the container - used for error messages */ +struct Returning { + Parse *pParse; /* The parse that includes the RETURNING clause */ + ExprList *pReturnEL; /* List of expressions to return */ + Trigger retTrig; /* The transient trigger that implements RETURNING */ + TriggerStep retTStep; /* The trigger step */ + int iRetCur; /* Transient table holding RETURNING results */ + int nRetCol; /* Number of in pReturnEL after expansion */ + int iRetReg; /* Register array for holding a row of RETURNING */ }; /* @@ -19080,7 +19212,8 @@ typedef struct { /* ** Allowed values for mInitFlags */ -#define INITFLAG_AlterTable 0x0001 /* This is a reparse after ALTER TABLE */ +#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ +#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ /* ** Structure containing global configuration data for the SQLite library. @@ -19192,10 +19325,26 @@ struct Walker { struct WhereConst *pConst; /* WHERE clause constants */ struct RenameCtx *pRename; /* RENAME COLUMN context */ struct Table *pTab; /* Table of generated column */ - struct SrcList_item *pSrcItem; /* A single FROM clause item */ + SrcItem *pSrcItem; /* A single FROM clause item */ + DbFixer *pFix; } u; }; +/* +** The following structure contains information used by the sqliteFix... +** routines as they walk the parse tree to make database references +** explicit. +*/ +struct DbFixer { + Parse *pParse; /* The parsing context. Error messages written here */ + Walker w; /* Walker object */ + Schema *pSchema; /* Fix items to this schema */ + u8 bTemp; /* True for TEMP schema entries */ + const char *zDb; /* Make sure all objects are contained in this database */ + const char *zType; /* Type of the container - used for error messages */ + const Token *pName; /* Name of the container - used for error messages */ +}; + /* Forward declarations */ SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); @@ -19221,20 +19370,55 @@ SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); #define WRC_Abort 2 /* Abandon the tree walk */ /* -** An instance of this structure represents a set of one or more CTEs -** (common table expressions) created by a single WITH clause. +** A single common table expression +*/ +struct Cte { + char *zName; /* Name of this CTE */ + ExprList *pCols; /* List of explicit column names, or NULL */ + Select *pSelect; /* The definition of this CTE */ + const char *zCteErr; /* Error message for circular references */ + CteUse *pUse; /* Usage information for this CTE */ + u8 eM10d; /* The MATERIALIZED flag */ +}; + +/* +** Allowed values for the materialized flag (eM10d): +*/ +#define M10d_Yes 0 /* AS MATERIALIZED */ +#define M10d_Any 1 /* Not specified. Query planner's choice */ +#define M10d_No 2 /* AS NOT MATERIALIZED */ + +/* +** An instance of the With object represents a WITH clause containing +** one or more CTEs (common table expressions). */ struct With { - int nCte; /* Number of CTEs in the WITH clause */ - With *pOuter; /* Containing WITH clause, or NULL */ - struct Cte { /* For each CTE in the WITH clause.... */ - char *zName; /* Name of this CTE */ - ExprList *pCols; /* List of explicit column names, or NULL */ - Select *pSelect; /* The definition of this CTE */ - const char *zCteErr; /* Error message for circular references */ - } a[1]; + int nCte; /* Number of CTEs in the WITH clause */ + With *pOuter; /* Containing WITH clause, or NULL */ + Cte a[1]; /* For each CTE in the WITH clause.... */ +}; + +/* +** The Cte object is not guaranteed to persist for the entire duration +** of code generation. (The query flattener or other parser tree +** edits might delete it.) The following object records information +** about each Common Table Expression that must be preserved for the +** duration of the parse. +** +** The CteUse objects are freed using sqlite3ParserAddCleanup() rather +** than sqlite3SelectDelete(), which is what enables them to persist +** until the end of code generation. +*/ +struct CteUse { + int nUse; /* Number of users of this CTE */ + int addrM9e; /* Start of subroutine to compute materialization */ + int regRtn; /* Return address register for addrM9e subroutine */ + int iCur; /* Ephemeral table holding the materialization */ + LogEst nRowEst; /* Estimated number of rows in the table */ + u8 eM10d; /* The MATERIALIZED flag */ }; + #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -19312,7 +19496,6 @@ SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*, int); SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Select*); SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*); -SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p); @@ -19629,6 +19812,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*) SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*); SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +SQLITE_PRIVATE void sqlite3AddReturning(Parse*,ExprList*); SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, sqlite3_vfs**,char**,char **); #define sqlite3CodecQueryParameters(A,B,C) 0 @@ -19694,7 +19878,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, T Token*, Select*, Expr*, IdList*); SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); -SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, SrcItem *); SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); @@ -19722,6 +19906,7 @@ SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe*,WhereInfo*); SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); @@ -19755,7 +19940,7 @@ SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); -SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); +SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *); SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); @@ -19883,6 +20068,7 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc(Parse*, TriggerStep*); #endif SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol); SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int); SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); @@ -19905,7 +20091,6 @@ SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Tok SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); -SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); SQLITE_PRIVATE void sqlite3Int64ToText(i64,char*); @@ -19968,6 +20153,7 @@ SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3*); SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); SQLITE_PRIVATE u8 sqlite3HexToInt(int h); @@ -20031,7 +20217,6 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; -SQLITE_API extern u32 sqlite3_unsupported_selecttrace; #ifndef SQLITE_OMIT_WSD SQLITE_PRIVATE int sqlite3PendingByte; #endif @@ -20050,6 +20235,7 @@ SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, @@ -20067,6 +20253,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse*, SrcList*, Token*); SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); @@ -20090,6 +20277,7 @@ SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); +SQLITE_PRIVATE const char *sqlite3SelectOpName(int); SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG @@ -20220,6 +20408,7 @@ SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); SQLITE_PRIVATE void sqlite3ParserReset(Parse*); +SQLITE_PRIVATE void *sqlite3ParserAddCleanup(Parse*,void(*)(sqlite3*,void*),void*); #ifdef SQLITE_ENABLE_NORMALIZE SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); #endif @@ -20234,23 +20423,32 @@ SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE -SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); +SQLITE_PRIVATE Cte *sqlite3CteNew(Parse*,Token*,ExprList*,Select*,u8); +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3*,Cte*); +SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Cte*); SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8); #else -#define sqlite3WithPush(x,y,z) -#define sqlite3WithDelete(x,y) +# define sqlite3CteNew(P,T,E,S) ((void*)0) +# define sqlite3CteDelete(D,C) +# define sqlite3CteWithAdd(P,W,C) ((void*)0) +# define sqlite3WithDelete(x,y) +# define sqlite3WithPush(x,y,z) #endif #ifndef SQLITE_OMIT_UPSERT -SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); +SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert*,Index*); +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert*); #else -#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) +#define sqlite3UpsertNew(u,v,w,x,y,z) ((Upsert*)0) #define sqlite3UpsertDelete(x,y) -#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertOfIndex(x,y) ((Upsert*)0) +#define sqlite3UpsertNextIsIPK(x) 0 #endif @@ -20746,9 +20944,10 @@ SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; #endif /* -** Flags for select tracing and the ".selecttrace" macro of the CLI +** Tracing flags set by SQLITE_TESTCTRL_TRACEFLAGS. */ -SQLITE_API u32 sqlite3_unsupported_selecttrace = 0; +SQLITE_PRIVATE u32 sqlite3SelectTrace = 0; +SQLITE_PRIVATE u32 sqlite3WhereTrace = 0; /* #include "opcodes.h" */ /* @@ -21167,7 +21366,7 @@ struct Vdbe { Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ - u32 magic; /* Magic number for sanity checking */ + u32 iVdbeMagic; /* Magic number defining state of the SQL statement */ int nMem; /* Number of memory locations currently allocated */ int nCursor; /* Number of slots in apCsr[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ @@ -22672,6 +22871,7 @@ static int isDate( int eType; memset(p, 0, sizeof(*p)); if( argc==0 ){ + if( !sqlite3NotPureFunc(context) ) return 1; return setDateTimeToCurrent(context, p); } if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT @@ -23172,6 +23372,8 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO && op!=SQLITE_FCNTL_LOCK_TIMEOUT + && op!=SQLITE_FCNTL_CKPT_DONE + && op!=SQLITE_FCNTL_CKPT_START ){ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding @@ -23182,7 +23384,12 @@ SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ ** The core must call OsFileControl() though, not OsFileControlHint(), ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably ** means the commit really has failed and an error should be returned - ** to the user. */ + ** to the user. + ** + ** The CKPT_DONE and CKPT_START file-controls are write-only signals + ** to the cksumvfs. Their return code is meaningless and is ignored + ** by the SQLite core, so there is no point in simulating OOMs for them. + */ DO_OS_MALLOC_TEST(id); } #endif @@ -29081,7 +29288,7 @@ SQLITE_API void sqlite3_str_vappendf( case etSRCLIST: { SrcList *pSrc; int k; - struct SrcList_item *pItem; + SrcItem *pItem; if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return; pSrc = va_arg(ap, SrcList*); k = va_arg(ap, int); @@ -29146,7 +29353,7 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ }else{ char *zOld = isMalloced(p) ? p->zText : 0; i64 szNew = p->nChar; - szNew += N + 1; + szNew += (sqlite3_int64)N + 1; if( szNew+p->nChar<=p->mxAlloc ){ /* Force exponential buffer size growth as long as it does not overflow, ** to avoid having to call this routine too often */ @@ -29649,7 +29856,10 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m } sqlite3_str_appendf(&x, ")"); } - sqlite3_str_appendf(&x, " AS"); + if( pCte->pUse ){ + sqlite3_str_appendf(&x, " (pUse=0x%p, nUse=%d)", pCte->pUse, + pCte->pUse->nUse); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inCte-1); sqlite3TreeViewSelect(pView, pCte->pSelect, 0); @@ -29665,7 +29875,7 @@ SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 m SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; for(i=0; inSrc; i++){ - const struct SrcList_item *pItem = &pSrc->a[i]; + const SrcItem *pItem = &pSrc->a[i]; StrAccum x; char zLine[100]; sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); @@ -29688,6 +29898,9 @@ SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc) if( pItem->fg.fromDDL ){ sqlite3_str_appendf(&x, " DDL"); } + if( pItem->fg.isCte ){ + sqlite3_str_appendf(&x, " CteUse=0x%p", pItem->u2.pCteUse); + } sqlite3StrAccumFinish(&x); sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ @@ -31384,6 +31597,16 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); } +/* +** The equivalent of sqlite3Error(db, SQLITE_OK). Clear the error state +** and error message. +*/ +SQLITE_PRIVATE void sqlite3ErrorClear(sqlite3 *db){ + assert( db!=0 ); + db->errCode = SQLITE_OK; + if( db->pErr ) sqlite3ValueSetNull(db->pErr); +} + /* ** Load the sqlite3.iSysErrno field if that is an appropriate thing ** to do based on the SQLite error code in rc. @@ -33330,103 +33553,105 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 77 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"), /* 78 */ "SCopy" OpHelp("r[P2]=r[P1]"), /* 79 */ "IntCopy" OpHelp("r[P2]=r[P1]"), - /* 80 */ "ResultRow" OpHelp("output=r[P1@P2]"), - /* 81 */ "CollSeq" OpHelp(""), - /* 82 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), - /* 83 */ "RealAffinity" OpHelp(""), - /* 84 */ "Cast" OpHelp("affinity(r[P1])"), - /* 85 */ "Permutation" OpHelp(""), - /* 86 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), - /* 87 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), - /* 88 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), - /* 89 */ "Column" OpHelp("r[P3]=PX"), - /* 90 */ "Affinity" OpHelp("affinity(r[P1@P2])"), - /* 91 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), - /* 92 */ "Count" OpHelp("r[P2]=count()"), - /* 93 */ "ReadCookie" OpHelp(""), - /* 94 */ "SetCookie" OpHelp(""), - /* 95 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), - /* 96 */ "OpenRead" OpHelp("root=P2 iDb=P3"), - /* 97 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), - /* 98 */ "OpenDup" OpHelp(""), - /* 99 */ "OpenAutoindex" OpHelp("nColumn=P2"), - /* 100 */ "OpenEphemeral" OpHelp("nColumn=P2"), - /* 101 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), - /* 102 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), - /* 103 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), - /* 105 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), - /* 106 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), - /* 107 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), - /* 108 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), - /* 109 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), - /* 110 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), - /* 111 */ "SorterOpen" OpHelp(""), - /* 112 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), - /* 113 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), - /* 114 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), - /* 115 */ "String8" OpHelp("r[P2]='P4'"), - /* 116 */ "Close" OpHelp(""), - /* 117 */ "ColumnsUsed" OpHelp(""), - /* 118 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), - /* 119 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), - /* 120 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), - /* 121 */ "NewRowid" OpHelp("r[P2]=rowid"), - /* 122 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), - /* 123 */ "Delete" OpHelp(""), - /* 124 */ "ResetCount" OpHelp(""), - /* 125 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), - /* 126 */ "SorterData" OpHelp("r[P2]=data"), - /* 127 */ "RowData" OpHelp("r[P2]=data"), - /* 128 */ "Rowid" OpHelp("r[P2]=rowid"), - /* 129 */ "NullRow" OpHelp(""), - /* 130 */ "SeekEnd" OpHelp(""), - /* 131 */ "IdxInsert" OpHelp("key=r[P2]"), - /* 132 */ "SorterInsert" OpHelp("key=r[P2]"), - /* 133 */ "IdxDelete" OpHelp("key=r[P2@P3]"), - /* 134 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), - /* 135 */ "IdxRowid" OpHelp("r[P2]=rowid"), - /* 136 */ "FinishSeek" OpHelp(""), - /* 137 */ "Destroy" OpHelp(""), - /* 138 */ "Clear" OpHelp(""), - /* 139 */ "ResetSorter" OpHelp(""), - /* 140 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), - /* 141 */ "SqlExec" OpHelp(""), - /* 142 */ "ParseSchema" OpHelp(""), - /* 143 */ "LoadAnalysis" OpHelp(""), - /* 144 */ "DropTable" OpHelp(""), - /* 145 */ "DropIndex" OpHelp(""), - /* 146 */ "DropTrigger" OpHelp(""), - /* 147 */ "IntegrityCk" OpHelp(""), - /* 148 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), - /* 149 */ "Param" OpHelp(""), - /* 150 */ "Real" OpHelp("r[P2]=P4"), - /* 151 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), - /* 152 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), - /* 153 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), - /* 154 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), - /* 155 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 156 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), - /* 157 */ "AggValue" OpHelp("r[P3]=value N=P2"), - /* 158 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), - /* 159 */ "Expire" OpHelp(""), - /* 160 */ "CursorLock" OpHelp(""), - /* 161 */ "CursorUnlock" OpHelp(""), - /* 162 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), - /* 163 */ "VBegin" OpHelp(""), - /* 164 */ "VCreate" OpHelp(""), - /* 165 */ "VDestroy" OpHelp(""), - /* 166 */ "VOpen" OpHelp(""), - /* 167 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), - /* 168 */ "VRename" OpHelp(""), - /* 169 */ "Pagecount" OpHelp(""), - /* 170 */ "MaxPgcnt" OpHelp(""), - /* 171 */ "Trace" OpHelp(""), - /* 172 */ "CursorHint" OpHelp(""), - /* 173 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), - /* 174 */ "Noop" OpHelp(""), - /* 175 */ "Explain" OpHelp(""), - /* 176 */ "Abortable" OpHelp(""), + /* 80 */ "ChngCntRow" OpHelp("output=r[P1]"), + /* 81 */ "ResultRow" OpHelp("output=r[P1@P2]"), + /* 82 */ "CollSeq" OpHelp(""), + /* 83 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"), + /* 84 */ "RealAffinity" OpHelp(""), + /* 85 */ "Cast" OpHelp("affinity(r[P1])"), + /* 86 */ "Permutation" OpHelp(""), + /* 87 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"), + /* 88 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"), + /* 89 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"), + /* 90 */ "Column" OpHelp("r[P3]=PX"), + /* 91 */ "Affinity" OpHelp("affinity(r[P1@P2])"), + /* 92 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"), + /* 93 */ "Count" OpHelp("r[P2]=count()"), + /* 94 */ "ReadCookie" OpHelp(""), + /* 95 */ "SetCookie" OpHelp(""), + /* 96 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"), + /* 97 */ "OpenRead" OpHelp("root=P2 iDb=P3"), + /* 98 */ "OpenWrite" OpHelp("root=P2 iDb=P3"), + /* 99 */ "OpenDup" OpHelp(""), + /* 100 */ "OpenAutoindex" OpHelp("nColumn=P2"), + /* 101 */ "OpenEphemeral" OpHelp("nColumn=P2"), + /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"), + /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"), + /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<>r[P1]"), + /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"), + /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"), + /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"), + /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"), + /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"), + /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"), + /* 112 */ "SorterOpen" OpHelp(""), + /* 113 */ "BitNot" OpHelp("r[P2]= ~r[P1]"), + /* 114 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"), + /* 115 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"), + /* 116 */ "String8" OpHelp("r[P2]='P4'"), + /* 117 */ "Close" OpHelp(""), + /* 118 */ "ColumnsUsed" OpHelp(""), + /* 119 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"), + /* 120 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"), + /* 121 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"), + /* 122 */ "NewRowid" OpHelp("r[P2]=rowid"), + /* 123 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"), + /* 124 */ "RowCell" OpHelp(""), + /* 125 */ "Delete" OpHelp(""), + /* 126 */ "ResetCount" OpHelp(""), + /* 127 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"), + /* 128 */ "SorterData" OpHelp("r[P2]=data"), + /* 129 */ "RowData" OpHelp("r[P2]=data"), + /* 130 */ "Rowid" OpHelp("r[P2]=rowid"), + /* 131 */ "NullRow" OpHelp(""), + /* 132 */ "SeekEnd" OpHelp(""), + /* 133 */ "IdxInsert" OpHelp("key=r[P2]"), + /* 134 */ "SorterInsert" OpHelp("key=r[P2]"), + /* 135 */ "IdxDelete" OpHelp("key=r[P2@P3]"), + /* 136 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"), + /* 137 */ "IdxRowid" OpHelp("r[P2]=rowid"), + /* 138 */ "FinishSeek" OpHelp(""), + /* 139 */ "Destroy" OpHelp(""), + /* 140 */ "Clear" OpHelp(""), + /* 141 */ "ResetSorter" OpHelp(""), + /* 142 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"), + /* 143 */ "SqlExec" OpHelp(""), + /* 144 */ "ParseSchema" OpHelp(""), + /* 145 */ "LoadAnalysis" OpHelp(""), + /* 146 */ "DropTable" OpHelp(""), + /* 147 */ "DropIndex" OpHelp(""), + /* 148 */ "DropTrigger" OpHelp(""), + /* 149 */ "IntegrityCk" OpHelp(""), + /* 150 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"), + /* 151 */ "Param" OpHelp(""), + /* 152 */ "Real" OpHelp("r[P2]=P4"), + /* 153 */ "FkCounter" OpHelp("fkctr[P1]+=P2"), + /* 154 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"), + /* 155 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"), + /* 156 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"), + /* 157 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 158 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"), + /* 159 */ "AggValue" OpHelp("r[P3]=value N=P2"), + /* 160 */ "AggFinal" OpHelp("accum=r[P1] N=P2"), + /* 161 */ "Expire" OpHelp(""), + /* 162 */ "CursorLock" OpHelp(""), + /* 163 */ "CursorUnlock" OpHelp(""), + /* 164 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"), + /* 165 */ "VBegin" OpHelp(""), + /* 166 */ "VCreate" OpHelp(""), + /* 167 */ "VDestroy" OpHelp(""), + /* 168 */ "VOpen" OpHelp(""), + /* 169 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"), + /* 170 */ "VRename" OpHelp(""), + /* 171 */ "Pagecount" OpHelp(""), + /* 172 */ "MaxPgcnt" OpHelp(""), + /* 173 */ "Trace" OpHelp(""), + /* 174 */ "CursorHint" OpHelp(""), + /* 175 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"), + /* 176 */ "Noop" OpHelp(""), + /* 177 */ "Explain" OpHelp(""), + /* 178 */ "Abortable" OpHelp(""), }; return azName[i]; } @@ -50435,6 +50660,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ p->page.pExtra = &p[1]; p->isBulkLocal = 0; p->isAnchor = 0; + p->pLruPrev = 0; /* Initializing this saves a valgrind error */ } (*pCache->pnPurgeable)++; return p; @@ -52353,6 +52579,7 @@ struct PagerSavepoint { Bitvec *pInSavepoint; /* Set of pages in this savepoint */ Pgno nOrig; /* Original number of pages in file */ Pgno iSubRec; /* Index of first record in sub-journal */ + int bTruncateOnRelease; /* If stmt journal may be truncated on RELEASE */ #ifndef SQLITE_OMIT_WAL u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ #endif @@ -52988,6 +53215,9 @@ static int subjRequiresPage(PgHdr *pPg){ for(i=0; inSavepoint; i++){ p = &pPager->aSavepoint[i]; if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + for(i=i+1; inSavepoint; i++){ + pPager->aSavepoint[i].bTruncateOnRelease = 0; + } return 1; } } @@ -58766,6 +58996,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ } aNew[ii].iSubRec = pPager->nSubRec; aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); + aNew[ii].bTruncateOnRelease = 1; if( !aNew[ii].pInSavepoint ){ return SQLITE_NOMEM_BKPT; } @@ -58847,13 +59078,15 @@ SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ /* If this is a release of the outermost savepoint, truncate ** the sub-journal to zero bytes in size. */ if( op==SAVEPOINT_RELEASE ){ - if( nNew==0 && isOpen(pPager->sjfd) ){ + PagerSavepoint *pRel = &pPager->aSavepoint[nNew]; + if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){ /* Only truncate if it is an in-memory sub-journal. */ if( sqlite3JournalIsInMemory(pPager->sjfd) ){ - rc = sqlite3OsTruncate(pPager->sjfd, 0); + i64 sz = (pPager->pageSize+4)*pRel->iSubRec; + rc = sqlite3OsTruncate(pPager->sjfd, sz); assert( rc==SQLITE_OK ); } - pPager->nSubRec = 0; + pPager->nSubRec = pRel->iSubRec; } } /* Else this is a rollback operation, playback the specified savepoint. @@ -64149,6 +64382,7 @@ struct BtShared { Btree *pWriter; /* Btree with currently open write transaction */ #endif u8 *pTmpSpace; /* Temp space sufficient to hold a single cell */ + int nPreformatSize; /* Size of last cell written by TransferRow() */ }; /* @@ -65862,6 +66096,24 @@ static SQLITE_NOINLINE void btreeParseCellAdjustSizeForOverflow( pInfo->nSize = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell) + 4; } +/* +** Given a record with nPayload bytes of payload stored within btree +** page pPage, return the number of bytes of payload stored locally. +*/ +static int btreePayloadToLocal(MemPage *pPage, i64 nPayload){ + int maxLocal; /* Maximum amount of payload held locally */ + maxLocal = pPage->maxLocal; + if( nPayload<=maxLocal ){ + return nPayload; + }else{ + int minLocal; /* Minimum amount of payload held locally */ + int surplus; /* Overflow payload available for local storage */ + minLocal = pPage->minLocal; + surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize-4); + return ( surplus <= maxLocal ) ? surplus : minLocal; + } +} + /* ** The following routines are implementations of the MemPage.xParseCell() ** method. @@ -67602,6 +67854,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, ((pageSize-1)&pageSize)==0 ){ assert( (pageSize & 7)==0 ); assert( !pBt->pCursor ); + if( nReserve>32 && pageSize==512 ) pageSize = 1024; pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } @@ -72337,7 +72590,9 @@ static int balance_nonroot( } pgno = get4byte(pRight); while( 1 ){ - rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + if( rc==SQLITE_OK ){ + rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + } if( rc ){ memset(apOld, 0, (i+1)*sizeof(MemPage*)); goto balance_cleanup; @@ -72376,12 +72631,10 @@ static int balance_nonroot( if( pBt->btsFlags & BTS_FAST_SECURE ){ int iOff; + /* If the following if() condition is not true, the db is corrupted. + ** The call to dropCell() below will detect this. */ iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData); - if( (iOff+szNew[i])>(int)pBt->usableSize ){ - rc = SQLITE_CORRUPT_BKPT; - memset(apOld, 0, (i+1)*sizeof(MemPage*)); - goto balance_cleanup; - }else{ + if( (iOff+szNew[i])<=(int)pBt->usableSize ){ memcpy(&aOvflSpace[iOff], apDiv[i], szNew[i]); apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; } @@ -72675,6 +72928,9 @@ static int balance_nonroot( apOld[i] = 0; rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; + if( sqlite3PagerPageRefcount(pNew->pDbPage)!=1+(i==(iParentIdx-nxDiv)) ){ + rc = SQLITE_CORRUPT_BKPT; + } if( rc ) goto balance_cleanup; }else{ assert( i>0 ); @@ -72711,7 +72967,7 @@ static int balance_nonroot( aPgOrder[i] = aPgno[i] = apNew[i]->pgno; aPgFlags[i] = apNew[i]->pDbPage->flags; for(j=0; jpKeyInfo==0 ); if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); @@ -73397,7 +73654,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** keys with no associated data. If the cursor was opened expecting an ** intkey table, the caller should be inserting integer keys with a ** blob of associated data. */ - assert( (pX->pKey==0)==(pCur->pKeyInfo==0) ); + assert( (flags & BTREE_PREFORMAT) || (pX->pKey==0)==(pCur->pKeyInfo==0) ); /* Save the positions of any other cursors open on this table. ** @@ -73507,7 +73764,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( || CORRUPT_DB ); pPage = pCur->pPage; - assert( pPage->intKey || pX->nKey>=0 ); + assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) ); assert( pPage->leaf || !pPage->intKey ); if( pPage->nFree<0 ){ if( pCur->eState>CURSOR_INVALID ){ @@ -73524,7 +73781,21 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( assert( pPage->isInit ); newCell = pBt->pTmpSpace; assert( newCell!=0 ); - rc = fillInCell(pPage, newCell, pX, &szNew); + if( flags & BTREE_PREFORMAT ){ + rc = SQLITE_OK; + szNew = pBt->nPreformatSize; + if( szNew<4 ) szNew = 4; + if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ + CellInfo info; + pPage->xParseCell(pPage, newCell, &info); + if( info.nPayload!=info.nLocal ){ + Pgno ovfl = get4byte(&newCell[szNew-4]); + ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); + } + } + }else{ + rc = fillInCell(pPage, newCell, pX, &szNew); + } if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); @@ -73631,6 +73902,114 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( return rc; } +/* +** This function is used as part of copying the current row from cursor +** pSrc into cursor pDest. If the cursors are open on intkey tables, then +** parameter iKey is used as the rowid value when the record is copied +** into pDest. Otherwise, the record is copied verbatim. +** +** This function does not actually write the new value to cursor pDest. +** Instead, it creates and populates any required overflow pages and +** writes the data for the new cell into the BtShared.pTmpSpace buffer +** for the destination database. The size of the cell, in bytes, is left +** in BtShared.nPreformatSize. The caller completes the insertion by +** calling sqlite3BtreeInsert() with the BTREE_PREFORMAT flag specified. +** +** SQLITE_OK is returned if successful, or an SQLite error code otherwise. +*/ +SQLITE_PRIVATE int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ + int rc = SQLITE_OK; + BtShared *pBt = pDest->pBt; + u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ + const u8 *aIn; /* Pointer to next input buffer */ + u32 nIn; /* Size of input buffer aIn[] */ + u32 nRem; /* Bytes of data still to copy */ + + getCellInfo(pSrc); + aOut += putVarint32(aOut, pSrc->info.nPayload); + if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); + nIn = pSrc->info.nLocal; + aIn = pSrc->info.pPayload; + if( aIn+nIn>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + nRem = pSrc->info.nPayload; + if( nIn==nRem && nInpPage->maxLocal ){ + memcpy(aOut, aIn, nIn); + pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); + }else{ + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; + u32 nOut; /* Size of output buffer aOut[] */ + + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); + if( nOutinfo.nPayload ){ + pPgnoOut = &aOut[nOut]; + pBt->nPreformatSize += 4; + } + + if( nRem>nIn ){ + if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ + return SQLITE_CORRUPT_BKPT; + } + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 ){ + Pgno pgnoNew; + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + if( ISAUTOVACUUM && pPageOut ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); + } + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pBt->usableSize - 4, nRem); + } + } + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); + } + + return rc; +} + /* ** Delete the entry that the cursor is pointing to. ** @@ -78019,7 +78398,7 @@ SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ p->pNext = db->pVdbe; p->pPrev = 0; db->pVdbe = p; - p->magic = VDBE_MAGIC_INIT; + p->iVdbeMagic = VDBE_MAGIC_INIT; p->pParse = pParse; pParse->pVdbe = p; assert( pParse->aLabel==0 ); @@ -78220,7 +78599,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ VdbeOp *pOp; i = p->nOp; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( op>=0 && op<0xff ); if( p->nOpAlloc<=i ){ return growOp3(p, op, p1, p2, p3); @@ -78455,9 +78834,10 @@ SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ ** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. */ -SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere, u16 p5){ int j; sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + sqlite3VdbeChangeP5(p, p5); for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); sqlite3MayAbort(p->pParse); } @@ -78549,7 +78929,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); - assert( v->magic==VDBE_MAGIC_INIT ); + assert( v->iVdbeMagic==VDBE_MAGIC_INIT ); assert( j<-p->nLabel ); assert( j>=0 ); #ifdef SQLITE_DEBUG @@ -78874,7 +79254,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ ** Return the address of the next instruction to be inserted. */ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); return p->nOp; } @@ -78959,7 +79339,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( int i; VdbeOp *pOut, *pFirst; assert( nOp>0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){ return 0; } @@ -79283,7 +79663,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int sqlite3 *db; assert( p!=0 ); db = p->db; - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( p->aOp!=0 || db->mallocFailed ); if( db->mallocFailed ){ if( n!=P4_VTAB ) freeP4(db, n, (void*)*(char**)&zP4); @@ -79412,7 +79792,7 @@ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); if( addr<0 ){ addr = p->nOp - 1; } @@ -80097,7 +80477,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( Op *pOp; /* Current opcode */ assert( p->explain ); - assert( p->magic==VDBE_MAGIC_RUN ); + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); /* Even though this opcode does not use dynamic strings for @@ -80277,14 +80657,14 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ int i; #endif assert( p!=0 ); - assert( p->magic==VDBE_MAGIC_INIT || p->magic==VDBE_MAGIC_RESET ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT || p->iVdbeMagic==VDBE_MAGIC_RESET ); /* There should be at least one opcode. */ assert( p->nOp>0 ); /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ - p->magic = VDBE_MAGIC_RUN; + p->iVdbeMagic = VDBE_MAGIC_RUN; #ifdef SQLITE_DEBUG for(i=0; inMem; i++){ @@ -80340,8 +80720,10 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); - assert( p->magic==VDBE_MAGIC_INIT ); + assert( p->iVdbeMagic==VDBE_MAGIC_INIT ); assert( pParse==p->pParse ); + p->pVList = pParse->pVList; + pParse->pVList = 0; db = p->db; assert( db->mallocFailed==0 ); nVar = pParse->nVar; @@ -80426,8 +80808,6 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( } } - p->pVList = pParse->pVList; - pParse->pVList = 0; if( db->mallocFailed ){ p->nVar = 0; p->nCursor = 0; @@ -81025,7 +81405,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ ** one, or the complete transaction if there is no statement transaction. */ - if( p->magic!=VDBE_MAGIC_RUN ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; } if( db->mallocFailed ){ @@ -81183,7 +81563,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ assert( db->nVdbeRead>=db->nVdbeWrite ); assert( db->nVdbeWrite>=0 ); } - p->magic = VDBE_MAGIC_HALT; + p->iVdbeMagic = VDBE_MAGIC_HALT; checkActiveVdbeCnt(db); if( db->mallocFailed ){ p->rc = SQLITE_NOMEM_BKPT; @@ -81356,7 +81736,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ } } #endif - p->magic = VDBE_MAGIC_RESET; + p->iVdbeMagic = VDBE_MAGIC_RESET; return p->rc & db->errMask; } @@ -81366,7 +81746,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ */ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; - if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ + if( p->iVdbeMagic==VDBE_MAGIC_RUN || p->iVdbeMagic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } @@ -81427,7 +81807,7 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } - if( p->magic!=VDBE_MAGIC_INIT ){ + if( p->iVdbeMagic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); sqlite3DbFree(db, p->pVList); sqlite3DbFree(db, p->pFree); @@ -81475,7 +81855,7 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } - p->magic = VDBE_MAGIC_DEAD; + p->iVdbeMagic = VDBE_MAGIC_DEAD; p->db = 0; sqlite3DbFreeNN(db, p); } @@ -83854,7 +84234,7 @@ static int sqlite3Step(Vdbe *p){ int rc; assert(p); - if( p->magic!=VDBE_MAGIC_RUN ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN ){ /* We used to require that sqlite3_reset() be called before retrying ** sqlite3_step() after any error or after SQLITE_DONE. But beginning ** with version 3.7.0, we changed this so that sqlite3_reset() would @@ -84570,7 +84950,7 @@ static int vdbeUnbind(Vdbe *p, int i){ return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(p->db->mutex); - if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ + if( p->iVdbeMagic!=VDBE_MAGIC_RUN || p->pc>=0 ){ sqlite3Error(p->db, SQLITE_MISUSE); sqlite3_mutex_leave(p->db->mutex); sqlite3_log(SQLITE_MISUSE, @@ -84924,7 +85304,7 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ */ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; - return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0; + return v!=0 && v->iVdbeMagic==VDBE_MAGIC_RUN && v->pc>=0; } /* @@ -85416,7 +85796,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql( assert( idx>0 ); } zRawSql += nToken; - nextIndex = idx + 1; + nextIndex = MAX(idx + 1, nextIndex); assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ @@ -86262,7 +86642,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec( #endif /*** INSERT STACK UNION HERE ***/ - assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + assert( p->iVdbeMagic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ @@ -87022,6 +87402,26 @@ case OP_IntCopy: { /* out2 */ break; } +/* Opcode: ChngCntRow P1 P2 * * * +** Synopsis: output=r[P1] +** +** Output value in register P1 as the chance count for a DML statement, +** due to the "PRAGMA count_changes=ON" setting. Or, if there was a +** foreign key error in the statement, trigger the error now. +** +** This opcode is a variant of OP_ResultRow that checks the foreign key +** immediate constraint count and throws an error if the count is +** non-zero. The P2 opcode must be 1. +*/ +case OP_ChngCntRow: { + assert( pOp->p2==1 ); + if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){ + goto abort_due_to_error; + } + /* Fall through to the next case, OP_ResultRow */ + /* no break */ deliberate_fall_through +} + /* Opcode: ResultRow P1 P2 * * * ** Synopsis: output=r[P1@P2] ** @@ -87038,34 +87438,6 @@ case OP_ResultRow: { assert( pOp->p1>0 ); assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); - /* If this statement has violated immediate foreign key constraints, do - ** not return the number of rows modified. And do not RELEASE the statement - ** transaction. It needs to be rolled back. */ - if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ - assert( db->flags&SQLITE_CountRows ); - assert( p->usesStmtJournal ); - goto abort_due_to_error; - } - - /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then - ** DML statements invoke this opcode to return the number of rows - ** modified to the user. This is the only way that a VM that - ** opens a statement transaction may invoke this opcode. - ** - ** In case this is such a statement, close any statement transaction - ** opened by this VM before returning control to the user. This is to - ** ensure that statement-transactions are always nested, not overlapping. - ** If the open statement-transaction is not closed here, then the user - ** may step another VM that opens its own statement transaction. This - ** may lead to overlapping statement transactions. - ** - ** The statement transaction is never a top-level transaction. Hence - ** the RELEASE call below can never fail. - */ - assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); - rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); - assert( rc==SQLITE_OK ); - /* Invalidate all ephemeral cursor row caches */ p->cacheCtr = (p->cacheCtr + 2)|1; @@ -89534,7 +89906,7 @@ case OP_OpenEphemeral: { aMem[pOp->p3].z = ""; } pCx = p->apCsr[pOp->p1]; - if( pCx && pCx->pBtx ){ + if( pCx && ALWAYS(pCx->pBtx) ){ /* If the ephermeral table is already open, erase all existing content ** so that the table is empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); @@ -90486,8 +90858,10 @@ case OP_NewRowid: { /* out2 */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ +#ifndef SQLITE_OMIT_AUTOINCREMENT Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ +#endif v = 0; res = 0; @@ -90703,7 +91077,8 @@ case OP_Insert: { } x.pKey = 0; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + seekResult ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; @@ -90720,6 +91095,33 @@ case OP_Insert: { break; } +/* Opcode: RowCell P1 P2 P3 * * +** +** P1 and P2 are both open cursors. Both must be opened on the same type +** of table - intkey or index. This opcode is used as part of copying +** the current row from P2 into P1. If the cursors are opened on intkey +** tables, register P3 contains the rowid to use with the new record in +** P1. If they are opened on index tables, P3 is not used. +** +** This opcode must be followed by either an Insert or InsertIdx opcode +** with the OPFLAG_PREFORMAT flag set to complete the insert operation. +*/ +case OP_RowCell: { + VdbeCursor *pDest; /* Cursor to write to */ + VdbeCursor *pSrc; /* Cursor to read from */ + i64 iKey; /* Rowid value to insert with */ + assert( pOp[1].opcode==OP_Insert || pOp[1].opcode==OP_IdxInsert ); + assert( pOp[1].opcode==OP_Insert || pOp->p3==0 ); + assert( pOp[1].opcode==OP_IdxInsert || pOp->p3>0 ); + assert( pOp[1].p5 & OPFLAG_PREFORMAT ); + pDest = p->apCsr[pOp->p1]; + pSrc = p->apCsr[pOp->p2]; + iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0; + rc = sqlite3BtreeTransferRow(pDest->uc.pCursor, pSrc->uc.pCursor, iKey); + if( rc!=SQLITE_OK ) goto abort_due_to_error; + break; +}; + /* Opcode: Delete P1 P2 P3 P4 P5 ** ** Delete the record at which the P1 cursor is currently pointing. @@ -91375,7 +91777,7 @@ case OP_IdxInsert: { /* in2 */ assert( pC!=0 ); assert( !isSorter(pC) ); pIn2 = &aMem[pOp->p2]; - assert( pIn2->flags & MEM_Blob ); + assert( (pIn2->flags & MEM_Blob) || (pOp->p5 & OPFLAG_PREFORMAT) ); if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isTable==0 ); @@ -91386,7 +91788,7 @@ case OP_IdxInsert: { /* in2 */ x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); @@ -91459,7 +91861,7 @@ case OP_IdxDelete: { rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; }else if( pOp->p5 ){ - rc = SQLITE_CORRUPT_INDEX; + rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption"); goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); @@ -91885,7 +92287,7 @@ case OP_ParseSchema: { if( pOp->p4.z==0 ){ sqlite3SchemaClear(db->aDb[iDb].pSchema); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; - rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, pOp->p5); db->mDbFlags |= DBFLAG_SchemaChange; p->expired = 0; }else @@ -97593,7 +97995,6 @@ struct MemJournal { int nChunkSize; /* In-memory chunk-size */ int nSpill; /* Bytes of data before flushing */ - int nSize; /* Bytes of data currently in memory */ FileChunk *pFirst; /* Head of in-memory chunk-list */ FilePoint endpoint; /* Pointer to the end of the file */ FilePoint readpoint; /* Pointer to the end of the last xRead() */ @@ -97654,14 +98055,13 @@ static int memjrnlRead( /* ** Free the list of FileChunk structures headed at MemJournal.pFirst. */ -static void memjrnlFreeChunks(MemJournal *p){ +static void memjrnlFreeChunks(FileChunk *pFirst){ FileChunk *pIter; FileChunk *pNext; - for(pIter=p->pFirst; pIter; pIter=pNext){ + for(pIter=pFirst; pIter; pIter=pNext){ pNext = pIter->pNext; sqlite3_free(pIter); } - p->pFirst = 0; } /* @@ -97688,7 +98088,7 @@ static int memjrnlCreateFile(MemJournal *p){ } if( rc==SQLITE_OK ){ /* No error has occurred. Free the in-memory buffers. */ - memjrnlFreeChunks(©); + memjrnlFreeChunks(copy.pFirst); } } if( rc!=SQLITE_OK ){ @@ -97771,7 +98171,6 @@ static int memjrnlWrite( nWrite -= iSpace; p->endpoint.iOffset += iSpace; } - p->nSize = iAmt + iOfst; } } @@ -97779,22 +98178,30 @@ static int memjrnlWrite( } /* -** Truncate the file. -** -** If the journal file is already on disk, truncate it there. Or, if it -** is still in main memory but is being truncated to zero bytes in size, -** ignore +** Truncate the in-memory file. */ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ MemJournal *p = (MemJournal *)pJfd; - if( ALWAYS(size==0) ){ - memjrnlFreeChunks(p); - p->nSize = 0; - p->endpoint.pChunk = 0; - p->endpoint.iOffset = 0; - p->readpoint.pChunk = 0; - p->readpoint.iOffset = 0; + FileChunk *pIter = 0; + + if( size==0 ){ + memjrnlFreeChunks(p->pFirst); + p->pFirst = 0; + }else{ + i64 iOff = p->nChunkSize; + for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ + iOff += p->nChunkSize; + } + if( ALWAYS(pIter) ){ + memjrnlFreeChunks(pIter->pNext); + pIter->pNext = 0; + } } + + p->endpoint.pChunk = pIter; + p->endpoint.iOffset = size; + p->readpoint.pChunk = 0; + p->readpoint.iOffset = 0; return SQLITE_OK; } @@ -97803,7 +98210,7 @@ static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ */ static int memjrnlClose(sqlite3_file *pJfd){ MemJournal *p = (MemJournal *)pJfd; - memjrnlFreeChunks(p); + memjrnlFreeChunks(p->pFirst); return SQLITE_OK; } @@ -97977,7 +98384,7 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ ** Walk all expressions linked into the list of Window objects passed ** as the second argument. */ -static int walkWindowList(Walker *pWalker, Window *pList){ +static int walkWindowList(Walker *pWalker, Window *pList, int bOneOnly){ Window *pWin; for(pWin=pList; pWin; pWin=pWin->pNextWin){ int rc; @@ -97996,6 +98403,7 @@ static int walkWindowList(Walker *pWalker, Window *pList){ if( NEVER(rc) ) return WRC_Abort; rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; + if( bOneOnly ) break; } return WRC_Continue; } @@ -98043,7 +98451,7 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ - if( walkWindowList(pWalker, pExpr->y.pWin) ) return WRC_Abort; + if( walkWindowList(pWalker, pExpr->y.pWin, 1) ) return WRC_Abort; } #endif } @@ -98090,7 +98498,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ if( pParse && IN_RENAME_OBJECT ){ /* The following may return WRC_Abort if there are unresolvable ** symbols (e.g. a table that does not exist) in a window definition. */ - int rc = walkWindowList(pWalker, p->pWinDefn); + int rc = walkWindowList(pWalker, p->pWinDefn, 0); return rc; } } @@ -98108,7 +98516,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ SrcList *pSrc; int i; - struct SrcList_item *pItem; + SrcItem *pItem; pSrc = p->pSrc; if( pSrc ){ @@ -98274,7 +98682,6 @@ static void resolveAlias( ExprList *pEList, /* A result set */ int iCol, /* A column in the result set. 0..pEList->nExpr-1 */ Expr *pExpr, /* Transform this into an alias to the result set */ - const char *zType, /* "GROUP" or "ORDER" or "" */ int nSubquery /* Number of subqueries that the label is moving */ ){ Expr *pOrig; /* The iCol-th column of the result set */ @@ -98287,7 +98694,7 @@ static void resolveAlias( db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ - if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); + incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } @@ -98316,7 +98723,6 @@ static void resolveAlias( } sqlite3DbFree(db, pDup); } - ExprSetProperty(pExpr, EP_Alias); } @@ -98451,8 +98857,8 @@ static int lookupName( int cntTab = 0; /* Number of matching table names */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ - struct SrcList_item *pItem; /* Use for looping over pSrcList items */ - struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ + SrcItem *pItem; /* Use for looping over pSrcList items */ + SrcItem *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ int eNewExprOp = TK_COLUMN; /* New value for pExpr->op on success */ @@ -98573,25 +98979,29 @@ static int lookupName( #if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference. Or - ** maybe it is an excluded.* from an upsert. + ** maybe it is an excluded.* from an upsert. Or maybe it is + ** a reference in the RETURNING clause to a table being modified. */ - if( zDb==0 && zTab!=0 && cntTab==0 ){ + if( cnt==0 && zDb==0 ){ pTab = 0; #ifndef SQLITE_OMIT_TRIGGER if( pParse->pTriggerTab!=0 ){ int op = pParse->eTriggerOp; assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ pExpr->iTable = 1; pTab = pParse->pTriggerTab; - }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ pExpr->iTable = 0; pTab = pParse->pTriggerTab; + }else if( pParse->bReturning && (pNC->ncFlags & NC_UBaseReg)!=0 ){ + pExpr->iTable = op!=TK_DELETE; + pTab = pParse->pTriggerTab; } } #endif /* SQLITE_OMIT_TRIGGER */ #ifndef SQLITE_OMIT_UPSERT - if( (pNC->ncFlags & NC_UUpsert)!=0 ){ + if( (pNC->ncFlags & NC_UUpsert)!=0 && zTab!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pTab; @@ -98619,6 +99029,7 @@ static int lookupName( } if( iColnCol ){ cnt++; + pMatch = 0; #ifndef SQLITE_OMIT_UPSERT if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ testcase( iCol==(-1) ); @@ -98630,27 +99041,32 @@ static int lookupName( pExpr->iTable = pNC->uNC.pUpsert->regData + sqlite3TableColumnToStorage(pTab, iCol); eNewExprOp = TK_REGISTER; - ExprSetProperty(pExpr, EP_Alias); } }else #endif /* SQLITE_OMIT_UPSERT */ { -#ifndef SQLITE_OMIT_TRIGGER - if( iCol<0 ){ - pExpr->affExpr = SQLITE_AFF_INTEGER; - }else if( pExpr->iTable==0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<y.pTab = pTab; - pExpr->iColumn = (i16)iCol; - eNewExprOp = TK_TRIGGER; + if( pParse->bReturning ){ + eNewExprOp = TK_REGISTER; + pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable + + sqlite3TableColumnToStorage(pTab, iCol) + 1; + }else{ + pExpr->iColumn = (i16)iCol; + eNewExprOp = TK_TRIGGER; +#ifndef SQLITE_OMIT_TRIGGER + if( iCol<0 ){ + pExpr->affExpr = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<newmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<op==TK_ID ); if( ExprHasProperty(pExpr,EP_DblQuoted) && areDoubleQuotedStringsEnabled(db, pTopNC) + && (db->init.bDropColumn==0 || sqlite3StrICmp(zCol, db->init.azInit[0])!=0) ){ /* If a double-quoted identifier does not match any known column name, ** then treat it as a string. @@ -98769,6 +99186,11 @@ static int lookupName( ** Someday, I hope to get rid of this hack. Unfortunately there is ** a huge amount of legacy SQL that uses it. So for now, we just ** issue a warning. + ** + ** 2021-03-15: ticket 1c24a659e6d7f3a1 + ** Do not do the ID-to-STRING conversion when doing the schema + ** sanity check following a DROP COLUMN if the identifer name matches + ** the name of the column being dropped. */ sqlite3_log(SQLITE_WARNING, "double-quoted string literal: \"%w\"", zCol); @@ -98822,18 +99244,24 @@ static int lookupName( /* Clean up and return */ - sqlite3ExprDelete(db, pExpr->pLeft); - pExpr->pLeft = 0; - sqlite3ExprDelete(db, pExpr->pRight); - pExpr->pRight = 0; + if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ + sqlite3ExprDelete(db, pExpr->pLeft); + pExpr->pLeft = 0; + sqlite3ExprDelete(db, pExpr->pRight); + pExpr->pRight = 0; + } pExpr->op = eNewExprOp; ExprSetProperty(pExpr, EP_Leaf); lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); - if( !ExprHasProperty(pExpr, EP_Alias) ){ +#ifndef SQLITE_OMIT_AUTHORIZATION + if( pParse->db->xAuth + && (pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER) + ){ sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } +#endif /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ for(;;){ @@ -98855,7 +99283,7 @@ static int lookupName( SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ - struct SrcList_item *pItem = &pSrc->a[iSrc]; + SrcItem *pItem = &pSrc->a[iSrc]; Table *pTab = p->y.pTab = pItem->pTab; p->iTable = pItem->iCursor; if( p->y.pTab->iPKey==iCol ){ @@ -98967,7 +99395,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ */ case TK_ROW: { SrcList *pSrcList = pNC->pSrcList; - struct SrcList_item *pItem; + SrcItem *pItem; assert( pSrcList && pSrcList->nSrc>=1 ); pItem = pSrcList->a; pExpr->op = TK_COLUMN; @@ -98978,6 +99406,47 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ break; } + /* An optimization: Attempt to convert + ** + ** "expr IS NOT NULL" --> "TRUE" + ** "expr IS NULL" --> "FALSE" + ** + ** if we can prove that "expr" is never NULL. Call this the + ** "NOT NULL strength reduction optimization". + ** + ** If this optimization occurs, also restore the NameContext ref-counts + ** to the state they where in before the "column" LHS expression was + ** resolved. This prevents "column" from being counted as having been + ** referenced, which might prevent a SELECT from being erroneously + ** marked as correlated. + */ + case TK_NOTNULL: + case TK_ISNULL: { + int anRef[8]; + NameContext *p; + int i; + for(i=0, p=pNC; p && ipNext, i++){ + anRef[i] = p->nRef; + } + sqlite3WalkExpr(pWalker, pExpr->pLeft); + if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){ + if( pExpr->op==TK_NOTNULL ){ + pExpr->u.zToken = "true"; + ExprSetProperty(pExpr, EP_IsTrue); + }else{ + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + } + pExpr->op = TK_TRUEFALSE; + for(i=0, p=pNC; p && ipNext, i++){ + p->nRef = anRef[i]; + } + sqlite3ExprDelete(pParse->db, pExpr->pLeft); + pExpr->pLeft = 0; + } + return WRC_Prune; + } + /* A column name: ID ** Or table name and column name: ID.ID ** Or a database, table and column: ID.ID.ID @@ -99205,6 +99674,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); + if( pParse->db->mallocFailed ) break; } sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); @@ -99279,7 +99749,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ - if( pRight && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){ + if( ALWAYS(pRight) && (pRight->op==TK_ID || pRight->op==TK_TRUEFALSE) ){ int rc = resolveExprStep(pWalker, pRight); if( rc==WRC_Abort ) return WRC_Abort; if( pRight->op==TK_TRUEFALSE ){ @@ -99595,8 +100065,7 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr); return 1; } - resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, - zType,0); + resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,0); } } return 0; @@ -99781,27 +100250,26 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Recursively resolve names in all subqueries */ for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; + SrcItem *pItem = &p->pSrc->a[i]; if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){ - NameContext *pNC; /* Used to iterate name contexts */ - int nRef = 0; /* Refcount for pOuterNC and outer contexts */ + int nRef = pOuterNC ? pOuterNC->nRef : 0; const char *zSavedContext = pParse->zAuthContext; - /* Count the total number of references to pOuterNC and all of its - ** parent contexts. After resolving references to expressions in - ** pItem->pSelect, check if this value has changed. If so, then - ** SELECT statement pItem->pSelect must be correlated. Set the - ** pItem->fg.isCorrelated flag if this is the case. */ - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; - if( pItem->zName ) pParse->zAuthContext = pItem->zName; sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr || db->mallocFailed ) return WRC_Abort; - for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef -= pNC->nRef; - assert( pItem->fg.isCorrelated==0 && nRef<=0 ); - pItem->fg.isCorrelated = (nRef!=0); + /* If the number of references to the outer context changed when + ** expressions in the sub-select were resolved, the sub-select + ** is correlated. It is not required to check the refcount on any + ** but the innermost outer context object, as lookupName() increments + ** the refcount on all contexts between the current one and the + ** context containing the column when it resolves a name. */ + if( pOuterNC ){ + assert( pItem->fg.isCorrelated==0 && pOuterNC->nRef>=nRef ); + pItem->fg.isCorrelated = (pOuterNC->nRef>nRef); + } } } @@ -99843,7 +100311,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** Minor point: If this is the case, then the expression will be ** re-evaluated for each reference to it. */ - assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 ); + assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert|NC_UBaseReg))==0 ); sNC.uNC.pEList = p->pEList; sNC.ncFlags |= NC_UEList; if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; @@ -99851,7 +100319,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* Resolve names in table-valued-function arguments */ for(i=0; ipSrc->nSrc; i++){ - struct SrcList_item *pItem = &p->pSrc->a[i]; + SrcItem *pItem = &p->pSrc->a[i]; if( pItem->fg.isTabFunc && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) ){ @@ -100260,7 +100728,18 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ - if( pCollName->n>0 ){ + assert( pExpr!=0 || pParse->db->mallocFailed ); + if( pExpr==0 ) return 0; + if( pExpr->op==TK_VECTOR ){ + ExprList *pList = pExpr->x.pList; + if( ALWAYS(pList!=0) ){ + int i; + for(i=0; inExpr; i++){ + pList->a[i].pExpr = sqlite3ExprAddCollateToken(pParse,pList->a[i].pExpr, + pCollName, dequote); + } + } + }else if( pCollName->n>0 ){ Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; @@ -101684,8 +102163,8 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ - struct SrcList_item *pNewItem = &pNew->a[i]; - struct SrcList_item *pOldItem = &p->a[i]; + SrcItem *pNewItem = &pNew->a[i]; + SrcItem *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); @@ -101698,7 +102177,10 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ if( pNewItem->fg.isIndexedBy ){ pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); } - pNewItem->pIBIndex = pOldItem->pIBIndex; + pNewItem->u2 = pOldItem->u2; + if( pNewItem->fg.isCte ){ + pNewItem->u2.pCteUse->nUse++; + } if( pNewItem->fg.isTabFunc ){ pNewItem->u1.pFuncArg = sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); @@ -102736,7 +103218,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex( /* Code an OP_Transaction and OP_TableLock for . */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); - assert( iDb>=0 && iDb=0 && iDbtnum, 0, pTab->zName); @@ -106015,7 +106497,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ /* Check to see if the column is in one of the tables in the FROM ** clause of the aggregate query */ if( ALWAYS(pSrcList!=0) ){ - struct SrcList_item *pItem = pSrcList->a; + SrcItem *pItem = pSrcList->a; for(i=0; inSrc; i++, pItem++){ struct AggInfo_col *pCol; assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); @@ -106304,15 +106786,22 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ ** statement to ensure that the operation has not rendered any schema ** objects unusable. */ -static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ +static void renameTestSchema( + Parse *pParse, /* Parse context */ + const char *zDb, /* Name of db to verify schema of */ + int bTemp, /* True if this is the temp db */ + const char *zWhen, /* "when" part of error message */ + const char *zDropColumn /* Name of column being dropped */ +){ + pParse->colNamesSet = 1; sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." DFLT_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" - " AND sqlite_rename_test(%Q, sql, type, name, %d)=NULL ", + " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %Q)=NULL ", zDb, - zDb, bTemp + zDb, bTemp, zWhen, zDropColumn ); if( bTemp==0 ){ @@ -106321,8 +106810,8 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ "FROM temp." DFLT_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" - " AND sqlite_rename_test(%Q, sql, type, name, 1)=NULL ", - zDb + " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %Q)=NULL ", + zDb, zWhen, zDropColumn ); } } @@ -106331,12 +106820,12 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ ** Generate code to reload the schema for database iDb. And, if iDb!=1, for ** the temp database as well. */ -static void renameReloadSchema(Parse *pParse, int iDb){ +static void renameReloadSchema(Parse *pParse, int iDb, u16 p5){ Vdbe *v = pParse->pVdbe; if( v ){ sqlite3ChangeCookie(pParse, iDb); - sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); - if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0, p5); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0, p5); } } @@ -106485,7 +106974,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " "CASE WHEN tbl_name=%Q COLLATE nocase AND " - " sqlite_rename_test(%Q, sql, type, name, 1) " + " sqlite_rename_test(%Q, sql, type, name, 1, 'after rename',0) " "THEN %Q ELSE tbl_name END " "WHERE type IN ('view', 'trigger')" , zDb, zTabName, zName, zTabName, zDb, zName); @@ -106504,8 +106993,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( } #endif - renameReloadSchema(pParse, iDb); - renameTestSchema(pParse, zDb, iDb==1); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iDb==1, "after rename", 0); exit_rename_table: sqlite3SrcListDelete(db, pSrc); @@ -106636,11 +107125,14 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ *zEnd-- = '\0'; } db->mDbFlags |= DBFLAG_PreferBuiltin; + /* substr() operations on characters, but addColOffset is in bytes. So we + ** have to use printf() to translate between these units: */ sqlite3NestedParse(pParse, "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " - "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " + "sql = printf('%%.%ds, ',sql) || %Q" + " || substr(sql,1+length(printf('%%.%ds',sql))) " "WHERE type = 'table' AND name = %Q", - zDb, pNew->addColOffset, zCol, pNew->addColOffset+1, + zDb, pNew->addColOffset, zCol, pNew->addColOffset, zTab ); sqlite3DbFree(db, zCol); @@ -106664,7 +107156,7 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ } /* Reload the table definition */ - renameReloadSchema(pParse, iDb); + renameReloadSchema(pParse, iDb, INITFLAG_AlterRename); } /* @@ -106764,7 +107256,7 @@ SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ ** Or, if pTab is not a view or virtual table, zero is returned. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -static int isRealTable(Parse *pParse, Table *pTab){ +static int isRealTable(Parse *pParse, Table *pTab, int bDrop){ const char *zType = 0; #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ @@ -106777,15 +107269,16 @@ static int isRealTable(Parse *pParse, Table *pTab){ } #endif if( zType ){ - sqlite3ErrorMsg( - pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName + sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", + (bDrop ? "drop column from" : "rename columns of"), + zType, pTab->zName ); return 1; } return 0; } #else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */ -# define isRealTable(x,y) (0) +# define isRealTable(x,y,z) (0) #endif /* @@ -106814,7 +107307,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( /* Cannot alter a system table */ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; - if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column; /* Which schema holds the table to be altered */ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -106868,8 +107361,8 @@ SQLITE_PRIVATE void sqlite3AlterRenameColumn( ); /* Drop and reload the database schema. */ - renameReloadSchema(pParse, iSchema); - renameTestSchema(pParse, zDb, iSchema==1); + renameReloadSchema(pParse, iSchema, INITFLAG_AlterRename); + renameTestSchema(pParse, zDb, iSchema==1, "after rename", 0); exit_rename_column: sqlite3SrcListDelete(db, pSrc); @@ -107121,23 +107614,33 @@ static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ /* ** Search the Parse object passed as the first argument for a RenameToken -** object associated with parse tree element pPtr. If found, remove it -** from the Parse object and add it to the list maintained by the -** RenameCtx object passed as the second argument. +** object associated with parse tree element pPtr. If found, return a pointer +** to it. Otherwise, return NULL. +** +** If the second argument passed to this function is not NULL and a matching +** RenameToken object is found, remove it from the Parse object and add it to +** the list maintained by the RenameCtx object. */ -static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ +static RenameToken *renameTokenFind( + Parse *pParse, + struct RenameCtx *pCtx, + void *pPtr +){ RenameToken **pp; assert( pPtr!=0 ); for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){ if( (*pp)->p==pPtr ){ RenameToken *pToken = *pp; - *pp = pToken->pNext; - pToken->pNext = pCtx->pList; - pCtx->pList = pToken; - pCtx->nList++; - break; + if( pCtx ){ + *pp = pToken->pNext; + pToken->pNext = pCtx->pList; + pCtx->pList = pToken; + pCtx->nList++; + } + return pToken; } } + return 0; } /* @@ -107208,7 +107711,7 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ */ static void renameColumnParseError( sqlite3_context *pCtx, - int bPost, + const char *zWhen, sqlite3_value *pType, sqlite3_value *pObject, Parse *pParse @@ -107217,8 +107720,8 @@ static void renameColumnParseError( const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3_mprintf("error in %s %s%s: %s", - zT, zN, (bPost ? " after rename" : ""), + zErr = sqlite3_mprintf("error in %s %s%s%s: %s", + zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); sqlite3_result_error(pCtx, zErr, -1); @@ -107283,12 +107786,17 @@ static int renameParseSql( const char *zDb, /* Name of schema SQL belongs to */ sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ - int bTemp /* True if SQL is from temp schema */ + int bTemp, /* True if SQL is from temp schema */ + const char *zDropColumn /* Name of column being dropped */ ){ int rc; char *zErr = 0; db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); + if( zDropColumn ){ + db->init.bDropColumn = 1; + db->init.azInit = (char**)&zDropColumn; + } /* Parse the SQL statement passed as the first argument. If no error ** occurs and the parse does not result in a new table, index or @@ -107297,7 +107805,7 @@ static int renameParseSql( p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = sqlite3RunParser(p, zSql, &zErr); + rc = zSql ? sqlite3RunParser(p, zSql, &zErr) : SQLITE_NOMEM; assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); p->zErrMsg = zErr; @@ -107321,6 +107829,7 @@ static int renameParseSql( #endif db->init.iDb = 0; + db->init.bDropColumn = 0; return rc; } @@ -107450,7 +107959,7 @@ static int renameResolveTrigger(Parse *pParse){ if( pSrc ){ int i; for(i=0; inSrc && rc==SQLITE_OK; i++){ - struct SrcList_item *p = &pSrc->a[i]; + SrcItem *p = &pSrc->a[i]; p->iCursor = pParse->nTab++; if( p->pSelect ){ sqlite3SelectPrep(pParse, p->pSelect, 0); @@ -107476,9 +107985,8 @@ static int renameResolveTrigger(Parse *pParse){ rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); } assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); - if( pStep->pUpsert ){ + if( pStep->pUpsert && rc==SQLITE_OK ){ Upsert *pUpsert = pStep->pUpsert; - assert( rc==SQLITE_OK ); pUpsert->pUpsertSrc = pSrc; sNC.uNC.pUpsert = pUpsert; sNC.ncFlags = NC_UUpsert; @@ -107623,7 +108131,7 @@ static void renameColumnFunc( #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = 0; #endif - rc = renameParseSql(&sParse, zDb, db, zSql, bTemp); + rc = renameParseSql(&sParse, zDb, db, zSql, bTemp, 0); /* Find tokens that need to be replaced. */ memset(&sWalker, 0, sizeof(Walker)); @@ -107665,12 +108173,12 @@ static void renameColumnFunc( for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } - } #ifndef SQLITE_OMIT_GENERATED_COLUMNS - for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); - } + for(i=0; inCol; i++){ + sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + } #endif + } for(pFKey=sParse.pNewTable->pFKey; pFKey; pFKey=pFKey->pNextFrom){ for(i=0; inCol; i++){ @@ -107724,7 +108232,7 @@ static void renameColumnFunc( renameColumnFunc_done: if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -107762,7 +108270,7 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ return WRC_Abort; } for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->pTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, pItem->zName); } @@ -107827,7 +108335,7 @@ static void renameTableFunc( sWalker.xSelectCallback = renameTableSelectCb; sWalker.u.pRename = &sCtx; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, 0); if( rc==SQLITE_OK ){ int isLegacy = (db->flags & SQLITE_LegacyAlter); @@ -107913,7 +108421,7 @@ static void renameTableFunc( } if( rc!=SQLITE_OK ){ if( sParse.zErrMsg ){ - renameColumnParseError(context, 0, argv[1], argv[2], &sParse); + renameColumnParseError(context, "", argv[1], argv[2], &sParse); }else{ sqlite3_result_error_code(context, rc); } @@ -107942,6 +108450,8 @@ static void renameTableFunc( ** 2: Object type ("view", "table", "trigger" or "index"). ** 3: Object name. ** 4: True if object is from temp schema. +** 5: "when" part of error message. +** 6: Name of column being dropped, or NULL. ** ** Unless it finds an error, this function normally returns NULL. However, it ** returns integer value 1 if: @@ -107959,6 +108469,8 @@ static void renameTableTest( char const *zInput = (const char*)sqlite3_value_text(argv[1]); int bTemp = sqlite3_value_int(argv[4]); int isLegacy = (db->flags & SQLITE_LegacyAlter); + char const *zWhen = (const char*)sqlite3_value_text(argv[5]); + char const *zDropColumn = (const char*)sqlite3_value_text(argv[6]); #ifndef SQLITE_OMIT_AUTHORIZATION sqlite3_xauth xAuth = db->xAuth; @@ -107969,7 +108481,7 @@ static void renameTableTest( if( zDb && zInput ){ int rc; Parse sParse; - rc = renameParseSql(&sParse, zDb, db, zInput, bTemp); + rc = renameParseSql(&sParse, zDb, db, zInput, bTemp, zDropColumn); if( rc==SQLITE_OK ){ if( isLegacy==0 && sParse.pNewTable && sParse.pNewTable->pSelect ){ NameContext sNC; @@ -107991,8 +108503,8 @@ static void renameTableTest( } } - if( rc!=SQLITE_OK ){ - renameColumnParseError(context, 1, argv[2], argv[3], &sParse); + if( rc!=SQLITE_OK && zWhen ){ + renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse); } renameParseCleanup(&sParse); } @@ -108002,14 +108514,206 @@ static void renameTableTest( #endif } +/* +** The implementation of internal UDF sqlite_drop_column(). +** +** Arguments: +** +** argv[0]: An integer - the index of the schema containing the table +** argv[1]: CREATE TABLE statement to modify. +** argv[2]: An integer - the index of the column to remove. +** +** The value returned is a string containing the CREATE TABLE statement +** with column argv[2] removed. +*/ +static void dropColumnFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + int iSchema = sqlite3_value_int(argv[0]); + const char *zSql = (const char*)sqlite3_value_text(argv[1]); + int iCol = sqlite3_value_int(argv[2]); + const char *zDb = db->aDb[iSchema].zDbSName; + int rc; + Parse sParse; + RenameToken *pCol; + Table *pTab; + const char *zEnd; + char *zNew = 0; + +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth = db->xAuth; + db->xAuth = 0; +#endif + + UNUSED_PARAMETER(NotUsed); + rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1, 0); + if( rc!=SQLITE_OK ) goto drop_column_done; + pTab = sParse.pNewTable; + if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ + /* This can happen if the sqlite_schema table is corrupt */ + rc = SQLITE_CORRUPT_BKPT; + goto drop_column_done; + } + + pCol = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol].zName); + if( iColnCol-1 ){ + RenameToken *pEnd; + pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zName); + zEnd = (const char*)pEnd->t.z; + }else{ + zEnd = (const char*)&zSql[pTab->addColOffset]; + while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--; + } + + zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd); + sqlite3_result_text(context, zNew, -1, SQLITE_TRANSIENT); + sqlite3_free(zNew); + +drop_column_done: + renameParseCleanup(&sParse); +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + if( rc!=SQLITE_OK ){ + sqlite3_result_error_code(context, rc); + } +} + +/* +** This function is called by the parser upon parsing an +** +** ALTER TABLE pSrc DROP COLUMN pName +** +** statement. Argument pSrc contains the possibly qualified name of the +** table being edited, and token pName the name of the column to drop. +*/ +SQLITE_PRIVATE void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){ + sqlite3 *db = pParse->db; /* Database handle */ + Table *pTab; /* Table to modify */ + int iDb; /* Index of db containing pTab in aDb[] */ + const char *zDb; /* Database containing pTab ("main" etc.) */ + char *zCol = 0; /* Name of column to drop */ + int iCol; /* Index of column zCol in pTab->aCol[] */ + + /* Look up the table being altered. */ + assert( pParse->pNewTable==0 ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + if( NEVER(db->mallocFailed) ) goto exit_drop_column; + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + if( !pTab ) goto exit_drop_column; + + /* Make sure this is not an attempt to ALTER a view, virtual table or + ** system table. */ + if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column; + if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column; + + /* Find the index of the column being dropped. */ + zCol = sqlite3NameFromToken(db, pName); + if( zCol==0 ){ + assert( db->mallocFailed ); + goto exit_drop_column; + } + iCol = sqlite3ColumnIndex(pTab, zCol); + if( iCol<0 ){ + sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zCol); + goto exit_drop_column; + } + + /* Do not allow the user to drop a PRIMARY KEY column or a column + ** constrained by a UNIQUE constraint. */ + if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){ + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE", + zCol + ); + goto exit_drop_column; + } + + /* Do not allow the number of columns to go to zero */ + if( pTab->nCol<=1 ){ + sqlite3ErrorMsg(pParse, "cannot drop column \"%s\": no other columns exist",zCol); + goto exit_drop_column; + } + + /* Edit the sqlite_schema table */ + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + assert( iDb>=0 ); + zDb = db->aDb[iDb].zDbSName; + renameTestSchema(pParse, zDb, iDb==1, "", 0); + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET " + "sql = sqlite_drop_column(%d, sql, %d) " + "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" + , zDb, iDb, iCol, pTab->zName + ); + + /* Drop and reload the database schema. */ + renameReloadSchema(pParse, iDb, INITFLAG_AlterDrop); + renameTestSchema(pParse, zDb, iDb==1, "after drop column", zCol); + + /* Edit rows of table on disk */ + if( pParse->nErr==0 && (pTab->aCol[iCol].colFlags & COLFLAG_VIRTUAL)==0 ){ + int i; + int addr; + int reg; + int regRec; + Index *pPk = 0; + int nField = 0; /* Number of non-virtual columns after drop */ + int iCur; + Vdbe *v = sqlite3GetVdbe(pParse); + iCur = pParse->nTab++; + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenWrite); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + reg = ++pParse->nMem; + pParse->nMem += pTab->nCol; + if( HasRowid(pTab) ){ + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, reg); + }else{ + pPk = sqlite3PrimaryKeyIndex(pTab); + } + for(i=0; inCol; i++){ + if( i!=iCol && (pTab->aCol[i].colFlags & COLFLAG_VIRTUAL)==0 ){ + int regOut; + if( pPk ){ + int iPos = sqlite3TableColumnToIndex(pPk, i); + int iColPos = sqlite3TableColumnToIndex(pPk, iCol); + regOut = reg+1+iPos-(iPos>iColPos); + }else{ + regOut = reg+1+nField; + } + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, i, regOut); + nField++; + } + } + regRec = reg + pTab->nCol; + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg+1, nField, regRec); + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iCur, regRec, reg+1, pPk->nKeyCol); + }else{ + sqlite3VdbeAddOp3(v, OP_Insert, iCur, regRec, reg); + } + + sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + } + +exit_drop_column: + sqlite3DbFree(db, zCol); + sqlite3SrcListDelete(db, pSrc); +} + /* ** Register built-in functions used to help implement ALTER TABLE */ SQLITE_PRIVATE void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { - INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), - INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), - INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), + INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), + INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), + INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest), + INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc), }; sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } @@ -110398,6 +111102,62 @@ SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *p } #endif /* SQLITE_OMIT_ATTACH */ +/* +** Expression callback used by sqlite3FixAAAA() routines. +*/ +static int fixExprCb(Walker *p, Expr *pExpr){ + DbFixer *pFix = p->u.pFix; + if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); + if( pExpr->op==TK_VARIABLE ){ + if( pFix->pParse->db->init.busy ){ + pExpr->op = TK_NULL; + }else{ + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + return WRC_Abort; + } + } + return WRC_Continue; +} + +/* +** Select callback used by sqlite3FixAAAA() routines. +*/ +static int fixSelectCb(Walker *p, Select *pSelect){ + DbFixer *pFix = p->u.pFix; + int i; + SrcItem *pItem; + sqlite3 *db = pFix->pParse->db; + int iDb = sqlite3FindDbName(db, pFix->zDb); + SrcList *pList = pSelect->pSrc; + + if( NEVER(pList==0) ) return WRC_Continue; + for(i=0, pItem=pList->a; inSrc; i++, pItem++){ + if( pFix->bTemp==0 ){ + if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ + sqlite3ErrorMsg(pFix->pParse, + "%s %T cannot reference objects in database %s", + pFix->zType, pFix->pName, pItem->zDatabase); + return WRC_Abort; + } + sqlite3DbFree(db, pItem->zDatabase); + pItem->zDatabase = 0; + pItem->pSchema = pFix->pSchema; + pItem->fg.fromDDL = 1; + } +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) + if( sqlite3WalkExpr(&pFix->w, pList->a[i].pOn) ) return WRC_Abort; +#endif + } + if( pSelect->pWith ){ + for(i=0; ipWith->nCte; i++){ + if( sqlite3WalkSelect(p, pSelect->pWith->a[i].pSelect) ){ + return WRC_Abort; + } + } + } + return WRC_Continue; +} + /* ** Initialize a DbFixer structure. This routine must be called prior ** to passing the structure to one of the sqliteFixAAAA() routines below. @@ -110409,9 +111169,7 @@ SQLITE_PRIVATE void sqlite3FixInit( const char *zType, /* "view", "trigger", or "index" */ const Token *pName /* Name of the view, trigger, or index */ ){ - sqlite3 *db; - - db = pParse->db; + sqlite3 *db = pParse->db; assert( db->nDb>iDb ); pFix->pParse = pParse; pFix->zDb = db->aDb[iDb].zDbSName; @@ -110419,6 +111177,13 @@ SQLITE_PRIVATE void sqlite3FixInit( pFix->zType = zType; pFix->pName = pName; pFix->bTemp = (iDb==1); + pFix->w.pParse = pParse; + pFix->w.xExprCallback = fixExprCb; + pFix->w.xSelectCallback = fixSelectCb; + pFix->w.xSelectCallback2 = 0; + pFix->w.walkerDepth = 0; + pFix->w.eCode = 0; + pFix->w.u.pFix = pFix; } /* @@ -110439,115 +111204,27 @@ SQLITE_PRIVATE int sqlite3FixSrcList( DbFixer *pFix, /* Context of the fixation */ SrcList *pList /* The Source list to check and modify */ ){ - int i; - struct SrcList_item *pItem; - sqlite3 *db = pFix->pParse->db; - int iDb = sqlite3FindDbName(db, pFix->zDb); - - if( NEVER(pList==0) ) return 0; - - for(i=0, pItem=pList->a; inSrc; i++, pItem++){ - if( pFix->bTemp==0 ){ - if( pItem->zDatabase && iDb!=sqlite3FindDbName(db, pItem->zDatabase) ){ - sqlite3ErrorMsg(pFix->pParse, - "%s %T cannot reference objects in database %s", - pFix->zType, pFix->pName, pItem->zDatabase); - return 1; - } - sqlite3DbFree(db, pItem->zDatabase); - pItem->zDatabase = 0; - pItem->pSchema = pFix->pSchema; - pItem->fg.fromDDL = 1; - } -#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; -#endif - if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ - return 1; - } + int res = 0; + if( pList ){ + Select s; + memset(&s, 0, sizeof(s)); + s.pSrc = pList; + res = sqlite3WalkSelect(&pFix->w, &s); } - return 0; + return res; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) SQLITE_PRIVATE int sqlite3FixSelect( DbFixer *pFix, /* Context of the fixation */ Select *pSelect /* The SELECT statement to be fixed to one database */ ){ - while( pSelect ){ - if( sqlite3FixExprList(pFix, pSelect->pEList) ){ - return 1; - } - if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ - return 1; - } - if( pSelect->pWith ){ - int i; - for(i=0; ipWith->nCte; i++){ - if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ - return 1; - } - } - } - pSelect = pSelect->pPrior; - } - return 0; + return sqlite3WalkSelect(&pFix->w, pSelect); } SQLITE_PRIVATE int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ - while( pExpr ){ - if( !pFix->bTemp ) ExprSetProperty(pExpr, EP_FromDDL); - if( pExpr->op==TK_VARIABLE ){ - if( pFix->pParse->db->init.busy ){ - pExpr->op = TK_NULL; - }else{ - sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); - return 1; - } - } - if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; - if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; - }else{ - if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; - } - if( sqlite3FixExpr(pFix, pExpr->pRight) ){ - return 1; - } - pExpr = pExpr->pLeft; - } - return 0; -} -SQLITE_PRIVATE int sqlite3FixExprList( - DbFixer *pFix, /* Context of the fixation */ - ExprList *pList /* The expression to be fixed to one database */ -){ - int i; - struct ExprList_item *pItem; - if( pList==0 ) return 0; - for(i=0, pItem=pList->a; inExpr; i++, pItem++){ - if( sqlite3FixExpr(pFix, pItem->pExpr) ){ - return 1; - } - } - return 0; + return sqlite3WalkExpr(&pFix->w, pExpr); } #endif @@ -110557,25 +111234,20 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( TriggerStep *pStep /* The trigger step be fixed to one database */ ){ while( pStep ){ - if( sqlite3FixSelect(pFix, pStep->pSelect) ){ - return 1; - } - if( sqlite3FixExpr(pFix, pStep->pWhere) ){ - return 1; - } - if( sqlite3FixExprList(pFix, pStep->pExprList) ){ - return 1; - } - if( pStep->pFrom && sqlite3FixSrcList(pFix, pStep->pFrom) ){ + if( sqlite3WalkSelect(&pFix->w, pStep->pSelect) + || sqlite3WalkExpr(&pFix->w, pStep->pWhere) + || sqlite3WalkExprList(&pFix->w, pStep->pExprList) + || sqlite3FixSrcList(pFix, pStep->pFrom) + ){ return 1; } #ifndef SQLITE_OMIT_UPSERT if( pStep->pUpsert ){ Upsert *pUp = pStep->pUpsert; - if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) - || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) - || sqlite3FixExprList(pFix, pUp->pUpsertSet) - || sqlite3FixExpr(pFix, pUp->pUpsertWhere) + if( sqlite3WalkExprList(&pFix->w, pUp->pUpsertTarget) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertTargetWhere) + || sqlite3WalkExprList(&pFix->w, pUp->pUpsertSet) + || sqlite3WalkExpr(&pFix->w, pUp->pUpsertWhere) ){ return 1; } @@ -110583,6 +111255,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( #endif pStep = pStep->pNext; } + return 0; } #endif @@ -110734,7 +111407,6 @@ SQLITE_PRIVATE void sqlite3AuthRead( Schema *pSchema, /* The schema of the expression */ SrcList *pTabList /* All table that pExpr might refer to */ ){ - sqlite3 *db = pParse->db; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ @@ -110742,8 +111414,8 @@ SQLITE_PRIVATE void sqlite3AuthRead( int iCol; /* Index of column in table */ assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); - assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->xAuth==0 ) return; + assert( !IN_RENAME_OBJECT ); + assert( pParse->db->xAuth!=0 ); iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other @@ -110755,7 +111427,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( pTab = pParse->pTriggerTab; }else{ assert( pTabList ); - for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ + for(iSrc=0; iSrcnSrc; iSrc++){ if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ pTab = pTabList->a[iSrc].pTab; break; @@ -110763,7 +111435,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( } } iCol = pExpr->iColumn; - if( NEVER(pTab==0) ) return; + if( pTab==0 ) return; if( iCol>=0 ){ assert( iColnCol ); @@ -110774,7 +111446,7 @@ SQLITE_PRIVATE void sqlite3AuthRead( }else{ zCol = "ROWID"; } - assert( iDb>=0 && iDbnDb ); + assert( iDb>=0 && iDbdb->nDb ); if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } @@ -110800,11 +111472,7 @@ SQLITE_PRIVATE int sqlite3AuthCheck( ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); - if( db->init.busy || IN_SPECIAL_PARSE ){ - return SQLITE_OK; - } - - if( db->xAuth==0 ){ + if( db->xAuth==0 || db->init.busy || IN_SPECIAL_PARSE ){ return SQLITE_OK; } @@ -111010,10 +111678,36 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ /* Begin by generating some termination code at the end of the ** vdbe program */ - v = sqlite3GetVdbe(pParse); + v = pParse->pVdbe; + if( v==0 ){ + if( db->init.busy ){ + pParse->rc = SQLITE_DONE; + return; + } + v = sqlite3GetVdbe(pParse); + if( v==0 ) pParse->rc = SQLITE_ERROR; + } assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ + if( pParse->bReturning ){ + Returning *pReturning = pParse->u1.pReturning; + int addrRewind; + int i; + int reg; + + addrRewind = + sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur); + VdbeCoverage(v); + reg = pReturning->iRetReg; + for(i=0; inRetCol; i++){ + sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i); + } + sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i); + sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1); + VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrRewind); + } sqlite3VdbeAddOp0(v, OP_Halt); #if SQLITE_USER_AUTHENTICATION @@ -111091,12 +111785,16 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ } } + if( pParse->bReturning ){ + Returning *pRet = pParse->u1.pReturning; + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol); + } + /* Finally, jump back to the beginning of the executable code. */ sqlite3VdbeGoto(v, 1); } } - /* Get the VDBE program ready for execution */ if( v && pParse->nErr==0 && !db->mallocFailed ){ @@ -111315,7 +112013,7 @@ SQLITE_PRIVATE Table *sqlite3LocateTable( SQLITE_PRIVATE Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, - struct SrcList_item *p + SrcItem *p ){ const char *zDb; assert( p->pSchema==0 || p->zDatabase==0 ); @@ -112073,7 +112771,8 @@ SQLITE_PRIVATE void sqlite3StartTable( }else #endif { - pParse->addrCrTab = + assert( !pParse->bReturning ); + pParse->u1.addrCrTab = sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } sqlite3OpenSchemaTable(pParse, iDb); @@ -112100,12 +112799,85 @@ SQLITE_PRIVATE void sqlite3StartTable( SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ pCol->colFlags |= COLFLAG_HIDDEN; + if( pTab ) pTab->tabFlags |= TF_HasHidden; }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ pTab->tabFlags |= TF_OOOHidden; } } #endif +/* +** Name of the special TEMP trigger used to implement RETURNING. The +** name begins with "sqlite_" so that it is guaranteed not to collide +** with any application-generated triggers. +*/ +#define RETURNING_TRIGGER_NAME "sqlite_returning" + +/* +** Clean up the data structures associated with the RETURNING clause. +*/ +static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ + Hash *pHash; + pHash = &(db->aDb[1].pSchema->trigHash); + sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0); + sqlite3ExprListDelete(db, pRet->pReturnEL); + sqlite3DbFree(db, pRet); +} + +/* +** Add the RETURNING clause to the parse currently underway. +** +** This routine creates a special TEMP trigger that will fire for each row +** of the DML statement. That TEMP trigger contains a single SELECT +** statement with a result set that is the argument of the RETURNING clause. +** The trigger has the Trigger.bReturning flag and an opcode of +** TK_RETURNING instead of TK_SELECT, so that the trigger code generator +** knows to handle it specially. The TEMP trigger is automatically +** removed at the end of the parse. +** +** When this routine is called, we do not yet know if the RETURNING clause +** is attached to a DELETE, INSERT, or UPDATE, so construct it as a +** RETURNING trigger instead. It will then be converted into the appropriate +** type on the first call to sqlite3TriggersExist(). +*/ +SQLITE_PRIVATE void sqlite3AddReturning(Parse *pParse, ExprList *pList){ + Returning *pRet; + Hash *pHash; + sqlite3 *db = pParse->db; + if( pParse->pNewTrigger ){ + sqlite3ErrorMsg(pParse, "cannot use RETURNING in a trigger"); + }else{ + assert( pParse->bReturning==0 ); + } + pParse->bReturning = 1; + pRet = sqlite3DbMallocZero(db, sizeof(*pRet)); + if( pRet==0 ){ + sqlite3ExprListDelete(db, pList); + return; + } + pParse->u1.pReturning = pRet; + pRet->pParse = pParse; + pRet->pReturnEL = pList; + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); + testcase( pParse->earlyCleanup ); + if( db->mallocFailed ) return; + pRet->retTrig.zName = RETURNING_TRIGGER_NAME; + pRet->retTrig.op = TK_RETURNING; + pRet->retTrig.tr_tm = TRIGGER_AFTER; + pRet->retTrig.bReturning = 1; + pRet->retTrig.pSchema = db->aDb[1].pSchema; + pRet->retTrig.step_list = &pRet->retTStep; + pRet->retTStep.op = TK_RETURNING; + pRet->retTStep.pTrig = &pRet->retTrig; + pRet->retTStep.pExprList = pList; + pHash = &(db->aDb[1].pSchema->trigHash); + assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 || pParse->nErr ); + if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) + ==&pRet->retTrig ){ + sqlite3OomFault(db); + } +} /* ** Add a new column to the table currently being constructed. @@ -112122,6 +112894,8 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ char *zType; Column *pCol; sqlite3 *db = pParse->db; + u8 hName; + if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); @@ -112133,8 +112907,9 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ memcpy(z, pName->z, pName->n); z[pName->n] = 0; sqlite3Dequote(z); + hName = sqlite3StrIHash(z); for(i=0; inCol; i++){ - if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ + if( p->aCol[i].hName==hName && sqlite3StrICmp(z, p->aCol[i].zName)==0 ){ sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); sqlite3DbFree(db, z); return; @@ -112152,7 +112927,7 @@ SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - pCol->hName = sqlite3StrIHash(z); + pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); if( pType->n==0 ){ @@ -112935,9 +113710,10 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY ** into BTREE_BLOBKEY. */ - if( pParse->addrCrTab ){ + assert( !pParse->bReturning ); + if( pParse->u1.addrCrTab ){ assert( v ); - sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); + sqlite3VdbeChangeP3(v, pParse->u1.addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally @@ -113401,7 +114177,7 @@ SQLITE_PRIVATE void sqlite3EndTable( /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); } /* Add the table to the in-memory representation of the database. @@ -113418,20 +114194,17 @@ SQLITE_PRIVATE void sqlite3EndTable( } pParse->pNewTable = 0; db->mDbFlags |= DBFLAG_SchemaChange; + } #ifndef SQLITE_OMIT_ALTERTABLE - if( !p->pSelect ){ - const char *zName = (const char *)pParse->sNameToken.z; - int nName; - assert( !pSelect && pCons && pEnd ); - if( pCons->z==0 ){ - pCons = pEnd; - } - nName = (int)((const char *)pCons->z - zName); - p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); + if( !pSelect && !p->pSelect ){ + assert( pCons && pEnd ); + if( pCons->z==0 ){ + pCons = pEnd; } -#endif + p->addColOffset = 13 + (int)(pCons->z - pParse->sNameToken.z); } +#endif } #ifndef SQLITE_OMIT_VIEW @@ -113622,6 +114395,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable->aCol==0 ); pTable->nCol = pSelTab->nCol; pTable->aCol = pSelTab->aCol; + pTable->tabFlags |= (pSelTab->tabFlags & COLFLAG_NOINSERT); pSelTab->nCol = 0; pSelTab->aCol = 0; assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); @@ -114889,7 +115663,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( sqlite3RefillIndex(pParse, pIndex, iMem); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName), 0); sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); } @@ -115282,7 +116056,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( pParse!=0 ); @@ -115323,7 +116097,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( */ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; assert(pList || pParse->db->mallocFailed ); if( pList ){ for(i=0, pItem=pList->a; inSrc; i++, pItem++){ @@ -115341,7 +116115,7 @@ SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ */ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; - struct SrcList_item *pItem; + SrcItem *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ if( pItem->zDatabase ) sqlite3DbFreeNN(db, pItem->zDatabase); @@ -115383,7 +116157,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( Expr *pOn, /* The ON clause of a join */ IdList *pUsing /* The USING clause of a join */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; sqlite3 *db = pParse->db; if( !p && (pOn || pUsing) ){ sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", @@ -115427,7 +116201,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); if( p && pIndexedBy->n>0 ){ - struct SrcList_item *pItem; + SrcItem *pItem; assert( p->nSrc>0 ); pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); @@ -115457,7 +116231,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, Src sqlite3SrcListDelete(pParse->db, p2); }else{ p1 = pNew; - memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(struct SrcList_item)); + memcpy(&p1->a[1], p2->a, p2->nSrc*sizeof(SrcItem)); sqlite3DbFree(pParse->db, p2); } } @@ -115470,7 +116244,7 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, Src */ SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ if( p ){ - struct SrcList_item *pItem = &p->a[p->nSrc-1]; + SrcItem *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); @@ -115625,7 +116399,7 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ static void sqlite3CodeVerifySchemaAtToplevel(Parse *pToplevel, int iDb){ assert( iDb>=0 && iDbdb->nDb ); assert( pToplevel->db->aDb[iDb].pBt!=0 || iDb==1 ); - assert( iDbdb, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); @@ -115967,24 +116741,76 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ } #ifndef SQLITE_OMIT_CTE +/* +** Create a new CTE object +*/ +SQLITE_PRIVATE Cte *sqlite3CteNew( + Parse *pParse, /* Parsing context */ + Token *pName, /* Name of the common-table */ + ExprList *pArglist, /* Optional column name list for the table */ + Select *pQuery, /* Query used to initialize the table */ + u8 eM10d /* The MATERIALIZED flag */ +){ + Cte *pNew; + sqlite3 *db = pParse->db; + + pNew = sqlite3DbMallocZero(db, sizeof(*pNew)); + assert( pNew!=0 || db->mallocFailed ); + + if( db->mallocFailed ){ + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + }else{ + pNew->pSelect = pQuery; + pNew->pCols = pArglist; + pNew->zName = sqlite3NameFromToken(pParse->db, pName); + pNew->eM10d = eM10d; + } + return pNew; +} + +/* +** Clear information from a Cte object, but do not deallocate storage +** for the object itself. +*/ +static void cteClear(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); +} + +/* +** Free the contents of the CTE object passed as the second argument. +*/ +SQLITE_PRIVATE void sqlite3CteDelete(sqlite3 *db, Cte *pCte){ + assert( pCte!=0 ); + cteClear(db, pCte); + sqlite3DbFree(db, pCte); +} + /* ** This routine is invoked once per CTE by the parser while parsing a -** WITH clause. +** WITH clause. The CTE described by teh third argument is added to +** the WITH clause of the second argument. If the second argument is +** NULL, then a new WITH argument is created. */ SQLITE_PRIVATE With *sqlite3WithAdd( Parse *pParse, /* Parsing context */ With *pWith, /* Existing WITH clause, or NULL */ - Token *pName, /* Name of the common-table */ - ExprList *pArglist, /* Optional column name list for the table */ - Select *pQuery /* Query used to initialize the table */ + Cte *pCte /* CTE to add to the WITH clause */ ){ sqlite3 *db = pParse->db; With *pNew; char *zName; + if( pCte==0 ){ + return pWith; + } + /* Check that the CTE name is unique within this WITH clause. If ** not, store an error in the Parse structure. */ - zName = sqlite3NameFromToken(pParse->db, pName); + zName = pCte->zName; if( zName && pWith ){ int i; for(i=0; inCte; i++){ @@ -116003,16 +116829,11 @@ SQLITE_PRIVATE With *sqlite3WithAdd( assert( (pNew!=0 && zName!=0) || db->mallocFailed ); if( db->mallocFailed ){ - sqlite3ExprListDelete(db, pArglist); - sqlite3SelectDelete(db, pQuery); - sqlite3DbFree(db, zName); + sqlite3CteDelete(db, pCte); pNew = pWith; }else{ - pNew->a[pNew->nCte].pSelect = pQuery; - pNew->a[pNew->nCte].pCols = pArglist; - pNew->a[pNew->nCte].zName = zName; - pNew->a[pNew->nCte].zCteErr = 0; - pNew->nCte++; + pNew->a[pNew->nCte++] = *pCte; + sqlite3DbFree(db, pCte); } return pNew; @@ -116025,10 +116846,7 @@ SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; inCte; i++){ - struct Cte *pCte = &pWith->a[i]; - sqlite3ExprListDelete(db, pCte->pCols); - sqlite3SelectDelete(db, pCte->pSelect); - sqlite3DbFree(db, pCte->zName); + cteClear(db, &pWith->a[i]); } sqlite3DbFree(db, pWith); } @@ -116607,7 +117425,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** */ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ - struct SrcList_item *pItem = pSrc->a; + SrcItem *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); @@ -116615,9 +117433,9 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ pItem->pTab = pTab; if( pTab ){ pTab->nTabRef++; - } - if( sqlite3IndexedByLookup(pParse, pItem) ){ - pTab = 0; + if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ + pTab = 0; + } } return pTab; } @@ -116785,9 +117603,15 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ pSrc->a[0].pTab = 0; - pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); + pSelectSrc = sqlite3SrcListDup(db, pSrc, 0); pSrc->a[0].pTab = pTab; - pSrc->a[0].pIBIndex = 0; + if( pSrc->a[0].fg.isIndexedBy ){ + pSrc->a[0].u2.pIBIndex = 0; + pSrc->a[0].fg.isIndexedBy = 0; + sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy); + }else if( pSrc->a[0].fg.isCte ){ + pSrc->a[0].u2.pCteUse->nUse++; + } /* generate the SELECT expression tree. */ pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, @@ -116965,6 +117789,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ memCnt = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); @@ -117186,7 +118011,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** invoke the callback function. */ if( memCnt ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); } @@ -118234,7 +119059,8 @@ static int patternCompare( /* Skip over multiple "*" characters in the pattern. If there ** are also "?" characters, skip those as well, but consume a ** single character of the input string for each "?" skipped */ - while( (c=Utf8Read(zPattern)) == matchAll || c == matchOne ){ + while( (c=Utf8Read(zPattern)) == matchAll + || (c == matchOne && matchOne!=0) ){ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ return SQLITE_NOWILDCARDMATCH; } @@ -119405,7 +120231,9 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive) SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; int nExpr; - if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){ + assert( pExpr!=0 ); + assert( pExpr->op==TK_FUNCTION ); + if( !pExpr->x.pList ){ return 0; } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -119444,6 +120272,203 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas return 1; } +/* Mathematical Constants */ +#ifndef M_PI +# define M_PI 3.141592653589793238462643383279502884 +#endif +#ifndef M_LN10 +# define M_LN10 2.302585092994045684017991454684364208 +#endif +#ifndef M_LN2 +# define M_LN2 0.693147180559945309417232121458176568 +#endif + + +/* Extra math functions that require linking with -lm +*/ +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS +/* +** Implementation SQL functions: +** +** ceil(X) +** ceiling(X) +** floor(X) +** +** The sqlite3_user_data() pointer is a pointer to the libm implementation +** of the underlying C function. +*/ +static void ceilingFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: { + sqlite3_result_int64(context, sqlite3_value_int64(argv[0])); + break; + } + case SQLITE_FLOAT: { + double (*x)(double) = (double(*)(double))sqlite3_user_data(context); + sqlite3_result_double(context, x(sqlite3_value_double(argv[0]))); + break; + } + default: { + break; + } + } +} + +/* +** On some systems, ceil() and floor() are intrinsic function. You are +** unable to take a pointer to these functions. Hence, we here wrap them +** in our own actual functions. +*/ +static double xCeil(double x){ return ceil(x); } +static double xFloor(double x){ return floor(x); } + +/* +** Implementation of SQL functions: +** +** ln(X) - natural logarithm +** log(X) - log X base 10 +** log10(X) - log X base 10 +** log(B,X) - log X base B +*/ +static void logFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double x, b, ans; + assert( argc==1 || argc==2 ); + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + x = sqlite3_value_double(argv[0]); + if( x<=0.0 ) return; + break; + default: + return; + } + if( argc==2 ){ + switch( sqlite3_value_numeric_type(argv[0]) ){ + case SQLITE_INTEGER: + case SQLITE_FLOAT: + b = log(x); + if( b<=0.0 ) return; + x = sqlite3_value_double(argv[1]); + if( x<=0.0 ) return; + break; + default: + return; + } + ans = log(x)/b; + }else{ + ans = log(x); + switch( SQLITE_PTR_TO_INT(sqlite3_user_data(context)) ){ + case 1: + /* Convert from natural logarithm to log base 10 */ + ans *= 1.0/M_LN10; + break; + case 2: + /* Convert from natural logarithm to log base 2 */ + ans *= 1.0/M_LN2; + break; + default: + break; + } + } + sqlite3_result_double(context, ans); +} + +/* +** Functions to converts degrees to radians and radians to degrees. +*/ +static double degToRad(double x){ return x*(M_PI/180.0); } +static double radToDeg(double x){ return x*(180.0/M_PI); } + +/* +** Implementation of 1-argument SQL math functions: +** +** exp(X) - Compute e to the X-th power +*/ +static void math1Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double v0, ans; + double (*x)(double); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + x = (double(*)(double))sqlite3_user_data(context); + ans = x(v0); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void math2Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0, type1; + double v0, v1, ans; + double (*x)(double,double); + assert( argc==2 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + type1 = sqlite3_value_numeric_type(argv[1]); + if( type1!=SQLITE_INTEGER && type1!=SQLITE_FLOAT ) return; + v0 = sqlite3_value_double(argv[0]); + v1 = sqlite3_value_double(argv[1]); + x = (double(*)(double,double))sqlite3_user_data(context); + ans = x(v0, v1); + sqlite3_result_double(context, ans); +} + +/* +** Implementation of 2-argument SQL math functions: +** +** power(X,Y) - Compute X to the Y-th power +*/ +static void piFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==0 ); + sqlite3_result_double(context, M_PI); +} + +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + +/* +** Implementation of sign(X) function. +*/ +static void signFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int type0; + double x; + UNUSED_PARAMETER(argc); + assert( argc==1 ); + type0 = sqlite3_value_numeric_type(argv[0]); + if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; + x = sqlite3_value_double(argv[0]); + sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); +} + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -119562,6 +120587,43 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ #endif FUNCTION(coalesce, 1, 0, 0, 0 ), FUNCTION(coalesce, 0, 0, 0, 0 ), +#ifdef SQLITE_ENABLE_MATH_FUNCTIONS + MFUNCTION(ceil, 1, xCeil, ceilingFunc ), + MFUNCTION(ceiling, 1, xCeil, ceilingFunc ), + MFUNCTION(floor, 1, xFloor, ceilingFunc ), +#if SQLITE_HAVE_C99_MATH_FUNCS + MFUNCTION(trunc, 1, trunc, ceilingFunc ), +#endif + FUNCTION(ln, 1, 0, 0, logFunc ), + FUNCTION(log, 1, 1, 0, logFunc ), + FUNCTION(log10, 1, 1, 0, logFunc ), + FUNCTION(log2, 1, 2, 0, logFunc ), + FUNCTION(log, 2, 0, 0, logFunc ), + MFUNCTION(exp, 1, exp, math1Func ), + MFUNCTION(pow, 2, pow, math2Func ), + MFUNCTION(power, 2, pow, math2Func ), + MFUNCTION(mod, 2, fmod, math2Func ), + MFUNCTION(acos, 1, acos, math1Func ), + MFUNCTION(asin, 1, asin, math1Func ), + MFUNCTION(atan, 1, atan, math1Func ), + MFUNCTION(atan2, 2, atan2, math2Func ), + MFUNCTION(cos, 1, cos, math1Func ), + MFUNCTION(sin, 1, sin, math1Func ), + MFUNCTION(tan, 1, tan, math1Func ), + MFUNCTION(cosh, 1, cosh, math1Func ), + MFUNCTION(sinh, 1, sinh, math1Func ), + MFUNCTION(tanh, 1, tanh, math1Func ), +#if SQLITE_HAVE_C99_MATH_FUNCS + MFUNCTION(acosh, 1, acosh, math1Func ), + MFUNCTION(asinh, 1, asinh, math1Func ), + MFUNCTION(atanh, 1, atanh, math1Func ), +#endif + MFUNCTION(sqrt, 1, sqrt, math1Func ), + MFUNCTION(radians, 1, degToRad, math1Func ), + MFUNCTION(degrees, 1, radToDeg, math1Func ), + FUNCTION(pi, 0, 0, 0, piFunc ), +#endif /* SQLITE_ENABLE_MATH_FUNCTIONS */ + FUNCTION(sign, 1, 0, 0, signFunc ), INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, 0 ), INLINE_FUNC(iif, 3, INLINEFUNC_iif, 0 ), }; @@ -120617,7 +121679,7 @@ SQLITE_PRIVATE void sqlite3FkCheck( ** child table as a SrcList for sqlite3WhereBegin() */ pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ - struct SrcList_item *pItem = pSrc->a; + SrcItem *pItem = pSrc->a; pItem->pTab = pFKey->pFrom; pItem->zName = pFKey->pFrom->zName; pItem->pTab->nTabRef++; @@ -120705,7 +121767,9 @@ SQLITE_PRIVATE u32 sqlite3FkOldmask( ** ** For an UPDATE, this function returns 2 if: ** -** * There are any FKs for which pTab is the child and the parent table, or +** * There are any FKs for which pTab is the child and the parent table +** and any FK processing at all is required (even of a different FK), or +** ** * the UPDATE modifies one or more parent keys for which the action is ** not "NO ACTION" (i.e. is CASCADE, SET DEFAULT or SET NULL). ** @@ -120717,13 +121781,14 @@ SQLITE_PRIVATE int sqlite3FkRequired( int *aChange, /* Non-NULL for UPDATE operations */ int chngRowid /* True for UPDATE that affects rowid */ ){ - int eRet = 0; + int eRet = 1; /* Value to return if bHaveFK is true */ + int bHaveFK = 0; /* If FK processing is required */ if( pParse->db->flags&SQLITE_ForeignKeys ){ if( !aChange ){ /* A DELETE operation. Foreign key processing is required if the ** table in question is either the child or parent table for any ** foreign key constraint. */ - eRet = (sqlite3FkReferences(pTab) || pTab->pFKey); + bHaveFK = (sqlite3FkReferences(pTab) || pTab->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ @@ -120731,9 +121796,9 @@ SQLITE_PRIVATE int sqlite3FkRequired( /* Check if any child key columns are being modified. */ for(p=pTab->pFKey; p; p=p->pNextFrom){ - if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2; if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ - eRet = 1; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) eRet = 2; + bHaveFK = 1; } } @@ -120741,12 +121806,12 @@ SQLITE_PRIVATE int sqlite3FkRequired( for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ if( p->aAction[1]!=OE_None ) return 2; - eRet = 1; + bHaveFK = 1; } } } } - return eRet; + return bHaveFK ? eRet : 0; } /* @@ -121415,7 +122480,9 @@ static int autoIncBegin( while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); - if( pInfo==0 ) return 0; + sqlite3ParserAddCleanup(pToplevel, sqlite3DbFree, pInfo); + testcase( pParse->earlyCleanup ); + if( pParse->db->mallocFailed ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; pInfo->pTab = pTab; @@ -121973,19 +123040,24 @@ SQLITE_PRIVATE void sqlite3Insert( } } #endif - } - /* Make sure the number of columns in the source data matches the number - ** of columns to be inserted into the table. - */ - for(i=0; inCol; i++){ - if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; - } - if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, - "table %S has %d columns but %d values were supplied", - pTabList, 0, pTab->nCol-nHidden, nColumn); - goto insert_cleanup; + /* Make sure the number of columns in the source data matches the number + ** of columns to be inserted into the table. + */ + assert( TF_HasHidden==COLFLAG_HIDDEN ); + assert( TF_HasGenerated==COLFLAG_GENERATED ); + assert( COLFLAG_NOINSERT==(COLFLAG_GENERATED|COLFLAG_HIDDEN) ); + if( (pTab->tabFlags & (TF_HasGenerated|TF_HasHidden))!=0 ){ + for(i=0; inCol; i++){ + if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; + } + } + if( nColumn!=(pTab->nCol-nHidden) ){ + sqlite3ErrorMsg(pParse, + "table %S has %d columns but %d values were supplied", + pTabList, 0, pTab->nCol-nHidden, nColumn); + goto insert_cleanup; + } } if( pColumn!=0 && nColumn!=pColumn->nId ){ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); @@ -121997,6 +123069,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( (db->flags & SQLITE_CountRows)!=0 && !pParse->nested && !pParse->pTriggerTab + && !pParse->bReturning ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); @@ -122020,6 +123093,7 @@ SQLITE_PRIVATE void sqlite3Insert( } #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ + Upsert *pNx; if( IsVirtual(pTab) ){ sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); @@ -122033,13 +123107,17 @@ SQLITE_PRIVATE void sqlite3Insert( goto insert_cleanup; } pTabList->a[0].iCursor = iDataCur; - pUpsert->pUpsertSrc = pTabList; - pUpsert->regData = regData; - pUpsert->iDataCur = iDataCur; - pUpsert->iIdxCur = iIdxCur; - if( pUpsert->pUpsertTarget ){ - sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); - } + pNx = pUpsert; + do{ + pNx->pUpsertSrc = pTabList; + pNx->regData = regData; + pNx->iDataCur = iDataCur; + pNx->iIdxCur = iIdxCur; + if( pNx->pUpsertTarget ){ + sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx); + } + pNx = pNx->pNextUpsert; + }while( pNx!=0 ); } #endif @@ -122180,11 +123258,6 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); } - /* Cannot have triggers on a virtual table. If it were possible, - ** this block would have to account for hidden column. - */ - assert( !IsVirtual(pTab) ); - /* Copy the new data already generated. */ assert( pTab->nNVCol>0 ); sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); @@ -122339,7 +123412,9 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3VdbeJumpHere(v, addrInsTop); } +#ifndef SQLITE_OMIT_XFER_OPT insert_end: +#endif /* SQLITE_OMIT_XFER_OPT */ /* Update the sqlite_sequence table by storing the content of the ** maximum rowid counter values recorded while inserting into ** autoincrement tables. @@ -122354,7 +123429,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** invoke the callback function. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); } @@ -122444,6 +123519,70 @@ SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( return w.eCode!=0; } +/* +** The sqlite3GenerateConstraintChecks() routine usually wants to visit +** the indexes of a table in the order provided in the Table->pIndex list. +** However, sometimes (rarely - when there is an upsert) it wants to visit +** the indexes in a different order. The following data structures accomplish +** this. +** +** The IndexIterator object is used to walk through all of the indexes +** of a table in either Index.pNext order, or in some other order established +** by an array of IndexListTerm objects. +*/ +typedef struct IndexListTerm IndexListTerm; +typedef struct IndexIterator IndexIterator; +struct IndexIterator { + int eType; /* 0 for Index.pNext list. 1 for an array of IndexListTerm */ + int i; /* Index of the current item from the list */ + union { + struct { /* Use this object for eType==0: A Index.pNext list */ + Index *pIdx; /* The current Index */ + } lx; + struct { /* Use this object for eType==1; Array of IndexListTerm */ + int nIdx; /* Size of the array */ + IndexListTerm *aIdx; /* Array of IndexListTerms */ + } ax; + } u; +}; + +/* When IndexIterator.eType==1, then each index is an array of instances +** of the following object +*/ +struct IndexListTerm { + Index *p; /* The index */ + int ix; /* Which entry in the original Table.pIndex list is this index*/ +}; + +/* Return the first index on the list */ +static Index *indexIteratorFirst(IndexIterator *pIter, int *pIx){ + assert( pIter->i==0 ); + if( pIter->eType ){ + *pIx = pIter->u.ax.aIdx[0].ix; + return pIter->u.ax.aIdx[0].p; + }else{ + *pIx = 0; + return pIter->u.lx.pIdx; + } +} + +/* Return the next index from the list. Return NULL when out of indexes */ +static Index *indexIteratorNext(IndexIterator *pIter, int *pIx){ + if( pIter->eType ){ + int i = ++pIter->i; + if( i>=pIter->u.ax.nIdx ){ + *pIx = i; + return 0; + } + *pIx = pIter->u.ax.aIdx[i].ix; + return pIter->u.ax.aIdx[i].p; + }else{ + ++(*pIx); + pIter->u.lx.pIdx = pIter->u.lx.pIdx->pNext; + return pIter->u.lx.pIdx; + } +} + /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE ** on table pTab. @@ -122552,7 +123691,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ){ Vdbe *v; /* VDBE under constrution */ Index *pIdx; /* Pointer to one of the indices */ - Index *pPk = 0; /* The PRIMARY KEY index */ + Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ sqlite3 *db; /* Database connection */ int i; /* loop counter */ int ix; /* Index loop counter */ @@ -122560,11 +123699,11 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int onError; /* Conflict resolution strategy */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ int nPkField; /* Number of fields in PRIMARY KEY. 1 for ROWID tables */ - Index *pUpIdx = 0; /* Index to which to apply the upsert */ - u8 isUpdate; /* True if this is an UPDATE operation */ + Upsert *pUpsertClause = 0; /* The specific ON CONFLICT clause for pIdx */ + u8 isUpdate; /* True if this is an UPDATE operation */ u8 bAffinityDone = 0; /* True if the OP_Affinity operation has been run */ - int upsertBypass = 0; /* Address of Goto to bypass upsert subroutine */ - int upsertJump = 0; /* Address of Goto that jumps into upsert subroutine */ + int upsertIpkReturn = 0; /* Address of Goto at end of IPK uniqueness check */ + int upsertIpkDelay = 0; /* Address of Goto to bypass initial IPK check */ int ipkTop = 0; /* Top of the IPK uniqueness check */ int ipkBottom = 0; /* OP_Goto at the end of the IPK uniqueness check */ /* Variables associated with retesting uniqueness constraints after @@ -122574,6 +123713,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int lblRecheckOk = 0; /* Each recheck jumps to this label if it passes */ Trigger *pTrigger; /* List of DELETE triggers on the table pTab */ int nReplaceTrig = 0; /* Number of replace triggers coded */ + IndexIterator sIdxIter; /* Index iterator */ isUpdate = regOldData!=0; db = pParse->db; @@ -122771,19 +123911,63 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** list of indexes attached to a table puts all OE_Replace indexes last ** in the list. See sqlite3CreateIndex() for where that happens. */ - + sIdxIter.eType = 0; + sIdxIter.i = 0; + sIdxIter.u.ax.aIdx = 0; /* Silence harmless compiler warning */ + sIdxIter.u.lx.pIdx = pTab->pIndex; if( pUpsert ){ if( pUpsert->pUpsertTarget==0 ){ - /* An ON CONFLICT DO NOTHING clause, without a constraint-target. - ** Make all unique constraint resolution be OE_Ignore */ - assert( pUpsert->pUpsertSet==0 ); - overrideError = OE_Ignore; - pUpsert = 0; - }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ - /* If the constraint-target uniqueness check must be run first. - ** Jump to that uniqueness check now */ - upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); - VdbeComment((v, "UPSERT constraint goes first")); + /* There is just on ON CONFLICT clause and it has no constraint-target */ + assert( pUpsert->pNextUpsert==0 ); + if( pUpsert->isDoUpdate==0 ){ + /* A single ON CONFLICT DO NOTHING clause, without a constraint-target. + ** Make all unique constraint resolution be OE_Ignore */ + overrideError = OE_Ignore; + pUpsert = 0; + }else{ + /* A single ON CONFLICT DO UPDATE. Make all resolutions OE_Update */ + overrideError = OE_Update; + } + }else if( pTab->pIndex!=0 ){ + /* Otherwise, we'll need to run the IndexListTerm array version of the + ** iterator to ensure that all of the ON CONFLICT conditions are + ** checked first and in order. */ + int nIdx, jj; + u64 nByte; + Upsert *pTerm; + u8 *bUsed; + for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ + assert( aRegIdx[nIdx]>0 ); + } + sIdxIter.eType = 1; + sIdxIter.u.ax.nIdx = nIdx; + nByte = (sizeof(IndexListTerm)+1)*nIdx + nIdx; + sIdxIter.u.ax.aIdx = sqlite3DbMallocZero(db, nByte); + if( sIdxIter.u.ax.aIdx==0 ) return; /* OOM */ + bUsed = (u8*)&sIdxIter.u.ax.aIdx[nIdx]; + pUpsert->pToFree = sIdxIter.u.ax.aIdx; + for(i=0, pTerm=pUpsert; pTerm; pTerm=pTerm->pNextUpsert){ + if( pTerm->pUpsertTarget==0 ) break; + if( pTerm->pUpsertIdx==0 ) continue; /* Skip ON CONFLICT for the IPK */ + jj = 0; + pIdx = pTab->pIndex; + while( ALWAYS(pIdx!=0) && pIdx!=pTerm->pUpsertIdx ){ + pIdx = pIdx->pNext; + jj++; + } + if( bUsed[jj] ) continue; /* Duplicate ON CONFLICT clause ignored */ + bUsed[jj] = 1; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + for(jj=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, jj++){ + if( bUsed[jj] ) continue; + sIdxIter.u.ax.aIdx[i].p = pIdx; + sIdxIter.u.ax.aIdx[i].ix = jj; + i++; + } + assert( i==nIdx ); } } @@ -122846,11 +124030,20 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } /* figure out whether or not upsert applies in this case */ - if( pUpsert && pUpsert->pUpsertIdx==0 ){ - if( pUpsert->pUpsertSet==0 ){ - onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ - }else{ - onError = OE_Update; /* DO UPDATE */ + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert,0); + if( pUpsertClause!=0 ){ + if( pUpsertClause->isDoUpdate==0 ){ + onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ + }else{ + onError = OE_Update; /* DO UPDATE */ + } + } + if( pUpsertClause!=pUpsert ){ + /* The first ON CONFLICT clause has a conflict target other than + ** the IPK. We have to jump ahead to that first ON CONFLICT clause + ** and then come back here and deal with the IPK afterwards */ + upsertIpkDelay = sqlite3VdbeAddOp0(v, OP_Goto); } } @@ -122860,7 +124053,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** the UNIQUE constraints have run. */ if( onError==OE_Replace /* IPK rule is REPLACE */ - && onError!=overrideError /* Rules for other contraints are different */ + && onError!=overrideError /* Rules for other constraints are different */ && pTab->pIndex /* There exist other constraints */ ){ ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; @@ -122957,7 +124150,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } } sqlite3VdbeResolveLabel(v, addrRowidOk); - if( ipkTop ){ + if( pUpsert && pUpsertClause!=pUpsert ){ + upsertIpkReturn = sqlite3VdbeAddOp0(v, OP_Goto); + }else if( ipkTop ){ ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); sqlite3VdbeJumpHere(v, ipkTop-1); } @@ -122970,7 +124165,10 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( ** This loop also handles the case of the PRIMARY KEY index for a ** WITHOUT ROWID table. */ - for(ix=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, ix++){ + for(pIdx = indexIteratorFirst(&sIdxIter, &ix); + pIdx; + pIdx = indexIteratorNext(&sIdxIter, &ix) + ){ int regIdx; /* Range of registers hold conent for pIdx */ int regR; /* Range of registers holding conflicting PK */ int iThisCur; /* Cursor for this UNIQUE index */ @@ -122978,15 +124176,14 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int addrConflictCk; /* First opcode in the conflict check logic */ if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ - if( pUpIdx==pIdx ){ - addrUniqueOk = upsertJump+1; - upsertBypass = sqlite3VdbeGoto(v, 0); - VdbeComment((v, "Skip upsert subroutine")); - sqlite3VdbeJumpHere(v, upsertJump); - }else{ - addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( pUpsert ){ + pUpsertClause = sqlite3UpsertOfIndex(pUpsert, pIdx); + if( upsertIpkDelay && pUpsertClause==pUpsert ){ + sqlite3VdbeJumpHere(v, upsertIpkDelay); + } } - if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); + if( bAffinityDone==0 ){ sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } @@ -123057,8 +124254,8 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } /* Figure out if the upsert clause applies to this index */ - if( pUpIdx==pIdx ){ - if( pUpsert->pUpsertSet==0 ){ + if( pUpsertClause ){ + if( pUpsertClause->isDoUpdate==0 ){ onError = OE_Ignore; /* DO NOTHING is the same as INSERT OR IGNORE */ }else{ onError = OE_Update; /* DO UPDATE */ @@ -123096,7 +124293,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ - regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); + regR = pIdx==pPk ? regIdx : sqlite3GetTempRange(pParse, nPkField); if( isUpdate || onError==OE_Replace ){ if( HasRowid(pTab) ){ sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); @@ -123248,13 +124445,16 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( break; } } - if( pUpIdx==pIdx ){ - sqlite3VdbeGoto(v, upsertJump+1); - sqlite3VdbeJumpHere(v, upsertBypass); - }else{ - sqlite3VdbeResolveLabel(v, addrUniqueOk); - } + sqlite3VdbeResolveLabel(v, addrUniqueOk); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); + if( pUpsertClause + && upsertIpkReturn + && sqlite3UpsertNextIsIPK(pUpsertClause) + ){ + sqlite3VdbeGoto(v, upsertIpkDelay+1); + sqlite3VdbeJumpHere(v, upsertIpkReturn); + upsertIpkReturn = 0; + } } /* If the IPK constraint is a REPLACE, run it last */ @@ -123320,6 +124520,32 @@ SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ } #endif +/* +** Table pTab is a WITHOUT ROWID table that is being written to. The cursor +** number is iCur, and register regData contains the new record for the +** PK index. This function adds code to invoke the pre-update hook, +** if one is registered. +*/ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +static void codeWithoutRowidPreupdate( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated */ + int iCur, /* Cursor number for table */ + int regData /* Data containing new record */ +){ + Vdbe *v = pParse->pVdbe; + int r = sqlite3GetTempReg(pParse); + assert( !HasRowid(pTab) ); + assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) ); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); +} +#else +# define codeWithoutRowidPreupdate(a,b,c,d) +#endif + /* ** This routine generates code to finish the INSERT or UPDATE operation ** that was started by a prior call to sqlite3GenerateConstraintChecks. @@ -123368,17 +124594,9 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( assert( pParse->nested==0 ); pik_flags |= OPFLAG_NCHANGE; pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); -#ifdef SQLITE_ENABLE_PREUPDATE_HOOK if( update_flags==0 ){ - int r = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Integer, 0, r); - sqlite3VdbeAddOp4(v, OP_Insert, - iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE - ); - sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); - sqlite3ReleaseTempReg(pParse, r); + codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]); } -#endif } sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], aRegIdx[i]+1, @@ -123576,7 +124794,7 @@ static int xferOptimization( ExprList *pEList; /* The result set of the SELECT */ Table *pSrc; /* The table in the FROM clause of SELECT */ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ - struct SrcList_item *pItem; /* An element of pSelect->pSrc */ + SrcItem *pItem; /* An element of pSelect->pSrc */ int i; /* Loop counter */ int iDbSrc; /* The database of pSrc */ int iSrc, iDest; /* Cursors from source and destination */ @@ -123793,6 +125011,7 @@ static int xferOptimization( iDest = pParse->nTab++; regAutoinc = autoIncBegin(pParse, iDbDest, pDest); regData = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, regData); regRowid = sqlite3GetTempReg(pParse); sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); assert( HasRowid(pDest) || destHasUniqueIdx ); @@ -123828,11 +125047,13 @@ static int xferOptimization( emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); - sqlite3VdbeVerifyAbortable(v, onError); - addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - VdbeCoverage(v); - sqlite3RowidConstraint(pParse, onError, pDest); - sqlite3VdbeJumpHere(v, addr2); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeVerifyAbortable(v, onError); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + VdbeCoverage(v); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); + } autoIncStep(pParse, regAutoinc, regRowid); }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); @@ -123840,16 +125061,28 @@ static int xferOptimization( addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } + if( db->mDbFlags & DBFLAG_Vacuum ){ sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); - insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT; + insFlags = OPFLAG_APPEND|OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; }else{ - insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; + insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND|OPFLAG_PREFORMAT; + } +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + insFlags &= ~OPFLAG_PREFORMAT; + }else +#endif + { + sqlite3VdbeAddOp3(v, OP_RowCell, iDest, iSrc, regRowid); + } + sqlite3VdbeAddOp3(v, OP_Insert, iDest, regData, regRowid); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 ){ + sqlite3VdbeChangeP4(v, -1, (char*)pDest, P4_TABLE); } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, - (char*)pDest, P4_TABLE); sqlite3VdbeChangeP5(v, insFlags); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); @@ -123891,13 +125124,22 @@ static int xferOptimization( if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; } if( i==pSrcIdx->nColumn ){ - idxInsFlags = OPFLAG_USESEEKRESULT; + idxInsFlags = OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT; sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp2(v, OP_RowCell, iDest, iSrc); } }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } - sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && !HasRowid(pDest) + && IsPrimaryKeyIndex(pDestIdx) + ){ + codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); + } + } sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); @@ -128213,7 +129455,7 @@ SQLITE_PRIVATE void sqlite3Pragma( ** Checkpoint the database. */ case PragTyp_WAL_CHECKPOINT: { - int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); + int iBt = (pId2->z?iDb:SQLITE_MAX_DB); int eMode = SQLITE_CHECKPOINT_PASSIVE; if( zRight ){ if( sqlite3StrICmp(zRight, "full")==0 ){ @@ -128861,7 +130103,7 @@ SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName) */ static void corruptSchema( InitData *pData, /* Initialization context */ - const char *zObj, /* Object being parsed at the point of error */ + char **azObj, /* Type and name of object being parsed */ const char *zExtra /* Error information */ ){ sqlite3 *db = pData->db; @@ -128869,14 +130111,18 @@ static void corruptSchema( pData->rc = SQLITE_NOMEM_BKPT; }else if( pData->pzErrMsg[0]!=0 ){ /* A error message has already been generated. Do not overwrite it */ - }else if( pData->mInitFlags & INITFLAG_AlterTable ){ - *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); + }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){ + *pData->pzErrMsg = sqlite3MPrintf(db, + "error in %s %s after %s: %s", azObj[0], azObj[1], + (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column", + zExtra + ); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; }else{ char *z; - if( zObj==0 ) zObj = "?"; + const char *zObj = azObj[1] ? azObj[1] : "?"; z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; @@ -128934,19 +130180,26 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char db->mDbFlags |= DBFLAG_EncodingFixed; pData->nInitRow++; if( db->mallocFailed ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); return 1; } assert( iDb>=0 && iDbnDb ); if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[3]==0 ){ - corruptSchema(pData, argv[1], 0); - }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){ + corruptSchema(pData, argv, 0); + }else if( argv[4] + && 'c'==sqlite3UpperToLower[(unsigned char)argv[4][0]] + && 'r'==sqlite3UpperToLower[(unsigned char)argv[4][1]] ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data ** structures that describe the table, index, or view. + ** + ** No other valid SQL statement, other than the variable CREATE statements, + ** can begin with the letters "C" and "R". Thus, it is not possible run + ** any other kind of statement while parsing the schema, even a corrupt + ** schema. */ int rc; u8 saved_iDb = db->init.iDb; @@ -128959,7 +130212,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char || (db->init.newTnum>pData->mxPage && pData->mxPage>0) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } db->init.orphanTrigger = 0; @@ -128978,13 +130231,13 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[1], sqlite3_errmsg(db)); + corruptSchema(pData, argv, sqlite3_errmsg(db)); } } } sqlite3_finalize(pStmt); }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ - corruptSchema(pData, argv[1], 0); + corruptSchema(pData, argv, 0); }else{ /* If the SQL column is blank it means this is an index that ** was created to be the PRIMARY KEY or to fulfill a UNIQUE @@ -128995,7 +130248,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char Index *pIndex; pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); if( pIndex==0 ){ - corruptSchema(pData, argv[1], "orphan index"); + corruptSchema(pData, argv, "orphan index"); }else if( sqlite3GetUInt32(argv[3],&pIndex->tnum)==0 || pIndex->tnum<2 @@ -129003,7 +130256,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char || sqlite3IndexHasDuplicateRootPage(pIndex) ){ if( sqlite3Config.bExtraSchemaChecks ){ - corruptSchema(pData, argv[1], "invalid rootpage"); + corruptSchema(pData, argv, "invalid rootpage"); } } } @@ -129383,28 +130636,21 @@ SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ return i; } -/* -** Deallocate a single AggInfo object -*/ -static void agginfoFree(sqlite3 *db, AggInfo *p){ - sqlite3DbFree(db, p->aCol); - sqlite3DbFree(db, p->aFunc); - sqlite3DbFree(db, p); -} - /* ** Free all memory allocations in the pParse object */ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ sqlite3 *db = pParse->db; - AggInfo *pThis = pParse->pAggList; - while( pThis ){ - AggInfo *pNext = pThis->pNext; - agginfoFree(db, pThis); - pThis = pNext; + while( pParse->pCleanup ){ + ParseCleanup *pCleanup = pParse->pCleanup; + pParse->pCleanup = pCleanup->pNext; + pCleanup->xCleanup(db, pCleanup->pPtr); + sqlite3DbFreeNN(db, pCleanup); } sqlite3DbFree(db, pParse->aLabel); - sqlite3ExprListDelete(db, pParse->pConstExpr); + if( pParse->pConstExpr ){ + sqlite3ExprListDelete(db, pParse->pConstExpr); + } if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -129413,6 +130659,55 @@ SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ pParse->disableLookaside = 0; } +/* +** Add a new cleanup operation to a Parser. The cleanup should happen when +** the parser object is destroyed. But, beware: the cleanup might happen +** immediately. +** +** Use this mechanism for uncommon cleanups. There is a higher setup +** cost for this mechansim (an extra malloc), so it should not be used +** for common cleanups that happen on most calls. But for less +** common cleanups, we save a single NULL-pointer comparison in +** sqlite3ParserReset(), which reduces the total CPU cycle count. +** +** If a memory allocation error occurs, then the cleanup happens immediately. +** When either SQLITE_DEBUG or SQLITE_COVERAGE_TEST are defined, the +** pParse->earlyCleanup flag is set in that case. Calling code show verify +** that test cases exist for which this happens, to guard against possible +** use-after-free errors following an OOM. The preferred way to do this is +** to immediately follow the call to this routine with: +** +** testcase( pParse->earlyCleanup ); +** +** This routine returns a copy of its pPtr input (the third parameter) +** except if an early cleanup occurs, in which case it returns NULL. So +** another way to check for early cleanup is to check the return value. +** Or, stop using the pPtr parameter with this call and use only its +** return value thereafter. Something like this: +** +** pObj = sqlite3ParserAddCleanup(pParse, destructor, pObj); +*/ +SQLITE_PRIVATE void *sqlite3ParserAddCleanup( + Parse *pParse, /* Destroy when this Parser finishes */ + void (*xCleanup)(sqlite3*,void*), /* The cleanup routine */ + void *pPtr /* Pointer to object to be cleaned up */ +){ + ParseCleanup *pCleanup = sqlite3DbMallocRaw(pParse->db, sizeof(*pCleanup)); + if( pCleanup ){ + pCleanup->pNext = pParse->pCleanup; + pParse->pCleanup = pCleanup; + pCleanup->pPtr = pPtr; + pCleanup->xCleanup = xCleanup; + }else{ + xCleanup(pParse->db, pPtr); + pPtr = 0; +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) + pParse->earlyCleanup = 1; +#endif + } + return pPtr; +} + /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ @@ -129511,12 +130806,6 @@ static int sqlite3Prepare( } assert( 0==sParse.nQueryLoop ); - if( sParse.rc==SQLITE_DONE ){ - sParse.rc = SQLITE_OK; - } - if( sParse.checkSchema ){ - schemaIsValid(&sParse); - } if( pzTail ){ *pzTail = sParse.zTail; } @@ -129527,20 +130816,28 @@ static int sqlite3Prepare( if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; } - rc = sParse.rc; - if( rc!=SQLITE_OK ){ - if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe); - assert(!(*ppStmt)); + if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ + if( sParse.checkSchema ){ + schemaIsValid(&sParse); + } + if( sParse.pVdbe ){ + sqlite3VdbeFinalize(sParse.pVdbe); + } + assert( 0==(*ppStmt) ); + rc = sParse.rc; + if( zErrMsg ){ + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); + }else{ + sqlite3Error(db, rc); + } }else{ + assert( zErrMsg==0 ); *ppStmt = (sqlite3_stmt*)sParse.pVdbe; + rc = SQLITE_OK; + sqlite3ErrorClear(db); } - if( zErrMsg ){ - sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - sqlite3DbFree(db, zErrMsg); - }else{ - sqlite3Error(db, rc); - } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while( sParse.pTriggerPrg ){ @@ -129886,12 +131183,16 @@ static void clearSelect(sqlite3 *db, Select *p, int bFree){ sqlite3ExprDelete(db, p->pHaving); sqlite3ExprListDelete(db, p->pOrderBy); sqlite3ExprDelete(db, p->pLimit); + if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ sqlite3WindowListDelete(db, p->pWinDefn); } + while( p->pWin ){ + assert( p->pWin->ppThis==&p->pWin ); + sqlite3WindowUnlinkFromSelect(p->pWin); + } #endif - if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; @@ -130063,7 +131364,7 @@ SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *p ** Return the index of a column in a table. Return -1 if the column ** is not contained in the table. */ -static int columnIndex(Table *pTab, const char *zCol){ +SQLITE_PRIVATE int sqlite3ColumnIndex(Table *pTab, const char *zCol){ int i; u8 h = sqlite3StrIHash(zCol); Column *pCol; @@ -130095,7 +131396,7 @@ static int tableAndColumnIndex( assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */ for(i=0; ia[i].pTab, zCol); + iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ @@ -130148,7 +131449,7 @@ static void addWhereTerm( ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); - pEq->iRightJoinTable = (i16)pE2->iTable; + pEq->iRightJoinTable = pE2->iTable; } *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } @@ -130184,7 +131485,7 @@ SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(p, EP_NoReduce); - p->iRightJoinTable = (i16)iTable; + p->iRightJoinTable = iTable; if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -130208,6 +131509,9 @@ static void unsetJoinExpr(Expr *p, int iTable){ && (iTable<0 || p->iRightJoinTable==iTable) ){ ExprClearProperty(p, EP_FromJoin); } + if( p->op==TK_COLUMN && p->iTable==iTable ){ + ExprClearProperty(p, EP_CanBeNull); + } if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -130236,8 +131540,8 @@ static void unsetJoinExpr(Expr *p, int iTable){ static int sqliteProcessJoin(Parse *pParse, Select *p){ SrcList *pSrc; /* All tables in the FROM clause */ int i, j; /* Loop counters */ - struct SrcList_item *pLeft; /* Left table being joined */ - struct SrcList_item *pRight; /* Right table being joined */ + SrcItem *pLeft; /* Left table being joined */ + SrcItem *pRight; /* Right table being joined */ pSrc = p->pSrc; pLeft = &pSrc->a[0]; @@ -130305,7 +131609,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ int iRightCol; /* Column number of matching column on the right */ zName = pList->a[j].zName; - iRightCol = columnIndex(pRightTab, zName); + iRightCol = sqlite3ColumnIndex(pRightTab, zName); if( iRightCol<0 || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ @@ -131184,7 +132488,7 @@ SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( /* ** Name of the connection operator, used for error messages. */ -static const char *selectOpName(int id){ +SQLITE_PRIVATE const char *sqlite3SelectOpName(int id){ char *z; switch( id ){ case TK_ALL: z = "UNION ALL"; break; @@ -131887,6 +133191,7 @@ SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation( for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ const char *zType; int n, m; + pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT); p = a[i].pExpr; zType = columnType(&sNC, p, 0, 0, 0); /* pCol->szEst = ... // Column size est for SELECT tables never used */ @@ -132402,12 +133707,8 @@ static int multiSelect( db = pParse->db; pPrior = p->pPrior; dest = *pDest; - if( pPrior->pOrderBy || pPrior->pLimit ){ - sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", - pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op)); - rc = 1; - goto multi_select_end; - } + assert( pPrior->pOrderBy==0 ); + assert( pPrior->pLimit==0 ); v = sqlite3GetVdbe(pParse); assert( v!=0 ); /* The VDBE already created by calling function */ @@ -132464,7 +133765,7 @@ static int multiSelect( pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; rc = sqlite3Select(pParse, pPrior, &dest); - p->pLimit = 0; + pPrior->pLimit = 0; if( rc ){ goto multi_select_end; } @@ -132485,8 +133786,8 @@ static int multiSelect( pDelete = p->pPrior; p->pPrior = pPrior; p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); - if( pPrior->pLimit - && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) + if( p->pLimit + && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); @@ -132550,7 +133851,7 @@ static int multiSelect( p->pLimit = 0; uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); assert( p->pOrderBy==0 ); @@ -132626,7 +133927,7 @@ static int multiSelect( p->pLimit = 0; intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", - selectOpName(p->op))); + sqlite3SelectOpName(p->op))); rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; @@ -132735,7 +134036,8 @@ SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); }else{ sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" - " do not have the same number of result columns", selectOpName(p->op)); + " do not have the same number of result columns", + sqlite3SelectOpName(p->op)); } } @@ -132832,10 +134134,8 @@ static int generateOutputSubroutine( ** if it is the RHS of a row-value IN operator. */ case SRT_Mem: { - if( pParse->nErr==0 ){ - testcase( pIn->nSdst>1 ); - sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); - } + testcase( pIn->nSdst>1 ); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); /* The LIMIT clause will jump out of the loop for us */ break; } @@ -133127,7 +134427,7 @@ static int multiSelectOrderBy( sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); - ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op))); + ExplainQueryPlan((pParse, 1, "MERGE (%s)", sqlite3SelectOpName(p->op))); /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. @@ -133397,7 +134697,7 @@ static void substSelect( int doPrior /* Do substitutes on p->pPrior too */ ){ SrcList *pSrc; - struct SrcList_item *pItem; + SrcItem *pItem; int i; if( !p ) return; do{ @@ -133427,7 +134727,7 @@ static void substSelect( ** pSrcItem->colUsed mask. */ static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ - struct SrcList_item *pItem; + SrcItem *pItem; if( pExpr->op!=TK_COLUMN ) return WRC_Continue; pItem = pWalker->u.pSrcItem; if( pItem->iCursor!=pExpr->iTable ) return WRC_Continue; @@ -133437,7 +134737,7 @@ static int recomputeColumnsUsedExpr(Walker *pWalker, Expr *pExpr){ } static void recomputeColumnsUsed( Select *pSelect, /* The complete SELECT statement */ - struct SrcList_item *pSrcItem /* Which FROM clause item to recompute */ + SrcItem *pSrcItem /* Which FROM clause item to recompute */ ){ Walker w; if( NEVER(pSrcItem->pTab==0) ) return; @@ -133450,6 +134750,89 @@ static void recomputeColumnsUsed( } #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +/* +** Assign new cursor numbers to each of the items in pSrc. For each +** new cursor number assigned, set an entry in the aCsrMap[] array +** to map the old cursor number to the new: +** +** aCsrMap[iOld] = iNew; +** +** The array is guaranteed by the caller to be large enough for all +** existing cursor numbers in pSrc. +** +** If pSrc contains any sub-selects, call this routine recursively +** on the FROM clause of each such sub-select, with iExcept set to -1. +*/ +static void srclistRenumberCursors( + Parse *pParse, /* Parse context */ + int *aCsrMap, /* Array to store cursor mappings in */ + SrcList *pSrc, /* FROM clause to renumber */ + int iExcept /* FROM clause item to skip */ +){ + int i; + SrcItem *pItem; + for(i=0, pItem=pSrc->a; inSrc; i++, pItem++){ + if( i!=iExcept ){ + Select *p; + pItem->iCursor = aCsrMap[pItem->iCursor] = pParse->nTab++; + for(p=pItem->pSelect; p; p=p->pPrior){ + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, -1); + } + } + } +} + +/* +** Expression walker callback used by renumberCursors() to update +** Expr objects to match newly assigned cursor numbers. +*/ +static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){ + int *aCsrMap = pWalker->u.aiCol; + int op = pExpr->op; + if( (op==TK_COLUMN || op==TK_IF_NULL_ROW) && aCsrMap[pExpr->iTable] ){ + pExpr->iTable = aCsrMap[pExpr->iTable]; + } + if( ExprHasProperty(pExpr, EP_FromJoin) && aCsrMap[pExpr->iRightJoinTable] ){ + pExpr->iRightJoinTable = aCsrMap[pExpr->iRightJoinTable]; + } + return WRC_Continue; +} + +/* +** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc) +** of the SELECT statement passed as the second argument, and to each +** cursor in the FROM clause of any FROM clause sub-selects, recursively. +** Except, do not assign a new cursor number to the iExcept'th element in +** the FROM clause of (*p). Update all expressions and other references +** to refer to the new cursor numbers. +** +** Argument aCsrMap is an array that may be used for temporary working +** space. Two guarantees are made by the caller: +** +** * the array is larger than the largest cursor number used within the +** select statement passed as an argument, and +** +** * the array entries for all cursor numbers that do *not* appear in +** FROM clauses of the select statement as described above are +** initialized to zero. +*/ +static void renumberCursors( + Parse *pParse, /* Parse context */ + Select *p, /* Select to renumber cursors within */ + int iExcept, /* FROM clause item to skip */ + int *aCsrMap /* Working space */ +){ + Walker w; + srclistRenumberCursors(pParse, aCsrMap, p->pSrc, iExcept); + memset(&w, 0, sizeof(w)); + w.u.aiCol = aCsrMap; + w.xExprCallback = renumberCursorsCb; + w.xSelectCallback = sqlite3SelectWalkNoop; + sqlite3WalkSelect(&w, p); +} +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** This routine attempts to flatten subqueries as a performance optimization. @@ -133544,9 +134927,9 @@ static void recomputeColumnsUsed( ** (17c) every term within the subquery compound must have a FROM clause ** (17d) the outer query may not be ** (17d1) aggregate, or -** (17d2) DISTINCT, or -** (17d3) a join. -** (17e) the subquery may not contain window functions +** (17d2) DISTINCT +** (17e) the subquery may not contain window functions, and +** (17f) the subquery must not be the RHS of a LEFT JOIN. ** ** The parent and sub-query may contain WHERE clauses. Subject to ** rules (11), (13) and (14), they may also contain ORDER BY, @@ -133562,8 +134945,8 @@ static void recomputeColumnsUsed( ** syntax error and return a detailed message. ** ** (18) If the sub-query is a compound select, then all terms of the -** ORDER BY clause of the parent must be simple references to -** columns of the sub-query. +** ORDER BY clause of the parent must be copies of a term returned +** by the parent query. ** ** (19) If the subquery uses LIMIT then the outer query may not ** have a WHERE clause. @@ -133579,9 +134962,8 @@ static void recomputeColumnsUsed( ** ** (22) The subquery may not be a recursive CTE. ** -** (**) Subsumed into restriction (17d3). Was: If the outer query is -** a recursive CTE, then the sub-query may not be a compound query. -** This restriction is because transforming the +** (23) If the outer query is a recursive CTE, then the sub-query may not be +** a compound query. This restriction is because transforming the ** parent to a compound query confuses the code that handles ** recursive queries in multiSelect(). ** @@ -133623,9 +135005,10 @@ static int flattenSubquery( int isLeftJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ - struct SrcList_item *pSubitem; /* The subquery */ + SrcItem *pSubitem; /* The subquery */ sqlite3 *db = pParse->db; Walker w; /* Walker to persist agginfo data */ + int *aCsrMap = 0; /* Check to see if flattening is permitted. Return 0 if not. */ @@ -133721,13 +135104,14 @@ static int flattenSubquery( if( pSub->pOrderBy ){ return 0; /* Restriction (20) */ } - if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){ - return 0; /* (17d1), (17d2), or (17d3) */ + if( isAgg || (p->selFlags & SF_Distinct)!=0 || isLeftJoin>0 ){ + return 0; /* (17d1), (17d2), or (17f) */ } for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){ testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct ); testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate ); assert( pSub->pSrc!=0 ); + assert( (pSub->selFlags & SF_Recursive)==0 ); assert( pSub->pEList->nExpr==pSub1->pEList->nExpr ); if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */ || (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */ @@ -133748,15 +135132,15 @@ static int flattenSubquery( if( p->pOrderBy->a[ii].u.x.iOrderByCol==0 ) return 0; } } - } - /* Ex-restriction (23): - ** The only way that the recursive part of a CTE can contain a compound - ** subquery is for the subquery to be one term of a join. But if the - ** subquery is a join, then the flattening has already been stopped by - ** restriction (17d3) - */ - assert( (p->selFlags & SF_Recursive)==0 || pSub->pPrior==0 ); + /* Restriction (23) */ + if( (p->selFlags & SF_Recursive) ) return 0; + + if( pSrc->nSrc>1 ){ + if( pParse->nSelect>500 ) return 0; + aCsrMap = sqlite3DbMallocZero(db, pParse->nTab*sizeof(int)); + } + } /***** If we reach this point, flattening is permitted. *****/ SELECTTRACE(1,pParse,p,("flatten %u.%p from term %d\n", @@ -133768,6 +135152,17 @@ static int flattenSubquery( testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; + /* Delete the transient structures associated with thesubquery */ + pSub1 = pSubitem->pSelect; + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); + pSubitem->zDatabase = 0; + pSubitem->zName = 0; + pSubitem->zAlias = 0; + pSubitem->pSelect = 0; + assert( pSubitem->pOn==0 ); + /* If the sub-query is a compound SELECT statement, then (by restrictions ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: @@ -133806,18 +135201,23 @@ static int flattenSubquery( ExprList *pOrderBy = p->pOrderBy; Expr *pLimit = p->pLimit; Select *pPrior = p->pPrior; + Table *pItemTab = pSubitem->pTab; + pSubitem->pTab = 0; p->pOrderBy = 0; - p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; pNew = sqlite3SelectDup(db, p, 0); p->pLimit = pLimit; p->pOrderBy = pOrderBy; - p->pSrc = pSrc; p->op = TK_ALL; + pSubitem->pTab = pItemTab; if( pNew==0 ){ p->pPrior = pPrior; }else{ + pNew->selId = ++pParse->nSelect; + if( aCsrMap && db->mallocFailed==0 ){ + renumberCursors(pParse, pNew, iFrom, aCsrMap); + } pNew->pPrior = pPrior; if( pPrior ) pPrior->pNext = pNew; pNew->pNext = p; @@ -133825,24 +135225,13 @@ static int flattenSubquery( SELECTTRACE(2,pParse,p,("compound-subquery flattener" " creates %u as peer\n",pNew->selId)); } - if( db->mallocFailed ) return 1; + assert( pSubitem->pSelect==0 ); + } + sqlite3DbFree(db, aCsrMap); + if( db->mallocFailed ){ + pSubitem->pSelect = pSub1; + return 1; } - - /* Begin flattening the iFrom-th entry of the FROM clause - ** in the outer query. - */ - pSub = pSub1 = pSubitem->pSelect; - - /* Delete the transient table structure associated with the - ** subquery - */ - sqlite3DbFree(db, pSubitem->zDatabase); - sqlite3DbFree(db, pSubitem->zName); - sqlite3DbFree(db, pSubitem->zAlias); - pSubitem->zDatabase = 0; - pSubitem->zName = 0; - pSubitem->zAlias = 0; - pSubitem->pSelect = 0; /* Defer deleting the Table object associated with the ** subquery until code generation is @@ -133855,8 +135244,10 @@ static int flattenSubquery( Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - pTabToDel->pNextZombie = pToplevel->pZombieTab; - pToplevel->pZombieTab = pTabToDel; + sqlite3ParserAddCleanup(pToplevel, + (void(*)(sqlite3*,void*))sqlite3DeleteTable, + pTabToDel); + testcase( pToplevel->earlyCleanup ); }else{ pTabToDel->nTabRef--; } @@ -133876,6 +135267,7 @@ static int flattenSubquery( ** those references with expressions that resolve to the subquery FROM ** elements we are now copying in. */ + pSub = pSub1; for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){ int nSubSrc; u8 jointype = 0; @@ -133884,14 +135276,8 @@ static int flattenSubquery( nSubSrc = pSubSrc->nSrc; /* Number of terms in subquery FROM clause */ pSrc = pParent->pSrc; /* FROM clause of the outer query */ - if( pSrc ){ - assert( pParent==p ); /* First time through the loop */ - jointype = pSubitem->fg.jointype; - }else{ - assert( pParent!=p ); /* 2nd and subsequent times through the loop */ - pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); - if( pSrc==0 ) break; - pParent->pSrc = pSrc; + if( pParent==p ){ + jointype = pSubitem->fg.jointype; /* First time through the loop */ } /* The subquery uses a single slot of the FROM clause of the outer @@ -134011,7 +135397,7 @@ static int flattenSubquery( sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -134205,6 +135591,35 @@ static int propagateConstants( return nChng; } +#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) +# if !defined(SQLITE_OMIT_WINDOWFUNC) +/* +** This function is called to determine whether or not it is safe to +** push WHERE clause expression pExpr down to FROM clause sub-query +** pSubq, which contains at least one window function. Return 1 +** if it is safe and the expression should be pushed down, or 0 +** otherwise. +** +** It is only safe to push the expression down if it consists only +** of constants and copies of expressions that appear in the PARTITION +** BY clause of all window function used by the sub-query. It is safe +** to filter out entire partitions, but not rows within partitions, as +** this may change the results of the window functions. +** +** At the time this function is called it is guaranteed that +** +** * the sub-query uses only one distinct window frame, and +** * that the window frame has a PARTITION BY clase. +*/ +static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ + assert( pSubq->pWin->pPartition ); + assert( (pSubq->selFlags & SF_MultiPart)==0 ); + assert( pSubq->pPrior==0 ); + return sqlite3ExprIsConstantOrGroupBy(pParse, pExpr, pSubq->pWin->pPartition); +} +# endif /* SQLITE_OMIT_WINDOWFUNC */ +#endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */ + #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** Make copies of relevant WHERE clause terms of the outer query into @@ -134252,9 +135667,24 @@ static int propagateConstants( ** But if the (b2=2) term were to be pushed down into the bb subquery, ** then the (1,1,NULL) row would be suppressed. ** -** (6) The inner query features one or more window-functions (since -** changes to the WHERE clause of the inner query could change the -** window over which window functions are calculated). +** (6) Window functions make things tricky as changes to the WHERE clause +** of the inner query could change the window over which window +** functions are calculated. Therefore, do not attempt the optimization +** if: +** +** (6a) The inner query uses multiple incompatible window partitions. +** +** (6b) The inner query is a compound and uses window-functions. +** +** (6c) The WHERE clause does not consist entirely of constants and +** copies of expressions found in the PARTITION BY clause of +** all window-functions used by the sub-query. It is safe to +** filter out entire partitions, as this does not change the +** window over which any window-function is calculated. +** +** (7) The inner query is a Common Table Expression (CTE) that should +** be materialized. (This restriction is implemented in the calling +** routine.) ** ** Return 0 if no changes are made and non-zero if one or more WHERE clause ** terms are duplicated into the subquery. @@ -134268,13 +135698,17 @@ static int pushDownWhereTerms( ){ Expr *pNew; int nChng = 0; - Select *pSel; if( pWhere==0 ) return 0; - if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */ + if( pSubq->selFlags & (SF_Recursive|SF_MultiPart) ) return 0; #ifndef SQLITE_OMIT_WINDOWFUNC - for(pSel=pSubq; pSel; pSel=pSel->pPrior){ - if( pSel->pWin ) return 0; /* restriction (6) */ + if( pSubq->pPrior ){ + Select *pSel; + for(pSel=pSubq; pSel; pSel=pSel->pPrior){ + if( pSel->pWin ) return 0; /* restriction (6b) */ + } + }else{ + if( pSubq->pWin && pSubq->pWin->pPartition==0 ) return 0; } #endif @@ -134310,6 +135744,7 @@ static int pushDownWhereTerms( } if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; + pSubq->selFlags |= SF_PushDown; while( pSubq ){ SubstContext x; pNew = sqlite3ExprDup(pParse->db, pWhere, 0); @@ -134320,6 +135755,14 @@ static int pushDownWhereTerms( x.isLeftJoin = 0; x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSubq->pWin && 0==pushDownWindowCheck(pParse, pSubq, pNew) ){ + /* Restriction 6c has prevented push-down in this case */ + sqlite3ExprDelete(pParse->db, pNew); + nChng--; + break; + } +#endif if( pSubq->selFlags & SF_Aggregate ){ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); }else{ @@ -134358,7 +135801,11 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ assert( *ppMinMax==0 ); assert( pFunc->op==TK_AGG_FUNCTION ); assert( !IsWindowFunc(pFunc) ); - if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) ){ + if( pEList==0 + || pEList->nExpr!=1 + || ExprHasProperty(pFunc, EP_WinFunc) + || OptimizationDisabled(db, SQLITE_MinMaxOpt) + ){ return eRet; } zFunc = pFunc->u.zToken; @@ -134421,24 +135868,26 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ -SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ - if( pFrom->pTab && pFrom->fg.isIndexedBy ){ - Table *pTab = pFrom->pTab; - char *zIndexedBy = pFrom->u1.zIndexedBy; - Index *pIdx; - for(pIdx=pTab->pIndex; - pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); - pIdx=pIdx->pNext - ); - if( !pIdx ){ - sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); - pParse->checkSchema = 1; - return SQLITE_ERROR; - } - pFrom->pIBIndex = pIdx; +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ + Table *pTab = pFrom->pTab; + char *zIndexedBy = pFrom->u1.zIndexedBy; + Index *pIdx; + assert( pTab!=0 ); + assert( pFrom->fg.isIndexedBy!=0 ); + + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); + pIdx=pIdx->pNext + ); + if( !pIdx ){ + sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); + pParse->checkSchema = 1; + return SQLITE_ERROR; } + pFrom->u2.pIBIndex = pIdx; return SQLITE_OK; } + /* ** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. @@ -134525,7 +135974,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ ** arguments. If it does, leave an error message in pParse and return ** non-zero, since pFrom is not allowed to be a table-valued function. */ -static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ +static int cannotBeFunction(Parse *pParse, SrcItem *pFrom){ if( pFrom->fg.isTabFunc ){ sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); return 1; @@ -134546,19 +135995,19 @@ static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ */ static struct Cte *searchWith( With *pWith, /* Current innermost WITH clause */ - struct SrcList_item *pItem, /* FROM clause element to resolve */ + SrcItem *pItem, /* FROM clause element to resolve */ With **ppContext /* OUT: WITH clause return value belongs to */ ){ - const char *zName; - if( pItem->zDatabase==0 && (zName = pItem->zName)!=0 ){ - With *p; - for(p=pWith; p; p=p->pOuter){ - int i; - for(i=0; inCte; i++){ - if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ - *ppContext = p; - return &p->a[i]; - } + const char *zName = pItem->zName; + With *p; + assert( pItem->zDatabase==0 ); + assert( zName!=0 ); + for(p=pWith; p; p=p->pOuter){ + int i; + for(i=0; inCte; i++){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ + *ppContext = p; + return &p->a[i]; } } } @@ -134576,46 +136025,54 @@ static struct Cte *searchWith( ** statement with which it is associated. */ SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ - assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); if( pWith ){ assert( pParse->pWith!=pWith ); pWith->pOuter = pParse->pWith; pParse->pWith = pWith; - if( bFree ) pParse->pWithToFree = pWith; + if( bFree ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3WithDelete, + pWith); + testcase( pParse->earlyCleanup ); + } } } /* ** This function checks if argument pFrom refers to a CTE declared by -** a WITH clause on the stack currently maintained by the parser. And, -** if currently processing a CTE expression, if it is a recursive -** reference to the current CTE. +** a WITH clause on the stack currently maintained by the parser (on the +** pParse->pWith linked list). And if currently processing a CTE +** CTE expression, through routine checks to see if the reference is +** a recursive reference to the CTE. ** -** If pFrom falls into either of the two categories above, pFrom->pTab -** and other fields are populated accordingly. The caller should check -** (pFrom->pTab!=0) to determine whether or not a successful match -** was found. +** If pFrom matches a CTE according to either of these two above, pFrom->pTab +** and other fields are populated accordingly. ** -** Whether or not a match is found, SQLITE_OK is returned if no error -** occurs. If an error does occur, an error message is stored in the -** parser and some error code other than SQLITE_OK returned. +** Return 0 if no match is found. +** Return 1 if a match is found. +** Return 2 if an error condition is detected. */ -static int withExpand( - Walker *pWalker, - struct SrcList_item *pFrom +static int resolveFromTermToCte( + Parse *pParse, /* The parsing context */ + Walker *pWalker, /* Current tree walker */ + SrcItem *pFrom /* The FROM clause term to check */ ){ - Parse *pParse = pWalker->pParse; - sqlite3 *db = pParse->db; - struct Cte *pCte; /* Matched CTE (or NULL if no match) */ - With *pWith; /* WITH clause that pCte belongs to */ + Cte *pCte; /* Matched CTE (or NULL if no match) */ + With *pWith; /* The matching WITH */ assert( pFrom->pTab==0 ); - if( pParse->nErr ){ - return SQLITE_ERROR; + if( pParse->pWith==0 ){ + /* There are no WITH clauses in the stack. No match is possible */ + return 0; + } + if( pFrom->zDatabase!=0 ){ + /* The FROM term contains a schema qualifier (ex: main.t1) and so + ** it cannot possibly be a CTE reference. */ + return 0; } - pCte = searchWith(pParse->pWith, pFrom, &pWith); if( pCte ){ + sqlite3 *db = pParse->db; Table *pTab; ExprList *pEList; Select *pSel; @@ -134624,6 +136081,7 @@ static int withExpand( int bMayRecursive; /* True if compound joined by UNION [ALL] */ With *pSavedWith; /* Initial value of pParse->pWith */ int iRecTab = -1; /* Cursor for recursive table */ + CteUse *pCteUse; /* If pCte->zCteErr is non-NULL at this point, then this is an illegal ** recursive reference to CTE pCte. Leave an error in pParse and return @@ -134631,21 +136089,39 @@ static int withExpand( ** In this case, proceed. */ if( pCte->zCteErr ){ sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); - return SQLITE_ERROR; + return 2; } - if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; + if( cannotBeFunction(pParse, pFrom) ) return 2; assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); - if( pTab==0 ) return WRC_Abort; + pTab = sqlite3DbMallocZero(db, sizeof(Table)); + if( pTab==0 ) return 2; + pCteUse = pCte->pUse; + if( pCteUse==0 ){ + pCte->pUse = pCteUse = sqlite3DbMallocZero(db, sizeof(pCteUse[0])); + if( pCteUse==0 + || sqlite3ParserAddCleanup(pParse,sqlite3DbFree,pCteUse)==0 + ){ + sqlite3DbFree(db, pTab); + return 2; + } + pCteUse->eM10d = pCte->eM10d; + } + pFrom->pTab = pTab; pTab->nTabRef = 1; pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); - if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; + if( db->mallocFailed ) return 2; assert( pFrom->pSelect ); + pFrom->fg.isCte = 1; + pFrom->u2.pCteUse = pCteUse; + pCteUse->nUse++; + if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){ + pCteUse->eM10d = M10d_Yes; + } /* Check if this is a recursive CTE. */ pRecTerm = pSel = pFrom->pSelect; @@ -134655,7 +136131,7 @@ static int withExpand( SrcList *pSrc = pRecTerm->pSrc; assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pSrc->a[i]; + SrcItem *pItem = &pSrc->a[i]; if( pItem->zDatabase==0 && pItem->zName!=0 && 0==sqlite3StrICmp(pItem->zName, pCte->zName) @@ -134667,7 +136143,7 @@ static int withExpand( sqlite3ErrorMsg(pParse, "multiple references to recursive table: %s", pCte->zName ); - return SQLITE_ERROR; + return 2; } pRecTerm->selFlags |= SF_Recursive; if( iRecTab<0 ) iRecTab = pParse->nTab++; @@ -134703,7 +136179,7 @@ static int withExpand( pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; - return SQLITE_ERROR; + return 2; } pEList = pCte->pCols; } @@ -134719,9 +136195,9 @@ static int withExpand( } pCte->zCteErr = 0; pParse->pWith = pSavedWith; + return 1; /* Success */ } - - return SQLITE_OK; + return 0; /* No match */ } #endif @@ -134755,7 +136231,7 @@ static void selectPopWith(Walker *pWalker, Select *p){ ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ -SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, SrcItem *pFrom){ Select *pSel = pFrom->pSelect; Table *pTab; @@ -134803,10 +136279,10 @@ SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFr */ static int selectExpander(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; - int i, j, k; + int i, j, k, rc; SrcList *pTabList; ExprList *pEList; - struct SrcList_item *pFrom; + SrcItem *pFrom; sqlite3 *db = pParse->db; Expr *pE, *pRight, *pExpr; u16 selFlags = p->selFlags; @@ -134842,10 +136318,6 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 ); if( pFrom->pTab ) continue; assert( pFrom->fg.isRecursive==0 ); -#ifndef SQLITE_OMIT_CTE - if( withExpand(pWalker, pFrom) ) return WRC_Abort; - if( pFrom->pTab ) {} else -#endif if( pFrom->zName==0 ){ #ifndef SQLITE_OMIT_SUBQUERY Select *pSel = pFrom->pSelect; @@ -134854,6 +136326,12 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( pFrom->pTab==0 ); if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; +#endif +#ifndef SQLITE_OMIT_CTE + }else if( (rc = resolveFromTermToCte(pParse, pWalker, pFrom))!=0 ){ + if( rc>1 ) return WRC_Abort; + pTab = pFrom->pTab; + assert( pTab!=0 ); #endif }else{ /* An ordinary table or view name in the FROM clause */ @@ -134876,7 +136354,10 @@ static int selectExpander(Walker *pWalker, Select *p){ u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); - if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ + if( pTab->pSelect + && (db->flags & SQLITE_EnableView)==0 + && pTab->pSchema!=db->aDb[1].pSchema + ){ sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } @@ -134902,7 +136383,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } /* Locate the index named by the INDEXED BY clause, if any. */ - if( sqlite3IndexedByLookup(pParse, pFrom) ){ + if( pFrom->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pFrom) ){ return WRC_Abort; } } @@ -135145,7 +136626,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Parse *pParse; int i; SrcList *pTabList; - struct SrcList_item *pFrom; + SrcItem *pFrom; assert( p->selFlags & SF_Resolved ); if( p->selFlags & SF_HasTypeInfo ) return; @@ -135457,7 +136938,7 @@ static void havingToWhere(Parse *pParse, Select *p){ sWalker.u.pSelect = p; sqlite3WalkExpr(&sWalker, p->pHaving); #if SELECTTRACE_ENABLED - if( sWalker.eCode && (sqlite3_unsupported_selecttrace & 0x100)!=0 ){ + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135469,11 +136950,13 @@ static void havingToWhere(Parse *pParse, Select *p){ ** If it is, then return the SrcList_item for the prior view. If it is not, ** then return 0. */ -static struct SrcList_item *isSelfJoinView( +static SrcItem *isSelfJoinView( SrcList *pTabList, /* Search for self-joins in this FROM clause */ - struct SrcList_item *pThis /* Search for prior reference to this subquery */ + SrcItem *pThis /* Search for prior reference to this subquery */ ){ - struct SrcList_item *pItem; + SrcItem *pItem; + assert( pThis->pSelect!=0 ); + if( pThis->pSelect->selFlags & SF_PushDown ) return 0; for(pItem = pTabList->a; pItempSelect==0 ) continue; @@ -135489,9 +136972,7 @@ static struct SrcList_item *isSelfJoinView( ** names in the same FROM clause. */ continue; } - if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) - || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) - ){ + if( pItem->pSelect->selFlags & SF_PushDown ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ continue; @@ -135501,6 +136982,15 @@ static struct SrcList_item *isSelfJoinView( return 0; } +/* +** Deallocate a single AggInfo object +*/ +static void agginfoFree(sqlite3 *db, AggInfo *p){ + sqlite3DbFree(db, p->aCol); + sqlite3DbFree(db, p->aFunc); + sqlite3DbFreeNN(db, p); +} + #ifdef SQLITE_COUNTOFVIEW_OPTIMIZATION /* ** Attempt to transform a query of the form @@ -135579,7 +137069,7 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ p->selFlags &= ~SF_Aggregate; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135632,7 +137122,7 @@ SQLITE_PRIVATE int sqlite3Select( if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -135646,8 +137136,19 @@ SQLITE_PRIVATE int sqlite3Select( pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ - sqlite3ExprListDelete(db, p->pOrderBy); - p->pOrderBy = 0; + if( p->pOrderBy ){ +#if SELECTTRACE_ENABLED + SELECTTRACE(1,pParse,p, ("dropping superfluous ORDER BY:\n")); + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); + } +#endif + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + p->pOrderBy); + testcase( pParse->earlyCleanup ); + p->pOrderBy = 0; + } p->selFlags &= ~SF_Distinct; p->selFlags |= SF_NoopOrderBy; } @@ -135657,7 +137158,7 @@ SQLITE_PRIVATE int sqlite3Select( } assert( p->pEList!=0 ); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x104 ){ + if( sqlite3SelectTrace & 0x104 ){ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135668,9 +137169,9 @@ SQLITE_PRIVATE int sqlite3Select( ** In this case, it is an error if the target object (pSrc->a[0]) name ** or alias is duplicated within FROM clause (pSrc->a[1..n]). */ if( p->selFlags & SF_UpdateFrom ){ - struct SrcList_item *p0 = &p->pSrc->a[0]; + SrcItem *p0 = &p->pSrc->a[0]; for(i=1; ipSrc->nSrc; i++){ - struct SrcList_item *p1 = &p->pSrc->a[i]; + SrcItem *p1 = &p->pSrc->a[i]; if( p0->pTab==p1->pTab && 0==sqlite3_stricmp(p0->zAlias, p1->zAlias) ){ sqlite3ErrorMsg(pParse, "target object/alias may not appear in FROM clause: %s", @@ -135692,7 +137193,7 @@ SQLITE_PRIVATE int sqlite3Select( goto select_end; } #if SELECTTRACE_ENABLED - if( p->pWin && (sqlite3_unsupported_selecttrace & 0x108)!=0 ){ + if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135708,7 +137209,7 @@ SQLITE_PRIVATE int sqlite3Select( */ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) for(i=0; !p->pPrior && inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; Select *pSub = pItem->pSelect; Table *pTab = pItem->pTab; @@ -135799,7 +137300,7 @@ SQLITE_PRIVATE int sqlite3Select( rc = multiSelect(pParse, p, pDest); #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); - if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -135818,7 +137319,7 @@ SQLITE_PRIVATE int sqlite3Select( && propagateConstants(pParse, p) ){ #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -135842,7 +137343,8 @@ SQLITE_PRIVATE int sqlite3Select( ** (2) Generate code for all sub-queries */ for(i=0; inSrc; i++){ - struct SrcList_item *pItem = &pTabList->a[i]; + SrcItem *pItem = &pTabList->a[i]; + SrcItem *pPrior; SelectDest dest; Select *pSub; #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) @@ -135902,16 +137404,18 @@ SQLITE_PRIVATE int sqlite3Select( ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor, (pItem->fg.jointype & JT_OUTER)!=0) ){ #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); sqlite3TreeViewSelect(0, p, 0); } #endif + assert( pItem->pSelect && (pItem->pSelect->selFlags & SF_PushDown)!=0 ); }else{ SELECTTRACE(0x100,pParse,p,("Push-down not possible\n")); } @@ -135921,16 +137425,18 @@ SQLITE_PRIVATE int sqlite3Select( /* Generate code to implement the subquery ** - ** The subquery is implemented as a co-routine if the subquery is - ** guaranteed to be the outer loop (so that it does not need to be - ** computed more than once) + ** The subquery is implemented as a co-routine if: + ** (1) the subquery is guaranteed to be the outer loop (so that + ** it does not need to be computed more than once), and + ** (2) the subquery is not a CTE that should be materialized ** - ** TODO: Are there other reasons beside (1) to use a co-routine + ** TODO: Are there other reasons beside (1) and (2) to use a co-routine ** implementation? */ if( i==0 && (pTabList->nSrc==1 || (pTabList->a[1].fg.jointype&(JT_LEFT|JT_CROSS))!=0) /* (1) */ + && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes) /* (2) */ ){ /* Implement a co-routine that will return a single row of the result ** set on each invocation. @@ -135950,16 +137456,30 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeEndCoroutine(v, pItem->regReturn); sqlite3VdbeJumpHere(v, addrTop-1); sqlite3ClearTempRegCache(pParse); - }else{ - /* Generate a subroutine that will fill an ephemeral table with - ** the content of this subquery. pItem->addrFillSub will point - ** to the address of the generated subroutine. pItem->regReturn - ** is a register allocated to hold the subroutine return address - */ + }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ + /* This is a CTE for which materialization code has already been + ** generated. Invoke the subroutine to compute the materialization, + ** the make the pItem->iCursor be a copy of the ephemerial table that + ** holds the result of the materialization. */ + CteUse *pCteUse = pItem->u2.pCteUse; + sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); + if( pItem->iCursor!=pCteUse->iCur ){ + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur); + } + pSub->nSelectRow = pCteUse->nRowEst; + }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){ + /* This view has already been materialized by a prior entry in + ** this same FROM clause. Reuse it. */ + if( pPrior->addrFillSub ){ + sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub); + } + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + pSub->nSelectRow = pPrior->pSelect->nSelectRow; + }else{ + /* Generate a subroutine that will materialize the view. */ int topAddr; int onceAddr = 0; int retAddr; - struct SrcList_item *pPrior; testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */ pItem->regReturn = ++pParse->nMem; @@ -135974,22 +137494,22 @@ SQLITE_PRIVATE int sqlite3Select( }else{ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); } - pPrior = isSelfJoinView(pTabList, pItem); - if( pPrior ){ - sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); - assert( pPrior->pSelect!=0 ); - pSub->nSelectRow = pPrior->pSelect->nSelectRow; - }else{ - sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); - ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - sqlite3Select(pParse, pSub, &dest); - } + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); + sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); + if( pItem->fg.isCte ){ + CteUse *pCteUse = pItem->u2.pCteUse; + pCteUse->addrM9e = pItem->addrFillSub; + pCteUse->regRtn = pItem->regReturn; + pCteUse->iCur = pItem->iCursor; + pCteUse->nRowEst = pSub->nSelectRow; + } } if( db->mallocFailed ) goto select_end; pParse->nHeight -= sqlite3SelectExprHeight(p); @@ -136006,7 +137526,7 @@ SQLITE_PRIVATE int sqlite3Select( sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -136042,7 +137562,7 @@ SQLITE_PRIVATE int sqlite3Select( assert( sDistinct.isTnct ); #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); sqlite3TreeViewSelect(0, p, 0); } @@ -136134,6 +137654,7 @@ SQLITE_PRIVATE int sqlite3Select( sSort.pOrderBy = 0; } } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral @@ -136172,6 +137693,7 @@ SQLITE_PRIVATE int sqlite3Select( /* End the database scan loop. */ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); } }else{ @@ -136242,11 +137764,14 @@ SQLITE_PRIVATE int sqlite3Select( ** SELECT statement. */ pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) ); - if( pAggInfo==0 ){ + if( pAggInfo ){ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))agginfoFree, pAggInfo); + testcase( pParse->earlyCleanup ); + } + if( db->mallocFailed ){ goto select_end; } - pAggInfo->pNext = pParse->pAggList; - pParse->pAggList = pAggInfo; pAggInfo->selId = p->selId; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; @@ -136290,10 +137815,14 @@ SQLITE_PRIVATE int sqlite3Select( pAggInfo->mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if SELECTTRACE_ENABLED - if( sqlite3_unsupported_selecttrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo)); sqlite3TreeViewSelect(0, p, 0); + if( minMaxFlag ){ + sqlite3DebugPrintf("MIN/MAX Optimization (0x%02x) adds:\n", minMaxFlag); + sqlite3TreeViewExprList(0, pMinMaxOrderBy, 0, "ORDERBY"); + } for(ii=0; iinColumn; ii++){ sqlite3DebugPrintf("agg-column[%d] iMem=%d\n", ii, pAggInfo->aCol[ii].iMem); @@ -136361,6 +137890,7 @@ SQLITE_PRIVATE int sqlite3Select( WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); if( pWInfo==0 ) goto select_end; + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ /* The optimizer is able to deliver rows in group by order so ** we do not have to sort. The OP_OpenEphemeral table will be @@ -136409,6 +137939,7 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); @@ -136483,9 +138014,10 @@ SQLITE_PRIVATE int sqlite3Select( /* End of the loop */ if( groupBySort ){ - sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop); + sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx,addrTopOfLoop); VdbeCoverage(v); }else{ + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); sqlite3VdbeChangeToNoop(v, addrSortingIdx); } @@ -136595,7 +138127,6 @@ SQLITE_PRIVATE int sqlite3Select( explainSimpleCount(pParse, pTab, pBest); }else{ int regAcc = 0; /* "populate accumulators" flag */ - int addrSkip; /* If there are accumulator registers but no min() or max() functions ** without FILTER clauses, allocate register regAcc. Register regAcc @@ -136642,12 +138173,13 @@ SQLITE_PRIVATE int sqlite3Select( if( pWInfo==0 ){ goto select_end; } + SELECTTRACE(1,pParse,p,("WhereBegin returns\n")); updateAccumulator(pParse, regAcc, pAggInfo); if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); - addrSkip = sqlite3WhereOrderByLimitOptLabel(pWInfo); - if( addrSkip!=sqlite3WhereContinueLabel(pWInfo) ){ - sqlite3VdbeGoto(v, addrSkip); + if( minMaxFlag ){ + sqlite3WhereMinMaxOptEarlyOut(v, pWInfo); } + SELECTTRACE(1,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, pAggInfo); } @@ -136692,15 +138224,13 @@ SQLITE_PRIVATE int sqlite3Select( if( pAggInfo && !db->mallocFailed ){ for(i=0; inColumn; i++){ Expr *pExpr = pAggInfo->aCol[i].pCExpr; - assert( pExpr!=0 || db->mallocFailed ); - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; - assert( pExpr!=0 || db->mallocFailed ); - if( pExpr==0 ) continue; + assert( pExpr!=0 ); assert( pExpr->pAggInfo==pAggInfo ); assert( pExpr->iAgg==i ); } @@ -136709,7 +138239,7 @@ SQLITE_PRIVATE int sqlite3Select( #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end processing\n")); - if( (sqlite3_unsupported_selecttrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ sqlite3TreeViewSelect(0, p, 0); } #endif @@ -136970,28 +138500,39 @@ SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3 *db, TriggerStep *pTriggerS ** pTab as well as the triggers lised in pTab->pTrigger. */ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ - Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; - Trigger *pList = 0; /* List of triggers to return */ + Schema *pTmpSchema; /* Schema of the pTab table */ + Trigger *pList; /* List of triggers to return */ + HashElem *p; /* Loop variable for TEMP triggers */ if( pParse->disableTriggers ){ return 0; } - + pTmpSchema = pParse->db->aDb[1].pSchema; + p = sqliteHashFirst(&pTmpSchema->trigHash); + if( p==0 ){ + return pTab->pTrigger; + } + pList = pTab->pTrigger; if( pTmpSchema!=pTab->pSchema ){ - HashElem *p; - assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); - for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ + while( p ){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ - pTrig->pNext = (pList ? pList : pTab->pTrigger); + pTrig->pNext = pList; + pList = pTrig; + }else if( pTrig->op==TK_RETURNING ){ + assert( pParse->bReturning ); + assert( &(pParse->u1.pReturning->retTrig) == pTrig ); + pTrig->table = pTab->zName; + pTrig->pTabSchema = pTab->pSchema; + pTrig->pNext = pList; pList = pTrig; } + p = sqliteHashNext(p); } } - - return (pList ? pList : pTab->pTrigger); + return pList; } /* @@ -137267,7 +138808,7 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( sqlite3DbFree(db, z); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddParseSchemaOp(v, iDb, - sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName), 0); } if( db->init.busy ){ @@ -137480,7 +139021,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( ** Recursively delete a Trigger structure */ SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ - if( pTrigger==0 ) return; + if( pTrigger==0 || pTrigger->bReturning ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); @@ -137645,15 +139186,53 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist( Trigger *pList = 0; Trigger *p; - if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ - pList = sqlite3TriggerList(pParse, pTab); - } - assert( pList==0 || IsVirtual(pTab)==0 ); - for(p=pList; p; p=p->pNext){ - if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ - mask |= p->tr_tm; + pList = sqlite3TriggerList(pParse, pTab); + assert( pList==0 || IsVirtual(pTab)==0 + || (pList->bReturning && pList->pNext==0) ); + if( pList!=0 ){ + p = pList; + if( (pParse->db->flags & SQLITE_EnableTrigger)==0 + && pTab->pTrigger!=0 + ){ + /* The SQLITE_DBCONFIG_ENABLE_TRIGGER setting is off. That means that + ** only TEMP triggers are allowed. Truncate the pList so that it + ** includes only TEMP triggers */ + if( pList==pTab->pTrigger ){ + pList = 0; + goto exit_triggers_exist; + } + while( ALWAYS(p->pNext) && p->pNext!=pTab->pTrigger ) p = p->pNext; + p->pNext = 0; + p = pList; } + do{ + if( p->op==op && checkColumnOverlap(p->pColumns, pChanges) ){ + mask |= p->tr_tm; + }else if( p->op==TK_RETURNING ){ + /* The first time a RETURNING trigger is seen, the "op" value tells + ** us what time of trigger it should be. */ + assert( sqlite3IsToplevel(pParse) ); + p->op = op; + if( IsVirtual(pTab) ){ + if( op!=TK_INSERT ){ + sqlite3ErrorMsg(pParse, + "%s RETURNING is not available on virtual tables", + op==TK_DELETE ? "DELETE" : "UPDATE"); + } + p->tr_tm = TRIGGER_BEFORE; + }else{ + p->tr_tm = TRIGGER_AFTER; + } + mask |= p->tr_tm; + }else if( p->bReturning && p->op==TK_INSERT && op==TK_UPDATE + && sqlite3IsToplevel(pParse) ){ + /* Also fire a RETURNING trigger for an UPSERT */ + mask |= p->tr_tm; + } + p = p->pNext; + }while( p ); } +exit_triggers_exist: if( pMask ){ *pMask = mask; } @@ -137696,6 +139275,111 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( return pSrc; } +/* The input list pList is the list of result set terms from a RETURNING +** clause. The table that we are returning from is pTab. +** +** This routine makes a copy of the pList, and at the same time expands +** any "*" wildcards to be the complete set of columns from pTab. +*/ +static ExprList *sqlite3ExpandReturning( + Parse *pParse, /* Parsing context */ + ExprList *pList, /* The arguments to RETURNING */ + Table *pTab /* The table being updated */ +){ + ExprList *pNew = 0; + sqlite3 *db = pParse->db; + int i; + + for(i=0; inExpr; i++){ + Expr *pOldExpr = pList->a[i].pExpr; + if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ + int jj; + for(jj=0; jjnCol; jj++){ + Expr *pNewExpr; + if( IsHiddenColumn(pTab->aCol+jj) ) continue; + pNewExpr = sqlite3Expr(db, TK_ID, pTab->aCol[jj].zName); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pTab->aCol[jj].zName); + pItem->eEName = ENAME_NAME; + } + } + }else{ + Expr *pNewExpr = sqlite3ExprDup(db, pOldExpr, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, pNewExpr); + if( !db->mallocFailed && ALWAYS(pList->a[i].zEName!=0) ){ + struct ExprList_item *pItem = &pNew->a[pNew->nExpr-1]; + pItem->zEName = sqlite3DbStrDup(db, pList->a[i].zEName); + pItem->eEName = pList->a[i].eEName; + } + } + } + if( !db->mallocFailed ){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + sqlite3VdbeSetNumCols(v, pNew->nExpr); + for(i=0; inExpr; i++){ + sqlite3VdbeSetColName(v, i, COLNAME_NAME, pNew->a[i].zEName, + SQLITE_TRANSIENT); + } + } + return pNew; +} + +/* +** Generate code for the RETURNING trigger. Unlike other triggers +** that invoke a subprogram in the bytecode, the code for RETURNING +** is generated in-line. +*/ +static void codeReturningTrigger( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* The trigger step that defines the RETURNING */ + Table *pTab, /* The table to code triggers from */ + int regIn /* The first in an array of registers */ +){ + Vdbe *v = pParse->pVdbe; + ExprList *pNew; + Returning *pReturning; + + assert( v!=0 ); + assert( pParse->bReturning ); + pReturning = pParse->u1.pReturning; + assert( pTrigger == &(pReturning->retTrig) ); + pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); + if( pNew ){ + NameContext sNC; + memset(&sNC, 0, sizeof(sNC)); + if( pReturning->nRetCol==0 ){ + pReturning->nRetCol = pNew->nExpr; + pReturning->iRetCur = pParse->nTab++; + } + sNC.pParse = pParse; + sNC.uNC.iBaseReg = regIn; + sNC.ncFlags = NC_UBaseReg; + pParse->eTriggerOp = pTrigger->op; + pParse->pTriggerTab = pTab; + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){ + int i; + int nCol = pNew->nExpr; + int reg = pParse->nMem+1; + pParse->nMem += nCol+2; + pReturning->iRetReg = reg; + for(i=0; ia[i].pExpr, reg+i); + } + sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); + sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); + sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); + } + sqlite3ExprListDelete(pParse->db, pNew); + pParse->eTriggerOp = 0; + pParse->pTriggerTab = 0; + } +} + + + /* ** Generate VDBE code for the statements inside the body of a single ** trigger. @@ -137745,6 +139429,7 @@ static int codeTriggerProgram( sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_INSERT: { @@ -137755,6 +139440,7 @@ static int codeTriggerProgram( pParse->eOrconf, sqlite3UpsertDup(db, pStep->pUpsert) ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } case TK_DELETE: { @@ -137762,6 +139448,7 @@ static int codeTriggerProgram( sqlite3TriggerStepSrc(pParse, pStep), sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); + sqlite3VdbeAddOp0(v, OP_ResetCount); break; } default: assert( pStep->op==TK_SELECT ); { @@ -137773,9 +139460,6 @@ static int codeTriggerProgram( break; } } - if( pStep->op!=TK_SELECT ){ - sqlite3VdbeAddOp0(v, OP_ResetCount); - } } return 0; @@ -137922,7 +139606,6 @@ static TriggerPrg *codeRowTrigger( sqlite3VdbeDelete(v); } - assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); sqlite3ParserReset(pSubParse); sqlite3StackFree(db, pSubParse); @@ -138024,7 +139707,7 @@ SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( ** ... ... ** reg+N OLD.* value of right-most column of pTab ** reg+N+1 NEW.rowid -** reg+N+2 OLD.* value of left-most column of pTab +** reg+N+2 NEW.* value of left-most column of pTab ** ... ... ** reg+N+N+1 NEW.* value of right-most column of pTab ** @@ -138069,12 +139752,20 @@ SQLITE_PRIVATE void sqlite3CodeRowTrigger( assert( p->pSchema==p->pTabSchema || p->pSchema==pParse->db->aDb[1].pSchema ); - /* Determine whether we should code this trigger */ - if( p->op==op + /* Determine whether we should code this trigger. One of two choices: + ** 1. The trigger is an exact match to the current DML statement + ** 2. This is a RETURNING trigger for INSERT but we are currently + ** doing the UPDATE part of an UPSERT. + */ + if( (p->op==op || (p->bReturning && p->op==TK_INSERT && op==TK_UPDATE)) && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ - sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + if( !p->bReturning ){ + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + }else if( sqlite3IsToplevel(pParse) ){ + codeReturningTrigger(pParse, p, pTab, reg); + } } } } @@ -138119,13 +139810,18 @@ SQLITE_PRIVATE u32 sqlite3TriggerColmask( assert( isNew==1 || isNew==0 ); for(p=pTrigger; p; p=p->pNext){ - if( p->op==op && (tr_tm&p->tr_tm) + if( p->op==op + && (tr_tm&p->tr_tm) && checkColumnOverlap(p->pColumns,pChanges) ){ - TriggerPrg *pPrg; - pPrg = getRowTrigger(pParse, p, pTab, orconf); - if( pPrg ){ - mask |= pPrg->aColmask[isNew]; + if( p->bReturning ){ + mask = 0xffffffff; + }else{ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->aColmask[isNew]; + } } } } @@ -138782,6 +140478,7 @@ SQLITE_PRIVATE void sqlite3Update( if( (db->flags&SQLITE_CountRows)!=0 && !pParse->pTriggerTab && !pParse->nested + && !pParse->bReturning && pUpsert==0 ){ regRowCount = ++pParse->nMem; @@ -139245,7 +140942,7 @@ SQLITE_PRIVATE void sqlite3Update( ** that information. */ if( regRowCount ){ - sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); } @@ -139480,16 +141177,23 @@ static void updateVirtualTable( /* ** Free a list of Upsert objects */ -SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ - if( p ){ +static void SQLITE_NOINLINE upsertDelete(sqlite3 *db, Upsert *p){ + do{ + Upsert *pNext = p->pNextUpsert; sqlite3ExprListDelete(db, p->pUpsertTarget); sqlite3ExprDelete(db, p->pUpsertTargetWhere); sqlite3ExprListDelete(db, p->pUpsertSet); sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p->pToFree); sqlite3DbFree(db, p); - } + p = pNext; + }while( p ); +} +SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3 *db, Upsert *p){ + if( p ) upsertDelete(db, p); } + /* ** Duplicate an Upsert object. */ @@ -139499,7 +141203,8 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ sqlite3ExprListDup(db, p->pUpsertTarget, 0), sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), sqlite3ExprListDup(db, p->pUpsertSet, 0), - sqlite3ExprDup(db, p->pUpsertWhere, 0) + sqlite3ExprDup(db, p->pUpsertWhere, 0), + sqlite3UpsertDup(db, p->pNextUpsert) ); } @@ -139511,22 +141216,25 @@ SQLITE_PRIVATE Upsert *sqlite3UpsertNew( ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ Expr *pTargetWhere, /* Optional WHERE clause on the target */ ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ - Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ + Expr *pWhere, /* WHERE clause for the ON CONFLICT UPDATE */ + Upsert *pNext /* Next ON CONFLICT clause in the list */ ){ Upsert *pNew; - pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); + pNew = sqlite3DbMallocZero(db, sizeof(Upsert)); if( pNew==0 ){ sqlite3ExprListDelete(db, pTarget); sqlite3ExprDelete(db, pTargetWhere); sqlite3ExprListDelete(db, pSet); sqlite3ExprDelete(db, pWhere); + sqlite3UpsertDelete(db, pNext); return 0; }else{ pNew->pUpsertTarget = pTarget; pNew->pUpsertTargetWhere = pTargetWhere; pNew->pUpsertSet = pSet; pNew->pUpsertWhere = pWhere; - pNew->pUpsertIdx = 0; + pNew->isDoUpdate = pSet!=0; + pNew->pNextUpsert = pNext; } return pNew; } @@ -139551,6 +141259,7 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( Expr *pTerm; /* One term of the conflict-target clause */ NameContext sNC; /* Context for resolving symbolic names */ Expr sCol[2]; /* Index column converted into an Expr */ + int nClause = 0; /* Counter of ON CONFLICT clauses */ assert( pTabList->nSrc==1 ); assert( pTabList->a[0].pTab!=0 ); @@ -139564,87 +141273,131 @@ SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; - rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); - if( rc ) return rc; - rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); - if( rc ) return rc; + for(; pUpsert && pUpsert->pUpsertTarget; + pUpsert=pUpsert->pNextUpsert, nClause++){ + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + if( rc ) return rc; + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + if( rc ) return rc; - /* Check to see if the conflict target matches the rowid. */ - pTab = pTabList->a[0].pTab; - pTarget = pUpsert->pUpsertTarget; - iCursor = pTabList->a[0].iCursor; - if( HasRowid(pTab) - && pTarget->nExpr==1 - && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN - && pTerm->iColumn==XN_ROWID - ){ - /* The conflict-target is the rowid of the primary table */ - assert( pUpsert->pUpsertIdx==0 ); - return SQLITE_OK; - } + /* Check to see if the conflict target matches the rowid. */ + pTab = pTabList->a[0].pTab; + pTarget = pUpsert->pUpsertTarget; + iCursor = pTabList->a[0].iCursor; + if( HasRowid(pTab) + && pTarget->nExpr==1 + && (pTerm = pTarget->a[0].pExpr)->op==TK_COLUMN + && pTerm->iColumn==XN_ROWID + ){ + /* The conflict-target is the rowid of the primary table */ + assert( pUpsert->pUpsertIdx==0 ); + continue; + } - /* Initialize sCol[0..1] to be an expression parse tree for a - ** single column of an index. The sCol[0] node will be the TK_COLLATE - ** operator and sCol[1] will be the TK_COLUMN operator. Code below - ** will populate the specific collation and column number values - ** prior to comparing against the conflict-target expression. - */ - memset(sCol, 0, sizeof(sCol)); - sCol[0].op = TK_COLLATE; - sCol[0].pLeft = &sCol[1]; - sCol[1].op = TK_COLUMN; - sCol[1].iTable = pTabList->a[0].iCursor; + /* Initialize sCol[0..1] to be an expression parse tree for a + ** single column of an index. The sCol[0] node will be the TK_COLLATE + ** operator and sCol[1] will be the TK_COLUMN operator. Code below + ** will populate the specific collation and column number values + ** prior to comparing against the conflict-target expression. + */ + memset(sCol, 0, sizeof(sCol)); + sCol[0].op = TK_COLLATE; + sCol[0].pLeft = &sCol[1]; + sCol[1].op = TK_COLUMN; + sCol[1].iTable = pTabList->a[0].iCursor; - /* Check for matches against other indexes */ - for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - int ii, jj, nn; - if( !IsUniqueIndex(pIdx) ) continue; - if( pTarget->nExpr!=pIdx->nKeyCol ) continue; - if( pIdx->pPartIdxWhere ){ - if( pUpsert->pUpsertTargetWhere==0 ) continue; - if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, - pIdx->pPartIdxWhere, iCursor)!=0 ){ - continue; + /* Check for matches against other indexes */ + for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int ii, jj, nn; + if( !IsUniqueIndex(pIdx) ) continue; + if( pTarget->nExpr!=pIdx->nKeyCol ) continue; + if( pIdx->pPartIdxWhere ){ + if( pUpsert->pUpsertTargetWhere==0 ) continue; + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + pIdx->pPartIdxWhere, iCursor)!=0 ){ + continue; + } } - } - nn = pIdx->nKeyCol; - for(ii=0; iiazColl[ii]; - if( pIdx->aiColumn[ii]==XN_EXPR ){ - assert( pIdx->aColExpr!=0 ); - assert( pIdx->aColExpr->nExpr>ii ); - pExpr = pIdx->aColExpr->a[ii].pExpr; - if( pExpr->op!=TK_COLLATE ){ - sCol[0].pLeft = pExpr; + nn = pIdx->nKeyCol; + for(ii=0; iiazColl[ii]; + if( pIdx->aiColumn[ii]==XN_EXPR ){ + assert( pIdx->aColExpr!=0 ); + assert( pIdx->aColExpr->nExpr>ii ); + pExpr = pIdx->aColExpr->a[ii].pExpr; + if( pExpr->op!=TK_COLLATE ){ + sCol[0].pLeft = pExpr; + pExpr = &sCol[0]; + } + }else{ + sCol[0].pLeft = &sCol[1]; + sCol[1].iColumn = pIdx->aiColumn[ii]; pExpr = &sCol[0]; } - }else{ - sCol[0].pLeft = &sCol[1]; - sCol[1].iColumn = pIdx->aiColumn[ii]; - pExpr = &sCol[0]; - } - for(jj=0; jja[jj].pExpr, pExpr,iCursor)<2 ){ - break; /* Column ii of the index matches column jj of target */ + for(jj=0; jja[jj].pExpr,pExpr,iCursor)<2 ){ + break; /* Column ii of the index matches column jj of target */ + } + } + if( jj>=nn ){ + /* The target contains no match for column jj of the index */ + break; } } - if( jj>=nn ){ - /* The target contains no match for column jj of the index */ - break; + if( iipUpsertIdx = pIdx; + break; } - if( iipUpsertIdx==0 ){ + char zWhich[16]; + if( nClause==0 && pUpsert->pNextUpsert==0 ){ + zWhich[0] = 0; + }else{ + sqlite3_snprintf(sizeof(zWhich),zWhich,"%r ", nClause+1); + } + sqlite3ErrorMsg(pParse, "%sON CONFLICT clause does not match any " + "PRIMARY KEY or UNIQUE constraint", zWhich); + return SQLITE_ERROR; } - pUpsert->pUpsertIdx = pIdx; - return SQLITE_OK; } - sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " - "PRIMARY KEY or UNIQUE constraint"); - return SQLITE_ERROR; + return SQLITE_OK; +} + +/* +** Return true if pUpsert is the last ON CONFLICT clause with a +** conflict target, or if pUpsert is followed by another ON CONFLICT +** clause that targets the INTEGER PRIMARY KEY. +*/ +SQLITE_PRIVATE int sqlite3UpsertNextIsIPK(Upsert *pUpsert){ + Upsert *pNext; + if( NEVER(pUpsert==0) ) return 0; + pNext = pUpsert->pNextUpsert; + if( pNext==0 ) return 1; + if( pNext->pUpsertTarget==0 ) return 1; + if( pNext->pUpsertIdx==0 ) return 1; + return 0; +} + +/* +** Given the list of ON CONFLICT clauses described by pUpsert, and +** a particular index pIdx, return a pointer to the particular ON CONFLICT +** clause that applies to the index. Or, if the index is not subject to +** any ON CONFLICT clause, return NULL. +*/ +SQLITE_PRIVATE Upsert *sqlite3UpsertOfIndex(Upsert *pUpsert, Index *pIdx){ + while( + pUpsert + && pUpsert->pUpsertTarget!=0 + && pUpsert->pUpsertIdx!=pIdx + ){ + pUpsert = pUpsert->pNextUpsert; + } + return pUpsert; } /* @@ -139668,11 +141421,13 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( SrcList *pSrc; /* FROM clause for the UPDATE */ int iDataCur; int i; + Upsert *pTop = pUpsert; assert( v!=0 ); assert( pUpsert!=0 ); - VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); iDataCur = pUpsert->iDataCur; + pUpsert = sqlite3UpsertOfIndex(pTop, pIdx); + VdbeNoopComment((v, "Begin DO UPDATE of UPSERT")); if( pIdx && iCur!=iDataCur ){ if( HasRowid(pTab) ){ int regRowid = sqlite3GetTempReg(pParse); @@ -139702,19 +141457,17 @@ SQLITE_PRIVATE void sqlite3UpsertDoUpdate( sqlite3VdbeJumpHere(v, i); } } - /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So - ** we have to make a copy before passing it down into sqlite3Update() */ - pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); + /* pUpsert does not own pTop->pUpsertSrc - the outer INSERT statement does. + ** So we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pTop->pUpsertSrc, 0); /* excluded.* columns of type REAL need to be converted to a hard real */ for(i=0; inCol; i++){ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); + sqlite3VdbeAddOp1(v, OP_RealAffinity, pTop->regData+i); } } - sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, - pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); - pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ - pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ + sqlite3Update(pParse, pSrc, sqlite3ExprListDup(db,pUpsert->pUpsertSet,0), + sqlite3ExprDup(db,pUpsert->pUpsertWhere,0), OE_Abort, 0, 0, pUpsert); VdbeNoopComment((v, "End DO UPDATE of UPSERT")); } @@ -140620,7 +142373,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ sqlite3VdbeAddOp0(v, OP_Expire); zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); - sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere, 0); sqlite3DbFree(db, zStmt); iReg = ++pParse->nMem; @@ -140791,6 +142544,7 @@ static int vtabCallConstructor( zType[i-1] = '\0'; } pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN; + pTab->tabFlags |= TF_HasHidden; oooHidden = TF_OOOHidden; }else{ pTab->tabFlags |= oooHidden; @@ -140959,7 +142713,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ Table *pNew = sParse.pNewTable; Index *pIdx; pTab->aCol = pNew->aCol; - pTab->nCol = pNew->nCol; + pTab->nNVCol = pTab->nCol = pNew->nCol; pTab->tabFlags |= pNew->tabFlags & (TF_WithoutRowid|TF_NoVisibleRowid); pNew->nCol = 0; pNew->aCol = 0; @@ -141491,19 +143245,6 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ #ifndef SQLITE_WHEREINT_H #define SQLITE_WHEREINT_H -/* -** Trace output macros -*/ -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ extern int sqlite3WhereTrace; -#endif -#if defined(SQLITE_DEBUG) \ - && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) -# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X -# define WHERETRACE_ENABLED 1 -#else -# define WHERETRACE(K,X) -#endif /* Forward references */ @@ -141757,11 +143498,7 @@ struct WhereTerm { #define TERM_ORINFO 0x0010 /* Need to free the WhereTerm.u.pOrInfo object */ #define TERM_ANDINFO 0x0020 /* Need to free the WhereTerm.u.pAndInfo obj */ #define TERM_OR_OK 0x0040 /* Used during OR-clause processing */ -#ifdef SQLITE_ENABLE_STAT4 -# define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ -#else -# define TERM_VNULL 0x0000 /* Disabled if not using stat4 */ -#endif +#define TERM_VNULL 0x0080 /* Manufactured x>NULL or x<=NULL term */ #define TERM_LIKEOPT 0x0100 /* Virtual terms from the LIKE optimization */ #define TERM_LIKECOND 0x0200 /* Conditionally this LIKE operator term */ #define TERM_LIKE 0x0400 /* The original LIKE operator */ @@ -142031,7 +143768,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); -SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); @@ -142209,7 +143946,7 @@ SQLITE_PRIVATE int sqlite3WhereExplainOneScan( if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { - struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; + SrcItem *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ @@ -143002,7 +144739,7 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ ** Insert an OP_CursorHint instruction if it is appropriate to do so. */ static void codeCursorHint( - struct SrcList_item *pTabItem, /* FROM clause item */ + SrcItem *pTabItem, /* FROM clause item */ WhereInfo *pWInfo, /* The where clause */ WhereLevel *pLevel, /* Which loop to provide hints for */ WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ @@ -143377,7 +145114,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ sqlite3 *db; /* Database connection */ - struct SrcList_item *pTabItem; /* FROM clause term being coded */ + SrcItem *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ int addrHalt; /* addrBrk for the outermost loop */ int addrCont; /* Jump here to continue with next cycle */ @@ -143823,6 +145560,12 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( SWAP(u8, nBtm, nTop); } + if( iLevel>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 ){ + /* In case OP_SeekScan is used, ensure that the index cursor does not + ** point to a valid row for the first iteration of this loop. */ + sqlite3VdbeAddOp1(v, OP_NullRow, iIdxCur); + } + /* Generate code to evaluate all constraint terms using == or IN ** and store the values of those terms in an array of registers ** starting at regBase. @@ -144159,7 +145902,7 @@ SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ - struct SrcList_item *origSrc; /* Original list of tables */ + SrcItem *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); @@ -145578,6 +147321,276 @@ static int exprMightBeIndexed( return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); } +/* +** Expression callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistCb(Walker *p, Expr *pExpr){ + if( pExpr->op==TK_COLUMN ){ + SrcList *pSrc = p->u.pSrcList; + int iCsr = pExpr->iTable; + int ii; + for(ii=0; iinSrc; ii++){ + if( pSrc->a[ii].iCursor==iCsr ){ + return p->eCode ? WRC_Abort : WRC_Continue; + } + } + return p->eCode ? WRC_Continue : WRC_Abort; + } + return WRC_Continue; +} + +/* +** Select callback for exprUsesSrclist(). +*/ +static int exprUsesSrclistSelectCb(Walker *NotUsed1, Select *NotUsed2){ + UNUSED_PARAMETER(NotUsed1); + UNUSED_PARAMETER(NotUsed2); + return WRC_Abort; +} + +/* +** This function always returns true if expression pExpr contains +** a sub-select. +** +** If there is no sub-select in pExpr, then return true if pExpr +** contains a TK_COLUMN node for a table that is (bUses==1) +** or is not (bUses==0) in pSrc. +** +** Said another way: +** +** bUses Return Meaning +** -------- ------ ------------------------------------------------ +** +** bUses==1 true pExpr contains either a sub-select or a +** TK_COLUMN referencing pSrc. +** +** bUses==1 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference tables not found in pSrc +** +** bUses==0 true pExpr contains either a sub-select or a TK_COLUMN +** that references a table not in pSrc. +** +** bUses==0 false pExpr contains no sub-selects and all TK_COLUMN +** nodes reference pSrc +*/ +static int exprUsesSrclist(SrcList *pSrc, Expr *pExpr, int bUses){ + Walker sWalker; + memset(&sWalker, 0, sizeof(Walker)); + sWalker.eCode = bUses; + sWalker.u.pSrcList = pSrc; + sWalker.xExprCallback = exprUsesSrclistCb; + sWalker.xSelectCallback = exprUsesSrclistSelectCb; + return (sqlite3WalkExpr(&sWalker, pExpr)==WRC_Abort); +} + +/* +** Context object used by exprExistsToInIter() as it iterates through an +** expression tree. +*/ +struct ExistsToInCtx { + SrcList *pSrc; /* The tables in an EXISTS(SELECT ... FROM ...) */ + Expr *pInLhs; /* OUT: Use this as the LHS of the IN operator */ + Expr *pEq; /* OUT: The == term that include pInLhs */ + Expr **ppAnd; /* OUT: The AND operator that includes pEq as a child */ + Expr **ppParent; /* The AND operator currently being examined */ +}; + +/* +** Iterate through all AND connected nodes in the expression tree +** headed by (*ppExpr), populating the structure passed as the first +** argument with the values required by exprAnalyzeExistsFindEq(). +** +** This function returns non-zero if the expression tree does not meet +** the two conditions described by the header comment for +** exprAnalyzeExistsFindEq(), or zero if it does. +*/ +static int exprExistsToInIter(struct ExistsToInCtx *p, Expr **ppExpr){ + Expr *pExpr = *ppExpr; + switch( pExpr->op ){ + case TK_AND: + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pLeft) ) return 1; + p->ppParent = ppExpr; + if( exprExistsToInIter(p, &pExpr->pRight) ) return 1; + break; + case TK_EQ: { + int bLeft = exprUsesSrclist(p->pSrc, pExpr->pLeft, 0); + int bRight = exprUsesSrclist(p->pSrc, pExpr->pRight, 0); + if( bLeft || bRight ){ + if( (bLeft && bRight) || p->pInLhs ) return 1; + p->pInLhs = bLeft ? pExpr->pLeft : pExpr->pRight; + if( exprUsesSrclist(p->pSrc, p->pInLhs, 1) ) return 1; + p->pEq = pExpr; + p->ppAnd = p->ppParent; + } + break; + } + default: + if( exprUsesSrclist(p->pSrc, pExpr, 0) ){ + return 1; + } + break; + } + + return 0; +} + +/* +** This function is used by exprAnalyzeExists() when creating virtual IN(...) +** terms equivalent to user-supplied EXIST(...) clauses. It splits the WHERE +** clause of the Select object passed as the first argument into one or more +** expressions joined by AND operators, and then tests if the following are +** true: +** +** 1. Exactly one of the AND separated terms refers to the outer +** query, and it is an == (TK_EQ) expression. +** +** 2. Only one side of the == expression refers to the outer query, and +** it does not refer to any columns from the inner query. +** +** If both these conditions are true, then a pointer to the side of the == +** expression that refers to the outer query is returned. The caller will +** use this expression as the LHS of the IN(...) virtual term. Or, if one +** or both of the above conditions are not true, NULL is returned. +** +** If non-NULL is returned and ppEq is non-NULL, *ppEq is set to point +** to the == expression node before returning. If pppAnd is non-NULL and +** the == node is not the root of the WHERE clause, then *pppAnd is set +** to point to the pointer to the AND node that is the parent of the == +** node within the WHERE expression tree. +*/ +static Expr *exprAnalyzeExistsFindEq( + Select *pSel, /* The SELECT of the EXISTS */ + Expr **ppEq, /* OUT: == node from WHERE clause */ + Expr ***pppAnd /* OUT: Pointer to parent of ==, if any */ +){ + struct ExistsToInCtx ctx; + memset(&ctx, 0, sizeof(ctx)); + ctx.pSrc = pSel->pSrc; + if( exprExistsToInIter(&ctx, &pSel->pWhere) ){ + return 0; + } + if( ppEq ) *ppEq = ctx.pEq; + if( pppAnd ) *pppAnd = ctx.ppAnd; + return ctx.pInLhs; +} + +/* +** Term idxTerm of the WHERE clause passed as the second argument is an +** EXISTS expression with a correlated SELECT statement on the RHS. +** This function analyzes the SELECT statement, and if possible adds an +** equivalent "? IN(SELECT...)" virtual term to the WHERE clause. +** +** For an EXISTS term such as the following: +** +** EXISTS (SELECT ... FROM WHERE = AND ) +** +** The virtual IN() term added is: +** +** IN (SELECT FROM WHERE ) +** +** The virtual term is only added if the following conditions are met: +** +** 1. The sub-select must not be an aggregate or use window functions, +** +** 2. The sub-select must not be a compound SELECT, +** +** 3. Expression must refer to at least one column from the outer +** query, and must not refer to any column from the inner query +** (i.e. from ). +** +** 4. and must not refer to any values from the outer query. +** In other words, once has been removed, the inner query +** must not be correlated. +** +*/ +static void exprAnalyzeExists( + SrcList *pSrc, /* the FROM clause */ + WhereClause *pWC, /* the WHERE clause */ + int idxTerm /* Index of the term to be analyzed */ +){ + Parse *pParse = pWC->pWInfo->pParse; + WhereTerm *pTerm = &pWC->a[idxTerm]; + Expr *pExpr = pTerm->pExpr; + Select *pSel = pExpr->x.pSelect; + Expr *pDup = 0; + Expr *pEq = 0; + Expr *pRet = 0; + Expr *pInLhs = 0; + Expr **ppAnd = 0; + int idxNew; + sqlite3 *db = pParse->db; + + assert( pExpr->op==TK_EXISTS ); + assert( (pExpr->flags & EP_VarSelect) && (pExpr->flags & EP_xIsSelect) ); + + if( pSel->selFlags & SF_Aggregate ) return; +#ifndef SQLITE_OMIT_WINDOWFUNC + if( pSel->pWin ) return; +#endif + if( pSel->pPrior ) return; + if( pSel->pWhere==0 ) return; + if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; + + pDup = sqlite3ExprDup(db, pExpr, 0); + if( db->mallocFailed ){ + sqlite3ExprDelete(db, pDup); + return; + } + pSel = pDup->x.pSelect; + sqlite3ExprListDelete(db, pSel->pEList); + pSel->pEList = 0; + + pInLhs = exprAnalyzeExistsFindEq(pSel, &pEq, &ppAnd); + assert( pInLhs && pEq ); + assert( pEq==pSel->pWhere || ppAnd ); + if( pInLhs==pEq->pLeft ){ + pRet = pEq->pRight; + }else{ + CollSeq *p = sqlite3ExprCompareCollSeq(pParse, pEq); + pInLhs = sqlite3ExprAddCollateString(pParse, pInLhs, p?p->zName:"BINARY"); + pRet = pEq->pLeft; + } + + assert( pDup->pLeft==0 ); + pDup->op = TK_IN; + pDup->pLeft = pInLhs; + pDup->flags &= ~EP_VarSelect; + if( pRet->op==TK_VECTOR ){ + pSel->pEList = pRet->x.pList; + pRet->x.pList = 0; + sqlite3ExprDelete(db, pRet); + }else{ + pSel->pEList = sqlite3ExprListAppend(pParse, 0, pRet); + } + pEq->pLeft = 0; + pEq->pRight = 0; + if( ppAnd ){ + Expr *pAnd = *ppAnd; + Expr *pOther = (pAnd->pLeft==pEq) ? pAnd->pRight : pAnd->pLeft; + pAnd->pLeft = pAnd->pRight = 0; + sqlite3ExprDelete(db, pAnd); + *ppAnd = pOther; + }else{ + assert( pSel->pWhere==pEq ); + pSel->pWhere = 0; + } + sqlite3ExprDelete(db, pEq); + +#ifdef WHERETRACE_ENABLED /* 0x20 */ + if( sqlite3WhereTrace & 0x20 ){ + sqlite3DebugPrintf("Convert EXISTS:\n"); + sqlite3TreeViewExpr(0, pExpr, 0); + sqlite3DebugPrintf("into IN:\n"); + sqlite3TreeViewExpr(0, pDup, 0); + } +#endif + idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); + exprAnalyze(pSrc, pWC, idxNew); + markTermAsChild(pWC, idxNew, idxTerm); + pWC->a[idxTerm].wtFlags |= TERM_COPIED; +} + /* ** The input to this routine is an WhereTerm structure with only the ** "pExpr" field filled in. The job of this routine is to analyze the @@ -145711,6 +147724,12 @@ static void exprAnalyze( pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; + }else if( op==TK_ISNULL && 0==sqlite3ExprCanBeNull(pLeft) ){ + pExpr->op = TK_TRUEFALSE; + pExpr->u.zToken = "false"; + ExprSetProperty(pExpr, EP_IsFalse); + pTerm->prereqAll = 0; + pTerm->eOperator = 0; } } @@ -145763,6 +147782,52 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ + else if( pExpr->op==TK_EXISTS ){ + /* Perhaps treat an EXISTS operator as an IN operator */ + if( (pExpr->flags & EP_VarSelect)!=0 + && OptimizationEnabled(db, SQLITE_ExistsToIN) + ){ + exprAnalyzeExists(pSrc, pWC, idxTerm); + } + } + + /* The form "x IS NOT NULL" can sometimes be evaluated more efficiently + ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a + ** virtual term of that form. + ** + ** The virtual term must be tagged with TERM_VNULL. + */ + else if( pExpr->op==TK_NOTNULL ){ + if( pExpr->pLeft->op==TK_COLUMN + && pExpr->pLeft->iColumn>=0 + && !ExprHasProperty(pExpr, EP_FromJoin) + ){ + Expr *pNewExpr; + Expr *pLeft = pExpr->pLeft; + int idxNew; + WhereTerm *pNewTerm; + + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); + + idxNew = whereClauseInsert(pWC, pNewExpr, + TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); + if( idxNew ){ + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = 0; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_GT; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + } + } + + #ifndef SQLITE_OMIT_LIKE_OPTIMIZATION /* Add constraints to reduce the search space on a LIKE or GLOB ** operator. @@ -145777,7 +147842,8 @@ static void exprAnalyze( ** bound is made all lowercase so that the bounds also work when comparing ** BLOBs. */ - if( pWC->op==TK_AND + else if( pExpr->op==TK_FUNCTION + && pWC->op==TK_AND && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase) ){ Expr *pLeft; /* LHS of LIKE/GLOB operator */ @@ -145847,52 +147913,6 @@ static void exprAnalyze( } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ -#ifndef SQLITE_OMIT_VIRTUALTABLE - /* Add a WO_AUX auxiliary term to the constraint set if the - ** current expression is of the form "column OP expr" where OP - ** is an operator that gets passed into virtual tables but which is - ** not normally optimized for ordinary tables. In other words, OP - ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. - ** This information is used by the xBestIndex methods of - ** virtual tables. The native query optimizer does not attempt - ** to do anything with MATCH functions. - */ - if( pWC->op==TK_AND ){ - Expr *pRight = 0, *pLeft = 0; - int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); - while( res-- > 0 ){ - int idxNew; - WhereTerm *pNewTerm; - Bitmask prereqColumn, prereqExpr; - - prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); - prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); - if( (prereqExpr & prereqColumn)==0 ){ - Expr *pNewExpr; - pNewExpr = sqlite3PExpr(pParse, TK_MATCH, - 0, sqlite3ExprDup(db, pRight, 0)); - if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ - ExprSetProperty(pNewExpr, EP_FromJoin); - pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; - } - idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); - testcase( idxNew==0 ); - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = prereqExpr; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.x.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_AUX; - pNewTerm->eMatchOp = eOp2; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; - } - SWAP(Expr*, pLeft, pRight); - } - } -#endif /* SQLITE_OMIT_VIRTUALTABLE */ - /* If there is a vector == or IS term - e.g. "(a, b) == (?, ?)" - create ** new terms for each component comparison - "a = ?" and "b = ?". The ** new terms completely replace the original vector comparison, which is @@ -145900,12 +147920,12 @@ static void exprAnalyze( ** ** This is only required if at least one side of the comparison operation ** is not a sub-select. */ - if( pWC->op==TK_AND - && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 - && sqlite3ExprVectorSize(pExpr->pRight)==nLeft - && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 - || (pExpr->pRight->flags & EP_xIsSelect)==0) + if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) + && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 + && sqlite3ExprVectorSize(pExpr->pRight)==nLeft + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + || (pExpr->pRight->flags & EP_xIsSelect)==0) + && pWC->op==TK_AND ){ int i; for(i=0; iop==TK_AND && pExpr->op==TK_IN && pTerm->u.x.iField==0 + else if( pExpr->op==TK_IN + && pTerm->u.x.iField==0 && pExpr->pLeft->op==TK_VECTOR && pExpr->x.pSelect->pPrior==0 #ifndef SQLITE_OMIT_WINDOWFUNC && pExpr->x.pSelect->pWin==0 #endif + && pWC->op==TK_AND ){ int i; for(i=0; ipLeft); i++){ @@ -145950,44 +147972,51 @@ static void exprAnalyze( } } -#ifdef SQLITE_ENABLE_STAT4 - /* When sqlite_stat4 histogram data is available an operator of the - ** form "x IS NOT NULL" can sometimes be evaluated more efficiently - ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a - ** virtual term of that form. - ** - ** Note that the virtual term must be tagged with TERM_VNULL. +#ifndef SQLITE_OMIT_VIRTUALTABLE + /* Add a WO_AUX auxiliary term to the constraint set if the + ** current expression is of the form "column OP expr" where OP + ** is an operator that gets passed into virtual tables but which is + ** not normally optimized for ordinary tables. In other words, OP + ** is one of MATCH, LIKE, GLOB, REGEXP, !=, IS, IS NOT, or NOT NULL. + ** This information is used by the xBestIndex methods of + ** virtual tables. The native query optimizer does not attempt + ** to do anything with MATCH functions. */ - if( pExpr->op==TK_NOTNULL - && pExpr->pLeft->op==TK_COLUMN - && pExpr->pLeft->iColumn>=0 - && !ExprHasProperty(pExpr, EP_FromJoin) - && OptimizationEnabled(db, SQLITE_Stat4) - ){ - Expr *pNewExpr; - Expr *pLeft = pExpr->pLeft; - int idxNew; - WhereTerm *pNewTerm; - - pNewExpr = sqlite3PExpr(pParse, TK_GT, - sqlite3ExprDup(db, pLeft, 0), - sqlite3ExprAlloc(db, TK_NULL, 0, 0)); - - idxNew = whereClauseInsert(pWC, pNewExpr, - TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); - if( idxNew ){ - pNewTerm = &pWC->a[idxNew]; - pNewTerm->prereqRight = 0; - pNewTerm->leftCursor = pLeft->iTable; - pNewTerm->u.x.leftColumn = pLeft->iColumn; - pNewTerm->eOperator = WO_GT; - markTermAsChild(pWC, idxNew, idxTerm); - pTerm = &pWC->a[idxTerm]; - pTerm->wtFlags |= TERM_COPIED; - pNewTerm->prereqAll = pTerm->prereqAll; + else if( pWC->op==TK_AND ){ + Expr *pRight = 0, *pLeft = 0; + int res = isAuxiliaryVtabOperator(db, pExpr, &eOp2, &pLeft, &pRight); + while( res-- > 0 ){ + int idxNew; + WhereTerm *pNewTerm; + Bitmask prereqColumn, prereqExpr; + + prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); + prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); + if( (prereqExpr & prereqColumn)==0 ){ + Expr *pNewExpr; + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0)); + if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ + ExprSetProperty(pNewExpr, EP_FromJoin); + pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; + } + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); + testcase( idxNew==0 ); + pNewTerm = &pWC->a[idxNew]; + pNewTerm->prereqRight = prereqExpr; + pNewTerm->leftCursor = pLeft->iTable; + pNewTerm->u.x.leftColumn = pLeft->iColumn; + pNewTerm->eOperator = WO_AUX; + pNewTerm->eMatchOp = eOp2; + markTermAsChild(pWC, idxNew, idxTerm); + pTerm = &pWC->a[idxTerm]; + pTerm->wtFlags |= TERM_COPIED; + pNewTerm->prereqAll = pTerm->prereqAll; + } + SWAP(Expr*, pLeft, pRight); } } -#endif /* SQLITE_ENABLE_STAT4 */ +#endif /* SQLITE_OMIT_VIRTUALTABLE */ /* Prevent ON clause terms of a LEFT JOIN from being used to drive ** an index for tables to the left of the join. @@ -146147,7 +148176,7 @@ SQLITE_PRIVATE void sqlite3WhereExprAnalyze( */ SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( Parse *pParse, /* Parsing context */ - struct SrcList_item *pItem, /* The FROM clause term to process */ + SrcItem *pItem, /* The FROM clause term to process */ WhereClause *pWC /* Xfer function arguments to here */ ){ Table *pTab; @@ -146224,12 +148253,6 @@ struct HiddenIndexInfo { /* Forward declaration of methods */ static int whereLoopResize(sqlite3*, WhereLoop*, int); -/* Test variable that can be set to enable WHERE tracing */ -#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ int sqlite3WhereTrace = 0; -#endif - - /* ** Return the estimated number of output rows from a WHERE clause */ @@ -146292,6 +148315,32 @@ SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ return pInner->addrNxt; } +/* +** While generating code for the min/max optimization, after handling +** the aggregate-step call to min() or max(), check to see if any +** additional looping is required. If the output order is such that +** we are certain that the correct answer has already been found, then +** code an OP_Goto to by pass subsequent processing. +** +** Any extra OP_Goto that is coded here is an optimization. The +** correct answer should be obtained regardless. This OP_Goto just +** makes the answer appear faster. +*/ +SQLITE_PRIVATE void sqlite3WhereMinMaxOptEarlyOut(Vdbe *v, WhereInfo *pWInfo){ + WhereLevel *pInner; + int i; + if( !pWInfo->bOrderedInnerLoop ) return; + if( pWInfo->nOBSat==0 ) return; + for(i=pWInfo->nLevel-1; i>=0; i--){ + pInner = &pWInfo->a[i]; + if( (pInner->pWLoop->wsFlags & WHERE_COLUMN_IN)!=0 ){ + sqlite3VdbeGoto(v, pInner->addrNxt); + return; + } + } + sqlite3VdbeGoto(v, pWInfo->iBreak); +} + /* ** Return the VDBE address or label to jump to in order to continue ** immediately with the next row of a WHERE clause. @@ -146861,7 +148910,7 @@ static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ */ static int termCanDriveIndex( WhereTerm *pTerm, /* WHERE clause term to check */ - struct SrcList_item *pSrc, /* Table we are trying to access */ + SrcItem *pSrc, /* Table we are trying to access */ Bitmask notReady /* Tables in outer loops of the join */ ){ char aff; @@ -146895,7 +148944,7 @@ static int termCanDriveIndex( static void constructAutomaticIndex( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause */ - struct SrcList_item *pSrc, /* The FROM clause term to get the next index */ + SrcItem *pSrc, /* The FROM clause term to get the next index */ Bitmask notReady, /* Mask of cursors that are not available */ WhereLevel *pLevel /* Write new index here */ ){ @@ -146919,7 +148968,7 @@ static void constructAutomaticIndex( u8 sentWarning = 0; /* True if a warnning has been issued */ Expr *pPartial = 0; /* Partial Index Expression */ int iContinue = 0; /* Jump here to skip excluded rows */ - struct SrcList_item *pTabItem; /* FROM clause term being indexed */ + SrcItem *pTabItem; /* FROM clause term being indexed */ int addrCounter = 0; /* Address where integer counter is initialized */ int regBase; /* Array of registers where record is assembled */ @@ -147103,7 +149152,7 @@ static sqlite3_index_info *allocateIndexInfo( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause being analyzed */ Bitmask mUnusable, /* Ignore terms with these prereqs */ - struct SrcList_item *pSrc, /* The FROM clause term that is the vtab */ + SrcItem *pSrc, /* The FROM clause term that is the vtab */ ExprList *pOrderBy, /* The ORDER BY clause */ u16 *pmNoOmit /* Mask of terms not to omit */ ){ @@ -148001,7 +150050,7 @@ SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; - struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; + SrcItem *pItem = pWInfo->pTabList->a + p->iTab; Table *pTab = pItem->pTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, @@ -148612,7 +150661,7 @@ static int whereRangeVectorLen( */ static int whereLoopAddBtreeIndex( WhereLoopBuilder *pBuilder, /* The WhereLoop factory */ - struct SrcList_item *pSrc, /* FROM clause term being analyzed */ + SrcItem *pSrc, /* FROM clause term being analyzed */ Index *pProbe, /* An index on pSrc */ LogEst nInMul /* log(Number of iterations due to IN) */ ){ @@ -148798,7 +150847,7 @@ static int whereLoopAddBtreeIndex( pBtm = pTerm; pTop = 0; if( pTerm->wtFlags & TERM_LIKEOPT ){ - /* Range contraints that come from the LIKE optimization are + /* Range constraints that come from the LIKE optimization are ** always used in pairs. */ pTop = &pTerm[1]; assert( (pTop-(pTerm->pWC->a))pWC->nTerm ); @@ -149103,7 +151152,7 @@ static int whereLoopAddBtree( LogEst aiRowEstPk[2]; /* The aiRowLogEst[] value for the sPk index */ i16 aiColumnPk = -1; /* The aColumn[] value for the sPk index */ SrcList *pTabList; /* The FROM clause */ - struct SrcList_item *pSrc; /* The FROM clause btree term to add */ + SrcItem *pSrc; /* The FROM clause btree term to add */ WhereLoop *pNew; /* Template WhereLoop object */ int rc = SQLITE_OK; /* Return code */ int iSortIdx = 1; /* Index number */ @@ -149121,9 +151170,9 @@ static int whereLoopAddBtree( pWC = pBuilder->pWC; assert( !IsVirtual(pSrc->pTab) ); - if( pSrc->pIBIndex ){ + if( pSrc->fg.isIndexedBy ){ /* An INDEXED BY clause specifies a particular index to use */ - pProbe = pSrc->pIBIndex; + pProbe = pSrc->u2.pIBIndex; }else if( !HasRowid(pTab) ){ pProbe = pTab->pIndex; }else{ @@ -149159,7 +151208,7 @@ static int whereLoopAddBtree( if( !pBuilder->pOrSet /* Not part of an OR optimization */ && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0 - && pSrc->pIBIndex==0 /* Has no INDEXED BY clause */ + && !pSrc->fg.isIndexedBy /* Has no INDEXED BY clause */ && !pSrc->fg.notIndexed /* Has no NOT INDEXED clause */ && HasRowid(pTab) /* Not WITHOUT ROWID table. (FIXME: Why not?) */ && !pSrc->fg.isCorrelated /* Not a correlated subquery */ @@ -149209,7 +151258,7 @@ static int whereLoopAddBtree( /* Loop over all indices. If there was an INDEXED BY clause, then only ** consider index pProbe. */ for(; rc==SQLITE_OK && pProbe; - pProbe=(pSrc->pIBIndex ? 0 : pProbe->pNext), iSortIdx++ + pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ ){ int isLeft = (pSrc->fg.jointype & JT_OUTER)!=0; if( pProbe->pPartIdxWhere!=0 @@ -149384,7 +151433,7 @@ static int whereLoopAddVirtualOne( int rc = SQLITE_OK; WhereLoop *pNew = pBuilder->pNew; Parse *pParse = pBuilder->pWInfo->pParse; - struct SrcList_item *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; + SrcItem *pSrc = &pBuilder->pWInfo->pTabList->a[pNew->iTab]; int nConstraint = pIdxInfo->nConstraint; assert( (mUsable & mPrereq)==mPrereq ); @@ -149576,7 +151625,7 @@ static int whereLoopAddVirtual( WhereInfo *pWInfo; /* WHERE analysis context */ Parse *pParse; /* The parsing context */ WhereClause *pWC; /* The WHERE clause */ - struct SrcList_item *pSrc; /* The FROM clause term to search */ + SrcItem *pSrc; /* The FROM clause term to search */ sqlite3_index_info *p; /* Object to pass to xBestIndex() */ int nConstraint; /* Number of constraints in p */ int bIn; /* True if plan uses IN(...) operator */ @@ -149704,7 +151753,7 @@ static int whereLoopAddOr( WhereClause tempWC; WhereLoopBuilder sSubBuild; WhereOrSet sSum, sCur; - struct SrcList_item *pItem; + SrcItem *pItem; pWC = pBuilder->pWC; pWCEnd = pWC->a + pWC->nTerm; @@ -149820,8 +151869,8 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ Bitmask mPrior = 0; int iTab; SrcList *pTabList = pWInfo->pTabList; - struct SrcList_item *pItem; - struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel]; + SrcItem *pItem; + SrcItem *pEnd = &pTabList->a[pWInfo->nLevel]; sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; WhereLoop *pNew; @@ -149844,7 +151893,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ } #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pItem->pTab) ){ - struct SrcList_item *p; + SrcItem *p; for(p=&pItem[1]; pfg.jointype & (JT_LEFT|JT_CROSS)) ){ mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); @@ -150699,7 +152748,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ */ static int whereShortCut(WhereLoopBuilder *pBuilder){ WhereInfo *pWInfo; - struct SrcList_item *pItem; + SrcItem *pItem; WhereClause *pWC; WhereTerm *pTerm; WhereLoop *pLoop; @@ -151158,7 +153207,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ pWInfo->revMask = ALLBITS; } - if( pParse->nErr || NEVER(db->mallocFailed) ){ + if( pParse->nErr || db->mallocFailed ){ goto whereBeginError; } #ifdef WHERETRACE_ENABLED @@ -151229,7 +153278,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( } for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; - struct SrcList_item *pItem; + SrcItem *pItem; pLoop = pWInfo->a[i].pWLoop; pItem = &pWInfo->pTabList->a[pLoop->iTab]; if( (pItem->fg.jointype & JT_LEFT)==0 ) continue; @@ -151319,7 +153368,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( for(ii=0, pLevel=pWInfo->a; iia[pLevel->iFrom]; pTab = pTabItem->pTab; @@ -151656,7 +153705,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ int k, last; VdbeOp *pOp, *pLastOp; Index *pIdx = 0; - struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom]; + SrcItem *pTabItem = &pTabList->a[pLevel->iFrom]; Table *pTab = pTabItem->pTab; assert( pTab!=0 ); pLoop = pLevel->pWLoop; @@ -151732,7 +153781,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ #endif pOp = sqlite3VdbeGetOp(v, k); pLastOp = pOp + (last - k); - assert( pOpnErr>0 && pOp==pLastOp) ); do{ if( pOp->p1!=pLevel->iTabCur ){ /* no-op */ @@ -153100,15 +155149,19 @@ SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ** SELECT, or (b) the windows already linked use a compatible window frame. */ SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin){ - if( pSel!=0 - && (0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0)) - ){ - pWin->pNextWin = pSel->pWin; - if( pSel->pWin ){ - pSel->pWin->ppThis = &pWin->pNextWin; + if( pSel ){ + if( 0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + }else{ + if( sqlite3ExprListCompare(pWin->pPartition, pSel->pWin->pPartition,-1) ){ + pSel->selFlags |= SF_MultiPart; + } } - pSel->pWin = pWin; - pWin->ppThis = &pSel->pWin; } } @@ -153857,6 +155910,7 @@ static void windowCodeRangeTest( int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ + CollSeq *pColl; assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); @@ -153947,6 +156001,8 @@ static void windowCodeRangeTest( ** control skips over this test if the BIGNULL flag is set and either ** reg1 or reg2 contain a NULL value. */ sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + pColl = sqlite3ExprNNCollSeq(pParse, pOrderBy->a[0].pExpr); + sqlite3VdbeAppendP4(v, (void*)pColl, P4_COLLSEQ); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); @@ -154953,11 +157009,21 @@ static void updateDeleteLimitError( static void parserDoubleLinkSelect(Parse *pParse, Select *p){ assert( p!=0 ); if( p->pPrior ){ - Select *pNext = 0, *pLoop; - int mxSelect, cnt = 0; - for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){ + Select *pNext = 0, *pLoop = p; + int mxSelect, cnt = 1; + while(1){ pLoop->pNext = pNext; pLoop->selFlags |= SF_Compound; + pNext = pLoop; + pLoop = pLoop->pPrior; + if( pLoop==0 ) break; + cnt++; + if( pLoop->pOrderBy || pLoop->pLimit ){ + sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", + pLoop->pOrderBy!=0 ? "ORDER BY" : "LIMIT", + sqlite3SelectOpName(pNext->op)); + break; + } } if( (p->selFlags & SF_MultiValue)==0 && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && @@ -154968,6 +157034,19 @@ static void updateDeleteLimitError( } } + /* Attach a With object describing the WITH clause to a Select + ** object describing the query for which the WITH clause is a prefix. + */ + static Select *attachWithToSelect(Parse *pParse, Select *pSelect, With *pWith){ + if( pSelect ){ + pSelect->pWith = pWith; + parserDoubleLinkSelect(pParse, pSelect); + }else{ + sqlite3WithDelete(pParse->db, pWith); + } + return pSelect; + } + /* Construct a new Expr object from a single identifier. Use the ** new Expr to populate pOut. Set the span of pOut to be the identifier @@ -155143,90 +157222,92 @@ static void updateDeleteLimitError( #define TK_TIES 94 #define TK_GENERATED 95 #define TK_ALWAYS 96 -#define TK_REINDEX 97 -#define TK_RENAME 98 -#define TK_CTIME_KW 99 -#define TK_ANY 100 -#define TK_BITAND 101 -#define TK_BITOR 102 -#define TK_LSHIFT 103 -#define TK_RSHIFT 104 -#define TK_PLUS 105 -#define TK_MINUS 106 -#define TK_STAR 107 -#define TK_SLASH 108 -#define TK_REM 109 -#define TK_CONCAT 110 -#define TK_COLLATE 111 -#define TK_BITNOT 112 -#define TK_ON 113 -#define TK_INDEXED 114 -#define TK_STRING 115 -#define TK_JOIN_KW 116 -#define TK_CONSTRAINT 117 -#define TK_DEFAULT 118 -#define TK_NULL 119 -#define TK_PRIMARY 120 -#define TK_UNIQUE 121 -#define TK_CHECK 122 -#define TK_REFERENCES 123 -#define TK_AUTOINCR 124 -#define TK_INSERT 125 -#define TK_DELETE 126 -#define TK_UPDATE 127 -#define TK_SET 128 -#define TK_DEFERRABLE 129 -#define TK_FOREIGN 130 -#define TK_DROP 131 -#define TK_UNION 132 -#define TK_ALL 133 -#define TK_EXCEPT 134 -#define TK_INTERSECT 135 -#define TK_SELECT 136 -#define TK_VALUES 137 -#define TK_DISTINCT 138 -#define TK_DOT 139 -#define TK_FROM 140 -#define TK_JOIN 141 -#define TK_USING 142 -#define TK_ORDER 143 -#define TK_GROUP 144 -#define TK_HAVING 145 -#define TK_LIMIT 146 -#define TK_WHERE 147 -#define TK_INTO 148 -#define TK_NOTHING 149 -#define TK_FLOAT 150 -#define TK_BLOB 151 -#define TK_INTEGER 152 -#define TK_VARIABLE 153 -#define TK_CASE 154 -#define TK_WHEN 155 -#define TK_THEN 156 -#define TK_ELSE 157 -#define TK_INDEX 158 -#define TK_ALTER 159 -#define TK_ADD 160 -#define TK_WINDOW 161 -#define TK_OVER 162 -#define TK_FILTER 163 -#define TK_COLUMN 164 -#define TK_AGG_FUNCTION 165 -#define TK_AGG_COLUMN 166 -#define TK_TRUEFALSE 167 -#define TK_ISNOT 168 -#define TK_FUNCTION 169 -#define TK_UMINUS 170 -#define TK_UPLUS 171 -#define TK_TRUTH 172 -#define TK_REGISTER 173 -#define TK_VECTOR 174 -#define TK_SELECT_COLUMN 175 -#define TK_IF_NULL_ROW 176 -#define TK_ASTERISK 177 -#define TK_SPAN 178 -#define TK_SPACE 179 -#define TK_ILLEGAL 180 +#define TK_MATERIALIZED 97 +#define TK_REINDEX 98 +#define TK_RENAME 99 +#define TK_CTIME_KW 100 +#define TK_ANY 101 +#define TK_BITAND 102 +#define TK_BITOR 103 +#define TK_LSHIFT 104 +#define TK_RSHIFT 105 +#define TK_PLUS 106 +#define TK_MINUS 107 +#define TK_STAR 108 +#define TK_SLASH 109 +#define TK_REM 110 +#define TK_CONCAT 111 +#define TK_COLLATE 112 +#define TK_BITNOT 113 +#define TK_ON 114 +#define TK_INDEXED 115 +#define TK_STRING 116 +#define TK_JOIN_KW 117 +#define TK_CONSTRAINT 118 +#define TK_DEFAULT 119 +#define TK_NULL 120 +#define TK_PRIMARY 121 +#define TK_UNIQUE 122 +#define TK_CHECK 123 +#define TK_REFERENCES 124 +#define TK_AUTOINCR 125 +#define TK_INSERT 126 +#define TK_DELETE 127 +#define TK_UPDATE 128 +#define TK_SET 129 +#define TK_DEFERRABLE 130 +#define TK_FOREIGN 131 +#define TK_DROP 132 +#define TK_UNION 133 +#define TK_ALL 134 +#define TK_EXCEPT 135 +#define TK_INTERSECT 136 +#define TK_SELECT 137 +#define TK_VALUES 138 +#define TK_DISTINCT 139 +#define TK_DOT 140 +#define TK_FROM 141 +#define TK_JOIN 142 +#define TK_USING 143 +#define TK_ORDER 144 +#define TK_GROUP 145 +#define TK_HAVING 146 +#define TK_LIMIT 147 +#define TK_WHERE 148 +#define TK_RETURNING 149 +#define TK_INTO 150 +#define TK_NOTHING 151 +#define TK_FLOAT 152 +#define TK_BLOB 153 +#define TK_INTEGER 154 +#define TK_VARIABLE 155 +#define TK_CASE 156 +#define TK_WHEN 157 +#define TK_THEN 158 +#define TK_ELSE 159 +#define TK_INDEX 160 +#define TK_ALTER 161 +#define TK_ADD 162 +#define TK_WINDOW 163 +#define TK_OVER 164 +#define TK_FILTER 165 +#define TK_COLUMN 166 +#define TK_AGG_FUNCTION 167 +#define TK_AGG_COLUMN 168 +#define TK_TRUEFALSE 169 +#define TK_ISNOT 170 +#define TK_FUNCTION 171 +#define TK_UMINUS 172 +#define TK_UPLUS 173 +#define TK_TRUTH 174 +#define TK_REGISTER 175 +#define TK_VECTOR 176 +#define TK_SELECT_COLUMN 177 +#define TK_IF_NULL_ROW 178 +#define TK_ASTERISK 179 +#define TK_SPAN 180 +#define TK_SPACE 181 +#define TK_ILLEGAL 182 #endif /**************** End token definitions ***************************************/ @@ -155286,28 +157367,29 @@ static void updateDeleteLimitError( #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 310 +#define YYNOCODE 316 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 100 +#define YYWILDCARD 101 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - SrcList* yy47; - u8 yy58; - struct FrameBound yy77; - With* yy131; - int yy192; - Expr* yy202; - struct {int value; int mask;} yy207; - struct TrigEvent yy230; - ExprList* yy242; - Window* yy303; - Upsert* yy318; - const char* yy436; - TriggerStep* yy447; - Select* yy539; - IdList* yy600; + Window* yy19; + struct TrigEvent yy50; + int yy60; + struct FrameBound yy113; + Upsert* yy178; + With* yy195; + IdList* yy288; + SrcList* yy291; + Select* yy307; + ExprList* yy338; + TriggerStep* yy483; + const char* yy528; + u8 yy570; + Expr* yy602; + Cte* yy607; + struct {int value; int mask;} yy615; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -155323,18 +157405,18 @@ typedef union { #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 -#define YYNSTATE 553 -#define YYNRULE 385 -#define YYNRULE_WITH_ACTION 325 -#define YYNTOKEN 181 -#define YY_MAX_SHIFT 552 -#define YY_MIN_SHIFTREDUCE 803 -#define YY_MAX_SHIFTREDUCE 1187 -#define YY_ERROR_ACTION 1188 -#define YY_ACCEPT_ACTION 1189 -#define YY_NO_ACTION 1190 -#define YY_MIN_REDUCE 1191 -#define YY_MAX_REDUCE 1575 +#define YYNSTATE 570 +#define YYNRULE 398 +#define YYNRULE_WITH_ACTION 337 +#define YYNTOKEN 183 +#define YY_MAX_SHIFT 569 +#define YY_MIN_SHIFTREDUCE 825 +#define YY_MAX_SHIFTREDUCE 1222 +#define YY_ERROR_ACTION 1223 +#define YY_ACCEPT_ACTION 1224 +#define YY_NO_ACTION 1225 +#define YY_MIN_REDUCE 1226 +#define YY_MAX_REDUCE 1623 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -155401,586 +157483,600 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (1962) +#define YY_ACTTAB_COUNT (2020) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 546, 1222, 546, 451, 1260, 546, 1239, 546, 114, 111, - /* 10 */ 211, 546, 1537, 546, 1260, 523, 114, 111, 211, 392, - /* 20 */ 1232, 344, 42, 42, 42, 42, 1225, 42, 42, 71, - /* 30 */ 71, 937, 1224, 71, 71, 71, 71, 1462, 1493, 938, - /* 40 */ 820, 453, 6, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 50 */ 999, 999, 119, 119, 120, 120, 120, 120, 1543, 392, - /* 60 */ 1358, 1517, 552, 2, 1193, 194, 528, 436, 143, 291, - /* 70 */ 528, 136, 528, 371, 261, 504, 272, 385, 1273, 527, - /* 80 */ 503, 493, 164, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 90 */ 999, 999, 119, 119, 120, 120, 120, 120, 1358, 442, - /* 100 */ 1514, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 110 */ 115, 424, 266, 266, 266, 266, 1498, 358, 1500, 435, - /* 120 */ 357, 1498, 517, 524, 1485, 543, 1114, 543, 1114, 392, - /* 130 */ 405, 241, 208, 114, 111, 211, 98, 290, 537, 221, - /* 140 */ 1029, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 150 */ 115, 424, 1142, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 160 */ 999, 999, 119, 119, 120, 120, 120, 120, 406, 428, - /* 170 */ 117, 117, 116, 116, 116, 115, 424, 1418, 468, 123, - /* 180 */ 118, 118, 118, 118, 117, 117, 116, 116, 116, 115, - /* 190 */ 424, 116, 116, 116, 115, 424, 540, 540, 540, 392, - /* 200 */ 505, 120, 120, 120, 120, 113, 1051, 1142, 1143, 1144, - /* 210 */ 1051, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 220 */ 115, 424, 1461, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 230 */ 999, 999, 119, 119, 120, 120, 120, 120, 392, 444, - /* 240 */ 316, 83, 463, 81, 359, 382, 1142, 80, 118, 118, - /* 250 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 179, - /* 260 */ 434, 424, 121, 122, 112, 1165, 1165, 1006, 1009, 999, - /* 270 */ 999, 119, 119, 120, 120, 120, 120, 434, 433, 266, - /* 280 */ 266, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 290 */ 115, 424, 543, 1109, 903, 506, 1142, 114, 111, 211, - /* 300 */ 1431, 1142, 1143, 1144, 206, 491, 1109, 392, 449, 1109, - /* 310 */ 545, 330, 120, 120, 120, 120, 298, 1431, 1433, 17, - /* 320 */ 118, 118, 118, 118, 117, 117, 116, 116, 116, 115, - /* 330 */ 424, 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, - /* 340 */ 119, 119, 120, 120, 120, 120, 392, 1358, 434, 1142, - /* 350 */ 482, 1142, 1143, 1144, 996, 996, 1007, 1010, 445, 118, - /* 360 */ 118, 118, 118, 117, 117, 116, 116, 116, 115, 424, - /* 370 */ 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 380 */ 119, 120, 120, 120, 120, 1054, 1054, 465, 1431, 118, - /* 390 */ 118, 118, 118, 117, 117, 116, 116, 116, 115, 424, - /* 400 */ 1142, 451, 546, 1426, 1142, 1143, 1144, 233, 966, 1142, - /* 410 */ 481, 478, 477, 171, 360, 392, 164, 407, 414, 842, - /* 420 */ 476, 164, 185, 334, 71, 71, 1243, 1000, 118, 118, - /* 430 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 121, - /* 440 */ 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, 119, - /* 450 */ 120, 120, 120, 120, 392, 1142, 1143, 1144, 835, 12, - /* 460 */ 314, 509, 163, 356, 1142, 1143, 1144, 114, 111, 211, - /* 470 */ 508, 290, 537, 546, 276, 180, 290, 537, 121, 122, - /* 480 */ 112, 1165, 1165, 1006, 1009, 999, 999, 119, 119, 120, - /* 490 */ 120, 120, 120, 345, 484, 71, 71, 118, 118, 118, - /* 500 */ 118, 117, 117, 116, 116, 116, 115, 424, 1142, 209, - /* 510 */ 411, 523, 1142, 1109, 1571, 378, 252, 269, 342, 487, - /* 520 */ 337, 486, 238, 392, 513, 364, 1109, 1127, 333, 1109, - /* 530 */ 191, 409, 286, 32, 457, 443, 118, 118, 118, 118, - /* 540 */ 117, 117, 116, 116, 116, 115, 424, 121, 122, 112, - /* 550 */ 1165, 1165, 1006, 1009, 999, 999, 119, 119, 120, 120, - /* 560 */ 120, 120, 392, 1142, 1143, 1144, 987, 1142, 1143, 1144, - /* 570 */ 1142, 233, 492, 1492, 481, 478, 477, 6, 163, 546, - /* 580 */ 512, 546, 115, 424, 476, 5, 121, 122, 112, 1165, - /* 590 */ 1165, 1006, 1009, 999, 999, 119, 119, 120, 120, 120, - /* 600 */ 120, 13, 13, 13, 13, 118, 118, 118, 118, 117, - /* 610 */ 117, 116, 116, 116, 115, 424, 403, 502, 408, 546, - /* 620 */ 1486, 544, 1142, 892, 892, 1142, 1143, 1144, 1473, 1142, - /* 630 */ 275, 392, 808, 809, 810, 971, 422, 422, 422, 16, - /* 640 */ 16, 55, 55, 1242, 118, 118, 118, 118, 117, 117, - /* 650 */ 116, 116, 116, 115, 424, 121, 122, 112, 1165, 1165, - /* 660 */ 1006, 1009, 999, 999, 119, 119, 120, 120, 120, 120, - /* 670 */ 392, 1189, 1, 1, 552, 2, 1193, 1142, 1143, 1144, - /* 680 */ 194, 291, 898, 136, 1142, 1143, 1144, 897, 521, 1492, - /* 690 */ 1273, 3, 380, 6, 121, 122, 112, 1165, 1165, 1006, - /* 700 */ 1009, 999, 999, 119, 119, 120, 120, 120, 120, 858, - /* 710 */ 546, 924, 546, 118, 118, 118, 118, 117, 117, 116, - /* 720 */ 116, 116, 115, 424, 266, 266, 1092, 1569, 1142, 551, - /* 730 */ 1569, 1193, 13, 13, 13, 13, 291, 543, 136, 392, - /* 740 */ 485, 421, 420, 966, 344, 1273, 468, 410, 859, 279, - /* 750 */ 140, 221, 118, 118, 118, 118, 117, 117, 116, 116, - /* 760 */ 116, 115, 424, 121, 122, 112, 1165, 1165, 1006, 1009, - /* 770 */ 999, 999, 119, 119, 120, 120, 120, 120, 546, 266, - /* 780 */ 266, 428, 392, 1142, 1143, 1144, 1172, 830, 1172, 468, - /* 790 */ 431, 145, 543, 1146, 401, 314, 439, 302, 838, 1490, - /* 800 */ 71, 71, 412, 6, 1090, 473, 221, 100, 112, 1165, - /* 810 */ 1165, 1006, 1009, 999, 999, 119, 119, 120, 120, 120, - /* 820 */ 120, 118, 118, 118, 118, 117, 117, 116, 116, 116, - /* 830 */ 115, 424, 237, 1425, 546, 451, 428, 287, 986, 546, - /* 840 */ 236, 235, 234, 830, 97, 529, 429, 1265, 1265, 1146, - /* 850 */ 494, 307, 430, 838, 977, 546, 71, 71, 976, 1241, - /* 860 */ 546, 51, 51, 300, 118, 118, 118, 118, 117, 117, - /* 870 */ 116, 116, 116, 115, 424, 194, 103, 70, 70, 266, - /* 880 */ 266, 546, 71, 71, 266, 266, 30, 391, 344, 976, - /* 890 */ 976, 978, 543, 528, 1109, 328, 392, 543, 495, 397, - /* 900 */ 1470, 195, 530, 13, 13, 1358, 240, 1109, 277, 280, - /* 910 */ 1109, 280, 304, 457, 306, 333, 392, 31, 188, 419, - /* 920 */ 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 930 */ 119, 120, 120, 120, 120, 142, 392, 365, 457, 986, - /* 940 */ 121, 122, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 950 */ 119, 120, 120, 120, 120, 977, 323, 1142, 326, 976, - /* 960 */ 121, 110, 112, 1165, 1165, 1006, 1009, 999, 999, 119, - /* 970 */ 119, 120, 120, 120, 120, 464, 377, 1185, 118, 118, - /* 980 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 1142, - /* 990 */ 976, 976, 978, 305, 9, 366, 244, 362, 118, 118, - /* 1000 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 313, - /* 1010 */ 546, 344, 1142, 1143, 1144, 299, 290, 537, 118, 118, - /* 1020 */ 118, 118, 117, 117, 116, 116, 116, 115, 424, 1263, - /* 1030 */ 1263, 1163, 13, 13, 278, 421, 420, 468, 392, 923, - /* 1040 */ 260, 260, 289, 1169, 1142, 1143, 1144, 189, 1171, 266, - /* 1050 */ 266, 468, 390, 543, 1186, 546, 1170, 263, 144, 489, - /* 1060 */ 922, 546, 543, 122, 112, 1165, 1165, 1006, 1009, 999, - /* 1070 */ 999, 119, 119, 120, 120, 120, 120, 71, 71, 1142, - /* 1080 */ 1172, 1272, 1172, 13, 13, 898, 1070, 1163, 546, 468, - /* 1090 */ 897, 107, 538, 1491, 4, 1268, 1109, 6, 525, 1049, - /* 1100 */ 12, 1071, 1092, 1570, 312, 455, 1570, 520, 541, 1109, - /* 1110 */ 56, 56, 1109, 1489, 423, 1358, 1072, 6, 345, 285, - /* 1120 */ 118, 118, 118, 118, 117, 117, 116, 116, 116, 115, - /* 1130 */ 424, 425, 1271, 321, 1142, 1143, 1144, 878, 266, 266, - /* 1140 */ 1277, 107, 538, 535, 4, 1488, 293, 879, 1211, 6, - /* 1150 */ 210, 543, 543, 164, 294, 496, 416, 204, 541, 267, - /* 1160 */ 267, 1214, 398, 511, 499, 204, 266, 266, 396, 531, - /* 1170 */ 8, 986, 543, 519, 546, 922, 458, 105, 105, 543, - /* 1180 */ 1090, 425, 266, 266, 106, 417, 425, 548, 547, 266, - /* 1190 */ 266, 976, 518, 535, 1373, 543, 15, 15, 266, 266, - /* 1200 */ 456, 1120, 543, 266, 266, 1070, 1372, 515, 290, 537, - /* 1210 */ 546, 543, 514, 97, 444, 316, 543, 546, 922, 125, - /* 1220 */ 1071, 986, 976, 976, 978, 979, 27, 105, 105, 401, - /* 1230 */ 343, 1511, 44, 44, 106, 1072, 425, 548, 547, 57, - /* 1240 */ 57, 976, 343, 1511, 107, 538, 546, 4, 462, 401, - /* 1250 */ 214, 1120, 459, 297, 377, 1091, 534, 1309, 546, 539, - /* 1260 */ 398, 541, 290, 537, 104, 244, 102, 526, 58, 58, - /* 1270 */ 546, 199, 976, 976, 978, 979, 27, 1516, 1131, 427, - /* 1280 */ 59, 59, 270, 237, 425, 138, 95, 375, 375, 374, - /* 1290 */ 255, 372, 60, 60, 817, 1180, 535, 546, 273, 546, - /* 1300 */ 1163, 1308, 389, 388, 546, 438, 546, 215, 210, 296, - /* 1310 */ 515, 849, 546, 265, 208, 516, 1476, 295, 274, 61, - /* 1320 */ 61, 62, 62, 308, 986, 109, 45, 45, 46, 46, - /* 1330 */ 105, 105, 1186, 922, 47, 47, 341, 106, 546, 425, - /* 1340 */ 548, 547, 1542, 546, 976, 867, 340, 217, 546, 937, - /* 1350 */ 397, 107, 538, 218, 4, 156, 1163, 938, 158, 546, - /* 1360 */ 49, 49, 1162, 546, 268, 50, 50, 546, 541, 1450, - /* 1370 */ 63, 63, 546, 1449, 216, 976, 976, 978, 979, 27, - /* 1380 */ 446, 64, 64, 546, 460, 65, 65, 546, 318, 14, - /* 1390 */ 14, 425, 1305, 546, 66, 66, 1087, 546, 141, 379, - /* 1400 */ 38, 546, 963, 535, 322, 127, 127, 546, 393, 67, - /* 1410 */ 67, 546, 325, 290, 537, 52, 52, 515, 546, 68, - /* 1420 */ 68, 845, 514, 69, 69, 399, 165, 857, 856, 53, - /* 1430 */ 53, 986, 311, 151, 151, 97, 432, 105, 105, 327, - /* 1440 */ 152, 152, 526, 1048, 106, 1048, 425, 548, 547, 1131, - /* 1450 */ 427, 976, 1032, 270, 968, 239, 329, 243, 375, 375, - /* 1460 */ 374, 255, 372, 940, 941, 817, 1296, 546, 220, 546, - /* 1470 */ 107, 538, 546, 4, 546, 1256, 199, 845, 215, 1036, - /* 1480 */ 296, 1530, 976, 976, 978, 979, 27, 541, 295, 76, - /* 1490 */ 76, 54, 54, 980, 72, 72, 128, 128, 864, 865, - /* 1500 */ 107, 538, 546, 4, 1047, 546, 1047, 533, 469, 546, - /* 1510 */ 425, 546, 450, 1240, 546, 243, 546, 541, 217, 546, - /* 1520 */ 452, 197, 535, 243, 73, 73, 156, 129, 129, 158, - /* 1530 */ 336, 130, 130, 126, 126, 1036, 150, 150, 149, 149, - /* 1540 */ 425, 134, 134, 317, 474, 216, 97, 239, 331, 980, - /* 1550 */ 986, 97, 535, 346, 347, 546, 105, 105, 902, 931, - /* 1560 */ 546, 895, 243, 106, 109, 425, 548, 547, 546, 1505, - /* 1570 */ 976, 828, 99, 538, 139, 4, 546, 133, 133, 393, - /* 1580 */ 986, 1317, 131, 131, 290, 537, 105, 105, 1357, 541, - /* 1590 */ 132, 132, 1292, 106, 1303, 425, 548, 547, 75, 75, - /* 1600 */ 976, 976, 976, 978, 979, 27, 546, 432, 896, 1289, - /* 1610 */ 532, 109, 425, 1363, 546, 1221, 1213, 1202, 258, 546, - /* 1620 */ 349, 546, 1201, 11, 535, 1203, 1524, 351, 77, 77, - /* 1630 */ 376, 976, 976, 978, 979, 27, 74, 74, 353, 213, - /* 1640 */ 301, 43, 43, 48, 48, 437, 310, 201, 303, 1350, - /* 1650 */ 315, 355, 986, 454, 479, 1239, 339, 192, 105, 105, - /* 1660 */ 1422, 1421, 193, 536, 205, 106, 1527, 425, 548, 547, - /* 1670 */ 1180, 167, 976, 270, 247, 1469, 1467, 1177, 375, 375, - /* 1680 */ 374, 255, 372, 200, 369, 817, 400, 83, 79, 82, - /* 1690 */ 1427, 448, 177, 95, 1342, 161, 169, 1339, 215, 440, - /* 1700 */ 296, 172, 173, 976, 976, 978, 979, 27, 295, 174, - /* 1710 */ 175, 441, 472, 223, 1347, 383, 35, 381, 36, 461, - /* 1720 */ 88, 1353, 181, 447, 384, 1416, 227, 467, 259, 229, - /* 1730 */ 186, 488, 470, 324, 1250, 230, 231, 320, 217, 1204, - /* 1740 */ 1438, 1259, 386, 1258, 413, 90, 156, 849, 1541, 158, - /* 1750 */ 206, 415, 1540, 507, 1300, 1257, 94, 348, 1229, 1301, - /* 1760 */ 387, 1510, 1228, 338, 1227, 216, 350, 1539, 498, 283, - /* 1770 */ 284, 1249, 501, 1299, 352, 245, 246, 418, 1298, 354, - /* 1780 */ 1496, 1495, 124, 10, 526, 363, 101, 1324, 253, 96, - /* 1790 */ 510, 1210, 34, 549, 1137, 254, 256, 257, 166, 393, - /* 1800 */ 550, 1199, 1282, 361, 290, 537, 1281, 196, 367, 368, - /* 1810 */ 1194, 153, 1454, 137, 281, 1323, 1455, 804, 154, 426, - /* 1820 */ 198, 155, 1453, 1452, 292, 212, 202, 432, 1402, 203, - /* 1830 */ 271, 135, 288, 78, 1046, 1044, 960, 168, 157, 881, - /* 1840 */ 170, 219, 309, 222, 1060, 176, 964, 159, 402, 84, - /* 1850 */ 178, 404, 85, 86, 87, 160, 1063, 224, 394, 395, - /* 1860 */ 225, 1059, 146, 18, 226, 319, 243, 1174, 466, 228, - /* 1870 */ 1052, 182, 183, 37, 819, 471, 340, 232, 332, 483, - /* 1880 */ 184, 89, 162, 19, 20, 475, 91, 480, 847, 335, - /* 1890 */ 147, 860, 282, 92, 490, 93, 1125, 148, 1012, 1095, - /* 1900 */ 39, 497, 1096, 40, 500, 262, 207, 264, 930, 187, - /* 1910 */ 925, 109, 1111, 1115, 1113, 7, 1099, 242, 33, 1119, - /* 1920 */ 21, 522, 22, 23, 24, 1118, 25, 190, 97, 26, - /* 1930 */ 1027, 1013, 1011, 1015, 1069, 1016, 1068, 249, 248, 28, - /* 1940 */ 41, 891, 981, 829, 108, 29, 250, 542, 251, 370, - /* 1950 */ 373, 1133, 1132, 1190, 1190, 1190, 1190, 1190, 1190, 1190, - /* 1960 */ 1532, 1531, + /* 0 */ 563, 1295, 563, 1274, 168, 361, 115, 112, 218, 373, + /* 10 */ 563, 1295, 374, 563, 488, 563, 115, 112, 218, 406, + /* 20 */ 1300, 1300, 41, 41, 41, 41, 514, 1504, 520, 1298, + /* 30 */ 1298, 959, 41, 41, 1257, 71, 71, 51, 51, 960, + /* 40 */ 557, 557, 557, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 50 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 414, 406, + /* 60 */ 273, 273, 273, 273, 115, 112, 218, 115, 112, 218, + /* 70 */ 197, 268, 545, 560, 515, 560, 1260, 563, 385, 248, + /* 80 */ 215, 521, 399, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 90 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 540, 13, + /* 100 */ 13, 1259, 119, 119, 119, 119, 118, 118, 117, 117, + /* 110 */ 117, 116, 441, 1176, 419, 1531, 446, 137, 512, 1539, + /* 120 */ 1545, 372, 1547, 6, 371, 1176, 1148, 1584, 1148, 406, + /* 130 */ 1545, 534, 115, 112, 218, 1267, 99, 441, 121, 121, + /* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117, + /* 150 */ 117, 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 160 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 197, 1176, + /* 170 */ 1177, 1178, 241, 304, 554, 501, 498, 497, 473, 124, + /* 180 */ 394, 1176, 1177, 1178, 1176, 496, 119, 119, 119, 119, + /* 190 */ 118, 118, 117, 117, 117, 116, 441, 139, 540, 406, + /* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 441, + /* 210 */ 541, 1532, 119, 119, 119, 119, 118, 118, 117, 117, + /* 220 */ 117, 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, + /* 230 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 406, 320, + /* 240 */ 1176, 1177, 1178, 81, 342, 1590, 396, 80, 119, 119, + /* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 1176, + /* 260 */ 211, 450, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 270 */ 1028, 120, 120, 121, 121, 121, 121, 251, 450, 449, + /* 280 */ 273, 273, 119, 119, 119, 119, 118, 118, 117, 117, + /* 290 */ 117, 116, 441, 560, 1224, 1, 1, 569, 2, 1228, + /* 300 */ 317, 1176, 319, 1561, 305, 337, 140, 340, 406, 430, + /* 310 */ 469, 1533, 1197, 1308, 348, 1176, 1177, 1178, 168, 462, + /* 320 */ 330, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 330 */ 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 340 */ 1028, 120, 120, 121, 121, 121, 121, 273, 273, 563, + /* 350 */ 83, 450, 416, 1564, 569, 2, 1228, 1176, 1177, 1178, + /* 360 */ 560, 305, 471, 140, 944, 995, 860, 563, 467, 1197, + /* 370 */ 1308, 13, 13, 137, 229, 118, 118, 117, 117, 117, + /* 380 */ 116, 441, 96, 318, 946, 504, 424, 361, 562, 71, + /* 390 */ 71, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 400 */ 116, 441, 427, 205, 273, 273, 445, 1015, 259, 276, + /* 410 */ 356, 507, 351, 506, 246, 406, 959, 560, 328, 344, + /* 420 */ 347, 315, 860, 1006, 960, 126, 545, 1005, 313, 304, + /* 430 */ 554, 229, 538, 1539, 148, 544, 281, 6, 203, 122, + /* 440 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, + /* 450 */ 121, 121, 121, 121, 563, 217, 563, 12, 406, 1005, + /* 460 */ 1005, 1007, 502, 445, 119, 119, 119, 119, 118, 118, + /* 470 */ 117, 117, 117, 116, 441, 452, 71, 71, 70, 70, + /* 480 */ 944, 137, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 490 */ 1028, 120, 120, 121, 121, 121, 121, 1530, 119, 119, + /* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 403, + /* 510 */ 402, 241, 1176, 545, 501, 498, 497, 1468, 1143, 451, + /* 520 */ 267, 267, 513, 1540, 496, 142, 1176, 6, 406, 530, + /* 530 */ 194, 1143, 864, 560, 1143, 461, 182, 304, 554, 32, + /* 540 */ 379, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 550 */ 116, 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, + /* 560 */ 1028, 120, 120, 121, 121, 121, 121, 406, 1176, 1177, + /* 570 */ 1178, 857, 568, 1176, 1228, 925, 1176, 454, 361, 305, + /* 580 */ 189, 140, 1176, 1177, 1178, 519, 529, 404, 1308, 183, + /* 590 */ 1015, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, + /* 600 */ 120, 120, 121, 121, 121, 121, 1006, 16, 16, 370, + /* 610 */ 1005, 119, 119, 119, 119, 118, 118, 117, 117, 117, + /* 620 */ 116, 441, 273, 273, 1537, 150, 1176, 98, 6, 1176, + /* 630 */ 1177, 1178, 1176, 1177, 1178, 560, 380, 406, 376, 438, + /* 640 */ 437, 1161, 1005, 1005, 1007, 1025, 1025, 1036, 1039, 229, + /* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, + /* 660 */ 441, 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, + /* 670 */ 120, 120, 121, 121, 121, 121, 406, 1143, 1619, 392, + /* 680 */ 1016, 445, 1176, 1177, 1178, 1207, 525, 1207, 1530, 995, + /* 690 */ 1143, 304, 554, 1143, 5, 563, 543, 3, 361, 216, + /* 700 */ 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, + /* 710 */ 120, 121, 121, 121, 121, 143, 563, 13, 13, 1029, + /* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, + /* 730 */ 441, 1176, 426, 563, 1176, 563, 274, 274, 13, 13, + /* 740 */ 1078, 1176, 328, 457, 316, 147, 406, 211, 361, 560, + /* 750 */ 1000, 213, 511, 293, 477, 55, 55, 71, 71, 119, + /* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 441, + /* 770 */ 122, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, + /* 780 */ 120, 121, 121, 121, 121, 406, 455, 1176, 1177, 1178, + /* 790 */ 1176, 1177, 1178, 471, 526, 149, 404, 1176, 1177, 1178, + /* 800 */ 105, 270, 103, 563, 944, 563, 116, 441, 1530, 122, + /* 810 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, + /* 820 */ 121, 121, 121, 121, 945, 13, 13, 13, 13, 119, + /* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 441, + /* 840 */ 191, 563, 192, 563, 416, 439, 439, 439, 1083, 1083, + /* 850 */ 485, 561, 285, 914, 914, 406, 462, 330, 1530, 830, + /* 860 */ 831, 832, 206, 71, 71, 71, 71, 286, 119, 119, + /* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 122, + /* 880 */ 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, + /* 890 */ 121, 121, 121, 121, 563, 217, 563, 1122, 1617, 406, + /* 900 */ 300, 1617, 301, 416, 1278, 1473, 244, 243, 242, 1249, + /* 910 */ 412, 556, 412, 282, 842, 279, 71, 71, 71, 71, + /* 920 */ 944, 1415, 1473, 1475, 101, 113, 1200, 1200, 1035, 1038, + /* 930 */ 1028, 1028, 120, 120, 121, 121, 121, 121, 119, 119, + /* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 441, 273, + /* 950 */ 273, 1099, 563, 436, 1143, 440, 563, 1122, 1618, 357, + /* 960 */ 1558, 1618, 560, 546, 488, 197, 1100, 1143, 378, 290, + /* 970 */ 1143, 1306, 284, 460, 71, 71, 1120, 405, 13, 13, + /* 980 */ 145, 1101, 119, 119, 119, 119, 118, 118, 117, 117, + /* 990 */ 117, 116, 441, 542, 104, 1473, 509, 273, 273, 294, + /* 1000 */ 1514, 294, 900, 273, 273, 273, 273, 563, 1503, 563, + /* 1010 */ 560, 545, 901, 464, 406, 1058, 560, 852, 560, 198, + /* 1020 */ 547, 1080, 920, 404, 1400, 1080, 146, 919, 38, 56, + /* 1030 */ 56, 15, 15, 563, 406, 12, 1120, 471, 122, 123, + /* 1040 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, + /* 1050 */ 121, 121, 121, 1460, 406, 43, 43, 483, 122, 123, + /* 1060 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, + /* 1070 */ 121, 121, 121, 563, 852, 9, 471, 251, 122, 111, + /* 1080 */ 113, 1200, 1200, 1035, 1038, 1028, 1028, 120, 120, 121, + /* 1090 */ 121, 121, 121, 563, 421, 57, 57, 119, 119, 119, + /* 1100 */ 119, 118, 118, 117, 117, 117, 116, 441, 1176, 493, + /* 1110 */ 563, 289, 1197, 478, 1516, 44, 44, 119, 119, 119, + /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 441, 880, 563, + /* 1130 */ 536, 563, 58, 58, 488, 1414, 245, 119, 119, 119, + /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 441, 563, 535, + /* 1150 */ 291, 59, 59, 60, 60, 438, 437, 406, 1154, 505, + /* 1160 */ 304, 554, 477, 1204, 1176, 1177, 1178, 881, 1206, 1197, + /* 1170 */ 61, 61, 1246, 357, 1558, 1538, 1205, 563, 1467, 6, + /* 1180 */ 1176, 488, 123, 113, 1200, 1200, 1035, 1038, 1028, 1028, + /* 1190 */ 120, 120, 121, 121, 121, 121, 1400, 1143, 410, 62, + /* 1200 */ 62, 1207, 1099, 1207, 411, 447, 273, 273, 537, 1154, + /* 1210 */ 1143, 108, 555, 1143, 4, 391, 1220, 1100, 1512, 560, + /* 1220 */ 347, 516, 428, 548, 308, 1307, 1536, 1077, 558, 1077, + /* 1230 */ 6, 488, 1101, 1400, 488, 309, 1176, 1177, 1178, 563, + /* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116, + /* 1250 */ 441, 442, 278, 551, 563, 273, 273, 273, 273, 563, + /* 1260 */ 327, 45, 45, 552, 563, 528, 422, 563, 560, 1400, + /* 1270 */ 560, 108, 555, 137, 4, 1303, 46, 46, 335, 563, + /* 1280 */ 482, 47, 47, 477, 479, 307, 49, 49, 558, 50, + /* 1290 */ 50, 563, 1015, 563, 1221, 563, 1400, 563, 106, 106, + /* 1300 */ 8, 63, 63, 423, 563, 107, 312, 442, 565, 564, + /* 1310 */ 563, 442, 1005, 64, 64, 65, 65, 14, 14, 66, + /* 1320 */ 66, 391, 1121, 552, 1312, 1180, 128, 128, 563, 304, + /* 1330 */ 554, 563, 67, 67, 563, 359, 560, 532, 563, 484, + /* 1340 */ 563, 1196, 531, 222, 1005, 1005, 1007, 1008, 27, 522, + /* 1350 */ 52, 52, 1015, 68, 68, 563, 69, 69, 106, 106, + /* 1360 */ 53, 53, 156, 156, 563, 107, 434, 442, 565, 564, + /* 1370 */ 272, 215, 1005, 425, 563, 359, 563, 157, 157, 563, + /* 1380 */ 1535, 292, 1180, 98, 6, 1344, 76, 76, 1215, 475, + /* 1390 */ 413, 169, 226, 563, 245, 563, 54, 54, 72, 72, + /* 1400 */ 1221, 129, 129, 1343, 1005, 1005, 1007, 1008, 27, 1563, + /* 1410 */ 1165, 444, 456, 433, 277, 73, 73, 130, 130, 389, + /* 1420 */ 389, 388, 262, 386, 1165, 444, 839, 1519, 277, 108, + /* 1430 */ 555, 321, 4, 389, 389, 388, 262, 386, 563, 223, + /* 1440 */ 839, 311, 468, 84, 202, 523, 558, 1492, 303, 310, + /* 1450 */ 563, 110, 404, 223, 563, 311, 206, 30, 404, 277, + /* 1460 */ 131, 131, 411, 310, 389, 389, 388, 262, 386, 442, + /* 1470 */ 920, 839, 127, 127, 563, 919, 155, 155, 1491, 225, + /* 1480 */ 563, 552, 871, 563, 223, 476, 311, 161, 31, 563, + /* 1490 */ 135, 563, 480, 225, 310, 532, 154, 154, 332, 17, + /* 1500 */ 533, 161, 136, 136, 135, 134, 134, 224, 228, 355, + /* 1510 */ 1015, 132, 132, 133, 133, 1589, 106, 106, 889, 354, + /* 1520 */ 563, 224, 563, 107, 225, 442, 565, 564, 1117, 275, + /* 1530 */ 1005, 393, 161, 518, 563, 135, 108, 555, 417, 4, + /* 1540 */ 1340, 407, 75, 75, 77, 77, 304, 554, 867, 563, + /* 1550 */ 336, 563, 224, 558, 463, 407, 74, 74, 465, 1065, + /* 1560 */ 304, 554, 1005, 1005, 1007, 1008, 27, 962, 963, 543, + /* 1570 */ 448, 42, 42, 48, 48, 326, 442, 325, 98, 997, + /* 1580 */ 470, 287, 250, 250, 448, 1009, 407, 472, 552, 339, + /* 1590 */ 250, 304, 554, 879, 878, 331, 108, 555, 98, 4, + /* 1600 */ 1277, 494, 532, 345, 247, 867, 98, 531, 341, 886, + /* 1610 */ 887, 1126, 1076, 558, 1076, 448, 1065, 1015, 1061, 953, + /* 1620 */ 343, 247, 250, 106, 106, 1291, 917, 1276, 850, 110, + /* 1630 */ 107, 144, 442, 565, 564, 918, 442, 1005, 110, 1275, + /* 1640 */ 350, 360, 1009, 1331, 1352, 299, 1399, 1577, 552, 1327, + /* 1650 */ 1552, 550, 1338, 549, 1405, 1256, 1248, 1237, 1236, 1238, + /* 1660 */ 1571, 489, 265, 200, 1324, 363, 365, 367, 11, 1005, + /* 1670 */ 1005, 1007, 1008, 27, 390, 221, 1386, 1015, 280, 1391, + /* 1680 */ 1381, 208, 323, 106, 106, 924, 1374, 453, 283, 324, + /* 1690 */ 107, 474, 442, 565, 564, 1390, 499, 1005, 212, 288, + /* 1700 */ 1274, 397, 353, 108, 555, 195, 4, 1464, 369, 1463, + /* 1710 */ 1574, 1215, 1212, 329, 553, 171, 207, 383, 1511, 196, + /* 1720 */ 558, 254, 1509, 415, 100, 555, 83, 4, 204, 1005, + /* 1730 */ 1005, 1007, 1008, 27, 219, 79, 82, 1469, 180, 166, + /* 1740 */ 173, 558, 458, 442, 175, 176, 177, 178, 35, 1387, + /* 1750 */ 492, 459, 231, 1395, 96, 552, 1393, 1392, 395, 184, + /* 1760 */ 481, 466, 36, 235, 442, 89, 398, 266, 487, 1480, + /* 1770 */ 1458, 237, 188, 338, 508, 429, 552, 490, 400, 238, + /* 1780 */ 334, 1239, 239, 1294, 1015, 1293, 1292, 1285, 91, 871, + /* 1790 */ 106, 106, 213, 431, 1588, 432, 524, 107, 517, 442, + /* 1800 */ 565, 564, 401, 1264, 1005, 1015, 1263, 1587, 352, 1262, + /* 1810 */ 1557, 106, 106, 1586, 1284, 297, 298, 358, 107, 1335, + /* 1820 */ 442, 565, 564, 95, 362, 1005, 253, 252, 435, 125, + /* 1830 */ 543, 10, 1444, 1543, 377, 1542, 1005, 1005, 1007, 1008, + /* 1840 */ 27, 302, 102, 97, 527, 1336, 260, 1317, 364, 1245, + /* 1850 */ 1334, 34, 566, 1171, 366, 381, 375, 1005, 1005, 1007, + /* 1860 */ 1008, 27, 1333, 1359, 368, 1316, 199, 382, 261, 263, + /* 1870 */ 264, 1358, 158, 1496, 141, 1497, 1495, 567, 1234, 1229, + /* 1880 */ 1494, 295, 159, 209, 210, 78, 826, 443, 201, 306, + /* 1890 */ 220, 1075, 138, 1073, 160, 314, 162, 172, 1196, 174, + /* 1900 */ 903, 227, 230, 322, 1089, 179, 163, 164, 418, 85, + /* 1910 */ 420, 181, 170, 408, 409, 86, 87, 165, 88, 1092, + /* 1920 */ 232, 233, 1088, 151, 18, 234, 1081, 250, 333, 185, + /* 1930 */ 1209, 486, 236, 186, 37, 841, 491, 354, 240, 346, + /* 1940 */ 503, 187, 90, 167, 19, 495, 20, 869, 500, 349, + /* 1950 */ 92, 882, 296, 152, 93, 510, 1127, 1159, 153, 1041, + /* 1960 */ 214, 1128, 39, 94, 269, 271, 952, 190, 947, 110, + /* 1970 */ 1149, 1145, 1153, 249, 1133, 1147, 7, 33, 21, 193, + /* 1980 */ 22, 23, 24, 25, 1152, 539, 98, 1056, 26, 1042, + /* 1990 */ 1040, 1044, 1098, 1045, 1097, 256, 255, 28, 40, 387, + /* 2000 */ 1010, 851, 109, 29, 1167, 559, 384, 257, 913, 258, + /* 2010 */ 1166, 1579, 1225, 1225, 1225, 1225, 1225, 1225, 1225, 1578, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 189, 211, 189, 189, 218, 189, 220, 189, 267, 268, - /* 10 */ 269, 189, 210, 189, 228, 189, 267, 268, 269, 19, - /* 20 */ 218, 189, 211, 212, 211, 212, 211, 211, 212, 211, - /* 30 */ 212, 31, 211, 211, 212, 211, 212, 288, 300, 39, - /* 40 */ 21, 189, 304, 43, 44, 45, 46, 47, 48, 49, - /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 225, 19, - /* 60 */ 189, 183, 184, 185, 186, 189, 248, 263, 236, 191, - /* 70 */ 248, 193, 248, 197, 208, 257, 262, 201, 200, 257, - /* 80 */ 200, 257, 81, 43, 44, 45, 46, 47, 48, 49, - /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 189, 80, - /* 100 */ 189, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 110 */ 110, 111, 234, 235, 234, 235, 305, 306, 305, 118, - /* 120 */ 307, 305, 306, 297, 298, 247, 86, 247, 88, 19, - /* 130 */ 259, 251, 252, 267, 268, 269, 26, 136, 137, 261, - /* 140 */ 121, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 150 */ 110, 111, 59, 43, 44, 45, 46, 47, 48, 49, - /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 259, 291, - /* 170 */ 105, 106, 107, 108, 109, 110, 111, 158, 189, 69, - /* 180 */ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 190 */ 111, 107, 108, 109, 110, 111, 205, 206, 207, 19, - /* 200 */ 19, 54, 55, 56, 57, 58, 29, 114, 115, 116, - /* 210 */ 33, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 220 */ 110, 111, 233, 43, 44, 45, 46, 47, 48, 49, - /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 126, - /* 240 */ 127, 148, 65, 24, 214, 200, 59, 67, 101, 102, - /* 250 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 22, - /* 260 */ 189, 111, 43, 44, 45, 46, 47, 48, 49, 50, - /* 270 */ 51, 52, 53, 54, 55, 56, 57, 206, 207, 234, - /* 280 */ 235, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 290 */ 110, 111, 247, 76, 107, 114, 59, 267, 268, 269, - /* 300 */ 189, 114, 115, 116, 162, 163, 89, 19, 263, 92, - /* 310 */ 189, 23, 54, 55, 56, 57, 189, 206, 207, 22, - /* 320 */ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 330 */ 111, 43, 44, 45, 46, 47, 48, 49, 50, 51, - /* 340 */ 52, 53, 54, 55, 56, 57, 19, 189, 277, 59, - /* 350 */ 23, 114, 115, 116, 46, 47, 48, 49, 61, 101, - /* 360 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 370 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 380 */ 53, 54, 55, 56, 57, 125, 126, 127, 277, 101, - /* 390 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - /* 400 */ 59, 189, 189, 276, 114, 115, 116, 117, 73, 59, - /* 410 */ 120, 121, 122, 72, 214, 19, 81, 259, 19, 23, - /* 420 */ 130, 81, 72, 24, 211, 212, 221, 119, 101, 102, - /* 430 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 43, + /* 0 */ 191, 220, 191, 222, 191, 191, 271, 272, 273, 216, + /* 10 */ 191, 230, 216, 191, 191, 191, 271, 272, 273, 19, + /* 20 */ 232, 233, 213, 214, 213, 214, 202, 292, 202, 232, + /* 30 */ 233, 31, 213, 214, 213, 213, 214, 213, 214, 39, + /* 40 */ 207, 208, 209, 43, 44, 45, 46, 47, 48, 49, + /* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 235, 19, + /* 60 */ 236, 237, 236, 237, 271, 272, 273, 271, 272, 273, + /* 70 */ 191, 210, 250, 249, 250, 249, 213, 191, 199, 253, + /* 80 */ 254, 259, 203, 43, 44, 45, 46, 47, 48, 49, + /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 191, 213, + /* 100 */ 214, 213, 102, 103, 104, 105, 106, 107, 108, 109, + /* 110 */ 110, 111, 112, 59, 228, 301, 293, 81, 305, 306, + /* 120 */ 311, 312, 311, 310, 313, 59, 86, 212, 88, 19, + /* 130 */ 311, 312, 271, 272, 273, 220, 26, 112, 54, 55, + /* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109, + /* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, + /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 191, 115, + /* 170 */ 116, 117, 118, 137, 138, 121, 122, 123, 191, 69, + /* 180 */ 203, 115, 116, 117, 59, 131, 102, 103, 104, 105, + /* 190 */ 106, 107, 108, 109, 110, 111, 112, 72, 191, 19, + /* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112, + /* 210 */ 303, 304, 102, 103, 104, 105, 106, 107, 108, 109, + /* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49, + /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 16, + /* 240 */ 115, 116, 117, 24, 16, 227, 202, 67, 102, 103, + /* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 59, + /* 260 */ 26, 191, 43, 44, 45, 46, 47, 48, 49, 50, + /* 270 */ 51, 52, 53, 54, 55, 56, 57, 24, 208, 209, + /* 280 */ 236, 237, 102, 103, 104, 105, 106, 107, 108, 109, + /* 290 */ 110, 111, 112, 249, 183, 184, 185, 186, 187, 188, + /* 300 */ 77, 59, 79, 191, 193, 77, 195, 79, 19, 19, + /* 310 */ 266, 304, 59, 202, 24, 115, 116, 117, 191, 127, + /* 320 */ 128, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, + /* 340 */ 51, 52, 53, 54, 55, 56, 57, 236, 237, 191, + /* 350 */ 150, 281, 191, 185, 186, 187, 188, 115, 116, 117, + /* 360 */ 249, 193, 191, 195, 26, 73, 59, 191, 114, 116, + /* 370 */ 202, 213, 214, 81, 263, 106, 107, 108, 109, 110, + /* 380 */ 111, 112, 148, 160, 142, 95, 228, 191, 191, 213, + /* 390 */ 214, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 400 */ 111, 112, 112, 149, 236, 237, 295, 100, 118, 119, + /* 410 */ 120, 121, 122, 123, 124, 19, 31, 249, 126, 23, + /* 420 */ 130, 260, 115, 116, 39, 22, 250, 120, 191, 137, + /* 430 */ 138, 263, 305, 306, 238, 259, 265, 310, 149, 43, /* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - /* 450 */ 54, 55, 56, 57, 19, 114, 115, 116, 23, 208, - /* 460 */ 125, 248, 189, 189, 114, 115, 116, 267, 268, 269, - /* 470 */ 189, 136, 137, 189, 262, 22, 136, 137, 43, 44, - /* 480 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - /* 490 */ 55, 56, 57, 189, 95, 211, 212, 101, 102, 103, - /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 59, 189, - /* 510 */ 111, 189, 59, 76, 294, 295, 117, 118, 119, 120, - /* 520 */ 121, 122, 123, 19, 87, 189, 89, 23, 129, 92, - /* 530 */ 279, 227, 248, 22, 189, 284, 101, 102, 103, 104, - /* 540 */ 105, 106, 107, 108, 109, 110, 111, 43, 44, 45, - /* 550 */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - /* 560 */ 56, 57, 19, 114, 115, 116, 23, 114, 115, 116, - /* 570 */ 59, 117, 299, 300, 120, 121, 122, 304, 189, 189, - /* 580 */ 143, 189, 110, 111, 130, 22, 43, 44, 45, 46, - /* 590 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 600 */ 57, 211, 212, 211, 212, 101, 102, 103, 104, 105, - /* 610 */ 106, 107, 108, 109, 110, 111, 226, 189, 226, 189, - /* 620 */ 298, 132, 59, 134, 135, 114, 115, 116, 189, 59, - /* 630 */ 285, 19, 7, 8, 9, 23, 205, 206, 207, 211, - /* 640 */ 212, 211, 212, 221, 101, 102, 103, 104, 105, 106, - /* 650 */ 107, 108, 109, 110, 111, 43, 44, 45, 46, 47, - /* 660 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - /* 670 */ 19, 181, 182, 183, 184, 185, 186, 114, 115, 116, - /* 680 */ 189, 191, 133, 193, 114, 115, 116, 138, 299, 300, - /* 690 */ 200, 22, 201, 304, 43, 44, 45, 46, 47, 48, - /* 700 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 35, - /* 710 */ 189, 141, 189, 101, 102, 103, 104, 105, 106, 107, - /* 720 */ 108, 109, 110, 111, 234, 235, 22, 23, 59, 184, - /* 730 */ 26, 186, 211, 212, 211, 212, 191, 247, 193, 19, - /* 740 */ 66, 105, 106, 73, 189, 200, 189, 226, 74, 226, - /* 750 */ 22, 261, 101, 102, 103, 104, 105, 106, 107, 108, - /* 760 */ 109, 110, 111, 43, 44, 45, 46, 47, 48, 49, - /* 770 */ 50, 51, 52, 53, 54, 55, 56, 57, 189, 234, - /* 780 */ 235, 291, 19, 114, 115, 116, 150, 59, 152, 189, - /* 790 */ 233, 236, 247, 59, 189, 125, 126, 127, 59, 300, - /* 800 */ 211, 212, 128, 304, 100, 19, 261, 156, 45, 46, - /* 810 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - /* 820 */ 57, 101, 102, 103, 104, 105, 106, 107, 108, 109, - /* 830 */ 110, 111, 46, 233, 189, 189, 291, 248, 99, 189, - /* 840 */ 125, 126, 127, 115, 26, 200, 289, 230, 231, 115, - /* 850 */ 200, 16, 189, 114, 115, 189, 211, 212, 119, 221, - /* 860 */ 189, 211, 212, 258, 101, 102, 103, 104, 105, 106, - /* 870 */ 107, 108, 109, 110, 111, 189, 156, 211, 212, 234, - /* 880 */ 235, 189, 211, 212, 234, 235, 22, 201, 189, 150, - /* 890 */ 151, 152, 247, 248, 76, 16, 19, 247, 248, 113, - /* 900 */ 189, 24, 257, 211, 212, 189, 26, 89, 262, 223, - /* 910 */ 92, 225, 77, 189, 79, 129, 19, 53, 226, 248, - /* 920 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 930 */ 53, 54, 55, 56, 57, 236, 19, 271, 189, 99, - /* 940 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 950 */ 53, 54, 55, 56, 57, 115, 77, 59, 79, 119, - /* 960 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - /* 970 */ 53, 54, 55, 56, 57, 259, 22, 23, 101, 102, - /* 980 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 59, - /* 990 */ 150, 151, 152, 158, 22, 244, 24, 246, 101, 102, - /* 1000 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 285, - /* 1010 */ 189, 189, 114, 115, 116, 200, 136, 137, 101, 102, - /* 1020 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 230, - /* 1030 */ 231, 59, 211, 212, 285, 105, 106, 189, 19, 141, - /* 1040 */ 234, 235, 239, 113, 114, 115, 116, 226, 118, 234, - /* 1050 */ 235, 189, 249, 247, 100, 189, 126, 23, 236, 107, - /* 1060 */ 26, 189, 247, 44, 45, 46, 47, 48, 49, 50, - /* 1070 */ 51, 52, 53, 54, 55, 56, 57, 211, 212, 59, - /* 1080 */ 150, 233, 152, 211, 212, 133, 12, 115, 189, 189, - /* 1090 */ 138, 19, 20, 300, 22, 233, 76, 304, 226, 11, - /* 1100 */ 208, 27, 22, 23, 200, 19, 26, 87, 36, 89, - /* 1110 */ 211, 212, 92, 300, 248, 189, 42, 304, 189, 250, - /* 1120 */ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - /* 1130 */ 111, 59, 200, 233, 114, 115, 116, 63, 234, 235, - /* 1140 */ 235, 19, 20, 71, 22, 300, 189, 73, 200, 304, - /* 1150 */ 116, 247, 247, 81, 189, 200, 227, 26, 36, 234, - /* 1160 */ 235, 203, 204, 143, 200, 26, 234, 235, 194, 200, - /* 1170 */ 48, 99, 247, 66, 189, 141, 284, 105, 106, 247, - /* 1180 */ 100, 59, 234, 235, 112, 259, 114, 115, 116, 234, - /* 1190 */ 235, 119, 85, 71, 266, 247, 211, 212, 234, 235, - /* 1200 */ 114, 94, 247, 234, 235, 12, 266, 85, 136, 137, - /* 1210 */ 189, 247, 90, 26, 126, 127, 247, 189, 26, 22, - /* 1220 */ 27, 99, 150, 151, 152, 153, 154, 105, 106, 189, - /* 1230 */ 302, 303, 211, 212, 112, 42, 114, 115, 116, 211, - /* 1240 */ 212, 119, 302, 303, 19, 20, 189, 22, 274, 189, - /* 1250 */ 15, 144, 278, 189, 22, 23, 63, 189, 189, 203, - /* 1260 */ 204, 36, 136, 137, 155, 24, 157, 143, 211, 212, - /* 1270 */ 189, 140, 150, 151, 152, 153, 154, 0, 1, 2, - /* 1280 */ 211, 212, 5, 46, 59, 161, 147, 10, 11, 12, - /* 1290 */ 13, 14, 211, 212, 17, 60, 71, 189, 258, 189, - /* 1300 */ 59, 189, 105, 106, 189, 189, 189, 30, 116, 32, - /* 1310 */ 85, 124, 189, 251, 252, 90, 189, 40, 258, 211, - /* 1320 */ 212, 211, 212, 189, 99, 26, 211, 212, 211, 212, - /* 1330 */ 105, 106, 100, 141, 211, 212, 119, 112, 189, 114, - /* 1340 */ 115, 116, 23, 189, 119, 26, 129, 70, 189, 31, - /* 1350 */ 113, 19, 20, 24, 22, 78, 115, 39, 81, 189, - /* 1360 */ 211, 212, 26, 189, 22, 211, 212, 189, 36, 189, - /* 1370 */ 211, 212, 189, 189, 97, 150, 151, 152, 153, 154, - /* 1380 */ 127, 211, 212, 189, 189, 211, 212, 189, 189, 211, - /* 1390 */ 212, 59, 189, 189, 211, 212, 23, 189, 22, 26, - /* 1400 */ 24, 189, 149, 71, 189, 211, 212, 189, 131, 211, - /* 1410 */ 212, 189, 189, 136, 137, 211, 212, 85, 189, 211, - /* 1420 */ 212, 59, 90, 211, 212, 292, 293, 118, 119, 211, - /* 1430 */ 212, 99, 23, 211, 212, 26, 159, 105, 106, 189, - /* 1440 */ 211, 212, 143, 150, 112, 152, 114, 115, 116, 1, - /* 1450 */ 2, 119, 23, 5, 23, 26, 189, 26, 10, 11, - /* 1460 */ 12, 13, 14, 83, 84, 17, 253, 189, 139, 189, - /* 1470 */ 19, 20, 189, 22, 189, 189, 140, 115, 30, 59, - /* 1480 */ 32, 139, 150, 151, 152, 153, 154, 36, 40, 211, - /* 1490 */ 212, 211, 212, 59, 211, 212, 211, 212, 7, 8, - /* 1500 */ 19, 20, 189, 22, 150, 189, 152, 231, 281, 189, - /* 1510 */ 59, 189, 23, 189, 189, 26, 189, 36, 70, 189, - /* 1520 */ 23, 237, 71, 26, 211, 212, 78, 211, 212, 81, - /* 1530 */ 189, 211, 212, 211, 212, 115, 211, 212, 211, 212, - /* 1540 */ 59, 211, 212, 23, 23, 97, 26, 26, 23, 115, - /* 1550 */ 99, 26, 71, 189, 189, 189, 105, 106, 107, 23, - /* 1560 */ 189, 23, 26, 112, 26, 114, 115, 116, 189, 309, - /* 1570 */ 119, 23, 19, 20, 26, 22, 189, 211, 212, 131, - /* 1580 */ 99, 189, 211, 212, 136, 137, 105, 106, 189, 36, - /* 1590 */ 211, 212, 189, 112, 189, 114, 115, 116, 211, 212, - /* 1600 */ 119, 150, 151, 152, 153, 154, 189, 159, 23, 250, - /* 1610 */ 189, 26, 59, 189, 189, 189, 189, 189, 280, 189, - /* 1620 */ 250, 189, 189, 238, 71, 189, 189, 250, 211, 212, - /* 1630 */ 187, 150, 151, 152, 153, 154, 211, 212, 250, 290, - /* 1640 */ 240, 211, 212, 211, 212, 254, 286, 209, 254, 241, - /* 1650 */ 240, 254, 99, 286, 215, 220, 214, 244, 105, 106, - /* 1660 */ 214, 214, 244, 273, 224, 112, 192, 114, 115, 116, - /* 1670 */ 60, 290, 119, 5, 139, 196, 196, 38, 10, 11, - /* 1680 */ 12, 13, 14, 238, 240, 17, 196, 148, 287, 287, - /* 1690 */ 276, 113, 22, 147, 241, 43, 229, 241, 30, 18, - /* 1700 */ 32, 232, 232, 150, 151, 152, 153, 154, 40, 232, - /* 1710 */ 232, 196, 18, 195, 265, 265, 264, 241, 264, 196, - /* 1720 */ 155, 229, 229, 241, 241, 241, 195, 62, 196, 195, - /* 1730 */ 22, 113, 216, 196, 222, 195, 195, 282, 70, 196, - /* 1740 */ 283, 213, 216, 213, 64, 22, 78, 124, 219, 81, - /* 1750 */ 162, 111, 219, 142, 256, 213, 113, 255, 213, 256, - /* 1760 */ 216, 303, 215, 213, 213, 97, 255, 213, 216, 275, - /* 1770 */ 275, 222, 216, 256, 255, 196, 91, 82, 256, 255, - /* 1780 */ 308, 308, 146, 22, 143, 196, 155, 260, 25, 145, - /* 1790 */ 144, 199, 26, 198, 13, 190, 190, 6, 293, 131, - /* 1800 */ 188, 188, 245, 244, 136, 137, 245, 243, 242, 241, - /* 1810 */ 188, 202, 208, 217, 217, 260, 208, 4, 202, 3, - /* 1820 */ 22, 202, 208, 208, 160, 15, 209, 159, 270, 209, - /* 1830 */ 98, 16, 272, 208, 23, 23, 137, 148, 128, 20, - /* 1840 */ 140, 24, 16, 142, 1, 140, 149, 128, 61, 53, - /* 1850 */ 148, 37, 53, 53, 53, 128, 114, 34, 296, 296, - /* 1860 */ 139, 1, 5, 22, 113, 158, 26, 75, 41, 139, - /* 1870 */ 68, 68, 113, 24, 20, 19, 129, 123, 23, 96, - /* 1880 */ 22, 22, 37, 22, 22, 67, 22, 67, 59, 24, - /* 1890 */ 23, 28, 67, 147, 22, 26, 23, 23, 23, 23, - /* 1900 */ 22, 24, 23, 22, 24, 23, 139, 23, 114, 22, - /* 1910 */ 141, 26, 88, 75, 86, 44, 23, 34, 22, 75, - /* 1920 */ 34, 24, 34, 34, 34, 93, 34, 26, 26, 34, - /* 1930 */ 23, 23, 23, 23, 23, 11, 23, 22, 26, 22, - /* 1940 */ 22, 133, 23, 23, 22, 22, 139, 26, 139, 23, - /* 1950 */ 15, 1, 1, 310, 310, 310, 310, 310, 310, 310, - /* 1960 */ 139, 139, 310, 310, 310, 310, 310, 310, 310, 310, - /* 1970 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 1980 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 1990 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2000 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2010 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2020 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2030 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2040 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2050 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2060 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2070 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2080 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2090 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2100 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2110 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2120 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2130 */ 310, 310, 310, 310, 310, 310, 310, 310, 310, 310, - /* 2140 */ 310, 310, 310, + /* 450 */ 54, 55, 56, 57, 191, 117, 191, 210, 19, 152, + /* 460 */ 153, 154, 23, 295, 102, 103, 104, 105, 106, 107, + /* 470 */ 108, 109, 110, 111, 112, 266, 213, 214, 213, 214, + /* 480 */ 142, 81, 43, 44, 45, 46, 47, 48, 49, 50, + /* 490 */ 51, 52, 53, 54, 55, 56, 57, 301, 102, 103, + /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 106, + /* 510 */ 107, 118, 59, 250, 121, 122, 123, 280, 76, 119, + /* 520 */ 236, 237, 259, 306, 131, 72, 59, 310, 19, 87, + /* 530 */ 283, 89, 23, 249, 92, 288, 22, 137, 138, 22, + /* 540 */ 275, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50, + /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 115, 116, + /* 570 */ 117, 23, 186, 59, 188, 108, 59, 241, 191, 193, + /* 580 */ 26, 195, 115, 116, 117, 191, 144, 251, 202, 22, + /* 590 */ 100, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 600 */ 52, 53, 54, 55, 56, 57, 116, 213, 214, 191, + /* 610 */ 120, 102, 103, 104, 105, 106, 107, 108, 109, 110, + /* 620 */ 111, 112, 236, 237, 306, 238, 59, 26, 310, 115, + /* 630 */ 116, 117, 115, 116, 117, 249, 246, 19, 248, 106, + /* 640 */ 107, 23, 152, 153, 154, 46, 47, 48, 49, 263, + /* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51, + /* 670 */ 52, 53, 54, 55, 56, 57, 19, 76, 298, 299, + /* 680 */ 23, 295, 115, 116, 117, 152, 191, 154, 301, 73, + /* 690 */ 89, 137, 138, 92, 22, 191, 144, 22, 191, 191, + /* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 710 */ 53, 54, 55, 56, 57, 163, 191, 213, 214, 120, + /* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 730 */ 112, 59, 228, 191, 59, 191, 236, 237, 213, 214, + /* 740 */ 11, 59, 126, 127, 128, 238, 19, 26, 191, 249, + /* 750 */ 23, 164, 165, 228, 191, 213, 214, 213, 214, 102, + /* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + /* 780 */ 53, 54, 55, 56, 57, 19, 241, 115, 116, 117, + /* 790 */ 115, 116, 117, 191, 250, 238, 251, 115, 116, 117, + /* 800 */ 157, 23, 159, 191, 26, 191, 111, 112, 301, 43, + /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 820 */ 54, 55, 56, 57, 142, 213, 214, 213, 214, 102, + /* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + /* 840 */ 228, 191, 228, 191, 191, 207, 208, 209, 126, 127, + /* 850 */ 128, 133, 289, 135, 136, 19, 127, 128, 301, 7, + /* 860 */ 8, 9, 141, 213, 214, 213, 214, 265, 102, 103, + /* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43, + /* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + /* 890 */ 54, 55, 56, 57, 191, 117, 191, 22, 23, 19, + /* 900 */ 250, 26, 250, 191, 223, 191, 126, 127, 128, 205, + /* 910 */ 206, 205, 206, 260, 21, 202, 213, 214, 213, 214, + /* 920 */ 142, 270, 208, 209, 158, 45, 46, 47, 48, 49, + /* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103, + /* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 236, + /* 950 */ 237, 12, 191, 250, 76, 250, 191, 22, 23, 308, + /* 960 */ 309, 26, 249, 202, 191, 191, 27, 89, 191, 202, + /* 970 */ 92, 202, 260, 80, 213, 214, 101, 203, 213, 214, + /* 980 */ 22, 42, 102, 103, 104, 105, 106, 107, 108, 109, + /* 990 */ 110, 111, 112, 228, 158, 281, 108, 236, 237, 225, + /* 1000 */ 191, 227, 63, 236, 237, 236, 237, 191, 235, 191, + /* 1010 */ 249, 250, 73, 241, 19, 122, 249, 59, 249, 24, + /* 1020 */ 259, 29, 134, 251, 191, 33, 22, 139, 24, 213, + /* 1030 */ 214, 213, 214, 191, 19, 210, 101, 191, 43, 44, + /* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1050 */ 55, 56, 57, 160, 19, 213, 214, 65, 43, 44, + /* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1070 */ 55, 56, 57, 191, 116, 22, 191, 24, 43, 44, + /* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + /* 1090 */ 55, 56, 57, 191, 261, 213, 214, 102, 103, 104, + /* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 19, + /* 1110 */ 191, 265, 59, 288, 191, 213, 214, 102, 103, 104, + /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 35, 191, + /* 1130 */ 66, 191, 213, 214, 191, 270, 46, 102, 103, 104, + /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 191, 85, + /* 1150 */ 265, 213, 214, 213, 214, 106, 107, 19, 94, 66, + /* 1160 */ 137, 138, 191, 114, 115, 116, 117, 74, 119, 116, + /* 1170 */ 213, 214, 202, 308, 309, 306, 127, 191, 235, 310, + /* 1180 */ 59, 191, 44, 45, 46, 47, 48, 49, 50, 51, + /* 1190 */ 52, 53, 54, 55, 56, 57, 191, 76, 196, 213, + /* 1200 */ 214, 152, 12, 154, 114, 191, 236, 237, 87, 145, + /* 1210 */ 89, 19, 20, 92, 22, 22, 23, 27, 191, 249, + /* 1220 */ 130, 202, 129, 202, 191, 235, 306, 152, 36, 154, + /* 1230 */ 310, 191, 42, 191, 191, 191, 115, 116, 117, 191, + /* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + /* 1250 */ 112, 59, 99, 63, 191, 236, 237, 236, 237, 191, + /* 1260 */ 289, 213, 214, 71, 191, 144, 261, 191, 249, 191, + /* 1270 */ 249, 19, 20, 81, 22, 235, 213, 214, 235, 191, + /* 1280 */ 278, 213, 214, 191, 282, 132, 213, 214, 36, 213, + /* 1290 */ 214, 191, 100, 191, 101, 191, 191, 191, 106, 107, + /* 1300 */ 48, 213, 214, 261, 191, 113, 191, 115, 116, 117, + /* 1310 */ 191, 59, 120, 213, 214, 213, 214, 213, 214, 213, + /* 1320 */ 214, 22, 23, 71, 237, 59, 213, 214, 191, 137, + /* 1330 */ 138, 191, 213, 214, 191, 191, 249, 85, 191, 261, + /* 1340 */ 191, 26, 90, 15, 152, 153, 154, 155, 156, 19, + /* 1350 */ 213, 214, 100, 213, 214, 191, 213, 214, 106, 107, + /* 1360 */ 213, 214, 213, 214, 191, 113, 261, 115, 116, 117, + /* 1370 */ 253, 254, 120, 229, 191, 191, 191, 213, 214, 191, + /* 1380 */ 306, 289, 116, 26, 310, 191, 213, 214, 60, 19, + /* 1390 */ 296, 297, 24, 191, 46, 191, 213, 214, 213, 214, + /* 1400 */ 101, 213, 214, 191, 152, 153, 154, 155, 156, 0, + /* 1410 */ 1, 2, 191, 229, 5, 213, 214, 213, 214, 10, + /* 1420 */ 11, 12, 13, 14, 1, 2, 17, 191, 5, 19, + /* 1430 */ 20, 191, 22, 10, 11, 12, 13, 14, 191, 30, + /* 1440 */ 17, 32, 241, 148, 149, 115, 36, 191, 241, 40, + /* 1450 */ 191, 26, 251, 30, 191, 32, 141, 22, 251, 5, + /* 1460 */ 213, 214, 114, 40, 10, 11, 12, 13, 14, 59, + /* 1470 */ 134, 17, 213, 214, 191, 139, 213, 214, 191, 70, + /* 1480 */ 191, 71, 125, 191, 30, 115, 32, 78, 53, 191, + /* 1490 */ 81, 191, 191, 70, 40, 85, 213, 214, 191, 22, + /* 1500 */ 90, 78, 213, 214, 81, 213, 214, 98, 140, 120, + /* 1510 */ 100, 213, 214, 213, 214, 23, 106, 107, 26, 130, + /* 1520 */ 191, 98, 191, 113, 70, 115, 116, 117, 23, 22, + /* 1530 */ 120, 26, 78, 19, 191, 81, 19, 20, 61, 22, + /* 1540 */ 191, 132, 213, 214, 213, 214, 137, 138, 59, 191, + /* 1550 */ 191, 191, 98, 36, 128, 132, 213, 214, 128, 59, + /* 1560 */ 137, 138, 152, 153, 154, 155, 156, 83, 84, 144, + /* 1570 */ 161, 213, 214, 213, 214, 23, 59, 151, 26, 23, + /* 1580 */ 23, 151, 26, 26, 161, 59, 132, 23, 71, 191, + /* 1590 */ 26, 137, 138, 119, 120, 23, 19, 20, 26, 22, + /* 1600 */ 223, 23, 85, 23, 26, 116, 26, 90, 191, 7, + /* 1610 */ 8, 97, 152, 36, 154, 161, 116, 100, 23, 23, + /* 1620 */ 191, 26, 26, 106, 107, 191, 23, 223, 23, 26, + /* 1630 */ 113, 26, 115, 116, 117, 23, 59, 120, 26, 191, + /* 1640 */ 191, 191, 116, 255, 191, 252, 191, 140, 71, 191, + /* 1650 */ 315, 233, 191, 191, 191, 191, 191, 191, 191, 191, + /* 1660 */ 191, 285, 284, 239, 252, 252, 252, 252, 240, 152, + /* 1670 */ 153, 154, 155, 156, 189, 294, 268, 100, 242, 268, + /* 1680 */ 264, 211, 290, 106, 107, 108, 264, 256, 256, 243, + /* 1690 */ 113, 290, 115, 116, 117, 268, 217, 120, 226, 243, + /* 1700 */ 222, 268, 216, 19, 20, 246, 22, 216, 256, 216, + /* 1710 */ 194, 60, 38, 242, 277, 294, 240, 242, 198, 246, + /* 1720 */ 36, 140, 198, 198, 19, 20, 150, 22, 149, 152, + /* 1730 */ 153, 154, 155, 156, 294, 291, 291, 280, 22, 43, + /* 1740 */ 231, 36, 18, 59, 234, 234, 234, 234, 267, 269, + /* 1750 */ 18, 198, 197, 231, 148, 71, 269, 269, 243, 231, + /* 1760 */ 198, 243, 267, 197, 59, 157, 243, 198, 62, 287, + /* 1770 */ 243, 197, 22, 198, 114, 64, 71, 218, 218, 197, + /* 1780 */ 286, 198, 197, 215, 100, 215, 215, 224, 22, 125, + /* 1790 */ 106, 107, 164, 24, 221, 112, 143, 113, 302, 115, + /* 1800 */ 116, 117, 218, 215, 120, 100, 217, 221, 215, 215, + /* 1810 */ 309, 106, 107, 215, 224, 279, 279, 218, 113, 258, + /* 1820 */ 115, 116, 117, 114, 257, 120, 91, 198, 82, 147, + /* 1830 */ 144, 22, 274, 314, 198, 314, 152, 153, 154, 155, + /* 1840 */ 156, 276, 157, 146, 145, 258, 25, 247, 257, 201, + /* 1850 */ 258, 26, 200, 13, 257, 244, 246, 152, 153, 154, + /* 1860 */ 155, 156, 258, 262, 257, 247, 245, 243, 192, 192, + /* 1870 */ 6, 262, 204, 210, 219, 210, 210, 190, 190, 190, + /* 1880 */ 210, 219, 204, 211, 211, 210, 4, 3, 22, 162, + /* 1890 */ 15, 23, 16, 23, 204, 138, 129, 150, 26, 141, + /* 1900 */ 20, 24, 143, 16, 1, 141, 129, 129, 61, 53, + /* 1910 */ 37, 150, 297, 300, 300, 53, 53, 129, 53, 115, + /* 1920 */ 34, 140, 1, 5, 22, 114, 68, 26, 160, 68, + /* 1930 */ 75, 41, 140, 114, 24, 20, 19, 130, 124, 23, + /* 1940 */ 96, 22, 22, 37, 22, 67, 22, 59, 67, 24, + /* 1950 */ 22, 28, 67, 23, 148, 22, 97, 23, 23, 23, + /* 1960 */ 140, 23, 22, 26, 23, 23, 115, 22, 142, 26, + /* 1970 */ 75, 88, 75, 34, 23, 86, 44, 22, 34, 26, + /* 1980 */ 34, 34, 34, 34, 93, 24, 26, 23, 34, 23, + /* 1990 */ 23, 23, 23, 11, 23, 22, 26, 22, 22, 15, + /* 2000 */ 23, 23, 22, 22, 1, 26, 23, 140, 134, 140, + /* 2010 */ 1, 140, 316, 316, 316, 316, 316, 316, 316, 140, + /* 2020 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2030 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2040 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2050 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2060 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2070 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2080 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2090 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2100 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2110 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2120 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2130 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2140 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2150 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2160 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2170 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2180 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2190 */ 316, 316, 316, 316, 316, 316, 316, 316, 316, 316, + /* 2200 */ 316, 316, 316, }; -#define YY_SHIFT_COUNT (552) +#define YY_SHIFT_COUNT (569) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (1951) +#define YY_SHIFT_MAX (2009) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 1448, 1277, 1668, 1072, 1072, 340, 1122, 1225, 1332, 1481, - /* 10 */ 1481, 1481, 335, 0, 0, 180, 897, 1481, 1481, 1481, - /* 20 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 30 */ 930, 930, 1020, 1020, 290, 1, 340, 340, 340, 340, - /* 40 */ 340, 340, 40, 110, 219, 288, 327, 396, 435, 504, - /* 50 */ 543, 612, 651, 720, 877, 897, 897, 897, 897, 897, - /* 60 */ 897, 897, 897, 897, 897, 897, 897, 897, 897, 897, - /* 70 */ 897, 897, 897, 917, 897, 1019, 763, 763, 1451, 1481, - /* 80 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 90 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 100 */ 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 110 */ 1481, 1481, 1553, 1481, 1481, 1481, 1481, 1481, 1481, 1481, - /* 120 */ 1481, 1481, 1481, 1481, 1481, 1481, 147, 258, 258, 258, - /* 130 */ 258, 258, 79, 65, 84, 449, 19, 786, 449, 636, - /* 140 */ 636, 449, 880, 880, 880, 880, 113, 142, 142, 472, - /* 150 */ 150, 1962, 1962, 399, 399, 399, 93, 237, 341, 237, - /* 160 */ 237, 1074, 1074, 437, 350, 704, 1080, 449, 449, 449, - /* 170 */ 449, 449, 449, 449, 449, 449, 449, 449, 449, 449, - /* 180 */ 449, 449, 449, 449, 449, 449, 449, 449, 818, 818, - /* 190 */ 449, 1088, 217, 217, 734, 734, 1124, 1126, 1962, 1962, - /* 200 */ 1962, 739, 840, 840, 453, 454, 511, 187, 563, 570, - /* 210 */ 898, 669, 449, 449, 449, 449, 449, 449, 449, 449, - /* 220 */ 449, 670, 449, 449, 449, 449, 449, 449, 449, 449, - /* 230 */ 449, 449, 449, 449, 674, 674, 674, 449, 449, 449, - /* 240 */ 449, 1034, 449, 449, 449, 972, 1107, 449, 449, 1193, - /* 250 */ 449, 449, 449, 449, 449, 449, 449, 449, 260, 177, - /* 260 */ 489, 1241, 1241, 1241, 1241, 1192, 489, 489, 952, 1197, - /* 270 */ 625, 1235, 1131, 181, 181, 1086, 1139, 1131, 1086, 1187, - /* 280 */ 1319, 1237, 1318, 1318, 1318, 181, 1299, 1299, 1109, 1336, - /* 290 */ 549, 1376, 1610, 1535, 1535, 1639, 1639, 1535, 1539, 1578, - /* 300 */ 1670, 1546, 1652, 1546, 1681, 1681, 1681, 1681, 1535, 1694, - /* 310 */ 1546, 1546, 1578, 1670, 1652, 1546, 1652, 1546, 1535, 1694, - /* 320 */ 1565, 1665, 1535, 1694, 1708, 1535, 1694, 1535, 1694, 1708, - /* 330 */ 1618, 1618, 1618, 1680, 1723, 1723, 1708, 1618, 1623, 1618, - /* 340 */ 1680, 1618, 1618, 1588, 1708, 1640, 1640, 1708, 1611, 1643, - /* 350 */ 1611, 1643, 1611, 1643, 1611, 1643, 1535, 1685, 1685, 1695, - /* 360 */ 1695, 1636, 1641, 1761, 1535, 1631, 1636, 1644, 1646, 1546, - /* 370 */ 1763, 1766, 1781, 1781, 1791, 1791, 1791, 1962, 1962, 1962, - /* 380 */ 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, 1962, - /* 390 */ 1962, 1962, 308, 835, 954, 1232, 879, 715, 728, 1373, - /* 400 */ 864, 1329, 1253, 1409, 297, 1431, 1489, 1497, 1520, 1521, - /* 410 */ 1525, 1362, 1309, 1491, 1217, 1420, 1429, 1536, 1380, 1538, - /* 420 */ 1293, 1354, 1548, 1585, 1434, 1342, 1813, 1816, 1798, 1664, - /* 430 */ 1810, 1732, 1815, 1811, 1812, 1699, 1689, 1710, 1817, 1700, - /* 440 */ 1819, 1701, 1826, 1843, 1705, 1697, 1719, 1787, 1814, 1702, - /* 450 */ 1796, 1799, 1800, 1801, 1727, 1742, 1823, 1721, 1860, 1857, - /* 460 */ 1841, 1751, 1707, 1802, 1840, 1803, 1792, 1827, 1730, 1759, - /* 470 */ 1849, 1854, 1856, 1747, 1754, 1858, 1818, 1859, 1861, 1855, - /* 480 */ 1862, 1820, 1829, 1865, 1783, 1863, 1864, 1825, 1845, 1867, - /* 490 */ 1746, 1872, 1873, 1874, 1875, 1869, 1876, 1878, 1877, 1879, - /* 500 */ 1881, 1880, 1767, 1882, 1884, 1794, 1883, 1887, 1769, 1885, - /* 510 */ 1886, 1888, 1889, 1890, 1824, 1838, 1828, 1871, 1844, 1832, - /* 520 */ 1892, 1893, 1896, 1897, 1901, 1902, 1895, 1907, 1885, 1908, - /* 530 */ 1909, 1910, 1911, 1912, 1913, 1915, 1924, 1917, 1918, 1919, - /* 540 */ 1920, 1922, 1923, 1921, 1808, 1807, 1809, 1821, 1822, 1926, - /* 550 */ 1935, 1950, 1951, + /* 0 */ 1423, 1409, 1454, 1192, 1192, 36, 1252, 1410, 1517, 1684, + /* 10 */ 1684, 1684, 292, 0, 0, 180, 1015, 1684, 1684, 1684, + /* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 30 */ 1049, 1049, 1121, 1121, 54, 400, 36, 36, 36, 36, + /* 40 */ 36, 40, 110, 219, 289, 396, 439, 509, 548, 618, + /* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015, + /* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, + /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1577, 1684, + /* 80 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 90 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 100 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, + /* 110 */ 1684, 1684, 1684, 1705, 1684, 1684, 1684, 1684, 1684, 1684, + /* 120 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 146, 84, 84, + /* 130 */ 84, 84, 84, 362, 269, 125, 97, 453, 66, 66, + /* 140 */ 893, 1090, 66, 66, 533, 533, 66, 554, 554, 554, + /* 150 */ 554, 192, 587, 587, 695, 25, 2020, 2020, 290, 290, + /* 160 */ 290, 200, 514, 514, 514, 514, 939, 939, 442, 875, + /* 170 */ 935, 66, 66, 66, 66, 66, 66, 66, 66, 66, + /* 180 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + /* 190 */ 66, 601, 601, 66, 729, 878, 878, 1266, 1266, 552, + /* 200 */ 1023, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 307, 490, + /* 210 */ 490, 567, 393, 517, 467, 672, 242, 682, 675, 66, + /* 220 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 616, + /* 230 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + /* 240 */ 66, 66, 1093, 1093, 1093, 66, 66, 66, 778, 66, + /* 250 */ 66, 66, 1053, 1064, 66, 66, 1190, 66, 66, 66, + /* 260 */ 66, 66, 66, 66, 66, 722, 992, 718, 253, 253, + /* 270 */ 253, 253, 338, 718, 718, 888, 403, 852, 1328, 254, + /* 280 */ 1295, 721, 1330, 1295, 1330, 1370, 234, 254, 254, 234, + /* 290 */ 254, 721, 1370, 1357, 1492, 1348, 385, 385, 385, 1330, + /* 300 */ 1425, 1425, 643, 1315, 1336, 1004, 1651, 1651, 1581, 1581, + /* 310 */ 1674, 1674, 1581, 1576, 1579, 1716, 1696, 1724, 1724, 1724, + /* 320 */ 1724, 1581, 1732, 1606, 1579, 1579, 1606, 1716, 1696, 1606, + /* 330 */ 1696, 1606, 1581, 1732, 1608, 1706, 1581, 1732, 1750, 1581, + /* 340 */ 1732, 1581, 1732, 1750, 1660, 1660, 1660, 1711, 1766, 1766, + /* 350 */ 1750, 1660, 1664, 1660, 1711, 1660, 1660, 1628, 1769, 1683, + /* 360 */ 1683, 1750, 1653, 1709, 1653, 1709, 1653, 1709, 1653, 1709, + /* 370 */ 1581, 1735, 1735, 1746, 1746, 1682, 1686, 1809, 1581, 1685, + /* 380 */ 1682, 1697, 1699, 1606, 1821, 1825, 1840, 1840, 1864, 1864, + /* 390 */ 1864, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, + /* 400 */ 2020, 2020, 2020, 2020, 2020, 2020, 599, 223, 1193, 1299, + /* 410 */ 228, 780, 958, 1505, 1153, 1435, 1368, 1426, 1430, 1552, + /* 420 */ 1477, 1556, 1557, 1564, 1572, 1578, 1580, 1489, 1474, 1602, + /* 430 */ 1389, 1514, 1500, 1595, 1596, 1484, 1603, 1075, 1460, 1605, + /* 440 */ 1612, 1526, 1507, 1882, 1884, 1866, 1727, 1875, 1876, 1868, + /* 450 */ 1870, 1757, 1747, 1767, 1872, 1872, 1877, 1758, 1880, 1759, + /* 460 */ 1887, 1903, 1764, 1777, 1872, 1778, 1847, 1873, 1872, 1761, + /* 470 */ 1856, 1862, 1863, 1865, 1788, 1804, 1886, 1781, 1921, 1918, + /* 480 */ 1902, 1811, 1768, 1858, 1901, 1861, 1855, 1890, 1792, 1819, + /* 490 */ 1910, 1915, 1917, 1807, 1814, 1919, 1878, 1920, 1922, 1916, + /* 500 */ 1924, 1881, 1888, 1925, 1844, 1923, 1928, 1885, 1906, 1930, + /* 510 */ 1806, 1933, 1934, 1935, 1936, 1937, 1938, 1940, 1859, 1820, + /* 520 */ 1941, 1942, 1851, 1939, 1945, 1826, 1943, 1944, 1946, 1947, + /* 530 */ 1948, 1883, 1895, 1889, 1932, 1897, 1891, 1949, 1951, 1955, + /* 540 */ 1961, 1953, 1960, 1954, 1964, 1943, 1966, 1967, 1968, 1969, + /* 550 */ 1970, 1971, 1973, 1982, 1975, 1976, 1977, 1978, 1980, 1981, + /* 560 */ 1979, 1874, 1867, 1869, 1871, 1879, 1983, 1984, 2003, 2009, }; -#define YY_REDUCE_COUNT (391) -#define YY_REDUCE_MIN (-262) -#define YY_REDUCE_MAX (1625) +#define YY_REDUCE_COUNT (405) +#define YY_REDUCE_MIN (-265) +#define YY_REDUCE_MAX (1690) static const short yy_reduce_ofst[] = { - /* 0 */ 490, -122, 545, 645, 650, -120, -189, -187, -184, -182, - /* 10 */ -178, -176, 45, 30, 200, -251, -134, 390, 392, 521, - /* 20 */ 523, 213, 692, 821, 284, 589, 872, 666, 671, 866, - /* 30 */ 71, 111, 273, 389, 686, 815, 904, 932, 948, 955, - /* 40 */ 964, 969, -259, -259, -259, -259, -259, -259, -259, -259, - /* 50 */ -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, - /* 60 */ -259, -259, -259, -259, -259, -259, -259, -259, -259, -259, - /* 70 */ -259, -259, -259, -259, -259, -259, -259, -259, 428, 430, - /* 80 */ 899, 985, 1021, 1028, 1057, 1069, 1081, 1108, 1110, 1115, - /* 90 */ 1117, 1123, 1149, 1154, 1159, 1170, 1174, 1178, 1183, 1194, - /* 100 */ 1198, 1204, 1208, 1212, 1218, 1222, 1229, 1278, 1280, 1283, - /* 110 */ 1285, 1313, 1316, 1320, 1322, 1325, 1327, 1330, 1366, 1371, - /* 120 */ 1379, 1387, 1417, 1425, 1430, 1432, -259, -259, -259, -259, - /* 130 */ -259, -259, -259, -259, -259, 557, 974, -214, -174, -9, - /* 140 */ 431, -124, 806, 925, 806, 925, 251, 928, 940, -259, - /* 150 */ -259, -259, -259, -198, -198, -198, 127, -186, -168, 212, - /* 160 */ 646, 617, 799, -262, 555, 220, 220, 491, 605, 1040, - /* 170 */ 1060, 699, -11, 600, 848, 862, 345, -129, 724, -91, - /* 180 */ 158, 749, 716, 900, 304, 822, 929, 926, 499, 793, - /* 190 */ 322, 892, 813, 845, 958, 1056, 751, 905, 1133, 1062, - /* 200 */ 803, -210, -185, -179, -148, -167, -89, 121, 274, 281, - /* 210 */ 320, 336, 439, 663, 711, 957, 965, 1064, 1068, 1112, - /* 220 */ 1116, -196, 1127, 1134, 1180, 1184, 1195, 1199, 1203, 1215, - /* 230 */ 1223, 1250, 1267, 1286, 205, 422, 638, 1324, 1341, 1364, - /* 240 */ 1365, 1213, 1392, 1399, 1403, 869, 1260, 1405, 1421, 1276, - /* 250 */ 1424, 121, 1426, 1427, 1428, 1433, 1436, 1437, 1227, 1338, - /* 260 */ 1284, 1359, 1370, 1377, 1388, 1213, 1284, 1284, 1385, 1438, - /* 270 */ 1443, 1349, 1400, 1391, 1394, 1360, 1408, 1410, 1367, 1439, - /* 280 */ 1440, 1435, 1442, 1446, 1447, 1397, 1413, 1418, 1390, 1444, - /* 290 */ 1445, 1474, 1381, 1479, 1480, 1401, 1402, 1490, 1414, 1449, - /* 300 */ 1452, 1453, 1467, 1456, 1469, 1470, 1477, 1478, 1515, 1518, - /* 310 */ 1476, 1482, 1450, 1454, 1492, 1483, 1493, 1484, 1523, 1531, - /* 320 */ 1457, 1455, 1532, 1534, 1516, 1537, 1540, 1543, 1541, 1526, - /* 330 */ 1528, 1530, 1542, 1512, 1529, 1533, 1544, 1545, 1547, 1550, - /* 340 */ 1549, 1551, 1554, 1458, 1552, 1494, 1495, 1556, 1498, 1502, - /* 350 */ 1503, 1511, 1517, 1519, 1522, 1524, 1579, 1472, 1473, 1527, - /* 360 */ 1555, 1557, 1559, 1558, 1589, 1560, 1561, 1564, 1566, 1568, - /* 370 */ 1592, 1595, 1605, 1606, 1612, 1613, 1622, 1562, 1563, 1505, - /* 380 */ 1609, 1604, 1608, 1614, 1615, 1616, 1596, 1597, 1617, 1620, - /* 390 */ 1625, 1619, + /* 0 */ 111, 168, 386, 761, -176, -174, -191, -189, -181, -178, + /* 10 */ 176, 263, 44, -207, -204, -265, -139, -114, 158, 504, + /* 20 */ 525, 544, 612, 614, 650, 652, 765, 265, 703, 705, + /* 30 */ 70, 714, -187, 127, 774, 713, 767, 769, 970, 1019, + /* 40 */ 1021, -255, -255, -255, -255, -255, -255, -255, -255, -255, + /* 50 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, + /* 60 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255, + /* 70 */ -255, -255, -255, -255, -255, -255, -255, -255, 394, 542, + /* 80 */ 816, 818, 842, 882, 902, 919, 938, 940, 957, 986, + /* 90 */ 1048, 1063, 1068, 1073, 1076, 1088, 1100, 1102, 1104, 1106, + /* 100 */ 1113, 1119, 1137, 1140, 1143, 1147, 1149, 1164, 1173, 1183, + /* 110 */ 1185, 1188, 1202, 1204, 1247, 1259, 1263, 1283, 1289, 1292, + /* 120 */ 1298, 1300, 1329, 1331, 1343, 1358, 1360, -255, -255, -255, + /* 130 */ -255, -255, -255, -255, -255, 196, -255, 387, -177, 507, + /* 140 */ 1002, -219, 557, -93, -167, 638, -121, 284, 500, 284, + /* 150 */ 500, 247, 651, 865, -255, -255, -255, -255, -85, -85, + /* 160 */ -85, 237, 171, 602, 846, 885, -212, -203, 217, 380, + /* 170 */ 380, -23, 161, 653, 712, 773, 943, 990, 1040, 563, + /* 180 */ 833, 971, 1005, 1042, 1092, 1078, 1043, 1144, 1184, -186, + /* 190 */ 1105, 318, 869, 7, 825, 920, 1074, 704, 706, 390, + /* 200 */ 1087, 1094, 336, 545, 772, 1201, 1117, 1207, -179, -137, + /* 210 */ -112, -13, 18, 112, 197, 418, 495, 508, 777, 809, + /* 220 */ 923, 1014, 1027, 1033, 1044, 1115, 1194, 1212, 1221, 209, + /* 230 */ 1236, 1240, 1256, 1287, 1301, 1307, 1349, 1359, 1398, 1417, + /* 240 */ 1429, 1434, 681, 1377, 1404, 1448, 1449, 1450, 1388, 1453, + /* 250 */ 1455, 1458, 1393, 1335, 1461, 1462, 1418, 1463, 197, 1464, + /* 260 */ 1465, 1466, 1467, 1468, 1469, 1376, 1378, 1424, 1412, 1413, + /* 270 */ 1414, 1415, 1388, 1424, 1424, 1428, 1470, 1485, 1381, 1408, + /* 280 */ 1416, 1436, 1431, 1422, 1432, 1392, 1446, 1411, 1427, 1456, + /* 290 */ 1433, 1471, 1401, 1479, 1472, 1478, 1486, 1491, 1493, 1452, + /* 300 */ 1459, 1473, 1437, 1475, 1476, 1516, 1421, 1440, 1520, 1524, + /* 310 */ 1444, 1445, 1525, 1457, 1480, 1481, 1509, 1510, 1511, 1512, + /* 320 */ 1513, 1553, 1555, 1515, 1487, 1488, 1518, 1495, 1522, 1523, + /* 330 */ 1528, 1527, 1562, 1566, 1482, 1494, 1569, 1574, 1559, 1575, + /* 340 */ 1582, 1583, 1585, 1560, 1568, 1570, 1571, 1563, 1573, 1586, + /* 350 */ 1584, 1588, 1589, 1593, 1590, 1594, 1598, 1501, 1496, 1536, + /* 360 */ 1537, 1599, 1561, 1567, 1587, 1591, 1592, 1597, 1604, 1607, + /* 370 */ 1629, 1519, 1521, 1601, 1609, 1600, 1610, 1558, 1636, 1565, + /* 380 */ 1618, 1621, 1611, 1624, 1648, 1652, 1676, 1677, 1687, 1688, + /* 390 */ 1689, 1613, 1614, 1615, 1668, 1663, 1665, 1666, 1670, 1678, + /* 400 */ 1655, 1662, 1672, 1673, 1675, 1690, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1575, 1575, 1575, 1411, 1188, 1297, 1188, 1188, 1188, 1411, - /* 10 */ 1411, 1411, 1188, 1327, 1327, 1464, 1219, 1188, 1188, 1188, - /* 20 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1410, 1188, 1188, - /* 30 */ 1188, 1188, 1494, 1494, 1188, 1188, 1188, 1188, 1188, 1188, - /* 40 */ 1188, 1188, 1188, 1336, 1188, 1188, 1188, 1188, 1188, 1188, - /* 50 */ 1412, 1413, 1188, 1188, 1188, 1463, 1465, 1428, 1346, 1345, - /* 60 */ 1344, 1343, 1446, 1314, 1341, 1334, 1338, 1406, 1407, 1405, - /* 70 */ 1409, 1413, 1412, 1188, 1337, 1377, 1391, 1376, 1188, 1188, - /* 80 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 90 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 100 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 110 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 120 */ 1188, 1188, 1188, 1188, 1188, 1188, 1385, 1390, 1396, 1389, - /* 130 */ 1386, 1379, 1378, 1380, 1381, 1188, 1209, 1261, 1188, 1188, - /* 140 */ 1188, 1188, 1482, 1481, 1188, 1188, 1219, 1371, 1370, 1382, - /* 150 */ 1383, 1393, 1392, 1471, 1529, 1528, 1429, 1188, 1188, 1188, - /* 160 */ 1188, 1188, 1188, 1494, 1188, 1188, 1188, 1188, 1188, 1188, - /* 170 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 180 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1494, 1494, - /* 190 */ 1188, 1219, 1494, 1494, 1215, 1215, 1321, 1188, 1477, 1297, - /* 200 */ 1288, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 210 */ 1188, 1188, 1188, 1188, 1188, 1468, 1466, 1188, 1188, 1188, - /* 220 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 230 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 240 */ 1188, 1188, 1188, 1188, 1188, 1293, 1188, 1188, 1188, 1188, - /* 250 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1523, 1188, 1441, - /* 260 */ 1275, 1293, 1293, 1293, 1293, 1295, 1276, 1274, 1287, 1220, - /* 270 */ 1195, 1567, 1294, 1316, 1316, 1564, 1340, 1294, 1564, 1236, - /* 280 */ 1545, 1231, 1327, 1327, 1327, 1316, 1321, 1321, 1408, 1294, - /* 290 */ 1287, 1188, 1567, 1302, 1302, 1566, 1566, 1302, 1429, 1349, - /* 300 */ 1355, 1340, 1264, 1340, 1270, 1270, 1270, 1270, 1302, 1206, - /* 310 */ 1340, 1340, 1349, 1355, 1264, 1340, 1264, 1340, 1302, 1206, - /* 320 */ 1445, 1561, 1302, 1206, 1419, 1302, 1206, 1302, 1206, 1419, - /* 330 */ 1262, 1262, 1262, 1251, 1188, 1188, 1419, 1262, 1236, 1262, - /* 340 */ 1251, 1262, 1262, 1512, 1419, 1423, 1423, 1419, 1320, 1315, - /* 350 */ 1320, 1315, 1320, 1315, 1320, 1315, 1302, 1504, 1504, 1330, - /* 360 */ 1330, 1335, 1321, 1414, 1302, 1188, 1335, 1333, 1331, 1340, - /* 370 */ 1212, 1254, 1526, 1526, 1522, 1522, 1522, 1572, 1572, 1477, - /* 380 */ 1538, 1219, 1219, 1219, 1219, 1538, 1238, 1238, 1220, 1220, - /* 390 */ 1219, 1538, 1188, 1188, 1188, 1188, 1188, 1188, 1533, 1188, - /* 400 */ 1430, 1306, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 410 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 420 */ 1188, 1188, 1188, 1188, 1188, 1360, 1188, 1191, 1474, 1188, - /* 430 */ 1188, 1472, 1188, 1188, 1188, 1188, 1188, 1188, 1307, 1188, - /* 440 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 450 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1563, 1188, 1188, - /* 460 */ 1188, 1188, 1188, 1188, 1444, 1443, 1188, 1188, 1304, 1188, - /* 470 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 480 */ 1188, 1188, 1234, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 490 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 500 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1332, - /* 510 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 520 */ 1188, 1188, 1188, 1188, 1509, 1322, 1188, 1188, 1554, 1188, - /* 530 */ 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, 1188, - /* 540 */ 1188, 1188, 1188, 1549, 1278, 1362, 1188, 1361, 1365, 1188, - /* 550 */ 1200, 1188, 1188, + /* 0 */ 1623, 1623, 1623, 1453, 1223, 1332, 1223, 1223, 1223, 1453, + /* 10 */ 1453, 1453, 1223, 1362, 1362, 1506, 1254, 1223, 1223, 1223, + /* 20 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1452, 1223, 1223, + /* 30 */ 1223, 1223, 1541, 1541, 1223, 1223, 1223, 1223, 1223, 1223, + /* 40 */ 1223, 1223, 1371, 1223, 1378, 1223, 1223, 1223, 1223, 1223, + /* 50 */ 1454, 1455, 1223, 1223, 1223, 1505, 1507, 1470, 1385, 1384, + /* 60 */ 1383, 1382, 1488, 1349, 1376, 1369, 1373, 1448, 1449, 1447, + /* 70 */ 1451, 1455, 1454, 1223, 1372, 1419, 1433, 1418, 1223, 1223, + /* 80 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 90 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 100 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 110 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 120 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1427, 1432, 1438, + /* 130 */ 1431, 1428, 1421, 1420, 1422, 1223, 1423, 1223, 1223, 1223, + /* 140 */ 1244, 1296, 1223, 1223, 1223, 1223, 1223, 1525, 1524, 1223, + /* 150 */ 1223, 1254, 1413, 1412, 1424, 1425, 1435, 1434, 1513, 1576, + /* 160 */ 1575, 1471, 1223, 1223, 1223, 1223, 1223, 1223, 1541, 1223, + /* 170 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 180 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 190 */ 1223, 1541, 1541, 1223, 1254, 1541, 1541, 1250, 1250, 1356, + /* 200 */ 1223, 1520, 1323, 1323, 1323, 1323, 1332, 1323, 1223, 1223, + /* 210 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 220 */ 1223, 1223, 1223, 1510, 1508, 1223, 1223, 1223, 1223, 1223, + /* 230 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 240 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 250 */ 1223, 1223, 1328, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 260 */ 1223, 1223, 1223, 1223, 1570, 1223, 1483, 1310, 1328, 1328, + /* 270 */ 1328, 1328, 1330, 1311, 1309, 1322, 1255, 1230, 1615, 1388, + /* 280 */ 1377, 1329, 1351, 1377, 1351, 1612, 1375, 1388, 1388, 1375, + /* 290 */ 1388, 1329, 1612, 1271, 1592, 1266, 1362, 1362, 1362, 1351, + /* 300 */ 1356, 1356, 1450, 1329, 1322, 1223, 1615, 1615, 1337, 1337, + /* 310 */ 1614, 1614, 1337, 1471, 1599, 1397, 1299, 1305, 1305, 1305, + /* 320 */ 1305, 1337, 1241, 1375, 1599, 1599, 1375, 1397, 1299, 1375, + /* 330 */ 1299, 1375, 1337, 1241, 1487, 1609, 1337, 1241, 1461, 1337, + /* 340 */ 1241, 1337, 1241, 1461, 1297, 1297, 1297, 1286, 1223, 1223, + /* 350 */ 1461, 1297, 1271, 1297, 1286, 1297, 1297, 1559, 1223, 1465, + /* 360 */ 1465, 1461, 1355, 1350, 1355, 1350, 1355, 1350, 1355, 1350, + /* 370 */ 1337, 1551, 1551, 1365, 1365, 1370, 1356, 1456, 1337, 1223, + /* 380 */ 1370, 1368, 1366, 1375, 1247, 1289, 1573, 1573, 1569, 1569, + /* 390 */ 1569, 1620, 1620, 1520, 1585, 1254, 1254, 1254, 1254, 1585, + /* 400 */ 1273, 1273, 1255, 1255, 1254, 1585, 1223, 1223, 1223, 1223, + /* 410 */ 1223, 1223, 1580, 1223, 1515, 1472, 1341, 1223, 1223, 1223, + /* 420 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 430 */ 1223, 1526, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 440 */ 1223, 1223, 1402, 1223, 1226, 1517, 1223, 1223, 1223, 1223, + /* 450 */ 1223, 1223, 1223, 1223, 1379, 1380, 1342, 1223, 1223, 1223, + /* 460 */ 1223, 1223, 1223, 1223, 1394, 1223, 1223, 1223, 1389, 1223, + /* 470 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1611, 1223, 1223, + /* 480 */ 1223, 1223, 1223, 1223, 1486, 1485, 1223, 1223, 1339, 1223, + /* 490 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 500 */ 1223, 1223, 1269, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 510 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 520 */ 1223, 1223, 1223, 1223, 1223, 1223, 1367, 1223, 1223, 1223, + /* 530 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 540 */ 1223, 1556, 1357, 1223, 1223, 1602, 1223, 1223, 1223, 1223, + /* 550 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 560 */ 1596, 1313, 1404, 1223, 1403, 1407, 1223, 1235, 1223, 1223, }; /********** End of lemon-generated parsing tables *****************************/ @@ -156097,6 +158193,7 @@ static const YYCODETYPE yyFallback[] = { 59, /* TIES => ID */ 59, /* GENERATED => ID */ 59, /* ALWAYS => ID */ + 59, /* MATERIALIZED => ID */ 59, /* REINDEX => ID */ 59, /* RENAME => ID */ 59, /* CTIME_KW => ID */ @@ -156148,6 +158245,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* HAVING => nothing */ 0, /* LIMIT => nothing */ 0, /* WHERE => nothing */ + 0, /* RETURNING => nothing */ 0, /* INTO => nothing */ 0, /* NOTHING => nothing */ 0, /* FLOAT => nothing */ @@ -156366,219 +158464,225 @@ static const char *const yyTokenName[] = { /* 94 */ "TIES", /* 95 */ "GENERATED", /* 96 */ "ALWAYS", - /* 97 */ "REINDEX", - /* 98 */ "RENAME", - /* 99 */ "CTIME_KW", - /* 100 */ "ANY", - /* 101 */ "BITAND", - /* 102 */ "BITOR", - /* 103 */ "LSHIFT", - /* 104 */ "RSHIFT", - /* 105 */ "PLUS", - /* 106 */ "MINUS", - /* 107 */ "STAR", - /* 108 */ "SLASH", - /* 109 */ "REM", - /* 110 */ "CONCAT", - /* 111 */ "COLLATE", - /* 112 */ "BITNOT", - /* 113 */ "ON", - /* 114 */ "INDEXED", - /* 115 */ "STRING", - /* 116 */ "JOIN_KW", - /* 117 */ "CONSTRAINT", - /* 118 */ "DEFAULT", - /* 119 */ "NULL", - /* 120 */ "PRIMARY", - /* 121 */ "UNIQUE", - /* 122 */ "CHECK", - /* 123 */ "REFERENCES", - /* 124 */ "AUTOINCR", - /* 125 */ "INSERT", - /* 126 */ "DELETE", - /* 127 */ "UPDATE", - /* 128 */ "SET", - /* 129 */ "DEFERRABLE", - /* 130 */ "FOREIGN", - /* 131 */ "DROP", - /* 132 */ "UNION", - /* 133 */ "ALL", - /* 134 */ "EXCEPT", - /* 135 */ "INTERSECT", - /* 136 */ "SELECT", - /* 137 */ "VALUES", - /* 138 */ "DISTINCT", - /* 139 */ "DOT", - /* 140 */ "FROM", - /* 141 */ "JOIN", - /* 142 */ "USING", - /* 143 */ "ORDER", - /* 144 */ "GROUP", - /* 145 */ "HAVING", - /* 146 */ "LIMIT", - /* 147 */ "WHERE", - /* 148 */ "INTO", - /* 149 */ "NOTHING", - /* 150 */ "FLOAT", - /* 151 */ "BLOB", - /* 152 */ "INTEGER", - /* 153 */ "VARIABLE", - /* 154 */ "CASE", - /* 155 */ "WHEN", - /* 156 */ "THEN", - /* 157 */ "ELSE", - /* 158 */ "INDEX", - /* 159 */ "ALTER", - /* 160 */ "ADD", - /* 161 */ "WINDOW", - /* 162 */ "OVER", - /* 163 */ "FILTER", - /* 164 */ "COLUMN", - /* 165 */ "AGG_FUNCTION", - /* 166 */ "AGG_COLUMN", - /* 167 */ "TRUEFALSE", - /* 168 */ "ISNOT", - /* 169 */ "FUNCTION", - /* 170 */ "UMINUS", - /* 171 */ "UPLUS", - /* 172 */ "TRUTH", - /* 173 */ "REGISTER", - /* 174 */ "VECTOR", - /* 175 */ "SELECT_COLUMN", - /* 176 */ "IF_NULL_ROW", - /* 177 */ "ASTERISK", - /* 178 */ "SPAN", - /* 179 */ "SPACE", - /* 180 */ "ILLEGAL", - /* 181 */ "input", - /* 182 */ "cmdlist", - /* 183 */ "ecmd", - /* 184 */ "cmdx", - /* 185 */ "explain", - /* 186 */ "cmd", - /* 187 */ "transtype", - /* 188 */ "trans_opt", - /* 189 */ "nm", - /* 190 */ "savepoint_opt", - /* 191 */ "create_table", - /* 192 */ "create_table_args", - /* 193 */ "createkw", - /* 194 */ "temp", - /* 195 */ "ifnotexists", - /* 196 */ "dbnm", - /* 197 */ "columnlist", - /* 198 */ "conslist_opt", - /* 199 */ "table_options", - /* 200 */ "select", - /* 201 */ "columnname", - /* 202 */ "carglist", - /* 203 */ "typetoken", - /* 204 */ "typename", - /* 205 */ "signed", - /* 206 */ "plus_num", - /* 207 */ "minus_num", - /* 208 */ "scanpt", - /* 209 */ "scantok", - /* 210 */ "ccons", - /* 211 */ "term", - /* 212 */ "expr", - /* 213 */ "onconf", - /* 214 */ "sortorder", - /* 215 */ "autoinc", - /* 216 */ "eidlist_opt", - /* 217 */ "refargs", - /* 218 */ "defer_subclause", - /* 219 */ "generated", - /* 220 */ "refarg", - /* 221 */ "refact", - /* 222 */ "init_deferred_pred_opt", - /* 223 */ "conslist", - /* 224 */ "tconscomma", - /* 225 */ "tcons", - /* 226 */ "sortlist", - /* 227 */ "eidlist", - /* 228 */ "defer_subclause_opt", - /* 229 */ "orconf", - /* 230 */ "resolvetype", - /* 231 */ "raisetype", - /* 232 */ "ifexists", - /* 233 */ "fullname", - /* 234 */ "selectnowith", - /* 235 */ "oneselect", - /* 236 */ "wqlist", - /* 237 */ "multiselect_op", - /* 238 */ "distinct", - /* 239 */ "selcollist", - /* 240 */ "from", - /* 241 */ "where_opt", - /* 242 */ "groupby_opt", - /* 243 */ "having_opt", - /* 244 */ "orderby_opt", - /* 245 */ "limit_opt", - /* 246 */ "window_clause", - /* 247 */ "values", - /* 248 */ "nexprlist", - /* 249 */ "sclp", - /* 250 */ "as", - /* 251 */ "seltablist", - /* 252 */ "stl_prefix", - /* 253 */ "joinop", - /* 254 */ "indexed_opt", - /* 255 */ "on_opt", - /* 256 */ "using_opt", - /* 257 */ "exprlist", - /* 258 */ "xfullname", - /* 259 */ "idlist", - /* 260 */ "nulls", - /* 261 */ "with", - /* 262 */ "setlist", - /* 263 */ "insert_cmd", - /* 264 */ "idlist_opt", - /* 265 */ "upsert", - /* 266 */ "filter_over", - /* 267 */ "likeop", - /* 268 */ "between_op", - /* 269 */ "in_op", - /* 270 */ "paren_exprlist", - /* 271 */ "case_operand", - /* 272 */ "case_exprlist", - /* 273 */ "case_else", - /* 274 */ "uniqueflag", - /* 275 */ "collate", - /* 276 */ "vinto", - /* 277 */ "nmnum", - /* 278 */ "trigger_decl", - /* 279 */ "trigger_cmd_list", - /* 280 */ "trigger_time", - /* 281 */ "trigger_event", - /* 282 */ "foreach_clause", - /* 283 */ "when_clause", - /* 284 */ "trigger_cmd", - /* 285 */ "trnm", - /* 286 */ "tridxby", - /* 287 */ "database_kw_opt", - /* 288 */ "key_opt", - /* 289 */ "add_column_fullname", - /* 290 */ "kwcolumn_opt", - /* 291 */ "create_vtab", - /* 292 */ "vtabarglist", - /* 293 */ "vtabarg", - /* 294 */ "vtabargtoken", - /* 295 */ "lp", - /* 296 */ "anylist", - /* 297 */ "windowdefn_list", - /* 298 */ "windowdefn", - /* 299 */ "window", - /* 300 */ "frame_opt", - /* 301 */ "part_opt", - /* 302 */ "filter_clause", - /* 303 */ "over_clause", - /* 304 */ "range_or_rows", - /* 305 */ "frame_bound", - /* 306 */ "frame_bound_s", - /* 307 */ "frame_bound_e", - /* 308 */ "frame_exclude_opt", - /* 309 */ "frame_exclude", + /* 97 */ "MATERIALIZED", + /* 98 */ "REINDEX", + /* 99 */ "RENAME", + /* 100 */ "CTIME_KW", + /* 101 */ "ANY", + /* 102 */ "BITAND", + /* 103 */ "BITOR", + /* 104 */ "LSHIFT", + /* 105 */ "RSHIFT", + /* 106 */ "PLUS", + /* 107 */ "MINUS", + /* 108 */ "STAR", + /* 109 */ "SLASH", + /* 110 */ "REM", + /* 111 */ "CONCAT", + /* 112 */ "COLLATE", + /* 113 */ "BITNOT", + /* 114 */ "ON", + /* 115 */ "INDEXED", + /* 116 */ "STRING", + /* 117 */ "JOIN_KW", + /* 118 */ "CONSTRAINT", + /* 119 */ "DEFAULT", + /* 120 */ "NULL", + /* 121 */ "PRIMARY", + /* 122 */ "UNIQUE", + /* 123 */ "CHECK", + /* 124 */ "REFERENCES", + /* 125 */ "AUTOINCR", + /* 126 */ "INSERT", + /* 127 */ "DELETE", + /* 128 */ "UPDATE", + /* 129 */ "SET", + /* 130 */ "DEFERRABLE", + /* 131 */ "FOREIGN", + /* 132 */ "DROP", + /* 133 */ "UNION", + /* 134 */ "ALL", + /* 135 */ "EXCEPT", + /* 136 */ "INTERSECT", + /* 137 */ "SELECT", + /* 138 */ "VALUES", + /* 139 */ "DISTINCT", + /* 140 */ "DOT", + /* 141 */ "FROM", + /* 142 */ "JOIN", + /* 143 */ "USING", + /* 144 */ "ORDER", + /* 145 */ "GROUP", + /* 146 */ "HAVING", + /* 147 */ "LIMIT", + /* 148 */ "WHERE", + /* 149 */ "RETURNING", + /* 150 */ "INTO", + /* 151 */ "NOTHING", + /* 152 */ "FLOAT", + /* 153 */ "BLOB", + /* 154 */ "INTEGER", + /* 155 */ "VARIABLE", + /* 156 */ "CASE", + /* 157 */ "WHEN", + /* 158 */ "THEN", + /* 159 */ "ELSE", + /* 160 */ "INDEX", + /* 161 */ "ALTER", + /* 162 */ "ADD", + /* 163 */ "WINDOW", + /* 164 */ "OVER", + /* 165 */ "FILTER", + /* 166 */ "COLUMN", + /* 167 */ "AGG_FUNCTION", + /* 168 */ "AGG_COLUMN", + /* 169 */ "TRUEFALSE", + /* 170 */ "ISNOT", + /* 171 */ "FUNCTION", + /* 172 */ "UMINUS", + /* 173 */ "UPLUS", + /* 174 */ "TRUTH", + /* 175 */ "REGISTER", + /* 176 */ "VECTOR", + /* 177 */ "SELECT_COLUMN", + /* 178 */ "IF_NULL_ROW", + /* 179 */ "ASTERISK", + /* 180 */ "SPAN", + /* 181 */ "SPACE", + /* 182 */ "ILLEGAL", + /* 183 */ "input", + /* 184 */ "cmdlist", + /* 185 */ "ecmd", + /* 186 */ "cmdx", + /* 187 */ "explain", + /* 188 */ "cmd", + /* 189 */ "transtype", + /* 190 */ "trans_opt", + /* 191 */ "nm", + /* 192 */ "savepoint_opt", + /* 193 */ "create_table", + /* 194 */ "create_table_args", + /* 195 */ "createkw", + /* 196 */ "temp", + /* 197 */ "ifnotexists", + /* 198 */ "dbnm", + /* 199 */ "columnlist", + /* 200 */ "conslist_opt", + /* 201 */ "table_options", + /* 202 */ "select", + /* 203 */ "columnname", + /* 204 */ "carglist", + /* 205 */ "typetoken", + /* 206 */ "typename", + /* 207 */ "signed", + /* 208 */ "plus_num", + /* 209 */ "minus_num", + /* 210 */ "scanpt", + /* 211 */ "scantok", + /* 212 */ "ccons", + /* 213 */ "term", + /* 214 */ "expr", + /* 215 */ "onconf", + /* 216 */ "sortorder", + /* 217 */ "autoinc", + /* 218 */ "eidlist_opt", + /* 219 */ "refargs", + /* 220 */ "defer_subclause", + /* 221 */ "generated", + /* 222 */ "refarg", + /* 223 */ "refact", + /* 224 */ "init_deferred_pred_opt", + /* 225 */ "conslist", + /* 226 */ "tconscomma", + /* 227 */ "tcons", + /* 228 */ "sortlist", + /* 229 */ "eidlist", + /* 230 */ "defer_subclause_opt", + /* 231 */ "orconf", + /* 232 */ "resolvetype", + /* 233 */ "raisetype", + /* 234 */ "ifexists", + /* 235 */ "fullname", + /* 236 */ "selectnowith", + /* 237 */ "oneselect", + /* 238 */ "wqlist", + /* 239 */ "multiselect_op", + /* 240 */ "distinct", + /* 241 */ "selcollist", + /* 242 */ "from", + /* 243 */ "where_opt", + /* 244 */ "groupby_opt", + /* 245 */ "having_opt", + /* 246 */ "orderby_opt", + /* 247 */ "limit_opt", + /* 248 */ "window_clause", + /* 249 */ "values", + /* 250 */ "nexprlist", + /* 251 */ "sclp", + /* 252 */ "as", + /* 253 */ "seltablist", + /* 254 */ "stl_prefix", + /* 255 */ "joinop", + /* 256 */ "indexed_opt", + /* 257 */ "on_opt", + /* 258 */ "using_opt", + /* 259 */ "exprlist", + /* 260 */ "xfullname", + /* 261 */ "idlist", + /* 262 */ "nulls", + /* 263 */ "with", + /* 264 */ "where_opt_ret", + /* 265 */ "setlist", + /* 266 */ "insert_cmd", + /* 267 */ "idlist_opt", + /* 268 */ "upsert", + /* 269 */ "returning", + /* 270 */ "filter_over", + /* 271 */ "likeop", + /* 272 */ "between_op", + /* 273 */ "in_op", + /* 274 */ "paren_exprlist", + /* 275 */ "case_operand", + /* 276 */ "case_exprlist", + /* 277 */ "case_else", + /* 278 */ "uniqueflag", + /* 279 */ "collate", + /* 280 */ "vinto", + /* 281 */ "nmnum", + /* 282 */ "trigger_decl", + /* 283 */ "trigger_cmd_list", + /* 284 */ "trigger_time", + /* 285 */ "trigger_event", + /* 286 */ "foreach_clause", + /* 287 */ "when_clause", + /* 288 */ "trigger_cmd", + /* 289 */ "trnm", + /* 290 */ "tridxby", + /* 291 */ "database_kw_opt", + /* 292 */ "key_opt", + /* 293 */ "add_column_fullname", + /* 294 */ "kwcolumn_opt", + /* 295 */ "create_vtab", + /* 296 */ "vtabarglist", + /* 297 */ "vtabarg", + /* 298 */ "vtabargtoken", + /* 299 */ "lp", + /* 300 */ "anylist", + /* 301 */ "wqitem", + /* 302 */ "wqas", + /* 303 */ "windowdefn_list", + /* 304 */ "windowdefn", + /* 305 */ "window", + /* 306 */ "frame_opt", + /* 307 */ "part_opt", + /* 308 */ "filter_clause", + /* 309 */ "over_clause", + /* 310 */ "range_or_rows", + /* 311 */ "frame_bound", + /* 312 */ "frame_bound_s", + /* 313 */ "frame_bound_e", + /* 314 */ "frame_exclude_opt", + /* 315 */ "frame_exclude", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -156734,243 +158838,256 @@ static const char *const yyRuleName[] = { /* 145 */ "limit_opt ::= LIMIT expr", /* 146 */ "limit_opt ::= LIMIT expr OFFSET expr", /* 147 */ "limit_opt ::= LIMIT expr COMMA expr", - /* 148 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt", + /* 148 */ "cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret", /* 149 */ "where_opt ::=", /* 150 */ "where_opt ::= WHERE expr", - /* 151 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt", - /* 152 */ "setlist ::= setlist COMMA nm EQ expr", - /* 153 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", - /* 154 */ "setlist ::= nm EQ expr", - /* 155 */ "setlist ::= LP idlist RP EQ expr", - /* 156 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", - /* 157 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES", - /* 158 */ "upsert ::=", - /* 159 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt", - /* 160 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING", - /* 161 */ "upsert ::= ON CONFLICT DO NOTHING", - /* 162 */ "insert_cmd ::= INSERT orconf", - /* 163 */ "insert_cmd ::= REPLACE", - /* 164 */ "idlist_opt ::=", - /* 165 */ "idlist_opt ::= LP idlist RP", - /* 166 */ "idlist ::= idlist COMMA nm", - /* 167 */ "idlist ::= nm", - /* 168 */ "expr ::= LP expr RP", - /* 169 */ "expr ::= ID|INDEXED", - /* 170 */ "expr ::= JOIN_KW", - /* 171 */ "expr ::= nm DOT nm", - /* 172 */ "expr ::= nm DOT nm DOT nm", - /* 173 */ "term ::= NULL|FLOAT|BLOB", - /* 174 */ "term ::= STRING", - /* 175 */ "term ::= INTEGER", - /* 176 */ "expr ::= VARIABLE", - /* 177 */ "expr ::= expr COLLATE ID|STRING", - /* 178 */ "expr ::= CAST LP expr AS typetoken RP", - /* 179 */ "expr ::= ID|INDEXED LP distinct exprlist RP", - /* 180 */ "expr ::= ID|INDEXED LP STAR RP", - /* 181 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", - /* 182 */ "expr ::= ID|INDEXED LP STAR RP filter_over", - /* 183 */ "term ::= CTIME_KW", - /* 184 */ "expr ::= LP nexprlist COMMA expr RP", - /* 185 */ "expr ::= expr AND expr", - /* 186 */ "expr ::= expr OR expr", - /* 187 */ "expr ::= expr LT|GT|GE|LE expr", - /* 188 */ "expr ::= expr EQ|NE expr", - /* 189 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", - /* 190 */ "expr ::= expr PLUS|MINUS expr", - /* 191 */ "expr ::= expr STAR|SLASH|REM expr", - /* 192 */ "expr ::= expr CONCAT expr", - /* 193 */ "likeop ::= NOT LIKE_KW|MATCH", - /* 194 */ "expr ::= expr likeop expr", - /* 195 */ "expr ::= expr likeop expr ESCAPE expr", - /* 196 */ "expr ::= expr ISNULL|NOTNULL", - /* 197 */ "expr ::= expr NOT NULL", - /* 198 */ "expr ::= expr IS expr", - /* 199 */ "expr ::= expr IS NOT expr", - /* 200 */ "expr ::= NOT expr", - /* 201 */ "expr ::= BITNOT expr", - /* 202 */ "expr ::= PLUS|MINUS expr", - /* 203 */ "between_op ::= BETWEEN", - /* 204 */ "between_op ::= NOT BETWEEN", - /* 205 */ "expr ::= expr between_op expr AND expr", - /* 206 */ "in_op ::= IN", - /* 207 */ "in_op ::= NOT IN", - /* 208 */ "expr ::= expr in_op LP exprlist RP", - /* 209 */ "expr ::= LP select RP", - /* 210 */ "expr ::= expr in_op LP select RP", - /* 211 */ "expr ::= expr in_op nm dbnm paren_exprlist", - /* 212 */ "expr ::= EXISTS LP select RP", - /* 213 */ "expr ::= CASE case_operand case_exprlist case_else END", - /* 214 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", - /* 215 */ "case_exprlist ::= WHEN expr THEN expr", - /* 216 */ "case_else ::= ELSE expr", - /* 217 */ "case_else ::=", - /* 218 */ "case_operand ::= expr", - /* 219 */ "case_operand ::=", - /* 220 */ "exprlist ::=", - /* 221 */ "nexprlist ::= nexprlist COMMA expr", - /* 222 */ "nexprlist ::= expr", - /* 223 */ "paren_exprlist ::=", - /* 224 */ "paren_exprlist ::= LP exprlist RP", - /* 225 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", - /* 226 */ "uniqueflag ::= UNIQUE", - /* 227 */ "uniqueflag ::=", - /* 228 */ "eidlist_opt ::=", - /* 229 */ "eidlist_opt ::= LP eidlist RP", - /* 230 */ "eidlist ::= eidlist COMMA nm collate sortorder", - /* 231 */ "eidlist ::= nm collate sortorder", - /* 232 */ "collate ::=", - /* 233 */ "collate ::= COLLATE ID|STRING", - /* 234 */ "cmd ::= DROP INDEX ifexists fullname", - /* 235 */ "cmd ::= VACUUM vinto", - /* 236 */ "cmd ::= VACUUM nm vinto", - /* 237 */ "vinto ::= INTO expr", - /* 238 */ "vinto ::=", - /* 239 */ "cmd ::= PRAGMA nm dbnm", - /* 240 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", - /* 241 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", - /* 242 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", - /* 243 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", - /* 244 */ "plus_num ::= PLUS INTEGER|FLOAT", - /* 245 */ "minus_num ::= MINUS INTEGER|FLOAT", - /* 246 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", - /* 247 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", - /* 248 */ "trigger_time ::= BEFORE|AFTER", - /* 249 */ "trigger_time ::= INSTEAD OF", - /* 250 */ "trigger_time ::=", - /* 251 */ "trigger_event ::= DELETE|INSERT", - /* 252 */ "trigger_event ::= UPDATE", - /* 253 */ "trigger_event ::= UPDATE OF idlist", - /* 254 */ "when_clause ::=", - /* 255 */ "when_clause ::= WHEN expr", - /* 256 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", - /* 257 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 258 */ "trnm ::= nm DOT nm", - /* 259 */ "tridxby ::= INDEXED BY nm", - /* 260 */ "tridxby ::= NOT INDEXED", - /* 261 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", - /* 262 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", - /* 263 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", - /* 264 */ "trigger_cmd ::= scanpt select scanpt", - /* 265 */ "expr ::= RAISE LP IGNORE RP", - /* 266 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 267 */ "raisetype ::= ROLLBACK", - /* 268 */ "raisetype ::= ABORT", - /* 269 */ "raisetype ::= FAIL", - /* 270 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 271 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 272 */ "cmd ::= DETACH database_kw_opt expr", - /* 273 */ "key_opt ::=", - /* 274 */ "key_opt ::= KEY expr", - /* 275 */ "cmd ::= REINDEX", - /* 276 */ "cmd ::= REINDEX nm dbnm", - /* 277 */ "cmd ::= ANALYZE", - /* 278 */ "cmd ::= ANALYZE nm dbnm", - /* 279 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 280 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", - /* 281 */ "add_column_fullname ::= fullname", - /* 282 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", - /* 283 */ "cmd ::= create_vtab", - /* 284 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 285 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", - /* 286 */ "vtabarg ::=", - /* 287 */ "vtabargtoken ::= ANY", - /* 288 */ "vtabargtoken ::= lp anylist RP", - /* 289 */ "lp ::= LP", - /* 290 */ "with ::= WITH wqlist", - /* 291 */ "with ::= WITH RECURSIVE wqlist", - /* 292 */ "wqlist ::= nm eidlist_opt AS LP select RP", - /* 293 */ "wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP", - /* 294 */ "windowdefn_list ::= windowdefn", - /* 295 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", - /* 296 */ "windowdefn ::= nm AS LP window RP", - /* 297 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", - /* 298 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", - /* 299 */ "window ::= ORDER BY sortlist frame_opt", - /* 300 */ "window ::= nm ORDER BY sortlist frame_opt", - /* 301 */ "window ::= frame_opt", - /* 302 */ "window ::= nm frame_opt", - /* 303 */ "frame_opt ::=", - /* 304 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", - /* 305 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", - /* 306 */ "range_or_rows ::= RANGE|ROWS|GROUPS", - /* 307 */ "frame_bound_s ::= frame_bound", - /* 308 */ "frame_bound_s ::= UNBOUNDED PRECEDING", - /* 309 */ "frame_bound_e ::= frame_bound", - /* 310 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", - /* 311 */ "frame_bound ::= expr PRECEDING|FOLLOWING", - /* 312 */ "frame_bound ::= CURRENT ROW", - /* 313 */ "frame_exclude_opt ::=", - /* 314 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", - /* 315 */ "frame_exclude ::= NO OTHERS", - /* 316 */ "frame_exclude ::= CURRENT ROW", - /* 317 */ "frame_exclude ::= GROUP|TIES", - /* 318 */ "window_clause ::= WINDOW windowdefn_list", - /* 319 */ "filter_over ::= filter_clause over_clause", - /* 320 */ "filter_over ::= over_clause", - /* 321 */ "filter_over ::= filter_clause", - /* 322 */ "over_clause ::= OVER LP window RP", - /* 323 */ "over_clause ::= OVER nm", - /* 324 */ "filter_clause ::= FILTER LP WHERE expr RP", - /* 325 */ "input ::= cmdlist", - /* 326 */ "cmdlist ::= cmdlist ecmd", - /* 327 */ "cmdlist ::= ecmd", - /* 328 */ "ecmd ::= SEMI", - /* 329 */ "ecmd ::= cmdx SEMI", - /* 330 */ "ecmd ::= explain cmdx SEMI", - /* 331 */ "trans_opt ::=", - /* 332 */ "trans_opt ::= TRANSACTION", - /* 333 */ "trans_opt ::= TRANSACTION nm", - /* 334 */ "savepoint_opt ::= SAVEPOINT", - /* 335 */ "savepoint_opt ::=", - /* 336 */ "cmd ::= create_table create_table_args", - /* 337 */ "columnlist ::= columnlist COMMA columnname carglist", - /* 338 */ "columnlist ::= columnname carglist", - /* 339 */ "nm ::= ID|INDEXED", - /* 340 */ "nm ::= STRING", - /* 341 */ "nm ::= JOIN_KW", - /* 342 */ "typetoken ::= typename", - /* 343 */ "typename ::= ID|STRING", - /* 344 */ "signed ::= plus_num", - /* 345 */ "signed ::= minus_num", - /* 346 */ "carglist ::= carglist ccons", - /* 347 */ "carglist ::=", - /* 348 */ "ccons ::= NULL onconf", - /* 349 */ "ccons ::= GENERATED ALWAYS AS generated", - /* 350 */ "ccons ::= AS generated", - /* 351 */ "conslist_opt ::= COMMA conslist", - /* 352 */ "conslist ::= conslist tconscomma tcons", - /* 353 */ "conslist ::= tcons", - /* 354 */ "tconscomma ::=", - /* 355 */ "defer_subclause_opt ::= defer_subclause", - /* 356 */ "resolvetype ::= raisetype", - /* 357 */ "selectnowith ::= oneselect", - /* 358 */ "oneselect ::= values", - /* 359 */ "sclp ::= selcollist COMMA", - /* 360 */ "as ::= ID|STRING", - /* 361 */ "expr ::= term", - /* 362 */ "likeop ::= LIKE_KW|MATCH", - /* 363 */ "exprlist ::= nexprlist", - /* 364 */ "nmnum ::= plus_num", - /* 365 */ "nmnum ::= nm", - /* 366 */ "nmnum ::= ON", - /* 367 */ "nmnum ::= DELETE", - /* 368 */ "nmnum ::= DEFAULT", - /* 369 */ "plus_num ::= INTEGER|FLOAT", - /* 370 */ "foreach_clause ::=", - /* 371 */ "foreach_clause ::= FOR EACH ROW", - /* 372 */ "trnm ::= nm", - /* 373 */ "tridxby ::=", - /* 374 */ "database_kw_opt ::= DATABASE", - /* 375 */ "database_kw_opt ::=", - /* 376 */ "kwcolumn_opt ::=", - /* 377 */ "kwcolumn_opt ::= COLUMNKW", - /* 378 */ "vtabarglist ::= vtabarg", - /* 379 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 380 */ "vtabarg ::= vtabarg vtabargtoken", - /* 381 */ "anylist ::=", - /* 382 */ "anylist ::= anylist LP anylist RP", - /* 383 */ "anylist ::= anylist ANY", - /* 384 */ "with ::=", + /* 151 */ "where_opt_ret ::=", + /* 152 */ "where_opt_ret ::= WHERE expr", + /* 153 */ "where_opt_ret ::= RETURNING selcollist", + /* 154 */ "where_opt_ret ::= WHERE expr RETURNING selcollist", + /* 155 */ "cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret", + /* 156 */ "setlist ::= setlist COMMA nm EQ expr", + /* 157 */ "setlist ::= setlist COMMA LP idlist RP EQ expr", + /* 158 */ "setlist ::= nm EQ expr", + /* 159 */ "setlist ::= LP idlist RP EQ expr", + /* 160 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert", + /* 161 */ "cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning", + /* 162 */ "upsert ::=", + /* 163 */ "upsert ::= RETURNING selcollist", + /* 164 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert", + /* 165 */ "upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert", + /* 166 */ "upsert ::= ON CONFLICT DO NOTHING returning", + /* 167 */ "upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning", + /* 168 */ "returning ::= RETURNING selcollist", + /* 169 */ "insert_cmd ::= INSERT orconf", + /* 170 */ "insert_cmd ::= REPLACE", + /* 171 */ "idlist_opt ::=", + /* 172 */ "idlist_opt ::= LP idlist RP", + /* 173 */ "idlist ::= idlist COMMA nm", + /* 174 */ "idlist ::= nm", + /* 175 */ "expr ::= LP expr RP", + /* 176 */ "expr ::= ID|INDEXED", + /* 177 */ "expr ::= JOIN_KW", + /* 178 */ "expr ::= nm DOT nm", + /* 179 */ "expr ::= nm DOT nm DOT nm", + /* 180 */ "term ::= NULL|FLOAT|BLOB", + /* 181 */ "term ::= STRING", + /* 182 */ "term ::= INTEGER", + /* 183 */ "expr ::= VARIABLE", + /* 184 */ "expr ::= expr COLLATE ID|STRING", + /* 185 */ "expr ::= CAST LP expr AS typetoken RP", + /* 186 */ "expr ::= ID|INDEXED LP distinct exprlist RP", + /* 187 */ "expr ::= ID|INDEXED LP STAR RP", + /* 188 */ "expr ::= ID|INDEXED LP distinct exprlist RP filter_over", + /* 189 */ "expr ::= ID|INDEXED LP STAR RP filter_over", + /* 190 */ "term ::= CTIME_KW", + /* 191 */ "expr ::= LP nexprlist COMMA expr RP", + /* 192 */ "expr ::= expr AND expr", + /* 193 */ "expr ::= expr OR expr", + /* 194 */ "expr ::= expr LT|GT|GE|LE expr", + /* 195 */ "expr ::= expr EQ|NE expr", + /* 196 */ "expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr", + /* 197 */ "expr ::= expr PLUS|MINUS expr", + /* 198 */ "expr ::= expr STAR|SLASH|REM expr", + /* 199 */ "expr ::= expr CONCAT expr", + /* 200 */ "likeop ::= NOT LIKE_KW|MATCH", + /* 201 */ "expr ::= expr likeop expr", + /* 202 */ "expr ::= expr likeop expr ESCAPE expr", + /* 203 */ "expr ::= expr ISNULL|NOTNULL", + /* 204 */ "expr ::= expr NOT NULL", + /* 205 */ "expr ::= expr IS expr", + /* 206 */ "expr ::= expr IS NOT expr", + /* 207 */ "expr ::= NOT expr", + /* 208 */ "expr ::= BITNOT expr", + /* 209 */ "expr ::= PLUS|MINUS expr", + /* 210 */ "between_op ::= BETWEEN", + /* 211 */ "between_op ::= NOT BETWEEN", + /* 212 */ "expr ::= expr between_op expr AND expr", + /* 213 */ "in_op ::= IN", + /* 214 */ "in_op ::= NOT IN", + /* 215 */ "expr ::= expr in_op LP exprlist RP", + /* 216 */ "expr ::= LP select RP", + /* 217 */ "expr ::= expr in_op LP select RP", + /* 218 */ "expr ::= expr in_op nm dbnm paren_exprlist", + /* 219 */ "expr ::= EXISTS LP select RP", + /* 220 */ "expr ::= CASE case_operand case_exprlist case_else END", + /* 221 */ "case_exprlist ::= case_exprlist WHEN expr THEN expr", + /* 222 */ "case_exprlist ::= WHEN expr THEN expr", + /* 223 */ "case_else ::= ELSE expr", + /* 224 */ "case_else ::=", + /* 225 */ "case_operand ::= expr", + /* 226 */ "case_operand ::=", + /* 227 */ "exprlist ::=", + /* 228 */ "nexprlist ::= nexprlist COMMA expr", + /* 229 */ "nexprlist ::= expr", + /* 230 */ "paren_exprlist ::=", + /* 231 */ "paren_exprlist ::= LP exprlist RP", + /* 232 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt", + /* 233 */ "uniqueflag ::= UNIQUE", + /* 234 */ "uniqueflag ::=", + /* 235 */ "eidlist_opt ::=", + /* 236 */ "eidlist_opt ::= LP eidlist RP", + /* 237 */ "eidlist ::= eidlist COMMA nm collate sortorder", + /* 238 */ "eidlist ::= nm collate sortorder", + /* 239 */ "collate ::=", + /* 240 */ "collate ::= COLLATE ID|STRING", + /* 241 */ "cmd ::= DROP INDEX ifexists fullname", + /* 242 */ "cmd ::= VACUUM vinto", + /* 243 */ "cmd ::= VACUUM nm vinto", + /* 244 */ "vinto ::= INTO expr", + /* 245 */ "vinto ::=", + /* 246 */ "cmd ::= PRAGMA nm dbnm", + /* 247 */ "cmd ::= PRAGMA nm dbnm EQ nmnum", + /* 248 */ "cmd ::= PRAGMA nm dbnm LP nmnum RP", + /* 249 */ "cmd ::= PRAGMA nm dbnm EQ minus_num", + /* 250 */ "cmd ::= PRAGMA nm dbnm LP minus_num RP", + /* 251 */ "plus_num ::= PLUS INTEGER|FLOAT", + /* 252 */ "minus_num ::= MINUS INTEGER|FLOAT", + /* 253 */ "cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END", + /* 254 */ "trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause", + /* 255 */ "trigger_time ::= BEFORE|AFTER", + /* 256 */ "trigger_time ::= INSTEAD OF", + /* 257 */ "trigger_time ::=", + /* 258 */ "trigger_event ::= DELETE|INSERT", + /* 259 */ "trigger_event ::= UPDATE", + /* 260 */ "trigger_event ::= UPDATE OF idlist", + /* 261 */ "when_clause ::=", + /* 262 */ "when_clause ::= WHEN expr", + /* 263 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", + /* 264 */ "trigger_cmd_list ::= trigger_cmd SEMI", + /* 265 */ "trnm ::= nm DOT nm", + /* 266 */ "tridxby ::= INDEXED BY nm", + /* 267 */ "tridxby ::= NOT INDEXED", + /* 268 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt", + /* 269 */ "trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt", + /* 270 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt", + /* 271 */ "trigger_cmd ::= scanpt select scanpt", + /* 272 */ "expr ::= RAISE LP IGNORE RP", + /* 273 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 274 */ "raisetype ::= ROLLBACK", + /* 275 */ "raisetype ::= ABORT", + /* 276 */ "raisetype ::= FAIL", + /* 277 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 278 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 279 */ "cmd ::= DETACH database_kw_opt expr", + /* 280 */ "key_opt ::=", + /* 281 */ "key_opt ::= KEY expr", + /* 282 */ "cmd ::= REINDEX", + /* 283 */ "cmd ::= REINDEX nm dbnm", + /* 284 */ "cmd ::= ANALYZE", + /* 285 */ "cmd ::= ANALYZE nm dbnm", + /* 286 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 287 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist", + /* 288 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm", + /* 289 */ "add_column_fullname ::= fullname", + /* 290 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm", + /* 291 */ "cmd ::= create_vtab", + /* 292 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 293 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm", + /* 294 */ "vtabarg ::=", + /* 295 */ "vtabargtoken ::= ANY", + /* 296 */ "vtabargtoken ::= lp anylist RP", + /* 297 */ "lp ::= LP", + /* 298 */ "with ::= WITH wqlist", + /* 299 */ "with ::= WITH RECURSIVE wqlist", + /* 300 */ "wqas ::= AS", + /* 301 */ "wqas ::= AS MATERIALIZED", + /* 302 */ "wqas ::= AS NOT MATERIALIZED", + /* 303 */ "wqitem ::= nm eidlist_opt wqas LP select RP", + /* 304 */ "wqlist ::= wqitem", + /* 305 */ "wqlist ::= wqlist COMMA wqitem", + /* 306 */ "windowdefn_list ::= windowdefn", + /* 307 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn", + /* 308 */ "windowdefn ::= nm AS LP window RP", + /* 309 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt", + /* 310 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt", + /* 311 */ "window ::= ORDER BY sortlist frame_opt", + /* 312 */ "window ::= nm ORDER BY sortlist frame_opt", + /* 313 */ "window ::= frame_opt", + /* 314 */ "window ::= nm frame_opt", + /* 315 */ "frame_opt ::=", + /* 316 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt", + /* 317 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt", + /* 318 */ "range_or_rows ::= RANGE|ROWS|GROUPS", + /* 319 */ "frame_bound_s ::= frame_bound", + /* 320 */ "frame_bound_s ::= UNBOUNDED PRECEDING", + /* 321 */ "frame_bound_e ::= frame_bound", + /* 322 */ "frame_bound_e ::= UNBOUNDED FOLLOWING", + /* 323 */ "frame_bound ::= expr PRECEDING|FOLLOWING", + /* 324 */ "frame_bound ::= CURRENT ROW", + /* 325 */ "frame_exclude_opt ::=", + /* 326 */ "frame_exclude_opt ::= EXCLUDE frame_exclude", + /* 327 */ "frame_exclude ::= NO OTHERS", + /* 328 */ "frame_exclude ::= CURRENT ROW", + /* 329 */ "frame_exclude ::= GROUP|TIES", + /* 330 */ "window_clause ::= WINDOW windowdefn_list", + /* 331 */ "filter_over ::= filter_clause over_clause", + /* 332 */ "filter_over ::= over_clause", + /* 333 */ "filter_over ::= filter_clause", + /* 334 */ "over_clause ::= OVER LP window RP", + /* 335 */ "over_clause ::= OVER nm", + /* 336 */ "filter_clause ::= FILTER LP WHERE expr RP", + /* 337 */ "input ::= cmdlist", + /* 338 */ "cmdlist ::= cmdlist ecmd", + /* 339 */ "cmdlist ::= ecmd", + /* 340 */ "ecmd ::= SEMI", + /* 341 */ "ecmd ::= cmdx SEMI", + /* 342 */ "ecmd ::= explain cmdx SEMI", + /* 343 */ "trans_opt ::=", + /* 344 */ "trans_opt ::= TRANSACTION", + /* 345 */ "trans_opt ::= TRANSACTION nm", + /* 346 */ "savepoint_opt ::= SAVEPOINT", + /* 347 */ "savepoint_opt ::=", + /* 348 */ "cmd ::= create_table create_table_args", + /* 349 */ "columnlist ::= columnlist COMMA columnname carglist", + /* 350 */ "columnlist ::= columnname carglist", + /* 351 */ "nm ::= ID|INDEXED", + /* 352 */ "nm ::= STRING", + /* 353 */ "nm ::= JOIN_KW", + /* 354 */ "typetoken ::= typename", + /* 355 */ "typename ::= ID|STRING", + /* 356 */ "signed ::= plus_num", + /* 357 */ "signed ::= minus_num", + /* 358 */ "carglist ::= carglist ccons", + /* 359 */ "carglist ::=", + /* 360 */ "ccons ::= NULL onconf", + /* 361 */ "ccons ::= GENERATED ALWAYS AS generated", + /* 362 */ "ccons ::= AS generated", + /* 363 */ "conslist_opt ::= COMMA conslist", + /* 364 */ "conslist ::= conslist tconscomma tcons", + /* 365 */ "conslist ::= tcons", + /* 366 */ "tconscomma ::=", + /* 367 */ "defer_subclause_opt ::= defer_subclause", + /* 368 */ "resolvetype ::= raisetype", + /* 369 */ "selectnowith ::= oneselect", + /* 370 */ "oneselect ::= values", + /* 371 */ "sclp ::= selcollist COMMA", + /* 372 */ "as ::= ID|STRING", + /* 373 */ "returning ::=", + /* 374 */ "expr ::= term", + /* 375 */ "likeop ::= LIKE_KW|MATCH", + /* 376 */ "exprlist ::= nexprlist", + /* 377 */ "nmnum ::= plus_num", + /* 378 */ "nmnum ::= nm", + /* 379 */ "nmnum ::= ON", + /* 380 */ "nmnum ::= DELETE", + /* 381 */ "nmnum ::= DEFAULT", + /* 382 */ "plus_num ::= INTEGER|FLOAT", + /* 383 */ "foreach_clause ::=", + /* 384 */ "foreach_clause ::= FOR EACH ROW", + /* 385 */ "trnm ::= nm", + /* 386 */ "tridxby ::=", + /* 387 */ "database_kw_opt ::= DATABASE", + /* 388 */ "database_kw_opt ::=", + /* 389 */ "kwcolumn_opt ::=", + /* 390 */ "kwcolumn_opt ::= COLUMNKW", + /* 391 */ "vtabarglist ::= vtabarg", + /* 392 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 393 */ "vtabarg ::= vtabarg vtabargtoken", + /* 394 */ "anylist ::=", + /* 395 */ "anylist ::= anylist LP anylist RP", + /* 396 */ "anylist ::= anylist ANY", + /* 397 */ "with ::=", }; #endif /* NDEBUG */ @@ -157096,98 +159213,99 @@ static void yy_destructor( ** inside the C code. */ /********* Begin destructor definitions ***************************************/ - case 200: /* select */ - case 234: /* selectnowith */ - case 235: /* oneselect */ - case 247: /* values */ + case 202: /* select */ + case 236: /* selectnowith */ + case 237: /* oneselect */ + case 249: /* values */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy539)); -} - break; - case 211: /* term */ - case 212: /* expr */ - case 241: /* where_opt */ - case 243: /* having_opt */ - case 255: /* on_opt */ - case 271: /* case_operand */ - case 273: /* case_else */ - case 276: /* vinto */ - case 283: /* when_clause */ - case 288: /* key_opt */ - case 302: /* filter_clause */ +sqlite3SelectDelete(pParse->db, (yypminor->yy307)); +} + break; + case 213: /* term */ + case 214: /* expr */ + case 243: /* where_opt */ + case 245: /* having_opt */ + case 257: /* on_opt */ + case 264: /* where_opt_ret */ + case 275: /* case_operand */ + case 277: /* case_else */ + case 280: /* vinto */ + case 287: /* when_clause */ + case 292: /* key_opt */ + case 308: /* filter_clause */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy202)); -} - break; - case 216: /* eidlist_opt */ - case 226: /* sortlist */ - case 227: /* eidlist */ - case 239: /* selcollist */ - case 242: /* groupby_opt */ - case 244: /* orderby_opt */ - case 248: /* nexprlist */ - case 249: /* sclp */ - case 257: /* exprlist */ - case 262: /* setlist */ - case 270: /* paren_exprlist */ - case 272: /* case_exprlist */ - case 301: /* part_opt */ +sqlite3ExprDelete(pParse->db, (yypminor->yy602)); +} + break; + case 218: /* eidlist_opt */ + case 228: /* sortlist */ + case 229: /* eidlist */ + case 241: /* selcollist */ + case 244: /* groupby_opt */ + case 246: /* orderby_opt */ + case 250: /* nexprlist */ + case 251: /* sclp */ + case 259: /* exprlist */ + case 265: /* setlist */ + case 274: /* paren_exprlist */ + case 276: /* case_exprlist */ + case 307: /* part_opt */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy242)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy338)); } break; - case 233: /* fullname */ - case 240: /* from */ - case 251: /* seltablist */ - case 252: /* stl_prefix */ - case 258: /* xfullname */ + case 235: /* fullname */ + case 242: /* from */ + case 253: /* seltablist */ + case 254: /* stl_prefix */ + case 260: /* xfullname */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy47)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy291)); } break; - case 236: /* wqlist */ + case 238: /* wqlist */ { -sqlite3WithDelete(pParse->db, (yypminor->yy131)); +sqlite3WithDelete(pParse->db, (yypminor->yy195)); } break; - case 246: /* window_clause */ - case 297: /* windowdefn_list */ + case 248: /* window_clause */ + case 303: /* windowdefn_list */ { -sqlite3WindowListDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy19)); } break; - case 256: /* using_opt */ - case 259: /* idlist */ - case 264: /* idlist_opt */ + case 258: /* using_opt */ + case 261: /* idlist */ + case 267: /* idlist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy600)); +sqlite3IdListDelete(pParse->db, (yypminor->yy288)); } break; - case 266: /* filter_over */ - case 298: /* windowdefn */ - case 299: /* window */ - case 300: /* frame_opt */ - case 303: /* over_clause */ + case 270: /* filter_over */ + case 304: /* windowdefn */ + case 305: /* window */ + case 306: /* frame_opt */ + case 309: /* over_clause */ { -sqlite3WindowDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowDelete(pParse->db, (yypminor->yy19)); } break; - case 279: /* trigger_cmd_list */ - case 284: /* trigger_cmd */ + case 283: /* trigger_cmd_list */ + case 288: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy447)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy483)); } break; - case 281: /* trigger_event */ + case 285: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy230).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy50).b); } break; - case 305: /* frame_bound */ - case 306: /* frame_bound_s */ - case 307: /* frame_bound_e */ + case 311: /* frame_bound */ + case 312: /* frame_bound_s */ + case 313: /* frame_bound_e */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy77).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy113).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -157478,391 +159596,404 @@ static void yy_shift( /* For rule J, yyRuleInfoLhs[J] contains the symbol on the left-hand side ** of that rule */ static const YYCODETYPE yyRuleInfoLhs[] = { - 185, /* (0) explain ::= EXPLAIN */ - 185, /* (1) explain ::= EXPLAIN QUERY PLAN */ - 184, /* (2) cmdx ::= cmd */ - 186, /* (3) cmd ::= BEGIN transtype trans_opt */ - 187, /* (4) transtype ::= */ - 187, /* (5) transtype ::= DEFERRED */ - 187, /* (6) transtype ::= IMMEDIATE */ - 187, /* (7) transtype ::= EXCLUSIVE */ - 186, /* (8) cmd ::= COMMIT|END trans_opt */ - 186, /* (9) cmd ::= ROLLBACK trans_opt */ - 186, /* (10) cmd ::= SAVEPOINT nm */ - 186, /* (11) cmd ::= RELEASE savepoint_opt nm */ - 186, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ - 191, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ - 193, /* (14) createkw ::= CREATE */ - 195, /* (15) ifnotexists ::= */ - 195, /* (16) ifnotexists ::= IF NOT EXISTS */ - 194, /* (17) temp ::= TEMP */ - 194, /* (18) temp ::= */ - 192, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ - 192, /* (20) create_table_args ::= AS select */ - 199, /* (21) table_options ::= */ - 199, /* (22) table_options ::= WITHOUT nm */ - 201, /* (23) columnname ::= nm typetoken */ - 203, /* (24) typetoken ::= */ - 203, /* (25) typetoken ::= typename LP signed RP */ - 203, /* (26) typetoken ::= typename LP signed COMMA signed RP */ - 204, /* (27) typename ::= typename ID|STRING */ - 208, /* (28) scanpt ::= */ - 209, /* (29) scantok ::= */ - 210, /* (30) ccons ::= CONSTRAINT nm */ - 210, /* (31) ccons ::= DEFAULT scantok term */ - 210, /* (32) ccons ::= DEFAULT LP expr RP */ - 210, /* (33) ccons ::= DEFAULT PLUS scantok term */ - 210, /* (34) ccons ::= DEFAULT MINUS scantok term */ - 210, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */ - 210, /* (36) ccons ::= NOT NULL onconf */ - 210, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */ - 210, /* (38) ccons ::= UNIQUE onconf */ - 210, /* (39) ccons ::= CHECK LP expr RP */ - 210, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */ - 210, /* (41) ccons ::= defer_subclause */ - 210, /* (42) ccons ::= COLLATE ID|STRING */ - 219, /* (43) generated ::= LP expr RP */ - 219, /* (44) generated ::= LP expr RP ID */ - 215, /* (45) autoinc ::= */ - 215, /* (46) autoinc ::= AUTOINCR */ - 217, /* (47) refargs ::= */ - 217, /* (48) refargs ::= refargs refarg */ - 220, /* (49) refarg ::= MATCH nm */ - 220, /* (50) refarg ::= ON INSERT refact */ - 220, /* (51) refarg ::= ON DELETE refact */ - 220, /* (52) refarg ::= ON UPDATE refact */ - 221, /* (53) refact ::= SET NULL */ - 221, /* (54) refact ::= SET DEFAULT */ - 221, /* (55) refact ::= CASCADE */ - 221, /* (56) refact ::= RESTRICT */ - 221, /* (57) refact ::= NO ACTION */ - 218, /* (58) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - 218, /* (59) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ - 222, /* (60) init_deferred_pred_opt ::= */ - 222, /* (61) init_deferred_pred_opt ::= INITIALLY DEFERRED */ - 222, /* (62) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ - 198, /* (63) conslist_opt ::= */ - 224, /* (64) tconscomma ::= COMMA */ - 225, /* (65) tcons ::= CONSTRAINT nm */ - 225, /* (66) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ - 225, /* (67) tcons ::= UNIQUE LP sortlist RP onconf */ - 225, /* (68) tcons ::= CHECK LP expr RP onconf */ - 225, /* (69) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ - 228, /* (70) defer_subclause_opt ::= */ - 213, /* (71) onconf ::= */ - 213, /* (72) onconf ::= ON CONFLICT resolvetype */ - 229, /* (73) orconf ::= */ - 229, /* (74) orconf ::= OR resolvetype */ - 230, /* (75) resolvetype ::= IGNORE */ - 230, /* (76) resolvetype ::= REPLACE */ - 186, /* (77) cmd ::= DROP TABLE ifexists fullname */ - 232, /* (78) ifexists ::= IF EXISTS */ - 232, /* (79) ifexists ::= */ - 186, /* (80) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ - 186, /* (81) cmd ::= DROP VIEW ifexists fullname */ - 186, /* (82) cmd ::= select */ - 200, /* (83) select ::= WITH wqlist selectnowith */ - 200, /* (84) select ::= WITH RECURSIVE wqlist selectnowith */ - 200, /* (85) select ::= selectnowith */ - 234, /* (86) selectnowith ::= selectnowith multiselect_op oneselect */ - 237, /* (87) multiselect_op ::= UNION */ - 237, /* (88) multiselect_op ::= UNION ALL */ - 237, /* (89) multiselect_op ::= EXCEPT|INTERSECT */ - 235, /* (90) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ - 235, /* (91) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ - 247, /* (92) values ::= VALUES LP nexprlist RP */ - 247, /* (93) values ::= values COMMA LP nexprlist RP */ - 238, /* (94) distinct ::= DISTINCT */ - 238, /* (95) distinct ::= ALL */ - 238, /* (96) distinct ::= */ - 249, /* (97) sclp ::= */ - 239, /* (98) selcollist ::= sclp scanpt expr scanpt as */ - 239, /* (99) selcollist ::= sclp scanpt STAR */ - 239, /* (100) selcollist ::= sclp scanpt nm DOT STAR */ - 250, /* (101) as ::= AS nm */ - 250, /* (102) as ::= */ - 240, /* (103) from ::= */ - 240, /* (104) from ::= FROM seltablist */ - 252, /* (105) stl_prefix ::= seltablist joinop */ - 252, /* (106) stl_prefix ::= */ - 251, /* (107) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ - 251, /* (108) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ - 251, /* (109) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ - 251, /* (110) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ - 196, /* (111) dbnm ::= */ - 196, /* (112) dbnm ::= DOT nm */ - 233, /* (113) fullname ::= nm */ - 233, /* (114) fullname ::= nm DOT nm */ - 258, /* (115) xfullname ::= nm */ - 258, /* (116) xfullname ::= nm DOT nm */ - 258, /* (117) xfullname ::= nm DOT nm AS nm */ - 258, /* (118) xfullname ::= nm AS nm */ - 253, /* (119) joinop ::= COMMA|JOIN */ - 253, /* (120) joinop ::= JOIN_KW JOIN */ - 253, /* (121) joinop ::= JOIN_KW nm JOIN */ - 253, /* (122) joinop ::= JOIN_KW nm nm JOIN */ - 255, /* (123) on_opt ::= ON expr */ - 255, /* (124) on_opt ::= */ - 254, /* (125) indexed_opt ::= */ - 254, /* (126) indexed_opt ::= INDEXED BY nm */ - 254, /* (127) indexed_opt ::= NOT INDEXED */ - 256, /* (128) using_opt ::= USING LP idlist RP */ - 256, /* (129) using_opt ::= */ - 244, /* (130) orderby_opt ::= */ - 244, /* (131) orderby_opt ::= ORDER BY sortlist */ - 226, /* (132) sortlist ::= sortlist COMMA expr sortorder nulls */ - 226, /* (133) sortlist ::= expr sortorder nulls */ - 214, /* (134) sortorder ::= ASC */ - 214, /* (135) sortorder ::= DESC */ - 214, /* (136) sortorder ::= */ - 260, /* (137) nulls ::= NULLS FIRST */ - 260, /* (138) nulls ::= NULLS LAST */ - 260, /* (139) nulls ::= */ - 242, /* (140) groupby_opt ::= */ - 242, /* (141) groupby_opt ::= GROUP BY nexprlist */ - 243, /* (142) having_opt ::= */ - 243, /* (143) having_opt ::= HAVING expr */ - 245, /* (144) limit_opt ::= */ - 245, /* (145) limit_opt ::= LIMIT expr */ - 245, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ - 245, /* (147) limit_opt ::= LIMIT expr COMMA expr */ - 186, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ - 241, /* (149) where_opt ::= */ - 241, /* (150) where_opt ::= WHERE expr */ - 186, /* (151) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ - 262, /* (152) setlist ::= setlist COMMA nm EQ expr */ - 262, /* (153) setlist ::= setlist COMMA LP idlist RP EQ expr */ - 262, /* (154) setlist ::= nm EQ expr */ - 262, /* (155) setlist ::= LP idlist RP EQ expr */ - 186, /* (156) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - 186, /* (157) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - 265, /* (158) upsert ::= */ - 265, /* (159) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - 265, /* (160) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - 265, /* (161) upsert ::= ON CONFLICT DO NOTHING */ - 263, /* (162) insert_cmd ::= INSERT orconf */ - 263, /* (163) insert_cmd ::= REPLACE */ - 264, /* (164) idlist_opt ::= */ - 264, /* (165) idlist_opt ::= LP idlist RP */ - 259, /* (166) idlist ::= idlist COMMA nm */ - 259, /* (167) idlist ::= nm */ - 212, /* (168) expr ::= LP expr RP */ - 212, /* (169) expr ::= ID|INDEXED */ - 212, /* (170) expr ::= JOIN_KW */ - 212, /* (171) expr ::= nm DOT nm */ - 212, /* (172) expr ::= nm DOT nm DOT nm */ - 211, /* (173) term ::= NULL|FLOAT|BLOB */ - 211, /* (174) term ::= STRING */ - 211, /* (175) term ::= INTEGER */ - 212, /* (176) expr ::= VARIABLE */ - 212, /* (177) expr ::= expr COLLATE ID|STRING */ - 212, /* (178) expr ::= CAST LP expr AS typetoken RP */ - 212, /* (179) expr ::= ID|INDEXED LP distinct exprlist RP */ - 212, /* (180) expr ::= ID|INDEXED LP STAR RP */ - 212, /* (181) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - 212, /* (182) expr ::= ID|INDEXED LP STAR RP filter_over */ - 211, /* (183) term ::= CTIME_KW */ - 212, /* (184) expr ::= LP nexprlist COMMA expr RP */ - 212, /* (185) expr ::= expr AND expr */ - 212, /* (186) expr ::= expr OR expr */ - 212, /* (187) expr ::= expr LT|GT|GE|LE expr */ - 212, /* (188) expr ::= expr EQ|NE expr */ - 212, /* (189) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - 212, /* (190) expr ::= expr PLUS|MINUS expr */ - 212, /* (191) expr ::= expr STAR|SLASH|REM expr */ - 212, /* (192) expr ::= expr CONCAT expr */ - 267, /* (193) likeop ::= NOT LIKE_KW|MATCH */ - 212, /* (194) expr ::= expr likeop expr */ - 212, /* (195) expr ::= expr likeop expr ESCAPE expr */ - 212, /* (196) expr ::= expr ISNULL|NOTNULL */ - 212, /* (197) expr ::= expr NOT NULL */ - 212, /* (198) expr ::= expr IS expr */ - 212, /* (199) expr ::= expr IS NOT expr */ - 212, /* (200) expr ::= NOT expr */ - 212, /* (201) expr ::= BITNOT expr */ - 212, /* (202) expr ::= PLUS|MINUS expr */ - 268, /* (203) between_op ::= BETWEEN */ - 268, /* (204) between_op ::= NOT BETWEEN */ - 212, /* (205) expr ::= expr between_op expr AND expr */ - 269, /* (206) in_op ::= IN */ - 269, /* (207) in_op ::= NOT IN */ - 212, /* (208) expr ::= expr in_op LP exprlist RP */ - 212, /* (209) expr ::= LP select RP */ - 212, /* (210) expr ::= expr in_op LP select RP */ - 212, /* (211) expr ::= expr in_op nm dbnm paren_exprlist */ - 212, /* (212) expr ::= EXISTS LP select RP */ - 212, /* (213) expr ::= CASE case_operand case_exprlist case_else END */ - 272, /* (214) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - 272, /* (215) case_exprlist ::= WHEN expr THEN expr */ - 273, /* (216) case_else ::= ELSE expr */ - 273, /* (217) case_else ::= */ - 271, /* (218) case_operand ::= expr */ - 271, /* (219) case_operand ::= */ - 257, /* (220) exprlist ::= */ - 248, /* (221) nexprlist ::= nexprlist COMMA expr */ - 248, /* (222) nexprlist ::= expr */ - 270, /* (223) paren_exprlist ::= */ - 270, /* (224) paren_exprlist ::= LP exprlist RP */ - 186, /* (225) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - 274, /* (226) uniqueflag ::= UNIQUE */ - 274, /* (227) uniqueflag ::= */ - 216, /* (228) eidlist_opt ::= */ - 216, /* (229) eidlist_opt ::= LP eidlist RP */ - 227, /* (230) eidlist ::= eidlist COMMA nm collate sortorder */ - 227, /* (231) eidlist ::= nm collate sortorder */ - 275, /* (232) collate ::= */ - 275, /* (233) collate ::= COLLATE ID|STRING */ - 186, /* (234) cmd ::= DROP INDEX ifexists fullname */ - 186, /* (235) cmd ::= VACUUM vinto */ - 186, /* (236) cmd ::= VACUUM nm vinto */ - 276, /* (237) vinto ::= INTO expr */ - 276, /* (238) vinto ::= */ - 186, /* (239) cmd ::= PRAGMA nm dbnm */ - 186, /* (240) cmd ::= PRAGMA nm dbnm EQ nmnum */ - 186, /* (241) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - 186, /* (242) cmd ::= PRAGMA nm dbnm EQ minus_num */ - 186, /* (243) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - 206, /* (244) plus_num ::= PLUS INTEGER|FLOAT */ - 207, /* (245) minus_num ::= MINUS INTEGER|FLOAT */ - 186, /* (246) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - 278, /* (247) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - 280, /* (248) trigger_time ::= BEFORE|AFTER */ - 280, /* (249) trigger_time ::= INSTEAD OF */ - 280, /* (250) trigger_time ::= */ - 281, /* (251) trigger_event ::= DELETE|INSERT */ - 281, /* (252) trigger_event ::= UPDATE */ - 281, /* (253) trigger_event ::= UPDATE OF idlist */ - 283, /* (254) when_clause ::= */ - 283, /* (255) when_clause ::= WHEN expr */ - 279, /* (256) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - 279, /* (257) trigger_cmd_list ::= trigger_cmd SEMI */ - 285, /* (258) trnm ::= nm DOT nm */ - 286, /* (259) tridxby ::= INDEXED BY nm */ - 286, /* (260) tridxby ::= NOT INDEXED */ - 284, /* (261) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - 284, /* (262) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - 284, /* (263) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - 284, /* (264) trigger_cmd ::= scanpt select scanpt */ - 212, /* (265) expr ::= RAISE LP IGNORE RP */ - 212, /* (266) expr ::= RAISE LP raisetype COMMA nm RP */ - 231, /* (267) raisetype ::= ROLLBACK */ - 231, /* (268) raisetype ::= ABORT */ - 231, /* (269) raisetype ::= FAIL */ - 186, /* (270) cmd ::= DROP TRIGGER ifexists fullname */ - 186, /* (271) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - 186, /* (272) cmd ::= DETACH database_kw_opt expr */ - 288, /* (273) key_opt ::= */ - 288, /* (274) key_opt ::= KEY expr */ - 186, /* (275) cmd ::= REINDEX */ - 186, /* (276) cmd ::= REINDEX nm dbnm */ - 186, /* (277) cmd ::= ANALYZE */ - 186, /* (278) cmd ::= ANALYZE nm dbnm */ - 186, /* (279) cmd ::= ALTER TABLE fullname RENAME TO nm */ - 186, /* (280) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - 289, /* (281) add_column_fullname ::= fullname */ - 186, /* (282) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - 186, /* (283) cmd ::= create_vtab */ - 186, /* (284) cmd ::= create_vtab LP vtabarglist RP */ - 291, /* (285) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 293, /* (286) vtabarg ::= */ - 294, /* (287) vtabargtoken ::= ANY */ - 294, /* (288) vtabargtoken ::= lp anylist RP */ - 295, /* (289) lp ::= LP */ - 261, /* (290) with ::= WITH wqlist */ - 261, /* (291) with ::= WITH RECURSIVE wqlist */ - 236, /* (292) wqlist ::= nm eidlist_opt AS LP select RP */ - 236, /* (293) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - 297, /* (294) windowdefn_list ::= windowdefn */ - 297, /* (295) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - 298, /* (296) windowdefn ::= nm AS LP window RP */ - 299, /* (297) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - 299, /* (298) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - 299, /* (299) window ::= ORDER BY sortlist frame_opt */ - 299, /* (300) window ::= nm ORDER BY sortlist frame_opt */ - 299, /* (301) window ::= frame_opt */ - 299, /* (302) window ::= nm frame_opt */ - 300, /* (303) frame_opt ::= */ - 300, /* (304) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - 300, /* (305) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - 304, /* (306) range_or_rows ::= RANGE|ROWS|GROUPS */ - 306, /* (307) frame_bound_s ::= frame_bound */ - 306, /* (308) frame_bound_s ::= UNBOUNDED PRECEDING */ - 307, /* (309) frame_bound_e ::= frame_bound */ - 307, /* (310) frame_bound_e ::= UNBOUNDED FOLLOWING */ - 305, /* (311) frame_bound ::= expr PRECEDING|FOLLOWING */ - 305, /* (312) frame_bound ::= CURRENT ROW */ - 308, /* (313) frame_exclude_opt ::= */ - 308, /* (314) frame_exclude_opt ::= EXCLUDE frame_exclude */ - 309, /* (315) frame_exclude ::= NO OTHERS */ - 309, /* (316) frame_exclude ::= CURRENT ROW */ - 309, /* (317) frame_exclude ::= GROUP|TIES */ - 246, /* (318) window_clause ::= WINDOW windowdefn_list */ - 266, /* (319) filter_over ::= filter_clause over_clause */ - 266, /* (320) filter_over ::= over_clause */ - 266, /* (321) filter_over ::= filter_clause */ - 303, /* (322) over_clause ::= OVER LP window RP */ - 303, /* (323) over_clause ::= OVER nm */ - 302, /* (324) filter_clause ::= FILTER LP WHERE expr RP */ - 181, /* (325) input ::= cmdlist */ - 182, /* (326) cmdlist ::= cmdlist ecmd */ - 182, /* (327) cmdlist ::= ecmd */ - 183, /* (328) ecmd ::= SEMI */ - 183, /* (329) ecmd ::= cmdx SEMI */ - 183, /* (330) ecmd ::= explain cmdx SEMI */ - 188, /* (331) trans_opt ::= */ - 188, /* (332) trans_opt ::= TRANSACTION */ - 188, /* (333) trans_opt ::= TRANSACTION nm */ - 190, /* (334) savepoint_opt ::= SAVEPOINT */ - 190, /* (335) savepoint_opt ::= */ - 186, /* (336) cmd ::= create_table create_table_args */ - 197, /* (337) columnlist ::= columnlist COMMA columnname carglist */ - 197, /* (338) columnlist ::= columnname carglist */ - 189, /* (339) nm ::= ID|INDEXED */ - 189, /* (340) nm ::= STRING */ - 189, /* (341) nm ::= JOIN_KW */ - 203, /* (342) typetoken ::= typename */ - 204, /* (343) typename ::= ID|STRING */ - 205, /* (344) signed ::= plus_num */ - 205, /* (345) signed ::= minus_num */ - 202, /* (346) carglist ::= carglist ccons */ - 202, /* (347) carglist ::= */ - 210, /* (348) ccons ::= NULL onconf */ - 210, /* (349) ccons ::= GENERATED ALWAYS AS generated */ - 210, /* (350) ccons ::= AS generated */ - 198, /* (351) conslist_opt ::= COMMA conslist */ - 223, /* (352) conslist ::= conslist tconscomma tcons */ - 223, /* (353) conslist ::= tcons */ - 224, /* (354) tconscomma ::= */ - 228, /* (355) defer_subclause_opt ::= defer_subclause */ - 230, /* (356) resolvetype ::= raisetype */ - 234, /* (357) selectnowith ::= oneselect */ - 235, /* (358) oneselect ::= values */ - 249, /* (359) sclp ::= selcollist COMMA */ - 250, /* (360) as ::= ID|STRING */ - 212, /* (361) expr ::= term */ - 267, /* (362) likeop ::= LIKE_KW|MATCH */ - 257, /* (363) exprlist ::= nexprlist */ - 277, /* (364) nmnum ::= plus_num */ - 277, /* (365) nmnum ::= nm */ - 277, /* (366) nmnum ::= ON */ - 277, /* (367) nmnum ::= DELETE */ - 277, /* (368) nmnum ::= DEFAULT */ - 206, /* (369) plus_num ::= INTEGER|FLOAT */ - 282, /* (370) foreach_clause ::= */ - 282, /* (371) foreach_clause ::= FOR EACH ROW */ - 285, /* (372) trnm ::= nm */ - 286, /* (373) tridxby ::= */ - 287, /* (374) database_kw_opt ::= DATABASE */ - 287, /* (375) database_kw_opt ::= */ - 290, /* (376) kwcolumn_opt ::= */ - 290, /* (377) kwcolumn_opt ::= COLUMNKW */ - 292, /* (378) vtabarglist ::= vtabarg */ - 292, /* (379) vtabarglist ::= vtabarglist COMMA vtabarg */ - 293, /* (380) vtabarg ::= vtabarg vtabargtoken */ - 296, /* (381) anylist ::= */ - 296, /* (382) anylist ::= anylist LP anylist RP */ - 296, /* (383) anylist ::= anylist ANY */ - 261, /* (384) with ::= */ + 187, /* (0) explain ::= EXPLAIN */ + 187, /* (1) explain ::= EXPLAIN QUERY PLAN */ + 186, /* (2) cmdx ::= cmd */ + 188, /* (3) cmd ::= BEGIN transtype trans_opt */ + 189, /* (4) transtype ::= */ + 189, /* (5) transtype ::= DEFERRED */ + 189, /* (6) transtype ::= IMMEDIATE */ + 189, /* (7) transtype ::= EXCLUSIVE */ + 188, /* (8) cmd ::= COMMIT|END trans_opt */ + 188, /* (9) cmd ::= ROLLBACK trans_opt */ + 188, /* (10) cmd ::= SAVEPOINT nm */ + 188, /* (11) cmd ::= RELEASE savepoint_opt nm */ + 188, /* (12) cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ + 193, /* (13) create_table ::= createkw temp TABLE ifnotexists nm dbnm */ + 195, /* (14) createkw ::= CREATE */ + 197, /* (15) ifnotexists ::= */ + 197, /* (16) ifnotexists ::= IF NOT EXISTS */ + 196, /* (17) temp ::= TEMP */ + 196, /* (18) temp ::= */ + 194, /* (19) create_table_args ::= LP columnlist conslist_opt RP table_options */ + 194, /* (20) create_table_args ::= AS select */ + 201, /* (21) table_options ::= */ + 201, /* (22) table_options ::= WITHOUT nm */ + 203, /* (23) columnname ::= nm typetoken */ + 205, /* (24) typetoken ::= */ + 205, /* (25) typetoken ::= typename LP signed RP */ + 205, /* (26) typetoken ::= typename LP signed COMMA signed RP */ + 206, /* (27) typename ::= typename ID|STRING */ + 210, /* (28) scanpt ::= */ + 211, /* (29) scantok ::= */ + 212, /* (30) ccons ::= CONSTRAINT nm */ + 212, /* (31) ccons ::= DEFAULT scantok term */ + 212, /* (32) ccons ::= DEFAULT LP expr RP */ + 212, /* (33) ccons ::= DEFAULT PLUS scantok term */ + 212, /* (34) ccons ::= DEFAULT MINUS scantok term */ + 212, /* (35) ccons ::= DEFAULT scantok ID|INDEXED */ + 212, /* (36) ccons ::= NOT NULL onconf */ + 212, /* (37) ccons ::= PRIMARY KEY sortorder onconf autoinc */ + 212, /* (38) ccons ::= UNIQUE onconf */ + 212, /* (39) ccons ::= CHECK LP expr RP */ + 212, /* (40) ccons ::= REFERENCES nm eidlist_opt refargs */ + 212, /* (41) ccons ::= defer_subclause */ + 212, /* (42) ccons ::= COLLATE ID|STRING */ + 221, /* (43) generated ::= LP expr RP */ + 221, /* (44) generated ::= LP expr RP ID */ + 217, /* (45) autoinc ::= */ + 217, /* (46) autoinc ::= AUTOINCR */ + 219, /* (47) refargs ::= */ + 219, /* (48) refargs ::= refargs refarg */ + 222, /* (49) refarg ::= MATCH nm */ + 222, /* (50) refarg ::= ON INSERT refact */ + 222, /* (51) refarg ::= ON DELETE refact */ + 222, /* (52) refarg ::= ON UPDATE refact */ + 223, /* (53) refact ::= SET NULL */ + 223, /* (54) refact ::= SET DEFAULT */ + 223, /* (55) refact ::= CASCADE */ + 223, /* (56) refact ::= RESTRICT */ + 223, /* (57) refact ::= NO ACTION */ + 220, /* (58) defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ + 220, /* (59) defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ + 224, /* (60) init_deferred_pred_opt ::= */ + 224, /* (61) init_deferred_pred_opt ::= INITIALLY DEFERRED */ + 224, /* (62) init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ + 200, /* (63) conslist_opt ::= */ + 226, /* (64) tconscomma ::= COMMA */ + 227, /* (65) tcons ::= CONSTRAINT nm */ + 227, /* (66) tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ + 227, /* (67) tcons ::= UNIQUE LP sortlist RP onconf */ + 227, /* (68) tcons ::= CHECK LP expr RP onconf */ + 227, /* (69) tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ + 230, /* (70) defer_subclause_opt ::= */ + 215, /* (71) onconf ::= */ + 215, /* (72) onconf ::= ON CONFLICT resolvetype */ + 231, /* (73) orconf ::= */ + 231, /* (74) orconf ::= OR resolvetype */ + 232, /* (75) resolvetype ::= IGNORE */ + 232, /* (76) resolvetype ::= REPLACE */ + 188, /* (77) cmd ::= DROP TABLE ifexists fullname */ + 234, /* (78) ifexists ::= IF EXISTS */ + 234, /* (79) ifexists ::= */ + 188, /* (80) cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ + 188, /* (81) cmd ::= DROP VIEW ifexists fullname */ + 188, /* (82) cmd ::= select */ + 202, /* (83) select ::= WITH wqlist selectnowith */ + 202, /* (84) select ::= WITH RECURSIVE wqlist selectnowith */ + 202, /* (85) select ::= selectnowith */ + 236, /* (86) selectnowith ::= selectnowith multiselect_op oneselect */ + 239, /* (87) multiselect_op ::= UNION */ + 239, /* (88) multiselect_op ::= UNION ALL */ + 239, /* (89) multiselect_op ::= EXCEPT|INTERSECT */ + 237, /* (90) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ + 237, /* (91) oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ + 249, /* (92) values ::= VALUES LP nexprlist RP */ + 249, /* (93) values ::= values COMMA LP nexprlist RP */ + 240, /* (94) distinct ::= DISTINCT */ + 240, /* (95) distinct ::= ALL */ + 240, /* (96) distinct ::= */ + 251, /* (97) sclp ::= */ + 241, /* (98) selcollist ::= sclp scanpt expr scanpt as */ + 241, /* (99) selcollist ::= sclp scanpt STAR */ + 241, /* (100) selcollist ::= sclp scanpt nm DOT STAR */ + 252, /* (101) as ::= AS nm */ + 252, /* (102) as ::= */ + 242, /* (103) from ::= */ + 242, /* (104) from ::= FROM seltablist */ + 254, /* (105) stl_prefix ::= seltablist joinop */ + 254, /* (106) stl_prefix ::= */ + 253, /* (107) seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ + 253, /* (108) seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ + 253, /* (109) seltablist ::= stl_prefix LP select RP as on_opt using_opt */ + 253, /* (110) seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ + 198, /* (111) dbnm ::= */ + 198, /* (112) dbnm ::= DOT nm */ + 235, /* (113) fullname ::= nm */ + 235, /* (114) fullname ::= nm DOT nm */ + 260, /* (115) xfullname ::= nm */ + 260, /* (116) xfullname ::= nm DOT nm */ + 260, /* (117) xfullname ::= nm DOT nm AS nm */ + 260, /* (118) xfullname ::= nm AS nm */ + 255, /* (119) joinop ::= COMMA|JOIN */ + 255, /* (120) joinop ::= JOIN_KW JOIN */ + 255, /* (121) joinop ::= JOIN_KW nm JOIN */ + 255, /* (122) joinop ::= JOIN_KW nm nm JOIN */ + 257, /* (123) on_opt ::= ON expr */ + 257, /* (124) on_opt ::= */ + 256, /* (125) indexed_opt ::= */ + 256, /* (126) indexed_opt ::= INDEXED BY nm */ + 256, /* (127) indexed_opt ::= NOT INDEXED */ + 258, /* (128) using_opt ::= USING LP idlist RP */ + 258, /* (129) using_opt ::= */ + 246, /* (130) orderby_opt ::= */ + 246, /* (131) orderby_opt ::= ORDER BY sortlist */ + 228, /* (132) sortlist ::= sortlist COMMA expr sortorder nulls */ + 228, /* (133) sortlist ::= expr sortorder nulls */ + 216, /* (134) sortorder ::= ASC */ + 216, /* (135) sortorder ::= DESC */ + 216, /* (136) sortorder ::= */ + 262, /* (137) nulls ::= NULLS FIRST */ + 262, /* (138) nulls ::= NULLS LAST */ + 262, /* (139) nulls ::= */ + 244, /* (140) groupby_opt ::= */ + 244, /* (141) groupby_opt ::= GROUP BY nexprlist */ + 245, /* (142) having_opt ::= */ + 245, /* (143) having_opt ::= HAVING expr */ + 247, /* (144) limit_opt ::= */ + 247, /* (145) limit_opt ::= LIMIT expr */ + 247, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ + 247, /* (147) limit_opt ::= LIMIT expr COMMA expr */ + 188, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ + 243, /* (149) where_opt ::= */ + 243, /* (150) where_opt ::= WHERE expr */ + 264, /* (151) where_opt_ret ::= */ + 264, /* (152) where_opt_ret ::= WHERE expr */ + 264, /* (153) where_opt_ret ::= RETURNING selcollist */ + 264, /* (154) where_opt_ret ::= WHERE expr RETURNING selcollist */ + 188, /* (155) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + 265, /* (156) setlist ::= setlist COMMA nm EQ expr */ + 265, /* (157) setlist ::= setlist COMMA LP idlist RP EQ expr */ + 265, /* (158) setlist ::= nm EQ expr */ + 265, /* (159) setlist ::= LP idlist RP EQ expr */ + 188, /* (160) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + 188, /* (161) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 268, /* (162) upsert ::= */ + 268, /* (163) upsert ::= RETURNING selcollist */ + 268, /* (164) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + 268, /* (165) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + 268, /* (166) upsert ::= ON CONFLICT DO NOTHING returning */ + 268, /* (167) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + 269, /* (168) returning ::= RETURNING selcollist */ + 266, /* (169) insert_cmd ::= INSERT orconf */ + 266, /* (170) insert_cmd ::= REPLACE */ + 267, /* (171) idlist_opt ::= */ + 267, /* (172) idlist_opt ::= LP idlist RP */ + 261, /* (173) idlist ::= idlist COMMA nm */ + 261, /* (174) idlist ::= nm */ + 214, /* (175) expr ::= LP expr RP */ + 214, /* (176) expr ::= ID|INDEXED */ + 214, /* (177) expr ::= JOIN_KW */ + 214, /* (178) expr ::= nm DOT nm */ + 214, /* (179) expr ::= nm DOT nm DOT nm */ + 213, /* (180) term ::= NULL|FLOAT|BLOB */ + 213, /* (181) term ::= STRING */ + 213, /* (182) term ::= INTEGER */ + 214, /* (183) expr ::= VARIABLE */ + 214, /* (184) expr ::= expr COLLATE ID|STRING */ + 214, /* (185) expr ::= CAST LP expr AS typetoken RP */ + 214, /* (186) expr ::= ID|INDEXED LP distinct exprlist RP */ + 214, /* (187) expr ::= ID|INDEXED LP STAR RP */ + 214, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + 214, /* (189) expr ::= ID|INDEXED LP STAR RP filter_over */ + 213, /* (190) term ::= CTIME_KW */ + 214, /* (191) expr ::= LP nexprlist COMMA expr RP */ + 214, /* (192) expr ::= expr AND expr */ + 214, /* (193) expr ::= expr OR expr */ + 214, /* (194) expr ::= expr LT|GT|GE|LE expr */ + 214, /* (195) expr ::= expr EQ|NE expr */ + 214, /* (196) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + 214, /* (197) expr ::= expr PLUS|MINUS expr */ + 214, /* (198) expr ::= expr STAR|SLASH|REM expr */ + 214, /* (199) expr ::= expr CONCAT expr */ + 271, /* (200) likeop ::= NOT LIKE_KW|MATCH */ + 214, /* (201) expr ::= expr likeop expr */ + 214, /* (202) expr ::= expr likeop expr ESCAPE expr */ + 214, /* (203) expr ::= expr ISNULL|NOTNULL */ + 214, /* (204) expr ::= expr NOT NULL */ + 214, /* (205) expr ::= expr IS expr */ + 214, /* (206) expr ::= expr IS NOT expr */ + 214, /* (207) expr ::= NOT expr */ + 214, /* (208) expr ::= BITNOT expr */ + 214, /* (209) expr ::= PLUS|MINUS expr */ + 272, /* (210) between_op ::= BETWEEN */ + 272, /* (211) between_op ::= NOT BETWEEN */ + 214, /* (212) expr ::= expr between_op expr AND expr */ + 273, /* (213) in_op ::= IN */ + 273, /* (214) in_op ::= NOT IN */ + 214, /* (215) expr ::= expr in_op LP exprlist RP */ + 214, /* (216) expr ::= LP select RP */ + 214, /* (217) expr ::= expr in_op LP select RP */ + 214, /* (218) expr ::= expr in_op nm dbnm paren_exprlist */ + 214, /* (219) expr ::= EXISTS LP select RP */ + 214, /* (220) expr ::= CASE case_operand case_exprlist case_else END */ + 276, /* (221) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + 276, /* (222) case_exprlist ::= WHEN expr THEN expr */ + 277, /* (223) case_else ::= ELSE expr */ + 277, /* (224) case_else ::= */ + 275, /* (225) case_operand ::= expr */ + 275, /* (226) case_operand ::= */ + 259, /* (227) exprlist ::= */ + 250, /* (228) nexprlist ::= nexprlist COMMA expr */ + 250, /* (229) nexprlist ::= expr */ + 274, /* (230) paren_exprlist ::= */ + 274, /* (231) paren_exprlist ::= LP exprlist RP */ + 188, /* (232) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + 278, /* (233) uniqueflag ::= UNIQUE */ + 278, /* (234) uniqueflag ::= */ + 218, /* (235) eidlist_opt ::= */ + 218, /* (236) eidlist_opt ::= LP eidlist RP */ + 229, /* (237) eidlist ::= eidlist COMMA nm collate sortorder */ + 229, /* (238) eidlist ::= nm collate sortorder */ + 279, /* (239) collate ::= */ + 279, /* (240) collate ::= COLLATE ID|STRING */ + 188, /* (241) cmd ::= DROP INDEX ifexists fullname */ + 188, /* (242) cmd ::= VACUUM vinto */ + 188, /* (243) cmd ::= VACUUM nm vinto */ + 280, /* (244) vinto ::= INTO expr */ + 280, /* (245) vinto ::= */ + 188, /* (246) cmd ::= PRAGMA nm dbnm */ + 188, /* (247) cmd ::= PRAGMA nm dbnm EQ nmnum */ + 188, /* (248) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + 188, /* (249) cmd ::= PRAGMA nm dbnm EQ minus_num */ + 188, /* (250) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + 208, /* (251) plus_num ::= PLUS INTEGER|FLOAT */ + 209, /* (252) minus_num ::= MINUS INTEGER|FLOAT */ + 188, /* (253) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + 282, /* (254) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + 284, /* (255) trigger_time ::= BEFORE|AFTER */ + 284, /* (256) trigger_time ::= INSTEAD OF */ + 284, /* (257) trigger_time ::= */ + 285, /* (258) trigger_event ::= DELETE|INSERT */ + 285, /* (259) trigger_event ::= UPDATE */ + 285, /* (260) trigger_event ::= UPDATE OF idlist */ + 287, /* (261) when_clause ::= */ + 287, /* (262) when_clause ::= WHEN expr */ + 283, /* (263) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + 283, /* (264) trigger_cmd_list ::= trigger_cmd SEMI */ + 289, /* (265) trnm ::= nm DOT nm */ + 290, /* (266) tridxby ::= INDEXED BY nm */ + 290, /* (267) tridxby ::= NOT INDEXED */ + 288, /* (268) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + 288, /* (269) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + 288, /* (270) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + 288, /* (271) trigger_cmd ::= scanpt select scanpt */ + 214, /* (272) expr ::= RAISE LP IGNORE RP */ + 214, /* (273) expr ::= RAISE LP raisetype COMMA nm RP */ + 233, /* (274) raisetype ::= ROLLBACK */ + 233, /* (275) raisetype ::= ABORT */ + 233, /* (276) raisetype ::= FAIL */ + 188, /* (277) cmd ::= DROP TRIGGER ifexists fullname */ + 188, /* (278) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + 188, /* (279) cmd ::= DETACH database_kw_opt expr */ + 292, /* (280) key_opt ::= */ + 292, /* (281) key_opt ::= KEY expr */ + 188, /* (282) cmd ::= REINDEX */ + 188, /* (283) cmd ::= REINDEX nm dbnm */ + 188, /* (284) cmd ::= ANALYZE */ + 188, /* (285) cmd ::= ANALYZE nm dbnm */ + 188, /* (286) cmd ::= ALTER TABLE fullname RENAME TO nm */ + 188, /* (287) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + 188, /* (288) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + 293, /* (289) add_column_fullname ::= fullname */ + 188, /* (290) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + 188, /* (291) cmd ::= create_vtab */ + 188, /* (292) cmd ::= create_vtab LP vtabarglist RP */ + 295, /* (293) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 297, /* (294) vtabarg ::= */ + 298, /* (295) vtabargtoken ::= ANY */ + 298, /* (296) vtabargtoken ::= lp anylist RP */ + 299, /* (297) lp ::= LP */ + 263, /* (298) with ::= WITH wqlist */ + 263, /* (299) with ::= WITH RECURSIVE wqlist */ + 302, /* (300) wqas ::= AS */ + 302, /* (301) wqas ::= AS MATERIALIZED */ + 302, /* (302) wqas ::= AS NOT MATERIALIZED */ + 301, /* (303) wqitem ::= nm eidlist_opt wqas LP select RP */ + 238, /* (304) wqlist ::= wqitem */ + 238, /* (305) wqlist ::= wqlist COMMA wqitem */ + 303, /* (306) windowdefn_list ::= windowdefn */ + 303, /* (307) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + 304, /* (308) windowdefn ::= nm AS LP window RP */ + 305, /* (309) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + 305, /* (310) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + 305, /* (311) window ::= ORDER BY sortlist frame_opt */ + 305, /* (312) window ::= nm ORDER BY sortlist frame_opt */ + 305, /* (313) window ::= frame_opt */ + 305, /* (314) window ::= nm frame_opt */ + 306, /* (315) frame_opt ::= */ + 306, /* (316) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + 306, /* (317) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + 310, /* (318) range_or_rows ::= RANGE|ROWS|GROUPS */ + 312, /* (319) frame_bound_s ::= frame_bound */ + 312, /* (320) frame_bound_s ::= UNBOUNDED PRECEDING */ + 313, /* (321) frame_bound_e ::= frame_bound */ + 313, /* (322) frame_bound_e ::= UNBOUNDED FOLLOWING */ + 311, /* (323) frame_bound ::= expr PRECEDING|FOLLOWING */ + 311, /* (324) frame_bound ::= CURRENT ROW */ + 314, /* (325) frame_exclude_opt ::= */ + 314, /* (326) frame_exclude_opt ::= EXCLUDE frame_exclude */ + 315, /* (327) frame_exclude ::= NO OTHERS */ + 315, /* (328) frame_exclude ::= CURRENT ROW */ + 315, /* (329) frame_exclude ::= GROUP|TIES */ + 248, /* (330) window_clause ::= WINDOW windowdefn_list */ + 270, /* (331) filter_over ::= filter_clause over_clause */ + 270, /* (332) filter_over ::= over_clause */ + 270, /* (333) filter_over ::= filter_clause */ + 309, /* (334) over_clause ::= OVER LP window RP */ + 309, /* (335) over_clause ::= OVER nm */ + 308, /* (336) filter_clause ::= FILTER LP WHERE expr RP */ + 183, /* (337) input ::= cmdlist */ + 184, /* (338) cmdlist ::= cmdlist ecmd */ + 184, /* (339) cmdlist ::= ecmd */ + 185, /* (340) ecmd ::= SEMI */ + 185, /* (341) ecmd ::= cmdx SEMI */ + 185, /* (342) ecmd ::= explain cmdx SEMI */ + 190, /* (343) trans_opt ::= */ + 190, /* (344) trans_opt ::= TRANSACTION */ + 190, /* (345) trans_opt ::= TRANSACTION nm */ + 192, /* (346) savepoint_opt ::= SAVEPOINT */ + 192, /* (347) savepoint_opt ::= */ + 188, /* (348) cmd ::= create_table create_table_args */ + 199, /* (349) columnlist ::= columnlist COMMA columnname carglist */ + 199, /* (350) columnlist ::= columnname carglist */ + 191, /* (351) nm ::= ID|INDEXED */ + 191, /* (352) nm ::= STRING */ + 191, /* (353) nm ::= JOIN_KW */ + 205, /* (354) typetoken ::= typename */ + 206, /* (355) typename ::= ID|STRING */ + 207, /* (356) signed ::= plus_num */ + 207, /* (357) signed ::= minus_num */ + 204, /* (358) carglist ::= carglist ccons */ + 204, /* (359) carglist ::= */ + 212, /* (360) ccons ::= NULL onconf */ + 212, /* (361) ccons ::= GENERATED ALWAYS AS generated */ + 212, /* (362) ccons ::= AS generated */ + 200, /* (363) conslist_opt ::= COMMA conslist */ + 225, /* (364) conslist ::= conslist tconscomma tcons */ + 225, /* (365) conslist ::= tcons */ + 226, /* (366) tconscomma ::= */ + 230, /* (367) defer_subclause_opt ::= defer_subclause */ + 232, /* (368) resolvetype ::= raisetype */ + 236, /* (369) selectnowith ::= oneselect */ + 237, /* (370) oneselect ::= values */ + 251, /* (371) sclp ::= selcollist COMMA */ + 252, /* (372) as ::= ID|STRING */ + 269, /* (373) returning ::= */ + 214, /* (374) expr ::= term */ + 271, /* (375) likeop ::= LIKE_KW|MATCH */ + 259, /* (376) exprlist ::= nexprlist */ + 281, /* (377) nmnum ::= plus_num */ + 281, /* (378) nmnum ::= nm */ + 281, /* (379) nmnum ::= ON */ + 281, /* (380) nmnum ::= DELETE */ + 281, /* (381) nmnum ::= DEFAULT */ + 208, /* (382) plus_num ::= INTEGER|FLOAT */ + 286, /* (383) foreach_clause ::= */ + 286, /* (384) foreach_clause ::= FOR EACH ROW */ + 289, /* (385) trnm ::= nm */ + 290, /* (386) tridxby ::= */ + 291, /* (387) database_kw_opt ::= DATABASE */ + 291, /* (388) database_kw_opt ::= */ + 294, /* (389) kwcolumn_opt ::= */ + 294, /* (390) kwcolumn_opt ::= COLUMNKW */ + 296, /* (391) vtabarglist ::= vtabarg */ + 296, /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ + 297, /* (393) vtabarg ::= vtabarg vtabargtoken */ + 300, /* (394) anylist ::= */ + 300, /* (395) anylist ::= anylist LP anylist RP */ + 300, /* (396) anylist ::= anylist ANY */ + 263, /* (397) with ::= */ }; /* For rule J, yyRuleInfoNRhs[J] contains the negative of the number @@ -158016,243 +160147,256 @@ static const signed char yyRuleInfoNRhs[] = { -2, /* (145) limit_opt ::= LIMIT expr */ -4, /* (146) limit_opt ::= LIMIT expr OFFSET expr */ -4, /* (147) limit_opt ::= LIMIT expr COMMA expr */ - -6, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + -6, /* (148) cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ 0, /* (149) where_opt ::= */ -2, /* (150) where_opt ::= WHERE expr */ - -9, /* (151) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ - -5, /* (152) setlist ::= setlist COMMA nm EQ expr */ - -7, /* (153) setlist ::= setlist COMMA LP idlist RP EQ expr */ - -3, /* (154) setlist ::= nm EQ expr */ - -5, /* (155) setlist ::= LP idlist RP EQ expr */ - -7, /* (156) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ - -7, /* (157) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ - 0, /* (158) upsert ::= */ - -11, /* (159) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ - -8, /* (160) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ - -4, /* (161) upsert ::= ON CONFLICT DO NOTHING */ - -2, /* (162) insert_cmd ::= INSERT orconf */ - -1, /* (163) insert_cmd ::= REPLACE */ - 0, /* (164) idlist_opt ::= */ - -3, /* (165) idlist_opt ::= LP idlist RP */ - -3, /* (166) idlist ::= idlist COMMA nm */ - -1, /* (167) idlist ::= nm */ - -3, /* (168) expr ::= LP expr RP */ - -1, /* (169) expr ::= ID|INDEXED */ - -1, /* (170) expr ::= JOIN_KW */ - -3, /* (171) expr ::= nm DOT nm */ - -5, /* (172) expr ::= nm DOT nm DOT nm */ - -1, /* (173) term ::= NULL|FLOAT|BLOB */ - -1, /* (174) term ::= STRING */ - -1, /* (175) term ::= INTEGER */ - -1, /* (176) expr ::= VARIABLE */ - -3, /* (177) expr ::= expr COLLATE ID|STRING */ - -6, /* (178) expr ::= CAST LP expr AS typetoken RP */ - -5, /* (179) expr ::= ID|INDEXED LP distinct exprlist RP */ - -4, /* (180) expr ::= ID|INDEXED LP STAR RP */ - -6, /* (181) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ - -5, /* (182) expr ::= ID|INDEXED LP STAR RP filter_over */ - -1, /* (183) term ::= CTIME_KW */ - -5, /* (184) expr ::= LP nexprlist COMMA expr RP */ - -3, /* (185) expr ::= expr AND expr */ - -3, /* (186) expr ::= expr OR expr */ - -3, /* (187) expr ::= expr LT|GT|GE|LE expr */ - -3, /* (188) expr ::= expr EQ|NE expr */ - -3, /* (189) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ - -3, /* (190) expr ::= expr PLUS|MINUS expr */ - -3, /* (191) expr ::= expr STAR|SLASH|REM expr */ - -3, /* (192) expr ::= expr CONCAT expr */ - -2, /* (193) likeop ::= NOT LIKE_KW|MATCH */ - -3, /* (194) expr ::= expr likeop expr */ - -5, /* (195) expr ::= expr likeop expr ESCAPE expr */ - -2, /* (196) expr ::= expr ISNULL|NOTNULL */ - -3, /* (197) expr ::= expr NOT NULL */ - -3, /* (198) expr ::= expr IS expr */ - -4, /* (199) expr ::= expr IS NOT expr */ - -2, /* (200) expr ::= NOT expr */ - -2, /* (201) expr ::= BITNOT expr */ - -2, /* (202) expr ::= PLUS|MINUS expr */ - -1, /* (203) between_op ::= BETWEEN */ - -2, /* (204) between_op ::= NOT BETWEEN */ - -5, /* (205) expr ::= expr between_op expr AND expr */ - -1, /* (206) in_op ::= IN */ - -2, /* (207) in_op ::= NOT IN */ - -5, /* (208) expr ::= expr in_op LP exprlist RP */ - -3, /* (209) expr ::= LP select RP */ - -5, /* (210) expr ::= expr in_op LP select RP */ - -5, /* (211) expr ::= expr in_op nm dbnm paren_exprlist */ - -4, /* (212) expr ::= EXISTS LP select RP */ - -5, /* (213) expr ::= CASE case_operand case_exprlist case_else END */ - -5, /* (214) case_exprlist ::= case_exprlist WHEN expr THEN expr */ - -4, /* (215) case_exprlist ::= WHEN expr THEN expr */ - -2, /* (216) case_else ::= ELSE expr */ - 0, /* (217) case_else ::= */ - -1, /* (218) case_operand ::= expr */ - 0, /* (219) case_operand ::= */ - 0, /* (220) exprlist ::= */ - -3, /* (221) nexprlist ::= nexprlist COMMA expr */ - -1, /* (222) nexprlist ::= expr */ - 0, /* (223) paren_exprlist ::= */ - -3, /* (224) paren_exprlist ::= LP exprlist RP */ - -12, /* (225) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ - -1, /* (226) uniqueflag ::= UNIQUE */ - 0, /* (227) uniqueflag ::= */ - 0, /* (228) eidlist_opt ::= */ - -3, /* (229) eidlist_opt ::= LP eidlist RP */ - -5, /* (230) eidlist ::= eidlist COMMA nm collate sortorder */ - -3, /* (231) eidlist ::= nm collate sortorder */ - 0, /* (232) collate ::= */ - -2, /* (233) collate ::= COLLATE ID|STRING */ - -4, /* (234) cmd ::= DROP INDEX ifexists fullname */ - -2, /* (235) cmd ::= VACUUM vinto */ - -3, /* (236) cmd ::= VACUUM nm vinto */ - -2, /* (237) vinto ::= INTO expr */ - 0, /* (238) vinto ::= */ - -3, /* (239) cmd ::= PRAGMA nm dbnm */ - -5, /* (240) cmd ::= PRAGMA nm dbnm EQ nmnum */ - -6, /* (241) cmd ::= PRAGMA nm dbnm LP nmnum RP */ - -5, /* (242) cmd ::= PRAGMA nm dbnm EQ minus_num */ - -6, /* (243) cmd ::= PRAGMA nm dbnm LP minus_num RP */ - -2, /* (244) plus_num ::= PLUS INTEGER|FLOAT */ - -2, /* (245) minus_num ::= MINUS INTEGER|FLOAT */ - -5, /* (246) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ - -11, /* (247) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ - -1, /* (248) trigger_time ::= BEFORE|AFTER */ - -2, /* (249) trigger_time ::= INSTEAD OF */ - 0, /* (250) trigger_time ::= */ - -1, /* (251) trigger_event ::= DELETE|INSERT */ - -1, /* (252) trigger_event ::= UPDATE */ - -3, /* (253) trigger_event ::= UPDATE OF idlist */ - 0, /* (254) when_clause ::= */ - -2, /* (255) when_clause ::= WHEN expr */ - -3, /* (256) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ - -2, /* (257) trigger_cmd_list ::= trigger_cmd SEMI */ - -3, /* (258) trnm ::= nm DOT nm */ - -3, /* (259) tridxby ::= INDEXED BY nm */ - -2, /* (260) tridxby ::= NOT INDEXED */ - -9, /* (261) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ - -8, /* (262) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ - -6, /* (263) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ - -3, /* (264) trigger_cmd ::= scanpt select scanpt */ - -4, /* (265) expr ::= RAISE LP IGNORE RP */ - -6, /* (266) expr ::= RAISE LP raisetype COMMA nm RP */ - -1, /* (267) raisetype ::= ROLLBACK */ - -1, /* (268) raisetype ::= ABORT */ - -1, /* (269) raisetype ::= FAIL */ - -4, /* (270) cmd ::= DROP TRIGGER ifexists fullname */ - -6, /* (271) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ - -3, /* (272) cmd ::= DETACH database_kw_opt expr */ - 0, /* (273) key_opt ::= */ - -2, /* (274) key_opt ::= KEY expr */ - -1, /* (275) cmd ::= REINDEX */ - -3, /* (276) cmd ::= REINDEX nm dbnm */ - -1, /* (277) cmd ::= ANALYZE */ - -3, /* (278) cmd ::= ANALYZE nm dbnm */ - -6, /* (279) cmd ::= ALTER TABLE fullname RENAME TO nm */ - -7, /* (280) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ - -1, /* (281) add_column_fullname ::= fullname */ - -8, /* (282) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ - -1, /* (283) cmd ::= create_vtab */ - -4, /* (284) cmd ::= create_vtab LP vtabarglist RP */ - -8, /* (285) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ - 0, /* (286) vtabarg ::= */ - -1, /* (287) vtabargtoken ::= ANY */ - -3, /* (288) vtabargtoken ::= lp anylist RP */ - -1, /* (289) lp ::= LP */ - -2, /* (290) with ::= WITH wqlist */ - -3, /* (291) with ::= WITH RECURSIVE wqlist */ - -6, /* (292) wqlist ::= nm eidlist_opt AS LP select RP */ - -8, /* (293) wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ - -1, /* (294) windowdefn_list ::= windowdefn */ - -3, /* (295) windowdefn_list ::= windowdefn_list COMMA windowdefn */ - -5, /* (296) windowdefn ::= nm AS LP window RP */ - -5, /* (297) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ - -6, /* (298) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ - -4, /* (299) window ::= ORDER BY sortlist frame_opt */ - -5, /* (300) window ::= nm ORDER BY sortlist frame_opt */ - -1, /* (301) window ::= frame_opt */ - -2, /* (302) window ::= nm frame_opt */ - 0, /* (303) frame_opt ::= */ - -3, /* (304) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ - -6, /* (305) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ - -1, /* (306) range_or_rows ::= RANGE|ROWS|GROUPS */ - -1, /* (307) frame_bound_s ::= frame_bound */ - -2, /* (308) frame_bound_s ::= UNBOUNDED PRECEDING */ - -1, /* (309) frame_bound_e ::= frame_bound */ - -2, /* (310) frame_bound_e ::= UNBOUNDED FOLLOWING */ - -2, /* (311) frame_bound ::= expr PRECEDING|FOLLOWING */ - -2, /* (312) frame_bound ::= CURRENT ROW */ - 0, /* (313) frame_exclude_opt ::= */ - -2, /* (314) frame_exclude_opt ::= EXCLUDE frame_exclude */ - -2, /* (315) frame_exclude ::= NO OTHERS */ - -2, /* (316) frame_exclude ::= CURRENT ROW */ - -1, /* (317) frame_exclude ::= GROUP|TIES */ - -2, /* (318) window_clause ::= WINDOW windowdefn_list */ - -2, /* (319) filter_over ::= filter_clause over_clause */ - -1, /* (320) filter_over ::= over_clause */ - -1, /* (321) filter_over ::= filter_clause */ - -4, /* (322) over_clause ::= OVER LP window RP */ - -2, /* (323) over_clause ::= OVER nm */ - -5, /* (324) filter_clause ::= FILTER LP WHERE expr RP */ - -1, /* (325) input ::= cmdlist */ - -2, /* (326) cmdlist ::= cmdlist ecmd */ - -1, /* (327) cmdlist ::= ecmd */ - -1, /* (328) ecmd ::= SEMI */ - -2, /* (329) ecmd ::= cmdx SEMI */ - -3, /* (330) ecmd ::= explain cmdx SEMI */ - 0, /* (331) trans_opt ::= */ - -1, /* (332) trans_opt ::= TRANSACTION */ - -2, /* (333) trans_opt ::= TRANSACTION nm */ - -1, /* (334) savepoint_opt ::= SAVEPOINT */ - 0, /* (335) savepoint_opt ::= */ - -2, /* (336) cmd ::= create_table create_table_args */ - -4, /* (337) columnlist ::= columnlist COMMA columnname carglist */ - -2, /* (338) columnlist ::= columnname carglist */ - -1, /* (339) nm ::= ID|INDEXED */ - -1, /* (340) nm ::= STRING */ - -1, /* (341) nm ::= JOIN_KW */ - -1, /* (342) typetoken ::= typename */ - -1, /* (343) typename ::= ID|STRING */ - -1, /* (344) signed ::= plus_num */ - -1, /* (345) signed ::= minus_num */ - -2, /* (346) carglist ::= carglist ccons */ - 0, /* (347) carglist ::= */ - -2, /* (348) ccons ::= NULL onconf */ - -4, /* (349) ccons ::= GENERATED ALWAYS AS generated */ - -2, /* (350) ccons ::= AS generated */ - -2, /* (351) conslist_opt ::= COMMA conslist */ - -3, /* (352) conslist ::= conslist tconscomma tcons */ - -1, /* (353) conslist ::= tcons */ - 0, /* (354) tconscomma ::= */ - -1, /* (355) defer_subclause_opt ::= defer_subclause */ - -1, /* (356) resolvetype ::= raisetype */ - -1, /* (357) selectnowith ::= oneselect */ - -1, /* (358) oneselect ::= values */ - -2, /* (359) sclp ::= selcollist COMMA */ - -1, /* (360) as ::= ID|STRING */ - -1, /* (361) expr ::= term */ - -1, /* (362) likeop ::= LIKE_KW|MATCH */ - -1, /* (363) exprlist ::= nexprlist */ - -1, /* (364) nmnum ::= plus_num */ - -1, /* (365) nmnum ::= nm */ - -1, /* (366) nmnum ::= ON */ - -1, /* (367) nmnum ::= DELETE */ - -1, /* (368) nmnum ::= DEFAULT */ - -1, /* (369) plus_num ::= INTEGER|FLOAT */ - 0, /* (370) foreach_clause ::= */ - -3, /* (371) foreach_clause ::= FOR EACH ROW */ - -1, /* (372) trnm ::= nm */ - 0, /* (373) tridxby ::= */ - -1, /* (374) database_kw_opt ::= DATABASE */ - 0, /* (375) database_kw_opt ::= */ - 0, /* (376) kwcolumn_opt ::= */ - -1, /* (377) kwcolumn_opt ::= COLUMNKW */ - -1, /* (378) vtabarglist ::= vtabarg */ - -3, /* (379) vtabarglist ::= vtabarglist COMMA vtabarg */ - -2, /* (380) vtabarg ::= vtabarg vtabargtoken */ - 0, /* (381) anylist ::= */ - -4, /* (382) anylist ::= anylist LP anylist RP */ - -2, /* (383) anylist ::= anylist ANY */ - 0, /* (384) with ::= */ + 0, /* (151) where_opt_ret ::= */ + -2, /* (152) where_opt_ret ::= WHERE expr */ + -2, /* (153) where_opt_ret ::= RETURNING selcollist */ + -4, /* (154) where_opt_ret ::= WHERE expr RETURNING selcollist */ + -9, /* (155) cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ + -5, /* (156) setlist ::= setlist COMMA nm EQ expr */ + -7, /* (157) setlist ::= setlist COMMA LP idlist RP EQ expr */ + -3, /* (158) setlist ::= nm EQ expr */ + -5, /* (159) setlist ::= LP idlist RP EQ expr */ + -7, /* (160) cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + -8, /* (161) cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ + 0, /* (162) upsert ::= */ + -2, /* (163) upsert ::= RETURNING selcollist */ + -12, /* (164) upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ + -9, /* (165) upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ + -5, /* (166) upsert ::= ON CONFLICT DO NOTHING returning */ + -8, /* (167) upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ + -2, /* (168) returning ::= RETURNING selcollist */ + -2, /* (169) insert_cmd ::= INSERT orconf */ + -1, /* (170) insert_cmd ::= REPLACE */ + 0, /* (171) idlist_opt ::= */ + -3, /* (172) idlist_opt ::= LP idlist RP */ + -3, /* (173) idlist ::= idlist COMMA nm */ + -1, /* (174) idlist ::= nm */ + -3, /* (175) expr ::= LP expr RP */ + -1, /* (176) expr ::= ID|INDEXED */ + -1, /* (177) expr ::= JOIN_KW */ + -3, /* (178) expr ::= nm DOT nm */ + -5, /* (179) expr ::= nm DOT nm DOT nm */ + -1, /* (180) term ::= NULL|FLOAT|BLOB */ + -1, /* (181) term ::= STRING */ + -1, /* (182) term ::= INTEGER */ + -1, /* (183) expr ::= VARIABLE */ + -3, /* (184) expr ::= expr COLLATE ID|STRING */ + -6, /* (185) expr ::= CAST LP expr AS typetoken RP */ + -5, /* (186) expr ::= ID|INDEXED LP distinct exprlist RP */ + -4, /* (187) expr ::= ID|INDEXED LP STAR RP */ + -6, /* (188) expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + -5, /* (189) expr ::= ID|INDEXED LP STAR RP filter_over */ + -1, /* (190) term ::= CTIME_KW */ + -5, /* (191) expr ::= LP nexprlist COMMA expr RP */ + -3, /* (192) expr ::= expr AND expr */ + -3, /* (193) expr ::= expr OR expr */ + -3, /* (194) expr ::= expr LT|GT|GE|LE expr */ + -3, /* (195) expr ::= expr EQ|NE expr */ + -3, /* (196) expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ + -3, /* (197) expr ::= expr PLUS|MINUS expr */ + -3, /* (198) expr ::= expr STAR|SLASH|REM expr */ + -3, /* (199) expr ::= expr CONCAT expr */ + -2, /* (200) likeop ::= NOT LIKE_KW|MATCH */ + -3, /* (201) expr ::= expr likeop expr */ + -5, /* (202) expr ::= expr likeop expr ESCAPE expr */ + -2, /* (203) expr ::= expr ISNULL|NOTNULL */ + -3, /* (204) expr ::= expr NOT NULL */ + -3, /* (205) expr ::= expr IS expr */ + -4, /* (206) expr ::= expr IS NOT expr */ + -2, /* (207) expr ::= NOT expr */ + -2, /* (208) expr ::= BITNOT expr */ + -2, /* (209) expr ::= PLUS|MINUS expr */ + -1, /* (210) between_op ::= BETWEEN */ + -2, /* (211) between_op ::= NOT BETWEEN */ + -5, /* (212) expr ::= expr between_op expr AND expr */ + -1, /* (213) in_op ::= IN */ + -2, /* (214) in_op ::= NOT IN */ + -5, /* (215) expr ::= expr in_op LP exprlist RP */ + -3, /* (216) expr ::= LP select RP */ + -5, /* (217) expr ::= expr in_op LP select RP */ + -5, /* (218) expr ::= expr in_op nm dbnm paren_exprlist */ + -4, /* (219) expr ::= EXISTS LP select RP */ + -5, /* (220) expr ::= CASE case_operand case_exprlist case_else END */ + -5, /* (221) case_exprlist ::= case_exprlist WHEN expr THEN expr */ + -4, /* (222) case_exprlist ::= WHEN expr THEN expr */ + -2, /* (223) case_else ::= ELSE expr */ + 0, /* (224) case_else ::= */ + -1, /* (225) case_operand ::= expr */ + 0, /* (226) case_operand ::= */ + 0, /* (227) exprlist ::= */ + -3, /* (228) nexprlist ::= nexprlist COMMA expr */ + -1, /* (229) nexprlist ::= expr */ + 0, /* (230) paren_exprlist ::= */ + -3, /* (231) paren_exprlist ::= LP exprlist RP */ + -12, /* (232) cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + -1, /* (233) uniqueflag ::= UNIQUE */ + 0, /* (234) uniqueflag ::= */ + 0, /* (235) eidlist_opt ::= */ + -3, /* (236) eidlist_opt ::= LP eidlist RP */ + -5, /* (237) eidlist ::= eidlist COMMA nm collate sortorder */ + -3, /* (238) eidlist ::= nm collate sortorder */ + 0, /* (239) collate ::= */ + -2, /* (240) collate ::= COLLATE ID|STRING */ + -4, /* (241) cmd ::= DROP INDEX ifexists fullname */ + -2, /* (242) cmd ::= VACUUM vinto */ + -3, /* (243) cmd ::= VACUUM nm vinto */ + -2, /* (244) vinto ::= INTO expr */ + 0, /* (245) vinto ::= */ + -3, /* (246) cmd ::= PRAGMA nm dbnm */ + -5, /* (247) cmd ::= PRAGMA nm dbnm EQ nmnum */ + -6, /* (248) cmd ::= PRAGMA nm dbnm LP nmnum RP */ + -5, /* (249) cmd ::= PRAGMA nm dbnm EQ minus_num */ + -6, /* (250) cmd ::= PRAGMA nm dbnm LP minus_num RP */ + -2, /* (251) plus_num ::= PLUS INTEGER|FLOAT */ + -2, /* (252) minus_num ::= MINUS INTEGER|FLOAT */ + -5, /* (253) cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + -11, /* (254) trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + -1, /* (255) trigger_time ::= BEFORE|AFTER */ + -2, /* (256) trigger_time ::= INSTEAD OF */ + 0, /* (257) trigger_time ::= */ + -1, /* (258) trigger_event ::= DELETE|INSERT */ + -1, /* (259) trigger_event ::= UPDATE */ + -3, /* (260) trigger_event ::= UPDATE OF idlist */ + 0, /* (261) when_clause ::= */ + -2, /* (262) when_clause ::= WHEN expr */ + -3, /* (263) trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + -2, /* (264) trigger_cmd_list ::= trigger_cmd SEMI */ + -3, /* (265) trnm ::= nm DOT nm */ + -3, /* (266) tridxby ::= INDEXED BY nm */ + -2, /* (267) tridxby ::= NOT INDEXED */ + -9, /* (268) trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ + -8, /* (269) trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + -6, /* (270) trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ + -3, /* (271) trigger_cmd ::= scanpt select scanpt */ + -4, /* (272) expr ::= RAISE LP IGNORE RP */ + -6, /* (273) expr ::= RAISE LP raisetype COMMA nm RP */ + -1, /* (274) raisetype ::= ROLLBACK */ + -1, /* (275) raisetype ::= ABORT */ + -1, /* (276) raisetype ::= FAIL */ + -4, /* (277) cmd ::= DROP TRIGGER ifexists fullname */ + -6, /* (278) cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + -3, /* (279) cmd ::= DETACH database_kw_opt expr */ + 0, /* (280) key_opt ::= */ + -2, /* (281) key_opt ::= KEY expr */ + -1, /* (282) cmd ::= REINDEX */ + -3, /* (283) cmd ::= REINDEX nm dbnm */ + -1, /* (284) cmd ::= ANALYZE */ + -3, /* (285) cmd ::= ANALYZE nm dbnm */ + -6, /* (286) cmd ::= ALTER TABLE fullname RENAME TO nm */ + -7, /* (287) cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + -6, /* (288) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ + -1, /* (289) add_column_fullname ::= fullname */ + -8, /* (290) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + -1, /* (291) cmd ::= create_vtab */ + -4, /* (292) cmd ::= create_vtab LP vtabarglist RP */ + -8, /* (293) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + 0, /* (294) vtabarg ::= */ + -1, /* (295) vtabargtoken ::= ANY */ + -3, /* (296) vtabargtoken ::= lp anylist RP */ + -1, /* (297) lp ::= LP */ + -2, /* (298) with ::= WITH wqlist */ + -3, /* (299) with ::= WITH RECURSIVE wqlist */ + -1, /* (300) wqas ::= AS */ + -2, /* (301) wqas ::= AS MATERIALIZED */ + -3, /* (302) wqas ::= AS NOT MATERIALIZED */ + -6, /* (303) wqitem ::= nm eidlist_opt wqas LP select RP */ + -1, /* (304) wqlist ::= wqitem */ + -3, /* (305) wqlist ::= wqlist COMMA wqitem */ + -1, /* (306) windowdefn_list ::= windowdefn */ + -3, /* (307) windowdefn_list ::= windowdefn_list COMMA windowdefn */ + -5, /* (308) windowdefn ::= nm AS LP window RP */ + -5, /* (309) window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + -6, /* (310) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + -4, /* (311) window ::= ORDER BY sortlist frame_opt */ + -5, /* (312) window ::= nm ORDER BY sortlist frame_opt */ + -1, /* (313) window ::= frame_opt */ + -2, /* (314) window ::= nm frame_opt */ + 0, /* (315) frame_opt ::= */ + -3, /* (316) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + -6, /* (317) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + -1, /* (318) range_or_rows ::= RANGE|ROWS|GROUPS */ + -1, /* (319) frame_bound_s ::= frame_bound */ + -2, /* (320) frame_bound_s ::= UNBOUNDED PRECEDING */ + -1, /* (321) frame_bound_e ::= frame_bound */ + -2, /* (322) frame_bound_e ::= UNBOUNDED FOLLOWING */ + -2, /* (323) frame_bound ::= expr PRECEDING|FOLLOWING */ + -2, /* (324) frame_bound ::= CURRENT ROW */ + 0, /* (325) frame_exclude_opt ::= */ + -2, /* (326) frame_exclude_opt ::= EXCLUDE frame_exclude */ + -2, /* (327) frame_exclude ::= NO OTHERS */ + -2, /* (328) frame_exclude ::= CURRENT ROW */ + -1, /* (329) frame_exclude ::= GROUP|TIES */ + -2, /* (330) window_clause ::= WINDOW windowdefn_list */ + -2, /* (331) filter_over ::= filter_clause over_clause */ + -1, /* (332) filter_over ::= over_clause */ + -1, /* (333) filter_over ::= filter_clause */ + -4, /* (334) over_clause ::= OVER LP window RP */ + -2, /* (335) over_clause ::= OVER nm */ + -5, /* (336) filter_clause ::= FILTER LP WHERE expr RP */ + -1, /* (337) input ::= cmdlist */ + -2, /* (338) cmdlist ::= cmdlist ecmd */ + -1, /* (339) cmdlist ::= ecmd */ + -1, /* (340) ecmd ::= SEMI */ + -2, /* (341) ecmd ::= cmdx SEMI */ + -3, /* (342) ecmd ::= explain cmdx SEMI */ + 0, /* (343) trans_opt ::= */ + -1, /* (344) trans_opt ::= TRANSACTION */ + -2, /* (345) trans_opt ::= TRANSACTION nm */ + -1, /* (346) savepoint_opt ::= SAVEPOINT */ + 0, /* (347) savepoint_opt ::= */ + -2, /* (348) cmd ::= create_table create_table_args */ + -4, /* (349) columnlist ::= columnlist COMMA columnname carglist */ + -2, /* (350) columnlist ::= columnname carglist */ + -1, /* (351) nm ::= ID|INDEXED */ + -1, /* (352) nm ::= STRING */ + -1, /* (353) nm ::= JOIN_KW */ + -1, /* (354) typetoken ::= typename */ + -1, /* (355) typename ::= ID|STRING */ + -1, /* (356) signed ::= plus_num */ + -1, /* (357) signed ::= minus_num */ + -2, /* (358) carglist ::= carglist ccons */ + 0, /* (359) carglist ::= */ + -2, /* (360) ccons ::= NULL onconf */ + -4, /* (361) ccons ::= GENERATED ALWAYS AS generated */ + -2, /* (362) ccons ::= AS generated */ + -2, /* (363) conslist_opt ::= COMMA conslist */ + -3, /* (364) conslist ::= conslist tconscomma tcons */ + -1, /* (365) conslist ::= tcons */ + 0, /* (366) tconscomma ::= */ + -1, /* (367) defer_subclause_opt ::= defer_subclause */ + -1, /* (368) resolvetype ::= raisetype */ + -1, /* (369) selectnowith ::= oneselect */ + -1, /* (370) oneselect ::= values */ + -2, /* (371) sclp ::= selcollist COMMA */ + -1, /* (372) as ::= ID|STRING */ + 0, /* (373) returning ::= */ + -1, /* (374) expr ::= term */ + -1, /* (375) likeop ::= LIKE_KW|MATCH */ + -1, /* (376) exprlist ::= nexprlist */ + -1, /* (377) nmnum ::= plus_num */ + -1, /* (378) nmnum ::= nm */ + -1, /* (379) nmnum ::= ON */ + -1, /* (380) nmnum ::= DELETE */ + -1, /* (381) nmnum ::= DEFAULT */ + -1, /* (382) plus_num ::= INTEGER|FLOAT */ + 0, /* (383) foreach_clause ::= */ + -3, /* (384) foreach_clause ::= FOR EACH ROW */ + -1, /* (385) trnm ::= nm */ + 0, /* (386) tridxby ::= */ + -1, /* (387) database_kw_opt ::= DATABASE */ + 0, /* (388) database_kw_opt ::= */ + 0, /* (389) kwcolumn_opt ::= */ + -1, /* (390) kwcolumn_opt ::= COLUMNKW */ + -1, /* (391) vtabarglist ::= vtabarg */ + -3, /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ + -2, /* (393) vtabarg ::= vtabarg vtabargtoken */ + 0, /* (394) anylist ::= */ + -4, /* (395) anylist ::= anylist LP anylist RP */ + -2, /* (396) anylist ::= anylist ANY */ + 0, /* (397) with ::= */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -158282,55 +160426,6 @@ static YYACTIONTYPE yy_reduce( (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; - assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); -#ifndef NDEBUG - if( yyTraceFILE ){ - yysize = yyRuleInfoNRhs[yyruleno]; - if( yysize ){ - fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - yyTracePrompt, - yyruleno, yyRuleName[yyruleno], - yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ - yypParser->yyhwm++; - assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack)); - } -#endif -#if YYSTACKDEPTH>0 - if( yypParser->yytos>=yypParser->yystackEnd ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ - if( yyGrowStack(yypParser) ){ - yyStackOverflow(yypParser); - /* The call to yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - yymsp = yypParser->yytos; - } -#endif - } switch( yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -158353,16 +160448,16 @@ static YYACTIONTYPE yy_reduce( { sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy192);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy60);} break; case 4: /* transtype ::= */ -{yymsp[1].minor.yy192 = TK_DEFERRED;} +{yymsp[1].minor.yy60 = TK_DEFERRED;} break; case 5: /* transtype ::= DEFERRED */ case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6); case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7); - case 306: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==306); -{yymsp[0].minor.yy192 = yymsp[0].major; /*A-overwrites-X*/} + case 318: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==318); +{yymsp[0].minor.yy60 = yymsp[0].major; /*A-overwrites-X*/} break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); @@ -158385,7 +160480,7 @@ static YYACTIONTYPE yy_reduce( break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy192,0,0,yymsp[-2].minor.yy192); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy60,0,0,yymsp[-2].minor.yy60); } break; case 14: /* createkw ::= CREATE */ @@ -158399,33 +160494,33 @@ static YYACTIONTYPE yy_reduce( case 70: /* defer_subclause_opt ::= */ yytestcase(yyruleno==70); case 79: /* ifexists ::= */ yytestcase(yyruleno==79); case 96: /* distinct ::= */ yytestcase(yyruleno==96); - case 232: /* collate ::= */ yytestcase(yyruleno==232); -{yymsp[1].minor.yy192 = 0;} + case 239: /* collate ::= */ yytestcase(yyruleno==239); +{yymsp[1].minor.yy60 = 0;} break; case 16: /* ifnotexists ::= IF NOT EXISTS */ -{yymsp[-2].minor.yy192 = 1;} +{yymsp[-2].minor.yy60 = 1;} break; case 17: /* temp ::= TEMP */ case 46: /* autoinc ::= AUTOINCR */ yytestcase(yyruleno==46); -{yymsp[0].minor.yy192 = 1;} +{yymsp[0].minor.yy60 = 1;} break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ { - sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy192,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy60,0); } break; case 20: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy539); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy307); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy307); } break; case 22: /* table_options ::= WITHOUT nm */ { if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ - yymsp[-1].minor.yy192 = TF_WithoutRowid | TF_NoVisibleRowid; + yymsp[-1].minor.yy60 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ - yymsp[-1].minor.yy192 = 0; + yymsp[-1].minor.yy60 = 0; sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } @@ -158454,7 +160549,7 @@ static YYACTIONTYPE yy_reduce( case 28: /* scanpt ::= */ { assert( yyLookahead!=YYNOCODE ); - yymsp[1].minor.yy436 = yyLookaheadToken.z; + yymsp[1].minor.yy528 = yyLookaheadToken.z; } break; case 29: /* scantok ::= */ @@ -158468,17 +160563,17 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 31: /* ccons ::= DEFAULT scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy202,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy602,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 32: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy202,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy602,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 33: /* ccons ::= DEFAULT PLUS scantok term */ -{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy202,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy602,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 34: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy202, 0); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy602, 0); sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; @@ -158493,176 +160588,158 @@ static YYACTIONTYPE yy_reduce( } break; case 36: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy192);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy60);} break; case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy192,yymsp[0].minor.yy192,yymsp[-2].minor.yy192);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy60,yymsp[0].minor.yy60,yymsp[-2].minor.yy60);} break; case 38: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy192,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy60,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 39: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy202,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy602,yymsp[-2].minor.yy0.z,yymsp[0].minor.yy0.z);} break; case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy242,yymsp[0].minor.yy192);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy338,yymsp[0].minor.yy60);} break; case 41: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy192);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy60);} break; case 42: /* ccons ::= COLLATE ID|STRING */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 43: /* generated ::= LP expr RP */ -{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy202,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy602,0);} break; case 44: /* generated ::= LP expr RP ID */ -{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy202,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy602,&yymsp[0].minor.yy0);} break; case 47: /* refargs ::= */ -{ yymsp[1].minor.yy192 = OE_None*0x0101; /* EV: R-19803-45884 */} +{ yymsp[1].minor.yy60 = OE_None*0x0101; /* EV: R-19803-45884 */} break; case 48: /* refargs ::= refargs refarg */ -{ yymsp[-1].minor.yy192 = (yymsp[-1].minor.yy192 & ~yymsp[0].minor.yy207.mask) | yymsp[0].minor.yy207.value; } +{ yymsp[-1].minor.yy60 = (yymsp[-1].minor.yy60 & ~yymsp[0].minor.yy615.mask) | yymsp[0].minor.yy615.value; } break; case 49: /* refarg ::= MATCH nm */ -{ yymsp[-1].minor.yy207.value = 0; yymsp[-1].minor.yy207.mask = 0x000000; } +{ yymsp[-1].minor.yy615.value = 0; yymsp[-1].minor.yy615.mask = 0x000000; } break; case 50: /* refarg ::= ON INSERT refact */ -{ yymsp[-2].minor.yy207.value = 0; yymsp[-2].minor.yy207.mask = 0x000000; } +{ yymsp[-2].minor.yy615.value = 0; yymsp[-2].minor.yy615.mask = 0x000000; } break; case 51: /* refarg ::= ON DELETE refact */ -{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy192; yymsp[-2].minor.yy207.mask = 0x0000ff; } +{ yymsp[-2].minor.yy615.value = yymsp[0].minor.yy60; yymsp[-2].minor.yy615.mask = 0x0000ff; } break; case 52: /* refarg ::= ON UPDATE refact */ -{ yymsp[-2].minor.yy207.value = yymsp[0].minor.yy192<<8; yymsp[-2].minor.yy207.mask = 0x00ff00; } +{ yymsp[-2].minor.yy615.value = yymsp[0].minor.yy60<<8; yymsp[-2].minor.yy615.mask = 0x00ff00; } break; case 53: /* refact ::= SET NULL */ -{ yymsp[-1].minor.yy192 = OE_SetNull; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy60 = OE_SetNull; /* EV: R-33326-45252 */} break; case 54: /* refact ::= SET DEFAULT */ -{ yymsp[-1].minor.yy192 = OE_SetDflt; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy60 = OE_SetDflt; /* EV: R-33326-45252 */} break; case 55: /* refact ::= CASCADE */ -{ yymsp[0].minor.yy192 = OE_Cascade; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy60 = OE_Cascade; /* EV: R-33326-45252 */} break; case 56: /* refact ::= RESTRICT */ -{ yymsp[0].minor.yy192 = OE_Restrict; /* EV: R-33326-45252 */} +{ yymsp[0].minor.yy60 = OE_Restrict; /* EV: R-33326-45252 */} break; case 57: /* refact ::= NO ACTION */ -{ yymsp[-1].minor.yy192 = OE_None; /* EV: R-33326-45252 */} +{ yymsp[-1].minor.yy60 = OE_None; /* EV: R-33326-45252 */} break; case 58: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ -{yymsp[-2].minor.yy192 = 0;} +{yymsp[-2].minor.yy60 = 0;} break; case 59: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 74: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==74); - case 162: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==162); -{yymsp[-1].minor.yy192 = yymsp[0].minor.yy192;} + case 169: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==169); +{yymsp[-1].minor.yy60 = yymsp[0].minor.yy60;} break; case 61: /* init_deferred_pred_opt ::= INITIALLY DEFERRED */ case 78: /* ifexists ::= IF EXISTS */ yytestcase(yyruleno==78); - case 204: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==204); - case 207: /* in_op ::= NOT IN */ yytestcase(yyruleno==207); - case 233: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==233); -{yymsp[-1].minor.yy192 = 1;} + case 211: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==211); + case 214: /* in_op ::= NOT IN */ yytestcase(yyruleno==214); + case 240: /* collate ::= COLLATE ID|STRING */ yytestcase(yyruleno==240); +{yymsp[-1].minor.yy60 = 1;} break; case 62: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ -{yymsp[-1].minor.yy192 = 0;} +{yymsp[-1].minor.yy60 = 0;} break; case 64: /* tconscomma ::= COMMA */ {pParse->constraintName.n = 0;} break; case 66: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy192,yymsp[-2].minor.yy192,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy338,yymsp[0].minor.yy60,yymsp[-2].minor.yy60,0);} break; case 67: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy192,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy338,yymsp[0].minor.yy60,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 68: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy202,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy602,yymsp[-3].minor.yy0.z,yymsp[-1].minor.yy0.z);} break; case 69: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy192); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy192); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy338, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy338, yymsp[-1].minor.yy60); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy60); } break; case 71: /* onconf ::= */ case 73: /* orconf ::= */ yytestcase(yyruleno==73); -{yymsp[1].minor.yy192 = OE_Default;} +{yymsp[1].minor.yy60 = OE_Default;} break; case 72: /* onconf ::= ON CONFLICT resolvetype */ -{yymsp[-2].minor.yy192 = yymsp[0].minor.yy192;} +{yymsp[-2].minor.yy60 = yymsp[0].minor.yy60;} break; case 75: /* resolvetype ::= IGNORE */ -{yymsp[0].minor.yy192 = OE_Ignore;} +{yymsp[0].minor.yy60 = OE_Ignore;} break; case 76: /* resolvetype ::= REPLACE */ - case 163: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==163); -{yymsp[0].minor.yy192 = OE_Replace;} + case 170: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==170); +{yymsp[0].minor.yy60 = OE_Replace;} break; case 77: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy47, 0, yymsp[-1].minor.yy192); + sqlite3DropTable(pParse, yymsp[0].minor.yy291, 0, yymsp[-1].minor.yy60); } break; case 80: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[0].minor.yy539, yymsp[-7].minor.yy192, yymsp[-5].minor.yy192); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy338, yymsp[0].minor.yy307, yymsp[-7].minor.yy60, yymsp[-5].minor.yy60); } break; case 81: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy47, 1, yymsp[-1].minor.yy192); + sqlite3DropTable(pParse, yymsp[0].minor.yy291, 1, yymsp[-1].minor.yy60); } break; case 82: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy539, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); + sqlite3Select(pParse, yymsp[0].minor.yy307, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy307); } break; case 83: /* select ::= WITH wqlist selectnowith */ -{ - Select *p = yymsp[0].minor.yy539; - if( p ){ - p->pWith = yymsp[-1].minor.yy131; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); - } - yymsp[-2].minor.yy539 = p; -} +{yymsp[-2].minor.yy307 = attachWithToSelect(pParse,yymsp[0].minor.yy307,yymsp[-1].minor.yy195);} break; case 84: /* select ::= WITH RECURSIVE wqlist selectnowith */ -{ - Select *p = yymsp[0].minor.yy539; - if( p ){ - p->pWith = yymsp[-1].minor.yy131; - parserDoubleLinkSelect(pParse, p); - }else{ - sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); - } - yymsp[-3].minor.yy539 = p; -} +{yymsp[-3].minor.yy307 = attachWithToSelect(pParse,yymsp[0].minor.yy307,yymsp[-1].minor.yy195);} break; case 85: /* select ::= selectnowith */ { - Select *p = yymsp[0].minor.yy539; + Select *p = yymsp[0].minor.yy307; if( p ){ parserDoubleLinkSelect(pParse, p); } - yymsp[0].minor.yy539 = p; /*A-overwrites-X*/ + yymsp[0].minor.yy307 = p; /*A-overwrites-X*/ } break; case 86: /* selectnowith ::= selectnowith multiselect_op oneselect */ { - Select *pRhs = yymsp[0].minor.yy539; - Select *pLhs = yymsp[-2].minor.yy539; + Select *pRhs = yymsp[0].minor.yy307; + Select *pLhs = yymsp[-2].minor.yy307; if( pRhs && pRhs->pPrior ){ SrcList *pFrom; Token x; @@ -158672,83 +160749,83 @@ static YYACTIONTYPE yy_reduce( pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ - pRhs->op = (u8)yymsp[-1].minor.yy192; + pRhs->op = (u8)yymsp[-1].minor.yy60; pRhs->pPrior = pLhs; if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue; pRhs->selFlags &= ~SF_MultiValue; - if( yymsp[-1].minor.yy192!=TK_ALL ) pParse->hasCompound = 1; + if( yymsp[-1].minor.yy60!=TK_ALL ) pParse->hasCompound = 1; }else{ sqlite3SelectDelete(pParse->db, pLhs); } - yymsp[-2].minor.yy539 = pRhs; + yymsp[-2].minor.yy307 = pRhs; } break; case 87: /* multiselect_op ::= UNION */ case 89: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==89); -{yymsp[0].minor.yy192 = yymsp[0].major; /*A-overwrites-OP*/} +{yymsp[0].minor.yy60 = yymsp[0].major; /*A-overwrites-OP*/} break; case 88: /* multiselect_op ::= UNION ALL */ -{yymsp[-1].minor.yy192 = TK_ALL;} +{yymsp[-1].minor.yy60 = TK_ALL;} break; case 90: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy539 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy242,yymsp[-5].minor.yy47,yymsp[-4].minor.yy202,yymsp[-3].minor.yy242,yymsp[-2].minor.yy202,yymsp[-1].minor.yy242,yymsp[-7].minor.yy192,yymsp[0].minor.yy202); + yymsp[-8].minor.yy307 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy338,yymsp[-5].minor.yy291,yymsp[-4].minor.yy602,yymsp[-3].minor.yy338,yymsp[-2].minor.yy602,yymsp[-1].minor.yy338,yymsp[-7].minor.yy60,yymsp[0].minor.yy602); } break; case 91: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy539 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy242,yymsp[-6].minor.yy47,yymsp[-5].minor.yy202,yymsp[-4].minor.yy242,yymsp[-3].minor.yy202,yymsp[-1].minor.yy242,yymsp[-8].minor.yy192,yymsp[0].minor.yy202); - if( yymsp[-9].minor.yy539 ){ - yymsp[-9].minor.yy539->pWinDefn = yymsp[-2].minor.yy303; + yymsp[-9].minor.yy307 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy338,yymsp[-6].minor.yy291,yymsp[-5].minor.yy602,yymsp[-4].minor.yy338,yymsp[-3].minor.yy602,yymsp[-1].minor.yy338,yymsp[-8].minor.yy60,yymsp[0].minor.yy602); + if( yymsp[-9].minor.yy307 ){ + yymsp[-9].minor.yy307->pWinDefn = yymsp[-2].minor.yy19; }else{ - sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy303); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy19); } } break; case 92: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy539 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy242,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy307 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy338,0,0,0,0,0,SF_Values,0); } break; case 93: /* values ::= values COMMA LP nexprlist RP */ { - Select *pRight, *pLeft = yymsp[-4].minor.yy539; - pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy242,0,0,0,0,0,SF_Values|SF_MultiValue,0); + Select *pRight, *pLeft = yymsp[-4].minor.yy307; + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy338,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; pRight->pPrior = pLeft; - yymsp[-4].minor.yy539 = pRight; + yymsp[-4].minor.yy307 = pRight; }else{ - yymsp[-4].minor.yy539 = pLeft; + yymsp[-4].minor.yy307 = pLeft; } } break; case 94: /* distinct ::= DISTINCT */ -{yymsp[0].minor.yy192 = SF_Distinct;} +{yymsp[0].minor.yy60 = SF_Distinct;} break; case 95: /* distinct ::= ALL */ -{yymsp[0].minor.yy192 = SF_All;} +{yymsp[0].minor.yy60 = SF_All;} break; case 97: /* sclp ::= */ case 130: /* orderby_opt ::= */ yytestcase(yyruleno==130); case 140: /* groupby_opt ::= */ yytestcase(yyruleno==140); - case 220: /* exprlist ::= */ yytestcase(yyruleno==220); - case 223: /* paren_exprlist ::= */ yytestcase(yyruleno==223); - case 228: /* eidlist_opt ::= */ yytestcase(yyruleno==228); -{yymsp[1].minor.yy242 = 0;} + case 227: /* exprlist ::= */ yytestcase(yyruleno==227); + case 230: /* paren_exprlist ::= */ yytestcase(yyruleno==230); + case 235: /* eidlist_opt ::= */ yytestcase(yyruleno==235); +{yymsp[1].minor.yy338 = 0;} break; case 98: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy242,yymsp[-3].minor.yy436,yymsp[-1].minor.yy436); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy338, yymsp[-2].minor.yy602); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy338, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy338,yymsp[-3].minor.yy528,yymsp[-1].minor.yy528); } break; case 99: /* selcollist ::= sclp scanpt STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy242, p); + yymsp[-2].minor.yy338 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy338, p); } break; case 100: /* selcollist ::= sclp scanpt nm DOT STAR */ @@ -158756,56 +160833,56 @@ static YYACTIONTYPE yy_reduce( Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, pDot); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338, pDot); } break; case 101: /* as ::= AS nm */ case 112: /* dbnm ::= DOT nm */ yytestcase(yyruleno==112); - case 244: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==244); - case 245: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==245); + case 251: /* plus_num ::= PLUS INTEGER|FLOAT */ yytestcase(yyruleno==251); + case 252: /* minus_num ::= MINUS INTEGER|FLOAT */ yytestcase(yyruleno==252); {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 103: /* from ::= */ case 106: /* stl_prefix ::= */ yytestcase(yyruleno==106); -{yymsp[1].minor.yy47 = 0;} +{yymsp[1].minor.yy291 = 0;} break; case 104: /* from ::= FROM seltablist */ { - yymsp[-1].minor.yy47 = yymsp[0].minor.yy47; - sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy47); + yymsp[-1].minor.yy291 = yymsp[0].minor.yy291; + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy291); } break; case 105: /* stl_prefix ::= seltablist joinop */ { - if( ALWAYS(yymsp[-1].minor.yy47 && yymsp[-1].minor.yy47->nSrc>0) ) yymsp[-1].minor.yy47->a[yymsp[-1].minor.yy47->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy192; + if( ALWAYS(yymsp[-1].minor.yy291 && yymsp[-1].minor.yy291->nSrc>0) ) yymsp[-1].minor.yy291->a[yymsp[-1].minor.yy291->nSrc-1].fg.jointype = (u8)yymsp[0].minor.yy60; } break; case 107: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy47, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy291, &yymsp[-2].minor.yy0); } break; case 108: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy47,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy47, yymsp[-4].minor.yy242); + yymsp[-8].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy291,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy291, yymsp[-4].minor.yy338); } break; case 109: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy539,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + yymsp[-6].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy307,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); } break; case 110: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy47==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy202==0 && yymsp[0].minor.yy600==0 ){ - yymsp[-6].minor.yy47 = yymsp[-4].minor.yy47; - }else if( yymsp[-4].minor.yy47->nSrc==1 ){ - yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - if( yymsp[-6].minor.yy47 ){ - struct SrcList_item *pNew = &yymsp[-6].minor.yy47->a[yymsp[-6].minor.yy47->nSrc-1]; - struct SrcList_item *pOld = yymsp[-4].minor.yy47->a; + if( yymsp[-6].minor.yy291==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy602==0 && yymsp[0].minor.yy288==0 ){ + yymsp[-6].minor.yy291 = yymsp[-4].minor.yy291; + }else if( yymsp[-4].minor.yy291->nSrc==1 ){ + yymsp[-6].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); + if( yymsp[-6].minor.yy291 ){ + SrcItem *pNew = &yymsp[-6].minor.yy291->a[yymsp[-6].minor.yy291->nSrc-1]; + SrcItem *pOld = yymsp[-4].minor.yy291->a; pNew->zName = pOld->zName; pNew->zDatabase = pOld->zDatabase; pNew->pSelect = pOld->pSelect; @@ -158818,12 +160895,12 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy47); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy291); }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy47); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy47,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy291); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy291,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy291 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy291,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy602,yymsp[0].minor.yy288); } } break; @@ -158833,63 +160910,65 @@ static YYACTIONTYPE yy_reduce( break; case 113: /* fullname ::= nm */ { - yylhsminor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy47 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy47->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy291 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy291->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy47 = yylhsminor.yy47; + yymsp[0].minor.yy291 = yylhsminor.yy291; break; case 114: /* fullname ::= nm DOT nm */ { - yylhsminor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy47 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy47->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy291 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy291->a[0].zName, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy47 = yylhsminor.yy47; + yymsp[-2].minor.yy291 = yylhsminor.yy291; break; case 115: /* xfullname ::= nm */ -{yymsp[0].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +{yymsp[0].minor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; case 116: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[-2].minor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 117: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy47 ) yymsp[-4].minor.yy47->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy291 ) yymsp[-4].minor.yy291->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 118: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy47 ) yymsp[-2].minor.yy47->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy291 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy291 ) yymsp[-2].minor.yy291->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 119: /* joinop ::= COMMA|JOIN */ -{ yymsp[0].minor.yy192 = JT_INNER; } +{ yymsp[0].minor.yy60 = JT_INNER; } break; case 120: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy60 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; case 121: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} +{yymsp[-2].minor.yy60 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; case 122: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} +{yymsp[-3].minor.yy60 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; case 123: /* on_opt ::= ON expr */ case 143: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==143); case 150: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==150); - case 216: /* case_else ::= ELSE expr */ yytestcase(yyruleno==216); - case 237: /* vinto ::= INTO expr */ yytestcase(yyruleno==237); -{yymsp[-1].minor.yy202 = yymsp[0].minor.yy202;} + case 152: /* where_opt_ret ::= WHERE expr */ yytestcase(yyruleno==152); + case 223: /* case_else ::= ELSE expr */ yytestcase(yyruleno==223); + case 244: /* vinto ::= INTO expr */ yytestcase(yyruleno==244); +{yymsp[-1].minor.yy602 = yymsp[0].minor.yy602;} break; case 124: /* on_opt ::= */ case 142: /* having_opt ::= */ yytestcase(yyruleno==142); case 144: /* limit_opt ::= */ yytestcase(yyruleno==144); case 149: /* where_opt ::= */ yytestcase(yyruleno==149); - case 217: /* case_else ::= */ yytestcase(yyruleno==217); - case 219: /* case_operand ::= */ yytestcase(yyruleno==219); - case 238: /* vinto ::= */ yytestcase(yyruleno==238); -{yymsp[1].minor.yy202 = 0;} + case 151: /* where_opt_ret ::= */ yytestcase(yyruleno==151); + case 224: /* case_else ::= */ yytestcase(yyruleno==224); + case 226: /* case_operand ::= */ yytestcase(yyruleno==226); + case 245: /* vinto ::= */ yytestcase(yyruleno==245); +{yymsp[1].minor.yy602 = 0;} break; case 126: /* indexed_opt ::= INDEXED BY nm */ {yymsp[-2].minor.yy0 = yymsp[0].minor.yy0;} @@ -158898,129 +160977,144 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy0.z=0; yymsp[-1].minor.yy0.n=1;} break; case 128: /* using_opt ::= USING LP idlist RP */ -{yymsp[-3].minor.yy600 = yymsp[-1].minor.yy600;} +{yymsp[-3].minor.yy288 = yymsp[-1].minor.yy288;} break; case 129: /* using_opt ::= */ - case 164: /* idlist_opt ::= */ yytestcase(yyruleno==164); -{yymsp[1].minor.yy600 = 0;} + case 171: /* idlist_opt ::= */ yytestcase(yyruleno==171); +{yymsp[1].minor.yy288 = 0;} break; case 131: /* orderby_opt ::= ORDER BY sortlist */ case 141: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==141); -{yymsp[-2].minor.yy242 = yymsp[0].minor.yy242;} +{yymsp[-2].minor.yy338 = yymsp[0].minor.yy338;} break; case 132: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202); - sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338,yymsp[-2].minor.yy602); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy338,yymsp[-1].minor.yy60,yymsp[0].minor.yy60); } break; case 133: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy202); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); + yymsp[-2].minor.yy338 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy602); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy338,yymsp[-1].minor.yy60,yymsp[0].minor.yy60); } break; case 134: /* sortorder ::= ASC */ -{yymsp[0].minor.yy192 = SQLITE_SO_ASC;} +{yymsp[0].minor.yy60 = SQLITE_SO_ASC;} break; case 135: /* sortorder ::= DESC */ -{yymsp[0].minor.yy192 = SQLITE_SO_DESC;} +{yymsp[0].minor.yy60 = SQLITE_SO_DESC;} break; case 136: /* sortorder ::= */ case 139: /* nulls ::= */ yytestcase(yyruleno==139); -{yymsp[1].minor.yy192 = SQLITE_SO_UNDEFINED;} +{yymsp[1].minor.yy60 = SQLITE_SO_UNDEFINED;} break; case 137: /* nulls ::= NULLS FIRST */ -{yymsp[-1].minor.yy192 = SQLITE_SO_ASC;} +{yymsp[-1].minor.yy60 = SQLITE_SO_ASC;} break; case 138: /* nulls ::= NULLS LAST */ -{yymsp[-1].minor.yy192 = SQLITE_SO_DESC;} +{yymsp[-1].minor.yy60 = SQLITE_SO_DESC;} break; case 145: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,0);} +{yymsp[-1].minor.yy602 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy602,0);} break; case 146: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} +{yymsp[-3].minor.yy602 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy602,yymsp[0].minor.yy602);} break; case 147: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,yymsp[-2].minor.yy202);} +{yymsp[-3].minor.yy602 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy602,yymsp[-2].minor.yy602);} break; - case 148: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ + case 148: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy47, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy47,yymsp[0].minor.yy202,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy291, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy291,yymsp[0].minor.yy602,0,0); } break; - case 151: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt */ + case 153: /* where_opt_ret ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy338); yymsp[-1].minor.yy602 = 0;} + break; + case 154: /* where_opt_ret ::= WHERE expr RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy338); yymsp[-3].minor.yy602 = yymsp[-2].minor.yy602;} + break; + case 155: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist from where_opt_ret */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy47, &yymsp[-4].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy242,"set list"); - yymsp[-5].minor.yy47 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy47, yymsp[-1].minor.yy47); - sqlite3Update(pParse,yymsp[-5].minor.yy47,yymsp[-2].minor.yy242,yymsp[0].minor.yy202,yymsp[-6].minor.yy192,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-5].minor.yy291, &yymsp[-4].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-2].minor.yy338,"set list"); + yymsp[-5].minor.yy291 = sqlite3SrcListAppendList(pParse, yymsp[-5].minor.yy291, yymsp[-1].minor.yy291); + sqlite3Update(pParse,yymsp[-5].minor.yy291,yymsp[-2].minor.yy338,yymsp[0].minor.yy602,yymsp[-6].minor.yy60,0,0,0); } break; - case 152: /* setlist ::= setlist COMMA nm EQ expr */ + case 156: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[0].minor.yy202); - sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy338, yymsp[0].minor.yy602); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy338, &yymsp[-2].minor.yy0, 1); } break; - case 153: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ + case 157: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy242 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy242, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-6].minor.yy338 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy338, yymsp[-3].minor.yy288, yymsp[0].minor.yy602); } break; - case 154: /* setlist ::= nm EQ expr */ + case 158: /* setlist ::= nm EQ expr */ { - yylhsminor.yy242 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy202); - sqlite3ExprListSetName(pParse, yylhsminor.yy242, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy338 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy602); + sqlite3ExprListSetName(pParse, yylhsminor.yy338, &yymsp[-2].minor.yy0, 1); } - yymsp[-2].minor.yy242 = yylhsminor.yy242; + yymsp[-2].minor.yy338 = yylhsminor.yy338; break; - case 155: /* setlist ::= LP idlist RP EQ expr */ + case 159: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-4].minor.yy338 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy288, yymsp[0].minor.yy602); } break; - case 156: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ + case 160: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy47, yymsp[-1].minor.yy539, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, yymsp[0].minor.yy318); + sqlite3Insert(pParse, yymsp[-3].minor.yy291, yymsp[-1].minor.yy307, yymsp[-2].minor.yy288, yymsp[-5].minor.yy60, yymsp[0].minor.yy178); } break; - case 157: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ + case 161: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES returning */ { - sqlite3Insert(pParse, yymsp[-3].minor.yy47, 0, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, 0); + sqlite3Insert(pParse, yymsp[-4].minor.yy291, 0, yymsp[-3].minor.yy288, yymsp[-6].minor.yy60, 0); } break; - case 158: /* upsert ::= */ -{ yymsp[1].minor.yy318 = 0; } + case 162: /* upsert ::= */ +{ yymsp[1].minor.yy178 = 0; } break; - case 159: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -{ yymsp[-10].minor.yy318 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy242,yymsp[-5].minor.yy202,yymsp[-1].minor.yy242,yymsp[0].minor.yy202);} + case 163: /* upsert ::= RETURNING selcollist */ +{ yymsp[-1].minor.yy178 = 0; sqlite3AddReturning(pParse,yymsp[0].minor.yy338); } break; - case 160: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -{ yymsp[-7].minor.yy318 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202,0,0); } + case 164: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt upsert */ +{ yymsp[-11].minor.yy178 = sqlite3UpsertNew(pParse->db,yymsp[-8].minor.yy338,yymsp[-6].minor.yy602,yymsp[-2].minor.yy338,yymsp[-1].minor.yy602,yymsp[0].minor.yy178);} break; - case 161: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy318 = sqlite3UpsertNew(pParse->db,0,0,0,0); } + case 165: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING upsert */ +{ yymsp[-8].minor.yy178 = sqlite3UpsertNew(pParse->db,yymsp[-5].minor.yy338,yymsp[-3].minor.yy602,0,0,yymsp[0].minor.yy178); } break; - case 165: /* idlist_opt ::= LP idlist RP */ -{yymsp[-2].minor.yy600 = yymsp[-1].minor.yy600;} + case 166: /* upsert ::= ON CONFLICT DO NOTHING returning */ +{ yymsp[-4].minor.yy178 = sqlite3UpsertNew(pParse->db,0,0,0,0,0); } break; - case 166: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy600 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy600,&yymsp[0].minor.yy0);} + case 167: /* upsert ::= ON CONFLICT DO UPDATE SET setlist where_opt returning */ +{ yymsp[-7].minor.yy178 = sqlite3UpsertNew(pParse->db,0,0,yymsp[-2].minor.yy338,yymsp[-1].minor.yy602,0);} break; - case 167: /* idlist ::= nm */ -{yymsp[0].minor.yy600 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + case 168: /* returning ::= RETURNING selcollist */ +{sqlite3AddReturning(pParse,yymsp[0].minor.yy338);} break; - case 168: /* expr ::= LP expr RP */ -{yymsp[-2].minor.yy202 = yymsp[-1].minor.yy202;} + case 172: /* idlist_opt ::= LP idlist RP */ +{yymsp[-2].minor.yy288 = yymsp[-1].minor.yy288;} break; - case 169: /* expr ::= ID|INDEXED */ - case 170: /* expr ::= JOIN_KW */ yytestcase(yyruleno==170); -{yymsp[0].minor.yy202=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 173: /* idlist ::= idlist COMMA nm */ +{yymsp[-2].minor.yy288 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy288,&yymsp[0].minor.yy0);} break; - case 171: /* expr ::= nm DOT nm */ + case 174: /* idlist ::= nm */ +{yymsp[0].minor.yy288 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} + break; + case 175: /* expr ::= LP expr RP */ +{yymsp[-2].minor.yy602 = yymsp[-1].minor.yy602;} + break; + case 176: /* expr ::= ID|INDEXED */ + case 177: /* expr ::= JOIN_KW */ yytestcase(yyruleno==177); +{yymsp[0].minor.yy602=tokenExpr(pParse,TK_ID,yymsp[0].minor.yy0); /*A-overwrites-X*/} + break; + case 178: /* expr ::= nm DOT nm */ { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); @@ -159028,11 +161122,11 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); } - yylhsminor.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy602 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } - yymsp[-2].minor.yy202 = yylhsminor.yy202; + yymsp[-2].minor.yy602 = yylhsminor.yy602; break; - case 172: /* expr ::= nm DOT nm DOT nm */ + case 179: /* expr ::= nm DOT nm DOT nm */ { Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); @@ -159042,26 +161136,26 @@ static YYACTIONTYPE yy_reduce( sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); } - yylhsminor.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy602 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy602 = yylhsminor.yy602; break; - case 173: /* term ::= NULL|FLOAT|BLOB */ - case 174: /* term ::= STRING */ yytestcase(yyruleno==174); -{yymsp[0].minor.yy202=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} + case 180: /* term ::= NULL|FLOAT|BLOB */ + case 181: /* term ::= STRING */ yytestcase(yyruleno==181); +{yymsp[0].minor.yy602=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0); /*A-overwrites-X*/} break; - case 175: /* term ::= INTEGER */ + case 182: /* term ::= INTEGER */ { - yylhsminor.yy202 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy602 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); } - yymsp[0].minor.yy202 = yylhsminor.yy202; + yymsp[0].minor.yy602 = yylhsminor.yy602; break; - case 176: /* expr ::= VARIABLE */ + case 183: /* expr ::= VARIABLE */ { if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; - yymsp[0].minor.yy202 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy202, n); + yymsp[0].minor.yy602 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy602, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -159070,159 +161164,159 @@ static YYACTIONTYPE yy_reduce( assert( t.n>=2 ); if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); - yymsp[0].minor.yy202 = 0; + yymsp[0].minor.yy602 = 0; }else{ - yymsp[0].minor.yy202 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy202 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy202->iTable); + yymsp[0].minor.yy602 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy602 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy602->iTable); } } } break; - case 177: /* expr ::= expr COLLATE ID|STRING */ + case 184: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy202 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy202, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy602 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy602, &yymsp[0].minor.yy0, 1); } break; - case 178: /* expr ::= CAST LP expr AS typetoken RP */ + case 185: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy202 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy202, yymsp[-3].minor.yy202, 0); + yymsp[-5].minor.yy602 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy602, yymsp[-3].minor.yy602, 0); } break; - case 179: /* expr ::= ID|INDEXED LP distinct exprlist RP */ + case 186: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy192); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy338, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy60); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy602 = yylhsminor.yy602; break; - case 180: /* expr ::= ID|INDEXED LP STAR RP */ + case 187: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } - yymsp[-3].minor.yy202 = yylhsminor.yy202; + yymsp[-3].minor.yy602 = yylhsminor.yy602; break; - case 181: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ + case 188: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy242, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy192); - sqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy338, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy60); + sqlite3WindowAttach(pParse, yylhsminor.yy602, yymsp[0].minor.yy19); } - yymsp[-5].minor.yy202 = yylhsminor.yy202; + yymsp[-5].minor.yy602 = yylhsminor.yy602; break; - case 182: /* expr ::= ID|INDEXED LP STAR RP filter_over */ + case 189: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - sqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy602, yymsp[0].minor.yy19); } - yymsp[-4].minor.yy202 = yylhsminor.yy202; + yymsp[-4].minor.yy602 = yylhsminor.yy602; break; - case 183: /* term ::= CTIME_KW */ + case 190: /* term ::= CTIME_KW */ { - yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy602 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } - yymsp[0].minor.yy202 = yylhsminor.yy202; + yymsp[0].minor.yy602 = yylhsminor.yy602; break; - case 184: /* expr ::= LP nexprlist COMMA expr RP */ + case 191: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy242, yymsp[-1].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy338, yymsp[-1].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = pList; if( ALWAYS(pList->nExpr) ){ - yymsp[-4].minor.yy202->flags |= pList->a[0].pExpr->flags & EP_Propagate; + yymsp[-4].minor.yy602->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ sqlite3ExprListDelete(pParse->db, pList); } } break; - case 185: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy202=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} + case 192: /* expr ::= expr AND expr */ +{yymsp[-2].minor.yy602=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy602,yymsp[0].minor.yy602);} break; - case 186: /* expr ::= expr OR expr */ - case 187: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==187); - case 188: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==188); - case 189: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==189); - case 190: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==190); - case 191: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==191); - case 192: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==192); -{yymsp[-2].minor.yy202=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} + case 193: /* expr ::= expr OR expr */ + case 194: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==194); + case 195: /* expr ::= expr EQ|NE expr */ yytestcase(yyruleno==195); + case 196: /* expr ::= expr BITAND|BITOR|LSHIFT|RSHIFT expr */ yytestcase(yyruleno==196); + case 197: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==197); + case 198: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==198); + case 199: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==199); +{yymsp[-2].minor.yy602=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy602,yymsp[0].minor.yy602);} break; - case 193: /* likeop ::= NOT LIKE_KW|MATCH */ + case 200: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} break; - case 194: /* expr ::= expr likeop expr */ + case 201: /* expr ::= expr likeop expr */ { ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy202); - yymsp[-2].minor.yy202 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy202, 0); - if( yymsp[-2].minor.yy202 ) yymsp[-2].minor.yy202->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy602); + yymsp[-2].minor.yy602 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy602, 0); + if( yymsp[-2].minor.yy602 ) yymsp[-2].minor.yy602->flags |= EP_InfixFunc; } break; - case 195: /* expr ::= expr likeop expr ESCAPE expr */ + case 202: /* expr ::= expr likeop expr ESCAPE expr */ { ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ) yymsp[-4].minor.yy202->flags |= EP_InfixFunc; + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ) yymsp[-4].minor.yy602->flags |= EP_InfixFunc; } break; - case 196: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy202,0);} + case 203: /* expr ::= expr ISNULL|NOTNULL */ +{yymsp[-1].minor.yy602 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy602,0);} break; - case 197: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy202,0);} + case 204: /* expr ::= expr NOT NULL */ +{yymsp[-2].minor.yy602 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy602,0);} break; - case 198: /* expr ::= expr IS expr */ + case 205: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy202,yymsp[0].minor.yy202); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy202, yymsp[-2].minor.yy202, TK_ISNULL); + yymsp[-2].minor.yy602 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy602,yymsp[0].minor.yy602); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy602, yymsp[-2].minor.yy602, TK_ISNULL); } break; - case 199: /* expr ::= expr IS NOT expr */ + case 206: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy202,yymsp[0].minor.yy202); - binaryToUnaryIfNull(pParse, yymsp[0].minor.yy202, yymsp[-3].minor.yy202, TK_NOTNULL); + yymsp[-3].minor.yy602 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy602,yymsp[0].minor.yy602); + binaryToUnaryIfNull(pParse, yymsp[0].minor.yy602, yymsp[-3].minor.yy602, TK_NOTNULL); } break; - case 200: /* expr ::= NOT expr */ - case 201: /* expr ::= BITNOT expr */ yytestcase(yyruleno==201); -{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy202, 0);/*A-overwrites-B*/} + case 207: /* expr ::= NOT expr */ + case 208: /* expr ::= BITNOT expr */ yytestcase(yyruleno==208); +{yymsp[-1].minor.yy602 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy602, 0);/*A-overwrites-B*/} break; - case 202: /* expr ::= PLUS|MINUS expr */ + case 209: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy202 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy202, 0); + yymsp[-1].minor.yy602 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy602, 0); /*A-overwrites-B*/ } break; - case 203: /* between_op ::= BETWEEN */ - case 206: /* in_op ::= IN */ yytestcase(yyruleno==206); -{yymsp[0].minor.yy192 = 0;} + case 210: /* between_op ::= BETWEEN */ + case 213: /* in_op ::= IN */ yytestcase(yyruleno==213); +{yymsp[0].minor.yy60 = 0;} break; - case 205: /* expr ::= expr between_op expr AND expr */ + case 212: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy602); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } break; - case 208: /* expr ::= expr in_op LP exprlist RP */ + case 215: /* expr ::= expr in_op LP exprlist RP */ { - if( yymsp[-1].minor.yy242==0 ){ + if( yymsp[-1].minor.yy338==0 ){ /* Expressions of the form ** ** expr1 IN () @@ -159231,197 +161325,197 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy202); - yymsp[-4].minor.yy202 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy192 ? "1" : "0"); - }else if( yymsp[-1].minor.yy242->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy242->a[0].pExpr) ){ - Expr *pRHS = yymsp[-1].minor.yy242->a[0].pExpr; - yymsp[-1].minor.yy242->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy602); + yymsp[-4].minor.yy602 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy60 ? "1" : "0"); + }else if( yymsp[-1].minor.yy338->nExpr==1 && sqlite3ExprIsConstant(yymsp[-1].minor.yy338->a[0].pExpr) ){ + Expr *pRHS = yymsp[-1].minor.yy338->a[0].pExpr; + yymsp[-1].minor.yy338->a[0].pExpr = 0; + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy338); pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy202, pRHS); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_EQ, yymsp[-4].minor.yy602, pRHS); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); }else{ - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy242; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = yymsp[-1].minor.yy338; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy602); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy338); } - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } } break; - case 209: /* expr ::= LP select RP */ + case 216: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy202 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); - sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy202, yymsp[-1].minor.yy539); + yymsp[-2].minor.yy602 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy602, yymsp[-1].minor.yy307); } break; - case 210: /* expr ::= expr in_op LP select RP */ + case 217: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, yymsp[-1].minor.yy539); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy602, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy602, yymsp[-1].minor.yy307); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } break; - case 211: /* expr ::= expr in_op nm dbnm paren_exprlist */ + case 218: /* expr ::= expr in_op nm dbnm paren_exprlist */ { SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy242 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy242); - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, pSelect); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[0].minor.yy338 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy338); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy602, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy602, pSelect); + if( yymsp[-3].minor.yy60 ) yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy602, 0); } break; - case 212: /* expr ::= EXISTS LP select RP */ + case 219: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy202 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); - sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy539); + p = yymsp[-3].minor.yy602 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy307); } break; - case 213: /* expr ::= CASE case_operand case_exprlist case_else END */ + case 220: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy202, 0); - if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy202 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[-1].minor.yy202) : yymsp[-2].minor.yy242; - sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); + yymsp[-4].minor.yy602 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy602, 0); + if( yymsp[-4].minor.yy602 ){ + yymsp[-4].minor.yy602->x.pList = yymsp[-1].minor.yy602 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy338,yymsp[-1].minor.yy602) : yymsp[-2].minor.yy338; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy602); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy242); - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy202); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy338); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy602); } } break; - case 214: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ + case 221: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); - yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[0].minor.yy202); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338, yymsp[-2].minor.yy602); + yymsp[-4].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy338, yymsp[0].minor.yy602); } break; - case 215: /* case_exprlist ::= WHEN expr THEN expr */ + case 222: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy242 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - yymsp[-3].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy242, yymsp[0].minor.yy202); + yymsp[-3].minor.yy338 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy602); + yymsp[-3].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy338, yymsp[0].minor.yy602); } break; - case 218: /* case_operand ::= expr */ -{yymsp[0].minor.yy202 = yymsp[0].minor.yy202; /*A-overwrites-X*/} + case 225: /* case_operand ::= expr */ +{yymsp[0].minor.yy602 = yymsp[0].minor.yy602; /*A-overwrites-X*/} break; - case 221: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[0].minor.yy202);} + case 228: /* nexprlist ::= nexprlist COMMA expr */ +{yymsp[-2].minor.yy338 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy338,yymsp[0].minor.yy602);} break; - case 222: /* nexprlist ::= expr */ -{yymsp[0].minor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy202); /*A-overwrites-Y*/} + case 229: /* nexprlist ::= expr */ +{yymsp[0].minor.yy338 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy602); /*A-overwrites-Y*/} break; - case 224: /* paren_exprlist ::= LP exprlist RP */ - case 229: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==229); -{yymsp[-2].minor.yy242 = yymsp[-1].minor.yy242;} + case 231: /* paren_exprlist ::= LP exprlist RP */ + case 236: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==236); +{yymsp[-2].minor.yy338 = yymsp[-1].minor.yy338;} break; - case 225: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ + case 232: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy242, yymsp[-10].minor.yy192, - &yymsp[-11].minor.yy0, yymsp[0].minor.yy202, SQLITE_SO_ASC, yymsp[-8].minor.yy192, SQLITE_IDXTYPE_APPDEF); + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy338, yymsp[-10].minor.yy60, + &yymsp[-11].minor.yy0, yymsp[0].minor.yy602, SQLITE_SO_ASC, yymsp[-8].minor.yy60, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; - case 226: /* uniqueflag ::= UNIQUE */ - case 268: /* raisetype ::= ABORT */ yytestcase(yyruleno==268); -{yymsp[0].minor.yy192 = OE_Abort;} + case 233: /* uniqueflag ::= UNIQUE */ + case 275: /* raisetype ::= ABORT */ yytestcase(yyruleno==275); +{yymsp[0].minor.yy60 = OE_Abort;} break; - case 227: /* uniqueflag ::= */ -{yymsp[1].minor.yy192 = OE_None;} + case 234: /* uniqueflag ::= */ +{yymsp[1].minor.yy60 = OE_None;} break; - case 230: /* eidlist ::= eidlist COMMA nm collate sortorder */ + case 237: /* eidlist ::= eidlist COMMA nm collate sortorder */ { - yymsp[-4].minor.yy242 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy242, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy192, yymsp[0].minor.yy192); + yymsp[-4].minor.yy338 = parserAddExprIdListTerm(pParse, yymsp[-4].minor.yy338, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy60, yymsp[0].minor.yy60); } break; - case 231: /* eidlist ::= nm collate sortorder */ + case 238: /* eidlist ::= nm collate sortorder */ { - yymsp[-2].minor.yy242 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy192, yymsp[0].minor.yy192); /*A-overwrites-Y*/ + yymsp[-2].minor.yy338 = parserAddExprIdListTerm(pParse, 0, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy60, yymsp[0].minor.yy60); /*A-overwrites-Y*/ } break; - case 234: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy47, yymsp[-1].minor.yy192);} + case 241: /* cmd ::= DROP INDEX ifexists fullname */ +{sqlite3DropIndex(pParse, yymsp[0].minor.yy291, yymsp[-1].minor.yy60);} break; - case 235: /* cmd ::= VACUUM vinto */ -{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy202);} + case 242: /* cmd ::= VACUUM vinto */ +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy602);} break; - case 236: /* cmd ::= VACUUM nm vinto */ -{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy202);} + case 243: /* cmd ::= VACUUM nm vinto */ +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy602);} break; - case 239: /* cmd ::= PRAGMA nm dbnm */ + case 246: /* cmd ::= PRAGMA nm dbnm */ {sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; - case 240: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ + case 247: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; - case 241: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ + case 248: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; - case 242: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ + case 249: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ {sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; - case 243: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ + case 250: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ {sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; - case 246: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ + case 253: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy447, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy483, &all); } break; - case 247: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ + case 254: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy192, yymsp[-4].minor.yy230.a, yymsp[-4].minor.yy230.b, yymsp[-2].minor.yy47, yymsp[0].minor.yy202, yymsp[-10].minor.yy192, yymsp[-8].minor.yy192); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy60, yymsp[-4].minor.yy50.a, yymsp[-4].minor.yy50.b, yymsp[-2].minor.yy291, yymsp[0].minor.yy602, yymsp[-10].minor.yy60, yymsp[-8].minor.yy60); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; - case 248: /* trigger_time ::= BEFORE|AFTER */ -{ yymsp[0].minor.yy192 = yymsp[0].major; /*A-overwrites-X*/ } + case 255: /* trigger_time ::= BEFORE|AFTER */ +{ yymsp[0].minor.yy60 = yymsp[0].major; /*A-overwrites-X*/ } break; - case 249: /* trigger_time ::= INSTEAD OF */ -{ yymsp[-1].minor.yy192 = TK_INSTEAD;} + case 256: /* trigger_time ::= INSTEAD OF */ +{ yymsp[-1].minor.yy60 = TK_INSTEAD;} break; - case 250: /* trigger_time ::= */ -{ yymsp[1].minor.yy192 = TK_BEFORE; } + case 257: /* trigger_time ::= */ +{ yymsp[1].minor.yy60 = TK_BEFORE; } break; - case 251: /* trigger_event ::= DELETE|INSERT */ - case 252: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==252); -{yymsp[0].minor.yy230.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy230.b = 0;} + case 258: /* trigger_event ::= DELETE|INSERT */ + case 259: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==259); +{yymsp[0].minor.yy50.a = yymsp[0].major; /*A-overwrites-X*/ yymsp[0].minor.yy50.b = 0;} break; - case 253: /* trigger_event ::= UPDATE OF idlist */ -{yymsp[-2].minor.yy230.a = TK_UPDATE; yymsp[-2].minor.yy230.b = yymsp[0].minor.yy600;} + case 260: /* trigger_event ::= UPDATE OF idlist */ +{yymsp[-2].minor.yy50.a = TK_UPDATE; yymsp[-2].minor.yy50.b = yymsp[0].minor.yy288;} break; - case 254: /* when_clause ::= */ - case 273: /* key_opt ::= */ yytestcase(yyruleno==273); -{ yymsp[1].minor.yy202 = 0; } + case 261: /* when_clause ::= */ + case 280: /* key_opt ::= */ yytestcase(yyruleno==280); +{ yymsp[1].minor.yy602 = 0; } break; - case 255: /* when_clause ::= WHEN expr */ - case 274: /* key_opt ::= KEY expr */ yytestcase(yyruleno==274); -{ yymsp[-1].minor.yy202 = yymsp[0].minor.yy202; } + case 262: /* when_clause ::= WHEN expr */ + case 281: /* key_opt ::= KEY expr */ yytestcase(yyruleno==281); +{ yymsp[-1].minor.yy602 = yymsp[0].minor.yy602; } break; - case 256: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ + case 263: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy447!=0 ); - yymsp[-2].minor.yy447->pLast->pNext = yymsp[-1].minor.yy447; - yymsp[-2].minor.yy447->pLast = yymsp[-1].minor.yy447; + assert( yymsp[-2].minor.yy483!=0 ); + yymsp[-2].minor.yy483->pLast->pNext = yymsp[-1].minor.yy483; + yymsp[-2].minor.yy483->pLast = yymsp[-1].minor.yy483; } break; - case 257: /* trigger_cmd_list ::= trigger_cmd SEMI */ + case 264: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy447!=0 ); - yymsp[-1].minor.yy447->pLast = yymsp[-1].minor.yy447; + assert( yymsp[-1].minor.yy483!=0 ); + yymsp[-1].minor.yy483->pLast = yymsp[-1].minor.yy483; } break; - case 258: /* trnm ::= nm DOT nm */ + case 265: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; sqlite3ErrorMsg(pParse, @@ -159429,344 +161523,364 @@ static YYACTIONTYPE yy_reduce( "statements within triggers"); } break; - case 259: /* tridxby ::= INDEXED BY nm */ + case 266: /* tridxby ::= INDEXED BY nm */ { sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 260: /* tridxby ::= NOT INDEXED */ + case 267: /* tridxby ::= NOT INDEXED */ { sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; - case 261: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ -{yylhsminor.yy447 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy47, yymsp[-3].minor.yy242, yymsp[-1].minor.yy202, yymsp[-7].minor.yy192, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy436);} - yymsp[-8].minor.yy447 = yylhsminor.yy447; + case 268: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist from where_opt scanpt */ +{yylhsminor.yy483 = sqlite3TriggerUpdateStep(pParse, &yymsp[-6].minor.yy0, yymsp[-2].minor.yy291, yymsp[-3].minor.yy338, yymsp[-1].minor.yy602, yymsp[-7].minor.yy60, yymsp[-8].minor.yy0.z, yymsp[0].minor.yy528);} + yymsp[-8].minor.yy483 = yylhsminor.yy483; break; - case 262: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ + case 269: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy447 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy600,yymsp[-2].minor.yy539,yymsp[-6].minor.yy192,yymsp[-1].minor.yy318,yymsp[-7].minor.yy436,yymsp[0].minor.yy436);/*yylhsminor.yy447-overwrites-yymsp[-6].minor.yy192*/ + yylhsminor.yy483 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy288,yymsp[-2].minor.yy307,yymsp[-6].minor.yy60,yymsp[-1].minor.yy178,yymsp[-7].minor.yy528,yymsp[0].minor.yy528);/*yylhsminor.yy483-overwrites-yymsp[-6].minor.yy60*/ } - yymsp[-7].minor.yy447 = yylhsminor.yy447; + yymsp[-7].minor.yy483 = yylhsminor.yy483; break; - case 263: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy447 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy202, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy436);} - yymsp[-5].minor.yy447 = yylhsminor.yy447; + case 270: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ +{yylhsminor.yy483 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy602, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy528);} + yymsp[-5].minor.yy483 = yylhsminor.yy483; break; - case 264: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy447 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy539, yymsp[-2].minor.yy436, yymsp[0].minor.yy436); /*yylhsminor.yy447-overwrites-yymsp[-1].minor.yy539*/} - yymsp[-2].minor.yy447 = yylhsminor.yy447; + case 271: /* trigger_cmd ::= scanpt select scanpt */ +{yylhsminor.yy483 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy307, yymsp[-2].minor.yy528, yymsp[0].minor.yy528); /*yylhsminor.yy483-overwrites-yymsp[-1].minor.yy307*/} + yymsp[-2].minor.yy483 = yylhsminor.yy483; break; - case 265: /* expr ::= RAISE LP IGNORE RP */ + case 272: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy202 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); - if( yymsp[-3].minor.yy202 ){ - yymsp[-3].minor.yy202->affExpr = OE_Ignore; + yymsp[-3].minor.yy602 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); + if( yymsp[-3].minor.yy602 ){ + yymsp[-3].minor.yy602->affExpr = OE_Ignore; } } break; - case 266: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 273: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy202 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); - if( yymsp[-5].minor.yy202 ) { - yymsp[-5].minor.yy202->affExpr = (char)yymsp[-3].minor.yy192; + yymsp[-5].minor.yy602 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + if( yymsp[-5].minor.yy602 ) { + yymsp[-5].minor.yy602->affExpr = (char)yymsp[-3].minor.yy60; } } break; - case 267: /* raisetype ::= ROLLBACK */ -{yymsp[0].minor.yy192 = OE_Rollback;} + case 274: /* raisetype ::= ROLLBACK */ +{yymsp[0].minor.yy60 = OE_Rollback;} break; - case 269: /* raisetype ::= FAIL */ -{yymsp[0].minor.yy192 = OE_Fail;} + case 276: /* raisetype ::= FAIL */ +{yymsp[0].minor.yy60 = OE_Fail;} break; - case 270: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 277: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy192); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy291,yymsp[-1].minor.yy60); } break; - case 271: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 278: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy202, yymsp[-1].minor.yy202, yymsp[0].minor.yy202); + sqlite3Attach(pParse, yymsp[-3].minor.yy602, yymsp[-1].minor.yy602, yymsp[0].minor.yy602); } break; - case 272: /* cmd ::= DETACH database_kw_opt expr */ + case 279: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy202); + sqlite3Detach(pParse, yymsp[0].minor.yy602); } break; - case 275: /* cmd ::= REINDEX */ + case 282: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 276: /* cmd ::= REINDEX nm dbnm */ + case 283: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 277: /* cmd ::= ANALYZE */ + case 284: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 278: /* cmd ::= ANALYZE nm dbnm */ + case 285: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 279: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 286: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy47,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy291,&yymsp[0].minor.yy0); } break; - case 280: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ + case 287: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; - case 281: /* add_column_fullname ::= fullname */ + case 288: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */ +{ + sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy291, &yymsp[0].minor.yy0); +} + break; + case 289: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy47); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy291); } break; - case 282: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ + case 290: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy47, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy291, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 283: /* cmd ::= create_vtab */ + case 291: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 284: /* cmd ::= create_vtab LP vtabarglist RP */ + case 292: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 285: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ + case 293: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy192); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy60); } break; - case 286: /* vtabarg ::= */ + case 294: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 287: /* vtabargtoken ::= ANY */ - case 288: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==288); - case 289: /* lp ::= LP */ yytestcase(yyruleno==289); + case 295: /* vtabargtoken ::= ANY */ + case 296: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==296); + case 297: /* lp ::= LP */ yytestcase(yyruleno==297); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; - case 290: /* with ::= WITH wqlist */ - case 291: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==291); -{ sqlite3WithPush(pParse, yymsp[0].minor.yy131, 1); } + case 298: /* with ::= WITH wqlist */ + case 299: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==299); +{ sqlite3WithPush(pParse, yymsp[0].minor.yy195, 1); } + break; + case 300: /* wqas ::= AS */ +{yymsp[0].minor.yy570 = M10d_Any;} + break; + case 301: /* wqas ::= AS MATERIALIZED */ +{yymsp[-1].minor.yy570 = M10d_Yes;} break; - case 292: /* wqlist ::= nm eidlist_opt AS LP select RP */ + case 302: /* wqas ::= AS NOT MATERIALIZED */ +{yymsp[-2].minor.yy570 = M10d_No;} + break; + case 303: /* wqitem ::= nm eidlist_opt wqas LP select RP */ { - yymsp[-5].minor.yy131 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); /*A-overwrites-X*/ + yymsp[-5].minor.yy607 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy338, yymsp[-1].minor.yy307, yymsp[-3].minor.yy570); /*A-overwrites-X*/ } break; - case 293: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ + case 304: /* wqlist ::= wqitem */ { - yymsp[-7].minor.yy131 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy131, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); + yymsp[0].minor.yy195 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy607); /*A-overwrites-X*/ } break; - case 294: /* windowdefn_list ::= windowdefn */ -{ yylhsminor.yy303 = yymsp[0].minor.yy303; } - yymsp[0].minor.yy303 = yylhsminor.yy303; + case 305: /* wqlist ::= wqlist COMMA wqitem */ +{ + yymsp[-2].minor.yy195 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy195, yymsp[0].minor.yy607); +} break; - case 295: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ + case 306: /* windowdefn_list ::= windowdefn */ +{ yylhsminor.yy19 = yymsp[0].minor.yy19; } + yymsp[0].minor.yy19 = yylhsminor.yy19; + break; + case 307: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { - assert( yymsp[0].minor.yy303!=0 ); - sqlite3WindowChain(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy303); - yymsp[0].minor.yy303->pNextWin = yymsp[-2].minor.yy303; - yylhsminor.yy303 = yymsp[0].minor.yy303; + assert( yymsp[0].minor.yy19!=0 ); + sqlite3WindowChain(pParse, yymsp[0].minor.yy19, yymsp[-2].minor.yy19); + yymsp[0].minor.yy19->pNextWin = yymsp[-2].minor.yy19; + yylhsminor.yy19 = yymsp[0].minor.yy19; } - yymsp[-2].minor.yy303 = yylhsminor.yy303; + yymsp[-2].minor.yy19 = yylhsminor.yy19; break; - case 296: /* windowdefn ::= nm AS LP window RP */ + case 308: /* windowdefn ::= nm AS LP window RP */ { - if( ALWAYS(yymsp[-1].minor.yy303) ){ - yymsp[-1].minor.yy303->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + if( ALWAYS(yymsp[-1].minor.yy19) ){ + yymsp[-1].minor.yy19->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } - yylhsminor.yy303 = yymsp[-1].minor.yy303; + yylhsminor.yy19 = yymsp[-1].minor.yy19; } - yymsp[-4].minor.yy303 = yylhsminor.yy303; + yymsp[-4].minor.yy19 = yylhsminor.yy19; break; - case 297: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ + case 309: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, 0); + yymsp[-4].minor.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, yymsp[-2].minor.yy338, yymsp[-1].minor.yy338, 0); } break; - case 298: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ + case 310: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, &yymsp[-5].minor.yy0); + yylhsminor.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, yymsp[-2].minor.yy338, yymsp[-1].minor.yy338, &yymsp[-5].minor.yy0); } - yymsp[-5].minor.yy303 = yylhsminor.yy303; + yymsp[-5].minor.yy19 = yylhsminor.yy19; break; - case 299: /* window ::= ORDER BY sortlist frame_opt */ + case 311: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, 0); + yymsp[-3].minor.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, 0, yymsp[-1].minor.yy338, 0); } break; - case 300: /* window ::= nm ORDER BY sortlist frame_opt */ + case 312: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0); + yylhsminor.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, 0, yymsp[-1].minor.yy338, &yymsp[-4].minor.yy0); } - yymsp[-4].minor.yy303 = yylhsminor.yy303; + yymsp[-4].minor.yy19 = yylhsminor.yy19; break; - case 301: /* window ::= frame_opt */ - case 320: /* filter_over ::= over_clause */ yytestcase(yyruleno==320); + case 313: /* window ::= frame_opt */ + case 332: /* filter_over ::= over_clause */ yytestcase(yyruleno==332); { - yylhsminor.yy303 = yymsp[0].minor.yy303; + yylhsminor.yy19 = yymsp[0].minor.yy19; } - yymsp[0].minor.yy303 = yylhsminor.yy303; + yymsp[0].minor.yy19 = yylhsminor.yy19; break; - case 302: /* window ::= nm frame_opt */ + case 314: /* window ::= nm frame_opt */ { - yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy19 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy19, 0, 0, &yymsp[-1].minor.yy0); } - yymsp[-1].minor.yy303 = yylhsminor.yy303; + yymsp[-1].minor.yy19 = yylhsminor.yy19; break; - case 303: /* frame_opt ::= */ + case 315: /* frame_opt ::= */ { - yymsp[1].minor.yy303 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy19 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; - case 304: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ + case 316: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy303 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy192, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy58); + yylhsminor.yy19 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy60, yymsp[-1].minor.yy113.eType, yymsp[-1].minor.yy113.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy570); } - yymsp[-2].minor.yy303 = yylhsminor.yy303; + yymsp[-2].minor.yy19 = yylhsminor.yy19; break; - case 305: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ + case 317: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { - yylhsminor.yy303 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy192, yymsp[-3].minor.yy77.eType, yymsp[-3].minor.yy77.pExpr, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, yymsp[0].minor.yy58); + yylhsminor.yy19 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy60, yymsp[-3].minor.yy113.eType, yymsp[-3].minor.yy113.pExpr, yymsp[-1].minor.yy113.eType, yymsp[-1].minor.yy113.pExpr, yymsp[0].minor.yy570); } - yymsp[-5].minor.yy303 = yylhsminor.yy303; + yymsp[-5].minor.yy19 = yylhsminor.yy19; break; - case 307: /* frame_bound_s ::= frame_bound */ - case 309: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==309); -{yylhsminor.yy77 = yymsp[0].minor.yy77;} - yymsp[0].minor.yy77 = yylhsminor.yy77; + case 319: /* frame_bound_s ::= frame_bound */ + case 321: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==321); +{yylhsminor.yy113 = yymsp[0].minor.yy113;} + yymsp[0].minor.yy113 = yylhsminor.yy113; break; - case 308: /* frame_bound_s ::= UNBOUNDED PRECEDING */ - case 310: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==310); - case 312: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==312); -{yylhsminor.yy77.eType = yymsp[-1].major; yylhsminor.yy77.pExpr = 0;} - yymsp[-1].minor.yy77 = yylhsminor.yy77; + case 320: /* frame_bound_s ::= UNBOUNDED PRECEDING */ + case 322: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==322); + case 324: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==324); +{yylhsminor.yy113.eType = yymsp[-1].major; yylhsminor.yy113.pExpr = 0;} + yymsp[-1].minor.yy113 = yylhsminor.yy113; break; - case 311: /* frame_bound ::= expr PRECEDING|FOLLOWING */ -{yylhsminor.yy77.eType = yymsp[0].major; yylhsminor.yy77.pExpr = yymsp[-1].minor.yy202;} - yymsp[-1].minor.yy77 = yylhsminor.yy77; + case 323: /* frame_bound ::= expr PRECEDING|FOLLOWING */ +{yylhsminor.yy113.eType = yymsp[0].major; yylhsminor.yy113.pExpr = yymsp[-1].minor.yy602;} + yymsp[-1].minor.yy113 = yylhsminor.yy113; break; - case 313: /* frame_exclude_opt ::= */ -{yymsp[1].minor.yy58 = 0;} + case 325: /* frame_exclude_opt ::= */ +{yymsp[1].minor.yy570 = 0;} break; - case 314: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ -{yymsp[-1].minor.yy58 = yymsp[0].minor.yy58;} + case 326: /* frame_exclude_opt ::= EXCLUDE frame_exclude */ +{yymsp[-1].minor.yy570 = yymsp[0].minor.yy570;} break; - case 315: /* frame_exclude ::= NO OTHERS */ - case 316: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==316); -{yymsp[-1].minor.yy58 = yymsp[-1].major; /*A-overwrites-X*/} + case 327: /* frame_exclude ::= NO OTHERS */ + case 328: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==328); +{yymsp[-1].minor.yy570 = yymsp[-1].major; /*A-overwrites-X*/} break; - case 317: /* frame_exclude ::= GROUP|TIES */ -{yymsp[0].minor.yy58 = yymsp[0].major; /*A-overwrites-X*/} + case 329: /* frame_exclude ::= GROUP|TIES */ +{yymsp[0].minor.yy570 = yymsp[0].major; /*A-overwrites-X*/} break; - case 318: /* window_clause ::= WINDOW windowdefn_list */ -{ yymsp[-1].minor.yy303 = yymsp[0].minor.yy303; } + case 330: /* window_clause ::= WINDOW windowdefn_list */ +{ yymsp[-1].minor.yy19 = yymsp[0].minor.yy19; } break; - case 319: /* filter_over ::= filter_clause over_clause */ + case 331: /* filter_over ::= filter_clause over_clause */ { - yymsp[0].minor.yy303->pFilter = yymsp[-1].minor.yy202; - yylhsminor.yy303 = yymsp[0].minor.yy303; + yymsp[0].minor.yy19->pFilter = yymsp[-1].minor.yy602; + yylhsminor.yy19 = yymsp[0].minor.yy19; } - yymsp[-1].minor.yy303 = yylhsminor.yy303; + yymsp[-1].minor.yy19 = yylhsminor.yy19; break; - case 321: /* filter_over ::= filter_clause */ + case 333: /* filter_over ::= filter_clause */ { - yylhsminor.yy303 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yylhsminor.yy303 ){ - yylhsminor.yy303->eFrmType = TK_FILTER; - yylhsminor.yy303->pFilter = yymsp[0].minor.yy202; + yylhsminor.yy19 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yylhsminor.yy19 ){ + yylhsminor.yy19->eFrmType = TK_FILTER; + yylhsminor.yy19->pFilter = yymsp[0].minor.yy602; }else{ - sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy202); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy602); } } - yymsp[0].minor.yy303 = yylhsminor.yy303; + yymsp[0].minor.yy19 = yylhsminor.yy19; break; - case 322: /* over_clause ::= OVER LP window RP */ + case 334: /* over_clause ::= OVER LP window RP */ { - yymsp[-3].minor.yy303 = yymsp[-1].minor.yy303; - assert( yymsp[-3].minor.yy303!=0 ); + yymsp[-3].minor.yy19 = yymsp[-1].minor.yy19; + assert( yymsp[-3].minor.yy19!=0 ); } break; - case 323: /* over_clause ::= OVER nm */ + case 335: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy303 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); - if( yymsp[-1].minor.yy303 ){ - yymsp[-1].minor.yy303->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy19 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); + if( yymsp[-1].minor.yy19 ){ + yymsp[-1].minor.yy19->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; - case 324: /* filter_clause ::= FILTER LP WHERE expr RP */ -{ yymsp[-4].minor.yy202 = yymsp[-1].minor.yy202; } + case 336: /* filter_clause ::= FILTER LP WHERE expr RP */ +{ yymsp[-4].minor.yy602 = yymsp[-1].minor.yy602; } break; default: - /* (325) input ::= cmdlist */ yytestcase(yyruleno==325); - /* (326) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==326); - /* (327) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=327); - /* (328) ecmd ::= SEMI */ yytestcase(yyruleno==328); - /* (329) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==329); - /* (330) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=330); - /* (331) trans_opt ::= */ yytestcase(yyruleno==331); - /* (332) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==332); - /* (333) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==333); - /* (334) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==334); - /* (335) savepoint_opt ::= */ yytestcase(yyruleno==335); - /* (336) cmd ::= create_table create_table_args */ yytestcase(yyruleno==336); - /* (337) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==337); - /* (338) columnlist ::= columnname carglist */ yytestcase(yyruleno==338); - /* (339) nm ::= ID|INDEXED */ yytestcase(yyruleno==339); - /* (340) nm ::= STRING */ yytestcase(yyruleno==340); - /* (341) nm ::= JOIN_KW */ yytestcase(yyruleno==341); - /* (342) typetoken ::= typename */ yytestcase(yyruleno==342); - /* (343) typename ::= ID|STRING */ yytestcase(yyruleno==343); - /* (344) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=344); - /* (345) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=345); - /* (346) carglist ::= carglist ccons */ yytestcase(yyruleno==346); - /* (347) carglist ::= */ yytestcase(yyruleno==347); - /* (348) ccons ::= NULL onconf */ yytestcase(yyruleno==348); - /* (349) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==349); - /* (350) ccons ::= AS generated */ yytestcase(yyruleno==350); - /* (351) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==351); - /* (352) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==352); - /* (353) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=353); - /* (354) tconscomma ::= */ yytestcase(yyruleno==354); - /* (355) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=355); - /* (356) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=356); - /* (357) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=357); - /* (358) oneselect ::= values */ yytestcase(yyruleno==358); - /* (359) sclp ::= selcollist COMMA */ yytestcase(yyruleno==359); - /* (360) as ::= ID|STRING */ yytestcase(yyruleno==360); - /* (361) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=361); - /* (362) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==362); - /* (363) exprlist ::= nexprlist */ yytestcase(yyruleno==363); - /* (364) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=364); - /* (365) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=365); - /* (366) nmnum ::= ON */ yytestcase(yyruleno==366); - /* (367) nmnum ::= DELETE */ yytestcase(yyruleno==367); - /* (368) nmnum ::= DEFAULT */ yytestcase(yyruleno==368); - /* (369) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==369); - /* (370) foreach_clause ::= */ yytestcase(yyruleno==370); - /* (371) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==371); - /* (372) trnm ::= nm */ yytestcase(yyruleno==372); - /* (373) tridxby ::= */ yytestcase(yyruleno==373); - /* (374) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==374); - /* (375) database_kw_opt ::= */ yytestcase(yyruleno==375); - /* (376) kwcolumn_opt ::= */ yytestcase(yyruleno==376); - /* (377) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==377); - /* (378) vtabarglist ::= vtabarg */ yytestcase(yyruleno==378); - /* (379) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==379); - /* (380) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==380); - /* (381) anylist ::= */ yytestcase(yyruleno==381); - /* (382) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==382); - /* (383) anylist ::= anylist ANY */ yytestcase(yyruleno==383); - /* (384) with ::= */ yytestcase(yyruleno==384); + /* (337) input ::= cmdlist */ yytestcase(yyruleno==337); + /* (338) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==338); + /* (339) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=339); + /* (340) ecmd ::= SEMI */ yytestcase(yyruleno==340); + /* (341) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==341); + /* (342) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=342); + /* (343) trans_opt ::= */ yytestcase(yyruleno==343); + /* (344) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==344); + /* (345) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==345); + /* (346) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==346); + /* (347) savepoint_opt ::= */ yytestcase(yyruleno==347); + /* (348) cmd ::= create_table create_table_args */ yytestcase(yyruleno==348); + /* (349) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==349); + /* (350) columnlist ::= columnname carglist */ yytestcase(yyruleno==350); + /* (351) nm ::= ID|INDEXED */ yytestcase(yyruleno==351); + /* (352) nm ::= STRING */ yytestcase(yyruleno==352); + /* (353) nm ::= JOIN_KW */ yytestcase(yyruleno==353); + /* (354) typetoken ::= typename */ yytestcase(yyruleno==354); + /* (355) typename ::= ID|STRING */ yytestcase(yyruleno==355); + /* (356) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=356); + /* (357) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=357); + /* (358) carglist ::= carglist ccons */ yytestcase(yyruleno==358); + /* (359) carglist ::= */ yytestcase(yyruleno==359); + /* (360) ccons ::= NULL onconf */ yytestcase(yyruleno==360); + /* (361) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==361); + /* (362) ccons ::= AS generated */ yytestcase(yyruleno==362); + /* (363) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==363); + /* (364) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==364); + /* (365) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=365); + /* (366) tconscomma ::= */ yytestcase(yyruleno==366); + /* (367) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=367); + /* (368) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=368); + /* (369) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=369); + /* (370) oneselect ::= values */ yytestcase(yyruleno==370); + /* (371) sclp ::= selcollist COMMA */ yytestcase(yyruleno==371); + /* (372) as ::= ID|STRING */ yytestcase(yyruleno==372); + /* (373) returning ::= */ yytestcase(yyruleno==373); + /* (374) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=374); + /* (375) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==375); + /* (376) exprlist ::= nexprlist */ yytestcase(yyruleno==376); + /* (377) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=377); + /* (378) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=378); + /* (379) nmnum ::= ON */ yytestcase(yyruleno==379); + /* (380) nmnum ::= DELETE */ yytestcase(yyruleno==380); + /* (381) nmnum ::= DEFAULT */ yytestcase(yyruleno==381); + /* (382) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==382); + /* (383) foreach_clause ::= */ yytestcase(yyruleno==383); + /* (384) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==384); + /* (385) trnm ::= nm */ yytestcase(yyruleno==385); + /* (386) tridxby ::= */ yytestcase(yyruleno==386); + /* (387) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==387); + /* (388) database_kw_opt ::= */ yytestcase(yyruleno==388); + /* (389) kwcolumn_opt ::= */ yytestcase(yyruleno==389); + /* (390) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==390); + /* (391) vtabarglist ::= vtabarg */ yytestcase(yyruleno==391); + /* (392) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==392); + /* (393) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==393); + /* (394) anylist ::= */ yytestcase(yyruleno==394); + /* (395) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==395); + /* (396) anylist ::= anylist ANY */ yytestcase(yyruleno==396); + /* (397) with ::= */ yytestcase(yyruleno==397); break; /********** End reduce actions ************************************************/ }; @@ -159918,12 +162032,56 @@ SQLITE_PRIVATE void sqlite3Parser( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( yypParser->yytos>=yypParser->yystack ); assert( yyact==yypParser->yytos->stateno ); yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ - yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor sqlite3ParserCTX_PARAM); + unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */ + assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ); +#ifndef NDEBUG + if( yyTraceFILE ){ + int yysize = yyRuleInfoNRhs[yyruleno]; + if( yysize ){ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + yyTracePrompt, + yyruleno, yyRuleName[yyruleno], + yyrulenoyytos[yysize].stateno); + }else{ + fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n", + yyTracePrompt, yyruleno, yyRuleName[yyruleno], + yyrulenoyytos - yypParser->yystack)>yypParser->yyhwm ){ + yypParser->yyhwm++; + assert( yypParser->yyhwm == + (int)(yypParser->yytos - yypParser->yystack)); + } +#endif +#if YYSTACKDEPTH>0 + if( yypParser->yytos>=yypParser->yystackEnd ){ + yyStackOverflow(yypParser); + break; + } +#else + if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){ + if( yyGrowStack(yypParser) ){ + yyStackOverflow(yypParser); + break; + } + } +#endif + } + yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor sqlite3ParserCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -160036,7 +162194,7 @@ SQLITE_PRIVATE void sqlite3Parser( break; #endif } - }while( yypParser->yytos>yypParser->yystack ); + } #ifndef NDEBUG if( yyTraceFILE ){ yyStackEntry *i; @@ -160097,8 +162255,8 @@ SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ ** all of them need to be used within the switch. */ #define CC_X 0 /* The letter 'x', or start of BLOB literal */ -#define CC_KYWD 1 /* Alphabetics or '_'. Usable in a keyword */ -#define CC_ID 2 /* unicode characters usable in IDs */ +#define CC_KYWD0 1 /* First letter of a keyword */ +#define CC_KYWD 2 /* Alphabetics or '_'. Usable in a keyword */ #define CC_DIGIT 3 /* Digits */ #define CC_DOLLAR 4 /* '$' */ #define CC_VARALPHA 5 /* '@', '#', ':'. Alphabetic SQL variables */ @@ -160123,20 +162281,21 @@ SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ #define CC_AND 24 /* '&' */ #define CC_TILDA 25 /* '~' */ #define CC_DOT 26 /* '.' */ -#define CC_ILLEGAL 27 /* Illegal character */ -#define CC_NUL 28 /* 0x00 */ +#define CC_ID 27 /* unicode characters usable in IDs */ +#define CC_ILLEGAL 28 /* Illegal character */ +#define CC_NUL 29 /* 0x00 */ static const unsigned char aiClass[] = { #ifdef SQLITE_ASCII /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 28, 27, 27, 27, 27, 27, 27, 27, 27, 7, 7, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +/* 0x */ 29, 28, 28, 28, 28, 28, 28, 28, 28, 7, 7, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, /* 2x */ 7, 15, 8, 5, 4, 22, 24, 8, 17, 18, 21, 20, 23, 11, 26, 16, /* 3x */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 19, 12, 14, 13, 6, /* 4x */ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 9, 27, 27, 27, 1, +/* 5x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 9, 28, 28, 28, 2, /* 6x */ 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 27, 10, 27, 25, 27, +/* 7x */ 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 28, 10, 28, 25, 28, /* 8x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* 9x */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* Ax */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -160148,22 +162307,22 @@ static const unsigned char aiClass[] = { #endif #ifdef SQLITE_EBCDIC /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ -/* 0x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 7, 7, 27, 27, -/* 1x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 2x */ 27, 27, 27, 27, 27, 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 3x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -/* 4x */ 7, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 26, 12, 17, 20, 10, -/* 5x */ 24, 27, 27, 27, 27, 27, 27, 27, 27, 27, 15, 4, 21, 18, 19, 27, -/* 6x */ 11, 16, 27, 27, 27, 27, 27, 27, 27, 27, 27, 23, 22, 1, 13, 6, -/* 7x */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 8, 5, 5, 5, 8, 14, 8, -/* 8x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* 9x */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ax */ 27, 25, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Bx */ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 9, 27, 27, 27, 27, 27, -/* Cx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Dx */ 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 27, 27, 27, 27, 27, -/* Ex */ 27, 27, 1, 1, 1, 1, 1, 0, 1, 1, 27, 27, 27, 27, 27, 27, -/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 27, 27, 27, 27, 27, 27, +/* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 3x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 4x */ 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10, +/* 5x */ 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 15, 4, 21, 18, 19, 28, +/* 6x */ 11, 16, 28, 28, 28, 28, 28, 28, 28, 28, 28, 23, 22, 2, 13, 6, +/* 7x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 8, 5, 5, 5, 8, 14, 8, +/* 8x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* 9x */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ax */ 28, 25, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Bx */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 9, 28, 28, 28, 28, 28, +/* Cx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Dx */ 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 28, 28, 28, 28, 28, +/* Ex */ 28, 28, 1, 1, 1, 1, 1, 0, 2, 2, 28, 28, 28, 28, 28, 28, +/* Fx */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 28, 28, 28, 28, 28, 28, #endif }; @@ -160228,20 +162387,21 @@ const unsigned char ebcdicToAscii[] = { ** is substantially reduced. This is important for embedded applications ** on platforms with limited memory. */ -/* Hash score: 227 */ -/* zKWText[] encodes 984 bytes of keyword text in 648 bytes */ +/* Hash score: 231 */ +/* zKWText[] encodes 1007 bytes of keyword text in 667 bytes */ /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ /* ABLEFTHENDEFERRABLELSEXCLUDELETEMPORARYISNULLSAVEPOINTERSECT */ /* IESNOTNULLIKEXCEPTRANSACTIONATURALTERAISEXCLUSIVEXISTS */ /* CONSTRAINTOFFSETRIGGERANGENERATEDETACHAVINGLOBEGINNEREFERENCES */ /* UNIQUERYWITHOUTERELEASEATTACHBETWEENOTHINGROUPSCASCADEFAULT */ /* CASECOLLATECREATECURRENT_DATEIMMEDIATEJOINSERTMATCHPLANALYZE */ -/* PRAGMABORTUPDATEVALUESVIRTUALWAYSWHENWHERECURSIVEAFTERENAMEAND */ -/* EFERREDISTINCTAUTOINCREMENTCASTCOLUMNCOMMITCONFLICTCROSS */ -/* CURRENT_TIMESTAMPARTITIONDROPRECEDINGFAILASTFILTEREPLACEFIRST */ -/* FOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVERIGHTROLLBACKROWS */ -/* UNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBYINITIALLYPRIMARY */ -static const char zKWText[647] = { +/* PRAGMATERIALIZEDEFERREDISTINCTUPDATEVALUESVIRTUALWAYSWHENWHERE */ +/* CURSIVEABORTAFTERENAMEANDROPARTITIONAUTOINCREMENTCASTCOLUMN */ +/* COMMITCONFLICTCROSSCURRENT_TIMESTAMPRECEDINGFAILASTFILTER */ +/* EPLACEFIRSTFOLLOWINGFROMFULLIMITIFORDERESTRICTOTHERSOVER */ +/* ETURNINGRIGHTROLLBACKROWSUNBOUNDEDUNIONUSINGVACUUMVIEWINDOWBY */ +/* INITIALLYPRIMARY */ +static const char zKWText[666] = { 'R','E','I','N','D','E','X','E','D','E','S','C','A','P','E','A','C','H', 'E','C','K','E','Y','B','E','F','O','R','E','I','G','N','O','R','E','G', 'E','X','P','L','A','I','N','S','T','E','A','D','D','A','T','A','B','A', @@ -160262,86 +162422,87 @@ static const char zKWText[647] = { 'C','R','E','A','T','E','C','U','R','R','E','N','T','_','D','A','T','E', 'I','M','M','E','D','I','A','T','E','J','O','I','N','S','E','R','T','M', 'A','T','C','H','P','L','A','N','A','L','Y','Z','E','P','R','A','G','M', - 'A','B','O','R','T','U','P','D','A','T','E','V','A','L','U','E','S','V', - 'I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H','E','R', - 'E','C','U','R','S','I','V','E','A','F','T','E','R','E','N','A','M','E', - 'A','N','D','E','F','E','R','R','E','D','I','S','T','I','N','C','T','A', - 'U','T','O','I','N','C','R','E','M','E','N','T','C','A','S','T','C','O', - 'L','U','M','N','C','O','M','M','I','T','C','O','N','F','L','I','C','T', - 'C','R','O','S','S','C','U','R','R','E','N','T','_','T','I','M','E','S', - 'T','A','M','P','A','R','T','I','T','I','O','N','D','R','O','P','R','E', - 'C','E','D','I','N','G','F','A','I','L','A','S','T','F','I','L','T','E', - 'R','E','P','L','A','C','E','F','I','R','S','T','F','O','L','L','O','W', - 'I','N','G','F','R','O','M','F','U','L','L','I','M','I','T','I','F','O', - 'R','D','E','R','E','S','T','R','I','C','T','O','T','H','E','R','S','O', - 'V','E','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O','W', - 'S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S','I', - 'N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W','B', - 'Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', + 'A','T','E','R','I','A','L','I','Z','E','D','E','F','E','R','R','E','D', + 'I','S','T','I','N','C','T','U','P','D','A','T','E','V','A','L','U','E', + 'S','V','I','R','T','U','A','L','W','A','Y','S','W','H','E','N','W','H', + 'E','R','E','C','U','R','S','I','V','E','A','B','O','R','T','A','F','T', + 'E','R','E','N','A','M','E','A','N','D','R','O','P','A','R','T','I','T', + 'I','O','N','A','U','T','O','I','N','C','R','E','M','E','N','T','C','A', + 'S','T','C','O','L','U','M','N','C','O','M','M','I','T','C','O','N','F', + 'L','I','C','T','C','R','O','S','S','C','U','R','R','E','N','T','_','T', + 'I','M','E','S','T','A','M','P','R','E','C','E','D','I','N','G','F','A', + 'I','L','A','S','T','F','I','L','T','E','R','E','P','L','A','C','E','F', + 'I','R','S','T','F','O','L','L','O','W','I','N','G','F','R','O','M','F', + 'U','L','L','I','M','I','T','I','F','O','R','D','E','R','E','S','T','R', + 'I','C','T','O','T','H','E','R','S','O','V','E','R','E','T','U','R','N', + 'I','N','G','R','I','G','H','T','R','O','L','L','B','A','C','K','R','O', + 'W','S','U','N','B','O','U','N','D','E','D','U','N','I','O','N','U','S', + 'I','N','G','V','A','C','U','U','M','V','I','E','W','I','N','D','O','W', + 'B','Y','I','N','I','T','I','A','L','L','Y','P','R','I','M','A','R','Y', }; /* aKWHash[i] is the hash value for the i-th keyword */ static const unsigned char aKWHash[127] = { - 84, 102, 132, 82, 114, 29, 0, 0, 91, 0, 85, 72, 0, - 53, 35, 86, 15, 0, 42, 94, 54, 126, 133, 19, 0, 0, - 138, 0, 40, 128, 0, 22, 104, 0, 9, 0, 0, 122, 80, - 0, 78, 6, 0, 65, 99, 145, 0, 134, 112, 0, 0, 48, - 0, 100, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 140, - 107, 121, 0, 73, 101, 71, 143, 61, 119, 74, 0, 49, 0, - 11, 41, 0, 110, 0, 0, 0, 106, 10, 108, 113, 124, 14, - 50, 123, 0, 89, 0, 18, 120, 142, 56, 129, 137, 88, 83, - 37, 30, 125, 0, 0, 105, 51, 130, 127, 0, 34, 0, 0, - 44, 0, 95, 38, 39, 0, 20, 45, 116, 90, + 84, 92, 134, 82, 105, 29, 0, 0, 94, 0, 85, 72, 0, + 53, 35, 86, 15, 0, 42, 97, 54, 89, 135, 19, 0, 0, + 140, 0, 40, 129, 0, 22, 107, 0, 9, 0, 0, 123, 80, + 0, 78, 6, 0, 65, 103, 147, 0, 136, 115, 0, 0, 48, + 0, 90, 24, 0, 17, 0, 27, 70, 23, 26, 5, 60, 142, + 110, 122, 0, 73, 91, 71, 145, 61, 120, 74, 0, 49, 0, + 11, 41, 0, 113, 0, 0, 0, 109, 10, 111, 116, 125, 14, + 50, 124, 0, 100, 0, 18, 121, 144, 56, 130, 139, 88, 83, + 37, 30, 126, 0, 0, 108, 51, 131, 128, 0, 34, 0, 0, + 132, 0, 98, 38, 39, 0, 20, 45, 117, 93, }; /* aKWNext[] forms the hash collision chain. If aKWHash[i]==0 ** then the i-th keyword has no more hash collisions. Otherwise, ** the next keyword with the same hash is aKWHash[i]-1. */ -static const unsigned char aKWNext[145] = { - 0, 0, 0, 0, 4, 0, 43, 0, 0, 103, 111, 0, 0, - 0, 2, 0, 0, 141, 0, 0, 0, 13, 0, 0, 0, 0, - 139, 0, 0, 118, 52, 0, 0, 135, 12, 0, 0, 62, 0, - 136, 0, 131, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, +static const unsigned char aKWNext[147] = { + 0, 0, 0, 0, 4, 0, 43, 0, 0, 106, 114, 0, 0, + 0, 2, 0, 0, 143, 0, 0, 0, 13, 0, 0, 0, 0, + 141, 0, 0, 119, 52, 0, 0, 137, 12, 0, 0, 62, 0, + 138, 0, 133, 0, 0, 36, 0, 0, 28, 77, 0, 0, 0, 0, 59, 0, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 69, 0, 0, 0, 0, 0, 144, 3, 0, 58, 0, 1, - 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 64, 66, - 63, 0, 0, 0, 0, 46, 0, 16, 0, 115, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 81, 97, 0, 8, 0, 109, - 21, 7, 67, 0, 79, 93, 117, 0, 0, 68, 0, 0, 96, - 0, 55, 0, 76, 0, 92, 32, 33, 57, 25, 0, 98, 0, - 0, 87, + 0, 69, 0, 0, 0, 0, 0, 146, 3, 0, 58, 0, 1, + 75, 0, 0, 0, 31, 0, 0, 0, 0, 0, 127, 0, 104, + 0, 64, 66, 63, 0, 0, 0, 0, 0, 46, 0, 16, 8, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 101, 0, + 112, 21, 7, 67, 0, 79, 96, 118, 0, 0, 68, 0, 0, + 99, 44, 0, 55, 0, 76, 0, 95, 32, 33, 57, 25, 0, + 102, 0, 0, 87, }; /* aKWLen[i] is the length (in bytes) of the i-th keyword */ -static const unsigned char aKWLen[145] = { +static const unsigned char aKWLen[147] = { 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 7, 6, 9, 4, 2, 6, 5, 9, 9, 4, 7, 3, 2, 4, 4, 6, 11, 6, 2, 7, 5, 5, 9, 6, 10, 4, 6, 2, 3, 7, 5, 9, 6, 6, 4, 5, 5, 10, 6, 5, 7, 4, 5, 7, 6, 7, 7, 6, 5, 7, 3, 7, 4, - 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 5, 6, 6, - 7, 6, 4, 5, 9, 5, 6, 3, 8, 8, 2, 13, 2, - 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, 4, 9, 4, - 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, 4, - 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, 2, 9, - 3, 7, + 7, 6, 12, 9, 4, 6, 5, 4, 7, 6, 12, 8, 8, + 2, 6, 6, 7, 6, 4, 5, 9, 5, 5, 6, 3, 4, + 9, 13, 2, 2, 4, 6, 6, 8, 5, 17, 12, 7, 9, + 4, 4, 6, 7, 5, 9, 4, 4, 5, 2, 5, 8, 6, + 4, 9, 5, 8, 4, 3, 9, 5, 5, 6, 4, 6, 2, + 2, 9, 3, 7, }; /* aKWOffset[i] is the index into zKWText[] of the start of ** the text for the i-th keyword. */ -static const unsigned short int aKWOffset[145] = { +static const unsigned short int aKWOffset[147] = { 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, 86, 90, 90, 94, 99, 101, 105, 111, 119, 123, 123, 123, 126, 129, 132, 137, 142, 146, 147, 152, 156, 160, 168, 174, 181, 184, 184, 187, 189, 195, 198, 206, 211, 216, 219, 222, 226, 236, 239, 244, 244, 248, 252, 259, 265, 271, 277, 277, 283, 284, 288, 295, - 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 360, 365, 371, - 377, 382, 388, 392, 395, 404, 408, 414, 416, 423, 424, 431, 433, - 435, 444, 448, 454, 460, 468, 473, 473, 473, 489, 498, 501, 510, - 513, 517, 522, 529, 534, 543, 547, 550, 555, 557, 561, 569, 575, - 578, 583, 591, 591, 595, 604, 609, 614, 620, 623, 626, 629, 631, - 636, 640, + 299, 306, 312, 324, 333, 335, 341, 346, 348, 355, 359, 370, 377, + 378, 385, 391, 397, 402, 408, 412, 415, 424, 429, 433, 439, 441, + 444, 453, 455, 457, 466, 470, 476, 482, 490, 495, 495, 495, 511, + 520, 523, 527, 532, 539, 544, 553, 557, 560, 565, 567, 571, 579, + 585, 588, 597, 602, 610, 610, 614, 623, 628, 633, 639, 642, 645, + 648, 650, 655, 659, }; /* aKWCode[i] is the parser symbol code for the i-th keyword */ -static const unsigned char aKWCode[145] = { +static const unsigned char aKWCode[147] = { TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, @@ -160359,18 +162520,19 @@ static const unsigned char aKWCode[145] = { TK_BETWEEN, TK_NOTHING, TK_GROUPS, TK_GROUP, TK_CASCADE, TK_ASC, TK_DEFAULT, TK_CASE, TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_IMMEDIATE, TK_JOIN, TK_INSERT, TK_MATCH, - TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT, TK_UPDATE, - TK_VALUES, TK_VIRTUAL, TK_ALWAYS, TK_WHEN, TK_WHERE, - TK_RECURSIVE, TK_AFTER, TK_RENAME, TK_AND, TK_DEFERRED, - TK_DISTINCT, TK_IS, TK_AUTOINCR, TK_TO, TK_IN, - TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, - TK_CTIME_KW, TK_CTIME_KW, TK_CURRENT, TK_PARTITION, TK_DROP, - TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, TK_REPLACE, - TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, TK_LIMIT, - TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, TK_OVER, - TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, TK_ROW, TK_UNBOUNDED, - TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_WINDOW, - TK_DO, TK_BY, TK_INITIALLY, TK_ALL, TK_PRIMARY, + TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_MATERIALIZED, TK_DEFERRED, + TK_DISTINCT, TK_IS, TK_UPDATE, TK_VALUES, TK_VIRTUAL, + TK_ALWAYS, TK_WHEN, TK_WHERE, TK_RECURSIVE, TK_ABORT, + TK_AFTER, TK_RENAME, TK_AND, TK_DROP, TK_PARTITION, + TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, + TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, + TK_CURRENT, TK_PRECEDING, TK_FAIL, TK_LAST, TK_FILTER, + TK_REPLACE, TK_FIRST, TK_FOLLOWING, TK_FROM, TK_JOIN_KW, + TK_LIMIT, TK_IF, TK_ORDER, TK_RESTRICT, TK_OTHERS, + TK_OVER, TK_RETURNING, TK_JOIN_KW, TK_ROLLBACK, TK_ROWS, + TK_ROW, TK_UNBOUNDED, TK_UNION, TK_USING, TK_VACUUM, + TK_VIEW, TK_WINDOW, TK_DO, TK_BY, TK_INITIALLY, + TK_ALL, TK_PRIMARY, }; /* Hash table decoded: ** 0: INSERT @@ -160394,7 +162556,7 @@ static const unsigned char aKWCode[145] = { ** 18: TRANSACTION RIGHT ** 19: WHEN ** 20: SET HAVING -** 21: IF +** 21: MATERIALIZED IF ** 22: ROWS ** 23: SELECT ** 24: @@ -160490,7 +162652,7 @@ static const unsigned char aKWCode[145] = { ** 114: INTERSECT UNBOUNDED ** 115: ** 116: -** 117: ON +** 117: RETURNING ON ** 118: ** 119: WHERE ** 120: NO INNER @@ -160508,7 +162670,7 @@ static int keywordCode(const char *z, int n, int *pType){ int i, j; const char *zKW; if( n>=2 ){ - i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n) % 127; + i = ((charMap(z[0])*4) ^ (charMap(z[n-1])*3) ^ n*1) % 127; for(i=((int)aKWHash[i])-1; i>=0; i=((int)aKWNext[i])-1){ if( aKWLen[i]!=n ) continue; zKW = &zKWText[aKWOffset[i]]; @@ -160613,63 +162775,65 @@ static int keywordCode(const char *z, int n, int *pType){ testcase( i==85 ); /* PLAN */ testcase( i==86 ); /* ANALYZE */ testcase( i==87 ); /* PRAGMA */ - testcase( i==88 ); /* ABORT */ - testcase( i==89 ); /* UPDATE */ - testcase( i==90 ); /* VALUES */ - testcase( i==91 ); /* VIRTUAL */ - testcase( i==92 ); /* ALWAYS */ - testcase( i==93 ); /* WHEN */ - testcase( i==94 ); /* WHERE */ - testcase( i==95 ); /* RECURSIVE */ - testcase( i==96 ); /* AFTER */ - testcase( i==97 ); /* RENAME */ - testcase( i==98 ); /* AND */ - testcase( i==99 ); /* DEFERRED */ - testcase( i==100 ); /* DISTINCT */ - testcase( i==101 ); /* IS */ - testcase( i==102 ); /* AUTOINCREMENT */ - testcase( i==103 ); /* TO */ - testcase( i==104 ); /* IN */ - testcase( i==105 ); /* CAST */ - testcase( i==106 ); /* COLUMN */ - testcase( i==107 ); /* COMMIT */ - testcase( i==108 ); /* CONFLICT */ - testcase( i==109 ); /* CROSS */ - testcase( i==110 ); /* CURRENT_TIMESTAMP */ - testcase( i==111 ); /* CURRENT_TIME */ - testcase( i==112 ); /* CURRENT */ - testcase( i==113 ); /* PARTITION */ - testcase( i==114 ); /* DROP */ - testcase( i==115 ); /* PRECEDING */ - testcase( i==116 ); /* FAIL */ - testcase( i==117 ); /* LAST */ - testcase( i==118 ); /* FILTER */ - testcase( i==119 ); /* REPLACE */ - testcase( i==120 ); /* FIRST */ - testcase( i==121 ); /* FOLLOWING */ - testcase( i==122 ); /* FROM */ - testcase( i==123 ); /* FULL */ - testcase( i==124 ); /* LIMIT */ - testcase( i==125 ); /* IF */ - testcase( i==126 ); /* ORDER */ - testcase( i==127 ); /* RESTRICT */ - testcase( i==128 ); /* OTHERS */ - testcase( i==129 ); /* OVER */ - testcase( i==130 ); /* RIGHT */ - testcase( i==131 ); /* ROLLBACK */ - testcase( i==132 ); /* ROWS */ - testcase( i==133 ); /* ROW */ - testcase( i==134 ); /* UNBOUNDED */ - testcase( i==135 ); /* UNION */ - testcase( i==136 ); /* USING */ - testcase( i==137 ); /* VACUUM */ - testcase( i==138 ); /* VIEW */ - testcase( i==139 ); /* WINDOW */ - testcase( i==140 ); /* DO */ - testcase( i==141 ); /* BY */ - testcase( i==142 ); /* INITIALLY */ - testcase( i==143 ); /* ALL */ - testcase( i==144 ); /* PRIMARY */ + testcase( i==88 ); /* MATERIALIZED */ + testcase( i==89 ); /* DEFERRED */ + testcase( i==90 ); /* DISTINCT */ + testcase( i==91 ); /* IS */ + testcase( i==92 ); /* UPDATE */ + testcase( i==93 ); /* VALUES */ + testcase( i==94 ); /* VIRTUAL */ + testcase( i==95 ); /* ALWAYS */ + testcase( i==96 ); /* WHEN */ + testcase( i==97 ); /* WHERE */ + testcase( i==98 ); /* RECURSIVE */ + testcase( i==99 ); /* ABORT */ + testcase( i==100 ); /* AFTER */ + testcase( i==101 ); /* RENAME */ + testcase( i==102 ); /* AND */ + testcase( i==103 ); /* DROP */ + testcase( i==104 ); /* PARTITION */ + testcase( i==105 ); /* AUTOINCREMENT */ + testcase( i==106 ); /* TO */ + testcase( i==107 ); /* IN */ + testcase( i==108 ); /* CAST */ + testcase( i==109 ); /* COLUMN */ + testcase( i==110 ); /* COMMIT */ + testcase( i==111 ); /* CONFLICT */ + testcase( i==112 ); /* CROSS */ + testcase( i==113 ); /* CURRENT_TIMESTAMP */ + testcase( i==114 ); /* CURRENT_TIME */ + testcase( i==115 ); /* CURRENT */ + testcase( i==116 ); /* PRECEDING */ + testcase( i==117 ); /* FAIL */ + testcase( i==118 ); /* LAST */ + testcase( i==119 ); /* FILTER */ + testcase( i==120 ); /* REPLACE */ + testcase( i==121 ); /* FIRST */ + testcase( i==122 ); /* FOLLOWING */ + testcase( i==123 ); /* FROM */ + testcase( i==124 ); /* FULL */ + testcase( i==125 ); /* LIMIT */ + testcase( i==126 ); /* IF */ + testcase( i==127 ); /* ORDER */ + testcase( i==128 ); /* RESTRICT */ + testcase( i==129 ); /* OTHERS */ + testcase( i==130 ); /* OVER */ + testcase( i==131 ); /* RETURNING */ + testcase( i==132 ); /* RIGHT */ + testcase( i==133 ); /* ROLLBACK */ + testcase( i==134 ); /* ROWS */ + testcase( i==135 ); /* ROW */ + testcase( i==136 ); /* UNBOUNDED */ + testcase( i==137 ); /* UNION */ + testcase( i==138 ); /* USING */ + testcase( i==139 ); /* VACUUM */ + testcase( i==140 ); /* VIEW */ + testcase( i==141 ); /* WINDOW */ + testcase( i==142 ); /* DO */ + testcase( i==143 ); /* BY */ + testcase( i==144 ); /* INITIALLY */ + testcase( i==145 ); /* ALL */ + testcase( i==146 ); /* PRIMARY */ *pType = aKWCode[i]; break; } @@ -160681,7 +162845,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ keywordCode((char*)z, n, &id); return id; } -#define SQLITE_N_KEYWORD 145 +#define SQLITE_N_KEYWORD 147 SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; *pzName = zKWText + aKWOffset[i]; @@ -161050,7 +163214,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ if( n==0 ) *tokenType = TK_ILLEGAL; return i; } - case CC_KYWD: { + case CC_KYWD0: { for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} if( IdChar(z[i]) ){ /* This token started out using characters that can appear in keywords, @@ -161080,6 +163244,7 @@ SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ ** SQL keywords start with the letter 'x'. Fall through */ /* no break */ deliberate_fall_through } + case CC_KYWD: case CC_ID: { i = 1; break; @@ -161262,19 +163427,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr if( !IN_RENAME_OBJECT ){ sqlite3DeleteTrigger(db, pParse->pNewTrigger); } - - if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); sqlite3DbFree(db, pParse->pVList); - while( pParse->pAinc ){ - AutoincInfo *p = pParse->pAinc; - pParse->pAinc = p->pNext; - sqlite3DbFreeNN(db, p); - } - while( pParse->pZombieTab ){ - Table *p = pParse->pZombieTab; - pParse->pZombieTab = p->pNextZombie; - sqlite3DeleteTable(db, p); - } db->pParse = pParse->pParentParse; pParse->pParentParse = 0; assert( nErr==0 || pParse->rc!=SQLITE_OK ); @@ -164181,7 +166334,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( return SQLITE_OK; #else int rc; /* Return code */ - int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ + int iDb; /* Schema to checkpoint */ #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; @@ -164204,6 +166357,8 @@ SQLITE_API int sqlite3_wal_checkpoint_v2( sqlite3_mutex_enter(db->mutex); if( zDb && zDb[0] ){ iDb = sqlite3FindDbName(db, zDb); + }else{ + iDb = SQLITE_MAX_DB; /* This means process all schemas */ } if( iDb<0 ){ rc = SQLITE_ERROR; @@ -164252,7 +166407,7 @@ SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ ** associated with the specific b-tree being checkpointed is taken by ** this function while the checkpoint is running. ** -** If iDb is passed SQLITE_MAX_ATTACHED, then all attached databases are +** If iDb is passed SQLITE_MAX_DB then all attached databases are ** checkpointed. If an error is encountered it is returned immediately - ** no attempt is made to checkpoint any remaining databases. ** @@ -164267,9 +166422,11 @@ SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog assert( sqlite3_mutex_held(db->mutex) ); assert( !pnLog || *pnLog==-1 ); assert( !pnCkpt || *pnCkpt==-1 ); + testcase( iDb==SQLITE_MAX_ATTACHED ); /* See forum post a006d86f72 */ + testcase( iDb==SQLITE_MAX_DB ); for(i=0; inDb && rc==SQLITE_OK; i++){ - if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ + if( i==iDb || iDb==SQLITE_MAX_DB ){ rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); pnLog = 0; pnCkpt = 0; @@ -165887,7 +168044,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { sqlite3 *db = va_arg(ap, sqlite3*); - db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); + db->dbOptFlags = va_arg(ap, u32); break; } @@ -166062,7 +168219,26 @@ SQLITE_API int sqlite3_test_control(int op, ...){ break; } - + /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) + ** + ** "ptr" is a pointer to a u32. + ** + ** op==0 Store the current sqlite3SelectTrace in *ptr + ** op==1 Set sqlite3SelectTrace to the value *ptr + ** op==3 Store the current sqlite3WhereTrace in *ptr + ** op==3 Set sqlite3WhereTrace to the value *ptr + */ + case SQLITE_TESTCTRL_TRACEFLAGS: { + int opTrace = va_arg(ap, int); + u32 *ptr = va_arg(ap, u32*); + switch( opTrace ){ + case 0: *ptr = sqlite3SelectTrace; break; + case 1: sqlite3SelectTrace = *ptr; break; + case 2: *ptr = sqlite3WhereTrace; break; + case 3: sqlite3WhereTrace = *ptr; break; + } + break; + } } va_end(ap); #endif /* SQLITE_UNTESTABLE */ @@ -172947,9 +175123,9 @@ static int fts3EvalNearTrim( ); if( res ){ nNew = (int)(pOut - pPhrase->doclist.pList) - 1; - if( nNew>=0 ){ + assert_fts3_nc( nNew<=pPhrase->doclist.nList && nNew>0 ); + if( nNew>=0 && nNew<=pPhrase->doclist.nList ){ assert( pPhrase->doclist.pList[nNew]=='\0' ); - assert( nNew<=pPhrase->doclist.nList && nNew>0 ); memset(&pPhrase->doclist.pList[nNew], 0, pPhrase->doclist.nList - nNew); pPhrase->doclist.nList = nNew; } @@ -174883,6 +177059,11 @@ static int getNextNode( if( *zInput=='(' ){ int nConsumed = 0; pParse->nNest++; +#if !defined(SQLITE_MAX_EXPR_DEPTH) + if( pParse->nNest>1000 ) return SQLITE_ERROR; +#elif SQLITE_MAX_EXPR_DEPTH>0 + if( pParse->nNest>SQLITE_MAX_EXPR_DEPTH ) return SQLITE_ERROR; +#endif rc = fts3ExprParse(pParse, zInput+1, nInput-1, ppExpr, &nConsumed); *pnConsumed = (int)(zInput - z) + 1 + nConsumed; return rc; @@ -182286,17 +184467,20 @@ static int fts3IncrmergeLoad( while( reader.aNode && rc==SQLITE_OK ) rc = nodeReaderNext(&reader); blobGrowBuffer(&pNode->key, reader.term.n, &rc); if( rc==SQLITE_OK ){ - memcpy(pNode->key.a, reader.term.a, reader.term.n); + assert_fts3_nc( reader.term.n>0 || reader.aNode==0 ); + if( reader.term.n>0 ){ + memcpy(pNode->key.a, reader.term.a, reader.term.n); + } pNode->key.n = reader.term.n; if( i>0 ){ char *aBlock = 0; int nBlock = 0; pNode = &pWriter->aNodeWriter[i-1]; pNode->iBlock = reader.iChild; - rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); + ); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; @@ -185784,6 +187968,7 @@ static int unicodeOpen( pCsr->aInput = (const unsigned char *)aInput; if( aInput==0 ){ pCsr->nInput = 0; + pCsr->aInput = (const unsigned char*)""; }else if( nInput<0 ){ pCsr->nInput = (int)strlen(aInput); }else{ @@ -201539,22 +203724,24 @@ static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ #endif assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); - if( pRbu && (pRbu->eStage==RBU_STAGE_OAL || pRbu->eStage==RBU_STAGE_MOVE) ){ - /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from - ** taking this lock also prevents any checkpoints from occurring. - ** todo: really, it's not clear why this might occur, as - ** wal_autocheckpoint ought to be turned off. */ + if( pRbu && ( + pRbu->eStage==RBU_STAGE_OAL + || pRbu->eStage==RBU_STAGE_MOVE + || pRbu->eStage==RBU_STAGE_DONE + )){ + /* Prevent SQLite from taking a shm-lock on the target file when it + ** is supplying heap memory to the upper layer in place of *-shm + ** segments. */ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY; }else{ int bCapture = 0; if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ bCapture = 1; } - if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags); if( bCapture && rc==SQLITE_OK ){ - pRbu->mLock |= (1 << ofst); + pRbu->mLock |= ((1<nMalloc += sqlite3_msize(pRet); + return pRet; +} + +/* +** Free buffer pFree, which must have been allocated by an earlier +** call to sessionMalloc64(). If pSession is not NULL, decrease the +** sqlite3_session.nMalloc counter by the number of bytes freed. +*/ +static void sessionFree(sqlite3_session *pSession, void *pFree){ + if( pSession ) pSession->nMalloc -= sqlite3_msize(pFree); + sqlite3_free(pFree); +} /* ** This macro is used to calculate hash key values for data structures. In @@ -204191,13 +206400,19 @@ static int sessionPreupdateEqual( ** Growing the hash table in this case is a performance optimization only, ** it is not required for correct operation. */ -static int sessionGrowHash(int bPatchset, SessionTable *pTab){ +static int sessionGrowHash( + sqlite3_session *pSession, /* For memory accounting. May be NULL */ + int bPatchset, + SessionTable *pTab +){ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ int i; SessionChange **apNew; sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128); - apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew); + apNew = (SessionChange**)sessionMalloc64( + pSession, sizeof(SessionChange*) * nNew + ); if( apNew==0 ){ if( pTab->nChange==0 ){ return SQLITE_ERROR; @@ -204218,7 +206433,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - sqlite3_free(pTab->apChange); + sessionFree(pSession, pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -204252,6 +206467,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ ** be freed using sqlite3_free() by the caller */ static int sessionTableInfo( + sqlite3_session *pSession, /* For memory accounting. May be NULL */ sqlite3 *db, /* Database connection */ const char *zDb, /* Name of attached database (e.g. "main") */ const char *zThis, /* Table name */ @@ -204306,7 +206522,7 @@ static int sessionTableInfo( if( rc==SQLITE_OK ){ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); - pAlloc = sqlite3_malloc64(nByte); + pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; } @@ -204349,7 +206565,7 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - sqlite3_free(azCol); + sessionFree(pSession, azCol); } sqlite3_finalize(pStmt); return rc; @@ -204371,7 +206587,7 @@ static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - pSession->rc = sessionTableInfo(pSession->db, pSession->zDb, + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK ); if( pSession->rc==SQLITE_OK ){ @@ -204462,7 +206678,7 @@ static void sessionPreupdateOneChange( } /* Grow the hash table if required */ - if( sessionGrowHash(0, pTab) ){ + if( sessionGrowHash(pSession, 0, pTab) ){ pSession->rc = SQLITE_NOMEM; return; } @@ -204529,7 +206745,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)sqlite3_malloc64(nByte); + pChange = (SessionChange *)sessionMalloc64(pSession, nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -204902,7 +207118,7 @@ SQLITE_API int sqlite3session_diff( int nCol; /* Columns in zFrom.zTbl */ u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK); if( rc==SQLITE_OK ){ if( pTo->nCol!=nCol ){ bMismatch = 1; @@ -205000,7 +207216,7 @@ SQLITE_API int sqlite3session_create( ** Free the list of table objects passed as the first argument. The contents ** of the changed-rows hash tables are also deleted. */ -static void sessionDeleteTable(SessionTable *pList){ +static void sessionDeleteTable(sqlite3_session *pSession, SessionTable *pList){ SessionTable *pNext; SessionTable *pTab; @@ -205012,12 +207228,12 @@ static void sessionDeleteTable(SessionTable *pList){ SessionChange *pNextChange; for(p=pTab->apChange[i]; p; p=pNextChange){ pNextChange = p->pNext; - sqlite3_free(p); + sessionFree(pSession, p); } } - sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ - sqlite3_free(pTab->apChange); - sqlite3_free(pTab); + sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ + sessionFree(pSession, pTab->apChange); + sessionFree(pSession, pTab); } } @@ -205045,9 +207261,11 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ /* Delete all attached table objects. And the contents of their ** associated hash-tables. */ - sessionDeleteTable(pSession->pTable); + sessionDeleteTable(pSession, pSession->pTable); - /* Free the session object itself. */ + /* Assert that all allocations have been freed and then free the + ** session object itself. */ + assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -205094,7 +207312,8 @@ SQLITE_API int sqlite3session_attach( if( !pTab ){ /* Allocate new SessionTable object. */ - pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1); + int nByte = sizeof(SessionTable) + nName + 1; + pTab = (SessionTable*)sessionMalloc64(pSession, nByte); if( !pTab ){ rc = SQLITE_NOMEM; }else{ @@ -205691,7 +207910,7 @@ static int sessionGenerateChangeset( int nNoop; /* Size of buffer after writing tbl header */ /* Check the table schema is still Ok. */ - rc = sessionTableInfo(db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK); + rc = sessionTableInfo(0, db, pSession->zDb, zName, &nCol, 0,&azCol,&abPK); if( !rc && (pTab->nCol!=nCol || memcmp(abPK, pTab->abPK, nCol)) ){ rc = SQLITE_SCHEMA; } @@ -205866,6 +208085,13 @@ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){ return (ret==0); } +/* +** Return the amount of heap memory in use. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession){ + return pSession->nMalloc; +} + /* ** Do the work for either sqlite3changeset_start() or start_strm(). */ @@ -205875,7 +208101,8 @@ static int sessionChangesetStart( void *pIn, int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset, /* Pointer to buffer containing changeset */ - int bInvert /* True to invert changeset */ + int bInvert, /* True to invert changeset */ + int bSkipEmpty /* True to skip empty UPDATE changes */ ){ sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ @@ -205896,6 +208123,7 @@ static int sessionChangesetStart( pRet->in.pIn = pIn; pRet->in.bEof = (xInput ? 0 : 1); pRet->bInvert = bInvert; + pRet->bSkipEmpty = bSkipEmpty; /* Populate the output variable and return success. */ *pp = pRet; @@ -205910,7 +208138,7 @@ SQLITE_API int sqlite3changeset_start( int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset /* Pointer to buffer containing changeset */ ){ - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0, 0); } SQLITE_API int sqlite3changeset_start_v2( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -205919,7 +208147,7 @@ SQLITE_API int sqlite3changeset_start_v2( int flags ){ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); - return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert); + return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, bInvert, 0); } /* @@ -205930,7 +208158,7 @@ SQLITE_API int sqlite3changeset_start_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ){ - return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0, 0); } SQLITE_API int sqlite3changeset_start_v2_strm( sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ @@ -205939,7 +208167,7 @@ SQLITE_API int sqlite3changeset_start_v2_strm( int flags ){ int bInvert = !!(flags & SQLITE_CHANGESETSTART_INVERT); - return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert); + return sessionChangesetStart(pp, xInput, pIn, 0, 0, bInvert, 0); } /* @@ -206065,11 +208293,14 @@ static int sessionReadRecord( SessionInput *pIn, /* Input data */ int nCol, /* Number of values in record */ u8 *abPK, /* Array of primary key flags, or NULL */ - sqlite3_value **apOut /* Write values to this array */ + sqlite3_value **apOut, /* Write values to this array */ + int *pbEmpty ){ int i; /* Used to iterate through columns */ int rc = SQLITE_OK; + assert( pbEmpty==0 || *pbEmpty==0 ); + if( pbEmpty ) *pbEmpty = 1; for(i=0; iaData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ + if( pbEmpty ) *pbEmpty = 0; apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } @@ -206260,31 +208492,27 @@ static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ } /* -** Advance the changeset iterator to the next change. -** -** If both paRec and pnRec are NULL, then this function works like the public -** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the -** sqlite3changeset_new() and old() APIs may be used to query for values. +** Advance the changeset iterator to the next change. The differences between +** this function and sessionChangesetNext() are that ** -** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change -** record is written to *paRec before returning and the number of bytes in -** the record to *pnRec. +** * If pbEmpty is not NULL and the change is a no-op UPDATE (an UPDATE +** that modifies no columns), this function sets (*pbEmpty) to 1. ** -** Either way, this function returns SQLITE_ROW if the iterator is -** successfully advanced to the next change in the changeset, an SQLite -** error code if an error occurs, or SQLITE_DONE if there are no further -** changes in the changeset. +** * If the iterator is configured to skip no-op UPDATEs, +** sessionChangesetNext() does that. This function does not. */ -static int sessionChangesetNext( +static int sessionChangesetNextOne( sqlite3_changeset_iter *p, /* Changeset iterator */ u8 **paRec, /* If non-NULL, store record pointer here */ int *pnRec, /* If non-NULL, store size of record here */ - int *pbNew /* If non-NULL, true if new table */ + int *pbNew, /* If non-NULL, true if new table */ + int *pbEmpty ){ int i; u8 op; assert( (paRec==0 && pnRec==0) || (paRec && pnRec) ); + assert( pbEmpty==0 || *pbEmpty==0 ); /* If the iterator is in the error-state, return immediately. */ if( p->rc!=SQLITE_OK ) return p->rc; @@ -206357,13 +208585,13 @@ static int sessionChangesetNext( /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ u8 *abPK = p->bPatchset ? p->abPK : 0; - p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld); + p->rc = sessionReadRecord(&p->in, p->nCol, abPK, apOld, 0); if( p->rc!=SQLITE_OK ) return p->rc; } /* If this is an INSERT or UPDATE, read the new.* record. */ if( p->op!=SQLITE_DELETE ){ - p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew); + p->rc = sessionReadRecord(&p->in, p->nCol, 0, apNew, pbEmpty); if( p->rc!=SQLITE_OK ) return p->rc; } @@ -206390,6 +208618,37 @@ static int sessionChangesetNext( return SQLITE_ROW; } +/* +** Advance the changeset iterator to the next change. +** +** If both paRec and pnRec are NULL, then this function works like the public +** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the +** sqlite3changeset_new() and old() APIs may be used to query for values. +** +** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change +** record is written to *paRec before returning and the number of bytes in +** the record to *pnRec. +** +** Either way, this function returns SQLITE_ROW if the iterator is +** successfully advanced to the next change in the changeset, an SQLite +** error code if an error occurs, or SQLITE_DONE if there are no further +** changes in the changeset. +*/ +static int sessionChangesetNext( + sqlite3_changeset_iter *p, /* Changeset iterator */ + u8 **paRec, /* If non-NULL, store record pointer here */ + int *pnRec, /* If non-NULL, store size of record here */ + int *pbNew /* If non-NULL, true if new table */ +){ + int bEmpty; + int rc; + do { + bEmpty = 0; + rc = sessionChangesetNextOne(p, paRec, pnRec, pbNew, &bEmpty); + }while( rc==SQLITE_ROW && p->bSkipEmpty && bEmpty); + return rc; +} + /* ** Advance an iterator created by sqlite3changeset_start() to the next ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE @@ -206662,9 +208921,9 @@ static int sessionChangesetInvert( /* Read the old.* and new.* records for the update change. */ pInput->iNext += 2; - rc = sessionReadRecord(pInput, nCol, 0, &apVal[0]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[0], 0); if( rc==SQLITE_OK ){ - rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol]); + rc = sessionReadRecord(pInput, nCol, 0, &apVal[nCol], 0); } /* Write the new old.* record. Consists of the PK columns from the @@ -206765,16 +209024,25 @@ SQLITE_API int sqlite3changeset_invert_strm( return rc; } + +typedef struct SessionUpdate SessionUpdate; +struct SessionUpdate { + sqlite3_stmt *pStmt; + u32 *aMask; + SessionUpdate *pNext; +}; + typedef struct SessionApplyCtx SessionApplyCtx; struct SessionApplyCtx { sqlite3 *db; sqlite3_stmt *pDelete; /* DELETE statement */ - sqlite3_stmt *pUpdate; /* UPDATE statement */ sqlite3_stmt *pInsert; /* INSERT statement */ sqlite3_stmt *pSelect; /* SELECT statement */ int nCol; /* Size of azCol[] and abPK[] arrays */ const char **azCol; /* Array of column names */ u8 *abPK; /* Boolean array - true if column is in PK */ + u32 *aUpdateMask; /* Used by sessionUpdateFind */ + SessionUpdate *pUp; int bStat1; /* True if table is sqlite_stat1 */ int bDeferConstraints; /* True to defer constraints */ int bInvertConstraints; /* Invert when iterating constraints buffer */ @@ -206784,6 +209052,167 @@ struct SessionApplyCtx { u8 bRebase; /* True to collect rebase information */ }; +/* Number of prepared UPDATE statements to cache. */ +#define SESSION_UPDATE_CACHE_SZ 12 + +/* +** Find a prepared UPDATE statement suitable for the UPDATE step currently +** being visited by the iterator. The UPDATE is of the form: +** +** UPDATE tbl SET col = ?, col2 = ? WHERE pk1 IS ? AND pk2 IS ? +*/ +static int sessionUpdateFind( + sqlite3_changeset_iter *pIter, + SessionApplyCtx *p, + int bPatchset, + sqlite3_stmt **ppStmt +){ + int rc = SQLITE_OK; + SessionUpdate *pUp = 0; + int nCol = pIter->nCol; + int nU32 = (pIter->nCol+33)/32; + int ii; + + if( p->aUpdateMask==0 ){ + p->aUpdateMask = sqlite3_malloc(nU32*sizeof(u32)); + if( p->aUpdateMask==0 ){ + rc = SQLITE_NOMEM; + } + } + + if( rc==SQLITE_OK ){ + memset(p->aUpdateMask, 0, nU32*sizeof(u32)); + rc = SQLITE_CORRUPT; + for(ii=0; iinCol; ii++){ + if( sessionChangesetNew(pIter, ii) ){ + p->aUpdateMask[ii/32] |= (1<<(ii%32)); + rc = SQLITE_OK; + } + } + } + + if( rc==SQLITE_OK ){ + if( bPatchset ) p->aUpdateMask[nCol/32] |= (1<<(nCol%32)); + + if( p->pUp ){ + int nUp = 0; + SessionUpdate **pp = &p->pUp; + while( 1 ){ + nUp++; + if( 0==memcmp(p->aUpdateMask, (*pp)->aMask, nU32*sizeof(u32)) ){ + pUp = *pp; + *pp = pUp->pNext; + pUp->pNext = p->pUp; + p->pUp = pUp; + break; + } + + if( (*pp)->pNext ){ + pp = &(*pp)->pNext; + }else{ + if( nUp>=SESSION_UPDATE_CACHE_SZ ){ + sqlite3_finalize((*pp)->pStmt); + sqlite3_free(*pp); + *pp = 0; + } + break; + } + } + } + + if( pUp==0 ){ + int nByte = sizeof(SessionUpdate) * nU32*sizeof(u32); + int bStat1 = (sqlite3_stricmp(pIter->zTab, "sqlite_stat1")==0); + pUp = (SessionUpdate*)sqlite3_malloc(nByte); + if( pUp==0 ){ + rc = SQLITE_NOMEM; + }else{ + const char *zSep = ""; + SessionBuffer buf; + + memset(&buf, 0, sizeof(buf)); + pUp->aMask = (u32*)&pUp[1]; + memcpy(pUp->aMask, p->aUpdateMask, nU32*sizeof(u32)); + + sessionAppendStr(&buf, "UPDATE main.", &rc); + sessionAppendIdent(&buf, pIter->zTab, &rc); + sessionAppendStr(&buf, " SET ", &rc); + + /* Create the assignments part of the UPDATE */ + for(ii=0; iinCol; ii++){ + if( p->abPK[ii]==0 && sessionChangesetNew(pIter, ii) ){ + sessionAppendStr(&buf, zSep, &rc); + sessionAppendIdent(&buf, p->azCol[ii], &rc); + sessionAppendStr(&buf, " = ?", &rc); + sessionAppendInteger(&buf, ii*2+1, &rc); + zSep = ", "; + } + } + + /* Create the WHERE clause part of the UPDATE */ + zSep = ""; + sessionAppendStr(&buf, " WHERE ", &rc); + for(ii=0; iinCol; ii++){ + if( p->abPK[ii] || (bPatchset==0 && sessionChangesetOld(pIter, ii)) ){ + sessionAppendStr(&buf, zSep, &rc); + if( bStat1 && ii==1 ){ + assert( sqlite3_stricmp(p->azCol[ii], "idx")==0 ); + sessionAppendStr(&buf, + "idx IS CASE " + "WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL " + "ELSE ?4 END ", &rc + ); + }else{ + sessionAppendIdent(&buf, p->azCol[ii], &rc); + sessionAppendStr(&buf, " IS ?", &rc); + sessionAppendInteger(&buf, ii*2+2, &rc); + } + zSep = " AND "; + } + } + + if( rc==SQLITE_OK ){ + char *zSql = (char*)buf.aBuf; + rc = sqlite3_prepare_v2(p->db, zSql, buf.nBuf, &pUp->pStmt, 0); + } + + if( rc!=SQLITE_OK ){ + sqlite3_free(pUp); + pUp = 0; + }else{ + pUp->pNext = p->pUp; + p->pUp = pUp; + } + sqlite3_free(buf.aBuf); + } + } + } + + assert( (rc==SQLITE_OK)==(pUp!=0) ); + if( pUp ){ + *ppStmt = pUp->pStmt; + }else{ + *ppStmt = 0; + } + return rc; +} + +/* +** Free all cached UPDATE statements. +*/ +static void sessionUpdateFree(SessionApplyCtx *p){ + SessionUpdate *pUp; + SessionUpdate *pNext; + for(pUp=p->pUp; pUp; pUp=pNext){ + pNext = pUp->pNext; + sqlite3_finalize(pUp->pStmt); + sqlite3_free(pUp); + } + p->pUp = 0; + sqlite3_free(p->aUpdateMask); + p->aUpdateMask = 0; +} + /* ** Formulate a statement to DELETE a row from database db. Assuming a table ** structure like this: @@ -206853,103 +209282,6 @@ static int sessionDeleteRow( return rc; } -/* -** Formulate and prepare a statement to UPDATE a row from database db. -** Assuming a table structure like this: -** -** CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c)); -** -** The UPDATE statement looks like this: -** -** UPDATE x SET -** a = CASE WHEN ?2 THEN ?3 ELSE a END, -** b = CASE WHEN ?5 THEN ?6 ELSE b END, -** c = CASE WHEN ?8 THEN ?9 ELSE c END, -** d = CASE WHEN ?11 THEN ?12 ELSE d END -** WHERE a = ?1 AND c = ?7 AND (?13 OR -** (?5==0 OR b IS ?4) AND (?11==0 OR d IS ?10) AND -** ) -** -** For each column in the table, there are three variables to bind: -** -** ?(i*3+1) The old.* value of the column, if any. -** ?(i*3+2) A boolean flag indicating that the value is being modified. -** ?(i*3+3) The new.* value of the column, if any. -** -** Also, a boolean flag that, if set to true, causes the statement to update -** a row even if the non-PK values do not match. This is required if the -** conflict-handler is invoked with CHANGESET_DATA and returns -** CHANGESET_REPLACE. This is variable "?(nCol*3+1)". -** -** If successful, SQLITE_OK is returned and SessionApplyCtx.pUpdate is left -** pointing to the prepared version of the SQL statement. -*/ -static int sessionUpdateRow( - sqlite3 *db, /* Database handle */ - const char *zTab, /* Table name */ - SessionApplyCtx *p /* Session changeset-apply context */ -){ - int rc = SQLITE_OK; - int i; - const char *zSep = ""; - SessionBuffer buf = {0, 0, 0}; - - /* Append "UPDATE tbl SET " */ - sessionAppendStr(&buf, "UPDATE main.", &rc); - sessionAppendIdent(&buf, zTab, &rc); - sessionAppendStr(&buf, " SET ", &rc); - - /* Append the assignments */ - for(i=0; inCol; i++){ - sessionAppendStr(&buf, zSep, &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = CASE WHEN ?", &rc); - sessionAppendInteger(&buf, i*3+2, &rc); - sessionAppendStr(&buf, " THEN ?", &rc); - sessionAppendInteger(&buf, i*3+3, &rc); - sessionAppendStr(&buf, " ELSE ", &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " END", &rc); - zSep = ", "; - } - - /* Append the PK part of the WHERE clause */ - sessionAppendStr(&buf, " WHERE ", &rc); - for(i=0; inCol; i++){ - if( p->abPK[i] ){ - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " = ?", &rc); - sessionAppendInteger(&buf, i*3+1, &rc); - sessionAppendStr(&buf, " AND ", &rc); - } - } - - /* Append the non-PK part of the WHERE clause */ - sessionAppendStr(&buf, " (?", &rc); - sessionAppendInteger(&buf, p->nCol*3+1, &rc); - sessionAppendStr(&buf, " OR 1", &rc); - for(i=0; inCol; i++){ - if( !p->abPK[i] ){ - sessionAppendStr(&buf, " AND (?", &rc); - sessionAppendInteger(&buf, i*3+2, &rc); - sessionAppendStr(&buf, "=0 OR ", &rc); - sessionAppendIdent(&buf, p->azCol[i], &rc); - sessionAppendStr(&buf, " IS ?", &rc); - sessionAppendInteger(&buf, i*3+1, &rc); - sessionAppendStr(&buf, ")", &rc); - } - } - sessionAppendStr(&buf, ")", &rc); - - if( rc==SQLITE_OK ){ - rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0); - } - sqlite3_free(buf.aBuf); - - return rc; -} - - /* ** Formulate and prepare an SQL statement to query table zTab by primary ** key. Assuming the following table structure: @@ -207030,17 +209362,6 @@ static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ "?3)" ); } - if( rc==SQLITE_OK ){ - rc = sessionPrepare(db, &p->pUpdate, - "UPDATE main.sqlite_stat1 SET " - "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, " - "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, " - "stat = CASE WHEN ?8 THEN ?9 ELSE stat END " - "WHERE tbl=?1 AND idx IS " - "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END " - "AND (?10 OR ?8=0 OR stat IS ?7)" - ); - } if( rc==SQLITE_OK ){ rc = sessionPrepare(db, &p->pDelete, "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS " @@ -207357,7 +209678,7 @@ static int sessionApplyOneOp( int nCol; int rc = SQLITE_OK; - assert( p->pDelete && p->pUpdate && p->pInsert && p->pSelect ); + assert( p->pDelete && p->pInsert && p->pSelect ); assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); @@ -207397,29 +209718,28 @@ static int sessionApplyOneOp( }else if( op==SQLITE_UPDATE ){ int i; + sqlite3_stmt *pUp = 0; + int bPatchset = (pbRetry==0 || pIter->bPatchset); + + rc = sessionUpdateFind(pIter, p, bPatchset, &pUp); /* Bind values to the UPDATE statement. */ for(i=0; rc==SQLITE_OK && ipUpdate, i*3+2, !!pNew); - if( pOld ){ - rc = sessionBindValue(p->pUpdate, i*3+1, pOld); + if( p->abPK[i] || (bPatchset==0 && pOld) ){ + rc = sessionBindValue(pUp, i*2+2, pOld); } if( rc==SQLITE_OK && pNew ){ - rc = sessionBindValue(p->pUpdate, i*3+3, pNew); + rc = sessionBindValue(pUp, i*2+1, pNew); } } - if( rc==SQLITE_OK ){ - sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset); - } if( rc!=SQLITE_OK ) return rc; /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, ** the result will be SQLITE_OK with 0 rows modified. */ - sqlite3_step(p->pUpdate); - rc = sqlite3_reset(p->pUpdate); + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ /* A NOTFOUND or DATA error. Search the table to see if it contains @@ -207551,7 +209871,7 @@ static int sessionRetryConstraints( memset(&pApply->constraints, 0, sizeof(SessionBuffer)); rc = sessionChangesetStart( - &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints + &pIter2, 0, 0, cons.nBuf, cons.aBuf, pApply->bInvertConstraints, 1 ); if( rc==SQLITE_OK ){ size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); @@ -207642,14 +209962,13 @@ static int sessionChangesetApply( ); if( rc!=SQLITE_OK ) break; + sessionUpdateFree(&sApply); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pSelect); sApply.db = db; sApply.pDelete = 0; - sApply.pUpdate = 0; sApply.pInsert = 0; sApply.pSelect = 0; sApply.nCol = 0; @@ -207677,7 +209996,7 @@ static int sessionChangesetApply( int i; sqlite3changeset_pk(pIter, &abPK, 0); - rc = sessionTableInfo( + rc = sessionTableInfo(0, db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); if( rc!=SQLITE_OK ) break; @@ -207713,11 +210032,10 @@ static int sessionChangesetApply( } sApply.bStat1 = 1; }else{ - if((rc = sessionSelectRow(db, zTab, &sApply)) - || (rc = sessionUpdateRow(db, zTab, &sApply)) - || (rc = sessionDeleteRow(db, zTab, &sApply)) - || (rc = sessionInsertRow(db, zTab, &sApply)) - ){ + if( (rc = sessionSelectRow(db, zTab, &sApply)) + || (rc = sessionDeleteRow(db, zTab, &sApply)) + || (rc = sessionInsertRow(db, zTab, &sApply)) + ){ break; } sApply.bStat1 = 0; @@ -207776,9 +210094,9 @@ static int sessionChangesetApply( *pnRebase = sApply.rebase.nBuf; sApply.rebase.aBuf = 0; } + sessionUpdateFree(&sApply); sqlite3_finalize(sApply.pInsert); sqlite3_finalize(sApply.pDelete); - sqlite3_finalize(sApply.pUpdate); sqlite3_finalize(sApply.pSelect); sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ sqlite3_free((char*)sApply.constraints.aBuf); @@ -207809,8 +210127,8 @@ SQLITE_API int sqlite3changeset_apply_v2( int flags ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ - int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse); + int bInv = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); + int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset, bInv, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -207868,7 +210186,7 @@ SQLITE_API int sqlite3changeset_apply_v2_strm( ){ sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); - int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse); + int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse, 1); if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags @@ -208156,7 +210474,7 @@ static int sessionChangesetToHash( } } - if( sessionGrowHash(pIter->bPatchset, pTab) ){ + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; } @@ -208342,7 +210660,7 @@ SQLITE_API int sqlite3changegroup_output_strm( */ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ - sessionDeleteTable(pGrp->pList); + sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } } @@ -208488,7 +210806,7 @@ static void sessionAppendPartialUpdate( int n1 = sessionSerialLen(a1); int n2 = sessionSerialLen(a2); if( pIter->abPK[i] || a2[0]==0 ){ - if( !pIter->abPK[i] ) bData = 1; + if( !pIter->abPK[i] && a1[0] ) bData = 1; memcpy(pOut, a1, n1); pOut += n1; }else if( a2[0]!=0xFF ){ @@ -208743,7 +211061,7 @@ SQLITE_API int sqlite3rebaser_rebase_strm( */ SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ - sessionDeleteTable(p->grp.pList); + sessionDeleteTable(0, p->grp.pList); sqlite3_free(p); } } @@ -211205,55 +213523,6 @@ static fts5YYACTIONTYPE fts5yy_reduce( (void)fts5yyLookahead; (void)fts5yyLookaheadToken; fts5yymsp = fts5yypParser->fts5yytos; - assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); -#ifndef NDEBUG - if( fts5yyTraceFILE ){ - fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; - if( fts5yysize ){ - fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", - fts5yyTracePrompt, - fts5yyruleno, fts5yyRuleName[fts5yyruleno], - fts5yyrulenofts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){ - fts5yypParser->fts5yyhwm++; - assert( fts5yypParser->fts5yyhwm == (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); - } -#endif -#if fts5YYSTACKDEPTH>0 - if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ - fts5yyStackOverflow(fts5yypParser); - /* The call to fts5yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } -#else - if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ - if( fts5yyGrowStack(fts5yypParser) ){ - fts5yyStackOverflow(fts5yypParser); - /* The call to fts5yyStackOverflow() above pops the stack until it is - ** empty, causing the main parser loop to exit. So the return value - ** is never used and does not matter. */ - return 0; - } - fts5yymsp = fts5yypParser->fts5yytos; - } -#endif - } switch( fts5yyruleno ){ /* Beginning here are the reduction cases. A typical example @@ -211556,12 +213825,56 @@ static void sqlite3Fts5Parser( } #endif - do{ + while(1){ /* Exit by "break" */ + assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack ); assert( fts5yyact==fts5yypParser->fts5yytos->stateno ); fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact); if( fts5yyact >= fts5YY_MIN_REDUCE ){ - fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor, - fts5yyminor sqlite3Fts5ParserCTX_PARAM); + unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */ + assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) ); +#ifndef NDEBUG + if( fts5yyTraceFILE ){ + int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno]; + if( fts5yysize ){ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n", + fts5yyTracePrompt, + fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyrulenofts5yytos[fts5yysize].stateno); + }else{ + fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s.\n", + fts5yyTracePrompt, fts5yyruleno, fts5yyRuleName[fts5yyruleno], + fts5yyrulenofts5yytos - fts5yypParser->fts5yystack)>fts5yypParser->fts5yyhwm ){ + fts5yypParser->fts5yyhwm++; + assert( fts5yypParser->fts5yyhwm == + (int)(fts5yypParser->fts5yytos - fts5yypParser->fts5yystack)); + } +#endif +#if fts5YYSTACKDEPTH>0 + if( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystackEnd ){ + fts5yyStackOverflow(fts5yypParser); + break; + } +#else + if( fts5yypParser->fts5yytos>=&fts5yypParser->fts5yystack[fts5yypParser->fts5yystksz-1] ){ + if( fts5yyGrowStack(fts5yypParser) ){ + fts5yyStackOverflow(fts5yypParser); + break; + } + } +#endif + } + fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyruleno,fts5yymajor,fts5yyminor sqlite3Fts5ParserCTX_PARAM); }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor); #ifndef fts5YYNOERRORRECOVERY @@ -211674,7 +213987,7 @@ static void sqlite3Fts5Parser( break; #endif } - }while( fts5yypParser->fts5yytos>fts5yypParser->fts5yystack ); + } #ifndef NDEBUG if( fts5yyTraceFILE ){ fts5yyStackEntry *i; @@ -215286,8 +217599,8 @@ static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bD } /* If the iterator is not at a real match, skip forward until it is. */ - while( pRoot->bNomatch ){ - assert( pRoot->bEof==0 && rc==SQLITE_OK ); + while( pRoot->bNomatch && rc==SQLITE_OK ){ + assert( pRoot->bEof==0 ); rc = fts5ExprNodeNext(p, pRoot, 0, 0); } return rc; @@ -219472,14 +221785,10 @@ static void fts5SegIterNext( }else{ /* The following could be done by calling fts5SegIterLoadNPos(). But ** this block is particularly performance critical, so equivalent - ** code is inlined. - ** - ** Later: Switched back to fts5SegIterLoadNPos() because it supports - ** detail=none mode. Not ideal. - */ + ** code is inlined. */ int nSz; assert( p->rc==SQLITE_OK ); - assert( pIter->iLeafOffset<=pIter->pLeaf->nn ); + assert_nc( pIter->iLeafOffset<=pIter->pLeaf->nn ); fts5FastGetVarint32(pIter->pLeaf->p, pIter->iLeafOffset, nSz); pIter->bDel = (nSz & 0x0001); pIter->nPos = nSz>>1; @@ -220471,7 +222780,7 @@ static void fts5ChunkIterate( int pgno = pSeg->iLeafPgno; int pgnoSave = 0; - /* This function does notmwork with detail=none databases. */ + /* This function does not work with detail=none databases. */ assert( p->pConfig->eDetail!=FTS5_DETAIL_NONE ); if( (pSeg->flags & FTS5_SEGITER_REVERSE)==0 ){ @@ -220484,6 +222793,9 @@ static void fts5ChunkIterate( fts5DataRelease(pData); if( nRem<=0 ){ break; + }else if( pSeg->pSeg==0 ){ + p->rc = FTS5_CORRUPT; + return; }else{ pgno++; pData = fts5LeafRead(p, FTS5_SEGMENT_ROWID(pSeg->pSeg->iSegid, pgno)); @@ -220535,66 +222847,72 @@ static void fts5SegiterPoslist( } /* -** IN/OUT parameter (*pa) points to a position list n bytes in size. If -** the position list contains entries for column iCol, then (*pa) is set -** to point to the sub-position-list for that column and the number of -** bytes in it returned. Or, if the argument position list does not -** contain any entries for column iCol, return 0. +** Parameter pPos points to a buffer containing a position list, size nPos. +** This function filters it according to pColset (which must be non-NULL) +** and sets pIter->base.pData/nData to point to the new position list. +** If memory is required for the new position list, use buffer pIter->poslist. +** Or, if the new position list is a contiguous subset of the input, set +** pIter->base.pData/nData to point directly to it. +** +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. If an OOM error is encountered, *pRc is set to SQLITE_NOMEM +** before returning. */ -static int fts5IndexExtractCol( - const u8 **pa, /* IN/OUT: Pointer to poslist */ - int n, /* IN: Size of poslist in bytes */ - int iCol /* Column to extract from poslist */ -){ - int iCurrent = 0; /* Anything before the first 0x01 is col 0 */ - const u8 *p = *pa; - const u8 *pEnd = &p[n]; /* One byte past end of position list */ - - while( iCol>iCurrent ){ - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint. Note that it is not possible for a negative - ** or extremely large varint to occur within an uncorrupted position - ** list. So the last byte of each varint may be assumed to have a clear - ** 0x80 bit. */ - while( *p!=0x01 ){ - while( *p++ & 0x80 ); - if( p>=pEnd ) return 0; - } - *pa = p++; - iCurrent = *p++; - if( iCurrent & 0x80 ){ - p--; - p += fts5GetVarint32(p, iCurrent); - } - } - if( iCol!=iCurrent ) return 0; - - /* Advance pointer p until it points to pEnd or an 0x01 byte that is - ** not part of a varint */ - while( pnCol; i++){ - const u8 *pSub = pPos; - int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]); - if( nSub ){ - fts5BufferAppendBlob(pRc, pBuf, nSub, pSub); + const u8 *p = pPos; + const u8 *aCopy = p; + const u8 *pEnd = &p[nPos]; /* One byte past end of position list */ + int i = 0; + int iCurrent = 0; + + if( pColset->nCol>1 && sqlite3Fts5BufferSize(pRc, &pIter->poslist, nPos) ){ + return; + } + + while( 1 ){ + while( pColset->aiCol[i]nCol ){ + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + return; + } + } + + /* Advance pointer p until it points to pEnd or an 0x01 byte that is + ** not part of a varint */ + while( paiCol[i]==iCurrent ){ + if( pColset->nCol==1 ){ + pIter->base.pData = aCopy; + pIter->base.nData = p-aCopy; + return; + } + fts5BufferSafeAppendBlob(&pIter->poslist, aCopy, p-aCopy); + } + if( p==pEnd ){ + pIter->base.pData = pIter->poslist.p; + pIter->base.nData = pIter->poslist.n; + return; + } + aCopy = p++; + iCurrent = *p++; + if( iCurrent & 0x80 ){ + p--; + p += fts5GetVarint32(p, iCurrent); } } } + } /* @@ -220714,16 +223032,9 @@ static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){ /* All data is stored on the current page. Populate the output ** variables to point into the body of the page object. */ const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset]; - if( pColset->nCol==1 ){ - pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]); - pIter->base.pData = a; - }else{ - int *pRc = &pIter->pIndex->rc; - fts5BufferZero(&pIter->poslist); - fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, &pIter->poslist); - pIter->base.pData = pIter->poslist.p; - pIter->base.nData = pIter->poslist.n; - } + int *pRc = &pIter->pIndex->rc; + fts5BufferZero(&pIter->poslist); + fts5IndexExtractColset(pRc, pColset, a, pSeg->nPos, pIter); }else{ /* The data is distributed over two or more pages. Copy it into the ** Fts5Iter.poslist buffer and then set the output pointer to point @@ -222206,7 +224517,7 @@ static void fts5AppendPoslist( static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist; - assert( pIter->aPoslist ); + assert( pIter->aPoslist || (p==0 && pIter->aPoslist==0) ); if( p>=pIter->aEof ){ pIter->aPoslist = 0; }else{ @@ -222226,6 +224537,9 @@ static void fts5DoclistIterNext(Fts5DoclistIter *pIter){ } pIter->aPoslist = p; + if( &pIter->aPoslist[pIter->nPoslist]>pIter->aEof ){ + pIter->aPoslist = 0; + } } } @@ -222234,9 +224548,11 @@ static void fts5DoclistIterInit( Fts5DoclistIter *pIter ){ memset(pIter, 0, sizeof(*pIter)); - pIter->aPoslist = pBuf->p; - pIter->aEof = &pBuf->p[pBuf->n]; - fts5DoclistIterNext(pIter); + if( pBuf->n>0 ){ + pIter->aPoslist = pBuf->p; + pIter->aEof = &pBuf->p[pBuf->n]; + fts5DoclistIterNext(pIter); + } } #if 0 @@ -222290,16 +224606,20 @@ static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){ static void fts5MergeRowidLists( Fts5Index *p, /* FTS5 backend object */ Fts5Buffer *p1, /* First list to merge */ - Fts5Buffer *p2 /* Second list to merge */ + int nBuf, /* Number of entries in apBuf[] */ + Fts5Buffer *aBuf /* Array of other lists to merge into p1 */ ){ int i1 = 0; int i2 = 0; i64 iRowid1 = 0; i64 iRowid2 = 0; i64 iOut = 0; - + Fts5Buffer *p2 = &aBuf[0]; Fts5Buffer out; + + (void)nBuf; memset(&out, 0, sizeof(out)); + assert( nBuf==1 ); sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); if( p->rc ) return; @@ -222326,180 +224646,213 @@ static void fts5MergeRowidLists( fts5BufferFree(&out); } +typedef struct PrefixMerger PrefixMerger; +struct PrefixMerger { + Fts5DoclistIter iter; /* Doclist iterator */ + i64 iPos; /* For iterating through a position list */ + int iOff; + u8 *aPos; + PrefixMerger *pNext; /* Next in docid/poslist order */ +}; + +static void fts5PrefixMergerInsertByRowid( + PrefixMerger **ppHead, + PrefixMerger *p +){ + if( p->iter.aPoslist ){ + PrefixMerger **pp = ppHead; + while( *pp && p->iter.iRowid>(*pp)->iter.iRowid ){ + pp = &(*pp)->pNext; + } + p->pNext = *pp; + *pp = p; + } +} + +static void fts5PrefixMergerInsertByPosition( + PrefixMerger **ppHead, + PrefixMerger *p +){ + if( p->iPos>=0 ){ + PrefixMerger **pp = ppHead; + while( *pp && p->iPos>(*pp)->iPos ){ + pp = &(*pp)->pNext; + } + p->pNext = *pp; + *pp = p; + } +} + + /* -** Buffers p1 and p2 contain doclists. This function merges the content -** of the two doclists together and sets buffer p1 to the result before -** returning. -** -** If an error occurs, an error code is left in p->rc. If an error has -** already occurred, this function is a no-op. +** Array aBuf[] contains nBuf doclists. These are all merged in with the +** doclist in buffer p1. */ static void fts5MergePrefixLists( Fts5Index *p, /* FTS5 backend object */ Fts5Buffer *p1, /* First list to merge */ - Fts5Buffer *p2 /* Second list to merge */ -){ - if( p2->n ){ - i64 iLastRowid = 0; - Fts5DoclistIter i1; - Fts5DoclistIter i2; - Fts5Buffer out = {0, 0, 0}; - Fts5Buffer tmp = {0, 0, 0}; - - /* The maximum size of the output is equal to the sum of the two - ** input sizes + 1 varint (9 bytes). The extra varint is because if the - ** first rowid in one input is a large negative number, and the first in - ** the other a non-negative number, the delta for the non-negative - ** number will be larger on disk than the literal integer value - ** was. - ** - ** Or, if the input position-lists are corrupt, then the output might - ** include up to 2 extra 10-byte positions created by interpreting -1 - ** (the value PoslistNext64() uses for EOF) as a position and appending - ** it to the output. This can happen at most once for each input - ** position-list, hence two 10 byte paddings. */ - if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return; - fts5DoclistIterInit(p1, &i1); - fts5DoclistIterInit(p2, &i2); + int nBuf, /* Number of buffers in array aBuf[] */ + Fts5Buffer *aBuf /* Other lists to merge in */ +){ +#define fts5PrefixMergerNextPosition(p) \ + sqlite3Fts5PoslistNext64((p)->aPos,(p)->iter.nPoslist,&(p)->iOff,&(p)->iPos); +#define FTS5_MERGE_NLIST 16 + PrefixMerger aMerger[FTS5_MERGE_NLIST]; + PrefixMerger *pHead = 0; + int i; + int nOut = 0; + Fts5Buffer out = {0, 0, 0}; + Fts5Buffer tmp = {0, 0, 0}; + i64 iLastRowid = 0; + + /* Initialize a doclist-iterator for each input buffer. Arrange them in + ** a linked-list starting at pHead in ascending order of rowid. Avoid + ** linking any iterators already at EOF into the linked list at all. */ + assert( nBuf+1<=sizeof(aMerger)/sizeof(aMerger[0]) ); + memset(aMerger, 0, sizeof(PrefixMerger)*(nBuf+1)); + pHead = &aMerger[nBuf]; + fts5DoclistIterInit(p1, &pHead->iter); + for(i=0; in + 9 + 10*nBuf; + + /* The maximum size of the output is equal to the sum of the + ** input sizes + 1 varint (9 bytes). The extra varint is because if the + ** first rowid in one input is a large negative number, and the first in + ** the other a non-negative number, the delta for the non-negative + ** number will be larger on disk than the literal integer value + ** was. + ** + ** Or, if the input position-lists are corrupt, then the output might + ** include up to (nBuf+1) extra 10-byte positions created by interpreting -1 + ** (the value PoslistNext64() uses for EOF) as a position and appending + ** it to the output. This can happen at most once for each input + ** position-list, hence (nBuf+1) 10 byte paddings. */ + if( sqlite3Fts5BufferSize(&p->rc, &out, nOut) ) return; + + while( pHead ){ + fts5MergeAppendDocid(&out, iLastRowid, pHead->iter.iRowid); + + if( pHead->pNext && iLastRowid==pHead->pNext->iter.iRowid ){ + /* Merge data from two or more poslists */ + i64 iPrev = 0; + int nTmp = FTS5_DATA_ZERO_PADDING; + int nMerge = 0; + PrefixMerger *pSave = pHead; + PrefixMerger *pThis = 0; + int nTail = 0; + + pHead = 0; + while( pSave && pSave->iter.iRowid==iLastRowid ){ + PrefixMerger *pNext = pSave->pNext; + pSave->iOff = 0; + pSave->iPos = 0; + pSave->aPos = &pSave->iter.aPoslist[pSave->iter.nSize]; + fts5PrefixMergerNextPosition(pSave); + nTmp += pSave->iter.nPoslist + 10; + nMerge++; + fts5PrefixMergerInsertByPosition(&pHead, pSave); + pSave = pNext; + } + + if( pHead==0 || pHead->pNext==0 ){ + p->rc = FTS5_CORRUPT; + break; + } - while( 1 ){ - if( i1.iRowidp) + (i2.aPoslist-p2->p)+9+10+10) ); - } - else if( i2.iRowid!=i1.iRowid ){ - /* Copy entry from i2 */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize); - fts5DoclistIterNext(&i2); - if( i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); + /* See the earlier comment in this function for an explanation of why + ** corrupt input position lists might cause the output to consume + ** at most nMerge*10 bytes of unexpected space. */ + if( sqlite3Fts5BufferSize(&p->rc, &tmp, nTmp+nMerge*10) ){ + break; } - else{ - /* Merge the two position lists. */ - i64 iPos1 = 0; - i64 iPos2 = 0; - int iOff1 = 0; - int iOff2 = 0; - u8 *a1 = &i1.aPoslist[i1.nSize]; - u8 *a2 = &i2.aPoslist[i2.nSize]; - int nCopy; - u8 *aCopy; - - i64 iPrev = 0; - Fts5PoslistWriter writer; - memset(&writer, 0, sizeof(writer)); - - /* See the earlier comment in this function for an explanation of why - ** corrupt input position lists might cause the output to consume - ** at most 20 bytes of unexpected space. */ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferZero(&tmp); - sqlite3Fts5BufferSize(&p->rc, &tmp, - i1.nPoslist + i2.nPoslist + 10 + 10 + FTS5_DATA_ZERO_PADDING - ); - if( p->rc ) break; + fts5BufferZero(&tmp); - sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); - assert_nc( iPos1>=0 && iPos2>=0 ); + pThis = pHead; + pHead = pThis->pNext; + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); + fts5PrefixMergerNextPosition(pThis); + fts5PrefixMergerInsertByPosition(&pHead, pThis); - if( iPos1=0 && iPos2>=0 ){ - while( 1 ){ - if( iPos1pNext ){ + pThis = pHead; + if( pThis->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pThis->iPos); } + fts5PrefixMergerNextPosition(pThis); + pHead = pThis->pNext; + fts5PrefixMergerInsertByPosition(&pHead, pThis); + } - if( iPos1>=0 ){ - if( iPos1!=iPrev ){ - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); - } - aCopy = &a1[iOff1]; - nCopy = i1.nPoslist - iOff1; - }else{ - assert_nc( iPos2>=0 && iPos2!=iPrev ); - sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); - aCopy = &a2[iOff2]; - nCopy = i2.nPoslist - iOff2; - } - if( nCopy>0 ){ - fts5BufferSafeAppendBlob(&tmp, aCopy, nCopy); - } + if( pHead->iPos!=iPrev ){ + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, pHead->iPos); + } + nTail = pHead->iter.nPoslist - pHead->iOff; - /* WRITEPOSLISTSIZE */ - assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist ); - assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 ); - if( tmp.n>i1.nPoslist+i2.nPoslist ){ - if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; - break; + /* WRITEPOSLISTSIZE */ + assert( tmp.n+nTail<=nTmp ); + if( tmp.n+nTail>nTmp-FTS5_DATA_ZERO_PADDING ){ + if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; + break; + } + fts5BufferSafeAppendVarint(&out, (tmp.n+nTail) * 2); + fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); + if( nTail>0 ){ + fts5BufferSafeAppendBlob(&out, &pHead->aPos[pHead->iOff], nTail); + } + + pHead = pSave; + for(i=0; iiter.aPoslist && pX->iter.iRowid==iLastRowid ){ + fts5DoclistIterNext(&pX->iter); + fts5PrefixMergerInsertByRowid(&pHead, pX); } - fts5BufferSafeAppendVarint(&out, tmp.n * 2); - fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); - fts5DoclistIterNext(&i1); - fts5DoclistIterNext(&i2); - assert_nc( out.n<=(p1->n+p2->n+9) ); - if( i1.aPoslist==0 || i2.aPoslist==0 ) break; - assert( out.n<=((i1.aPoslist-p1->p) + (i2.aPoslist-p2->p)+9+10+10) ); } - } - if( i1.aPoslist ){ - fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid); - fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist); - } - else if( i2.aPoslist ){ - fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); - fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist); + }else{ + /* Copy poslist from pHead to output */ + PrefixMerger *pThis = pHead; + Fts5DoclistIter *pI = &pThis->iter; + fts5BufferSafeAppendBlob(&out, pI->aPoslist, pI->nPoslist+pI->nSize); + fts5DoclistIterNext(pI); + pHead = pThis->pNext; + fts5PrefixMergerInsertByRowid(&pHead, pThis); } - assert_nc( out.n<=(p1->n+p2->n+9) ); - - fts5BufferFree(p1); - fts5BufferFree(&tmp); - memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); - *p1 = out; } + + fts5BufferFree(p1); + fts5BufferFree(&tmp); + memset(&out.p[out.n], 0, FTS5_DATA_ZERO_PADDING); + *p1 = out; } static void fts5SetupPrefixIter( Fts5Index *p, /* Index to read from */ int bDesc, /* True for "ORDER BY rowid DESC" */ - const u8 *pToken, /* Buffer containing prefix to match */ + int iIdx, /* Index to scan for data */ + u8 *pToken, /* Buffer containing prefix to match */ int nToken, /* Size of buffer pToken in bytes */ Fts5Colset *pColset, /* Restrict matches to these columns */ Fts5Iter **ppIter /* OUT: New iterator */ ){ Fts5Structure *pStruct; Fts5Buffer *aBuf; - const int nBuf = 32; + int nBuf = 32; + int nMerge = 1; - void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*); + void (*xMerge)(Fts5Index*, Fts5Buffer*, int, Fts5Buffer*); void (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Buffer*); if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){ xMerge = fts5MergeRowidLists; xAppend = fts5AppendRowid; }else{ + nMerge = FTS5_MERGE_NLIST-1; + nBuf = nMerge*8; /* Sufficient to merge (16^8)==(2^32) lists */ xMerge = fts5MergePrefixLists; xAppend = fts5AppendPoslist; } @@ -222519,6 +224872,27 @@ static void fts5SetupPrefixIter( int bNewTerm = 1; memset(&doclist, 0, sizeof(doclist)); + if( iIdx!=0 ){ + int dummy = 0; + const int f2 = FTS5INDEX_QUERY_SKIPEMPTY|FTS5INDEX_QUERY_NOOUTPUT; + pToken[0] = FTS5_MAIN_PREFIX; + fts5MultiIterNew(p, pStruct, f2, pColset, pToken, nToken, -1, 0, &p1); + fts5IterSetOutputCb(&p->rc, p1); + for(; + fts5MultiIterEof(p, p1)==0; + fts5MultiIterNext2(p, p1, &dummy) + ){ + Fts5SegIter *pSeg = &p1->aSeg[ p1->aFirst[1].iFirst ]; + p1->xSetOutputs(p1, pSeg); + if( p1->base.nData ){ + xAppend(p, p1->base.iRowid-iLastRowid, p1, &doclist); + iLastRowid = p1->base.iRowid; + } + } + fts5MultiIterFree(p1); + } + + pToken[0] = FTS5_MAIN_PREFIX + iIdx; fts5MultiIterNew(p, pStruct, flags, pColset, pToken, nToken, -1, 0, &p1); fts5IterSetOutputCb(&p->rc, p1); for( /* no-op */ ; @@ -222539,13 +224913,21 @@ static void fts5SetupPrefixIter( if( p1->base.iRowid<=iLastRowid && doclist.n>0 ){ for(i=0; p->rc==SQLITE_OK && doclist.n; i++){ - assert( ibase.iRowid; } - for(i=0; irc==SQLITE_OK ){ - xMerge(p, &doclist, &aBuf[i]); + xMerge(p, &doclist, nMerge, &aBuf[i]); + } + for(iFree=i; iFreerc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ + int iPrefixIdx = 0; /* +1 prefix index */ if( nToken ) memcpy(&buf.p[1], pToken, nToken); /* Figure out which index to search and set iIdx accordingly. If this @@ -222835,7 +225222,9 @@ static int sqlite3Fts5IndexQuery( if( flags & FTS5INDEX_QUERY_PREFIX ){ int nChar = fts5IndexCharlen(pToken, nToken); for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){ - if( pConfig->aPrefix[iIdx-1]==nChar ) break; + int nIdxChar = pConfig->aPrefix[iIdx-1]; + if( nIdxChar==nChar ) break; + if( nIdxChar==nChar+1 ) iPrefixIdx = iIdx; } } @@ -222852,8 +225241,7 @@ static int sqlite3Fts5IndexQuery( }else{ /* Scan multiple terms in the main index */ int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0; - buf.p[0] = FTS5_MAIN_PREFIX; - fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet); + fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet); assert( p->rc!=SQLITE_OK || pRet->pColset==0 ); fts5IterSetOutputCb(&p->rc, pRet); if( p->rc==SQLITE_OK ){ @@ -222926,8 +225314,9 @@ static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ int n; const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n); + assert_nc( z || n<=1 ); *pn = n-1; - return &z[1]; + return (z ? &z[1] : 0); } /* @@ -226213,7 +228602,8 @@ static int fts5ApiPhraseFirst( int n; int rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n); if( rc==SQLITE_OK ){ - pIter->b = &pIter->a[n]; + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); *piCol = 0; *piOff = 0; fts5ApiPhraseNext(pCtx, pIter, piCol, piOff); @@ -226272,7 +228662,8 @@ static int fts5ApiPhraseFirstColumn( rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); } if( rc==SQLITE_OK ){ - pIter->b = &pIter->a[n]; + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); *piCol = 0; fts5ApiPhraseNextColumn(pCtx, pIter, piCol); } @@ -226280,7 +228671,8 @@ static int fts5ApiPhraseFirstColumn( int n; rc = fts5CsrPoslist(pCsr, iPhrase, &pIter->a, &n); if( rc==SQLITE_OK ){ - pIter->b = &pIter->a[n]; + assert( pIter->a || n==0 ); + pIter->b = (pIter->a ? &pIter->a[n] : 0); if( n<=0 ){ *piCol = -1; }else if( pIter->a[0]==0x01 ){ @@ -226758,7 +229150,7 @@ static int sqlite3Fts5GetTokenizer( *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate( - pMod->pUserData, &azArg[1], (nArg?nArg-1:0), &pConfig->pTok + pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok ); pConfig->pTokApi = &pMod->x; if( rc!=SQLITE_OK ){ @@ -226821,7 +229213,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50c3827", -1, SQLITE_TRANSIENT); } /* @@ -231747,9 +234139,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=231750 +#if __LINE__!=234142 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ealt2" +#define SQLITE_SOURCE_ID "2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50calt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/src/vendor/sqlite3/sqlite3.h b/src/vendor/sqlite3/sqlite3.h index 44e53ef62..f636b294d 100644 --- a/src/vendor/sqlite3/sqlite3.h +++ b/src/vendor/sqlite3/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.34.1" -#define SQLITE_VERSION_NUMBER 3034001 -#define SQLITE_SOURCE_ID "2021-01-20 14:10:07 10e20c0b43500cfb9bbc0eaa061c57514f715d87238f4d835880cd846b9ebd1f" +#define SQLITE_VERSION "3.35.2" +#define SQLITE_VERSION_NUMBER 3035002 +#define SQLITE_SOURCE_ID "2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50c3827" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -2115,7 +2115,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether triggers are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the trigger setting is not reported back. +** which case the trigger setting is not reported back. +** +**

Originally this option disabled all triggers. ^(However, since +** SQLite version 3.35.0, TEMP triggers are still allowed even if +** this option is off. So, in other words, this option now only disables +** triggers in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_VIEW]] **

SQLITE_DBCONFIG_ENABLE_VIEW
@@ -2126,7 +2132,13 @@ struct sqlite3_mem_methods { ** The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether views are disabled or enabled ** following this call. The second parameter may be a NULL pointer, in -** which case the view setting is not reported back. +** which case the view setting is not reported back. +** +**

Originally this option disabled all views. ^(However, since +** SQLite version 3.35.0, TEMP views are still allowed even if +** this option is off. So, in other words, this option now only disables +** views in the main database schema or in the schemas of ATTACH-ed +** databases.)^ ** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **

SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
@@ -3499,6 +3511,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** that uses dot-files in place of posix advisory locking. **
file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. +** Use "ro" instead: "file:data.db?mode=ro". **
** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and @@ -7765,7 +7778,8 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PRNG_SEED 28 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29 #define SQLITE_TESTCTRL_SEEK_COUNT 30 -#define SQLITE_TESTCTRL_LAST 30 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_TRACEFLAGS 31 +#define SQLITE_TESTCTRL_LAST 31 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking @@ -10438,6 +10452,14 @@ SQLITE_API int sqlite3session_patchset( */ SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); +/* +** CAPI3REF: Query for the amount of heap memory used by a session object. +** +** This API returns the total amount of heap memory in bytes currently +** used by the session object passed as the only argument. +*/ +SQLITE_API sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession); + /* ** CAPI3REF: Create An Iterator To Traverse A Changeset ** CONSTRUCTOR: sqlite3_changeset_iter @@ -10540,18 +10562,23 @@ SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); ** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this ** is not the case, this function returns [SQLITE_MISUSE]. ** -** If argument pzTab is not NULL, then *pzTab is set to point to a -** nul-terminated utf-8 encoded string containing the name of the table -** affected by the current change. The buffer remains valid until either -** sqlite3changeset_next() is called on the iterator or until the -** conflict-handler function returns. If pnCol is not NULL, then *pnCol is -** set to the number of columns in the table affected by the change. If -** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change +** Arguments pOp, pnCol and pzTab may not be NULL. Upon return, three +** outputs are set through these pointers: +** +** *pOp is set to one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], +** depending on the type of change that the iterator currently points to; +** +** *pnCol is set to the number of columns in the table affected by the change; and +** +** *pzTab is set to point to a nul-terminated utf-8 encoded string containing +** the name of the table affected by the current change. The buffer remains +** valid until either sqlite3changeset_next() is called on the iterator +** or until the conflict-handler function returns. +** +** If pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for ** [sqlite3session_indirect()] for a description of direct and indirect -** changes. Finally, if pOp is not NULL, then *pOp is set to one of -** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the -** type of change that the iterator currently points to. +** changes. ** ** If no error occurs, SQLITE_OK is returned. If an error does occur, an ** SQLite error code is returned. The values of the output variables may not From 31196b255e439460e0a9dc80236b0a938f73abb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 25 Mar 2021 17:07:00 +0100 Subject: [PATCH 17/47] Bump version to 2.2.5 --- DESCRIPTION | 4 ++-- NEWS.md | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 627a82c7a..d0ec5ec9c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: RSQLite Title: 'SQLite' Interface for R -Version: 2.2.4.9000 -Date: 2021-03-12 +Version: 2.2.5 +Date: 2021-03-25 Authors@R: c(person(given = "Kirill", family = "M\u00fcller", diff --git a/NEWS.md b/NEWS.md index dcf7873a7..0230751d9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,11 @@ +# RSQLite 2.2.5 (2021-03-25) + +- Upgrade bundled SQLite to version 3.35.2 (#357). +- If the busy handler fails, the transaction is aborted explicitly (#348, @gaborcsardi). + + # RSQLite 2.2.4.9000 (2021-03-12) - Same as previous version. From 144a3bb5e636498d01c7565664ee210f639a9254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 25 Mar 2021 17:07:02 +0100 Subject: [PATCH 18/47] Update CRAN comments --- cran-comments.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/cran-comments.md b/cran-comments.md index b24234547..fe2a38284 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,4 +1,4 @@ -RSQLite 2.2.4 +RSQLite 2.2.5 ## Cran Repository Policy @@ -7,10 +7,15 @@ RSQLite 2.2.4 ## R CMD check results - [x] Checked locally, R 4.0.4 -- [x] Checked on CI system, R 4.0.4 -- [x] Checked on win-builder, R devel +- [ ] Checked on CI system, R 4.0.4 +- [ ] Checked on win-builder, R devel + +Check the boxes above after successful execution and remove this line. Then run `fledge::release()`. ## Current CRAN check results -- [x] Checked on 2021-03-12, problems found: https://cran.r-project.org/web/checks/check_results_RSQLite.html -- [x] NOTE: r-devel-linux-x86_64-fedora-clang, r-devel-windows-ix86+x86_64, r-release-macos-x86_64, r-release-windows-ix86+x86_64, r-oldrel-macos-x86_64: large binaries +- [x] Checked on 2021-03-25, problems found: https://cran.r-project.org/web/checks/check_results_RSQLite.html +- [ ] NOTE: r-devel-linux-x86_64-fedora-clang, r-devel-windows-ix86+x86_64, r-release-macos-x86_64, r-release-windows-ix86+x86_64, r-oldrel-macos-x86_64 +- [ ] ERROR: r-patched-solaris-x86 + +Check results at: https://cran.r-project.org/web/checks/check_results_RSQLite.html From 78dbf719c39de862011467c4dd76611954930b6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 25 Mar 2021 17:07:08 +0100 Subject: [PATCH 19/47] Bump version to 2.2.5.9000 --- DESCRIPTION | 2 +- NEWS.md | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index d0ec5ec9c..360dc684d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: RSQLite Title: 'SQLite' Interface for R -Version: 2.2.5 +Version: 2.2.5.9000 Date: 2021-03-25 Authors@R: c(person(given = "Kirill", diff --git a/NEWS.md b/NEWS.md index 0230751d9..c309d67de 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,11 @@ +# RSQLite 2.2.5.9000 (2021-03-25) + +- Upgrade bundled SQLite to version 3.35.2 (#357). +- If the busy handler fails, the transaction is aborted explicitly (#348, @gaborcsardi). + + # RSQLite 2.2.5 (2021-03-25) - Upgrade bundled SQLite to version 3.35.2 (#357). From 518611182ffbf1ae27c1c3bbbf6c8729247d71bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 25 Mar 2021 17:12:13 +0100 Subject: [PATCH 20/47] NEWS and CRAN comments --- NEWS.md | 5 ----- cran-comments.md | 10 ++++------ 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0230751d9..c2e73fc8f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,11 +6,6 @@ - If the busy handler fails, the transaction is aborted explicitly (#348, @gaborcsardi). -# RSQLite 2.2.4.9000 (2021-03-12) - -- Same as previous version. - - # RSQLite 2.2.4 (2021-03-12) ## Features diff --git a/cran-comments.md b/cran-comments.md index fe2a38284..1628bd058 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -7,15 +7,13 @@ RSQLite 2.2.5 ## R CMD check results - [x] Checked locally, R 4.0.4 -- [ ] Checked on CI system, R 4.0.4 -- [ ] Checked on win-builder, R devel +- [x] Checked on CI system, R 4.0.4 +- [x] Checked on win-builder, R devel Check the boxes above after successful execution and remove this line. Then run `fledge::release()`. ## Current CRAN check results - [x] Checked on 2021-03-25, problems found: https://cran.r-project.org/web/checks/check_results_RSQLite.html -- [ ] NOTE: r-devel-linux-x86_64-fedora-clang, r-devel-windows-ix86+x86_64, r-release-macos-x86_64, r-release-windows-ix86+x86_64, r-oldrel-macos-x86_64 -- [ ] ERROR: r-patched-solaris-x86 - -Check results at: https://cran.r-project.org/web/checks/check_results_RSQLite.html +- [x] NOTE: r-devel-linux-x86_64-fedora-clang, r-devel-windows-ix86+x86_64, r-release-macos-x86_64, r-release-windows-ix86+x86_64, r-oldrel-macos-x86_64: large binary +- [x] ERROR: r-patched-solaris-x86: fixed From 061e46c4c5d60ed50b80b31de133633ec7ecca5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 25 Mar 2021 17:26:19 +0100 Subject: [PATCH 21/47] NEWS --- NEWS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index c309d67de..12d8acb30 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,8 +2,7 @@ # RSQLite 2.2.5.9000 (2021-03-25) -- Upgrade bundled SQLite to version 3.35.2 (#357). -- If the busy handler fails, the transaction is aborted explicitly (#348, @gaborcsardi). +- Same as previous version. # RSQLite 2.2.5 (2021-03-25) From 538b5c9708d9a6d90a855355c6b5a1e0bad49593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Thu, 25 Mar 2021 17:42:47 +0100 Subject: [PATCH 22/47] Fix URL --- _pkgdown.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_pkgdown.yml b/_pkgdown.yml index ef2f817fc..6cdcd2654 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -17,4 +17,4 @@ development: authors: Kirill Müller: - href: http://krlmlr.info + href: https://krlmlr.info From 86e42c1e86bd7fb678a9f5736435a0859a1a77f9 Mon Sep 17 00:00:00 2001 From: upgrade Date: Mon, 29 Mar 2021 08:16:52 +0000 Subject: [PATCH 23/47] Upgrade bundled SQLite to 3.35.3 --- src/vendor/sqlite3/sqlite3.c | 190 +++++++++++++++++++++-------------- src/vendor/sqlite3/sqlite3.h | 6 +- 2 files changed, 118 insertions(+), 78 deletions(-) diff --git a/src/vendor/sqlite3/sqlite3.c b/src/vendor/sqlite3/sqlite3.c index 54f8277a7..bb962bf09 100644 --- a/src/vendor/sqlite3/sqlite3.c +++ b/src/vendor/sqlite3/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.35.2. By combining all the individual C code files into this +** version 3.35.3. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -1186,9 +1186,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.35.2" -#define SQLITE_VERSION_NUMBER 3035002 -#define SQLITE_SOURCE_ID "2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50c3827" +#define SQLITE_VERSION "3.35.3" +#define SQLITE_VERSION_NUMBER 3035003 +#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -21071,6 +21071,7 @@ struct VdbeCursor { Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ + Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ Btree *pBtx; /* Separate file holding temporary table */ i64 seqCount; /* Sequence counter */ @@ -40220,7 +40221,8 @@ static int unixBackupDir(const char *z, int *pJ){ int j = *pJ; int i; if( j<=0 ) return 0; - for(i=j-1; ALWAYS(i>0) && z[i-1]!='/'; i--){} + for(i=j-1; i>0 && z[i-1]!='/'; i--){} + if( i==0 ) return 0; if( z[i]=='.' && i==j-2 && z[i+1]=='.' ) return 0; *pJ = i-1; return 1; @@ -64277,7 +64279,7 @@ struct Btree { u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */ int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ int nBackup; /* Number of backup operations reading this btree */ - u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ + u32 iBDataVersion; /* Combines with pBt->pPager->iDataVersion */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */ #ifdef SQLITE_DEBUG @@ -67690,19 +67692,23 @@ static void freeTempSpace(BtShared *pBt){ */ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ BtShared *pBt = p->pBt; - BtCursor *pCur; /* Close all cursors opened via this handle. */ assert( sqlite3_mutex_held(p->db->mutex) ); sqlite3BtreeEnter(p); - pCur = pBt->pCursor; - while( pCur ){ - BtCursor *pTmp = pCur; - pCur = pCur->pNext; - if( pTmp->pBtree==p ){ - sqlite3BtreeCloseCursor(pTmp); + + /* Verify that no other cursors have this Btree open */ +#ifdef SQLITE_DEBUG + { + BtCursor *pCur = pBt->pCursor; + while( pCur ){ + BtCursor *pTmp = pCur; + pCur = pCur->pNext; + assert( pTmp->pBtree!=p ); + } } +#endif /* Rollback any active transaction and free the handle structure. ** The call to sqlite3BtreeRollback() drops any table-locks held by @@ -69084,7 +69090,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ sqlite3BtreeLeave(p); return rc; } - p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */ + p->iBDataVersion--; /* Compensate for pPager->iDataVersion++; */ pBt->inTransaction = TRANS_READ; btreeClearHasContent(pBt); } @@ -69494,7 +69500,14 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ unlockBtreeIfUnused(pBt); sqlite3_free(pCur->aOverflow); sqlite3_free(pCur->pKey); - sqlite3BtreeLeave(pBtree); + if( (pBt->openFlags & BTREE_SINGLE) && pBt->pCursor==0 ){ + /* Since the BtShared is not sharable, there is no need to + ** worry about the missing sqlite3BtreeLeave() call here. */ + assert( pBtree->sharable==0 ); + sqlite3BtreeClose(pBtree); + }else{ + sqlite3BtreeLeave(pBtree); + } pCur->pBtree = 0; } return SQLITE_OK; @@ -74607,7 +74620,7 @@ SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ assert( idx>=0 && idx<=15 ); if( idx==BTREE_DATA_VERSION ){ - *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iBDataVersion; }else{ *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); } @@ -80835,20 +80848,15 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ return; } assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); + assert( pCx->pBtx==0 || pCx->isEphemeral ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); break; } case CURTYPE_BTREE: { - if( pCx->isEphemeral ){ - if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx); - /* The pCx->pCursor will be close automatically, if it exists, by - ** the call above. */ - }else{ - assert( pCx->uc.pCursor!=0 ); - sqlite3BtreeCloseCursor(pCx->uc.pCursor); - } + assert( pCx->uc.pCursor!=0 ); + sqlite3BtreeCloseCursor(pCx->uc.pCursor); break; } #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -81932,6 +81940,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, u32 *piCol){ assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ u32 iMap; + assert( !p->isEphemeral ); if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ *pp = p->pAltCursor; *piCol = iMap - 1; @@ -86140,11 +86149,6 @@ static VdbeCursor *allocateCursor( assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ - /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag - ** is clear. Otherwise, if this is an ephemeral cursor created by - ** OP_OpenDup, the cursor will not be closed and will still be part - ** of a BtShared.pCursor list. */ - if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0; sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } @@ -89830,7 +89834,7 @@ case OP_OpenDup: { pOrig = p->apCsr[pOp->p2]; assert( pOrig ); - assert( pOrig->pBtx!=0 ); /* Only ephemeral cursors can be duplicated */ + assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */ pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; @@ -89840,7 +89844,10 @@ case OP_OpenDup: { pCx->isTable = pOrig->isTable; pCx->pgnoRoot = pOrig->pgnoRoot; pCx->isOrdered = pOrig->isOrdered; - rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pCx->pBtx = pOrig->pBtx; + pCx->hasBeenDuped = 1; + pOrig->hasBeenDuped = 1; + rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this @@ -89906,9 +89913,10 @@ case OP_OpenEphemeral: { aMem[pOp->p3].z = ""; } pCx = p->apCsr[pOp->p1]; - if( pCx && ALWAYS(pCx->pBtx) ){ - /* If the ephermeral table is already open, erase all existing content - ** so that the table is empty again, rather than creating a new table. */ + if( pCx && !pCx->hasBeenDuped ){ + /* If the ephermeral table is already open and has no duplicates from + ** OP_OpenDup, then erase all existing content so that the table is + ** empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); pCx->seqCount = 0; pCx->cacheStatus = CACHE_STALE; @@ -89922,33 +89930,36 @@ case OP_OpenEphemeral: { vfsFlags); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); - } - if( rc==SQLITE_OK ){ - /* If a transient index is required, create it by calling - ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before - ** opening it. If a transient table is required, just use the - ** automatically created table with root-page 1 (an BLOB_INTKEY table). - */ - if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ - assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(pCx->pBtx, &pCx->pgnoRoot, - BTREE_BLOBKEY | pOp->p5); - if( rc==SQLITE_OK ){ - assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); - assert( pKeyInfo->db==db ); - assert( pKeyInfo->enc==ENC(db) ); - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, - pKeyInfo, pCx->uc.pCursor); + if( rc==SQLITE_OK ){ + /* If a transient index is required, create it by calling + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before + ** opening it. If a transient table is required, just use the + ** automatically created table with root-page 1 (an BLOB_INTKEY table). + */ + if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ + assert( pOp->p4type==P4_KEYINFO ); + rc = sqlite3BtreeCreateTable(pCx->pBtx, &pCx->pgnoRoot, + BTREE_BLOBKEY | pOp->p5); + if( rc==SQLITE_OK ){ + assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); + assert( pKeyInfo->db==db ); + assert( pKeyInfo->enc==ENC(db) ); + rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + pKeyInfo, pCx->uc.pCursor); + } + pCx->isTable = 0; + }else{ + pCx->pgnoRoot = SCHEMA_ROOT; + rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR, + 0, pCx->uc.pCursor); + pCx->isTable = 1; } - pCx->isTable = 0; - }else{ - pCx->pgnoRoot = SCHEMA_ROOT; - rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR, - 0, pCx->uc.pCursor); - pCx->isTable = 1; + } + pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); + if( rc ){ + sqlite3BtreeClose(pCx->pBtx); } } - pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); } if( rc ) goto abort_due_to_error; pCx->nullRow = 1; @@ -90382,13 +90393,13 @@ case OP_SeekGT: { /* jump, in3, group */ ** ** There are three possible outcomes from this opcode:
    ** -**
  1. If after This.P1 steps, the cursor is still point to a place that -** is earlier in the btree than the target row, -** then fall through into the subsquence OP_SeekGE opcode. +**
  2. If after This.P1 steps, the cursor is still pointing to a place that +** is earlier in the btree than the target row, then fall through +** into the subsquence OP_SeekGE opcode. ** **
  3. If the cursor is successfully moved to the target row by 0 or more ** sqlite3BtreeNext() calls, then jump to This.P2, which will land just -** past the OP_IdxGT opcode that follows the OP_SeekGE. +** past the OP_IdxGT or OP_IdxGE opcode that follows the OP_SeekGE. ** **
  4. If the cursor ends up past the target row (indicating the the target ** row does not exist in the btree) then jump to SeekOP.P2. @@ -90405,7 +90416,8 @@ case OP_SeekScan: { /* pOp->p2 points to the first instruction past the OP_IdxGT that ** follows the OP_SeekGE. */ assert( pOp->p2>=(int)(pOp-aOp)+2 ); - assert( aOp[pOp->p2-1].opcode==OP_IdxGT ); + assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); + testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); @@ -91940,6 +91952,8 @@ case OP_IdxRowid: { /* out2 */ pTabCur->deferredMoveto = 1; assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); pTabCur->aAltMap = pOp->p4.ai; + assert( !pC->isEphemeral ); + assert( !pTabCur->isEphemeral ); pTabCur->pAltCursor = pC; }else{ pOut = out2Prerelease(p, pOp); @@ -115684,7 +115698,11 @@ SQLITE_PRIVATE void sqlite3CreateIndex( /* Clean up before exiting */ exit_create_index: if( pIndex ) sqlite3FreeIndex(db, pIndex); - if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */ + if( pTab ){ + /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list. + ** The list was already ordered when this routine was entered, so at this + ** point at most a single index (the newly added index) will be out of + ** order. So we have to reorder at most one index. */ Index **ppFrom = &pTab->pIndex; Index *pThis; for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){ @@ -115698,6 +115716,16 @@ SQLITE_PRIVATE void sqlite3CreateIndex( } break; } +#ifdef SQLITE_DEBUG + /* Verify that all REPLACE indexes really are now at the end + ** of the index list. In other words, no other index type ever + ** comes after a REPLACE index on the list. */ + for(pThis = pTab->pIndex; pThis; pThis=pThis->pNext){ + assert( pThis->onError!=OE_Replace + || pThis->pNext==0 + || pThis->pNext->onError==OE_Replace ); + } +#endif } sqlite3ExprDelete(db, pPIWhere); sqlite3ExprListDelete(db, pList); @@ -123114,7 +123142,9 @@ SQLITE_PRIVATE void sqlite3Insert( pNx->iDataCur = iDataCur; pNx->iIdxCur = iIdxCur; if( pNx->pUpsertTarget ){ - sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx); + if( sqlite3UpsertAnalyzeTarget(pParse, pTabList, pNx) ){ + goto insert_cleanup; + } } pNx = pNx->pNextUpsert; }while( pNx!=0 ); @@ -124536,7 +124566,7 @@ static void codeWithoutRowidPreupdate( Vdbe *v = pParse->pVdbe; int r = sqlite3GetTempReg(pParse); assert( !HasRowid(pTab) ); - assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) ); + assert( 0==(pParse->db->mDbFlags & DBFLAG_Vacuum) || CORRUPT_DB ); sqlite3VdbeAddOp2(v, OP_Integer, 0, r); sqlite3VdbeAddOp4(v, OP_Insert, iCur, regData, r, (char*)pTab, P4_TABLE); sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); @@ -133084,7 +133114,7 @@ SQLITE_PRIVATE int sqlite3ColumnsFromExprList( nCol = pEList->nExpr; aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); testcase( aCol==0 ); - if( nCol>32767 ) nCol = 32767; + if( NEVER(nCol>32767) ) nCol = 32767; }else{ nCol = 0; aCol = 0; @@ -136158,16 +136188,24 @@ static int resolveFromTermToCte( pSavedWith = pParse->pWith; pParse->pWith = pWith; if( pSel->selFlags & SF_Recursive ){ + int rc; assert( pRecTerm!=0 ); assert( (pRecTerm->selFlags & SF_Recursive)==0 ); assert( pRecTerm->pNext!=0 ); assert( (pRecTerm->pNext->selFlags & SF_Recursive)!=0 ); assert( pRecTerm->pWith==0 ); pRecTerm->pWith = pSel->pWith; - sqlite3WalkSelect(pWalker, pRecTerm); + rc = sqlite3WalkSelect(pWalker, pRecTerm); pRecTerm->pWith = 0; + if( rc ){ + pParse->pWith = pSavedWith; + return 2; + } }else{ - sqlite3WalkSelect(pWalker, pSel); + if( sqlite3WalkSelect(pWalker, pSel) ){ + pParse->pWith = pSavedWith; + return 2; + } } pParse->pWith = pWith; @@ -137476,7 +137514,9 @@ SQLITE_PRIVATE int sqlite3Select( sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); pSub->nSelectRow = pPrior->pSelect->nSelectRow; }else{ - /* Generate a subroutine that will materialize the view. */ + /* Materalize the view. If the view is not correlated, generate a + ** subroutine to do the materialization so that subsequent uses of + ** the same view can reuse the materialization. */ int topAddr; int onceAddr = 0; int retAddr; @@ -137503,7 +137543,7 @@ SQLITE_PRIVATE int sqlite3Select( VdbeComment((v, "end %s", pItem->pTab->zName)); sqlite3VdbeChangeP1(v, topAddr, retAddr); sqlite3ClearTempRegCache(pParse); - if( pItem->fg.isCte ){ + if( pItem->fg.isCte && pItem->fg.isCorrelated==0 ){ CteUse *pCteUse = pItem->u2.pCteUse; pCteUse->addrM9e = pItem->addrFillSub; pCteUse->regRtn = pItem->regReturn; @@ -162308,7 +162348,7 @@ static const unsigned char aiClass[] = { #ifdef SQLITE_EBCDIC /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xa xb xc xd xe xf */ /* 0x */ 29, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 7, 7, 28, 28, -/* 1x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +/* 1x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, /* 2x */ 28, 28, 28, 28, 28, 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, /* 3x */ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, /* 4x */ 7, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 12, 17, 20, 10, @@ -229213,7 +229253,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50c3827", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a", -1, SQLITE_TRANSIENT); } /* @@ -234139,9 +234179,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=234142 +#if __LINE__!=234182 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50calt2" +#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40alt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/src/vendor/sqlite3/sqlite3.h b/src/vendor/sqlite3/sqlite3.h index f636b294d..cec3d9929 100644 --- a/src/vendor/sqlite3/sqlite3.h +++ b/src/vendor/sqlite3/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.35.2" -#define SQLITE_VERSION_NUMBER 3035002 -#define SQLITE_SOURCE_ID "2021-03-17 19:07:21 ea80f3002f4120f5dcee76e8779dfdc88e1e096c5cdd06904c20fd26d50c3827" +#define SQLITE_VERSION "3.35.3" +#define SQLITE_VERSION_NUMBER 3035003 +#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a" /* ** CAPI3REF: Run-Time Library Version Numbers From 89140d33bb651f7fdea8d8bdaaeb3363c11135e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 30 Mar 2021 04:24:49 +0200 Subject: [PATCH 24/47] style_pkg(scope = "line_breaks", strict = FALSE) --- R/SQLiteConnection.R | 4 +- R/connect.R | 6 +- R/datasetsDb.R | 2 +- R/deprecated.R | 4 +- R/regularExpressions.R | 2 +- R/table.R | 24 ++-- data-raw/datasets.R | 2 +- tests/testthat/helper-DBItest.R | 2 +- tests/testthat/test-affinity.R | 4 +- tests/testthat/test-basic-types.R | 6 +- tests/testthat/test-data-type.R | 10 +- tests/testthat/test-dbConnect.R | 6 +- tests/testthat/test-dbSendQuery.R | 2 +- tests/testthat/test-dbWriteTable.R | 24 ++-- .../testthat/test-dbWriteTableAutoincrement.R | 20 ++-- tests/testthat/test-error.R | 2 +- tests/testthat/test-extendedTypes.R | 17 ++- tests/testthat/test-field-types.R | 2 +- tests/testthat/test-json.R | 4 +- tests/testthat/test-regularExpressions.R | 1 - tests/testthat/test-transactions.R | 112 ++++++++++++------ 21 files changed, 152 insertions(+), 104 deletions(-) diff --git a/R/SQLiteConnection.R b/R/SQLiteConnection.R index bca0ddbd3..ea0625b92 100644 --- a/R/SQLiteConnection.R +++ b/R/SQLiteConnection.R @@ -242,8 +242,8 @@ sqliteSetBusyHandler <- function(dbObj, handler) { stopifnot( inherits(dbObj, "SQLiteConnection"), is.null(handler) || - is.function(handler) || - (is.numeric(handler) && length(handler) == 1 && !is.na(handler)) + is.function(handler) || + (is.numeric(handler) && length(handler) == 1 && !is.na(handler)) ) if (is.numeric(handler)) handler <- as.integer(handler) set_busy_handler(dbObj@ptr, handler) diff --git a/R/connect.R b/R/connect.R index 3fc639b41..75cab539a 100644 --- a/R/connect.R +++ b/R/connect.R @@ -182,8 +182,8 @@ setMethod("dbConnect", "SQLiteDriver", dbExecute(conn, sprintf("PRAGMA synchronous=%s", synchronous)), error = function(e) { warning("Couldn't set synchronous mode: ", conditionMessage(e), "\n", - "Use `synchronous` = NULL to turn off this warning.", - call. = FALSE) + "Use `synchronous` = NULL to turn off this warning.", + call. = FALSE) } ) } @@ -231,7 +231,7 @@ is_url_or_special_filename <- function(x) grepl("^(?:file|http|ftp|https|):", x) #' @export #' @rdname SQLite -setMethod("dbConnect", "SQLiteConnection", function(drv, ...){ +setMethod("dbConnect", "SQLiteConnection", function(drv, ...) { if (drv@dbname %in% c("", ":memory:", "file::memory:")) { stop("Can't clone a temporary database", call. = FALSE) } diff --git a/R/datasetsDb.R b/R/datasetsDb.R index 7c9d9252a..8d0bce0d9 100644 --- a/R/datasetsDb.R +++ b/R/datasetsDb.R @@ -15,5 +15,5 @@ #' dbDisconnect(db) datasetsDb <- function() { dbConnect(SQLite(), system.file("db", "datasets.sqlite", package = "RSQLite"), - flags = SQLITE_RO) + flags = SQLITE_RO) } diff --git a/R/deprecated.R b/R/deprecated.R index 522c524f6..be212ce93 100644 --- a/R/deprecated.R +++ b/R/deprecated.R @@ -93,7 +93,7 @@ isIdCurrent <- function(obj) { #' @keywords internal #' @export setMethod("make.db.names", - signature(dbObj="SQLiteConnection", snames = "character"), + signature(dbObj = "SQLiteConnection", snames = "character"), function(dbObj, snames, keywords, unique, allow.keywords, ...) { warning_once("RSQLite::make.db.names() is deprecated, please switch to DBI::dbQuoteIdentifier().") make.db.names.default(snames, keywords, unique, allow.keywords) @@ -109,7 +109,7 @@ setMethod("SQLKeywords", "SQLiteConnection", function(dbObj, ...) { #' @export #' @rdname make.db.names-SQLiteConnection-character-method setMethod("isSQLKeyword", - signature(dbObj="SQLiteConnection", name="character"), + signature(dbObj = "SQLiteConnection", name = "character"), function(dbObj, name, keywords, case, ...) { warning_once("RSQLite::isSQLKeyword() is deprecated, please switch to DBI::dbQuoteIdentifier().") isSQLKeyword.default(name, keywords = .SQL92Keywords, case) diff --git a/R/regularExpressions.R b/R/regularExpressions.R index 973a3ccfd..afeaf0431 100644 --- a/R/regularExpressions.R +++ b/R/regularExpressions.R @@ -24,7 +24,7 @@ initRegExp <- function(db) { if (!db@loadable.extensions) { stop("Loadable extensions are not enabled for this db connection", - call. = FALSE) + call. = FALSE) } extension_load(db@ptr, get_lib_path(), "sqlite3_regexp_init") diff --git a/R/table.R b/R/table.R index 6040cdcf7..aab755640 100644 --- a/R/table.R +++ b/R/table.R @@ -64,16 +64,16 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "data.frame"), row.names <- compatRowNames(row.names) - if ((!is.logical(row.names) && !is.character(row.names)) || length(row.names) != 1L) { + if ((!is.logical(row.names) && !is.character(row.names)) || length(row.names) != 1L) { stopc("`row.names` must be a logical scalar or a string") } - if (!is.logical(overwrite) || length(overwrite) != 1L || is.na(overwrite)) { + if (!is.logical(overwrite) || length(overwrite) != 1L || is.na(overwrite)) { stopc("`overwrite` must be a logical scalar") } - if (!is.logical(append) || length(append) != 1L || is.na(append)) { + if (!is.logical(append) || length(append) != 1L || is.na(append)) { stopc("`append` must be a logical scalar") } - if (!is.logical(temporary) || length(temporary) != 1L) { + if (!is.logical(temporary) || length(temporary) != 1L) { stopc("`temporary` must be a logical scalar") } if (overwrite && append) { @@ -136,7 +136,7 @@ match_col <- function(value, col_names) { if (!all(names(value) == col_names)) { if (all(tolower(names(value)) == tolower(col_names))) { warning("Column names will be matched ignoring character case", - call. = FALSE) + call. = FALSE) names(value) <- col_names return(value) } @@ -187,8 +187,8 @@ db_data_types <- function(conn, data) { setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), function(conn, name, value, ..., field.types = NULL, overwrite = FALSE, append = FALSE, header = TRUE, colClasses = NA, row.names = FALSE, - nrows = 50, sep = ",", eol="\n", skip = 0, temporary = FALSE) { - if(overwrite && append) + nrows = 50, sep = ",", eol = "\n", skip = 0, temporary = FALSE) { + if (overwrite && append) stop("overwrite and append cannot both be TRUE") value <- path.expand(value) @@ -201,7 +201,7 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), found <- dbExistsTable(conn, name) if (found && !overwrite && !append) { stop("Table ", name, " exists in database, and both overwrite and", - " append are FALSE", call. = FALSE) + " append are FALSE", call. = FALSE) } if (found && overwrite) { dbRemoveTable(conn, name) @@ -218,7 +218,7 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), fields <- field.types } sql <- sqlCreateTable(conn, name, fields, row.names = FALSE, - temporary = temporary) + temporary = temporary) dbExecute(conn, sql) } @@ -300,11 +300,11 @@ setMethod("dbReadTable", c("SQLiteConnection", "character"), row.names <- compatRowNames(row.names) - if ((!is.logical(row.names) && !is.character(row.names)) || length(row.names) != 1L) { + if ((!is.logical(row.names) && !is.character(row.names)) || length(row.names) != 1L) { stopc("`row.names` must be a logical scalar or a string") } - if (!is.logical(check.names) || length(check.names) != 1L) { + if (!is.logical(check.names) || length(check.names) != 1L) { stopc("`check.names` must be a logical scalar") } @@ -317,7 +317,7 @@ setMethod("dbReadTable", c("SQLiteConnection", "character"), name <- dbQuoteIdentifier(conn, name) out <- dbGetQuery(conn, paste("SELECT", select.cols, "FROM", name), - row.names = row.names) + row.names = row.names) if (check.names) { names(out) <- make.names(names(out), unique = TRUE) diff --git a/data-raw/datasets.R b/data-raw/datasets.R index 83fd34c12..41e64d7e2 100644 --- a/data-raw/datasets.R +++ b/data-raw/datasets.R @@ -2,7 +2,7 @@ tables <- unique(data(package = "datasets")$results[, 3]) tables <- tables[!grepl("(", tables, fixed = TRUE)] con <- dbConnect(SQLite(), "inst/db/datasets.sqlite") -for(table in tables) { +for (table in tables) { df <- getExportedValue("datasets", table) if (!is.data.frame(df)) next diff --git a/tests/testthat/helper-DBItest.R b/tests/testthat/helper-DBItest.R index 362f7be9e..db2b24be1 100644 --- a/tests/testthat/helper-DBItest.R +++ b/tests/testthat/helper-DBItest.R @@ -1,7 +1,7 @@ default_skip <- c( # enable to test a particular test only - #"(?!data_timestamp_current).*", + # "(?!data_timestamp_current).*", # sql "roundtrip_date", # #109 diff --git a/tests/testthat/test-affinity.R b/tests/testthat/test-affinity.R index 99bba13f0..953f591be 100644 --- a/tests/testthat/test-affinity.R +++ b/tests/testthat/test-affinity.R @@ -15,8 +15,8 @@ create_affinity_test_table <- function(con, affinity) { } check_affinity_get <- function(affinity, type, - real_type = "numeric", integer_type = type, - blob_integer_type = integer_type) { + real_type = "numeric", integer_type = type, + blob_integer_type = integer_type) { con <- memory_db() on.exit(dbDisconnect(con)) diff --git a/tests/testthat/test-basic-types.R b/tests/testthat/test-basic-types.R index 9f5da1c1d..e7c4b30b7 100644 --- a/tests/testthat/test-basic-types.R +++ b/tests/testthat/test-basic-types.R @@ -35,7 +35,11 @@ test_that("row-by-row fetch is equivalent", { dbWriteTable(db, "t1", basicDf, row.names = FALSE) rs <- dbSendQuery(db, "SELECT * FROM t1") - on.exit({dbClearResult(rs); dbDisconnect(db)}, add = FALSE) + on.exit( + { + dbClearResult(rs); dbDisconnect(db) + }, + add = FALSE) for (i in 1:5) { row <- dbFetch(rs, 1L) expect_equal(row, basicDf[i, ], check.attributes = FALSE) diff --git a/tests/testthat/test-data-type.R b/tests/testthat/test-data-type.R index 870f60e3e..3d08601bf 100644 --- a/tests/testthat/test-data-type.R +++ b/tests/testthat/test-data-type.R @@ -28,7 +28,7 @@ test_that("character and factor stored as TEXT", { test_that("raw and list stored as BLOB", { expect_equal(sqliteDataType(list(raw(1))), "BLOB") expect_equal(sqliteDataType(list()), "BLOB") - expect_equal(sqliteDataType(list(a=NULL)), "BLOB") + expect_equal(sqliteDataType(list(a = NULL)), "BLOB") }) # Specific to RSQLite @@ -46,19 +46,19 @@ test_that("AsIs class is ignored", { d = I(c(1.1, 2.2)) ) got <- sapply(df, sqliteDataType) - expect_equal(got, c(a="INTEGER", b="TEXT", c="BLOB", d="REAL")) + expect_equal(got, c(a = "INTEGER", b = "TEXT", c = "BLOB", d = "REAL")) }) test_that("unknown classes default to storage.mode()", { expect_equal(sqliteDataType(Sys.Date()), "REAL") expect_equal(sqliteDataType(Sys.time()), "REAL") - intClass <- structure(1L, class="unknown1") + intClass <- structure(1L, class = "unknown1") expect_equal(sqliteDataType(intClass), "INTEGER") - dblClass <- structure(3.14, class="unknown1") + dblClass <- structure(3.14, class = "unknown1") expect_equal(sqliteDataType(dblClass), "REAL") - strClass <- structure("abc", class="unknown1") + strClass <- structure("abc", class = "unknown1") expect_equal(sqliteDataType(strClass), "TEXT") }) diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index 30de4a8f6..07dc2d1a6 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -50,7 +50,7 @@ test_that("forbidden operations throw errors", { expect_error(dbConnect(SQLite(), tmpFile, flags = SQLITE_RW), "unable to open") dbrw <- dbConnect(SQLite(), tmpFile, flags = SQLITE_RWC) - df <- data.frame(a=letters, b=runif(26L), stringsAsFactors=FALSE) + df <- data.frame(a = letters, b = runif(26L), stringsAsFactors = FALSE) expect_true(dbWriteTable(dbrw, "t1", df)) dbDisconnect(dbrw) @@ -104,7 +104,9 @@ test_that("busy_handler", { on.exit(dbDisconnect(con1), add = TRUE) num <- NULL - cb <- function(n) { num <<- n; if (n >= 5) 0L else 1L } + cb <- function(n) { + num <<- n; if (n >= 5) 0L else 1L + } sqliteSetBusyHandler(con2, cb) dbExecute(con1, "BEGIN IMMEDIATE") diff --git a/tests/testthat/test-dbSendQuery.R b/tests/testthat/test-dbSendQuery.R index 66b928a55..4d8828563 100644 --- a/tests/testthat/test-dbSendQuery.R +++ b/tests/testthat/test-dbSendQuery.R @@ -139,7 +139,7 @@ test_that("NA matches NULL", { expect_warning( got <- dbGetPreparedQuery(con, "SELECT id FROM t1 WHERE y IS :y", - data.frame(y = NA_integer_)), + data.frame(y = NA_integer_)), "deprecated") expect_equal(got$id, "x") diff --git a/tests/testthat/test-dbWriteTable.R b/tests/testthat/test-dbWriteTable.R index 6eb882623..0eb881122 100644 --- a/tests/testthat/test-dbWriteTable.R +++ b/tests/testthat/test-dbWriteTable.R @@ -56,7 +56,7 @@ test_that("rownames not preserved by default", { on.exit(dbDisconnect(con)) df <- data.frame(x = 1:10) - row.names(df) <- paste(letters[1:10], 1:10, sep="") + row.names(df) <- paste(letters[1:10], 1:10, sep = "") dbWriteTable(con, "t1", df) t1 <- dbReadTable(con, "t1") @@ -68,7 +68,7 @@ test_that("rownames preserved with row.names = TRUE", { on.exit(dbDisconnect(con)) df <- data.frame(x = 1:10) - row.names(df) <- paste(letters[1:10], 1:10, sep="") + row.names(df) <- paste(letters[1:10], 1:10, sep = "") dbWriteTable(con, "t1", df, row.names = TRUE) t1 <- dbReadTable(con, "t1", row.names = TRUE) @@ -80,7 +80,7 @@ test_that("commas in fields are preserved", { on.exit(dbDisconnect(con)) df <- data.frame( - x = c("ABC, Inc.","DEF Holdings"), + x = c("ABC, Inc.", "DEF Holdings"), stringsAsFactors = FALSE ) dbWriteTable(con, "t1", df, row.names = FALSE) @@ -150,7 +150,7 @@ test_that("colclasses overridden by argument", { remote <- dbReadTable(con, "t1") expect_equal(sapply(remote, class), - c(A="character", B="integer", C="numeric")) + c(A = "character", B = "integer", C = "numeric")) }) test_that("options work", { @@ -163,12 +163,12 @@ test_that("options work", { stringsAsFactors = FALSE ) - dbWriteTable(con, "dat", "dat-rn.txt", sep="|", eol="\r\n", overwrite = TRUE) + dbWriteTable(con, "dat", "dat-rn.txt", sep = "|", eol = "\r\n", overwrite = TRUE) expect_equal(dbReadTable(con, "dat"), expected) # No idea why this fails in GHA on Windows skip_on_os("windows") - dbWriteTable(con, "dat", "dat-n.txt", sep="|", eol="\n", overwrite = TRUE) + dbWriteTable(con, "dat", "dat-n.txt", sep = "|", eol = "\n", overwrite = TRUE) expect_equal(dbReadTable(con, "dat"), expected) }) @@ -177,8 +177,8 @@ test_that("temporary works", { con <- dbConnect(SQLite(), db_file) on.exit(dbDisconnect(con), add = TRUE) - dbWriteTable(con, "prm", "dat-n.txt", sep="|", eol="\n", overwrite = TRUE) - dbWriteTable(con, "tmp", "dat-n.txt", sep="|", eol="\n", overwrite = TRUE, temporary = TRUE) + dbWriteTable(con, "prm", "dat-n.txt", sep = "|", eol = "\n", overwrite = TRUE) + dbWriteTable(con, "tmp", "dat-n.txt", sep = "|", eol = "\n", overwrite = TRUE, temporary = TRUE) expect_true(dbExistsTable(con, "prm")) expect_true(dbExistsTable(con, "tmp")) @@ -199,10 +199,10 @@ test_that("works within transaction", { stringsAsFactors = FALSE ) - csv_file <- tempfile(fileext='.csv') - write.csv(df, file=csv_file, row.names=FALSE, eol='\n') + csv_file <- tempfile(fileext = '.csv') + write.csv(df, file = csv_file, row.names = FALSE, eol = '\n') dbWithTransaction(con, { - dbWriteTable(con, 'tbl', csv_file, eol='\n', overwrite=TRUE) + dbWriteTable(con, 'tbl', csv_file, eol = '\n', overwrite = TRUE) expect_true(dbExistsTable(con, 'tbl')) dbBreak() }) @@ -387,7 +387,7 @@ test_that("dbWriteTable with AsIs raw fields", { on.exit(dbDisconnect(con)) expect_warning(dbWriteTable(con, "a", data.frame(a = I(as.raw(1:3)))), - " raw ") + " raw ") res <- dbReadTable(con, "a") expected <- data.frame(a = 1:3) diff --git a/tests/testthat/test-dbWriteTableAutoincrement.R b/tests/testthat/test-dbWriteTableAutoincrement.R index 5c11a7251..af1d27bee 100644 --- a/tests/testthat/test-dbWriteTableAutoincrement.R +++ b/tests/testthat/test-dbWriteTableAutoincrement.R @@ -6,8 +6,8 @@ sql_ddl <- "CREATE TABLE `tbl` ( `name` TEXT NOT NULL UNIQUE, `score` INTEGER NOT NULL);" -create_and_compare_table <- function( d_local, expected_remote_id ) { - #Create a connection, create a table, and populate the table. +create_and_compare_table <- function(d_local, expected_remote_id) { + # Create a connection, create a table, and populate the table. con <- dbConnect(SQLite()) on.exit(dbDisconnect(con), add = TRUE) @@ -15,11 +15,11 @@ create_and_compare_table <- function( d_local, expected_remote_id ) { write_successful <- dbWriteTable(con, name = 'tbl', value = d_local, append = TRUE, row.names = FALSE) expect_true(write_successful) - #Reads from the database and sort so comparisons are more robust. + # Reads from the database and sort so comparisons are more robust. d_remote <- dbReadTable(con, "tbl") d_remote <- d_remote[order(d_remote$score), ] - #Compares actual to expected values. + # Compares actual to expected values. expect_equal(d_remote$id, expected_remote_id, label = "The autoincrement values should be assigned correctly.") expect_equal(d_remote$name, d_local$name) expect_equal(d_remote$score, d_local$score) @@ -27,7 +27,7 @@ create_and_compare_table <- function( d_local, expected_remote_id ) { } test_that("autoincrement column not present before sending to database", { - #The column is created and populated in the DB. + # The column is created and populated in the DB. ds_local <- data.frame( # id = , # The 'id' column is not declared in R. name = letters, @@ -39,7 +39,7 @@ test_that("autoincrement column not present before sending to database", { }) test_that("autoincrement populated before database with integers", { - #The id column is set locally, which prevents/overrides the autoincrement assignment in the DB. + # The id column is set locally, which prevents/overrides the autoincrement assignment in the DB. ds_local <- data.frame( id = 126:101, name = letters, @@ -51,7 +51,7 @@ test_that("autoincrement populated before database with integers", { }) test_that("autoincrement populated before database with all NAs", { - #The id column is set to NAs, and replaced by an incremented value in the DB. + # The id column is set to NAs, and replaced by an incremented value in the DB. ds_local <- data.frame( id = NA_integer_, name = letters, @@ -63,14 +63,14 @@ test_that("autoincrement populated before database with all NAs", { }) test_that("autoincrement populated before database with some NAs in sequential order", { - #The NA holes are assigned an autoincrementing value in the DB. + # The NA holes are assigned an autoincrementing value in the DB. ds_local <- data.frame( id = c(101, 102, NA_integer_, 204, NA_integer_, 306, NA_integer_), name = letters[1:7], score = 1:7, stringsAsFactors = FALSE ) - expected_ids <- c(101, 102, 103, 204, 205, 306, 307) #Notice the jumps to 204 and to 306. + expected_ids <- c(101, 102, 103, 204, 205, 306, 307) # Notice the jumps to 204 and to 306. create_and_compare_table(ds_local, expected_ids) }) @@ -83,7 +83,7 @@ test_that("autoincrement populated before database with some NAs in reverse orde score = 1:7, stringsAsFactors = FALSE ) - expected_ids <- c(1, 306, 307, -204, 103, 102, 308) #The last value is `308`, not a duplicate `103`. + expected_ids <- c(1, 306, 307, -204, 103, 102, 308) # The last value is `308`, not a duplicate `103`. create_and_compare_table(ds_local, expected_ids) }) diff --git a/tests/testthat/test-error.R b/tests/testthat/test-error.R index 3152e3f99..5ace5b512 100644 --- a/tests/testthat/test-error.R +++ b/tests/testthat/test-error.R @@ -16,7 +16,7 @@ test_that("parameters with length != 1 (#89)", { dbExecute( con, "INSERT INTO records (x, y) VALUES (:x, :y)", - params = list(x = 1, y = list(1,2)) + params = list(x = 1, y = list(1, 2)) ), "Parameter 2 does not have length 1") expect_error( diff --git a/tests/testthat/test-extendedTypes.R b/tests/testthat/test-extendedTypes.R index b29c7ae71..aa38bfa1f 100644 --- a/tests/testthat/test-extendedTypes.R +++ b/tests/testthat/test-extendedTypes.R @@ -6,7 +6,7 @@ test_that("Can read dates", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt DATE)") - dbExecute(con, "insert into t1 values (1), (18612.2), ('2020-01-10') , ('not a date'), (?)", param=as.Date("2021-12-11")) + dbExecute(con, "insert into t1 values (1), (18612.2), ('2020-01-10') , ('not a date'), (?)", param = as.Date("2021-12-11")) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") expect_that(resdf[[1]], equals(as.Date(c("1970-01-02", "2020-12-16", "2020-01-10", NA, "2021-12-11")))) @@ -20,7 +20,7 @@ test_that("Can read datetime", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt DATETIME)") dbExecute(con, "insert into t1 values (1), (1608110307.2), ('2020-01-10 12:13:14'), ('not a date'), (?)", - param=as.POSIXct("2021-11-12 13:12:11", tz="UTC")) + param = as.POSIXct("2021-11-12 13:12:11", tz = "UTC")) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") expect_that(resdf[[1]], equals(as.POSIXct(c("1970-01-01 00:00:01", "2020-12-16 09:18:27.2", "2020-01-10 12:13:14", NA, "2021-11-12 13:12:11"), tz = "UTC"))) @@ -36,7 +36,7 @@ test_that("Can read time", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt TIME)") dbExecute(con, "insert into t1 values (1), (-90000.2), ('25:12:13.123') , ('not a time'), (?)", - param=structure(123, units = "secs", class = c("hms", "difftime"))) + param = structure(123, units = "secs", class = c("hms", "difftime"))) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") expected_times <- structure(c(1, -90000.2, 90733.123, NA, 123), units = "secs", class = c("hms", "difftime")) @@ -100,7 +100,7 @@ test_that("Blob as dates", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt DATE)") - dbExecute(con, "insert into t1 values (?)", param=list(blob::as_blob(as.raw(7)))) + dbExecute(con, "insert into t1 values (?)", param = list(blob::as_blob(as.raw(7)))) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(as.Date(NA))) @@ -113,10 +113,10 @@ test_that("Blob as datetime", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt DATETIME)") - dbExecute(con, "insert into t1 values (?)", param=list(blob::as_blob(as.raw(7)))) + dbExecute(con, "insert into t1 values (?)", param = list(blob::as_blob(as.raw(7)))) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") - expect_that(resdf[[1]], equals(as.POSIXct(NA_real_, origin="1970-01-01", tz="UTC"))) + expect_that(resdf[[1]], equals(as.POSIXct(NA_real_, origin = "1970-01-01", tz = "UTC"))) }) @@ -127,10 +127,9 @@ test_that("Blob as time", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt TIME)") - dbExecute(con, "insert into t1 values (?)", param=list(blob::as_blob(as.raw(7)))) + dbExecute(con, "insert into t1 values (?)", param = list(blob::as_blob(as.raw(7)))) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") - expect_that(resdf[[1]], equals(structure(NA_real_, units="secs", class=c("hms", "difftime")))) + expect_that(resdf[[1]], equals(structure(NA_real_, units = "secs", class = c("hms", "difftime")))) }) - diff --git a/tests/testthat/test-field-types.R b/tests/testthat/test-field-types.R index 46254832a..1e51ff83b 100644 --- a/tests/testthat/test-field-types.R +++ b/tests/testthat/test-field-types.R @@ -44,7 +44,7 @@ test_that("passing field.types with primary key information and non-unique value on.exit(dbDisconnect(con)) expect_error(dbWriteTable(con, "a", data.frame(a = c(1, 2, 1)), field.types = c("a" = "INTEGER PRIMARY KEY")), - "UNIQUE") + "UNIQUE") }) test_that("combining numeric types and NA to integer64 (#291)", { diff --git a/tests/testthat/test-json.R b/tests/testthat/test-json.R index effeaa9ce..8a030040c 100644 --- a/tests/testthat/test-json.R +++ b/tests/testthat/test-json.R @@ -5,8 +5,8 @@ test_that("JSON types function", { on.exit(dbDisconnect(con), add = TRUE) gotJson <- dbGetQuery(con, 'SELECT json(\'{"this":"is","a":["test"]}\')') - expect_that(gotJson[1,], equals('{"this":"is","a":["test"]}')) + expect_that(gotJson[1, ], equals('{"this":"is","a":["test"]}')) jsonArray <- dbGetQuery(con, 'SELECT json_array(1,2,3,4)') - expect_that(jsonArray[1,], equals('[1,2,3,4]')) + expect_that(jsonArray[1, ], equals('[1,2,3,4]')) }) diff --git a/tests/testthat/test-regularExpressions.R b/tests/testthat/test-regularExpressions.R index 896440b36..503b2746d 100644 --- a/tests/testthat/test-regularExpressions.R +++ b/tests/testthat/test-regularExpressions.R @@ -70,4 +70,3 @@ test_that("regular expressions can be initialized twice without harm", { expect_true(initRegExp(db = con)) }) - diff --git a/tests/testthat/test-transactions.R b/tests/testthat/test-transactions.R index 36cc53665..d33b37d35 100644 --- a/tests/testthat/test-transactions.R +++ b/tests/testthat/test-transactions.R @@ -4,9 +4,13 @@ test_that("autocommit", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con2), "a") }) @@ -14,17 +18,21 @@ test_that("commit unnamed transactions", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con) - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) dbCommit(con) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), "a") - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), c("a", "b")) }) @@ -33,17 +41,21 @@ test_that("rollback unnamed transactions", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con) - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) dbRollback(con) expect_equal(dbListTables(con), character()) expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), "b") expect_equal(dbListTables(con2), "b") }) @@ -52,13 +64,17 @@ test_that("no nested unnamed transactions (commit after error)", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con) expect_error(dbBegin(con)) dbCommit(con) - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), "a") }) @@ -67,13 +83,17 @@ test_that("no nested unnamed transactions (rollback after error)", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con) expect_error(dbBegin(con)) dbCommit(con) - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), "a") }) @@ -82,17 +102,21 @@ test_that("commit named transactions", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con, name = "tx") - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) dbCommit(con, name = "tx") expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), "a") - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), c("a", "b")) }) @@ -101,10 +125,14 @@ test_that("rollback named transactions", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con, name = "tx") - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) @@ -112,7 +140,7 @@ test_that("rollback named transactions", { expect_equal(dbListTables(con), character()) expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), "b") expect_equal(dbListTables(con2), "b") }) @@ -121,10 +149,14 @@ test_that("nested named transactions (commit - commit)", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con, name = "tx") - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) @@ -132,7 +164,7 @@ test_that("nested named transactions (commit - commit)", { expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), character()) @@ -144,7 +176,7 @@ test_that("nested named transactions (commit - commit)", { expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), c("a", "b")) - dbWriteTable(con, "c", data.frame(a=1)) + dbWriteTable(con, "c", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b", "c")) expect_equal(dbListTables(con2), c("a", "b", "c")) }) @@ -153,10 +185,14 @@ test_that("nested named transactions (commit - rollback)", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con, name = "tx") - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) @@ -164,7 +200,7 @@ test_that("nested named transactions (commit - rollback)", { expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), character()) @@ -176,7 +212,7 @@ test_that("nested named transactions (commit - rollback)", { expect_equal(dbListTables(con), character()) expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "c", data.frame(a=1)) + dbWriteTable(con, "c", data.frame(a = 1)) expect_equal(dbListTables(con), "c") expect_equal(dbListTables(con2), "c") }) @@ -185,10 +221,14 @@ test_that("nested named transactions (rollback - commit)", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con, name = "tx") - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) @@ -196,7 +236,7 @@ test_that("nested named transactions (rollback - commit)", { expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), character()) @@ -208,7 +248,7 @@ test_that("nested named transactions (rollback - commit)", { expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), "a") - dbWriteTable(con, "c", data.frame(a=1)) + dbWriteTable(con, "c", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "c")) expect_equal(dbListTables(con2), c("a", "c")) }) @@ -217,10 +257,14 @@ test_that("nested named transactions (rollback - rollback)", { db_file <- tempfile("transactions", fileext = ".sqlite") con <- dbConnect(SQLite(), db_file) con2 <- dbConnect(SQLite(), db_file) - on.exit({dbDisconnect(con); dbDisconnect(con2)}, add = TRUE) + on.exit( + { + dbDisconnect(con); dbDisconnect(con2) + }, + add = TRUE) dbBegin(con, name = "tx") - dbWriteTable(con, "a", data.frame(a=1)) + dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) @@ -228,7 +272,7 @@ test_that("nested named transactions (rollback - rollback)", { expect_equal(dbListTables(con), "a") expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "b", data.frame(a=1)) + dbWriteTable(con, "b", data.frame(a = 1)) expect_equal(dbListTables(con), c("a", "b")) expect_equal(dbListTables(con2), character()) @@ -240,7 +284,7 @@ test_that("nested named transactions (rollback - rollback)", { expect_equal(dbListTables(con), character()) expect_equal(dbListTables(con2), character()) - dbWriteTable(con, "c", data.frame(a=1)) + dbWriteTable(con, "c", data.frame(a = 1)) expect_equal(dbListTables(con), "c") expect_equal(dbListTables(con2), "c") }) From e15f3e3de2b7124e36dfe46f988ecc6f17080e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 30 Mar 2021 04:24:49 +0200 Subject: [PATCH 25/47] style_pkg(scope = "line_breaks", strict = TRUE) --- R/connect.R | 30 +++++++++------ R/datasetsDb.R | 3 +- R/deprecated.R | 9 +++-- R/extensions.R | 3 +- R/regularExpressions.R | 3 +- R/table.R | 31 ++++++++++----- R/transactions.R | 3 +- tests/testthat/test-DBItest.R | 2 - tests/testthat/test-basic-types.R | 3 +- tests/testthat/test-dbConnect.R | 1 - tests/testthat/test-dbSendQuery.R | 48 ++++++++++++++++-------- tests/testthat/test-dbWriteTable.R | 30 ++++++++++----- tests/testthat/test-encoding.R | 32 ++++++++++------ tests/testthat/test-error.R | 10 +++-- tests/testthat/test-extendedTypes.R | 15 ++------ tests/testthat/test-field-types.R | 6 ++- tests/testthat/test-regularExpressions.R | 35 ++++++++++------- tests/testthat/test-transactions.R | 33 ++++++++++------ 18 files changed, 186 insertions(+), 111 deletions(-) diff --git a/R/connect.R b/R/connect.R index 75cab539a..99084335e 100644 --- a/R/connect.R +++ b/R/connect.R @@ -33,9 +33,9 @@ SQLite <- function(...) { # From https://www.sqlite.org/c3ref/c_open_autoproxy.html #' @export -SQLITE_RW <- 0x00000002L +SQLITE_RW <- 0x00000002L #' @export -SQLITE_RO <- 0x00000001L +SQLITE_RO <- 0x00000001L #' @export SQLITE_RWC <- bitwOr(bitwOr(0x00000004L, 0x00000002L), 0x00000040L) # read/write + create + url @@ -119,9 +119,9 @@ SQLITE_RWC <- bitwOr(bitwOr(0x00000004L, 0x00000002L), 0x00000040L) #' #' # Or do it in batches #' rs <- dbSendQuery(con, "SELECT * FROM USArrests") -#' d1 <- dbFetch(rs, n = 10) # extract data in chunks of 10 rows +#' d1 <- dbFetch(rs, n = 10) # extract data in chunks of 10 rows #' dbHasCompleted(rs) -#' d2 <- dbFetch(rs, n = -1) # extract all remaining data +#' d2 <- dbFetch(rs, n = -1) # extract all remaining data #' dbHasCompleted(rs) #' dbClearResult(rs) #' @@ -171,7 +171,8 @@ setMethod("dbConnect", "SQLiteDriver", error = function(e) { warning("Couldn't set cache size: ", conditionMessage(e), "\n", "Use `cache_size` = NULL to turn off this warning.", - call. = FALSE) + call. = FALSE + ) } ) } @@ -183,7 +184,8 @@ setMethod("dbConnect", "SQLiteDriver", error = function(e) { warning("Couldn't set synchronous mode: ", conditionMessage(e), "\n", "Use `synchronous` = NULL to turn off this warning.", - call. = FALSE) + call. = FALSE + ) } ) } @@ -210,12 +212,16 @@ check_vfs <- function(vfs) { if (.Platform[["OS.type"]] == "windows") { warning("vfs customization not available on this platform.", - " Ignoring value: vfs = ", vfs, call. = FALSE) + " Ignoring value: vfs = ", vfs, + call. = FALSE + ) return("") } - match.arg(vfs, c("unix-posix", "unix-afp", "unix-flock", "unix-dotfile", - "unix-none")) + match.arg(vfs, c( + "unix-posix", "unix-afp", "unix-flock", "unix-dotfile", + "unix-none" + )) } # From the SQLite docs: If the filename is ":memory:", then a private, @@ -236,8 +242,10 @@ setMethod("dbConnect", "SQLiteConnection", function(drv, ...) { stop("Can't clone a temporary database", call. = FALSE) } - dbConnect(SQLite(), drv@dbname, vfs = drv@vfs, flags = drv@flags, - loadable.extensions = drv@loadable.extensions) + dbConnect(SQLite(), drv@dbname, + vfs = drv@vfs, flags = drv@flags, + loadable.extensions = drv@loadable.extensions + ) }) diff --git a/R/datasetsDb.R b/R/datasetsDb.R index 8d0bce0d9..0da28d8f0 100644 --- a/R/datasetsDb.R +++ b/R/datasetsDb.R @@ -15,5 +15,6 @@ #' dbDisconnect(db) datasetsDb <- function() { dbConnect(SQLite(), system.file("db", "datasets.sqlite", package = "RSQLite"), - flags = SQLITE_RO) + flags = SQLITE_RO + ) } diff --git a/R/deprecated.R b/R/deprecated.R index be212ce93..ed4d264e3 100644 --- a/R/deprecated.R +++ b/R/deprecated.R @@ -59,8 +59,10 @@ sqliteBuildTableDefinition <- function(con, name, value, field.types = NULL, value <- sqlColumnToRownames(value, row.names) if (is.null(field.types)) { - field.types <- vapply(value, dbDataType, dbObj = con, - FUN.VALUE = character(1)) + field.types <- vapply(value, dbDataType, + dbObj = con, + FUN.VALUE = character(1) + ) } # Escape field names names(field.types) <- dbQuoteIdentifier(con, names(field.types)) @@ -188,7 +190,8 @@ sqliteQuickColumn <- function(con, table, column) { #' @export setMethod("dbListResults", "SQLiteConnection", function(conn, ...) { warning("Querying the results associated with a connection is no longer supported", - call. = FALSE) + call. = FALSE + ) if (is.null(conn@ref$result)) list() else diff --git a/R/extensions.R b/R/extensions.R index 2c178a496..854e62860 100644 --- a/R/extensions.R +++ b/R/extensions.R @@ -27,7 +27,8 @@ initExtension <- function(db) { if (!db@loadable.extensions) { stop("Loadable extensions are not enabled for this db connection", - call. = FALSE) + call. = FALSE + ) } extension_load(db@ptr, get_lib_path(), "sqlite3_math_init") diff --git a/R/regularExpressions.R b/R/regularExpressions.R index afeaf0431..ee64570aa 100644 --- a/R/regularExpressions.R +++ b/R/regularExpressions.R @@ -24,7 +24,8 @@ initRegExp <- function(db) { if (!db@loadable.extensions) { stop("Loadable extensions are not enabled for this db connection", - call. = FALSE) + call. = FALSE + ) } extension_load(db@ptr, get_lib_path(), "sqlite3_regexp_init") diff --git a/R/table.R b/R/table.R index aab755640..5b03fe527 100644 --- a/R/table.R +++ b/R/table.R @@ -95,7 +95,9 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "data.frame"), found <- dbExistsTable(conn, name) if (found && !overwrite && !append) { stop("Table ", name, " exists in database, and both overwrite and", - " append are FALSE", call. = FALSE) + " append are FALSE", + call. = FALSE + ) } if (found && overwrite) { dbRemoveTable(conn, name) @@ -136,7 +138,8 @@ match_col <- function(value, col_names) { if (!all(names(value) == col_names)) { if (all(tolower(names(value)) == tolower(col_names))) { warning("Column names will be matched ignoring character case", - call. = FALSE) + call. = FALSE + ) names(value) <- col_names return(value) } @@ -188,6 +191,7 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), function(conn, name, value, ..., field.types = NULL, overwrite = FALSE, append = FALSE, header = TRUE, colClasses = NA, row.names = FALSE, nrows = 50, sep = ",", eol = "\n", skip = 0, temporary = FALSE) { + if (overwrite && append) stop("overwrite and append cannot both be TRUE") value <- path.expand(value) @@ -201,7 +205,9 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), found <- dbExistsTable(conn, name) if (found && !overwrite && !append) { stop("Table ", name, " exists in database, and both overwrite and", - " append are FALSE", call. = FALSE) + " append are FALSE", + call. = FALSE + ) } if (found && overwrite) { dbRemoveTable(conn, name) @@ -211,14 +217,18 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), # Initialise table with first `nrows` lines if (is.null(field.types)) { fields <- utils::read.table( - value, sep = sep, header = header, skip = skip, nrows = nrows, + value, + sep = sep, header = header, skip = skip, nrows = nrows, na.strings = "\\N", comment.char = "", colClasses = colClasses, - stringsAsFactors = FALSE) + stringsAsFactors = FALSE + ) } else { fields <- field.types } - sql <- sqlCreateTable(conn, name, fields, row.names = FALSE, - temporary = temporary) + sql <- sqlCreateTable(conn, name, fields, + row.names = FALSE, + temporary = temporary + ) dbExecute(conn, sql) } @@ -296,6 +306,7 @@ setMethod("dbReadTable", c("SQLiteConnection", "character"), function(conn, name, ..., row.names = pkgconfig::get_config("RSQLite::row.names.table", FALSE), check.names = TRUE, select.cols = NULL) { + name <- check_quoted_identifier(name) row.names <- compatRowNames(row.names) @@ -312,12 +323,14 @@ setMethod("dbReadTable", c("SQLiteConnection", "character"), select.cols = "*" } else { warning_once("`select.cols` is deprecated, use `dbGetQuery()` for complex queries.", - call. = FALSE) + call. = FALSE + ) } name <- dbQuoteIdentifier(conn, name) out <- dbGetQuery(conn, paste("SELECT", select.cols, "FROM", name), - row.names = row.names) + row.names = row.names + ) if (check.names) { names(out) <- make.names(names(out), unique = TRUE) diff --git a/R/transactions.R b/R/transactions.R index 0ed84e133..fc9074819 100644 --- a/R/transactions.R +++ b/R/transactions.R @@ -101,7 +101,8 @@ setMethod("dbRollback", "SQLiteConnection", function(conn, .name = NULL, ..., na compat_name <- function(name, .name) { if (!is.null(.name)) { warning("Please use `dbBegin(..., name = \"\")` to specify the name of the savepoint.", - call. = FALSE) + call. = FALSE + ) .name } else { name diff --git a/tests/testthat/test-DBItest.R b/tests/testthat/test-DBItest.R index 2e32cdacb..568903fca 100644 --- a/tests/testthat/test-DBItest.R +++ b/tests/testthat/test-DBItest.R @@ -1,9 +1,7 @@ if (identical(Sys.getenv("NOT_CRAN"), "true")) { - if (packageVersion("DBItest") >= "1.6.0") { DBItest::test_all() } else { DBItest::test_all(skip = c(default_skip, "roundtrip_raw", "roundtrip_blob")) } - } diff --git a/tests/testthat/test-basic-types.R b/tests/testthat/test-basic-types.R index e7c4b30b7..97ef60212 100644 --- a/tests/testthat/test-basic-types.R +++ b/tests/testthat/test-basic-types.R @@ -39,7 +39,8 @@ test_that("row-by-row fetch is equivalent", { { dbClearResult(rs); dbDisconnect(db) }, - add = FALSE) + add = FALSE + ) for (i in 1:5) { row <- dbFetch(rs, 1L) expect_equal(row, basicDf[i, ], check.attributes = FALSE) diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index 07dc2d1a6..d997ee36b 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -144,7 +144,6 @@ test_that("error in busy handler", { }) test_that("busy_handler timeout", { - skip_on_cran() dbfile <- tempfile() diff --git a/tests/testthat/test-dbSendQuery.R b/tests/testthat/test-dbSendQuery.R index 4d8828563..883e4fe4e 100644 --- a/tests/testthat/test-dbSendQuery.R +++ b/tests/testthat/test-dbSendQuery.R @@ -25,8 +25,10 @@ test_that("attempting to change schema with pending rows generates warning", { row1 <- dbFetch(rs, n = 1) expect_equal(row1, df[1, ]) - expect_warning(rs <- dbSendStatement(con, "CREATE TABLE t2 (x text, y integer)"), - "pending rows") + expect_warning( + rs <- dbSendStatement(con, "CREATE TABLE t2 (x text, y integer)"), + "pending rows" + ) dbClearResult(rs) }) @@ -40,8 +42,10 @@ test_that("simple position binding works", { expect_warning( dbGetPreparedQuery(con, "INSERT INTO t1 VALUES (?, ?)", - bind.data = data.frame(x = 2, y = 1)), - "deprecated") + bind.data = data.frame(x = 2, y = 1) + ), + "deprecated" + ) expect_equal(dbReadTable(con, "t1")$x, c(1, 2)) }) @@ -55,8 +59,10 @@ test_that("simple named binding works", { expect_warning( dbGetPreparedQuery(con, "INSERT INTO t1 VALUES (:x, :y)", - bind.data = data.frame(y = 1, x = 2)), - "deprecated") + bind.data = data.frame(y = 1, x = 2) + ), + "deprecated" + ) expect_equal(dbReadTable(con, "t1")$x, c(1, 2)) }) @@ -69,8 +75,10 @@ test_that("named binding errors if missing name", { expect_error( expect_warning( dbGetPreparedQuery(con, "INSERT INTO t1 VALUES (:x, :y)", - bind.data = data.frame(y = 1)), - "deprecated"), + bind.data = data.frame(y = 1) + ), + "deprecated" + ), "No value given for placeholder" ) }) @@ -84,7 +92,8 @@ test_that("one row per bound select, with factor", { expect_warning( got <- dbGetPreparedQuery(con, "select * from t1 where id = ?", id_frame), - "deprecated") + "deprecated" + ) expect_equal(got$id, c("e", "a", "c")) }) @@ -98,7 +107,8 @@ test_that("one row per bound select", { expect_warning( got <- dbGetPreparedQuery(con, "select * from t1 where id = ?", id_frame), - "deprecated") + "deprecated" + ) expect_equal(got$id, c("e", "a", "c")) }) @@ -111,21 +121,24 @@ test_that("failed matches are silently dropped", { memoise::forget(warning_once) expect_warning( df1 <- dbGetPreparedQuery(con, sql, data.frame(id = I("X"))), - "deprecated") + "deprecated" + ) expect_equal(nrow(df1), 0) expect_equal(names(df1), c("id", "x", "y")) memoise::forget(warning_once) expect_warning( df2 <- dbGetPreparedQuery(con, sql, data.frame(id = I(c("X", "Y")))), - "deprecated") + "deprecated" + ) expect_equal(nrow(df2), 0) expect_equal(names(df2), c("id", "x", "y")) memoise::forget(warning_once) expect_warning( df3 <- dbGetPreparedQuery(con, sql, data.frame(id = I(c("X", "a", "Y")))), - "deprecated") + "deprecated" + ) expect_equal(nrow(df3), 1) expect_equal(names(df3), c("id", "x", "y")) }) @@ -138,9 +151,12 @@ test_that("NA matches NULL", { dbExecute(con, "INSERT INTO t1 VALUES ('x', NULL, NULL)") expect_warning( - got <- dbGetPreparedQuery(con, "SELECT id FROM t1 WHERE y IS :y", - data.frame(y = NA_integer_)), - "deprecated") + got <- dbGetPreparedQuery( + con, "SELECT id FROM t1 WHERE y IS :y", + data.frame(y = NA_integer_) + ), + "deprecated" + ) expect_equal(got$id, "x") }) diff --git a/tests/testthat/test-dbWriteTable.R b/tests/testthat/test-dbWriteTable.R index 0eb881122..048cec0ae 100644 --- a/tests/testthat/test-dbWriteTable.R +++ b/tests/testthat/test-dbWriteTable.R @@ -9,8 +9,10 @@ test_that("throws error if constraint violated", { dbWriteTable(con, "t1", x) dbExecute(con, "CREATE UNIQUE INDEX t1_c1_c2_idx ON t1(col1, col2)") - expect_error(dbWriteTable(con, "t1", x, append = TRUE), - "UNIQUE constraint failed") + expect_error( + dbWriteTable(con, "t1", x, append = TRUE), + "UNIQUE constraint failed" + ) }) @@ -33,8 +35,10 @@ test_that("throws error if constrainted violated", { dbWriteTable(con, "t1", x) dbExecute(con, "CREATE UNIQUE INDEX t1_c1_c2_idx ON t1(col1, col2)") - expect_error(dbWriteTable(con, "t1", x, append = TRUE), - "UNIQUE constraint failed") + expect_error( + dbWriteTable(con, "t1", x, append = TRUE), + "UNIQUE constraint failed" + ) }) test_that("can't add table when result set open", { @@ -145,12 +149,16 @@ test_that("colclasses overridden by argument", { cat('A,B,C\n1,2,3\n4,5,6\na,7,8\n', file = tmp_file) on.exit(file.remove(tmp_file), add = TRUE) - dbWriteTable(con, "t1", tmp_file, header = TRUE, sep = ",", - colClasses = c("character", "integer", "double")) + dbWriteTable(con, "t1", tmp_file, + header = TRUE, sep = ",", + colClasses = c("character", "integer", "double") + ) remote <- dbReadTable(con, "t1") - expect_equal(sapply(remote, class), - c(A = "character", B = "integer", C = "numeric")) + expect_equal( + sapply(remote, class), + c(A = "character", B = "integer", C = "numeric") + ) }) test_that("options work", { @@ -386,8 +394,10 @@ test_that("dbWriteTable with AsIs raw fields", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) - expect_warning(dbWriteTable(con, "a", data.frame(a = I(as.raw(1:3)))), - " raw ") + expect_warning( + dbWriteTable(con, "a", data.frame(a = I(as.raw(1:3)))), + " raw " + ) res <- dbReadTable(con, "a") expected <- data.frame(a = 1:3) diff --git a/tests/testthat/test-encoding.R b/tests/testthat/test-encoding.R index 3dad00b57..c28b6baed 100644 --- a/tests/testthat/test-encoding.R +++ b/tests/testthat/test-encoding.R @@ -16,7 +16,8 @@ test_that("write tables whose colnames or contents are BIG5 encoded (#277)", { df <- structure( list(V1 = 1:3), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- big5_string dbWriteTable(con, "a", df) res <- dbReadTable(con, "a") @@ -25,7 +26,8 @@ test_that("write tables whose colnames or contents are BIG5 encoded (#277)", { df <- structure( list(V1 = 1:3, V2 = rep(big5_string, 3)), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- paste(big5_string, 1:2, sep = "") dbWriteTable(con, "b", df) res <- dbReadTable(con, "b") @@ -50,7 +52,8 @@ test_that("write tables whose colnames and contents are UTF-8 encoded (#277)", { df <- structure( list(V1 = 1:3), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- utf8_string dbWriteTable(con, "a", df) res <- dbReadTable(con, "a") @@ -59,7 +62,8 @@ test_that("write tables whose colnames and contents are UTF-8 encoded (#277)", { df <- structure( list(V1 = 1:3, V2 = rep(utf8_string, 3)), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- paste(utf8_string, 1:2, sep = "") dbWriteTable(con, "b", df) res <- dbReadTable(con, "b") @@ -86,18 +90,19 @@ test_that("list the field of tables whose colnames are BIG5 encoded (#277)", { df <- structure( list(V1 = 1:3), class = "data.frame", - row.names = c(NA, -3L)) + row.names = c(NA, -3L) + ) colnames(df) <- big5_string dbWriteTable(con, "a", df) expect_identical(dbListFields(con, "a"), colnames(df)) df <- structure( list(V1 = 1:3, V2 = rep(big5_string, 3)), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- paste(big5_string, 1:2, sep = "") dbWriteTable(con, "b", df) expect_identical(dbListFields(con, "b"), colnames(df)) - }) test_that("list the field of tables whose colnames are UTF-8 encoded (#277)", { @@ -118,18 +123,19 @@ test_that("list the field of tables whose colnames are UTF-8 encoded (#277)", { df <- structure( list(V1 = 1:3), class = "data.frame", - row.names = c(NA, -3L)) + row.names = c(NA, -3L) + ) colnames(df) <- utf8_string dbWriteTable(con, "a", df) expect_identical(dbListFields(con, "a"), colnames(df)) df <- structure( list(V1 = 1:3, V2 = rep(utf8_string, 3)), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- paste(utf8_string, 1:2, sep = "") dbWriteTable(con, "b", df) expect_identical(dbListFields(con, "b"), colnames(df)) - }) test_that("append tables whose colnames are UTF-8 encoded (#277)", { @@ -148,7 +154,8 @@ test_that("append tables whose colnames are UTF-8 encoded (#277)", { df <- structure( list(V1 = 1:3), class = "data.frame", - row.names = c(NA, -3L)) + row.names = c(NA, -3L) + ) utf8_string <- rawToChar(as.raw(c(0xe4, 0xb8, 0xad, 0xe6, 0x96, 0x87))) Encoding(utf8_string) <- "UTF-8" colnames(df) <- utf8_string @@ -158,7 +165,8 @@ test_that("append tables whose colnames are UTF-8 encoded (#277)", { df <- structure( list(V1 = 1:3, V2 = rep(utf8_string, 3)), class = "data.frame", - row.names = 1:3) + row.names = 1:3 + ) colnames(df) <- paste(utf8_string, 1:2, sep = "") dbWriteTable(con, "b", df) expect_error(dbWriteTable(con, "b", df, append = TRUE), NA) diff --git a/tests/testthat/test-error.R b/tests/testthat/test-error.R index 5ace5b512..f766aaf2d 100644 --- a/tests/testthat/test-error.R +++ b/tests/testthat/test-error.R @@ -11,22 +11,24 @@ test_that("parameters with length != 1 (#89)", { "INSERT INTO records (x, y) VALUES (:x, :y)", params = list(x = 1, y = 1) ), - NA) + NA + ) expect_error( dbExecute( con, "INSERT INTO records (x, y) VALUES (:x, :y)", params = list(x = 1, y = list(1, 2)) ), - "Parameter 2 does not have length 1") + "Parameter 2 does not have length 1" + ) expect_error( dbExecute( con, "INSERT INTO records (x, y) VALUES (:x, :y)", params = list(x = 1, y = NULL) ), - "Parameter 2 does not have length 1") - + "Parameter 2 does not have length 1" + ) }) test_that("multipart queries (#313)", { diff --git a/tests/testthat/test-extendedTypes.R b/tests/testthat/test-extendedTypes.R index aa38bfa1f..5b2757bba 100644 --- a/tests/testthat/test-extendedTypes.R +++ b/tests/testthat/test-extendedTypes.R @@ -10,7 +10,6 @@ test_that("Can read dates", { expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") expect_that(resdf[[1]], equals(as.Date(c("1970-01-02", "2020-12-16", "2020-01-10", NA, "2021-12-11")))) - }) test_that("Can read datetime", { @@ -20,11 +19,11 @@ test_that("Can read datetime", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt DATETIME)") dbExecute(con, "insert into t1 values (1), (1608110307.2), ('2020-01-10 12:13:14'), ('not a date'), (?)", - param = as.POSIXct("2021-11-12 13:12:11", tz = "UTC")) + param = as.POSIXct("2021-11-12 13:12:11", tz = "UTC") + ) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") expect_that(resdf[[1]], equals(as.POSIXct(c("1970-01-01 00:00:01", "2020-12-16 09:18:27.2", "2020-01-10 12:13:14", NA, "2021-11-12 13:12:11"), tz = "UTC"))) - }) @@ -36,12 +35,12 @@ test_that("Can read time", { dbExecute(con, "drop table if exists t1") dbExecute(con, "create table t1(dt TIME)") dbExecute(con, "insert into t1 values (1), (-90000.2), ('25:12:13.123') , ('not a time'), (?)", - param = structure(123, units = "secs", class = c("hms", "difftime"))) + param = structure(123, units = "secs", class = c("hms", "difftime")) + ) expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") expected_times <- structure(c(1, -90000.2, 90733.123, NA, 123), units = "secs", class = c("hms", "difftime")) expect_that(resdf[[1]], equals(expected_times)) - }) @@ -57,7 +56,6 @@ test_that("Columninfo dates", { col_info = dbColumnInfo(stmt) expect_that(col_info$type, equals("Date")) - }) test_that("Columninfo datetime", { @@ -72,7 +70,6 @@ test_that("Columninfo datetime", { col_info = dbColumnInfo(stmt) expect_that(col_info$type, equals("POSIXct")) - }) @@ -89,7 +86,6 @@ test_that("Columninfo time", { col_info = dbColumnInfo(stmt) expect_that(col_info$type, equals("hms")) - }) @@ -104,7 +100,6 @@ test_that("Blob as dates", { expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(as.Date(NA))) - }) test_that("Blob as datetime", { @@ -117,7 +112,6 @@ test_that("Blob as datetime", { expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(as.POSIXct(NA_real_, origin = "1970-01-01", tz = "UTC"))) - }) @@ -131,5 +125,4 @@ test_that("Blob as time", { expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(structure(NA_real_, units = "secs", class = c("hms", "difftime")))) - }) diff --git a/tests/testthat/test-field-types.R b/tests/testthat/test-field-types.R index 1e51ff83b..d9f638e88 100644 --- a/tests/testthat/test-field-types.R +++ b/tests/testthat/test-field-types.R @@ -43,8 +43,10 @@ test_that("passing field.types with primary key information and non-unique value con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) - expect_error(dbWriteTable(con, "a", data.frame(a = c(1, 2, 1)), field.types = c("a" = "INTEGER PRIMARY KEY")), - "UNIQUE") + expect_error( + dbWriteTable(con, "a", data.frame(a = c(1, 2, 1)), field.types = c("a" = "INTEGER PRIMARY KEY")), + "UNIQUE" + ) }) test_that("combining numeric types and NA to integer64 (#291)", { diff --git a/tests/testthat/test-regularExpressions.R b/tests/testthat/test-regularExpressions.R index 503b2746d..20cd566a3 100644 --- a/tests/testthat/test-regularExpressions.R +++ b/tests/testthat/test-regularExpressions.R @@ -1,43 +1,51 @@ context("regexp") test_that("adding support for regular expressions (#296)", { - con <- dbConnect( - SQLite()) + SQLite() + ) on.exit( dbDisconnect(con), - add = TRUE) + add = TRUE + ) # note true only from first # invocation of dbConnect() expect_true( initRegExp( - db = con)) + db = con + ) + ) dbWriteTable( conn = con, name = "iris", - value = iris) + value = iris + ) # this regular expression is just to # try out various syntax elements, # selecting versicolor and virginica res <- dbGetQuery( conn = con, - statement = 'SELECT "Sepal.Length" FROM iris WHERE Species REGEXP "^v[ei]\\w*[^x-z\\\\s]+$";') + statement = 'SELECT "Sepal.Length" FROM iris WHERE Species REGEXP "^v[ei]\\w*[^x-z\\\\s]+$";' + ) expect_equal( object = nrow(res), - expected = 100L) + expected = 100L + ) expect_true( - object = (6.2 < mean(res$Sepal.Length)) < 6.3) + object = (6.2 < mean(res$Sepal.Length)) < 6.3 + ) # REGEXP also works with numerical columns res <- dbGetQuery( conn = con, - statement = 'SELECT Species FROM iris WHERE "Sepal.Width" REGEXP "3[.][4-6]";') + statement = 'SELECT Species FROM iris WHERE "Sepal.Width" REGEXP "3[.][4-6]";' + ) # frequencies of Species res <- table(sort(res$Species)) @@ -48,25 +56,24 @@ test_that("adding support for regular expressions (#296)", { conn = con, name = "mtcars", value = mtcars, - row.names = TRUE) + row.names = TRUE + ) # another REGEXP example as we # are not interested in E types res <- dbGetQuery( conn = con, - statement = 'SELECT * FROM mtcars WHERE row_names REGEXP "Merc.*S[^E].*";') + statement = 'SELECT * FROM mtcars WHERE row_names REGEXP "Merc.*S[^E].*";' + ) # expected output expect_setequal(res$row_names, c("Merc 450SL", "Merc 450SLC")) - }) test_that("regular expressions can be initialized twice without harm", { - con <- dbConnect(SQLite()) expect_true(initRegExp(db = con)) expect_true(initRegExp(db = con)) - }) diff --git a/tests/testthat/test-transactions.R b/tests/testthat/test-transactions.R index d33b37d35..68a72ac0a 100644 --- a/tests/testthat/test-transactions.R +++ b/tests/testthat/test-transactions.R @@ -8,7 +8,8 @@ test_that("autocommit", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbWriteTable(con, "a", data.frame(a = 1)) expect_equal(dbListTables(con2), "a") @@ -22,7 +23,8 @@ test_that("commit unnamed transactions", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con) dbWriteTable(con, "a", data.frame(a = 1)) @@ -45,7 +47,8 @@ test_that("rollback unnamed transactions", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con) dbWriteTable(con, "a", data.frame(a = 1)) @@ -68,7 +71,8 @@ test_that("no nested unnamed transactions (commit after error)", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con) expect_error(dbBegin(con)) @@ -87,7 +91,8 @@ test_that("no nested unnamed transactions (rollback after error)", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con) expect_error(dbBegin(con)) @@ -106,7 +111,8 @@ test_that("commit named transactions", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con, name = "tx") dbWriteTable(con, "a", data.frame(a = 1)) @@ -129,7 +135,8 @@ test_that("rollback named transactions", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con, name = "tx") dbWriteTable(con, "a", data.frame(a = 1)) @@ -153,7 +160,8 @@ test_that("nested named transactions (commit - commit)", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con, name = "tx") dbWriteTable(con, "a", data.frame(a = 1)) @@ -189,7 +197,8 @@ test_that("nested named transactions (commit - rollback)", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con, name = "tx") dbWriteTable(con, "a", data.frame(a = 1)) @@ -225,7 +234,8 @@ test_that("nested named transactions (rollback - commit)", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con, name = "tx") dbWriteTable(con, "a", data.frame(a = 1)) @@ -261,7 +271,8 @@ test_that("nested named transactions (rollback - rollback)", { { dbDisconnect(con); dbDisconnect(con2) }, - add = TRUE) + add = TRUE + ) dbBegin(con, name = "tx") dbWriteTable(con, "a", data.frame(a = 1)) From d61bbaf9a9853c7a0cdc14fdaf9cef0b8827944a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 30 Mar 2021 04:24:49 +0200 Subject: [PATCH 26/47] style_pkg(scope = "tokens", strict = FALSE) --- R/connect.R | 2 +- R/table.R | 2 +- tests/testthat/test-basic-types.R | 3 +- tests/testthat/test-dbConnect.R | 3 +- tests/testthat/test-dbSendQuery.R | 2 +- tests/testthat/test-dbWriteTable.R | 18 +++++----- .../testthat/test-dbWriteTableAutoincrement.R | 4 +-- tests/testthat/test-extendedTypes.R | 18 +++++----- tests/testthat/test-json.R | 4 +-- tests/testthat/test-transactions.R | 33 ++++++++++++------- 10 files changed, 51 insertions(+), 38 deletions(-) diff --git a/R/connect.R b/R/connect.R index 99084335e..2a7b0a032 100644 --- a/R/connect.R +++ b/R/connect.R @@ -198,7 +198,7 @@ setMethod("dbConnect", "SQLiteDriver", conn@ptr, function(x) { if (dbIsValid(conn)) { - warning_once("call dbDisconnect() when finished working with a connection"); + warning_once("call dbDisconnect() when finished working with a connection") } } ) diff --git a/R/table.R b/R/table.R index 5b03fe527..8769604e4 100644 --- a/R/table.R +++ b/R/table.R @@ -320,7 +320,7 @@ setMethod("dbReadTable", c("SQLiteConnection", "character"), } if (is.null(select.cols)) { - select.cols = "*" + select.cols <- "*" } else { warning_once("`select.cols` is deprecated, use `dbGetQuery()` for complex queries.", call. = FALSE diff --git a/tests/testthat/test-basic-types.R b/tests/testthat/test-basic-types.R index 97ef60212..4e2d29d5a 100644 --- a/tests/testthat/test-basic-types.R +++ b/tests/testthat/test-basic-types.R @@ -37,7 +37,8 @@ test_that("row-by-row fetch is equivalent", { rs <- dbSendQuery(db, "SELECT * FROM t1") on.exit( { - dbClearResult(rs); dbDisconnect(db) + dbClearResult(rs) + dbDisconnect(db) }, add = FALSE ) diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index d997ee36b..32e627451 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -105,7 +105,8 @@ test_that("busy_handler", { num <- NULL cb <- function(n) { - num <<- n; if (n >= 5) 0L else 1L + num <<- n + if (n >= 5) 0L else 1L } sqliteSetBusyHandler(con2, cb) diff --git a/tests/testthat/test-dbSendQuery.R b/tests/testthat/test-dbSendQuery.R index 883e4fe4e..b27e4b56d 100644 --- a/tests/testthat/test-dbSendQuery.R +++ b/tests/testthat/test-dbSendQuery.R @@ -164,7 +164,7 @@ test_that("NA matches NULL", { test_that("mark UTF-8 encoding on non-ASCII colnames", { con <- dbConnect(SQLite()) on.exit(dbDisconnect(con)) - cn_field <- '\u4e2d\u6587' + cn_field <- "\u4e2d\u6587" tbl <- data.frame("a") colnames(tbl) <- cn_field dbWriteTable(con, name = "test", value = tbl) diff --git a/tests/testthat/test-dbWriteTable.R b/tests/testthat/test-dbWriteTable.R index 048cec0ae..b9272f1ad 100644 --- a/tests/testthat/test-dbWriteTable.R +++ b/tests/testthat/test-dbWriteTable.R @@ -133,7 +133,7 @@ test_that("comments are preserved", { on.exit(dbDisconnect(con), add = TRUE) tmp_file <- tempfile() - cat('A,B,C\n11,2#2,33\n', file = tmp_file) + cat("A,B,C\n11,2#2,33\n", file = tmp_file) on.exit(file.remove(tmp_file), add = TRUE) dbWriteTable(con, "t1", tmp_file, header = TRUE, sep = ",") @@ -146,7 +146,7 @@ test_that("colclasses overridden by argument", { on.exit(dbDisconnect(con), add = TRUE) tmp_file <- tempfile() - cat('A,B,C\n1,2,3\n4,5,6\na,7,8\n', file = tmp_file) + cat("A,B,C\n1,2,3\n4,5,6\na,7,8\n", file = tmp_file) on.exit(file.remove(tmp_file), add = TRUE) dbWriteTable(con, "t1", tmp_file, @@ -207,14 +207,14 @@ test_that("works within transaction", { stringsAsFactors = FALSE ) - csv_file <- tempfile(fileext = '.csv') - write.csv(df, file = csv_file, row.names = FALSE, eol = '\n') + csv_file <- tempfile(fileext = ".csv") + write.csv(df, file = csv_file, row.names = FALSE, eol = "\n") dbWithTransaction(con, { - dbWriteTable(con, 'tbl', csv_file, eol = '\n', overwrite = TRUE) - expect_true(dbExistsTable(con, 'tbl')) + dbWriteTable(con, "tbl", csv_file, eol = "\n", overwrite = TRUE) + expect_true(dbExistsTable(con, "tbl")) dbBreak() }) - expect_false(dbExistsTable(con, 'tbl')) + expect_false(dbExistsTable(con, "tbl")) }) @@ -315,7 +315,7 @@ test_that("dbWriteTable(iris, row.names = NA)", { res <- dbReadTable(con, "iris", row.names = NA) expect_equal(rownames(res), as.character(seq_len(nrow(iris)))) - res$Species = factor(res$Species) + res$Species <- factor(res$Species) expect_identical(res, iris) }) @@ -337,7 +337,7 @@ test_that("dbWriteTable(iris, row.names = 'rn')", { res <- dbReadTable(con, "iris", row.names = "rn") expect_equal(rownames(res), as.character(seq_len(nrow(iris)))) - res$Species = factor(res$Species) + res$Species <- factor(res$Species) # Original row names are numeric, RSQLite returns them as character # for simplicity diff --git a/tests/testthat/test-dbWriteTableAutoincrement.R b/tests/testthat/test-dbWriteTableAutoincrement.R index af1d27bee..0435bc623 100644 --- a/tests/testthat/test-dbWriteTableAutoincrement.R +++ b/tests/testthat/test-dbWriteTableAutoincrement.R @@ -12,7 +12,7 @@ create_and_compare_table <- function(d_local, expected_remote_id) { on.exit(dbDisconnect(con), add = TRUE) dbExecute(con, sql_ddl) - write_successful <- dbWriteTable(con, name = 'tbl', value = d_local, append = TRUE, row.names = FALSE) + write_successful <- dbWriteTable(con, name = "tbl", value = d_local, append = TRUE, row.names = FALSE) expect_true(write_successful) # Reads from the database and sort so comparisons are more robust. @@ -115,7 +115,7 @@ test_that("autoincrement partially populated with duplicate IDs throws an error" dbExecute(con, sql_ddl) expect_error( - dbWriteTable(con, name = 'tbl', value = ds_local, append = TRUE, row.names = FALSE), + dbWriteTable(con, name = "tbl", value = ds_local, append = TRUE, row.names = FALSE), "UNIQUE constraint failed: tbl[.]id" ) }) diff --git a/tests/testthat/test-extendedTypes.R b/tests/testthat/test-extendedTypes.R index 5b2757bba..62640c2ae 100644 --- a/tests/testthat/test-extendedTypes.R +++ b/tests/testthat/test-extendedTypes.R @@ -8,7 +8,7 @@ test_that("Can read dates", { dbExecute(con, "create table t1(dt DATE)") dbExecute(con, "insert into t1 values (1), (18612.2), ('2020-01-10') , ('not a date'), (?)", param = as.Date("2021-12-11")) - expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") + expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Unknown string format, NA is returned.") expect_that(resdf[[1]], equals(as.Date(c("1970-01-02", "2020-12-16", "2020-01-10", NA, "2021-12-11")))) }) @@ -22,7 +22,7 @@ test_that("Can read datetime", { param = as.POSIXct("2021-11-12 13:12:11", tz = "UTC") ) - expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") + expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Unknown string format, NA is returned.") expect_that(resdf[[1]], equals(as.POSIXct(c("1970-01-01 00:00:01", "2020-12-16 09:18:27.2", "2020-01-10 12:13:14", NA, "2021-11-12 13:12:11"), tz = "UTC"))) }) @@ -38,7 +38,7 @@ test_that("Can read time", { param = structure(123, units = "secs", class = c("hms", "difftime")) ) - expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Unknown string format, NA is returned.") + expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Unknown string format, NA is returned.") expected_times <- structure(c(1, -90000.2, 90733.123, NA, 123), units = "secs", class = c("hms", "difftime")) expect_that(resdf[[1]], equals(expected_times)) }) @@ -54,7 +54,7 @@ test_that("Columninfo dates", { stmt <- dbSendQuery(con, "select * from t1") on.exit(dbClearResult(stmt), add = TRUE, after = FALSE) - col_info = dbColumnInfo(stmt) + col_info <- dbColumnInfo(stmt) expect_that(col_info$type, equals("Date")) }) @@ -68,7 +68,7 @@ test_that("Columninfo datetime", { stmt <- dbSendQuery(con, "select * from t1") on.exit(dbClearResult(stmt), add = TRUE, after = FALSE) - col_info = dbColumnInfo(stmt) + col_info <- dbColumnInfo(stmt) expect_that(col_info$type, equals("POSIXct")) }) @@ -84,7 +84,7 @@ test_that("Columninfo time", { stmt <- dbSendQuery(con, "select * from t1") on.exit(dbClearResult(stmt), add = TRUE, after = FALSE) - col_info = dbColumnInfo(stmt) + col_info <- dbColumnInfo(stmt) expect_that(col_info$type, equals("hms")) }) @@ -98,7 +98,7 @@ test_that("Blob as dates", { dbExecute(con, "create table t1(dt DATE)") dbExecute(con, "insert into t1 values (?)", param = list(blob::as_blob(as.raw(7)))) - expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") + expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(as.Date(NA))) }) @@ -110,7 +110,7 @@ test_that("Blob as datetime", { dbExecute(con, "create table t1(dt DATETIME)") dbExecute(con, "insert into t1 values (?)", param = list(blob::as_blob(as.raw(7)))) - expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") + expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(as.POSIXct(NA_real_, origin = "1970-01-01", tz = "UTC"))) }) @@ -123,6 +123,6 @@ test_that("Blob as time", { dbExecute(con, "create table t1(dt TIME)") dbExecute(con, "insert into t1 values (?)", param = list(blob::as_blob(as.raw(7)))) - expect_warning(resdf <- dbGetQuery(con, 'SELECT * from t1'), "Cannot convert blob, NA is returned.") + expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(structure(NA_real_, units = "secs", class = c("hms", "difftime")))) }) diff --git a/tests/testthat/test-json.R b/tests/testthat/test-json.R index 8a030040c..24069fec1 100644 --- a/tests/testthat/test-json.R +++ b/tests/testthat/test-json.R @@ -7,6 +7,6 @@ test_that("JSON types function", { gotJson <- dbGetQuery(con, 'SELECT json(\'{"this":"is","a":["test"]}\')') expect_that(gotJson[1, ], equals('{"this":"is","a":["test"]}')) - jsonArray <- dbGetQuery(con, 'SELECT json_array(1,2,3,4)') - expect_that(jsonArray[1, ], equals('[1,2,3,4]')) + jsonArray <- dbGetQuery(con, "SELECT json_array(1,2,3,4)") + expect_that(jsonArray[1, ], equals("[1,2,3,4]")) }) diff --git a/tests/testthat/test-transactions.R b/tests/testthat/test-transactions.R index 68a72ac0a..fc1c11ee6 100644 --- a/tests/testthat/test-transactions.R +++ b/tests/testthat/test-transactions.R @@ -6,7 +6,8 @@ test_that("autocommit", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -21,7 +22,8 @@ test_that("commit unnamed transactions", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -45,7 +47,8 @@ test_that("rollback unnamed transactions", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -69,7 +72,8 @@ test_that("no nested unnamed transactions (commit after error)", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -89,7 +93,8 @@ test_that("no nested unnamed transactions (rollback after error)", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -109,7 +114,8 @@ test_that("commit named transactions", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -133,7 +139,8 @@ test_that("rollback named transactions", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -158,7 +165,8 @@ test_that("nested named transactions (commit - commit)", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -195,7 +203,8 @@ test_that("nested named transactions (commit - rollback)", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -232,7 +241,8 @@ test_that("nested named transactions (rollback - commit)", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) @@ -269,7 +279,8 @@ test_that("nested named transactions (rollback - rollback)", { con2 <- dbConnect(SQLite(), db_file) on.exit( { - dbDisconnect(con); dbDisconnect(con2) + dbDisconnect(con) + dbDisconnect(con2) }, add = TRUE ) From 85f289d58baccfdf57cf5e654eb56a0228112aa9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 30 Mar 2021 04:24:49 +0200 Subject: [PATCH 27/47] style_pkg(scope = "tokens", strict = TRUE) --- R/SQLiteDriver.R | 12 +++++++++--- R/connect.R | 4 +++- R/copy.R | 6 ++++-- R/deprecated.R | 5 +++-- R/query.R | 15 +++++++++++---- R/table.R | 3 ++- tests/testthat/helper-tibble.R | 5 +++-- tests/testthat/test-dbConnect.R | 8 ++++++-- 8 files changed, 41 insertions(+), 17 deletions(-) diff --git a/R/SQLiteDriver.R b/R/SQLiteDriver.R index 9d7851289..dcfcd85c6 100644 --- a/R/SQLiteDriver.R +++ b/R/SQLiteDriver.R @@ -22,9 +22,15 @@ setClass("SQLiteDriver", #' @rdname SQLiteDriver-class #' @export setMethod("dbDataType", "SQLiteDriver", function(dbObj, obj, ...) { - if (is.factor(obj)) return("TEXT") - if (is.data.frame(obj)) return(callNextMethod(dbObj, obj)) - if (is.integer64(obj)) return("INTEGER") + if (is.factor(obj)) { + return("TEXT") + } + if (is.data.frame(obj)) { + return(callNextMethod(dbObj, obj)) + } + if (is.integer64(obj)) { + return("INTEGER") + } switch(typeof(obj), integer = "INTEGER", diff --git a/R/connect.R b/R/connect.R index 2a7b0a032..2b7214b5f 100644 --- a/R/connect.R +++ b/R/connect.R @@ -208,7 +208,9 @@ setMethod("dbConnect", "SQLiteDriver", ) check_vfs <- function(vfs) { - if (is.null(vfs) || vfs == "") return("") + if (is.null(vfs) || vfs == "") { + return("") + } if (.Platform[["OS.type"]] == "windows") { warning("vfs customization not available on this platform.", diff --git a/R/copy.R b/R/copy.R index eb0a2f464..c8111411f 100644 --- a/R/copy.R +++ b/R/copy.R @@ -25,14 +25,16 @@ #' #' dbDisconnect(con) sqliteCopyDatabase <- function(from, to) { - if (!is(from, "SQLiteConnection")) + if (!is(from, "SQLiteConnection")) { stop("'from' must be a SQLiteConnection object") + } if (is.character(to)) { to <- dbConnect(SQLite(), to) on.exit(dbDisconnect(to), add = TRUE) } - if (!is(to, "SQLiteConnection")) + if (!is(to, "SQLiteConnection")) { stop("'to' must be a SQLiteConnection object") + } connection_copy_database(from@ptr, to@ptr) invisible(NULL) diff --git a/R/deprecated.R b/R/deprecated.R index ed4d264e3..a8b521e2b 100644 --- a/R/deprecated.R +++ b/R/deprecated.R @@ -192,10 +192,11 @@ setMethod("dbListResults", "SQLiteConnection", function(conn, ...) { warning("Querying the results associated with a connection is no longer supported", call. = FALSE ) - if (is.null(conn@ref$result)) + if (is.null(conn@ref$result)) { list() - else + } else { list(conn@ref$result) + } }) diff --git a/R/query.R b/R/query.R index d4c957bbf..5e98b20f1 100644 --- a/R/query.R +++ b/R/query.R @@ -67,8 +67,11 @@ db_bind <- function(res, params, ..., allow_named_superset) { } unmatched_param_indexes <- setdiff(seq_along(params), param_indexes) if (length(unmatched_param_indexes) > 0L) { - if (allow_named_superset) errorc <- warningc - else errorc <- stopc + if (allow_named_superset) { + errorc <- warningc + } else { + errorc <- stopc + } errorc( "Named parameters not used in query: ", @@ -103,9 +106,13 @@ setMethod("dbFetch", "SQLiteResult", function(res, n = -1, ..., }) convert_bigint <- function(df, bigint) { - if (bigint == "integer64") return(df) + if (bigint == "integer64") { + return(df) + } is_int64 <- which(vlapply(df, inherits, "integer64")) - if (length(is_int64) == 0) return(df) + if (length(is_int64) == 0) { + return(df) + } as_bigint <- switch(bigint, integer = as.integer, diff --git a/R/table.R b/R/table.R index 8769604e4..f3be7713a 100644 --- a/R/table.R +++ b/R/table.R @@ -192,8 +192,9 @@ setMethod("dbWriteTable", c("SQLiteConnection", "character", "character"), append = FALSE, header = TRUE, colClasses = NA, row.names = FALSE, nrows = 50, sep = ",", eol = "\n", skip = 0, temporary = FALSE) { - if (overwrite && append) + if (overwrite && append) { stop("overwrite and append cannot both be TRUE") + } value <- path.expand(value) row.names <- compatRowNames(row.names) diff --git a/tests/testthat/helper-tibble.R b/tests/testthat/helper-tibble.R index e1a97111f..74921d38c 100644 --- a/tests/testthat/helper-tibble.R +++ b/tests/testthat/helper-tibble.R @@ -1,9 +1,10 @@ list_df <- function(...) { df <- list(...) - if (length(df) > 0) + if (length(df) > 0) { attr(df, "row.names") <- .set_row_names(length(df[[1]])) - else + } else { attr(df, "row.names") <- .set_row_names(0L) + } class(df) <- "data.frame" df } diff --git a/tests/testthat/test-dbConnect.R b/tests/testthat/test-dbConnect.R index 32e627451..56e04df86 100644 --- a/tests/testthat/test-dbConnect.R +++ b/tests/testthat/test-dbConnect.R @@ -2,8 +2,12 @@ context("dbConnect") os <- function() { ostype <- .Platform[["OS.type"]] - if (ostype == "windows") return("windows") - if (grepl("darwin", R.Version()$os)) return("osx") + if (ostype == "windows") { + return("windows") + } + if (grepl("darwin", R.Version()$os)) { + return("osx") + } ostype } From 99c165624fefe51fae5c58d230977ea7396372f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 30 Mar 2021 04:40:26 +0200 Subject: [PATCH 28/47] Avoid strictness --- .github/workflows/pr-commands.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml index 4cdb3787c..d8c858c79 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -45,7 +45,7 @@ jobs: - name: Install dependencies run: Rscript -e 'install.packages("styler")' - name: Style - run: Rscript -e 'styler::style_pkg()' + run: Rscript -e 'styler::style_pkg(strict = FALSE)' - name: commit run: | git add \*.R From 9a70911e0a05d8442066b9d2c8593dd75faab9f7 Mon Sep 17 00:00:00 2001 From: Adam Black Date: Fri, 2 Apr 2021 09:11:37 -0400 Subject: [PATCH 29/47] Modify dbDataType to recognize date, time and datetime types when extended_types is TRUE. --- R/SQLiteDriver.R | 11 ++++++++++- R/table.R | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/R/SQLiteDriver.R b/R/SQLiteDriver.R index dcfcd85c6..d34290e68 100644 --- a/R/SQLiteDriver.R +++ b/R/SQLiteDriver.R @@ -21,7 +21,7 @@ setClass("SQLiteDriver", #' @rdname SQLiteDriver-class #' @export -setMethod("dbDataType", "SQLiteDriver", function(dbObj, obj, ...) { +setMethod("dbDataType", "SQLiteDriver", function(dbObj, obj, extended_types = FALSE, ...) { if (is.factor(obj)) { return("TEXT") } @@ -31,6 +31,15 @@ setMethod("dbDataType", "SQLiteDriver", function(dbObj, obj, ...) { if (is.integer64(obj)) { return("INTEGER") } + if (extended_types && methods::is(obj, "Date")) { + return("DATE") + } + if (extended_types && methods::is(obj, "POSIXct")) { + return("TIMESTAMP") + } + if (extended_types && methods::is(obj, "hms")) { + return("TIME") + } switch(typeof(obj), integer = "INTEGER", diff --git a/R/table.R b/R/table.R index f3be7713a..4505d0a29 100644 --- a/R/table.R +++ b/R/table.R @@ -426,5 +426,5 @@ sqliteListTablesQuery <- function(conn, schema = NULL, name = NULL) { #' @rdname SQLiteConnection-class #' @export setMethod("dbDataType", "SQLiteConnection", function(dbObj, obj, ...) { - dbDataType(SQLite(), obj, ...) + dbDataType(SQLite(), obj, extended_types = dbObj@extended_types, ...) }) From e2605897b4afd6c0cf6ef9559cca6918052b4d48 Mon Sep 17 00:00:00 2001 From: Adam Black Date: Fri, 2 Apr 2021 09:57:24 -0400 Subject: [PATCH 30/47] Add roundtrip date/time test --- tests/testthat/test-extendedTypes.R | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/testthat/test-extendedTypes.R b/tests/testthat/test-extendedTypes.R index 62640c2ae..119d49382 100644 --- a/tests/testthat/test-extendedTypes.R +++ b/tests/testthat/test-extendedTypes.R @@ -126,3 +126,21 @@ test_that("Blob as time", { expect_warning(resdf <- dbGetQuery(con, "SELECT * from t1"), "Cannot convert blob, NA is returned.") expect_that(resdf[[1]], equals(structure(NA_real_, units = "secs", class = c("hms", "difftime")))) }) + + +test_that("roundtrip extended_types with dbWriteTable", { + con <- dbConnect(SQLite(), extended_types = TRUE) + on.exit(dbDisconnect(con), add = TRUE) + + dates_times <- data.frame(some_date = as.Date(c("2000-01-01", "2000-02-03")), + some_datetime = .POSIXct(1:2, tz = "UTC"), + some_time = hms::hms(1:2)) + + dbWriteTable(con, "dates_times", dates_times) + + to_match <- dbReadTable(con, "dates_times") + + expect_identical(lapply(to_match, class), + lapply(dates_times, class)) + +}) From b10a7e737353ed7af6d987e8a2303c3652864543 Mon Sep 17 00:00:00 2001 From: upgrade Date: Sat, 3 Apr 2021 08:05:51 +0000 Subject: [PATCH 31/47] Upgrade bundled SQLite to 3.35.4 --- src/vendor/sqlite3/sqlite3.c | 77 +++++++++++++++++++++++++++--------- src/vendor/sqlite3/sqlite3.h | 6 +-- 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/src/vendor/sqlite3/sqlite3.c b/src/vendor/sqlite3/sqlite3.c index bb962bf09..9fca48f9f 100644 --- a/src/vendor/sqlite3/sqlite3.c +++ b/src/vendor/sqlite3/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.35.3. By combining all the individual C code files into this +** version 3.35.4. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -1186,9 +1186,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.35.3" -#define SQLITE_VERSION_NUMBER 3035003 -#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a" +#define SQLITE_VERSION "3.35.4" +#define SQLITE_VERSION_NUMBER 3035004 +#define SQLITE_SOURCE_ID "2021-04-02 15:20:15 5d4c65779dab868b285519b19e4cf9d451d50c6048f06f653aa701ec212df45e" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -19764,6 +19764,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*); SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); +SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse*, Expr*); SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); @@ -99002,15 +99003,19 @@ static int lookupName( if( pParse->pTriggerTab!=0 ){ int op = pParse->eTriggerOp; assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ + if( pParse->bReturning ){ + if( (pNC->ncFlags & NC_UBaseReg)!=0 + && (zTab==0 || sqlite3StrICmp(zTab,pParse->pTriggerTab->zName)==0) + ){ + pExpr->iTable = op!=TK_DELETE; + pTab = pParse->pTriggerTab; + } + }else if( op!=TK_DELETE && zTab && sqlite3StrICmp("new",zTab) == 0 ){ pExpr->iTable = 1; pTab = pParse->pTriggerTab; }else if( op!=TK_INSERT && zTab && sqlite3StrICmp("old",zTab)==0 ){ pExpr->iTable = 0; pTab = pParse->pTriggerTab; - }else if( pParse->bReturning && (pNC->ncFlags & NC_UBaseReg)!=0 ){ - pExpr->iTable = op!=TK_DELETE; - pTab = pParse->pTriggerTab; } } #endif /* SQLITE_OMIT_TRIGGER */ @@ -101605,8 +101610,8 @@ SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) && !IN_RENAME_OBJECT ){ - sqlite3ExprDelete(db, pLeft); - sqlite3ExprDelete(db, pRight); + sqlite3ExprDeferredDelete(pParse, pLeft); + sqlite3ExprDeferredDelete(pParse, pRight); return sqlite3Expr(db, TK_INTEGER, "0"); }else{ return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); @@ -101803,6 +101808,22 @@ SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ if( p ) sqlite3ExprDeleteNN(db, p); } + +/* +** Arrange to cause pExpr to be deleted when the pParse is deleted. +** This is similar to sqlite3ExprDelete() except that the delete is +** deferred untilthe pParse is deleted. +** +** The pExpr might be deleted immediately on an OOM error. +** +** The deferred delete is (currently) implemented by adding the +** pExpr to the pParse->pConstExpr list with a register number of 0. +*/ +SQLITE_PRIVATE void sqlite3ExprDeferredDelete(Parse *pParse, Expr *pExpr){ + pParse->pConstExpr = + sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); +} + /* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the ** expression. */ @@ -106428,8 +106449,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aCol[iAgg].pCExpr = pExpr; - pParse->pConstExpr = - sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); + sqlite3ExprDeferredDelete(pParse, pExpr); } } }else{ @@ -106438,8 +106458,7 @@ static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){ pExpr = sqlite3ExprDup(db, pExpr, 0); if( pExpr ){ pAggInfo->aFunc[iAgg].pFExpr = pExpr; - pParse->pConstExpr = - sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr); + sqlite3ExprDeferredDelete(pParse, pExpr); } } } @@ -139315,6 +139334,25 @@ SQLITE_PRIVATE SrcList *sqlite3TriggerStepSrc( return pSrc; } +/* +** Return true if the pExpr term from the RETURNING clause argument +** list is of the form "*". Raise an error if the terms if of the +** form "table.*". +*/ +static int isAsteriskTerm( + Parse *pParse, /* Parsing context */ + Expr *pTerm /* A term in the RETURNING clause */ +){ + assert( pTerm!=0 ); + if( pTerm->op==TK_ASTERISK ) return 1; + if( pTerm->op!=TK_DOT ) return 0; + assert( pTerm->pRight!=0 ); + assert( pTerm->pLeft!=0 ); + if( pTerm->pRight->op!=TK_ASTERISK ) return 0; + sqlite3ErrorMsg(pParse, "RETURNING may not use \"TABLE.*\" wildcards"); + return 1; +} + /* The input list pList is the list of result set terms from a RETURNING ** clause. The table that we are returning from is pTab. ** @@ -139332,7 +139370,8 @@ static ExprList *sqlite3ExpandReturning( for(i=0; inExpr; i++){ Expr *pOldExpr = pList->a[i].pExpr; - if( ALWAYS(pOldExpr!=0) && pOldExpr->op==TK_ASTERISK ){ + if( NEVER(pOldExpr==0) ) continue; + if( isAsteriskTerm(pParse, pOldExpr) ){ int jj; for(jj=0; jjnCol; jj++){ Expr *pNewExpr; @@ -147570,6 +147609,7 @@ static void exprAnalyzeExists( #endif if( pSel->pPrior ) return; if( pSel->pWhere==0 ) return; + if( pSel->pLimit ) return; if( 0==exprAnalyzeExistsFindEq(pSel, 0, 0) ) return; pDup = sqlite3ExprDup(db, pExpr, 0); @@ -155354,6 +155394,7 @@ static void windowCheckValue(Parse *pParse, int reg, int eCond){ VdbeCoverageIf(v, eCond==2); } sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC); VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */ VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */ VdbeCoverageNeverNullIf(v, eCond==2); @@ -229253,7 +229294,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2021-04-02 15:20:15 5d4c65779dab868b285519b19e4cf9d451d50c6048f06f653aa701ec212df45e", -1, SQLITE_TRANSIENT); } /* @@ -234179,9 +234220,9 @@ SQLITE_API int sqlite3_stmt_init( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) */ /************** End of stmt.c ************************************************/ -#if __LINE__!=234182 +#if __LINE__!=234223 #undef SQLITE_SOURCE_ID -#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40alt2" +#define SQLITE_SOURCE_ID "2021-04-02 15:20:15 5d4c65779dab868b285519b19e4cf9d451d50c6048f06f653aa701ec212dalt2" #endif /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } diff --git a/src/vendor/sqlite3/sqlite3.h b/src/vendor/sqlite3/sqlite3.h index cec3d9929..21ab5f1aa 100644 --- a/src/vendor/sqlite3/sqlite3.h +++ b/src/vendor/sqlite3/sqlite3.h @@ -123,9 +123,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.35.3" -#define SQLITE_VERSION_NUMBER 3035003 -#define SQLITE_SOURCE_ID "2021-03-26 12:12:52 4c5e6c200adc8afe0814936c67a971efc516d1bd739cb620235592f18f40be2a" +#define SQLITE_VERSION "3.35.4" +#define SQLITE_VERSION_NUMBER 3035004 +#define SQLITE_SOURCE_ID "2021-04-02 15:20:15 5d4c65779dab868b285519b19e4cf9d451d50c6048f06f653aa701ec212df45e" /* ** CAPI3REF: Run-Time Library Version Numbers From 67e167ba77dda10181b5226d9702b973bd2b5b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 5 Apr 2021 17:13:39 +0200 Subject: [PATCH 32/47] Bump version to 2.2.5.9001 --- DESCRIPTION | 4 ++-- NEWS.md | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 360dc684d..2cae8a76d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: RSQLite Title: 'SQLite' Interface for R -Version: 2.2.5.9000 -Date: 2021-03-25 +Version: 2.2.5.9001 +Date: 2021-04-05 Authors@R: c(person(given = "Kirill", family = "M\u00fcller", diff --git a/NEWS.md b/NEWS.md index c78187d97..02546dce3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,10 @@ +# RSQLite 2.2.5.9001 (2021-04-05) + +- Upgrade bundled SQLite to 3.35.4 (#361). + + # RSQLite 2.2.5.9000 (2021-03-25) - Same as previous version. From e20b511e511f7469df8dcf4a2594ec03332d09ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 5 Apr 2021 17:45:29 +0200 Subject: [PATCH 33/47] Remove BH dependency --- DESCRIPTION | 1 - src/Makevars | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 2cae8a76d..2315d0f5e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -55,7 +55,6 @@ Suggests: testthat, xml2 LinkingTo: - BH (>= 1.75.0-0), plogr (>= 0.2.0), Rcpp VignetteBuilder: diff --git a/src/Makevars b/src/Makevars index c5d559247..df204a849 100644 --- a/src/Makevars +++ b/src/Makevars @@ -1,5 +1,5 @@ # BOOST_NO_AUTO_PTR: https://github.com/eddelbuettel/bh/issues/57#issuecomment-406261595 -PKG_CPPFLAGS=-I. \ +PKG_CPPFLAGS=-I. -Ivendor \ -DRSQLITE_USE_BUNDLED_SQLITE \ -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_FTS3 \ From 0b4fde343b28cb0836112890df4dd07488fad143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Mon, 5 Apr 2021 18:10:21 +0200 Subject: [PATCH 34/47] Only necessary files --- src/vendor/boost/algorithm/string.hpp | 31 + .../boost/algorithm/string/case_conv.hpp | 176 + .../boost/algorithm/string/classification.hpp | 312 ++ src/vendor/boost/algorithm/string/compare.hpp | 199 + src/vendor/boost/algorithm/string/concept.hpp | 83 + src/vendor/boost/algorithm/string/config.hpp | 28 + .../boost/algorithm/string/constants.hpp | 36 + .../algorithm/string/detail/case_conv.hpp | 130 + .../string/detail/classification.hpp | 355 ++ .../algorithm/string/detail/find_format.hpp | 204 + .../string/detail/find_format_all.hpp | 275 ++ .../string/detail/find_format_store.hpp | 89 + .../algorithm/string/detail/find_iterator.hpp | 87 + .../boost/algorithm/string/detail/finder.hpp | 639 ++++ .../algorithm/string/detail/formatter.hpp | 119 + .../algorithm/string/detail/predicate.hpp | 77 + .../string/detail/replace_storage.hpp | 159 + .../algorithm/string/detail/sequence.hpp | 200 + .../boost/algorithm/string/detail/trim.hpp | 95 + .../boost/algorithm/string/detail/util.hpp | 107 + src/vendor/boost/algorithm/string/erase.hpp | 844 +++++ src/vendor/boost/algorithm/string/find.hpp | 334 ++ .../boost/algorithm/string/find_format.hpp | 286 ++ .../boost/algorithm/string/find_iterator.hpp | 388 ++ src/vendor/boost/algorithm/string/finder.hpp | 266 ++ .../boost/algorithm/string/formatter.hpp | 119 + .../boost/algorithm/string/iter_find.hpp | 201 + src/vendor/boost/algorithm/string/join.hpp | 145 + .../boost/algorithm/string/predicate.hpp | 476 +++ .../algorithm/string/predicate_facade.hpp | 42 + src/vendor/boost/algorithm/string/replace.hpp | 926 +++++ .../algorithm/string/sequence_traits.hpp | 120 + src/vendor/boost/algorithm/string/split.hpp | 175 + .../algorithm/string/std/list_traits.hpp | 68 + .../algorithm/string/std/slist_traits.hpp | 69 + .../algorithm/string/std/string_traits.hpp | 44 + .../string/std_containers_traits.hpp | 26 + src/vendor/boost/algorithm/string/trim.hpp | 398 ++ .../boost/algorithm/string/yes_no_type.hpp | 33 + src/vendor/boost/array.hpp | 456 +++ src/vendor/boost/assert.hpp | 85 + src/vendor/boost/assert/source_location.hpp | 93 + src/vendor/boost/bind.hpp | 60 + src/vendor/boost/bind/arg.hpp | 69 + src/vendor/boost/bind/bind.hpp | 2344 ++++++++++++ src/vendor/boost/bind/bind_cc.hpp | 117 + src/vendor/boost/bind/bind_mf2_cc.hpp | 228 ++ src/vendor/boost/bind/bind_mf_cc.hpp | 441 +++ .../boost/bind/detail/result_traits.hpp | 154 + src/vendor/boost/bind/mem_fn.hpp | 403 ++ src/vendor/boost/bind/mem_fn_cc.hpp | 103 + src/vendor/boost/bind/mem_fn_template.hpp | 1047 +++++ src/vendor/boost/bind/placeholders.hpp | 74 + src/vendor/boost/bind/storage.hpp | 475 +++ src/vendor/boost/call_traits.hpp | 20 + src/vendor/boost/checked_delete.hpp | 17 + src/vendor/boost/compressed_pair.hpp | 20 + src/vendor/boost/concept/assert.hpp | 45 + .../concept/detail/backward_compatibility.hpp | 16 + .../boost/concept/detail/concept_def.hpp | 34 + .../boost/concept/detail/concept_undef.hpp | 5 + src/vendor/boost/concept/detail/general.hpp | 77 + .../boost/concept/detail/has_constraints.hpp | 50 + src/vendor/boost/concept/usage.hpp | 36 + src/vendor/boost/concept_check.hpp | 1082 ++++++ src/vendor/boost/config.hpp | 67 + src/vendor/boost/config/auto_link.hpp | 524 +++ src/vendor/boost/config/compiler/gcc.hpp | 375 ++ .../boost/config/detail/posix_features.hpp | 95 + .../config/detail/select_compiler_config.hpp | 157 + .../config/detail/select_platform_config.hpp | 142 + .../config/detail/select_stdlib_config.hpp | 121 + src/vendor/boost/config/detail/suffix.hpp | 1116 ++++++ src/vendor/boost/config/helper_macros.hpp | 37 + src/vendor/boost/config/no_tr1/cmath.hpp | 28 + src/vendor/boost/config/no_tr1/complex.hpp | 28 + src/vendor/boost/config/no_tr1/functional.hpp | 28 + src/vendor/boost/config/no_tr1/memory.hpp | 28 + src/vendor/boost/config/platform/linux.hpp | 106 + src/vendor/boost/config/pragma_message.hpp | 31 + src/vendor/boost/config/stdlib/libstdcpp3.hpp | 359 ++ src/vendor/boost/config/user.hpp | 133 + src/vendor/boost/config/workaround.hpp | 294 ++ .../boost/container/allocator_traits.hpp | 493 +++ src/vendor/boost/container/container_fwd.hpp | 390 ++ .../boost/container/detail/addressof.hpp | 41 + .../container/detail/advanced_insert_int.hpp | 567 +++ .../boost/container/detail/algorithm.hpp | 157 + .../boost/container/detail/alloc_helpers.hpp | 60 + .../container/detail/allocation_type.hpp | 58 + .../detail/allocator_version_traits.hpp | 163 + .../boost/container/detail/config_begin.hpp | 50 + .../boost/container/detail/config_end.hpp | 13 + .../container/detail/construct_in_place.hpp | 96 + .../boost/container/detail/copy_move_algo.hpp | 1278 +++++++ .../boost/container/detail/destroyers.hpp | 447 +++ .../boost/container/detail/iterator.hpp | 86 + .../boost/container/detail/iterators.hpp | 891 +++++ src/vendor/boost/container/detail/min_max.hpp | 37 + src/vendor/boost/container/detail/mpl.hpp | 144 + .../detail/multiallocation_chain.hpp | 304 ++ .../boost/container/detail/next_capacity.hpp | 98 + .../boost/container/detail/placement_new.hpp | 30 + src/vendor/boost/container/detail/std_fwd.hpp | 59 + .../container/detail/transform_iterator.hpp | 180 + .../boost/container/detail/type_traits.hpp | 73 + .../boost/container/detail/value_functors.hpp | 42 + .../boost/container/detail/value_init.hpp | 51 + .../detail/variadic_templates_tools.hpp | 163 + .../boost/container/detail/version_type.hpp | 101 + .../boost/container/detail/workaround.hpp | 142 + src/vendor/boost/container/new_allocator.hpp | 194 + src/vendor/boost/container/options.hpp | 562 +++ src/vendor/boost/container/stable_vector.hpp | 2200 +++++++++++ .../boost/container/throw_exception.hpp | 176 + src/vendor/boost/container/vector.hpp | 3360 +++++++++++++++++ src/vendor/boost/container_hash/hash_fwd.hpp | 36 + src/vendor/boost/core/addressof.hpp | 274 ++ src/vendor/boost/core/checked_delete.hpp | 71 + src/vendor/boost/core/demangle.hpp | 126 + src/vendor/boost/core/enable_if.hpp | 128 + src/vendor/boost/core/ignore_unused.hpp | 70 + src/vendor/boost/core/is_same.hpp | 40 + .../boost/core/no_exceptions_support.hpp | 56 + src/vendor/boost/core/noncopyable.hpp | 63 + src/vendor/boost/core/ref.hpp | 302 ++ src/vendor/boost/core/swap.hpp | 70 + src/vendor/boost/core/use_default.hpp | 17 + src/vendor/boost/cstdint.hpp | 556 +++ src/vendor/boost/current_function.hpp | 75 + .../boost/date_time/adjust_functors.hpp | 164 + src/vendor/boost/date_time/c_time.hpp | 128 + .../boost/date_time/compiler_config.hpp | 161 + .../boost/date_time/constrained_value.hpp | 129 + src/vendor/boost/date_time/date.hpp | 209 + .../boost/date_time/date_clock_device.hpp | 77 + src/vendor/boost/date_time/date_defs.hpp | 26 + src/vendor/boost/date_time/date_duration.hpp | 146 + .../boost/date_time/date_duration_types.hpp | 265 ++ src/vendor/boost/date_time/date_facet.hpp | 766 ++++ .../boost/date_time/date_format_simple.hpp | 159 + .../boost/date_time/date_formatting.hpp | 137 + .../date_time/date_formatting_locales.hpp | 234 ++ .../date_time/date_generator_formatter.hpp | 265 ++ .../boost/date_time/date_generator_parser.hpp | 330 ++ .../boost/date_time/date_generators.hpp | 514 +++ src/vendor/boost/date_time/date_iterator.hpp | 101 + src/vendor/boost/date_time/date_names_put.hpp | 321 ++ src/vendor/boost/date_time/date_parsing.hpp | 342 ++ src/vendor/boost/date_time/dst_rules.hpp | 391 ++ .../boost/date_time/filetime_functions.hpp | 84 + src/vendor/boost/date_time/find_match.hpp | 42 + .../boost/date_time/format_date_parser.hpp | 724 ++++ .../boost/date_time/gregorian/conversion.hpp | 68 + .../boost/date_time/gregorian/formatters.hpp | 162 + .../date_time/gregorian/greg_calendar.hpp | 49 + .../boost/date_time/gregorian/greg_date.hpp | 145 + .../boost/date_time/gregorian/greg_day.hpp | 58 + .../date_time/gregorian/greg_day_of_year.hpp | 39 + .../date_time/gregorian/greg_duration.hpp | 147 + .../gregorian/greg_duration_types.hpp | 44 + .../boost/date_time/gregorian/greg_month.hpp | 133 + .../date_time/gregorian/greg_weekday.hpp | 100 + .../boost/date_time/gregorian/greg_year.hpp | 52 + .../boost/date_time/gregorian/greg_ymd.hpp | 33 + .../boost/date_time/gregorian/gregorian.hpp | 38 + .../date_time/gregorian/gregorian_io.hpp | 784 ++++ .../date_time/gregorian/gregorian_types.hpp | 109 + .../boost/date_time/gregorian/parsers.hpp | 110 + .../boost/date_time/gregorian_calendar.hpp | 69 + .../boost/date_time/gregorian_calendar.ipp | 224 ++ src/vendor/boost/date_time/int_adapter.hpp | 516 +++ src/vendor/boost/date_time/iso_format.hpp | 303 ++ src/vendor/boost/date_time/locale_config.hpp | 33 + .../boost/date_time/microsec_time_clock.hpp | 158 + .../boost/date_time/parse_format_base.hpp | 29 + src/vendor/boost/date_time/period.hpp | 375 ++ .../boost/date_time/period_formatter.hpp | 200 + src/vendor/boost/date_time/period_parser.hpp | 197 + .../boost/date_time/posix_time/conversion.hpp | 100 + .../posix_time/date_duration_operators.hpp | 114 + .../boost/date_time/posix_time/posix_time.hpp | 39 + .../posix_time/posix_time_config.hpp | 165 + .../posix_time/posix_time_duration.hpp | 91 + .../date_time/posix_time/posix_time_io.hpp | 236 ++ .../posix_time/posix_time_system.hpp | 68 + .../date_time/posix_time/posix_time_types.hpp | 55 + .../boost/date_time/posix_time/ptime.hpp | 84 + .../date_time/posix_time/time_formatters.hpp | 289 ++ .../date_time/posix_time/time_parsers.hpp | 48 + .../date_time/posix_time/time_period.hpp | 29 + src/vendor/boost/date_time/special_defs.hpp | 25 + .../date_time/special_values_formatter.hpp | 97 + .../boost/date_time/special_values_parser.hpp | 163 + src/vendor/boost/date_time/string_convert.hpp | 32 + .../boost/date_time/string_parse_tree.hpp | 281 ++ .../boost/date_time/strings_from_facet.hpp | 127 + src/vendor/boost/date_time/time.hpp | 214 ++ src/vendor/boost/date_time/time_clock.hpp | 83 + src/vendor/boost/date_time/time_defs.hpp | 43 + src/vendor/boost/date_time/time_duration.hpp | 310 ++ src/vendor/boost/date_time/time_facet.hpp | 1370 +++++++ .../date_time/time_formatting_streams.hpp | 122 + src/vendor/boost/date_time/time_iterator.hpp | 52 + src/vendor/boost/date_time/time_parsing.hpp | 339 ++ .../date_time/time_resolution_traits.hpp | 167 + .../boost/date_time/time_system_counted.hpp | 269 ++ .../boost/date_time/time_system_split.hpp | 226 ++ src/vendor/boost/date_time/wrapping_int.hpp | 170 + src/vendor/boost/date_time/year_month_day.hpp | 49 + src/vendor/boost/detail/basic_pointerbuf.hpp | 138 + src/vendor/boost/detail/call_traits.hpp | 172 + src/vendor/boost/detail/compressed_pair.hpp | 452 +++ src/vendor/boost/detail/indirect_traits.hpp | 195 + src/vendor/boost/detail/is_incrementable.hpp | 121 + src/vendor/boost/detail/lcast_precision.hpp | 185 + src/vendor/boost/detail/select_type.hpp | 36 + src/vendor/boost/detail/workaround.hpp | 10 + src/vendor/boost/exception/exception.hpp | 487 +++ src/vendor/boost/function.hpp | 74 + .../function/detail/function_iterate.hpp | 16 + .../boost/function/detail/maybe_include.hpp | 369 ++ src/vendor/boost/function/detail/prologue.hpp | 26 + src/vendor/boost/function/function_base.hpp | 878 +++++ src/vendor/boost/function/function_fwd.hpp | 69 + .../boost/function/function_template.hpp | 1203 ++++++ src/vendor/boost/function_equal.hpp | 28 + src/vendor/boost/get_pointer.hpp | 76 + src/vendor/boost/integer.hpp | 262 ++ src/vendor/boost/integer_fwd.hpp | 190 + src/vendor/boost/integer_traits.hpp | 256 ++ .../intrusive/circular_slist_algorithms.hpp | 406 ++ .../boost/intrusive/detail/algo_type.hpp | 53 + .../boost/intrusive/detail/algorithm.hpp | 90 + .../intrusive/detail/array_initializer.hpp | 96 + src/vendor/boost/intrusive/detail/assert.hpp | 45 + .../detail/common_slist_algorithms.hpp | 198 + .../boost/intrusive/detail/config_begin.hpp | 43 + .../boost/intrusive/detail/config_end.hpp | 15 + .../detail/default_header_holder.hpp | 70 + .../intrusive/detail/ebo_functor_holder.hpp | 292 ++ .../boost/intrusive/detail/equal_to_value.hpp | 50 + .../intrusive/detail/exception_disposer.hpp | 90 + .../intrusive/detail/function_detector.hpp | 92 + .../boost/intrusive/detail/generic_hook.hpp | 223 ++ .../intrusive/detail/get_value_traits.hpp | 222 ++ .../has_member_function_callable_with.hpp | 366 ++ .../boost/intrusive/detail/hook_traits.hpp | 195 + .../boost/intrusive/detail/iiterator.hpp | 122 + .../detail/is_stateful_value_traits.hpp | 81 + .../boost/intrusive/detail/iterator.hpp | 262 ++ .../intrusive/detail/key_nodeptr_comp.hpp | 125 + .../detail/minimal_less_equal_header.hpp | 30 + .../intrusive/detail/minimal_pair_header.hpp | 30 + src/vendor/boost/intrusive/detail/mpl.hpp | 217 ++ .../boost/intrusive/detail/node_holder.hpp | 35 + .../intrusive/detail/parent_from_member.hpp | 121 + .../intrusive/detail/reverse_iterator.hpp | 165 + .../intrusive/detail/simple_disposers.hpp | 52 + .../boost/intrusive/detail/size_holder.hpp | 91 + .../boost/intrusive/detail/slist_iterator.hpp | 137 + .../boost/intrusive/detail/slist_node.hpp | 64 + src/vendor/boost/intrusive/detail/std_fwd.hpp | 43 + .../intrusive/detail/tree_value_compare.hpp | 186 + src/vendor/boost/intrusive/detail/uncast.hpp | 55 + .../boost/intrusive/detail/workaround.hpp | 58 + src/vendor/boost/intrusive/intrusive_fwd.hpp | 766 ++++ .../intrusive/linear_slist_algorithms.hpp | 342 ++ src/vendor/boost/intrusive/link_mode.hpp | 63 + src/vendor/boost/intrusive/options.hpp | 264 ++ src/vendor/boost/intrusive/pack_options.hpp | 380 ++ src/vendor/boost/intrusive/pointer_rebind.hpp | 188 + src/vendor/boost/intrusive/pointer_traits.hpp | 318 ++ src/vendor/boost/intrusive/slist.hpp | 2251 +++++++++++ src/vendor/boost/intrusive/slist_hook.hpp | 296 ++ src/vendor/boost/io/ios_state.hpp | 485 +++ src/vendor/boost/io_fwd.hpp | 63 + src/vendor/boost/is_placeholder.hpp | 31 + src/vendor/boost/iterator/advance.hpp | 84 + .../boost/iterator/detail/config_def.hpp | 128 + .../boost/iterator/detail/config_undef.hpp | 24 + .../boost/iterator/detail/enable_if.hpp | 83 + .../detail/facade_iterator_category.hpp | 194 + src/vendor/boost/iterator/distance.hpp | 65 + src/vendor/boost/iterator/interoperable.hpp | 54 + .../boost/iterator/iterator_adaptor.hpp | 358 ++ .../boost/iterator/iterator_categories.hpp | 216 ++ .../boost/iterator/iterator_concepts.hpp | 273 ++ src/vendor/boost/iterator/iterator_facade.hpp | 981 +++++ src/vendor/boost/iterator/iterator_traits.hpp | 61 + .../boost/iterator/minimum_category.hpp | 95 + .../boost/iterator/reverse_iterator.hpp | 77 + .../boost/iterator/transform_iterator.hpp | 175 + src/vendor/boost/lexical_cast.hpp | 105 + .../boost/lexical_cast/bad_lexical_cast.hpp | 106 + .../lexical_cast/detail/converter_lexical.hpp | 498 +++ .../detail/converter_lexical_streams.hpp | 786 ++++ .../lexical_cast/detail/converter_numeric.hpp | 172 + .../boost/lexical_cast/detail/inf_nan.hpp | 197 + .../lexical_cast/detail/is_character.hpp | 59 + .../detail/lcast_char_constants.hpp | 46 + .../detail/lcast_unsigned_converters.hpp | 294 ++ .../boost/lexical_cast/detail/widest_char.hpp | 43 + .../lexical_cast/try_lexical_convert.hpp | 232 ++ src/vendor/boost/limits.hpp | 146 + src/vendor/boost/math/policies/policy.hpp | 1038 +++++ .../special_functions/detail/fp_traits.hpp | 582 +++ .../special_functions/detail/round_fwd.hpp | 93 + .../math/special_functions/fpclassify.hpp | 640 ++++ .../boost/math/special_functions/math_fwd.hpp | 1833 +++++++++ .../boost/math/special_functions/sign.hpp | 194 + src/vendor/boost/math/tools/config.hpp | 489 +++ src/vendor/boost/math/tools/promotion.hpp | 182 + src/vendor/boost/math/tools/real_cast.hpp | 31 + src/vendor/boost/math/tools/user.hpp | 105 + src/vendor/boost/mem_fn.hpp | 24 + src/vendor/boost/move/adl_move_swap.hpp | 272 ++ src/vendor/boost/move/algo/adaptive_merge.hpp | 350 ++ .../move/algo/detail/adaptive_sort_merge.hpp | 1492 ++++++++ .../boost/move/algo/detail/basic_op.hpp | 121 + .../boost/move/algo/detail/heap_sort.hpp | 111 + .../boost/move/algo/detail/insertion_sort.hpp | 128 + .../boost/move/algo/detail/is_sorted.hpp | 55 + src/vendor/boost/move/algo/detail/merge.hpp | 936 +++++ .../boost/move/algo/detail/merge_sort.hpp | 207 + .../boost/move/algo/detail/set_difference.hpp | 207 + src/vendor/boost/move/algo/move.hpp | 156 + src/vendor/boost/move/algo/predicate.hpp | 101 + src/vendor/boost/move/algo/unique.hpp | 55 + src/vendor/boost/move/core.hpp | 494 +++ src/vendor/boost/move/detail/config_begin.hpp | 21 + src/vendor/boost/move/detail/config_end.hpp | 12 + src/vendor/boost/move/detail/destruct_n.hpp | 66 + src/vendor/boost/move/detail/fwd_macros.hpp | 893 +++++ .../move/detail/iterator_to_raw_pointer.hpp | 59 + .../boost/move/detail/iterator_traits.hpp | 77 + src/vendor/boost/move/detail/meta_utils.hpp | 587 +++ .../boost/move/detail/meta_utils_core.hpp | 137 + src/vendor/boost/move/detail/move_helpers.hpp | 256 ++ .../boost/move/detail/placement_new.hpp | 30 + .../boost/move/detail/pointer_element.hpp | 168 + .../boost/move/detail/reverse_iterator.hpp | 171 + src/vendor/boost/move/detail/std_ns_begin.hpp | 30 + src/vendor/boost/move/detail/std_ns_end.hpp | 14 + .../boost/move/detail/to_raw_pointer.hpp | 45 + src/vendor/boost/move/detail/type_traits.hpp | 1194 ++++++ src/vendor/boost/move/detail/workaround.hpp | 69 + src/vendor/boost/move/iterator.hpp | 311 ++ src/vendor/boost/move/traits.hpp | 77 + src/vendor/boost/move/utility_core.hpp | 318 ++ src/vendor/boost/mpl/O1_size.hpp | 40 + src/vendor/boost/mpl/O1_size_fwd.hpp | 24 + src/vendor/boost/mpl/advance.hpp | 76 + src/vendor/boost/mpl/advance_fwd.hpp | 28 + src/vendor/boost/mpl/always.hpp | 38 + src/vendor/boost/mpl/and.hpp | 60 + src/vendor/boost/mpl/apply.hpp | 229 ++ src/vendor/boost/mpl/apply_fwd.hpp | 107 + src/vendor/boost/mpl/apply_wrap.hpp | 234 ++ src/vendor/boost/mpl/arg.hpp | 131 + src/vendor/boost/mpl/arg_fwd.hpp | 28 + src/vendor/boost/mpl/assert.hpp | 459 +++ src/vendor/boost/mpl/at.hpp | 52 + src/vendor/boost/mpl/at_fwd.hpp | 24 + src/vendor/boost/mpl/aux_/O1_size_impl.hpp | 87 + src/vendor/boost/mpl/aux_/adl_barrier.hpp | 48 + .../boost/mpl/aux_/advance_backward.hpp | 128 + src/vendor/boost/mpl/aux_/advance_forward.hpp | 127 + src/vendor/boost/mpl/aux_/arg_typedef.hpp | 31 + src/vendor/boost/mpl/aux_/arithmetic_op.hpp | 92 + src/vendor/boost/mpl/aux_/arity.hpp | 39 + src/vendor/boost/mpl/aux_/arity_spec.hpp | 67 + src/vendor/boost/mpl/aux_/at_impl.hpp | 45 + src/vendor/boost/mpl/aux_/begin_end_impl.hpp | 101 + src/vendor/boost/mpl/aux_/clear_impl.hpp | 35 + .../boost/mpl/aux_/common_name_wknd.hpp | 34 + src/vendor/boost/mpl/aux_/comparison_op.hpp | 83 + src/vendor/boost/mpl/aux_/config/adl.hpp | 40 + src/vendor/boost/mpl/aux_/config/arrays.hpp | 30 + src/vendor/boost/mpl/aux_/config/bcc.hpp | 28 + src/vendor/boost/mpl/aux_/config/bind.hpp | 33 + src/vendor/boost/mpl/aux_/config/compiler.hpp | 66 + src/vendor/boost/mpl/aux_/config/ctps.hpp | 30 + src/vendor/boost/mpl/aux_/config/dtp.hpp | 46 + src/vendor/boost/mpl/aux_/config/eti.hpp | 47 + .../boost/mpl/aux_/config/forwarding.hpp | 27 + src/vendor/boost/mpl/aux_/config/gcc.hpp | 23 + src/vendor/boost/mpl/aux_/config/gpu.hpp | 35 + .../boost/mpl/aux_/config/has_apply.hpp | 32 + src/vendor/boost/mpl/aux_/config/has_xxx.hpp | 34 + src/vendor/boost/mpl/aux_/config/integral.hpp | 38 + src/vendor/boost/mpl/aux_/config/intel.hpp | 21 + src/vendor/boost/mpl/aux_/config/lambda.hpp | 32 + src/vendor/boost/mpl/aux_/config/msvc.hpp | 21 + .../boost/mpl/aux_/config/msvc_typename.hpp | 26 + src/vendor/boost/mpl/aux_/config/nttp.hpp | 41 + .../mpl/aux_/config/overload_resolution.hpp | 29 + .../boost/mpl/aux_/config/pp_counter.hpp | 26 + .../boost/mpl/aux_/config/preprocessor.hpp | 39 + .../boost/mpl/aux_/config/static_constant.hpp | 25 + src/vendor/boost/mpl/aux_/config/ttp.hpp | 41 + src/vendor/boost/mpl/aux_/config/typeof.hpp | 38 + .../mpl/aux_/config/use_preprocessed.hpp | 19 + .../boost/mpl/aux_/config/workaround.hpp | 19 + src/vendor/boost/mpl/aux_/contains_impl.hpp | 61 + src/vendor/boost/mpl/aux_/find_if_pred.hpp | 31 + src/vendor/boost/mpl/aux_/fold_impl.hpp | 43 + src/vendor/boost/mpl/aux_/full_lambda.hpp | 354 ++ src/vendor/boost/mpl/aux_/has_apply.hpp | 32 + src/vendor/boost/mpl/aux_/has_begin.hpp | 23 + src/vendor/boost/mpl/aux_/has_size.hpp | 23 + src/vendor/boost/mpl/aux_/has_tag.hpp | 23 + src/vendor/boost/mpl/aux_/has_type.hpp | 23 + .../boost/mpl/aux_/include_preprocessed.hpp | 42 + .../boost/mpl/aux_/inserter_algorithm.hpp | 159 + .../boost/mpl/aux_/integral_wrapper.hpp | 93 + src/vendor/boost/mpl/aux_/is_msvc_eti_arg.hpp | 64 + src/vendor/boost/mpl/aux_/iter_apply.hpp | 47 + .../boost/mpl/aux_/iter_fold_if_impl.hpp | 210 ++ src/vendor/boost/mpl/aux_/iter_fold_impl.hpp | 42 + .../boost/mpl/aux_/lambda_arity_param.hpp | 25 + src/vendor/boost/mpl/aux_/lambda_spec.hpp | 49 + src/vendor/boost/mpl/aux_/lambda_support.hpp | 169 + src/vendor/boost/mpl/aux_/largest_int.hpp | 63 + src/vendor/boost/mpl/aux_/msvc_eti_base.hpp | 77 + src/vendor/boost/mpl/aux_/msvc_never_true.hpp | 34 + src/vendor/boost/mpl/aux_/msvc_type.hpp | 62 + src/vendor/boost/mpl/aux_/na.hpp | 95 + src/vendor/boost/mpl/aux_/na_assert.hpp | 34 + src/vendor/boost/mpl/aux_/na_fwd.hpp | 31 + src/vendor/boost/mpl/aux_/na_spec.hpp | 175 + .../boost/mpl/aux_/nested_type_wknd.hpp | 48 + src/vendor/boost/mpl/aux_/nttp_decl.hpp | 35 + .../boost/mpl/aux_/numeric_cast_utils.hpp | 77 + src/vendor/boost/mpl/aux_/numeric_op.hpp | 315 ++ .../preprocessed/gcc/advance_backward.hpp | 97 + .../aux_/preprocessed/gcc/advance_forward.hpp | 97 + .../boost/mpl/aux_/preprocessed/gcc/and.hpp | 69 + .../boost/mpl/aux_/preprocessed/gcc/apply.hpp | 169 + .../mpl/aux_/preprocessed/gcc/apply_fwd.hpp | 52 + .../mpl/aux_/preprocessed/gcc/apply_wrap.hpp | 84 + .../boost/mpl/aux_/preprocessed/gcc/arg.hpp | 123 + .../boost/mpl/aux_/preprocessed/gcc/bind.hpp | 561 +++ .../mpl/aux_/preprocessed/gcc/bind_fwd.hpp | 52 + .../mpl/aux_/preprocessed/gcc/equal_to.hpp | 94 + .../mpl/aux_/preprocessed/gcc/fold_impl.hpp | 180 + .../mpl/aux_/preprocessed/gcc/full_lambda.hpp | 558 +++ .../mpl/aux_/preprocessed/gcc/greater.hpp | 94 + .../aux_/preprocessed/gcc/greater_equal.hpp | 94 + .../preprocessed/gcc/iter_fold_if_impl.hpp | 133 + .../aux_/preprocessed/gcc/iter_fold_impl.hpp | 180 + .../boost/mpl/aux_/preprocessed/gcc/less.hpp | 94 + .../mpl/aux_/preprocessed/gcc/less_equal.hpp | 94 + .../boost/mpl/aux_/preprocessed/gcc/list.hpp | 323 ++ .../boost/mpl/aux_/preprocessed/gcc/minus.hpp | 146 + .../aux_/preprocessed/gcc/not_equal_to.hpp | 94 + .../boost/mpl/aux_/preprocessed/gcc/or.hpp | 69 + .../aux_/preprocessed/gcc/placeholders.hpp | 105 + .../boost/mpl/aux_/preprocessed/gcc/plus.hpp | 146 + .../boost/mpl/aux_/preprocessed/gcc/quote.hpp | 123 + .../preprocessed/gcc/reverse_fold_impl.hpp | 231 ++ .../aux_/preprocessed/gcc/template_arity.hpp | 97 + .../boost/mpl/aux_/preprocessed/gcc/times.hpp | 146 + .../mpl/aux_/preprocessed/gcc/vector.hpp | 323 ++ .../mpl/aux_/preprocessor/def_params_tail.hpp | 105 + .../mpl/aux_/preprocessor/default_params.hpp | 67 + .../boost/mpl/aux_/preprocessor/enum.hpp | 74 + .../boost/mpl/aux_/preprocessor/params.hpp | 77 + src/vendor/boost/mpl/aux_/push_back_impl.hpp | 70 + src/vendor/boost/mpl/aux_/push_front_impl.hpp | 71 + .../boost/mpl/aux_/reverse_fold_impl.hpp | 44 + src/vendor/boost/mpl/aux_/size_impl.hpp | 52 + src/vendor/boost/mpl/aux_/static_cast.hpp | 27 + src/vendor/boost/mpl/aux_/template_arity.hpp | 189 + .../boost/mpl/aux_/template_arity_fwd.hpp | 23 + .../boost/mpl/aux_/traits_lambda_spec.hpp | 63 + src/vendor/boost/mpl/aux_/type_wrapper.hpp | 47 + src/vendor/boost/mpl/aux_/value_wknd.hpp | 89 + src/vendor/boost/mpl/aux_/yes_no.hpp | 58 + src/vendor/boost/mpl/back_fwd.hpp | 24 + src/vendor/boost/mpl/back_inserter.hpp | 34 + src/vendor/boost/mpl/begin_end.hpp | 57 + src/vendor/boost/mpl/begin_end_fwd.hpp | 27 + src/vendor/boost/mpl/bind.hpp | 551 +++ src/vendor/boost/mpl/bind_fwd.hpp | 99 + src/vendor/boost/mpl/bool.hpp | 39 + src/vendor/boost/mpl/bool_fwd.hpp | 33 + src/vendor/boost/mpl/clear.hpp | 39 + src/vendor/boost/mpl/clear_fwd.hpp | 24 + src/vendor/boost/mpl/comparison.hpp | 24 + src/vendor/boost/mpl/contains.hpp | 41 + src/vendor/boost/mpl/contains_fwd.hpp | 25 + src/vendor/boost/mpl/deref.hpp | 41 + src/vendor/boost/mpl/distance.hpp | 78 + src/vendor/boost/mpl/distance_fwd.hpp | 28 + src/vendor/boost/mpl/empty_fwd.hpp | 24 + src/vendor/boost/mpl/equal_to.hpp | 21 + src/vendor/boost/mpl/eval_if.hpp | 71 + src/vendor/boost/mpl/find.hpp | 38 + src/vendor/boost/mpl/find_if.hpp | 50 + src/vendor/boost/mpl/fold.hpp | 48 + src/vendor/boost/mpl/front_fwd.hpp | 24 + src/vendor/boost/mpl/front_inserter.hpp | 33 + src/vendor/boost/mpl/greater.hpp | 21 + src/vendor/boost/mpl/greater_equal.hpp | 21 + src/vendor/boost/mpl/has_xxx.hpp | 647 ++++ src/vendor/boost/mpl/identity.hpp | 45 + src/vendor/boost/mpl/if.hpp | 135 + src/vendor/boost/mpl/inserter.hpp | 32 + src/vendor/boost/mpl/int.hpp | 22 + src/vendor/boost/mpl/int_fwd.hpp | 27 + src/vendor/boost/mpl/integral_c.hpp | 51 + src/vendor/boost/mpl/integral_c_fwd.hpp | 32 + src/vendor/boost/mpl/integral_c_tag.hpp | 26 + src/vendor/boost/mpl/iter_fold.hpp | 49 + src/vendor/boost/mpl/iter_fold_if.hpp | 117 + src/vendor/boost/mpl/iterator_range.hpp | 42 + src/vendor/boost/mpl/iterator_tags.hpp | 27 + src/vendor/boost/mpl/lambda.hpp | 29 + src/vendor/boost/mpl/lambda_fwd.hpp | 57 + src/vendor/boost/mpl/less.hpp | 21 + src/vendor/boost/mpl/less_equal.hpp | 21 + src/vendor/boost/mpl/limits/arity.hpp | 21 + src/vendor/boost/mpl/limits/list.hpp | 21 + src/vendor/boost/mpl/limits/vector.hpp | 21 + src/vendor/boost/mpl/list.hpp | 57 + src/vendor/boost/mpl/list/aux_/O1_size.hpp | 33 + src/vendor/boost/mpl/list/aux_/begin_end.hpp | 44 + src/vendor/boost/mpl/list/aux_/clear.hpp | 34 + src/vendor/boost/mpl/list/aux_/empty.hpp | 34 + src/vendor/boost/mpl/list/aux_/front.hpp | 33 + .../mpl/list/aux_/include_preprocessed.hpp | 35 + src/vendor/boost/mpl/list/aux_/item.hpp | 55 + src/vendor/boost/mpl/list/aux_/iterator.hpp | 76 + src/vendor/boost/mpl/list/aux_/pop_front.hpp | 34 + .../list/aux_/preprocessed/plain/list10.hpp | 149 + .../list/aux_/preprocessed/plain/list20.hpp | 169 + src/vendor/boost/mpl/list/aux_/push_back.hpp | 36 + src/vendor/boost/mpl/list/aux_/push_front.hpp | 39 + src/vendor/boost/mpl/list/aux_/size.hpp | 33 + src/vendor/boost/mpl/list/aux_/tag.hpp | 24 + src/vendor/boost/mpl/list/list0.hpp | 42 + src/vendor/boost/mpl/list/list10.hpp | 43 + src/vendor/boost/mpl/list/list20.hpp | 43 + src/vendor/boost/mpl/logical.hpp | 21 + src/vendor/boost/mpl/long.hpp | 22 + src/vendor/boost/mpl/long_fwd.hpp | 27 + src/vendor/boost/mpl/minus.hpp | 21 + src/vendor/boost/mpl/multiplies.hpp | 53 + src/vendor/boost/mpl/negate.hpp | 81 + src/vendor/boost/mpl/next.hpp | 19 + src/vendor/boost/mpl/next_prior.hpp | 49 + src/vendor/boost/mpl/not.hpp | 51 + src/vendor/boost/mpl/not_equal_to.hpp | 21 + src/vendor/boost/mpl/numeric_cast.hpp | 41 + src/vendor/boost/mpl/or.hpp | 61 + src/vendor/boost/mpl/pair.hpp | 70 + src/vendor/boost/mpl/placeholders.hpp | 100 + src/vendor/boost/mpl/plus.hpp | 21 + src/vendor/boost/mpl/pop_back_fwd.hpp | 24 + src/vendor/boost/mpl/pop_front_fwd.hpp | 24 + src/vendor/boost/mpl/prior.hpp | 19 + src/vendor/boost/mpl/protect.hpp | 55 + src/vendor/boost/mpl/push_back.hpp | 53 + src/vendor/boost/mpl/push_back_fwd.hpp | 24 + src/vendor/boost/mpl/push_front.hpp | 52 + src/vendor/boost/mpl/push_front_fwd.hpp | 24 + src/vendor/boost/mpl/quote.hpp | 151 + src/vendor/boost/mpl/remove_if.hpp | 83 + src/vendor/boost/mpl/reverse_fold.hpp | 50 + src/vendor/boost/mpl/same_as.hpp | 55 + src/vendor/boost/mpl/sequence_tag.hpp | 124 + src/vendor/boost/mpl/sequence_tag_fwd.hpp | 26 + src/vendor/boost/mpl/size.hpp | 42 + src/vendor/boost/mpl/size_fwd.hpp | 24 + src/vendor/boost/mpl/tag.hpp | 52 + src/vendor/boost/mpl/times.hpp | 21 + src/vendor/boost/mpl/vector.hpp | 57 + src/vendor/boost/mpl/vector/aux_/O1_size.hpp | 56 + src/vendor/boost/mpl/vector/aux_/at.hpp | 116 + src/vendor/boost/mpl/vector/aux_/back.hpp | 59 + .../boost/mpl/vector/aux_/begin_end.hpp | 49 + src/vendor/boost/mpl/vector/aux_/clear.hpp | 55 + src/vendor/boost/mpl/vector/aux_/empty.hpp | 68 + src/vendor/boost/mpl/vector/aux_/front.hpp | 56 + .../mpl/vector/aux_/include_preprocessed.hpp | 55 + src/vendor/boost/mpl/vector/aux_/item.hpp | 103 + src/vendor/boost/mpl/vector/aux_/iterator.hpp | 130 + src/vendor/boost/mpl/vector/aux_/pop_back.hpp | 40 + .../boost/mpl/vector/aux_/pop_front.hpp | 40 + .../preprocessed/typeof_based/vector10.hpp | 139 + .../preprocessed/typeof_based/vector20.hpp | 159 + .../boost/mpl/vector/aux_/push_back.hpp | 40 + .../boost/mpl/vector/aux_/push_front.hpp | 40 + src/vendor/boost/mpl/vector/aux_/size.hpp | 49 + src/vendor/boost/mpl/vector/aux_/tag.hpp | 32 + src/vendor/boost/mpl/vector/aux_/vector0.hpp | 52 + src/vendor/boost/mpl/vector/vector0.hpp | 34 + src/vendor/boost/mpl/vector/vector10.hpp | 45 + src/vendor/boost/mpl/vector/vector20.hpp | 45 + src/vendor/boost/mpl/void.hpp | 76 + src/vendor/boost/mpl/void_fwd.hpp | 26 + src/vendor/boost/next_prior.hpp | 195 + src/vendor/boost/noncopyable.hpp | 17 + .../boost/numeric/conversion/bounds.hpp | 24 + src/vendor/boost/numeric/conversion/cast.hpp | 61 + .../numeric/conversion/conversion_traits.hpp | 32 + .../boost/numeric/conversion/converter.hpp | 68 + .../numeric/conversion/converter_policies.hpp | 194 + .../numeric/conversion/detail/bounds.hpp | 58 + .../conversion/detail/conversion_traits.hpp | 97 + .../numeric/conversion/detail/converter.hpp | 593 +++ .../conversion/detail/int_float_mixture.hpp | 72 + .../conversion/detail/is_subranged.hpp | 234 ++ .../boost/numeric/conversion/detail/meta.hpp | 120 + .../conversion/detail/numeric_cast_traits.hpp | 138 + .../numeric_cast_traits_common.hpp | 1741 +++++++++ .../numeric_cast_traits_long_long.hpp | 347 ++ .../conversion/detail/sign_mixture.hpp | 72 + .../conversion/detail/udt_builtin_mixture.hpp | 69 + .../conversion/int_float_mixture_enum.hpp | 29 + .../conversion/numeric_cast_traits.hpp | 31 + .../numeric/conversion/sign_mixture_enum.hpp | 29 + .../conversion/udt_builtin_mixture_enum.hpp | 26 + src/vendor/boost/operators.hpp | 918 +++++ src/vendor/boost/pointee.hpp | 76 + src/vendor/boost/predef/architecture/x86.h | 38 + src/vendor/boost/predef/architecture/x86/32.h | 88 + src/vendor/boost/predef/architecture/x86/64.h | 51 + src/vendor/boost/predef/detail/_cassert.h | 17 + src/vendor/boost/predef/detail/test.h | 17 + src/vendor/boost/predef/library/c/_prefix.h | 13 + src/vendor/boost/predef/library/c/gnu.h | 62 + src/vendor/boost/predef/make.h | 159 + src/vendor/boost/predef/os/bsd.h | 102 + src/vendor/boost/predef/os/bsd/bsdi.h | 49 + src/vendor/boost/predef/os/bsd/dragonfly.h | 51 + src/vendor/boost/predef/os/bsd/free.h | 68 + src/vendor/boost/predef/os/bsd/net.h | 85 + src/vendor/boost/predef/os/bsd/open.h | 252 ++ src/vendor/boost/predef/os/ios.h | 52 + src/vendor/boost/predef/os/macos.h | 66 + src/vendor/boost/predef/other/endian.h | 204 + src/vendor/boost/predef/platform/android.h | 44 + src/vendor/boost/predef/version_number.h | 74 + .../boost/preprocessor/arithmetic/add.hpp | 104 + .../boost/preprocessor/arithmetic/dec.hpp | 322 ++ .../arithmetic/detail/div_base.hpp | 61 + .../arithmetic/detail/is_1_number.hpp | 21 + .../arithmetic/detail/is_maximum_number.hpp | 22 + .../arithmetic/detail/is_minimum_number.hpp | 21 + .../arithmetic/detail/maximum_number.hpp | 19 + .../boost/preprocessor/arithmetic/inc.hpp | 321 ++ .../arithmetic/limits/dec_256.hpp | 276 ++ .../arithmetic/limits/inc_256.hpp | 275 ++ .../boost/preprocessor/arithmetic/mod.hpp | 75 + .../boost/preprocessor/arithmetic/sub.hpp | 100 + src/vendor/boost/preprocessor/array/data.hpp | 28 + src/vendor/boost/preprocessor/array/elem.hpp | 29 + src/vendor/boost/preprocessor/array/size.hpp | 28 + src/vendor/boost/preprocessor/cat.hpp | 35 + src/vendor/boost/preprocessor/comma_if.hpp | 17 + .../boost/preprocessor/comparison/equal.hpp | 34 + .../preprocessor/comparison/less_equal.hpp | 39 + .../comparison/limits/not_equal_256.hpp | 793 ++++ .../preprocessor/comparison/not_equal.hpp | 857 +++++ .../boost/preprocessor/config/config.hpp | 98 + .../boost/preprocessor/config/limits.hpp | 163 + .../boost/preprocessor/control/deduce_d.hpp | 49 + .../control/detail/limits/while_256.hpp | 533 +++ .../preprocessor/control/detail/while.hpp | 563 +++ .../boost/preprocessor/control/expr_iif.hpp | 31 + src/vendor/boost/preprocessor/control/if.hpp | 30 + src/vendor/boost/preprocessor/control/iif.hpp | 34 + .../preprocessor/control/limits/while_256.hpp | 275 ++ .../boost/preprocessor/control/while.hpp | 387 ++ src/vendor/boost/preprocessor/debug/error.hpp | 33 + .../boost/preprocessor/detail/auto_rec.hpp | 334 ++ .../boost/preprocessor/detail/check.hpp | 48 + .../boost/preprocessor/detail/is_binary.hpp | 30 + .../detail/limits/auto_rec_256.hpp | 280 ++ src/vendor/boost/preprocessor/empty.hpp | 17 + src/vendor/boost/preprocessor/enum.hpp | 17 + src/vendor/boost/preprocessor/enum_params.hpp | 17 + .../preprocessor/facilities/check_empty.hpp | 19 + .../boost/preprocessor/facilities/empty.hpp | 23 + .../boost/preprocessor/facilities/expand.hpp | 28 + .../preprocessor/facilities/identity.hpp | 27 + .../preprocessor/facilities/intercept.hpp | 306 ++ .../facilities/limits/intercept_256.hpp | 273 ++ .../preprocessor/facilities/overload.hpp | 23 + src/vendor/boost/preprocessor/identity.hpp | 17 + src/vendor/boost/preprocessor/inc.hpp | 17 + src/vendor/boost/preprocessor/iterate.hpp | 17 + .../iteration/detail/bounds/lower1.hpp | 99 + .../iteration/detail/bounds/upper1.hpp | 99 + .../iteration/detail/iter/forward1.hpp | 1369 +++++++ .../detail/iter/limits/forward1_256.hpp | 1296 +++++++ .../boost/preprocessor/iteration/iterate.hpp | 82 + src/vendor/boost/preprocessor/list/adt.hpp | 73 + .../preprocessor/list/detail/fold_left.hpp | 307 ++ .../preprocessor/list/detail/fold_right.hpp | 303 ++ .../list/detail/limits/fold_left_256.hpp | 275 ++ .../list/detail/limits/fold_right_256.hpp | 275 ++ .../boost/preprocessor/list/fold_left.hpp | 363 ++ .../boost/preprocessor/list/fold_right.hpp | 84 + .../list/limits/fold_left_256.hpp | 275 ++ .../boost/preprocessor/list/reverse.hpp | 75 + src/vendor/boost/preprocessor/logical/and.hpp | 30 + .../boost/preprocessor/logical/bitand.hpp | 38 + .../boost/preprocessor/logical/bitor.hpp | 38 + .../boost/preprocessor/logical/bool.hpp | 310 ++ .../boost/preprocessor/logical/compl.hpp | 36 + .../preprocessor/logical/limits/bool_256.hpp | 275 ++ src/vendor/boost/preprocessor/logical/not.hpp | 30 + .../boost/preprocessor/punctuation/comma.hpp | 21 + .../preprocessor/punctuation/comma_if.hpp | 31 + src/vendor/boost/preprocessor/repeat.hpp | 17 + .../preprocessor/repetition/detail/for.hpp | 564 +++ .../repetition/detail/limits/for_256.hpp | 533 +++ .../boost/preprocessor/repetition/enum.hpp | 66 + .../repetition/enum_binary_params.hpp | 54 + .../preprocessor/repetition/enum_params.hpp | 41 + .../repetition/enum_shifted_params.hpp | 44 + .../repetition/enum_trailing_params.hpp | 38 + .../boost/preprocessor/repetition/for.hpp | 438 +++ .../repetition/limits/for_256.hpp | 275 ++ .../repetition/limits/repeat_256.hpp | 791 ++++ .../boost/preprocessor/repetition/repeat.hpp | 847 +++++ .../repetition/repeat_from_to.hpp | 114 + src/vendor/boost/preprocessor/seq/cat.hpp | 49 + .../preprocessor/seq/detail/is_empty.hpp | 49 + src/vendor/boost/preprocessor/seq/elem.hpp | 327 ++ src/vendor/boost/preprocessor/seq/enum.hpp | 311 ++ .../boost/preprocessor/seq/fold_left.hpp | 1122 ++++++ .../boost/preprocessor/seq/for_each_i.hpp | 109 + .../preprocessor/seq/limits/elem_256.hpp | 272 ++ .../preprocessor/seq/limits/enum_256.hpp | 272 ++ .../preprocessor/seq/limits/fold_left_256.hpp | 1053 ++++++ .../preprocessor/seq/limits/size_256.hpp | 532 +++ src/vendor/boost/preprocessor/seq/seq.hpp | 44 + src/vendor/boost/preprocessor/seq/size.hpp | 571 +++ .../boost/preprocessor/seq/transform.hpp | 48 + .../boost/preprocessor/slot/detail/def.hpp | 49 + .../boost/preprocessor/slot/detail/shared.hpp | 247 ++ src/vendor/boost/preprocessor/slot/slot.hpp | 32 + src/vendor/boost/preprocessor/stringize.hpp | 33 + .../tuple/detail/is_single_return.hpp | 28 + src/vendor/boost/preprocessor/tuple/eat.hpp | 101 + src/vendor/boost/preprocessor/tuple/elem.hpp | 55 + src/vendor/boost/preprocessor/tuple/rem.hpp | 127 + .../boost/preprocessor/variadic/elem.hpp | 116 + .../boost/preprocessor/variadic/has_opt.hpp | 28 + .../preprocessor/variadic/limits/elem_64.hpp | 81 + .../preprocessor/variadic/limits/size_64.hpp | 23 + .../boost/preprocessor/variadic/size.hpp | 65 + .../boost/ptr_container/clone_allocator.hpp | 88 + .../ptr_container/detail/default_deleter.hpp | 69 + .../ptr_container/detail/is_convertible.hpp | 73 + .../boost/ptr_container/detail/move.hpp | 44 + .../ptr_container_disable_deprecated.hpp | 40 + .../detail/reversible_ptr_container.hpp | 866 +++++ .../ptr_container/detail/scoped_deleter.hpp | 132 + .../ptr_container/detail/static_move_ptr.hpp | 205 + .../ptr_container/detail/throw_exception.hpp | 33 + .../detail/void_ptr_iterator.hpp | 267 ++ src/vendor/boost/ptr_container/exception.hpp | 58 + .../boost/ptr_container/indirect_fun.hpp | 151 + src/vendor/boost/ptr_container/nullable.hpp | 85 + .../ptr_container/ptr_sequence_adapter.hpp | 819 ++++ src/vendor/boost/ptr_container/ptr_vector.hpp | 100 + src/vendor/boost/range/algorithm/equal.hpp | 200 + .../boost/range/algorithm_ext/for_each.hpp | 86 + src/vendor/boost/range/as_literal.hpp | 164 + src/vendor/boost/range/begin.hpp | 137 + src/vendor/boost/range/concepts.hpp | 388 ++ src/vendor/boost/range/config.hpp | 56 + src/vendor/boost/range/const_iterator.hpp | 76 + src/vendor/boost/range/detail/common.hpp | 116 + .../range/detail/extract_optional_type.hpp | 48 + .../boost/range/detail/has_member_size.hpp | 66 + .../range/detail/implementation_help.hpp | 114 + .../boost/range/detail/misc_concept.hpp | 33 + .../detail/msvc_has_iterator_workaround.hpp | 132 + src/vendor/boost/range/detail/safe_bool.hpp | 72 + src/vendor/boost/range/detail/sfinae.hpp | 77 + src/vendor/boost/range/detail/str_types.hpp | 38 + src/vendor/boost/range/difference_type.hpp | 47 + src/vendor/boost/range/distance.hpp | 40 + src/vendor/boost/range/empty.hpp | 34 + src/vendor/boost/range/end.hpp | 130 + src/vendor/boost/range/functions.hpp | 27 + src/vendor/boost/range/has_range_iterator.hpp | 83 + src/vendor/boost/range/iterator.hpp | 74 + src/vendor/boost/range/iterator_range.hpp | 16 + .../boost/range/iterator_range_core.hpp | 852 +++++ src/vendor/boost/range/iterator_range_io.hpp | 93 + src/vendor/boost/range/mutable_iterator.hpp | 79 + src/vendor/boost/range/range_fwd.hpp | 63 + src/vendor/boost/range/rbegin.hpp | 52 + src/vendor/boost/range/rend.hpp | 52 + src/vendor/boost/range/reverse_iterator.hpp | 42 + src/vendor/boost/range/size.hpp | 76 + src/vendor/boost/range/size_type.hpp | 90 + src/vendor/boost/range/value_type.hpp | 30 + src/vendor/boost/ref.hpp | 17 + src/vendor/boost/scoped_array.hpp | 15 + src/vendor/boost/scoped_ptr.hpp | 15 + src/vendor/boost/shared_ptr.hpp | 19 + src/vendor/boost/smart_ptr/bad_weak_ptr.hpp | 70 + .../smart_ptr/detail/local_counted_base.hpp | 148 + .../smart_ptr/detail/local_sp_deleter.hpp | 91 + .../boost/smart_ptr/detail/operator_bool.hpp | 64 + .../boost/smart_ptr/detail/shared_count.hpp | 707 ++++ .../boost/smart_ptr/detail/sp_convertible.hpp | 92 + .../smart_ptr/detail/sp_counted_base.hpp | 92 + .../detail/sp_counted_base_gcc_atomic.hpp | 148 + .../smart_ptr/detail/sp_counted_impl.hpp | 289 ++ .../detail/sp_disable_deprecated.hpp | 40 + .../detail/sp_has_gcc_intrinsics.hpp | 27 + .../detail/sp_has_sync_intrinsics.hpp | 69 + .../boost/smart_ptr/detail/sp_noexcept.hpp | 48 + .../boost/smart_ptr/detail/sp_nullptr_t.hpp | 45 + .../smart_ptr/detail/sp_thread_pause.hpp | 51 + .../smart_ptr/detail/sp_thread_sleep.hpp | 104 + .../boost/smart_ptr/detail/sp_typeinfo_.hpp | 58 + .../boost/smart_ptr/detail/spinlock.hpp | 66 + .../smart_ptr/detail/spinlock_gcc_atomic.hpp | 85 + .../boost/smart_ptr/detail/spinlock_pool.hpp | 91 + src/vendor/boost/smart_ptr/detail/yield_k.hpp | 51 + src/vendor/boost/smart_ptr/scoped_array.hpp | 132 + src/vendor/boost/smart_ptr/scoped_ptr.hpp | 167 + src/vendor/boost/smart_ptr/shared_ptr.hpp | 1219 ++++++ src/vendor/boost/static_assert.hpp | 180 + src/vendor/boost/swap.hpp | 17 + src/vendor/boost/throw_exception.hpp | 182 + src/vendor/boost/token_functions.hpp | 653 ++++ src/vendor/boost/token_iterator.hpp | 131 + src/vendor/boost/tokenizer.hpp | 98 + src/vendor/boost/type.hpp | 18 + src/vendor/boost/type_index.hpp | 265 ++ .../boost/type_index/stl_type_index.hpp | 278 ++ .../boost/type_index/type_index_facade.hpp | 297 ++ src/vendor/boost/type_traits/add_const.hpp | 52 + .../type_traits/add_lvalue_reference.hpp | 33 + src/vendor/boost/type_traits/add_pointer.hpp | 67 + .../boost/type_traits/add_reference.hpp | 66 + .../type_traits/add_rvalue_reference.hpp | 70 + src/vendor/boost/type_traits/add_volatile.hpp | 46 + src/vendor/boost/type_traits/alignment_of.hpp | 119 + .../boost/type_traits/composite_traits.hpp | 29 + src/vendor/boost/type_traits/conditional.hpp | 28 + .../boost/type_traits/conversion_traits.hpp | 17 + src/vendor/boost/type_traits/declval.hpp | 44 + .../type_traits/detail/bool_trait_undef.hpp | 28 + .../boost/type_traits/detail/config.hpp | 113 + .../detail/has_binary_operator.hpp | 279 ++ .../type_traits/detail/is_function_cxx_11.hpp | 597 +++ .../is_member_function_pointer_cxx_11.hpp | 672 ++++ .../boost/type_traits/detail/yes_no_type.hpp | 26 + src/vendor/boost/type_traits/enable_if.hpp | 37 + .../boost/type_traits/function_traits.hpp | 174 + .../boost/type_traits/has_left_shift.hpp | 49 + src/vendor/boost/type_traits/has_minus.hpp | 158 + .../boost/type_traits/has_minus_assign.hpp | 163 + src/vendor/boost/type_traits/has_plus.hpp | 54 + .../boost/type_traits/has_plus_assign.hpp | 161 + .../boost/type_traits/has_right_shift.hpp | 49 + .../boost/type_traits/has_trivial_copy.hpp | 63 + .../type_traits/has_trivial_destructor.hpp | 48 + .../boost/type_traits/integral_constant.hpp | 97 + src/vendor/boost/type_traits/intrinsics.hpp | 391 ++ src/vendor/boost/type_traits/is_abstract.hpp | 150 + .../boost/type_traits/is_arithmetic.hpp | 22 + src/vendor/boost/type_traits/is_array.hpp | 43 + .../boost/type_traits/is_base_and_derived.hpp | 244 ++ src/vendor/boost/type_traits/is_base_of.hpp | 39 + src/vendor/boost/type_traits/is_class.hpp | 114 + src/vendor/boost/type_traits/is_complete.hpp | 92 + src/vendor/boost/type_traits/is_const.hpp | 47 + .../boost/type_traits/is_constructible.hpp | 90 + .../boost/type_traits/is_convertible.hpp | 506 +++ .../type_traits/is_copy_constructible.hpp | 185 + .../type_traits/is_default_constructible.hpp | 98 + .../boost/type_traits/is_destructible.hpp | 69 + src/vendor/boost/type_traits/is_empty.hpp | 120 + src/vendor/boost/type_traits/is_enum.hpp | 166 + src/vendor/boost/type_traits/is_final.hpp | 30 + src/vendor/boost/type_traits/is_float.hpp | 20 + .../boost/type_traits/is_floating_point.hpp | 30 + src/vendor/boost/type_traits/is_function.hpp | 27 + src/vendor/boost/type_traits/is_integral.hpp | 89 + .../boost/type_traits/is_lvalue_reference.hpp | 50 + .../is_member_function_pointer.hpp | 26 + .../boost/type_traits/is_member_pointer.hpp | 45 + src/vendor/boost/type_traits/is_pod.hpp | 59 + src/vendor/boost/type_traits/is_pointer.hpp | 47 + src/vendor/boost/type_traits/is_reference.hpp | 30 + .../boost/type_traits/is_rvalue_reference.hpp | 29 + src/vendor/boost/type_traits/is_same.hpp | 41 + src/vendor/boost/type_traits/is_scalar.hpp | 27 + src/vendor/boost/type_traits/is_signed.hpp | 163 + src/vendor/boost/type_traits/is_union.hpp | 31 + src/vendor/boost/type_traits/is_unsigned.hpp | 163 + src/vendor/boost/type_traits/is_void.hpp | 26 + src/vendor/boost/type_traits/is_volatile.hpp | 46 + .../boost/type_traits/make_unsigned.hpp | 136 + src/vendor/boost/type_traits/make_void.hpp | 52 + .../boost/type_traits/remove_bounds.hpp | 28 + src/vendor/boost/type_traits/remove_const.hpp | 39 + src/vendor/boost/type_traits/remove_cv.hpp | 45 + .../boost/type_traits/remove_extent.hpp | 41 + .../boost/type_traits/remove_pointer.hpp | 84 + .../boost/type_traits/remove_reference.hpp | 59 + .../boost/type_traits/type_identity.hpp | 31 + src/vendor/boost/utility.hpp | 24 + src/vendor/boost/utility/base_from_member.hpp | 172 + src/vendor/boost/utility/binary.hpp | 708 ++++ .../utility/detail/result_of_iterate.hpp | 218 ++ src/vendor/boost/utility/enable_if.hpp | 17 + src/vendor/boost/utility/identity_type.hpp | 46 + src/vendor/boost/utility/result_of.hpp | 234 ++ src/vendor/boost/version.hpp | 32 + src/vendor/boost/visit_each.hpp | 27 + 924 files changed, 154128 insertions(+) create mode 100644 src/vendor/boost/algorithm/string.hpp create mode 100644 src/vendor/boost/algorithm/string/case_conv.hpp create mode 100644 src/vendor/boost/algorithm/string/classification.hpp create mode 100644 src/vendor/boost/algorithm/string/compare.hpp create mode 100644 src/vendor/boost/algorithm/string/concept.hpp create mode 100644 src/vendor/boost/algorithm/string/config.hpp create mode 100644 src/vendor/boost/algorithm/string/constants.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/case_conv.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/classification.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/find_format.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/find_format_all.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/find_format_store.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/find_iterator.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/finder.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/formatter.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/predicate.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/replace_storage.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/sequence.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/trim.hpp create mode 100644 src/vendor/boost/algorithm/string/detail/util.hpp create mode 100644 src/vendor/boost/algorithm/string/erase.hpp create mode 100644 src/vendor/boost/algorithm/string/find.hpp create mode 100644 src/vendor/boost/algorithm/string/find_format.hpp create mode 100644 src/vendor/boost/algorithm/string/find_iterator.hpp create mode 100644 src/vendor/boost/algorithm/string/finder.hpp create mode 100644 src/vendor/boost/algorithm/string/formatter.hpp create mode 100644 src/vendor/boost/algorithm/string/iter_find.hpp create mode 100644 src/vendor/boost/algorithm/string/join.hpp create mode 100644 src/vendor/boost/algorithm/string/predicate.hpp create mode 100644 src/vendor/boost/algorithm/string/predicate_facade.hpp create mode 100644 src/vendor/boost/algorithm/string/replace.hpp create mode 100644 src/vendor/boost/algorithm/string/sequence_traits.hpp create mode 100644 src/vendor/boost/algorithm/string/split.hpp create mode 100644 src/vendor/boost/algorithm/string/std/list_traits.hpp create mode 100644 src/vendor/boost/algorithm/string/std/slist_traits.hpp create mode 100644 src/vendor/boost/algorithm/string/std/string_traits.hpp create mode 100644 src/vendor/boost/algorithm/string/std_containers_traits.hpp create mode 100644 src/vendor/boost/algorithm/string/trim.hpp create mode 100644 src/vendor/boost/algorithm/string/yes_no_type.hpp create mode 100644 src/vendor/boost/array.hpp create mode 100644 src/vendor/boost/assert.hpp create mode 100644 src/vendor/boost/assert/source_location.hpp create mode 100644 src/vendor/boost/bind.hpp create mode 100644 src/vendor/boost/bind/arg.hpp create mode 100644 src/vendor/boost/bind/bind.hpp create mode 100644 src/vendor/boost/bind/bind_cc.hpp create mode 100644 src/vendor/boost/bind/bind_mf2_cc.hpp create mode 100644 src/vendor/boost/bind/bind_mf_cc.hpp create mode 100644 src/vendor/boost/bind/detail/result_traits.hpp create mode 100644 src/vendor/boost/bind/mem_fn.hpp create mode 100644 src/vendor/boost/bind/mem_fn_cc.hpp create mode 100644 src/vendor/boost/bind/mem_fn_template.hpp create mode 100644 src/vendor/boost/bind/placeholders.hpp create mode 100644 src/vendor/boost/bind/storage.hpp create mode 100644 src/vendor/boost/call_traits.hpp create mode 100644 src/vendor/boost/checked_delete.hpp create mode 100644 src/vendor/boost/compressed_pair.hpp create mode 100644 src/vendor/boost/concept/assert.hpp create mode 100644 src/vendor/boost/concept/detail/backward_compatibility.hpp create mode 100644 src/vendor/boost/concept/detail/concept_def.hpp create mode 100644 src/vendor/boost/concept/detail/concept_undef.hpp create mode 100644 src/vendor/boost/concept/detail/general.hpp create mode 100644 src/vendor/boost/concept/detail/has_constraints.hpp create mode 100644 src/vendor/boost/concept/usage.hpp create mode 100644 src/vendor/boost/concept_check.hpp create mode 100644 src/vendor/boost/config.hpp create mode 100644 src/vendor/boost/config/auto_link.hpp create mode 100644 src/vendor/boost/config/compiler/gcc.hpp create mode 100644 src/vendor/boost/config/detail/posix_features.hpp create mode 100644 src/vendor/boost/config/detail/select_compiler_config.hpp create mode 100644 src/vendor/boost/config/detail/select_platform_config.hpp create mode 100644 src/vendor/boost/config/detail/select_stdlib_config.hpp create mode 100644 src/vendor/boost/config/detail/suffix.hpp create mode 100644 src/vendor/boost/config/helper_macros.hpp create mode 100644 src/vendor/boost/config/no_tr1/cmath.hpp create mode 100644 src/vendor/boost/config/no_tr1/complex.hpp create mode 100644 src/vendor/boost/config/no_tr1/functional.hpp create mode 100644 src/vendor/boost/config/no_tr1/memory.hpp create mode 100644 src/vendor/boost/config/platform/linux.hpp create mode 100644 src/vendor/boost/config/pragma_message.hpp create mode 100644 src/vendor/boost/config/stdlib/libstdcpp3.hpp create mode 100644 src/vendor/boost/config/user.hpp create mode 100644 src/vendor/boost/config/workaround.hpp create mode 100644 src/vendor/boost/container/allocator_traits.hpp create mode 100644 src/vendor/boost/container/container_fwd.hpp create mode 100644 src/vendor/boost/container/detail/addressof.hpp create mode 100644 src/vendor/boost/container/detail/advanced_insert_int.hpp create mode 100644 src/vendor/boost/container/detail/algorithm.hpp create mode 100644 src/vendor/boost/container/detail/alloc_helpers.hpp create mode 100644 src/vendor/boost/container/detail/allocation_type.hpp create mode 100644 src/vendor/boost/container/detail/allocator_version_traits.hpp create mode 100644 src/vendor/boost/container/detail/config_begin.hpp create mode 100644 src/vendor/boost/container/detail/config_end.hpp create mode 100644 src/vendor/boost/container/detail/construct_in_place.hpp create mode 100644 src/vendor/boost/container/detail/copy_move_algo.hpp create mode 100644 src/vendor/boost/container/detail/destroyers.hpp create mode 100644 src/vendor/boost/container/detail/iterator.hpp create mode 100644 src/vendor/boost/container/detail/iterators.hpp create mode 100644 src/vendor/boost/container/detail/min_max.hpp create mode 100644 src/vendor/boost/container/detail/mpl.hpp create mode 100644 src/vendor/boost/container/detail/multiallocation_chain.hpp create mode 100644 src/vendor/boost/container/detail/next_capacity.hpp create mode 100644 src/vendor/boost/container/detail/placement_new.hpp create mode 100644 src/vendor/boost/container/detail/std_fwd.hpp create mode 100644 src/vendor/boost/container/detail/transform_iterator.hpp create mode 100644 src/vendor/boost/container/detail/type_traits.hpp create mode 100644 src/vendor/boost/container/detail/value_functors.hpp create mode 100644 src/vendor/boost/container/detail/value_init.hpp create mode 100644 src/vendor/boost/container/detail/variadic_templates_tools.hpp create mode 100644 src/vendor/boost/container/detail/version_type.hpp create mode 100644 src/vendor/boost/container/detail/workaround.hpp create mode 100644 src/vendor/boost/container/new_allocator.hpp create mode 100644 src/vendor/boost/container/options.hpp create mode 100644 src/vendor/boost/container/stable_vector.hpp create mode 100644 src/vendor/boost/container/throw_exception.hpp create mode 100644 src/vendor/boost/container/vector.hpp create mode 100644 src/vendor/boost/container_hash/hash_fwd.hpp create mode 100644 src/vendor/boost/core/addressof.hpp create mode 100644 src/vendor/boost/core/checked_delete.hpp create mode 100644 src/vendor/boost/core/demangle.hpp create mode 100644 src/vendor/boost/core/enable_if.hpp create mode 100644 src/vendor/boost/core/ignore_unused.hpp create mode 100644 src/vendor/boost/core/is_same.hpp create mode 100644 src/vendor/boost/core/no_exceptions_support.hpp create mode 100644 src/vendor/boost/core/noncopyable.hpp create mode 100644 src/vendor/boost/core/ref.hpp create mode 100644 src/vendor/boost/core/swap.hpp create mode 100644 src/vendor/boost/core/use_default.hpp create mode 100644 src/vendor/boost/cstdint.hpp create mode 100644 src/vendor/boost/current_function.hpp create mode 100644 src/vendor/boost/date_time/adjust_functors.hpp create mode 100644 src/vendor/boost/date_time/c_time.hpp create mode 100644 src/vendor/boost/date_time/compiler_config.hpp create mode 100644 src/vendor/boost/date_time/constrained_value.hpp create mode 100644 src/vendor/boost/date_time/date.hpp create mode 100644 src/vendor/boost/date_time/date_clock_device.hpp create mode 100644 src/vendor/boost/date_time/date_defs.hpp create mode 100644 src/vendor/boost/date_time/date_duration.hpp create mode 100644 src/vendor/boost/date_time/date_duration_types.hpp create mode 100644 src/vendor/boost/date_time/date_facet.hpp create mode 100644 src/vendor/boost/date_time/date_format_simple.hpp create mode 100644 src/vendor/boost/date_time/date_formatting.hpp create mode 100644 src/vendor/boost/date_time/date_formatting_locales.hpp create mode 100644 src/vendor/boost/date_time/date_generator_formatter.hpp create mode 100644 src/vendor/boost/date_time/date_generator_parser.hpp create mode 100644 src/vendor/boost/date_time/date_generators.hpp create mode 100644 src/vendor/boost/date_time/date_iterator.hpp create mode 100644 src/vendor/boost/date_time/date_names_put.hpp create mode 100644 src/vendor/boost/date_time/date_parsing.hpp create mode 100644 src/vendor/boost/date_time/dst_rules.hpp create mode 100644 src/vendor/boost/date_time/filetime_functions.hpp create mode 100644 src/vendor/boost/date_time/find_match.hpp create mode 100644 src/vendor/boost/date_time/format_date_parser.hpp create mode 100644 src/vendor/boost/date_time/gregorian/conversion.hpp create mode 100644 src/vendor/boost/date_time/gregorian/formatters.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_calendar.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_date.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_day.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_day_of_year.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_duration.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_duration_types.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_month.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_weekday.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_year.hpp create mode 100644 src/vendor/boost/date_time/gregorian/greg_ymd.hpp create mode 100644 src/vendor/boost/date_time/gregorian/gregorian.hpp create mode 100644 src/vendor/boost/date_time/gregorian/gregorian_io.hpp create mode 100644 src/vendor/boost/date_time/gregorian/gregorian_types.hpp create mode 100644 src/vendor/boost/date_time/gregorian/parsers.hpp create mode 100644 src/vendor/boost/date_time/gregorian_calendar.hpp create mode 100644 src/vendor/boost/date_time/gregorian_calendar.ipp create mode 100644 src/vendor/boost/date_time/int_adapter.hpp create mode 100644 src/vendor/boost/date_time/iso_format.hpp create mode 100644 src/vendor/boost/date_time/locale_config.hpp create mode 100644 src/vendor/boost/date_time/microsec_time_clock.hpp create mode 100644 src/vendor/boost/date_time/parse_format_base.hpp create mode 100644 src/vendor/boost/date_time/period.hpp create mode 100644 src/vendor/boost/date_time/period_formatter.hpp create mode 100644 src/vendor/boost/date_time/period_parser.hpp create mode 100644 src/vendor/boost/date_time/posix_time/conversion.hpp create mode 100644 src/vendor/boost/date_time/posix_time/date_duration_operators.hpp create mode 100644 src/vendor/boost/date_time/posix_time/posix_time.hpp create mode 100644 src/vendor/boost/date_time/posix_time/posix_time_config.hpp create mode 100644 src/vendor/boost/date_time/posix_time/posix_time_duration.hpp create mode 100644 src/vendor/boost/date_time/posix_time/posix_time_io.hpp create mode 100644 src/vendor/boost/date_time/posix_time/posix_time_system.hpp create mode 100644 src/vendor/boost/date_time/posix_time/posix_time_types.hpp create mode 100644 src/vendor/boost/date_time/posix_time/ptime.hpp create mode 100644 src/vendor/boost/date_time/posix_time/time_formatters.hpp create mode 100644 src/vendor/boost/date_time/posix_time/time_parsers.hpp create mode 100644 src/vendor/boost/date_time/posix_time/time_period.hpp create mode 100644 src/vendor/boost/date_time/special_defs.hpp create mode 100644 src/vendor/boost/date_time/special_values_formatter.hpp create mode 100644 src/vendor/boost/date_time/special_values_parser.hpp create mode 100644 src/vendor/boost/date_time/string_convert.hpp create mode 100644 src/vendor/boost/date_time/string_parse_tree.hpp create mode 100644 src/vendor/boost/date_time/strings_from_facet.hpp create mode 100644 src/vendor/boost/date_time/time.hpp create mode 100644 src/vendor/boost/date_time/time_clock.hpp create mode 100644 src/vendor/boost/date_time/time_defs.hpp create mode 100644 src/vendor/boost/date_time/time_duration.hpp create mode 100644 src/vendor/boost/date_time/time_facet.hpp create mode 100644 src/vendor/boost/date_time/time_formatting_streams.hpp create mode 100644 src/vendor/boost/date_time/time_iterator.hpp create mode 100644 src/vendor/boost/date_time/time_parsing.hpp create mode 100644 src/vendor/boost/date_time/time_resolution_traits.hpp create mode 100644 src/vendor/boost/date_time/time_system_counted.hpp create mode 100644 src/vendor/boost/date_time/time_system_split.hpp create mode 100644 src/vendor/boost/date_time/wrapping_int.hpp create mode 100644 src/vendor/boost/date_time/year_month_day.hpp create mode 100644 src/vendor/boost/detail/basic_pointerbuf.hpp create mode 100644 src/vendor/boost/detail/call_traits.hpp create mode 100644 src/vendor/boost/detail/compressed_pair.hpp create mode 100644 src/vendor/boost/detail/indirect_traits.hpp create mode 100644 src/vendor/boost/detail/is_incrementable.hpp create mode 100644 src/vendor/boost/detail/lcast_precision.hpp create mode 100644 src/vendor/boost/detail/select_type.hpp create mode 100644 src/vendor/boost/detail/workaround.hpp create mode 100644 src/vendor/boost/exception/exception.hpp create mode 100644 src/vendor/boost/function.hpp create mode 100644 src/vendor/boost/function/detail/function_iterate.hpp create mode 100644 src/vendor/boost/function/detail/maybe_include.hpp create mode 100644 src/vendor/boost/function/detail/prologue.hpp create mode 100644 src/vendor/boost/function/function_base.hpp create mode 100644 src/vendor/boost/function/function_fwd.hpp create mode 100644 src/vendor/boost/function/function_template.hpp create mode 100644 src/vendor/boost/function_equal.hpp create mode 100644 src/vendor/boost/get_pointer.hpp create mode 100644 src/vendor/boost/integer.hpp create mode 100644 src/vendor/boost/integer_fwd.hpp create mode 100644 src/vendor/boost/integer_traits.hpp create mode 100644 src/vendor/boost/intrusive/circular_slist_algorithms.hpp create mode 100644 src/vendor/boost/intrusive/detail/algo_type.hpp create mode 100644 src/vendor/boost/intrusive/detail/algorithm.hpp create mode 100644 src/vendor/boost/intrusive/detail/array_initializer.hpp create mode 100644 src/vendor/boost/intrusive/detail/assert.hpp create mode 100644 src/vendor/boost/intrusive/detail/common_slist_algorithms.hpp create mode 100644 src/vendor/boost/intrusive/detail/config_begin.hpp create mode 100644 src/vendor/boost/intrusive/detail/config_end.hpp create mode 100644 src/vendor/boost/intrusive/detail/default_header_holder.hpp create mode 100644 src/vendor/boost/intrusive/detail/ebo_functor_holder.hpp create mode 100644 src/vendor/boost/intrusive/detail/equal_to_value.hpp create mode 100644 src/vendor/boost/intrusive/detail/exception_disposer.hpp create mode 100644 src/vendor/boost/intrusive/detail/function_detector.hpp create mode 100644 src/vendor/boost/intrusive/detail/generic_hook.hpp create mode 100644 src/vendor/boost/intrusive/detail/get_value_traits.hpp create mode 100644 src/vendor/boost/intrusive/detail/has_member_function_callable_with.hpp create mode 100644 src/vendor/boost/intrusive/detail/hook_traits.hpp create mode 100644 src/vendor/boost/intrusive/detail/iiterator.hpp create mode 100644 src/vendor/boost/intrusive/detail/is_stateful_value_traits.hpp create mode 100644 src/vendor/boost/intrusive/detail/iterator.hpp create mode 100644 src/vendor/boost/intrusive/detail/key_nodeptr_comp.hpp create mode 100644 src/vendor/boost/intrusive/detail/minimal_less_equal_header.hpp create mode 100644 src/vendor/boost/intrusive/detail/minimal_pair_header.hpp create mode 100644 src/vendor/boost/intrusive/detail/mpl.hpp create mode 100644 src/vendor/boost/intrusive/detail/node_holder.hpp create mode 100644 src/vendor/boost/intrusive/detail/parent_from_member.hpp create mode 100644 src/vendor/boost/intrusive/detail/reverse_iterator.hpp create mode 100644 src/vendor/boost/intrusive/detail/simple_disposers.hpp create mode 100644 src/vendor/boost/intrusive/detail/size_holder.hpp create mode 100644 src/vendor/boost/intrusive/detail/slist_iterator.hpp create mode 100644 src/vendor/boost/intrusive/detail/slist_node.hpp create mode 100644 src/vendor/boost/intrusive/detail/std_fwd.hpp create mode 100644 src/vendor/boost/intrusive/detail/tree_value_compare.hpp create mode 100644 src/vendor/boost/intrusive/detail/uncast.hpp create mode 100644 src/vendor/boost/intrusive/detail/workaround.hpp create mode 100644 src/vendor/boost/intrusive/intrusive_fwd.hpp create mode 100644 src/vendor/boost/intrusive/linear_slist_algorithms.hpp create mode 100644 src/vendor/boost/intrusive/link_mode.hpp create mode 100644 src/vendor/boost/intrusive/options.hpp create mode 100644 src/vendor/boost/intrusive/pack_options.hpp create mode 100644 src/vendor/boost/intrusive/pointer_rebind.hpp create mode 100644 src/vendor/boost/intrusive/pointer_traits.hpp create mode 100644 src/vendor/boost/intrusive/slist.hpp create mode 100644 src/vendor/boost/intrusive/slist_hook.hpp create mode 100644 src/vendor/boost/io/ios_state.hpp create mode 100644 src/vendor/boost/io_fwd.hpp create mode 100644 src/vendor/boost/is_placeholder.hpp create mode 100644 src/vendor/boost/iterator/advance.hpp create mode 100644 src/vendor/boost/iterator/detail/config_def.hpp create mode 100644 src/vendor/boost/iterator/detail/config_undef.hpp create mode 100644 src/vendor/boost/iterator/detail/enable_if.hpp create mode 100644 src/vendor/boost/iterator/detail/facade_iterator_category.hpp create mode 100644 src/vendor/boost/iterator/distance.hpp create mode 100644 src/vendor/boost/iterator/interoperable.hpp create mode 100644 src/vendor/boost/iterator/iterator_adaptor.hpp create mode 100644 src/vendor/boost/iterator/iterator_categories.hpp create mode 100644 src/vendor/boost/iterator/iterator_concepts.hpp create mode 100644 src/vendor/boost/iterator/iterator_facade.hpp create mode 100644 src/vendor/boost/iterator/iterator_traits.hpp create mode 100644 src/vendor/boost/iterator/minimum_category.hpp create mode 100644 src/vendor/boost/iterator/reverse_iterator.hpp create mode 100644 src/vendor/boost/iterator/transform_iterator.hpp create mode 100644 src/vendor/boost/lexical_cast.hpp create mode 100644 src/vendor/boost/lexical_cast/bad_lexical_cast.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/converter_lexical.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/converter_lexical_streams.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/converter_numeric.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/inf_nan.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/is_character.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/lcast_char_constants.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/lcast_unsigned_converters.hpp create mode 100644 src/vendor/boost/lexical_cast/detail/widest_char.hpp create mode 100644 src/vendor/boost/lexical_cast/try_lexical_convert.hpp create mode 100644 src/vendor/boost/limits.hpp create mode 100644 src/vendor/boost/math/policies/policy.hpp create mode 100644 src/vendor/boost/math/special_functions/detail/fp_traits.hpp create mode 100644 src/vendor/boost/math/special_functions/detail/round_fwd.hpp create mode 100644 src/vendor/boost/math/special_functions/fpclassify.hpp create mode 100644 src/vendor/boost/math/special_functions/math_fwd.hpp create mode 100644 src/vendor/boost/math/special_functions/sign.hpp create mode 100644 src/vendor/boost/math/tools/config.hpp create mode 100644 src/vendor/boost/math/tools/promotion.hpp create mode 100644 src/vendor/boost/math/tools/real_cast.hpp create mode 100644 src/vendor/boost/math/tools/user.hpp create mode 100644 src/vendor/boost/mem_fn.hpp create mode 100644 src/vendor/boost/move/adl_move_swap.hpp create mode 100644 src/vendor/boost/move/algo/adaptive_merge.hpp create mode 100644 src/vendor/boost/move/algo/detail/adaptive_sort_merge.hpp create mode 100644 src/vendor/boost/move/algo/detail/basic_op.hpp create mode 100644 src/vendor/boost/move/algo/detail/heap_sort.hpp create mode 100644 src/vendor/boost/move/algo/detail/insertion_sort.hpp create mode 100644 src/vendor/boost/move/algo/detail/is_sorted.hpp create mode 100644 src/vendor/boost/move/algo/detail/merge.hpp create mode 100644 src/vendor/boost/move/algo/detail/merge_sort.hpp create mode 100644 src/vendor/boost/move/algo/detail/set_difference.hpp create mode 100644 src/vendor/boost/move/algo/move.hpp create mode 100644 src/vendor/boost/move/algo/predicate.hpp create mode 100644 src/vendor/boost/move/algo/unique.hpp create mode 100644 src/vendor/boost/move/core.hpp create mode 100644 src/vendor/boost/move/detail/config_begin.hpp create mode 100644 src/vendor/boost/move/detail/config_end.hpp create mode 100644 src/vendor/boost/move/detail/destruct_n.hpp create mode 100644 src/vendor/boost/move/detail/fwd_macros.hpp create mode 100644 src/vendor/boost/move/detail/iterator_to_raw_pointer.hpp create mode 100644 src/vendor/boost/move/detail/iterator_traits.hpp create mode 100644 src/vendor/boost/move/detail/meta_utils.hpp create mode 100644 src/vendor/boost/move/detail/meta_utils_core.hpp create mode 100644 src/vendor/boost/move/detail/move_helpers.hpp create mode 100644 src/vendor/boost/move/detail/placement_new.hpp create mode 100644 src/vendor/boost/move/detail/pointer_element.hpp create mode 100644 src/vendor/boost/move/detail/reverse_iterator.hpp create mode 100644 src/vendor/boost/move/detail/std_ns_begin.hpp create mode 100644 src/vendor/boost/move/detail/std_ns_end.hpp create mode 100644 src/vendor/boost/move/detail/to_raw_pointer.hpp create mode 100644 src/vendor/boost/move/detail/type_traits.hpp create mode 100644 src/vendor/boost/move/detail/workaround.hpp create mode 100644 src/vendor/boost/move/iterator.hpp create mode 100644 src/vendor/boost/move/traits.hpp create mode 100644 src/vendor/boost/move/utility_core.hpp create mode 100644 src/vendor/boost/mpl/O1_size.hpp create mode 100644 src/vendor/boost/mpl/O1_size_fwd.hpp create mode 100644 src/vendor/boost/mpl/advance.hpp create mode 100644 src/vendor/boost/mpl/advance_fwd.hpp create mode 100644 src/vendor/boost/mpl/always.hpp create mode 100644 src/vendor/boost/mpl/and.hpp create mode 100644 src/vendor/boost/mpl/apply.hpp create mode 100644 src/vendor/boost/mpl/apply_fwd.hpp create mode 100644 src/vendor/boost/mpl/apply_wrap.hpp create mode 100644 src/vendor/boost/mpl/arg.hpp create mode 100644 src/vendor/boost/mpl/arg_fwd.hpp create mode 100644 src/vendor/boost/mpl/assert.hpp create mode 100644 src/vendor/boost/mpl/at.hpp create mode 100644 src/vendor/boost/mpl/at_fwd.hpp create mode 100644 src/vendor/boost/mpl/aux_/O1_size_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/adl_barrier.hpp create mode 100644 src/vendor/boost/mpl/aux_/advance_backward.hpp create mode 100644 src/vendor/boost/mpl/aux_/advance_forward.hpp create mode 100644 src/vendor/boost/mpl/aux_/arg_typedef.hpp create mode 100644 src/vendor/boost/mpl/aux_/arithmetic_op.hpp create mode 100644 src/vendor/boost/mpl/aux_/arity.hpp create mode 100644 src/vendor/boost/mpl/aux_/arity_spec.hpp create mode 100644 src/vendor/boost/mpl/aux_/at_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/begin_end_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/clear_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/common_name_wknd.hpp create mode 100644 src/vendor/boost/mpl/aux_/comparison_op.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/adl.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/arrays.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/bcc.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/bind.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/compiler.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/ctps.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/dtp.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/eti.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/forwarding.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/gcc.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/gpu.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/has_apply.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/has_xxx.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/integral.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/intel.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/lambda.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/msvc.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/msvc_typename.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/nttp.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/overload_resolution.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/pp_counter.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/preprocessor.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/static_constant.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/ttp.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/typeof.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/use_preprocessed.hpp create mode 100644 src/vendor/boost/mpl/aux_/config/workaround.hpp create mode 100644 src/vendor/boost/mpl/aux_/contains_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/find_if_pred.hpp create mode 100644 src/vendor/boost/mpl/aux_/fold_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/full_lambda.hpp create mode 100644 src/vendor/boost/mpl/aux_/has_apply.hpp create mode 100644 src/vendor/boost/mpl/aux_/has_begin.hpp create mode 100644 src/vendor/boost/mpl/aux_/has_size.hpp create mode 100644 src/vendor/boost/mpl/aux_/has_tag.hpp create mode 100644 src/vendor/boost/mpl/aux_/has_type.hpp create mode 100644 src/vendor/boost/mpl/aux_/include_preprocessed.hpp create mode 100644 src/vendor/boost/mpl/aux_/inserter_algorithm.hpp create mode 100644 src/vendor/boost/mpl/aux_/integral_wrapper.hpp create mode 100644 src/vendor/boost/mpl/aux_/is_msvc_eti_arg.hpp create mode 100644 src/vendor/boost/mpl/aux_/iter_apply.hpp create mode 100644 src/vendor/boost/mpl/aux_/iter_fold_if_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/iter_fold_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/lambda_arity_param.hpp create mode 100644 src/vendor/boost/mpl/aux_/lambda_spec.hpp create mode 100644 src/vendor/boost/mpl/aux_/lambda_support.hpp create mode 100644 src/vendor/boost/mpl/aux_/largest_int.hpp create mode 100644 src/vendor/boost/mpl/aux_/msvc_eti_base.hpp create mode 100644 src/vendor/boost/mpl/aux_/msvc_never_true.hpp create mode 100644 src/vendor/boost/mpl/aux_/msvc_type.hpp create mode 100644 src/vendor/boost/mpl/aux_/na.hpp create mode 100644 src/vendor/boost/mpl/aux_/na_assert.hpp create mode 100644 src/vendor/boost/mpl/aux_/na_fwd.hpp create mode 100644 src/vendor/boost/mpl/aux_/na_spec.hpp create mode 100644 src/vendor/boost/mpl/aux_/nested_type_wknd.hpp create mode 100644 src/vendor/boost/mpl/aux_/nttp_decl.hpp create mode 100644 src/vendor/boost/mpl/aux_/numeric_cast_utils.hpp create mode 100644 src/vendor/boost/mpl/aux_/numeric_op.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/advance_backward.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/advance_forward.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/and.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/apply.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/apply_fwd.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/arg.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/bind.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/bind_fwd.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/fold_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/full_lambda.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/greater.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/greater_equal.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/iter_fold_if_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/iter_fold_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/less.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/less_equal.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/list.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/minus.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/not_equal_to.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/or.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/placeholders.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/plus.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/quote.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/reverse_fold_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/template_arity.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/times.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessed/gcc/vector.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessor/def_params_tail.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessor/default_params.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessor/enum.hpp create mode 100644 src/vendor/boost/mpl/aux_/preprocessor/params.hpp create mode 100644 src/vendor/boost/mpl/aux_/push_back_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/push_front_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/reverse_fold_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/size_impl.hpp create mode 100644 src/vendor/boost/mpl/aux_/static_cast.hpp create mode 100644 src/vendor/boost/mpl/aux_/template_arity.hpp create mode 100644 src/vendor/boost/mpl/aux_/template_arity_fwd.hpp create mode 100644 src/vendor/boost/mpl/aux_/traits_lambda_spec.hpp create mode 100644 src/vendor/boost/mpl/aux_/type_wrapper.hpp create mode 100644 src/vendor/boost/mpl/aux_/value_wknd.hpp create mode 100644 src/vendor/boost/mpl/aux_/yes_no.hpp create mode 100644 src/vendor/boost/mpl/back_fwd.hpp create mode 100644 src/vendor/boost/mpl/back_inserter.hpp create mode 100644 src/vendor/boost/mpl/begin_end.hpp create mode 100644 src/vendor/boost/mpl/begin_end_fwd.hpp create mode 100644 src/vendor/boost/mpl/bind.hpp create mode 100644 src/vendor/boost/mpl/bind_fwd.hpp create mode 100644 src/vendor/boost/mpl/bool.hpp create mode 100644 src/vendor/boost/mpl/bool_fwd.hpp create mode 100644 src/vendor/boost/mpl/clear.hpp create mode 100644 src/vendor/boost/mpl/clear_fwd.hpp create mode 100644 src/vendor/boost/mpl/comparison.hpp create mode 100644 src/vendor/boost/mpl/contains.hpp create mode 100644 src/vendor/boost/mpl/contains_fwd.hpp create mode 100644 src/vendor/boost/mpl/deref.hpp create mode 100644 src/vendor/boost/mpl/distance.hpp create mode 100644 src/vendor/boost/mpl/distance_fwd.hpp create mode 100644 src/vendor/boost/mpl/empty_fwd.hpp create mode 100644 src/vendor/boost/mpl/equal_to.hpp create mode 100644 src/vendor/boost/mpl/eval_if.hpp create mode 100644 src/vendor/boost/mpl/find.hpp create mode 100644 src/vendor/boost/mpl/find_if.hpp create mode 100644 src/vendor/boost/mpl/fold.hpp create mode 100644 src/vendor/boost/mpl/front_fwd.hpp create mode 100644 src/vendor/boost/mpl/front_inserter.hpp create mode 100644 src/vendor/boost/mpl/greater.hpp create mode 100644 src/vendor/boost/mpl/greater_equal.hpp create mode 100644 src/vendor/boost/mpl/has_xxx.hpp create mode 100644 src/vendor/boost/mpl/identity.hpp create mode 100644 src/vendor/boost/mpl/if.hpp create mode 100644 src/vendor/boost/mpl/inserter.hpp create mode 100644 src/vendor/boost/mpl/int.hpp create mode 100644 src/vendor/boost/mpl/int_fwd.hpp create mode 100644 src/vendor/boost/mpl/integral_c.hpp create mode 100644 src/vendor/boost/mpl/integral_c_fwd.hpp create mode 100644 src/vendor/boost/mpl/integral_c_tag.hpp create mode 100644 src/vendor/boost/mpl/iter_fold.hpp create mode 100644 src/vendor/boost/mpl/iter_fold_if.hpp create mode 100644 src/vendor/boost/mpl/iterator_range.hpp create mode 100644 src/vendor/boost/mpl/iterator_tags.hpp create mode 100644 src/vendor/boost/mpl/lambda.hpp create mode 100644 src/vendor/boost/mpl/lambda_fwd.hpp create mode 100644 src/vendor/boost/mpl/less.hpp create mode 100644 src/vendor/boost/mpl/less_equal.hpp create mode 100644 src/vendor/boost/mpl/limits/arity.hpp create mode 100644 src/vendor/boost/mpl/limits/list.hpp create mode 100644 src/vendor/boost/mpl/limits/vector.hpp create mode 100644 src/vendor/boost/mpl/list.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/O1_size.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/begin_end.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/clear.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/empty.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/front.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/include_preprocessed.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/item.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/iterator.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/pop_front.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/preprocessed/plain/list10.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/preprocessed/plain/list20.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/push_back.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/push_front.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/size.hpp create mode 100644 src/vendor/boost/mpl/list/aux_/tag.hpp create mode 100644 src/vendor/boost/mpl/list/list0.hpp create mode 100644 src/vendor/boost/mpl/list/list10.hpp create mode 100644 src/vendor/boost/mpl/list/list20.hpp create mode 100644 src/vendor/boost/mpl/logical.hpp create mode 100644 src/vendor/boost/mpl/long.hpp create mode 100644 src/vendor/boost/mpl/long_fwd.hpp create mode 100644 src/vendor/boost/mpl/minus.hpp create mode 100644 src/vendor/boost/mpl/multiplies.hpp create mode 100644 src/vendor/boost/mpl/negate.hpp create mode 100644 src/vendor/boost/mpl/next.hpp create mode 100644 src/vendor/boost/mpl/next_prior.hpp create mode 100644 src/vendor/boost/mpl/not.hpp create mode 100644 src/vendor/boost/mpl/not_equal_to.hpp create mode 100644 src/vendor/boost/mpl/numeric_cast.hpp create mode 100644 src/vendor/boost/mpl/or.hpp create mode 100644 src/vendor/boost/mpl/pair.hpp create mode 100644 src/vendor/boost/mpl/placeholders.hpp create mode 100644 src/vendor/boost/mpl/plus.hpp create mode 100644 src/vendor/boost/mpl/pop_back_fwd.hpp create mode 100644 src/vendor/boost/mpl/pop_front_fwd.hpp create mode 100644 src/vendor/boost/mpl/prior.hpp create mode 100644 src/vendor/boost/mpl/protect.hpp create mode 100644 src/vendor/boost/mpl/push_back.hpp create mode 100644 src/vendor/boost/mpl/push_back_fwd.hpp create mode 100644 src/vendor/boost/mpl/push_front.hpp create mode 100644 src/vendor/boost/mpl/push_front_fwd.hpp create mode 100644 src/vendor/boost/mpl/quote.hpp create mode 100644 src/vendor/boost/mpl/remove_if.hpp create mode 100644 src/vendor/boost/mpl/reverse_fold.hpp create mode 100644 src/vendor/boost/mpl/same_as.hpp create mode 100644 src/vendor/boost/mpl/sequence_tag.hpp create mode 100644 src/vendor/boost/mpl/sequence_tag_fwd.hpp create mode 100644 src/vendor/boost/mpl/size.hpp create mode 100644 src/vendor/boost/mpl/size_fwd.hpp create mode 100644 src/vendor/boost/mpl/tag.hpp create mode 100644 src/vendor/boost/mpl/times.hpp create mode 100644 src/vendor/boost/mpl/vector.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/O1_size.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/at.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/back.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/begin_end.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/clear.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/empty.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/front.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/include_preprocessed.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/item.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/iterator.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/pop_back.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/pop_front.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/preprocessed/typeof_based/vector10.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/preprocessed/typeof_based/vector20.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/push_back.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/push_front.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/size.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/tag.hpp create mode 100644 src/vendor/boost/mpl/vector/aux_/vector0.hpp create mode 100644 src/vendor/boost/mpl/vector/vector0.hpp create mode 100644 src/vendor/boost/mpl/vector/vector10.hpp create mode 100644 src/vendor/boost/mpl/vector/vector20.hpp create mode 100644 src/vendor/boost/mpl/void.hpp create mode 100644 src/vendor/boost/mpl/void_fwd.hpp create mode 100644 src/vendor/boost/next_prior.hpp create mode 100644 src/vendor/boost/noncopyable.hpp create mode 100644 src/vendor/boost/numeric/conversion/bounds.hpp create mode 100644 src/vendor/boost/numeric/conversion/cast.hpp create mode 100644 src/vendor/boost/numeric/conversion/conversion_traits.hpp create mode 100644 src/vendor/boost/numeric/conversion/converter.hpp create mode 100644 src/vendor/boost/numeric/conversion/converter_policies.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/bounds.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/conversion_traits.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/converter.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/int_float_mixture.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/is_subranged.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/meta.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/numeric_cast_traits.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/sign_mixture.hpp create mode 100644 src/vendor/boost/numeric/conversion/detail/udt_builtin_mixture.hpp create mode 100644 src/vendor/boost/numeric/conversion/int_float_mixture_enum.hpp create mode 100644 src/vendor/boost/numeric/conversion/numeric_cast_traits.hpp create mode 100644 src/vendor/boost/numeric/conversion/sign_mixture_enum.hpp create mode 100644 src/vendor/boost/numeric/conversion/udt_builtin_mixture_enum.hpp create mode 100644 src/vendor/boost/operators.hpp create mode 100644 src/vendor/boost/pointee.hpp create mode 100644 src/vendor/boost/predef/architecture/x86.h create mode 100644 src/vendor/boost/predef/architecture/x86/32.h create mode 100644 src/vendor/boost/predef/architecture/x86/64.h create mode 100644 src/vendor/boost/predef/detail/_cassert.h create mode 100644 src/vendor/boost/predef/detail/test.h create mode 100644 src/vendor/boost/predef/library/c/_prefix.h create mode 100644 src/vendor/boost/predef/library/c/gnu.h create mode 100644 src/vendor/boost/predef/make.h create mode 100644 src/vendor/boost/predef/os/bsd.h create mode 100644 src/vendor/boost/predef/os/bsd/bsdi.h create mode 100644 src/vendor/boost/predef/os/bsd/dragonfly.h create mode 100644 src/vendor/boost/predef/os/bsd/free.h create mode 100644 src/vendor/boost/predef/os/bsd/net.h create mode 100644 src/vendor/boost/predef/os/bsd/open.h create mode 100644 src/vendor/boost/predef/os/ios.h create mode 100644 src/vendor/boost/predef/os/macos.h create mode 100644 src/vendor/boost/predef/other/endian.h create mode 100644 src/vendor/boost/predef/platform/android.h create mode 100644 src/vendor/boost/predef/version_number.h create mode 100644 src/vendor/boost/preprocessor/arithmetic/add.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/dec.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/detail/div_base.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/detail/is_1_number.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/detail/is_maximum_number.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/detail/is_minimum_number.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/detail/maximum_number.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/inc.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/limits/dec_256.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/limits/inc_256.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/mod.hpp create mode 100644 src/vendor/boost/preprocessor/arithmetic/sub.hpp create mode 100644 src/vendor/boost/preprocessor/array/data.hpp create mode 100644 src/vendor/boost/preprocessor/array/elem.hpp create mode 100644 src/vendor/boost/preprocessor/array/size.hpp create mode 100644 src/vendor/boost/preprocessor/cat.hpp create mode 100644 src/vendor/boost/preprocessor/comma_if.hpp create mode 100644 src/vendor/boost/preprocessor/comparison/equal.hpp create mode 100644 src/vendor/boost/preprocessor/comparison/less_equal.hpp create mode 100644 src/vendor/boost/preprocessor/comparison/limits/not_equal_256.hpp create mode 100644 src/vendor/boost/preprocessor/comparison/not_equal.hpp create mode 100644 src/vendor/boost/preprocessor/config/config.hpp create mode 100644 src/vendor/boost/preprocessor/config/limits.hpp create mode 100644 src/vendor/boost/preprocessor/control/deduce_d.hpp create mode 100644 src/vendor/boost/preprocessor/control/detail/limits/while_256.hpp create mode 100644 src/vendor/boost/preprocessor/control/detail/while.hpp create mode 100644 src/vendor/boost/preprocessor/control/expr_iif.hpp create mode 100644 src/vendor/boost/preprocessor/control/if.hpp create mode 100644 src/vendor/boost/preprocessor/control/iif.hpp create mode 100644 src/vendor/boost/preprocessor/control/limits/while_256.hpp create mode 100644 src/vendor/boost/preprocessor/control/while.hpp create mode 100644 src/vendor/boost/preprocessor/debug/error.hpp create mode 100644 src/vendor/boost/preprocessor/detail/auto_rec.hpp create mode 100644 src/vendor/boost/preprocessor/detail/check.hpp create mode 100644 src/vendor/boost/preprocessor/detail/is_binary.hpp create mode 100644 src/vendor/boost/preprocessor/detail/limits/auto_rec_256.hpp create mode 100644 src/vendor/boost/preprocessor/empty.hpp create mode 100644 src/vendor/boost/preprocessor/enum.hpp create mode 100644 src/vendor/boost/preprocessor/enum_params.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/check_empty.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/empty.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/expand.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/identity.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/intercept.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/limits/intercept_256.hpp create mode 100644 src/vendor/boost/preprocessor/facilities/overload.hpp create mode 100644 src/vendor/boost/preprocessor/identity.hpp create mode 100644 src/vendor/boost/preprocessor/inc.hpp create mode 100644 src/vendor/boost/preprocessor/iterate.hpp create mode 100644 src/vendor/boost/preprocessor/iteration/detail/bounds/lower1.hpp create mode 100644 src/vendor/boost/preprocessor/iteration/detail/bounds/upper1.hpp create mode 100644 src/vendor/boost/preprocessor/iteration/detail/iter/forward1.hpp create mode 100644 src/vendor/boost/preprocessor/iteration/detail/iter/limits/forward1_256.hpp create mode 100644 src/vendor/boost/preprocessor/iteration/iterate.hpp create mode 100644 src/vendor/boost/preprocessor/list/adt.hpp create mode 100644 src/vendor/boost/preprocessor/list/detail/fold_left.hpp create mode 100644 src/vendor/boost/preprocessor/list/detail/fold_right.hpp create mode 100644 src/vendor/boost/preprocessor/list/detail/limits/fold_left_256.hpp create mode 100644 src/vendor/boost/preprocessor/list/detail/limits/fold_right_256.hpp create mode 100644 src/vendor/boost/preprocessor/list/fold_left.hpp create mode 100644 src/vendor/boost/preprocessor/list/fold_right.hpp create mode 100644 src/vendor/boost/preprocessor/list/limits/fold_left_256.hpp create mode 100644 src/vendor/boost/preprocessor/list/reverse.hpp create mode 100644 src/vendor/boost/preprocessor/logical/and.hpp create mode 100644 src/vendor/boost/preprocessor/logical/bitand.hpp create mode 100644 src/vendor/boost/preprocessor/logical/bitor.hpp create mode 100644 src/vendor/boost/preprocessor/logical/bool.hpp create mode 100644 src/vendor/boost/preprocessor/logical/compl.hpp create mode 100644 src/vendor/boost/preprocessor/logical/limits/bool_256.hpp create mode 100644 src/vendor/boost/preprocessor/logical/not.hpp create mode 100644 src/vendor/boost/preprocessor/punctuation/comma.hpp create mode 100644 src/vendor/boost/preprocessor/punctuation/comma_if.hpp create mode 100644 src/vendor/boost/preprocessor/repeat.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/detail/for.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/detail/limits/for_256.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/enum.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/enum_binary_params.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/enum_params.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/enum_shifted_params.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/enum_trailing_params.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/for.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/limits/for_256.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/limits/repeat_256.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/repeat.hpp create mode 100644 src/vendor/boost/preprocessor/repetition/repeat_from_to.hpp create mode 100644 src/vendor/boost/preprocessor/seq/cat.hpp create mode 100644 src/vendor/boost/preprocessor/seq/detail/is_empty.hpp create mode 100644 src/vendor/boost/preprocessor/seq/elem.hpp create mode 100644 src/vendor/boost/preprocessor/seq/enum.hpp create mode 100644 src/vendor/boost/preprocessor/seq/fold_left.hpp create mode 100644 src/vendor/boost/preprocessor/seq/for_each_i.hpp create mode 100644 src/vendor/boost/preprocessor/seq/limits/elem_256.hpp create mode 100644 src/vendor/boost/preprocessor/seq/limits/enum_256.hpp create mode 100644 src/vendor/boost/preprocessor/seq/limits/fold_left_256.hpp create mode 100644 src/vendor/boost/preprocessor/seq/limits/size_256.hpp create mode 100644 src/vendor/boost/preprocessor/seq/seq.hpp create mode 100644 src/vendor/boost/preprocessor/seq/size.hpp create mode 100644 src/vendor/boost/preprocessor/seq/transform.hpp create mode 100644 src/vendor/boost/preprocessor/slot/detail/def.hpp create mode 100644 src/vendor/boost/preprocessor/slot/detail/shared.hpp create mode 100644 src/vendor/boost/preprocessor/slot/slot.hpp create mode 100644 src/vendor/boost/preprocessor/stringize.hpp create mode 100644 src/vendor/boost/preprocessor/tuple/detail/is_single_return.hpp create mode 100644 src/vendor/boost/preprocessor/tuple/eat.hpp create mode 100644 src/vendor/boost/preprocessor/tuple/elem.hpp create mode 100644 src/vendor/boost/preprocessor/tuple/rem.hpp create mode 100644 src/vendor/boost/preprocessor/variadic/elem.hpp create mode 100644 src/vendor/boost/preprocessor/variadic/has_opt.hpp create mode 100644 src/vendor/boost/preprocessor/variadic/limits/elem_64.hpp create mode 100644 src/vendor/boost/preprocessor/variadic/limits/size_64.hpp create mode 100644 src/vendor/boost/preprocessor/variadic/size.hpp create mode 100644 src/vendor/boost/ptr_container/clone_allocator.hpp create mode 100644 src/vendor/boost/ptr_container/detail/default_deleter.hpp create mode 100644 src/vendor/boost/ptr_container/detail/is_convertible.hpp create mode 100644 src/vendor/boost/ptr_container/detail/move.hpp create mode 100644 src/vendor/boost/ptr_container/detail/ptr_container_disable_deprecated.hpp create mode 100644 src/vendor/boost/ptr_container/detail/reversible_ptr_container.hpp create mode 100644 src/vendor/boost/ptr_container/detail/scoped_deleter.hpp create mode 100644 src/vendor/boost/ptr_container/detail/static_move_ptr.hpp create mode 100644 src/vendor/boost/ptr_container/detail/throw_exception.hpp create mode 100644 src/vendor/boost/ptr_container/detail/void_ptr_iterator.hpp create mode 100644 src/vendor/boost/ptr_container/exception.hpp create mode 100644 src/vendor/boost/ptr_container/indirect_fun.hpp create mode 100644 src/vendor/boost/ptr_container/nullable.hpp create mode 100644 src/vendor/boost/ptr_container/ptr_sequence_adapter.hpp create mode 100644 src/vendor/boost/ptr_container/ptr_vector.hpp create mode 100644 src/vendor/boost/range/algorithm/equal.hpp create mode 100644 src/vendor/boost/range/algorithm_ext/for_each.hpp create mode 100644 src/vendor/boost/range/as_literal.hpp create mode 100644 src/vendor/boost/range/begin.hpp create mode 100644 src/vendor/boost/range/concepts.hpp create mode 100644 src/vendor/boost/range/config.hpp create mode 100644 src/vendor/boost/range/const_iterator.hpp create mode 100644 src/vendor/boost/range/detail/common.hpp create mode 100644 src/vendor/boost/range/detail/extract_optional_type.hpp create mode 100644 src/vendor/boost/range/detail/has_member_size.hpp create mode 100644 src/vendor/boost/range/detail/implementation_help.hpp create mode 100644 src/vendor/boost/range/detail/misc_concept.hpp create mode 100644 src/vendor/boost/range/detail/msvc_has_iterator_workaround.hpp create mode 100644 src/vendor/boost/range/detail/safe_bool.hpp create mode 100644 src/vendor/boost/range/detail/sfinae.hpp create mode 100644 src/vendor/boost/range/detail/str_types.hpp create mode 100644 src/vendor/boost/range/difference_type.hpp create mode 100644 src/vendor/boost/range/distance.hpp create mode 100644 src/vendor/boost/range/empty.hpp create mode 100644 src/vendor/boost/range/end.hpp create mode 100644 src/vendor/boost/range/functions.hpp create mode 100644 src/vendor/boost/range/has_range_iterator.hpp create mode 100644 src/vendor/boost/range/iterator.hpp create mode 100644 src/vendor/boost/range/iterator_range.hpp create mode 100644 src/vendor/boost/range/iterator_range_core.hpp create mode 100644 src/vendor/boost/range/iterator_range_io.hpp create mode 100644 src/vendor/boost/range/mutable_iterator.hpp create mode 100644 src/vendor/boost/range/range_fwd.hpp create mode 100644 src/vendor/boost/range/rbegin.hpp create mode 100644 src/vendor/boost/range/rend.hpp create mode 100644 src/vendor/boost/range/reverse_iterator.hpp create mode 100644 src/vendor/boost/range/size.hpp create mode 100644 src/vendor/boost/range/size_type.hpp create mode 100644 src/vendor/boost/range/value_type.hpp create mode 100644 src/vendor/boost/ref.hpp create mode 100644 src/vendor/boost/scoped_array.hpp create mode 100644 src/vendor/boost/scoped_ptr.hpp create mode 100644 src/vendor/boost/shared_ptr.hpp create mode 100644 src/vendor/boost/smart_ptr/bad_weak_ptr.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/local_counted_base.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/local_sp_deleter.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/operator_bool.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/shared_count.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_convertible.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_counted_base.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_counted_base_gcc_atomic.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_counted_impl.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_disable_deprecated.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_has_gcc_intrinsics.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_has_sync_intrinsics.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_noexcept.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_nullptr_t.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_thread_pause.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_thread_sleep.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/sp_typeinfo_.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/spinlock.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/spinlock_gcc_atomic.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/spinlock_pool.hpp create mode 100644 src/vendor/boost/smart_ptr/detail/yield_k.hpp create mode 100644 src/vendor/boost/smart_ptr/scoped_array.hpp create mode 100644 src/vendor/boost/smart_ptr/scoped_ptr.hpp create mode 100644 src/vendor/boost/smart_ptr/shared_ptr.hpp create mode 100644 src/vendor/boost/static_assert.hpp create mode 100644 src/vendor/boost/swap.hpp create mode 100644 src/vendor/boost/throw_exception.hpp create mode 100644 src/vendor/boost/token_functions.hpp create mode 100644 src/vendor/boost/token_iterator.hpp create mode 100644 src/vendor/boost/tokenizer.hpp create mode 100644 src/vendor/boost/type.hpp create mode 100644 src/vendor/boost/type_index.hpp create mode 100644 src/vendor/boost/type_index/stl_type_index.hpp create mode 100644 src/vendor/boost/type_index/type_index_facade.hpp create mode 100644 src/vendor/boost/type_traits/add_const.hpp create mode 100644 src/vendor/boost/type_traits/add_lvalue_reference.hpp create mode 100644 src/vendor/boost/type_traits/add_pointer.hpp create mode 100644 src/vendor/boost/type_traits/add_reference.hpp create mode 100644 src/vendor/boost/type_traits/add_rvalue_reference.hpp create mode 100644 src/vendor/boost/type_traits/add_volatile.hpp create mode 100644 src/vendor/boost/type_traits/alignment_of.hpp create mode 100644 src/vendor/boost/type_traits/composite_traits.hpp create mode 100644 src/vendor/boost/type_traits/conditional.hpp create mode 100644 src/vendor/boost/type_traits/conversion_traits.hpp create mode 100644 src/vendor/boost/type_traits/declval.hpp create mode 100644 src/vendor/boost/type_traits/detail/bool_trait_undef.hpp create mode 100644 src/vendor/boost/type_traits/detail/config.hpp create mode 100644 src/vendor/boost/type_traits/detail/has_binary_operator.hpp create mode 100644 src/vendor/boost/type_traits/detail/is_function_cxx_11.hpp create mode 100644 src/vendor/boost/type_traits/detail/is_member_function_pointer_cxx_11.hpp create mode 100644 src/vendor/boost/type_traits/detail/yes_no_type.hpp create mode 100644 src/vendor/boost/type_traits/enable_if.hpp create mode 100644 src/vendor/boost/type_traits/function_traits.hpp create mode 100644 src/vendor/boost/type_traits/has_left_shift.hpp create mode 100644 src/vendor/boost/type_traits/has_minus.hpp create mode 100644 src/vendor/boost/type_traits/has_minus_assign.hpp create mode 100644 src/vendor/boost/type_traits/has_plus.hpp create mode 100644 src/vendor/boost/type_traits/has_plus_assign.hpp create mode 100644 src/vendor/boost/type_traits/has_right_shift.hpp create mode 100644 src/vendor/boost/type_traits/has_trivial_copy.hpp create mode 100644 src/vendor/boost/type_traits/has_trivial_destructor.hpp create mode 100644 src/vendor/boost/type_traits/integral_constant.hpp create mode 100644 src/vendor/boost/type_traits/intrinsics.hpp create mode 100644 src/vendor/boost/type_traits/is_abstract.hpp create mode 100644 src/vendor/boost/type_traits/is_arithmetic.hpp create mode 100644 src/vendor/boost/type_traits/is_array.hpp create mode 100644 src/vendor/boost/type_traits/is_base_and_derived.hpp create mode 100644 src/vendor/boost/type_traits/is_base_of.hpp create mode 100644 src/vendor/boost/type_traits/is_class.hpp create mode 100644 src/vendor/boost/type_traits/is_complete.hpp create mode 100644 src/vendor/boost/type_traits/is_const.hpp create mode 100644 src/vendor/boost/type_traits/is_constructible.hpp create mode 100644 src/vendor/boost/type_traits/is_convertible.hpp create mode 100644 src/vendor/boost/type_traits/is_copy_constructible.hpp create mode 100644 src/vendor/boost/type_traits/is_default_constructible.hpp create mode 100644 src/vendor/boost/type_traits/is_destructible.hpp create mode 100644 src/vendor/boost/type_traits/is_empty.hpp create mode 100644 src/vendor/boost/type_traits/is_enum.hpp create mode 100644 src/vendor/boost/type_traits/is_final.hpp create mode 100644 src/vendor/boost/type_traits/is_float.hpp create mode 100644 src/vendor/boost/type_traits/is_floating_point.hpp create mode 100644 src/vendor/boost/type_traits/is_function.hpp create mode 100644 src/vendor/boost/type_traits/is_integral.hpp create mode 100644 src/vendor/boost/type_traits/is_lvalue_reference.hpp create mode 100644 src/vendor/boost/type_traits/is_member_function_pointer.hpp create mode 100644 src/vendor/boost/type_traits/is_member_pointer.hpp create mode 100644 src/vendor/boost/type_traits/is_pod.hpp create mode 100644 src/vendor/boost/type_traits/is_pointer.hpp create mode 100644 src/vendor/boost/type_traits/is_reference.hpp create mode 100644 src/vendor/boost/type_traits/is_rvalue_reference.hpp create mode 100644 src/vendor/boost/type_traits/is_same.hpp create mode 100644 src/vendor/boost/type_traits/is_scalar.hpp create mode 100644 src/vendor/boost/type_traits/is_signed.hpp create mode 100644 src/vendor/boost/type_traits/is_union.hpp create mode 100644 src/vendor/boost/type_traits/is_unsigned.hpp create mode 100644 src/vendor/boost/type_traits/is_void.hpp create mode 100644 src/vendor/boost/type_traits/is_volatile.hpp create mode 100644 src/vendor/boost/type_traits/make_unsigned.hpp create mode 100644 src/vendor/boost/type_traits/make_void.hpp create mode 100644 src/vendor/boost/type_traits/remove_bounds.hpp create mode 100644 src/vendor/boost/type_traits/remove_const.hpp create mode 100644 src/vendor/boost/type_traits/remove_cv.hpp create mode 100644 src/vendor/boost/type_traits/remove_extent.hpp create mode 100644 src/vendor/boost/type_traits/remove_pointer.hpp create mode 100644 src/vendor/boost/type_traits/remove_reference.hpp create mode 100644 src/vendor/boost/type_traits/type_identity.hpp create mode 100644 src/vendor/boost/utility.hpp create mode 100644 src/vendor/boost/utility/base_from_member.hpp create mode 100644 src/vendor/boost/utility/binary.hpp create mode 100644 src/vendor/boost/utility/detail/result_of_iterate.hpp create mode 100644 src/vendor/boost/utility/enable_if.hpp create mode 100644 src/vendor/boost/utility/identity_type.hpp create mode 100644 src/vendor/boost/utility/result_of.hpp create mode 100644 src/vendor/boost/version.hpp create mode 100644 src/vendor/boost/visit_each.hpp diff --git a/src/vendor/boost/algorithm/string.hpp b/src/vendor/boost/algorithm/string.hpp new file mode 100644 index 000000000..077151739 --- /dev/null +++ b/src/vendor/boost/algorithm/string.hpp @@ -0,0 +1,31 @@ +// Boost string_algo library string_algo.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ALGO_HPP +#define BOOST_STRING_ALGO_HPP + +/*! \file + Cumulative include for string_algo library +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#endif // BOOST_STRING_ALGO_HPP diff --git a/src/vendor/boost/algorithm/string/case_conv.hpp b/src/vendor/boost/algorithm/string/case_conv.hpp new file mode 100644 index 000000000..683340b8e --- /dev/null +++ b/src/vendor/boost/algorithm/string/case_conv.hpp @@ -0,0 +1,176 @@ +// Boost string_algo library case_conv.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CASE_CONV_HPP +#define BOOST_STRING_CASE_CONV_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +/*! \file + Defines sequence case-conversion algorithms. + Algorithms convert each element in the input sequence to the + desired case using provided locales. +*/ + +namespace boost { + namespace algorithm { + +// to_lower -----------------------------------------------// + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The result is a copy of the input converted to lower case. + It is returned as a sequence or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param Loc A locale used for conversion + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + + */ + template + inline OutputIteratorT + to_lower_copy( + OutputIteratorT Output, + const RangeT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Output, + ::boost::as_literal(Input), + ::boost::algorithm::detail::to_lowerF< + typename range_value::type >(Loc)); + } + + //! Convert to lower case + /*! + \overload + */ + template + inline SequenceT to_lower_copy( + const SequenceT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Input, + ::boost::algorithm::detail::to_lowerF< + typename range_value::type >(Loc)); + } + + //! Convert to lower case + /*! + Each element of the input sequence is converted to lower + case. The input sequence is modified in-place. + + \param Input A range + \param Loc a locale used for conversion + */ + template + inline void to_lower( + WritableRangeT& Input, + const std::locale& Loc=std::locale()) + { + ::boost::algorithm::detail::transform_range( + ::boost::as_literal(Input), + ::boost::algorithm::detail::to_lowerF< + typename range_value::type >(Loc)); + } + +// to_upper -----------------------------------------------// + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The result is a copy of the input converted to upper case. + It is returned as a sequence or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param Loc A locale used for conversion + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT + to_upper_copy( + OutputIteratorT Output, + const RangeT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Output, + ::boost::as_literal(Input), + ::boost::algorithm::detail::to_upperF< + typename range_value::type >(Loc)); + } + + //! Convert to upper case + /*! + \overload + */ + template + inline SequenceT to_upper_copy( + const SequenceT& Input, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::detail::transform_range_copy( + Input, + ::boost::algorithm::detail::to_upperF< + typename range_value::type >(Loc)); + } + + //! Convert to upper case + /*! + Each element of the input sequence is converted to upper + case. The input sequence is modified in-place. + + \param Input An input range + \param Loc a locale used for conversion + */ + template + inline void to_upper( + WritableRangeT& Input, + const std::locale& Loc=std::locale()) + { + ::boost::algorithm::detail::transform_range( + ::boost::as_literal(Input), + ::boost::algorithm::detail::to_upperF< + typename range_value::type >(Loc)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::to_lower; + using algorithm::to_lower_copy; + using algorithm::to_upper; + using algorithm::to_upper_copy; + +} // namespace boost + +#endif // BOOST_STRING_CASE_CONV_HPP diff --git a/src/vendor/boost/algorithm/string/classification.hpp b/src/vendor/boost/algorithm/string/classification.hpp new file mode 100644 index 000000000..ca43602d4 --- /dev/null +++ b/src/vendor/boost/algorithm/string/classification.hpp @@ -0,0 +1,312 @@ +// Boost string_algo library classification.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CLASSIFICATION_HPP +#define BOOST_STRING_CLASSIFICATION_HPP + +#include +#include +#include +#include +#include +#include + + +/*! \file + Classification predicates are included in the library to give + some more convenience when using algorithms like \c trim() and \c all(). + They wrap functionality of STL classification functions ( e.g. \c std::isspace() ) + into generic functors. +*/ + +namespace boost { + namespace algorithm { + +// classification functor generator -------------------------------------// + + //! is_classified predicate + /*! + Construct the \c is_classified predicate. This predicate holds if the input is + of specified \c std::ctype category. + + \param Type A \c std::ctype category + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_classified(std::ctype_base::mask Type, const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(Type, Loc); + } + + //! is_space predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::space category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_space(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::space, Loc); + } + + //! is_alnum predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alnum category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alnum(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alnum, Loc); + } + + //! is_alpha predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::alpha category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_alpha(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::alpha, Loc); + } + + //! is_cntrl predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::cntrl category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_cntrl(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::cntrl, Loc); + } + + //! is_digit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::digit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_digit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::digit, Loc); + } + + //! is_graph predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::graph category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_graph(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::graph, Loc); + } + + //! is_lower predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::lower category. + + \param Loc A locale used for classification + \return An instance of \c is_classified predicate + */ + inline detail::is_classifiedF + is_lower(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::lower, Loc); + } + + //! is_print predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::print category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_print(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::print, Loc); + } + + //! is_punct predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::punct category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_punct(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::punct, Loc); + } + + //! is_upper predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::upper category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_upper(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::upper, Loc); + } + + //! is_xdigit predicate + /*! + Construct the \c is_classified predicate for the \c ctype_base::xdigit category. + + \param Loc A locale used for classification + \return An instance of the \c is_classified predicate + */ + inline detail::is_classifiedF + is_xdigit(const std::locale& Loc=std::locale()) + { + return detail::is_classifiedF(std::ctype_base::xdigit, Loc); + } + + //! is_any_of predicate + /*! + Construct the \c is_any_of predicate. The predicate holds if the input + is included in the specified set of characters. + + \param Set A set of characters to be recognized + \return An instance of the \c is_any_of predicate + */ + template + inline detail::is_any_ofF< + BOOST_STRING_TYPENAME range_value::type> + is_any_of( const RangeT& Set ) + { + iterator_range::type> lit_set(boost::as_literal(Set)); + return detail::is_any_ofF::type>(lit_set); + } + + //! is_from_range predicate + /*! + Construct the \c is_from_range predicate. The predicate holds if the input + is included in the specified range. (i.e. From <= Ch <= To ) + + \param From The start of the range + \param To The end of the range + \return An instance of the \c is_from_range predicate + */ + template + inline detail::is_from_rangeF is_from_range(CharT From, CharT To) + { + return detail::is_from_rangeF(From,To); + } + + // predicate combinators ---------------------------------------------------// + + //! predicate 'and' composition predicate + /*! + Construct the \c class_and predicate. This predicate can be used + to logically combine two classification predicates. \c class_and holds, + if both predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_and predicate + */ + template + inline detail::pred_andF + operator&&( + const predicate_facade& Pred1, + const predicate_facade& Pred2 ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_andF( + *static_cast(&Pred1), + *static_cast(&Pred2) ); + } + + //! predicate 'or' composition predicate + /*! + Construct the \c class_or predicate. This predicate can be used + to logically combine two classification predicates. \c class_or holds, + if one of the predicates return true. + + \param Pred1 The first predicate + \param Pred2 The second predicate + \return An instance of the \c class_or predicate + */ + template + inline detail::pred_orF + operator||( + const predicate_facade& Pred1, + const predicate_facade& Pred2 ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_orF( + *static_cast(&Pred1), + *static_cast(&Pred2)); + } + + //! predicate negation operator + /*! + Construct the \c class_not predicate. This predicate represents a negation. + \c class_or holds if of the predicates return false. + + \param Pred The predicate to be negated + \return An instance of the \c class_not predicate + */ + template + inline detail::pred_notF + operator!( const predicate_facade& Pred ) + { + // Doing the static_cast with the pointer instead of the reference + // is a workaround for some compilers which have problems with + // static_cast's of template references, i.e. CW8. /grafik/ + return detail::pred_notF(*static_cast(&Pred)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_classified; + using algorithm::is_space; + using algorithm::is_alnum; + using algorithm::is_alpha; + using algorithm::is_cntrl; + using algorithm::is_digit; + using algorithm::is_graph; + using algorithm::is_lower; + using algorithm::is_upper; + using algorithm::is_print; + using algorithm::is_punct; + using algorithm::is_xdigit; + using algorithm::is_any_of; + using algorithm::is_from_range; + +} // namespace boost + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/src/vendor/boost/algorithm/string/compare.hpp b/src/vendor/boost/algorithm/string/compare.hpp new file mode 100644 index 000000000..dc34007cf --- /dev/null +++ b/src/vendor/boost/algorithm/string/compare.hpp @@ -0,0 +1,199 @@ +// Boost string_algo library compare.hpp header file -------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_COMPARE_HPP +#define BOOST_STRING_COMPARE_HPP + +#include +#include + +/*! \file + Defines element comparison predicates. Many algorithms in this library can + take an additional argument with a predicate used to compare elements. + This makes it possible, for instance, to have case insensitive versions + of the algorithms. +*/ + +namespace boost { + namespace algorithm { + + // is_equal functor -----------------------------------------------// + + //! is_equal functor + /*! + Standard STL equal_to only handle comparison between arguments + of the same type. This is a less restrictive version which wraps operator ==. + */ + struct is_equal + { + //! Function operator + /*! + Compare two operands for equality + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1==Arg2; + } + }; + + //! case insensitive version of is_equal + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_iequal + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_iequal( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)==std::toupper(Arg2); + #else + return std::toupper(Arg1,m_Loc)==std::toupper(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + // is_less functor -----------------------------------------------// + + //! is_less functor + /*! + Convenient version of standard std::less. Operation is templated, therefore it is + not required to specify the exact types upon the construction + */ + struct is_less + { + //! Functor operation + /*! + Compare two operands using > operator + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1 + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)(Arg1,m_Loc)(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + // is_not_greater functor -----------------------------------------------// + + //! is_not_greater functor + /*! + Convenient version of standard std::not_greater_to. Operation is templated, therefore it is + not required to specify the exact types upon the construction + */ + struct is_not_greater + { + //! Functor operation + /*! + Compare two operands using > operator + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + return Arg1<=Arg2; + } + }; + + + //! case insensitive version of is_not_greater + /*! + Case insensitive comparison predicate. Comparison is done using + specified locales. + */ + struct is_not_igreater + { + //! Constructor + /*! + \param Loc locales used for comparison + */ + is_not_igreater( const std::locale& Loc=std::locale() ) : + m_Loc( Loc ) {} + + //! Function operator + /*! + Compare two operands. Case is ignored. + */ + template< typename T1, typename T2 > + bool operator()( const T1& Arg1, const T2& Arg2 ) const + { + #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper(Arg1)<=std::toupper(Arg2); + #else + return std::toupper(Arg1,m_Loc)<=std::toupper(Arg2,m_Loc); + #endif + } + + private: + std::locale m_Loc; + }; + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::is_equal; + using algorithm::is_iequal; + using algorithm::is_less; + using algorithm::is_iless; + using algorithm::is_not_greater; + using algorithm::is_not_igreater; + +} // namespace boost + + +#endif // BOOST_STRING_COMPARE_HPP diff --git a/src/vendor/boost/algorithm/string/concept.hpp b/src/vendor/boost/algorithm/string/concept.hpp new file mode 100644 index 000000000..17e834959 --- /dev/null +++ b/src/vendor/boost/algorithm/string/concept.hpp @@ -0,0 +1,83 @@ +// Boost string_algo library concept.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONCEPT_HPP +#define BOOST_STRING_CONCEPT_HPP + +#include +#include +#include +#include + +/*! \file + Defines concepts used in string_algo library +*/ + +namespace boost { + namespace algorithm { + + //! Finder concept + /*! + Defines the Finder concept. Finder is a functor which selects + an arbitrary part of a string. Search is performed on + the range specified by starting and ending iterators. + + Result of the find operation must be convertible to iterator_range. + */ + template + struct FinderConcept + { + private: + typedef iterator_range range; + public: + void constraints() + { + // Operation + r=(*pF)(i,i); + } + private: + range r; + IteratorT i; + FinderT* pF; + }; // Finder_concept + + + //! Formatter concept + /*! + Defines the Formatter concept. Formatter is a functor, which + takes a result from a finder operation and transforms it + in a specific way. + + Result must be a container supported by container_traits, + or a reference to it. + */ + template + struct FormatterConcept + { + public: + void constraints() + { + // Operation + ::boost::begin((*pFo)( (*pF)(i,i) )); + ::boost::end((*pFo)( (*pF)(i,i) )); + } + private: + IteratorT i; + FinderT* pF; + FormatterT *pFo; + }; // FormatterConcept; + + } // namespace algorithm +} // namespace boost + + + + +#endif // BOOST_STRING_CONCEPT_HPP diff --git a/src/vendor/boost/algorithm/string/config.hpp b/src/vendor/boost/algorithm/string/config.hpp new file mode 100644 index 000000000..559750ac8 --- /dev/null +++ b/src/vendor/boost/algorithm/string/config.hpp @@ -0,0 +1,28 @@ +// Boost string_algo library config.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONFIG_HPP +#define BOOST_STRING_CONFIG_HPP + +#include +#include + +#ifdef BOOST_STRING_DEDUCED_TYPENAME +# error "macro already defined!" +#endif + +#define BOOST_STRING_TYPENAME BOOST_DEDUCED_TYPENAME + +// Metrowerks workaround +#if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) // 8.x +#pragma parse_func_templ off +#endif + +#endif // BOOST_STRING_CONFIG_HPP diff --git a/src/vendor/boost/algorithm/string/constants.hpp b/src/vendor/boost/algorithm/string/constants.hpp new file mode 100644 index 000000000..6ed70effc --- /dev/null +++ b/src/vendor/boost/algorithm/string/constants.hpp @@ -0,0 +1,36 @@ +// Boost string_algo library constants.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CONSTANTS_HPP +#define BOOST_STRING_CONSTANTS_HPP + +namespace boost { + namespace algorithm { + + //! Token compression mode + /*! + Specifies token compression mode for the token_finder. + */ + enum token_compress_mode_type + { + token_compress_on, //!< Compress adjacent tokens + token_compress_off //!< Do not compress adjacent tokens + }; + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::token_compress_on; + using algorithm::token_compress_off; + +} // namespace boost + +#endif // BOOST_STRING_CONSTANTS_HPP + diff --git a/src/vendor/boost/algorithm/string/detail/case_conv.hpp b/src/vendor/boost/algorithm/string/detail/case_conv.hpp new file mode 100644 index 000000000..188602a1d --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/case_conv.hpp @@ -0,0 +1,130 @@ +// Boost string_algo library string_funct.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CASE_CONV_DETAIL_HPP +#define BOOST_STRING_CASE_CONV_DETAIL_HPP + +#include +#include +#include + +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// case conversion functors -----------------------------------------------// + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + + // a tolower functor + template + struct to_lowerF + { + typedef CharT argument_type; + typedef CharT result_type; + // Constructor + to_lowerF( const std::locale& Loc ) : m_Loc( &Loc ) {} + + // Operation + CharT operator ()( CharT Ch ) const + { + #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::tolower( static_cast::type> ( Ch )); + #else + return std::tolower( Ch, *m_Loc ); + #endif + } + private: + const std::locale* m_Loc; + }; + + // a toupper functor + template + struct to_upperF + { + typedef CharT argument_type; + typedef CharT result_type; + // Constructor + to_upperF( const std::locale& Loc ) : m_Loc( &Loc ) {} + + // Operation + CharT operator ()( CharT Ch ) const + { + #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x564) && !defined(_USE_OLD_RW_STL) + return std::toupper( static_cast::type> ( Ch )); + #else + return std::toupper( Ch, *m_Loc ); + #endif + } + private: + const std::locale* m_Loc; + }; + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + +// algorithm implementation ------------------------------------------------------------------------- + + // Transform a range + template + OutputIteratorT transform_range_copy( + OutputIteratorT Output, + const RangeT& Input, + FunctorT Functor) + { + return std::transform( + ::boost::begin(Input), + ::boost::end(Input), + Output, + Functor); + } + + // Transform a range (in-place) + template + void transform_range( + const RangeT& Input, + FunctorT Functor) + { + std::transform( + ::boost::begin(Input), + ::boost::end(Input), + ::boost::begin(Input), + Functor); + } + + template + inline SequenceT transform_range_copy( + const RangeT& Input, + FunctorT Functor) + { + return SequenceT( + ::boost::make_transform_iterator( + ::boost::begin(Input), + Functor), + ::boost::make_transform_iterator( + ::boost::end(Input), + Functor)); + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CASE_CONV_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/classification.hpp b/src/vendor/boost/algorithm/string/detail/classification.hpp new file mode 100644 index 000000000..30a37c698 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/classification.hpp @@ -0,0 +1,355 @@ +// Boost string_algo library classification.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP +#define BOOST_STRING_CLASSIFICATION_DETAIL_HPP + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// classification functors -----------------------------------------------// + + // is_classified functor + struct is_classifiedF : + public predicate_facade + { + // Boost.ResultOf support + typedef bool result_type; + + // Constructor from a locale + is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) : + m_Type(Type), m_Locale(Loc) {} + // Operation + template + bool operator()( CharT Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + + #if defined(BOOST_BORLANDC) && (BOOST_BORLANDC >= 0x560) && (BOOST_BORLANDC <= 0x582) && !defined(_USE_OLD_RW_STL) + template<> + bool operator()( char const Ch ) const + { + return std::use_facet< std::ctype >(m_Locale).is( m_Type, Ch ); + } + #endif + + private: + std::ctype_base::mask m_Type; + std::locale m_Locale; + }; + + + // is_any_of functor + /* + returns true if the value is from the specified set + */ + template + struct is_any_ofF : + public predicate_facade > + { + private: + // set cannot operate on const value-type + typedef typename ::boost::remove_const::type set_value_type; + + public: + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + template + is_any_ofF( const RangeT& Range ) : m_Size(0) + { + // Prepare storage + m_Storage.m_dynSet=0; + + std::size_t Size=::boost::distance(Range); + m_Size=Size; + set_value_type* Storage=0; + + if(use_fixed_storage(m_Size)) + { + // Use fixed storage + Storage=&m_Storage.m_fixSet[0]; + } + else + { + // Use dynamic storage + m_Storage.m_dynSet=new set_value_type[m_Size]; + Storage=m_Storage.m_dynSet; + } + + // Use fixed storage + ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage); + ::std::sort(Storage, Storage+m_Size); + } + + // Copy constructor + is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size) + { + // Prepare storage + m_Storage.m_dynSet=0; + const set_value_type* SrcStorage=0; + set_value_type* DestStorage=0; + + if(use_fixed_storage(m_Size)) + { + // Use fixed storage + DestStorage=&m_Storage.m_fixSet[0]; + SrcStorage=&Other.m_Storage.m_fixSet[0]; + } + else + { + // Use dynamic storage + m_Storage.m_dynSet=new set_value_type[m_Size]; + DestStorage=m_Storage.m_dynSet; + SrcStorage=Other.m_Storage.m_dynSet; + } + + // Use fixed storage + ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size); + } + + // Destructor + ~is_any_ofF() + { + if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) + { + delete [] m_Storage.m_dynSet; + } + } + + // Assignment + is_any_ofF& operator=(const is_any_ofF& Other) + { + // Handle self assignment + if(this==&Other) return *this; + + // Prepare storage + const set_value_type* SrcStorage; + set_value_type* DestStorage; + + if(use_fixed_storage(Other.m_Size)) + { + // Use fixed storage + DestStorage=&m_Storage.m_fixSet[0]; + SrcStorage=&Other.m_Storage.m_fixSet[0]; + + // Delete old storage if was present + if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0) + { + delete [] m_Storage.m_dynSet; + } + + // Set new size + m_Size=Other.m_Size; + } + else + { + // Other uses dynamic storage + SrcStorage=Other.m_Storage.m_dynSet; + + // Check what kind of storage are we using right now + if(use_fixed_storage(m_Size)) + { + // Using fixed storage, allocate new + set_value_type* pTemp=new set_value_type[Other.m_Size]; + DestStorage=pTemp; + m_Storage.m_dynSet=pTemp; + m_Size=Other.m_Size; + } + else + { + // Using dynamic storage, check if can reuse + if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size + bool operator()( Char2T Ch ) const + { + const set_value_type* Storage= + (use_fixed_storage(m_Size)) + ? &m_Storage.m_fixSet[0] + : m_Storage.m_dynSet; + + return ::std::binary_search(Storage, Storage+m_Size, Ch); + } + private: + // check if the size is eligible for fixed storage + static bool use_fixed_storage(std::size_t size) + { + return size<=sizeof(set_value_type*)*2; + } + + + private: + // storage + // The actual used storage is selected on the type + union + { + set_value_type* m_dynSet; + set_value_type m_fixSet[sizeof(set_value_type*)*2]; + } + m_Storage; + + // storage size + ::std::size_t m_Size; + }; + + // is_from_range functor + /* + returns true if the value is from the specified range. + (i.e. x>=From && x>=To) + */ + template + struct is_from_rangeF : + public predicate_facade< is_from_rangeF > + { + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {} + + // Operation + template + bool operator()( Char2T Ch ) const + { + return ( m_From <= Ch ) && ( Ch <= m_To ); + } + + private: + CharT m_From; + CharT m_To; + }; + + // class_and composition predicate + template + struct pred_andF : + public predicate_facade< pred_andF > + { + public: + + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + pred_andF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) && m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_or composition predicate + template + struct pred_orF : + public predicate_facade< pred_orF > + { + public: + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + pred_orF( Pred1T Pred1, Pred2T Pred2 ) : + m_Pred1(Pred1), m_Pred2(Pred2) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return m_Pred1(Ch) || m_Pred2(Ch); + } + + private: + Pred1T m_Pred1; + Pred2T m_Pred2; + }; + + // class_not composition predicate + template< typename PredT > + struct pred_notF : + public predicate_facade< pred_notF > + { + public: + // Boost.ResultOf support + typedef bool result_type; + + // Constructor + pred_notF( PredT Pred ) : m_Pred(Pred) {} + + // Operation + template + bool operator()( CharT Ch ) const + { + return !m_Pred(Ch); + } + + private: + PredT m_Pred; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/find_format.hpp b/src/vendor/boost/algorithm/string/detail/find_format.hpp new file mode 100644 index 000000000..b39875024 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/find_format.hpp @@ -0,0 +1,204 @@ +// Boost string_algo library find_format.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_format_copy (iterator variant) implementation -------------------------------// + + template< + typename OutputIteratorT, + typename InputT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline OutputIteratorT find_format_copy_impl2( + OutputIteratorT Output, + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult ) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + range_const_iterator::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Match not found - return original sequence + Output = std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); + return Output; + } + + // Copy the beginning of the sequence + Output = std::copy( ::boost::begin(Input), ::boost::begin(M), Output ); + // Format find result + // Copy formatted result + Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output ); + // Copy the rest of the sequence + Output = std::copy( M.end(), ::boost::end(Input), Output ); + + return Output; + } + + template< + typename OutputIteratorT, + typename InputT, + typename FormatterT, + typename FindResultT > + inline OutputIteratorT find_format_copy_impl( + OutputIteratorT Output, + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult ) + { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { + return ::boost::algorithm::detail::find_format_copy_impl2( + Output, + Input, + Formatter, + FindResult, + Formatter(FindResult) ); + } else { + return std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); + } + } + + +// find_format_copy implementation --------------------------------------------------// + + template< + typename InputT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline InputT find_format_copy_impl2( + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + range_const_iterator::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Match not found - return original sequence + return InputT( Input ); + } + + InputT Output; + // Copy the beginning of the sequence + boost::algorithm::detail::insert( Output, ::boost::end(Output), ::boost::begin(Input), M.begin() ); + // Copy formatted result + boost::algorithm::detail::insert( Output, ::boost::end(Output), M.format_result() ); + // Copy the rest of the sequence + boost::algorithm::detail::insert( Output, ::boost::end(Output), M.end(), ::boost::end(Input) ); + + return Output; + } + + template< + typename InputT, + typename FormatterT, + typename FindResultT > + inline InputT find_format_copy_impl( + const InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult) + { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { + return ::boost::algorithm::detail::find_format_copy_impl2( + Input, + Formatter, + FindResult, + Formatter(FindResult) ); + } else { + return Input; + } + } + + // replace implementation ----------------------------------------------------// + + template< + typename InputT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline void find_format_impl2( + InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef find_format_store< + BOOST_STRING_TYPENAME + range_iterator::type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + if ( !M ) + { + // Search not found - return original sequence + return; + } + + // Replace match + ::boost::algorithm::detail::replace( Input, M.begin(), M.end(), M.format_result() ); + } + + template< + typename InputT, + typename FormatterT, + typename FindResultT > + inline void find_format_impl( + InputT& Input, + FormatterT Formatter, + const FindResultT& FindResult) + { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { + ::boost::algorithm::detail::find_format_impl2( + Input, + Formatter, + FindResult, + Formatter(FindResult) ); + } + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/find_format_all.hpp b/src/vendor/boost/algorithm/string/detail/find_format_all.hpp new file mode 100644 index 000000000..311fa26ff --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/find_format_all.hpp @@ -0,0 +1,275 @@ +// Boost string_algo library find_format_all.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_format_all_copy (iterator variant) implementation ---------------------------// + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline OutputIteratorT find_format_all_copy_impl2( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult ) + { + typedef BOOST_STRING_TYPENAME + range_const_iterator::type input_iterator_type; + + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Initialize last match + input_iterator_type LastMatch=::boost::begin(Input); + + // Iterate through all matches + while( M ) + { + // Copy the beginning of the sequence + Output = std::copy( LastMatch, M.begin(), Output ); + // Copy formatted result + Output = std::copy( ::boost::begin(M.format_result()), ::boost::end(M.format_result()), Output ); + + // Proceed to the next match + LastMatch=M.end(); + M=Finder( LastMatch, ::boost::end(Input) ); + } + + // Copy the rest of the sequence + Output = std::copy( LastMatch, ::boost::end(Input), Output ); + + return Output; + } + + template< + typename OutputIteratorT, + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline OutputIteratorT find_format_all_copy_impl( + OutputIteratorT Output, + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult ) + { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { + return ::boost::algorithm::detail::find_format_all_copy_impl2( + Output, + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } else { + return std::copy( ::boost::begin(Input), ::boost::end(Input), Output ); + } + } + + // find_format_all_copy implementation ----------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline InputT find_format_all_copy_impl2( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult, + const FormatResultT& FormatResult) + { + typedef BOOST_STRING_TYPENAME + range_const_iterator::type input_iterator_type; + + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Initialize last match + input_iterator_type LastMatch=::boost::begin(Input); + + // Output temporary + InputT Output; + + // Iterate through all matches + while( M ) + { + // Copy the beginning of the sequence + boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, M.begin() ); + // Copy formatted result + boost::algorithm::detail::insert( Output, ::boost::end(Output), M.format_result() ); + + // Proceed to the next match + LastMatch=M.end(); + M=Finder( LastMatch, ::boost::end(Input) ); + } + + // Copy the rest of the sequence + ::boost::algorithm::detail::insert( Output, ::boost::end(Output), LastMatch, ::boost::end(Input) ); + + return Output; + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline InputT find_format_all_copy_impl( + const InputT& Input, + FinderT Finder, + FormatterT Formatter, + const FindResultT& FindResult) + { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { + return ::boost::algorithm::detail::find_format_all_copy_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } else { + return Input; + } + } + + // find_format_all implementation ------------------------------------------------// + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT, + typename FormatResultT > + inline void find_format_all_impl2( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + FindResultT FindResult, + FormatResultT FormatResult) + { + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef find_format_store< + input_iterator_type, + FormatterT, + FormatResultT > store_type; + + // Create store for the find result + store_type M( FindResult, FormatResult, Formatter ); + + // Instantiate replacement storage + std::deque< + BOOST_STRING_TYPENAME range_value::type> Storage; + + // Initialize replacement iterators + input_iterator_type InsertIt=::boost::begin(Input); + input_iterator_type SearchIt=::boost::begin(Input); + + while( M ) + { + // process the segment + InsertIt=process_segment( + Storage, + Input, + InsertIt, + SearchIt, + M.begin() ); + + // Adjust search iterator + SearchIt=M.end(); + + // Copy formatted replace to the storage + ::boost::algorithm::detail::copy_to_storage( Storage, M.format_result() ); + + // Find range for a next match + M=Finder( SearchIt, ::boost::end(Input) ); + } + + // process the last segment + InsertIt=::boost::algorithm::detail::process_segment( + Storage, + Input, + InsertIt, + SearchIt, + ::boost::end(Input) ); + + if ( Storage.empty() ) + { + // Truncate input + ::boost::algorithm::detail::erase( Input, InsertIt, ::boost::end(Input) ); + } + else + { + // Copy remaining data to the end of input + ::boost::algorithm::detail::insert( Input, ::boost::end(Input), Storage.begin(), Storage.end() ); + } + } + + template< + typename InputT, + typename FinderT, + typename FormatterT, + typename FindResultT > + inline void find_format_all_impl( + InputT& Input, + FinderT Finder, + FormatterT Formatter, + FindResultT FindResult) + { + if( ::boost::algorithm::detail::check_find_result(Input, FindResult) ) { + ::boost::algorithm::detail::find_format_all_impl2( + Input, + Finder, + Formatter, + FindResult, + Formatter(FindResult) ); + } + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/find_format_store.hpp b/src/vendor/boost/algorithm/string/detail/find_format_store.hpp new file mode 100644 index 000000000..b9f4a88d9 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/find_format_store.hpp @@ -0,0 +1,89 @@ +// Boost string_algo library find_format_store.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP +#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// temporary format and find result storage --------------------------------// + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(push) +#pragma warning(disable:4512) //assignment operator could not be generated +#endif + template< + typename ForwardIteratorT, + typename FormatterT, + typename FormatResultT > + class find_format_store : + public iterator_range + { + public: + // typedefs + typedef iterator_range base_type; + typedef FormatterT formatter_type; + typedef FormatResultT format_result_type; + + public: + // Construction + find_format_store( + const base_type& FindResult, + const format_result_type& FormatResult, + const formatter_type& Formatter ) : + base_type(FindResult), + m_FormatResult(FormatResult), + m_Formatter(Formatter) {} + + // Assignment + template< typename FindResultT > + find_format_store& operator=( FindResultT FindResult ) + { + iterator_range::operator=(FindResult); + if( !this->empty() ) { + m_FormatResult=m_Formatter(FindResult); + } + + return *this; + } + + // Retrieve format result + const format_result_type& format_result() + { + return m_FormatResult; + } + + private: + format_result_type m_FormatResult; + const formatter_type& m_Formatter; + }; + + template + bool check_find_result(InputT&, FindResultT& FindResult) + { + typedef BOOST_STRING_TYPENAME + range_const_iterator::type input_iterator_type; + iterator_range ResultRange(FindResult); + return !ResultRange.empty(); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +#pragma warning(pop) +#endif + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/find_iterator.hpp b/src/vendor/boost/algorithm/string/detail/find_iterator.hpp new file mode 100644 index 000000000..4f90a98fc --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/find_iterator.hpp @@ -0,0 +1,87 @@ +// Boost string_algo library find_iterator.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_ITERATOR_DETAIL_HPP +#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// find_iterator base -----------------------------------------------// + + // Find iterator base + template + class find_iterator_base + { + protected: + // typedefs + typedef IteratorT input_iterator_type; + typedef iterator_range match_type; + typedef function2< + match_type, + input_iterator_type, + input_iterator_type> finder_type; + + protected: + // Protected construction/destruction + + // Default constructor + find_iterator_base() {} + // Copy construction + find_iterator_base( const find_iterator_base& Other ) : + m_Finder(Other.m_Finder) {} + + // Constructor + template + find_iterator_base( FinderT Finder, int ) : + m_Finder(Finder) {} + + // Destructor + ~find_iterator_base() {} + + // Find operation + match_type do_find( + input_iterator_type Begin, + input_iterator_type End ) const + { + if (!m_Finder.empty()) + { + return m_Finder(Begin,End); + } + else + { + return match_type(End,End); + } + } + + // Check + bool is_null() const + { + return m_Finder.empty(); + } + + private: + // Finder + finder_type m_Finder; + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/finder.hpp b/src/vendor/boost/algorithm/string/detail/finder.hpp new file mode 100644 index 000000000..8e70240de --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/finder.hpp @@ -0,0 +1,639 @@ +// Boost string_algo library finder.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_DETAIL_HPP +#define BOOST_STRING_FINDER_DETAIL_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + + +// find first functor -----------------------------------------------// + + // find a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, functor returns + */ + template + struct first_finderF + { + typedef SearchIteratorT search_iterator_type; + + // Construction + template< typename SearchT > + first_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {} + first_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=Begin; + OuterIt!=End; + ++OuterIt) + { + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + input_iterator_type InnerIt=OuterIt; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if ( SubstrIt==m_Search.end() ) + return result_type( OuterIt, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find last functor -----------------------------------------------// + + // find the last match a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct last_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + + // Construction + template< typename SearchT > + last_finderF( const SearchT& Search, PredicateT Comp ) : + m_Search(::boost::begin(Search), ::boost::end(Search)), m_Comp(Comp) {} + last_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + PredicateT Comp ) : + m_Search(SearchBegin, SearchEnd), m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + if( boost::empty(m_Search) ) + return result_type( End, End ); + + typedef BOOST_STRING_TYPENAME + std::iterator_traits::iterator_category category; + + return findit( Begin, End, category() ); + } + + private: + // forward iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::forward_iterator_tag ) const + { + typedef iterator_range result_type; + + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M=first_finder( Begin, End ); + result_type Last=M; + + while( M ) + { + Last=M; + M=first_finder( ::boost::end(M), End ); + } + + return Last; + } + + // bidirectional iterator + template< typename ForwardIteratorT > + iterator_range + findit( + ForwardIteratorT Begin, + ForwardIteratorT End, + std::bidirectional_iterator_tag ) const + { + typedef iterator_range result_type; + typedef ForwardIteratorT input_iterator_type; + + // Outer loop + for(input_iterator_type OuterIt=End; + OuterIt!=Begin; ) + { + input_iterator_type OuterIt2=--OuterIt; + + input_iterator_type InnerIt=OuterIt2; + search_iterator_type SubstrIt=m_Search.begin(); + for(; + InnerIt!=End && SubstrIt!=m_Search.end(); + ++InnerIt,++SubstrIt) + { + if( !( m_Comp(*InnerIt,*SubstrIt) ) ) + break; + } + + // Substring matching succeeded + if( SubstrIt==m_Search.end() ) + return result_type( OuterIt2, InnerIt ); + } + + return result_type( End, End ); + } + + private: + iterator_range m_Search; + PredicateT m_Comp; + }; + +// find n-th functor -----------------------------------------------// + + // find the n-th match of a subsequence in the sequence ( functor ) + /* + Returns a pair marking the subsequence in the sequence. + If the find fails, returns + */ + template + struct nth_finderF + { + typedef SearchIteratorT search_iterator_type; + typedef first_finderF< + search_iterator_type, + PredicateT> first_finder_type; + typedef last_finderF< + search_iterator_type, + PredicateT> last_finder_type; + + // Construction + template< typename SearchT > + nth_finderF( + const SearchT& Search, + int Nth, + PredicateT Comp) : + m_Search(::boost::begin(Search), ::boost::end(Search)), + m_Nth(Nth), + m_Comp(Comp) {} + nth_finderF( + search_iterator_type SearchBegin, + search_iterator_type SearchEnd, + int Nth, + PredicateT Comp) : + m_Search(SearchBegin, SearchEnd), + m_Nth(Nth), + m_Comp(Comp) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_Nth>=0) + { + return find_forward(Begin, End, m_Nth); + } + else + { + return find_backward(Begin, End, -m_Nth); + } + + } + + private: + // Implementation helpers + template< typename ForwardIteratorT > + iterator_range + find_forward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef iterator_range result_type; + + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find functor + first_finder_type first_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( Begin, Begin ); + + for( unsigned int n=0; n<=N; ++n ) + { + // find next match + M=first_finder( ::boost::end(M), End ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + template< typename ForwardIteratorT > + iterator_range + find_backward( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N) const + { + typedef iterator_range result_type; + + // Sanity check + if( boost::empty(m_Search) ) + return result_type( End, End ); + + // Instantiate find functor + last_finder_type last_finder( + m_Search.begin(), m_Search.end(), m_Comp ); + + result_type M( End, End ); + + for( unsigned int n=1; n<=N; ++n ) + { + // find next match + M=last_finder( Begin, ::boost::begin(M) ); + + if ( !M ) + { + // Subsequence not found, return + return M; + } + } + + return M; + } + + + private: + iterator_range m_Search; + int m_Nth; + PredicateT m_Comp; + }; + +// find head/tail implementation helpers ---------------------------// + + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=Begin; + for( unsigned int Index=0; Index + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type(Begin,Begin+N); + } + + // Find head implementation + template + iterator_range + find_head_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME + std::iterator_traits::iterator_category category; + + return ::boost::algorithm::detail::find_head_impl( Begin, End, N, category() ); + } + + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::forward_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + unsigned int Index=0; + input_iterator_type It=Begin; + input_iterator_type It2=Begin; + + // Advance It2 by N increments + for( Index=0; Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::bidirectional_iterator_tag ) + { + typedef ForwardIteratorT input_iterator_type; + typedef iterator_range result_type; + + input_iterator_type It=End; + for( unsigned int Index=0; Index + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N, + std::random_access_iterator_tag ) + { + typedef iterator_range result_type; + + if ( (End<=Begin) || ( static_cast(End-Begin) < N ) ) + return result_type( Begin, End ); + + return result_type( End-N, End ); + } + + // Operation + template< typename ForwardIteratorT > + iterator_range + find_tail_impl( + ForwardIteratorT Begin, + ForwardIteratorT End, + unsigned int N ) + { + typedef BOOST_STRING_TYPENAME + std::iterator_traits::iterator_category category; + + return ::boost::algorithm::detail::find_tail_impl( Begin, End, N, category() ); + } + + + +// find head functor -----------------------------------------------// + + + // find a head in the sequence ( functor ) + /* + This functor find a head of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct head_finderF + { + // Construction + head_finderF( int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_N>=0) + { + return ::boost::algorithm::detail::find_head_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + ::boost::algorithm::detail::find_tail_impl( Begin, End, -m_N ); + + return ::boost::make_iterator_range(Begin, Res.begin()); + } + } + + private: + int m_N; + }; + +// find tail functor -----------------------------------------------// + + + // find a tail in the sequence ( functor ) + /* + This functor find a tail of the specified range. For + a specified N, the head is a subsequence of N starting + elements of the range. + */ + struct tail_finderF + { + // Construction + tail_finderF( int N ) : m_N(N) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + if(m_N>=0) + { + return ::boost::algorithm::detail::find_tail_impl( Begin, End, m_N ); + } + else + { + iterator_range Res= + ::boost::algorithm::detail::find_head_impl( Begin, End, -m_N ); + + return ::boost::make_iterator_range(Res.end(), End); + } + } + + private: + int m_N; + }; + +// find token functor -----------------------------------------------// + + // find a token in a sequence ( functor ) + /* + This find functor finds a token specified be a predicate + in a sequence. It is equivalent of std::find algorithm, + with an exception that it return range instead of a single + iterator. + + If bCompress is set to true, adjacent matching tokens are + concatenated into one match. + */ + template< typename PredicateT > + struct token_finderF + { + // Construction + token_finderF( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) : + m_Pred(Pred), m_eCompress(eCompress) {} + + // Operation + template< typename ForwardIteratorT > + iterator_range + operator()( + ForwardIteratorT Begin, + ForwardIteratorT End ) const + { + typedef iterator_range result_type; + + ForwardIteratorT It=std::find_if( Begin, End, m_Pred ); + + if( It==End ) + { + return result_type( End, End ); + } + else + { + ForwardIteratorT It2=It; + + if( m_eCompress==token_compress_on ) + { + // Find first non-matching character + while( It2!=End && m_Pred(*It2) ) ++It2; + } + else + { + // Advance by one position + ++It2; + } + + return result_type( It, It2 ); + } + } + + private: + PredicateT m_Pred; + token_compress_mode_type m_eCompress; + }; + +// find range functor -----------------------------------------------// + + // find a range in the sequence ( functor ) + /* + This functor actually does not perform any find operation. + It always returns given iterator range as a result. + */ + template + struct range_finderF + { + typedef ForwardIterator1T input_iterator_type; + typedef iterator_range result_type; + + // Construction + range_finderF( + input_iterator_type Begin, + input_iterator_type End ) : m_Range(Begin, End) {} + + range_finderF(const iterator_range& Range) : + m_Range(Range) {} + + // Operation + template< typename ForwardIterator2T > + iterator_range + operator()( + ForwardIterator2T, + ForwardIterator2T ) const + { +#if BOOST_WORKAROUND( __MWERKS__, <= 0x3003 ) + return iterator_range(this->m_Range); +#else + return m_Range; +#endif + } + + private: + iterator_range m_Range; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FINDER_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/formatter.hpp b/src/vendor/boost/algorithm/string/detail/formatter.hpp new file mode 100644 index 000000000..f4c6728b3 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/formatter.hpp @@ -0,0 +1,119 @@ +// Boost string_algo library formatter.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FORMATTER_DETAIL_HPP +#define BOOST_STRING_FORMATTER_DETAIL_HPP + + +#include +#include +#include +#include + +#include + +// generic replace functors -----------------------------------------------// + +namespace boost { + namespace algorithm { + namespace detail { + +// const format functor ----------------------------------------------------// + + // constant format functor + template + struct const_formatF + { + private: + typedef BOOST_STRING_TYPENAME + range_const_iterator::type format_iterator; + typedef iterator_range result_type; + + public: + // Construction + const_formatF(const RangeT& Format) : + m_Format(::boost::begin(Format), ::boost::end(Format)) {} + + // Operation +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) + template + result_type& operator()(const Range2T&) + { + return m_Format; + } +#endif + + template + const result_type& operator()(const Range2T&) const + { + return m_Format; + } + + private: + result_type m_Format; + }; + +// identity format functor ----------------------------------------------------// + + // identity format functor + template + struct identity_formatF + { + // Operation + template< typename Range2T > + const RangeT& operator()(const Range2T& Replace) const + { + return RangeT(::boost::begin(Replace), ::boost::end(Replace)); + } + }; + +// empty format functor ( used by erase ) ------------------------------------// + + // empty format functor + template< typename CharT > + struct empty_formatF + { + template< typename ReplaceT > + empty_container operator()(const ReplaceT&) const + { + return empty_container(); + } + }; + +// dissect format functor ----------------------------------------------------// + + // dissect format functor + template + struct dissect_formatF + { + public: + // Construction + dissect_formatF(FinderT Finder) : + m_Finder(Finder) {} + + // Operation + template + inline iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> + operator()(const RangeT& Replace) const + { + return m_Finder(::boost::begin(Replace), ::boost::end(Replace)); + } + + private: + FinderT m_Finder; + }; + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_FORMATTER_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/predicate.hpp b/src/vendor/boost/algorithm/string/detail/predicate.hpp new file mode 100644 index 000000000..5acf3cc66 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/predicate.hpp @@ -0,0 +1,77 @@ +// Boost string_algo library predicate.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_DETAIL_HPP +#define BOOST_STRING_PREDICATE_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// ends_with predicate implementation ----------------------------------// + + template< + typename ForwardIterator1T, + typename ForwardIterator2T, + typename PredicateT> + inline bool ends_with_iter_select( + ForwardIterator1T Begin, + ForwardIterator1T End, + ForwardIterator2T SubBegin, + ForwardIterator2T SubEnd, + PredicateT Comp, + std::bidirectional_iterator_tag) + { + ForwardIterator1T it=End; + ForwardIterator2T pit=SubEnd; + for(;it!=Begin && pit!=SubBegin;) + { + if( !(Comp(*(--it),*(--pit))) ) + return false; + } + + return pit==SubBegin; + } + + template< + typename ForwardIterator1T, + typename ForwardIterator2T, + typename PredicateT> + inline bool ends_with_iter_select( + ForwardIterator1T Begin, + ForwardIterator1T End, + ForwardIterator2T SubBegin, + ForwardIterator2T SubEnd, + PredicateT Comp, + std::forward_iterator_tag) + { + if ( SubBegin==SubEnd ) + { + // empty subsequence check + return true; + } + + iterator_range Result + =last_finder( + ::boost::make_iterator_range(SubBegin, SubEnd), + Comp)(Begin, End); + + return !Result.empty() && Result.end()==End; + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_PREDICATE_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/replace_storage.hpp b/src/vendor/boost/algorithm/string/detail/replace_storage.hpp new file mode 100644 index 000000000..db35e4c53 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/replace_storage.hpp @@ -0,0 +1,159 @@ +// Boost string_algo library replace_storage.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP +#define BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP + +#include +#include +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// storage handling routines -----------------------------------------------// + + template< typename StorageT, typename OutputIteratorT > + inline OutputIteratorT move_from_storage( + StorageT& Storage, + OutputIteratorT DestBegin, + OutputIteratorT DestEnd ) + { + OutputIteratorT OutputIt=DestBegin; + + while( !Storage.empty() && OutputIt!=DestEnd ) + { + *OutputIt=Storage.front(); + Storage.pop_front(); + ++OutputIt; + } + + return OutputIt; + } + + template< typename StorageT, typename WhatT > + inline void copy_to_storage( + StorageT& Storage, + const WhatT& What ) + { + Storage.insert( Storage.end(), ::boost::begin(What), ::boost::end(What) ); + } + + +// process segment routine -----------------------------------------------// + + template< bool HasStableIterators > + struct process_segment_helper + { + // Optimized version of process_segment for generic sequence + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + ForwardIteratorT operator()( + StorageT& Storage, + InputT& /*Input*/, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + // Copy data from the storage until the beginning of the segment + ForwardIteratorT It=::boost::algorithm::detail::move_from_storage( Storage, InsertIt, SegmentBegin ); + + // 3 cases are possible : + // a) Storage is empty, It==SegmentBegin + // b) Storage is empty, It!=SegmentBegin + // c) Storage is not empty + + if( Storage.empty() ) + { + if( It==SegmentBegin ) + { + // Case a) everything is grand, just return end of segment + return SegmentEnd; + } + else + { + // Case b) move the segment backwards + return std::copy( SegmentBegin, SegmentEnd, It ); + } + } + else + { + // Case c) -> shift the segment to the left and keep the overlap in the storage + while( It!=SegmentEnd ) + { + // Store value into storage + Storage.push_back( *It ); + // Get the top from the storage and put it here + *It=Storage.front(); + Storage.pop_front(); + + // Advance + ++It; + } + + return It; + } + } + }; + + template<> + struct process_segment_helper< true > + { + // Optimized version of process_segment for list-like sequence + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + ForwardIteratorT operator()( + StorageT& Storage, + InputT& Input, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + + { + // Call replace to do the job + ::boost::algorithm::detail::replace( Input, InsertIt, SegmentBegin, Storage ); + // Empty the storage + Storage.clear(); + // Iterators were not changed, simply return the end of segment + return SegmentEnd; + } + }; + + // Process one segment in the replace_all algorithm + template< + typename StorageT, + typename InputT, + typename ForwardIteratorT > + inline ForwardIteratorT process_segment( + StorageT& Storage, + InputT& Input, + ForwardIteratorT InsertIt, + ForwardIteratorT SegmentBegin, + ForwardIteratorT SegmentEnd ) + { + return + process_segment_helper< + has_stable_iterators::value>()( + Storage, Input, InsertIt, SegmentBegin, SegmentEnd ); + } + + + } // namespace detail + } // namespace algorithm +} // namespace boost + +#endif // BOOST_STRING_REPLACE_STORAGE_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/sequence.hpp b/src/vendor/boost/algorithm/string/detail/sequence.hpp new file mode 100644 index 000000000..dc4740911 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/sequence.hpp @@ -0,0 +1,200 @@ +// Boost string_algo library sequence.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_DETAIL_SEQUENCE_HPP +#define BOOST_STRING_DETAIL_SEQUENCE_HPP + +#include +#include +#include +#include +#include + +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// insert helpers -------------------------------------------------// + + template< typename InputT, typename ForwardIteratorT > + inline void insert( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator At, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + Input.insert( At, Begin, End ); + } + + template< typename InputT, typename InsertT > + inline void insert( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator At, + const InsertT& Insert ) + { + ::boost::algorithm::detail::insert( Input, At, ::boost::begin(Insert), ::boost::end(Insert) ); + } + +// erase helper ---------------------------------------------------// + + // Erase a range in the sequence + /* + Returns the iterator pointing just after the erase subrange + */ + template< typename InputT > + inline typename InputT::iterator erase( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To ) + { + return Input.erase( From, To ); + } + +// replace helper implementation ----------------------------------// + + // Optimized version of replace for generic sequence containers + // Assumption: insert and erase are expensive + template< bool HasConstTimeOperations > + struct replace_const_time_helper + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + // Copy data to the container ( as much as possible ) + ForwardIteratorT InsertIt=Begin; + BOOST_STRING_TYPENAME InputT::iterator InputIt=From; + for(; InsertIt!=End && InputIt!=To; InsertIt++, InputIt++ ) + { + *InputIt=*InsertIt; + } + + if ( InsertIt!=End ) + { + // Replace sequence is longer, insert it + Input.insert( InputIt, InsertIt, End ); + } + else + { + if ( InputIt!=To ) + { + // Replace sequence is shorter, erase the rest + Input.erase( InputIt, To ); + } + } + } + }; + + template<> + struct replace_const_time_helper< true > + { + // Const-time erase and insert methods -> use them + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + BOOST_STRING_TYPENAME InputT::iterator At=Input.erase( From, To ); + if ( Begin!=End ) + { + if(!Input.empty()) + { + Input.insert( At, Begin, End ); + } + else + { + Input.insert( Input.begin(), Begin, End ); + } + } + } + }; + + // No native replace method + template< bool HasNative > + struct replace_native_helper + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + replace_const_time_helper< + boost::mpl::and_< + has_const_time_insert, + has_const_time_erase >::value >()( + Input, From, To, Begin, End ); + } + }; + + // Container has native replace method + template<> + struct replace_native_helper< true > + { + template< typename InputT, typename ForwardIteratorT > + void operator()( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + Input.replace( From, To, Begin, End ); + } + }; + +// replace helper -------------------------------------------------// + + template< typename InputT, typename ForwardIteratorT > + inline void replace( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + replace_native_helper< has_native_replace::value >()( + Input, From, To, Begin, End ); + } + + template< typename InputT, typename InsertT > + inline void replace( + InputT& Input, + BOOST_STRING_TYPENAME InputT::iterator From, + BOOST_STRING_TYPENAME InputT::iterator To, + const InsertT& Insert ) + { + if(From!=To) + { + ::boost::algorithm::detail::replace( Input, From, To, ::boost::begin(Insert), ::boost::end(Insert) ); + } + else + { + ::boost::algorithm::detail::insert( Input, From, ::boost::begin(Insert), ::boost::end(Insert) ); + } + } + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_DETAIL_SEQUENCE_HPP diff --git a/src/vendor/boost/algorithm/string/detail/trim.hpp b/src/vendor/boost/algorithm/string/detail/trim.hpp new file mode 100644 index 000000000..3bb4ef203 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/trim.hpp @@ -0,0 +1,95 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_DETAIL_HPP +#define BOOST_STRING_TRIM_DETAIL_HPP + +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// trim iterator helper -----------------------------------------------// + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::forward_iterator_tag ) + { + ForwardIteratorT TrimIt=InBegin; + + for( ForwardIteratorT It=InBegin; It!=InEnd; ++It ) + { + if ( !IsSpace(*It) ) + { + TrimIt=It; + ++TrimIt; + } + } + + return TrimIt; + } + + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end_iter_select( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace, + std::bidirectional_iterator_tag ) + { + for( ForwardIteratorT It=InEnd; It!=InBegin; ) + { + if ( !IsSpace(*(--It)) ) + return ++It; + } + + return InBegin; + } + // Search for first non matching character from the beginning of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_begin( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + ForwardIteratorT It=InBegin; + for(; It!=InEnd; ++It ) + { + if (!IsSpace(*It)) + return It; + } + + return It; + } + + // Search for first non matching character from the end of the sequence + template< typename ForwardIteratorT, typename PredicateT > + inline ForwardIteratorT trim_end( + ForwardIteratorT InBegin, + ForwardIteratorT InEnd, + PredicateT IsSpace ) + { + typedef BOOST_STRING_TYPENAME + std::iterator_traits::iterator_category category; + + return ::boost::algorithm::detail::trim_end_iter_select( InBegin, InEnd, IsSpace, category() ); + } + + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_TRIM_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/detail/util.hpp b/src/vendor/boost/algorithm/string/detail/util.hpp new file mode 100644 index 000000000..7844b6723 --- /dev/null +++ b/src/vendor/boost/algorithm/string/detail/util.hpp @@ -0,0 +1,107 @@ +// Boost string_algo library util.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_UTIL_DETAIL_HPP +#define BOOST_STRING_UTIL_DETAIL_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + namespace detail { + +// empty container -----------------------------------------------// + + // empty_container + /* + This class represents always empty container, + containing elements of type CharT. + + It is supposed to be used in a const version only + */ + template< typename CharT > + struct empty_container + { + typedef empty_container type; + typedef CharT value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef const value_type& reference; + typedef const value_type& const_reference; + typedef const value_type* iterator; + typedef const value_type* const_iterator; + + + // Operations + const_iterator begin() const + { + return reinterpret_cast(0); + } + + const_iterator end() const + { + return reinterpret_cast(0); + } + + bool empty() const + { + return false; + } + + size_type size() const + { + return 0; + } + }; + +// bounded copy algorithm -----------------------------------------------// + + // Bounded version of the std::copy algorithm + template + inline OutputIteratorT bounded_copy( + InputIteratorT First, + InputIteratorT Last, + OutputIteratorT DestFirst, + OutputIteratorT DestLast ) + { + InputIteratorT InputIt=First; + OutputIteratorT OutputIt=DestFirst; + for(; InputIt!=Last && OutputIt!=DestLast; InputIt++, OutputIt++ ) + { + *OutputIt=*InputIt; + } + + return OutputIt; + } + +// iterator range utilities -----------------------------------------// + + // copy range functor + template< + typename SeqT, + typename IteratorT=BOOST_STRING_TYPENAME SeqT::const_iterator > + struct copy_iterator_rangeF + { + typedef iterator_range argument_type; + typedef SeqT result_type; + SeqT operator()( const iterator_range& Range ) const + { + return copy_range(Range); + } + }; + + } // namespace detail + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_UTIL_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/erase.hpp b/src/vendor/boost/algorithm/string/erase.hpp new file mode 100644 index 000000000..688379097 --- /dev/null +++ b/src/vendor/boost/algorithm/string/erase.hpp @@ -0,0 +1,844 @@ +// Boost string_algo library erase.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ERASE_HPP +#define BOOST_STRING_ERASE_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines various erase algorithms. Each algorithm removes + part(s) of the input according to a searching criteria. +*/ + +namespace boost { + namespace algorithm { + +// erase_range -------------------------------------------------------// + + //! Erase range algorithm + /*! + Remove the given range from the input. The result is a modified copy of + the input. It is returned as a sequence or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param SearchRange A range in the input to be removed + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT erase_range_copy( + OutputIteratorT Output, + const RangeT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::range_finder(SearchRange), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase range algorithm + /*! + \overload + */ + template + inline SequenceT erase_range_copy( + const SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::range_finder(SearchRange), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase range algorithm + /*! + Remove the given range from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param SearchRange A range in the input to be removed + */ + template + inline void erase_range( + SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_iterator::type>& SearchRange ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::range_finder(SearchRange), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_first --------------------------------------------------------// + + //! Erase first algorithm + /*! + Remove the first occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase first algorithm + /*! + \overload + */ + template + inline SequenceT erase_first_copy( + const SequenceT& Input, + const RangeT& Search ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase first algorithm + /*! + Remove the first occurrence of the substring from the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for. + */ + template + inline void erase_first( + SequenceT& Input, + const RangeT& Search ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_first ( case insensitive ) ------------------------------------// + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase first algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ierase_first_copy( + const SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase first algorithm ( case insensitive ) + /*! + Remove the first occurrence of the substring from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_first( + SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_last --------------------------------------------------------// + + //! Erase last algorithm + /*! + Remove the last occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::last_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase last algorithm + /*! + \overload + */ + template + inline SequenceT erase_last_copy( + const SequenceT& Input, + const RangeT& Search ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::last_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase last algorithm + /*! + Remove the last occurrence of the substring from the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + */ + template + inline void erase_last( + SequenceT& Input, + const RangeT& Search ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::last_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_last ( case insensitive ) ------------------------------------// + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last occurrence of the substring from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::last_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase last algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ierase_last_copy( + const SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::last_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase last algorithm ( case insensitive ) + /*! + Remove the last occurrence of the substring from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_last( + SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::last_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_nth --------------------------------------------------------------------// + + //! Erase nth algorithm + /*! + Remove the Nth occurrence of the substring in the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::nth_finder(Search, Nth), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + \overload + */ + template + inline SequenceT erase_nth_copy( + const SequenceT& Input, + const RangeT& Search, + int Nth ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::nth_finder(Search, Nth), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth occurrence of the substring in the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + */ + template + inline void erase_nth( + SequenceT& Input, + const RangeT& Search, + int Nth ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::nth_finder(Search, Nth), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_nth ( case insensitive ) ---------------------------------------------// + + //! Erase nth algorithm ( case insensitive ) + /*! + Remove the Nth occurrence of the substring in the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + \overload + */ + template + inline SequenceT ierase_nth_copy( + const SequenceT& Input, + const RangeT& Search, + int Nth, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)), + empty_formatter(Input) ); + } + + //! Erase nth algorithm + /*! + Remove the Nth occurrence of the substring in the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for. + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_nth( + SequenceT& Input, + const RangeT& Search, + int Nth, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + +// erase_all --------------------------------------------------------// + + //! Erase all algorithm + /*! + Remove all the occurrences of the string from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param Search A substring to be searched for. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT erase_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search ) + { + return ::boost::algorithm::find_format_all_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase all algorithm + /*! + \overload + */ + template + inline SequenceT erase_all_copy( + const SequenceT& Input, + const RangeT& Search ) + { + return ::boost::algorithm::find_format_all_copy( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase all algorithm + /*! + Remove all the occurrences of the string from the input. + The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for. + */ + template + inline void erase_all( + SequenceT& Input, + const RangeT& Search ) + { + ::boost::algorithm::find_format_all( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_all ( case insensitive ) ------------------------------------// + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the string from the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT ierase_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_all_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase all algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ierase_all_copy( + const SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_all_copy( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + + //! Erase all algorithm ( case insensitive ) + /*! + Remove all the occurrences of the string from the input. + The input sequence is modified in-place. Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + */ + template + inline void ierase_all( + SequenceT& Input, + const RangeT& Search, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format_all( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::empty_formatter(Input) ); + } + +// erase_head --------------------------------------------------------------------// + + //! Erase head algorithm + /*! + Remove the head from the input. The head is a prefix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the head. The result is a modified copy of the input. + It is returned as a sequence or copied to the output iterator. + + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT> + inline OutputIteratorT erase_head_copy( + OutputIteratorT Output, + const RangeT& Input, + int N ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::head_finder(N), + ::boost::algorithm::empty_formatter( Input ) ); + } + + //! Erase head algorithm + /*! + \overload + */ + template + inline SequenceT erase_head_copy( + const SequenceT& Input, + int N ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::head_finder(N), + ::boost::algorithm::empty_formatter( Input ) ); + } + + //! Erase head algorithm + /*! + Remove the head from the input. The head is a prefix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the head. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the head + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + */ + template + inline void erase_head( + SequenceT& Input, + int N ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::head_finder(N), + ::boost::algorithm::empty_formatter( Input ) ); + } + +// erase_tail --------------------------------------------------------------------// + + //! Erase tail algorithm + /*! + Remove the tail from the input. The tail is a suffix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the tail. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT> + inline OutputIteratorT erase_tail_copy( + OutputIteratorT Output, + const RangeT& Input, + int N ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::tail_finder(N), + ::boost::algorithm::empty_formatter( Input ) ); + } + + //! Erase tail algorithm + /*! + \overload + */ + template + inline SequenceT erase_tail_copy( + const SequenceT& Input, + int N ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::tail_finder(N), + ::boost::algorithm::empty_formatter( Input ) ); + } + + //! Erase tail algorithm + /*! + Remove the tail from the input. The tail is a suffix of a sequence of given size. + If the sequence is shorter then required, the whole string is + considered to be the tail. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the tail + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + */ + template + inline void erase_tail( + SequenceT& Input, + int N ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::tail_finder(N), + ::boost::algorithm::empty_formatter( Input ) ); + } + + } // namespace algorithm + + // pull names into the boost namespace + using algorithm::erase_range_copy; + using algorithm::erase_range; + using algorithm::erase_first_copy; + using algorithm::erase_first; + using algorithm::ierase_first_copy; + using algorithm::ierase_first; + using algorithm::erase_last_copy; + using algorithm::erase_last; + using algorithm::ierase_last_copy; + using algorithm::ierase_last; + using algorithm::erase_nth_copy; + using algorithm::erase_nth; + using algorithm::ierase_nth_copy; + using algorithm::ierase_nth; + using algorithm::erase_all_copy; + using algorithm::erase_all; + using algorithm::ierase_all_copy; + using algorithm::ierase_all; + using algorithm::erase_head_copy; + using algorithm::erase_head; + using algorithm::erase_tail_copy; + using algorithm::erase_tail; + +} // namespace boost + + +#endif // BOOST_ERASE_HPP diff --git a/src/vendor/boost/algorithm/string/find.hpp b/src/vendor/boost/algorithm/string/find.hpp new file mode 100644 index 000000000..f2c2926b5 --- /dev/null +++ b/src/vendor/boost/algorithm/string/find.hpp @@ -0,0 +1,334 @@ +// Boost string_algo library find.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_HPP +#define BOOST_STRING_FIND_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines a set of find algorithms. The algorithms are searching + for a substring of the input. The result is given as an \c iterator_range + delimiting the substring. +*/ + +namespace boost { + namespace algorithm { + +// Generic find -----------------------------------------------// + + //! Generic find algorithm + /*! + Search the input using the given finder. + + \param Input A string which will be searched. + \param Finder Finder object used for searching. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find( + RangeT& Input, + const FinderT& Finder) + { + iterator_range::type> lit_input(::boost::as_literal(Input)); + + return Finder(::boost::begin(lit_input),::boost::end(lit_input)); + } + +// find_first -----------------------------------------------// + + //! Find first algorithm + /*! + Search for the first occurrence of the substring in the input. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_first( + Range1T& Input, + const Range2T& Search) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::first_finder(Search)); + } + + //! Find first algorithm ( case insensitive ) + /*! + Search for the first occurrence of the substring in the input. + Searching is case insensitive. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + ifind_first( + Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::first_finder(Search,is_iequal(Loc))); + } + +// find_last -----------------------------------------------// + + //! Find last algorithm + /*! + Search for the last occurrence of the substring in the input. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_last( + Range1T& Input, + const Range2T& Search) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::last_finder(Search)); + } + + //! Find last algorithm ( case insensitive ) + /*! + Search for the last match a string in the input. + Searching is case insensitive. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + ifind_last( + Range1T& Input, + const Range2T& Search, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::last_finder(Search, is_iequal(Loc))); + } + +// find_nth ----------------------------------------------------------------------// + + //! Find n-th algorithm + /*! + Search for the n-th (zero-indexed) occurrence of the substring in the + input. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Nth An index (zero-indexed) of the match to be found. + For negative N, the matches are counted from the end of string. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_nth( + Range1T& Input, + const Range2T& Search, + int Nth) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::nth_finder(Search,Nth)); + } + + //! Find n-th algorithm ( case insensitive ). + /*! + Search for the n-th (zero-indexed) occurrence of the substring in the + input. Searching is case insensitive. + + \param Input A string which will be searched. + \param Search A substring to be searched for. + \param Nth An index (zero-indexed) of the match to be found. + For negative N, the matches are counted from the end of string. + \param Loc A locale used for case insensitive comparison + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + ifind_nth( + Range1T& Input, + const Range2T& Search, + int Nth, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::nth_finder(Search,Nth,is_iequal(Loc))); + } + +// find_head ----------------------------------------------------------------------// + + //! Find head algorithm + /*! + Get the head of the input. Head is a prefix of the string of the + given size. If the input is shorter then required, whole input is considered + to be the head. + + \param Input An input string + \param N Length of the head + For N>=0, at most N characters are extracted. + For N<0, at most size(Input)-|N| characters are extracted. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c Range1T::iterator or + \c Range1T::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_head( + RangeT& Input, + int N) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::head_finder(N)); + } + +// find_tail ----------------------------------------------------------------------// + + //! Find tail algorithm + /*! + Get the tail of the input. Tail is a suffix of the string of the + given size. If the input is shorter then required, whole input is considered + to be the tail. + + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, at most size(Input)-|N| characters are extracted. + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_tail( + RangeT& Input, + int N) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::tail_finder(N)); + } + +// find_token --------------------------------------------------------------------// + + //! Find token algorithm + /*! + Look for a given token in the string. Token is a character that matches the + given predicate. + If the "token compress mode" is enabled, adjacent tokens are considered to be one match. + + \param Input A input string. + \param Pred A unary predicate to identify a token + \param eCompress Enable/Disable compressing of adjacent tokens + \return + An \c iterator_range delimiting the match. + Returned iterator is either \c RangeT::iterator or + \c RangeT::const_iterator, depending on the constness of + the input parameter. + + \note This function provides the strong exception-safety guarantee + */ + template + inline iterator_range< + BOOST_STRING_TYPENAME range_iterator::type> + find_token( + RangeT& Input, + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off) + { + return ::boost::algorithm::find(Input, ::boost::algorithm::token_finder(Pred, eCompress)); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find; + using algorithm::find_first; + using algorithm::ifind_first; + using algorithm::find_last; + using algorithm::ifind_last; + using algorithm::find_nth; + using algorithm::ifind_nth; + using algorithm::find_head; + using algorithm::find_tail; + using algorithm::find_token; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_HPP diff --git a/src/vendor/boost/algorithm/string/find_format.hpp b/src/vendor/boost/algorithm/string/find_format.hpp new file mode 100644 index 000000000..4d9315cb1 --- /dev/null +++ b/src/vendor/boost/algorithm/string/find_format.hpp @@ -0,0 +1,286 @@ +// Boost string_algo library find_format.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_FORMAT_HPP +#define BOOST_STRING_FIND_FORMAT_HPP + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines generic replace algorithms. Each algorithm replaces + part(s) of the input. The part to be replaced is looked up using a Finder object. + Result of finding is then used by a Formatter object to generate the replacement. +*/ + +namespace boost { + namespace algorithm { + +// generic replace -----------------------------------------------------------------// + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename FinderT, + typename FormatterT> + inline OutputIteratorT find_format_copy( + OutputIteratorT Output, + const RangeT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_const_iterator::type> + )); + BOOST_CONCEPT_ASSERT(( + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> + )); + + iterator_range::type> lit_input(::boost::as_literal(Input)); + + return detail::find_format_copy_impl( + Output, + lit_input, + Formatter, + Finder( ::boost::begin(lit_input), ::boost::end(lit_input) ) ); + } + + //! Generic replace algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT> + inline SequenceT find_format_copy( + const SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_const_iterator::type> + )); + BOOST_CONCEPT_ASSERT(( + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> + )); + + return detail::find_format_copy_impl( + Input, + Formatter, + Finder(::boost::begin(Input), ::boost::end(Input))); + } + + //! Generic replace algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. The input is modified in-place. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT> + inline void find_format( + SequenceT& Input, + FinderT Finder, + FormatterT Formatter) + { + // Concept check + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_const_iterator::type> + )); + BOOST_CONCEPT_ASSERT(( + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> + )); + + detail::find_format_impl( + Input, + Formatter, + Finder(::boost::begin(Input), ::boost::end(Input))); + } + + +// find_format_all generic ----------------------------------------------------------------// + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename RangeT, + typename FinderT, + typename FormatterT> + inline OutputIteratorT find_format_all_copy( + OutputIteratorT Output, + const RangeT& Input, + FinderT Finder, + FormatterT Formatter) + { + // Concept check + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_const_iterator::type> + )); + BOOST_CONCEPT_ASSERT(( + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> + )); + + iterator_range::type> lit_input(::boost::as_literal(Input)); + + return detail::find_format_all_copy_impl( + Output, + lit_input, + Finder, + Formatter, + Finder(::boost::begin(lit_input), ::boost::end(lit_input))); + } + + //! Generic replace all algorithm + /*! + \overload + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT > + inline SequenceT find_format_all_copy( + const SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_const_iterator::type> + )); + BOOST_CONCEPT_ASSERT(( + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> + )); + + return detail::find_format_all_copy_impl( + Input, + Finder, + Formatter, + Finder( ::boost::begin(Input), ::boost::end(Input) ) ); + } + + //! Generic replace all algorithm + /*! + Use the Finder to search for a substring. Use the Formatter to format + this substring and replace it in the input. Repeat this for all matching + substrings.The input is modified in-place. + + \param Input An input sequence + \param Finder A Finder object used to search for a match to be replaced + \param Formatter A Formatter object used to format a match + */ + template< + typename SequenceT, + typename FinderT, + typename FormatterT > + inline void find_format_all( + SequenceT& Input, + FinderT Finder, + FormatterT Formatter ) + { + // Concept check + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_const_iterator::type> + )); + BOOST_CONCEPT_ASSERT(( + FormatterConcept< + FormatterT, + FinderT,BOOST_STRING_TYPENAME range_const_iterator::type> + )); + + detail::find_format_all_impl( + Input, + Finder, + Formatter, + Finder(::boost::begin(Input), ::boost::end(Input))); + + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::find_format_copy; + using algorithm::find_format; + using algorithm::find_format_all_copy; + using algorithm::find_format_all; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_FORMAT_HPP diff --git a/src/vendor/boost/algorithm/string/find_iterator.hpp b/src/vendor/boost/algorithm/string/find_iterator.hpp new file mode 100644 index 000000000..5a52d92e4 --- /dev/null +++ b/src/vendor/boost/algorithm/string/find_iterator.hpp @@ -0,0 +1,388 @@ +// Boost string_algo library find_iterator.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FIND_ITERATOR_HPP +#define BOOST_STRING_FIND_ITERATOR_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +/*! \file + Defines find iterator classes. Find iterator repeatedly applies a Finder + to the specified input string to search for matches. Dereferencing + the iterator yields the current match or a range between the last and the current + match depending on the iterator used. +*/ + +namespace boost { + namespace algorithm { + +// find_iterator -----------------------------------------------// + + //! find_iterator + /*! + Find iterator encapsulates a Finder and allows + for incremental searching in a string. + Each increment moves the iterator to the next match. + + Find iterator is a readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class find_iterator : + public iterator_facade< + find_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class ::boost::iterator_core_access; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + find_iterator() {} + + //! Copy constructor + /*! + Construct a copy of the find_iterator + */ + find_iterator( const find_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_End(Other.m_End) {} + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_End(End) + { + increment(); + } + + //! Constructor + /*! + Construct new find_iterator for a given finder + and a range. + */ + template + find_iterator( + RangeT& Col, + FinderT Finder ) : + detail::find_iterator_base(Finder,0) + { + iterator_range::type> lit_col(::boost::as_literal(Col)); + m_Match=::boost::make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); + m_End=::boost::end(lit_col); + + increment(); + } + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + m_Match=this->do_find(m_Match.end(),m_End); + } + + // comparison + bool equal( const find_iterator& Other ) const + { + bool bEof=eof(); + bool bOtherEof=Other.eof(); + + return bEof || bOtherEof ? bEof==bOtherEof : + ( + m_Match==Other.m_Match && + m_End==Other.m_End + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return + this->is_null() || + ( + m_Match.begin() == m_End && + m_Match.end() == m_End + ); + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_End; + }; + + //! find iterator construction helper + /*! + * Construct a find iterator to iterate through the specified string + */ + template + inline find_iterator< + BOOST_STRING_TYPENAME range_iterator::type> + make_find_iterator( + RangeT& Collection, + FinderT Finder) + { + return find_iterator::type>( + Collection, Finder); + } + +// split iterator -----------------------------------------------// + + //! split_iterator + /*! + Split iterator encapsulates a Finder and allows + for incremental searching in a string. + Unlike the find iterator, split iterator iterates + through gaps between matches. + + Find iterator is a readable forward traversal iterator. + + Dereferencing the iterator yields an iterator_range delimiting + the current match. + */ + template + class split_iterator : + public iterator_facade< + split_iterator, + const iterator_range, + forward_traversal_tag >, + private detail::find_iterator_base + { + private: + // facade support + friend class ::boost::iterator_core_access; + + private: + // typedefs + + typedef detail::find_iterator_base base_type; + typedef BOOST_STRING_TYPENAME + base_type::input_iterator_type input_iterator_type; + typedef BOOST_STRING_TYPENAME + base_type::match_type match_type; + + public: + //! Default constructor + /*! + Construct null iterator. All null iterators are equal. + + \post eof()==true + */ + split_iterator() : + m_Next(), + m_End(), + m_bEof(true) + {} + + //! Copy constructor + /*! + Construct a copy of the split_iterator + */ + split_iterator( const split_iterator& Other ) : + base_type(Other), + m_Match(Other.m_Match), + m_Next(Other.m_Next), + m_End(Other.m_End), + m_bEof(Other.m_bEof) + {} + + //! Constructor + /*! + Construct new split_iterator for a given finder + and a range. + */ + template + split_iterator( + IteratorT Begin, + IteratorT End, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_Match(Begin,Begin), + m_Next(Begin), + m_End(End), + m_bEof(false) + { + // force the correct behavior for empty sequences and yield at least one token + if(Begin!=End) + { + increment(); + } + } + //! Constructor + /*! + Construct new split_iterator for a given finder + and a collection. + */ + template + split_iterator( + RangeT& Col, + FinderT Finder ) : + detail::find_iterator_base(Finder,0), + m_bEof(false) + { + iterator_range::type> lit_col(::boost::as_literal(Col)); + m_Match=make_iterator_range(::boost::begin(lit_col), ::boost::begin(lit_col)); + m_Next=::boost::begin(lit_col); + m_End=::boost::end(lit_col); + + // force the correct behavior for empty sequences and yield at least one token + if(m_Next!=m_End) + { + increment(); + } + } + + + private: + // iterator operations + + // dereference + const match_type& dereference() const + { + return m_Match; + } + + // increment + void increment() + { + match_type FindMatch=this->do_find( m_Next, m_End ); + + if(FindMatch.begin()==m_End && FindMatch.end()==m_End) + { + if(m_Match.end()==m_End) + { + // Mark iterator as eof + m_bEof=true; + } + } + + m_Match=match_type( m_Next, FindMatch.begin() ); + m_Next=FindMatch.end(); + } + + // comparison + bool equal( const split_iterator& Other ) const + { + bool bEof=eof(); + bool bOtherEof=Other.eof(); + + return bEof || bOtherEof ? bEof==bOtherEof : + ( + m_Match==Other.m_Match && + m_Next==Other.m_Next && + m_End==Other.m_End + ); + } + + public: + // operations + + //! Eof check + /*! + Check the eof condition. Eof condition means that + there is nothing more to be searched i.e. find_iterator + is after the last match. + */ + bool eof() const + { + return this->is_null() || m_bEof; + } + + private: + // Attributes + match_type m_Match; + input_iterator_type m_Next; + input_iterator_type m_End; + bool m_bEof; + }; + + //! split iterator construction helper + /*! + * Construct a split iterator to iterate through the specified collection + */ + template + inline split_iterator< + BOOST_STRING_TYPENAME range_iterator::type> + make_split_iterator( + RangeT& Collection, + FinderT Finder) + { + return split_iterator::type>( + Collection, Finder); + } + + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_iterator; + using algorithm::make_find_iterator; + using algorithm::split_iterator; + using algorithm::make_split_iterator; + +} // namespace boost + + +#endif // BOOST_STRING_FIND_ITERATOR_HPP diff --git a/src/vendor/boost/algorithm/string/finder.hpp b/src/vendor/boost/algorithm/string/finder.hpp new file mode 100644 index 000000000..61f6e4155 --- /dev/null +++ b/src/vendor/boost/algorithm/string/finder.hpp @@ -0,0 +1,266 @@ +// Boost string_algo library finder.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FINDER_HPP +#define BOOST_STRING_FINDER_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines Finder generators. Finder object is a functor which is able to + find a substring matching a specific criteria in the input. + Finders are used as a pluggable components for replace, find + and split facilities. This header contains generator functions + for finders provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// Finder generators ------------------------------------------// + + //! "First" finder + /*! + Construct the \c first_finder. The finder searches for the first + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \return An instance of the \c first_finder object + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + first_finder( const RangeT& Search ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( ::boost::as_literal(Search), is_equal() ) ; + } + + //! "First" finder + /*! + \overload + */ + template + inline detail::first_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + first_finder( + const RangeT& Search, PredicateT Comp ) + { + return + detail::first_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( ::boost::as_literal(Search), Comp ); + } + + //! "Last" finder + /*! + Construct the \c last_finder. The finder searches for the last + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \return An instance of the \c last_finder object + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + last_finder( const RangeT& Search ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( ::boost::as_literal(Search), is_equal() ); + } + //! "Last" finder + /*! + \overload + */ + template + inline detail::last_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + last_finder( const RangeT& Search, PredicateT Comp ) + { + return + detail::last_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( ::boost::as_literal(Search), Comp ) ; + } + + //! "Nth" finder + /*! + Construct the \c nth_finder. The finder searches for the n-th (zero-indexed) + occurrence of the string in a given input. + The result is given as an \c iterator_range delimiting the match. + + \param Search A substring to be searched for. + \param Nth An index of the match to be find + \return An instance of the \c nth_finder object + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + is_equal> + nth_finder( + const RangeT& Search, + int Nth) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + is_equal>( ::boost::as_literal(Search), Nth, is_equal() ) ; + } + //! "Nth" finder + /*! + \overload + */ + template + inline detail::nth_finderF< + BOOST_STRING_TYPENAME range_const_iterator::type, + PredicateT> + nth_finder( + const RangeT& Search, + int Nth, + PredicateT Comp ) + { + return + detail::nth_finderF< + BOOST_STRING_TYPENAME + range_const_iterator::type, + PredicateT>( ::boost::as_literal(Search), Nth, Comp ); + } + + //! "Head" finder + /*! + Construct the \c head_finder. The finder returns a head of a given + input. The head is a prefix of a string up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as an \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c head_finder object + */ + inline detail::head_finderF + head_finder( int N ) + { + return detail::head_finderF(N); + } + + //! "Tail" finder + /*! + Construct the \c tail_finder. The finder returns a tail of a given + input. The tail is a suffix of a string up to n elements in + size. If an input has less then n elements, whole input is + considered a head. + The result is given as an \c iterator_range delimiting the match. + + \param N The size of the head + \return An instance of the \c tail_finder object + */ + inline detail::tail_finderF + tail_finder( int N ) + { + return detail::tail_finderF(N); + } + + //! "Token" finder + /*! + Construct the \c token_finder. The finder searches for a token + specified by a predicate. It is similar to std::find_if + algorithm, with an exception that it return a range of + instead of a single iterator. + + If "compress token mode" is enabled, adjacent matching tokens are + concatenated into one match. Thus the finder can be used to + search for continuous segments of characters satisfying the + given predicate. + + The result is given as an \c iterator_range delimiting the match. + + \param Pred An element selection predicate + \param eCompress Compress flag + \return An instance of the \c token_finder object + */ + template< typename PredicateT > + inline detail::token_finderF + token_finder( + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return detail::token_finderF( Pred, eCompress ); + } + + //! "Range" finder + /*! + Construct the \c range_finder. The finder does not perform + any operation. It simply returns the given range for + any input. + + \param Begin Beginning of the range + \param End End of the range + \return An instance of the \c range_finger object + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( + ForwardIteratorT Begin, + ForwardIteratorT End ) + { + return detail::range_finderF( Begin, End ); + } + + //! "Range" finder + /*! + \overload + */ + template< typename ForwardIteratorT > + inline detail::range_finderF + range_finder( iterator_range Range ) + { + return detail::range_finderF( Range ); + } + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::first_finder; + using algorithm::last_finder; + using algorithm::nth_finder; + using algorithm::head_finder; + using algorithm::tail_finder; + using algorithm::token_finder; + using algorithm::range_finder; + +} // namespace boost + + +#endif // BOOST_STRING_FINDER_HPP diff --git a/src/vendor/boost/algorithm/string/formatter.hpp b/src/vendor/boost/algorithm/string/formatter.hpp new file mode 100644 index 000000000..0e08ae7b3 --- /dev/null +++ b/src/vendor/boost/algorithm/string/formatter.hpp @@ -0,0 +1,119 @@ +// Boost string_algo library formatter.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_FORMATTER_HPP +#define BOOST_STRING_FORMATTER_HPP + +#include +#include +#include + +#include + +/*! \file + Defines Formatter generators. Formatter is a functor which formats + a string according to given parameters. A Formatter works + in conjunction with a Finder. A Finder can provide additional information + for a specific Formatter. An example of such a cooperation is regex_finder + and regex_formatter. + + Formatters are used as pluggable components for replace facilities. + This header contains generator functions for the Formatters provided in this library. +*/ + +namespace boost { + namespace algorithm { + +// generic formatters ---------------------------------------------------------------// + + //! Constant formatter + /*! + Constructs a \c const_formatter. Const formatter always returns + the same value, regardless of the parameter. + + \param Format A predefined value used as a result for formatting + \return An instance of the \c const_formatter object. + */ + template + inline detail::const_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> > + const_formatter(const RangeT& Format) + { + return detail::const_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> >(::boost::as_literal(Format)); + } + + //! Identity formatter + /*! + Constructs an \c identity_formatter. Identity formatter always returns + the parameter. + + \return An instance of the \c identity_formatter object. + */ + template + inline detail::identity_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> > + identity_formatter() + { + return detail::identity_formatF< + iterator_range< + BOOST_STRING_TYPENAME range_const_iterator::type> >(); + } + + //! Empty formatter + /*! + Constructs an \c empty_formatter. Empty formatter always returns an empty + sequence. + + \param Input container used to select a correct value_type for the + resulting empty_container<>. + \return An instance of the \c empty_formatter object. + */ + template + inline detail::empty_formatF< + BOOST_STRING_TYPENAME range_value::type> + empty_formatter(const RangeT&) + { + return detail::empty_formatF< + BOOST_STRING_TYPENAME range_value::type>(); + } + + //! Empty formatter + /*! + Constructs a \c dissect_formatter. Dissect formatter uses a specified finder + to extract a portion of the formatted sequence. The first finder's match is returned + as a result + + \param Finder a finder used to select a portion of the formatted sequence + \return An instance of the \c dissect_formatter object. + */ + template + inline detail::dissect_formatF< FinderT > + dissect_formatter(const FinderT& Finder) + { + return detail::dissect_formatF(Finder); + } + + + } // namespace algorithm + + // pull the names to the boost namespace + using algorithm::const_formatter; + using algorithm::identity_formatter; + using algorithm::empty_formatter; + using algorithm::dissect_formatter; + +} // namespace boost + + +#endif // BOOST_FORMATTER_HPP diff --git a/src/vendor/boost/algorithm/string/iter_find.hpp b/src/vendor/boost/algorithm/string/iter_find.hpp new file mode 100644 index 000000000..d76a81989 --- /dev/null +++ b/src/vendor/boost/algorithm/string/iter_find.hpp @@ -0,0 +1,201 @@ +// Boost string_algo library iter_find.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_ITER_FIND_HPP +#define BOOST_STRING_ITER_FIND_HPP + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines generic split algorithms. Split algorithms can be + used to divide a sequence into several part according + to a given criteria. Result is given as a 'container + of containers' where elements are copies or references + to extracted parts. + + There are two algorithms provided. One iterates over matching + substrings, the other one over the gaps between these matches. +*/ + +namespace boost { + namespace algorithm { + +// iterate find ---------------------------------------------------// + + //! Iter find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + In each iteration new match is found and added to the result. + + \param Result A 'container container' to contain the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A Finder object used for searching + \return A reference to the result + + \note Prior content of the result will be overwritten. + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename FinderT > + inline SequenceSequenceT& + iter_find( + SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + RangeT&& Input, +#else + RangeT& Input, +#endif + FinderT Finder ) + { + BOOST_CONCEPT_ASSERT(( + FinderConcept< + FinderT, + BOOST_STRING_TYPENAME range_iterator::type> + )); + + iterator_range::type> lit_input(::boost::as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef find_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + range_value::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=::boost::end(lit_input); + + typedef transform_iterator + transform_iter_type; + + transform_iter_type itBegin= + ::boost::make_transform_iterator( + find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), + copy_range_type()); + + transform_iter_type itEnd= + ::boost::make_transform_iterator( + find_iterator_type(), + copy_range_type()); + + SequenceSequenceT Tmp(itBegin, itEnd); + + Result.swap(Tmp); + return Result; + } + +// iterate split ---------------------------------------------------// + + //! Split find algorithm + /*! + This algorithm executes a given finder in iteration on the input, + until the end of input is reached, or no match is found. + Iteration is done using built-in find_iterator, so the real + searching is performed only when needed. + Each match is used as a separator of segments. These segments are then + returned in the result. + + \param Result A 'container container' to contain the result of search. + Both outer and inner container must have constructor taking a pair + of iterators as an argument. + Typical type of the result is + \c std::vector> + (each element of such a vector will container a range delimiting + a match). + \param Input A container which will be searched. + \param Finder A finder object used for searching + \return A reference to the result + + \note Prior content of the result will be overwritten. + */ + template< + typename SequenceSequenceT, + typename RangeT, + typename FinderT > + inline SequenceSequenceT& + iter_split( + SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + RangeT&& Input, +#else + RangeT& Input, +#endif + FinderT Finder ) + { + BOOST_CONCEPT_ASSERT(( + FinderConcept::type> + )); + + iterator_range::type> lit_input(::boost::as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_iterator::type input_iterator_type; + typedef split_iterator find_iterator_type; + typedef detail::copy_iterator_rangeF< + BOOST_STRING_TYPENAME + range_value::type, + input_iterator_type> copy_range_type; + + input_iterator_type InputEnd=::boost::end(lit_input); + + typedef transform_iterator + transform_iter_type; + + transform_iter_type itBegin= + ::boost::make_transform_iterator( + find_iterator_type( ::boost::begin(lit_input), InputEnd, Finder ), + copy_range_type() ); + + transform_iter_type itEnd= + ::boost::make_transform_iterator( + find_iterator_type(), + copy_range_type() ); + + SequenceSequenceT Tmp(itBegin, itEnd); + + Result.swap(Tmp); + return Result; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::iter_find; + using algorithm::iter_split; + +} // namespace boost + + +#endif // BOOST_STRING_ITER_FIND_HPP diff --git a/src/vendor/boost/algorithm/string/join.hpp b/src/vendor/boost/algorithm/string/join.hpp new file mode 100644 index 000000000..b871eb44f --- /dev/null +++ b/src/vendor/boost/algorithm/string/join.hpp @@ -0,0 +1,145 @@ +// Boost string_algo library join.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_JOIN_HPP +#define BOOST_STRING_JOIN_HPP + +#include +#include +#include +#include + +/*! \file + Defines join algorithm. + + Join algorithm is a counterpart to split algorithms. + It joins strings from a 'list' by adding user defined separator. + Additionally there is a version that allows simple filtering + by providing a predicate. +*/ + +namespace boost { + namespace algorithm { + +// join --------------------------------------------------------------// + + //! Join algorithm + /*! + This algorithm joins all strings in a 'list' into one long string. + Segments are concatenated by given separator. + + \param Input A container that holds the input strings. It must be a container-of-containers. + \param Separator A string that will separate the joined segments. + \return Concatenated string. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T> + inline typename range_value::type + join( + const SequenceSequenceT& Input, + const Range1T& Separator) + { + // Define working types + typedef typename range_value::type ResultT; + typedef typename range_const_iterator::type InputIteratorT; + + // Parse input + InputIteratorT itBegin=::boost::begin(Input); + InputIteratorT itEnd=::boost::end(Input); + + // Construct container to hold the result + ResultT Result; + + // Append first element + if(itBegin!=itEnd) + { + detail::insert(Result, ::boost::end(Result), *itBegin); + ++itBegin; + } + + for(;itBegin!=itEnd; ++itBegin) + { + // Add separator + detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator)); + // Add element + detail::insert(Result, ::boost::end(Result), *itBegin); + } + + return Result; + } + +// join_if ----------------------------------------------------------// + + //! Conditional join algorithm + /*! + This algorithm joins all strings in a 'list' into one long string. + Segments are concatenated by given separator. Only segments that + satisfy the predicate will be added to the result. + + \param Input A container that holds the input strings. It must be a container-of-containers. + \param Separator A string that will separate the joined segments. + \param Pred A segment selection predicate + \return Concatenated string. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename PredicateT> + inline typename range_value::type + join_if( + const SequenceSequenceT& Input, + const Range1T& Separator, + PredicateT Pred) + { + // Define working types + typedef typename range_value::type ResultT; + typedef typename range_const_iterator::type InputIteratorT; + + // Parse input + InputIteratorT itBegin=::boost::begin(Input); + InputIteratorT itEnd=::boost::end(Input); + + // Construct container to hold the result + ResultT Result; + + // Roll to the first element that will be added + while(itBegin!=itEnd && !Pred(*itBegin)) ++itBegin; + // Add this element + if(itBegin!=itEnd) + { + detail::insert(Result, ::boost::end(Result), *itBegin); + ++itBegin; + } + + for(;itBegin!=itEnd; ++itBegin) + { + if(Pred(*itBegin)) + { + // Add separator + detail::insert(Result, ::boost::end(Result), ::boost::as_literal(Separator)); + // Add element + detail::insert(Result, ::boost::end(Result), *itBegin); + } + } + + return Result; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::join; + using algorithm::join_if; + +} // namespace boost + + +#endif // BOOST_STRING_JOIN_HPP + diff --git a/src/vendor/boost/algorithm/string/predicate.hpp b/src/vendor/boost/algorithm/string/predicate.hpp new file mode 100644 index 000000000..d7c86e8a5 --- /dev/null +++ b/src/vendor/boost/algorithm/string/predicate.hpp @@ -0,0 +1,476 @@ +// Boost string_algo library predicate.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_HPP +#define BOOST_STRING_PREDICATE_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file boost/algorithm/string/predicate.hpp + Defines string-related predicates. + The predicates determine whether a substring is contained in the input string + under various conditions: a string starts with the substring, ends with the + substring, simply contains the substring or if both strings are equal. + Additionaly the algorithm \c all() checks all elements of a container to satisfy a + condition. + + All predicates provide the strong exception guarantee. +*/ + +namespace boost { + namespace algorithm { + +// starts_with predicate -----------------------------------------------// + + //! 'Starts with' predicate + /*! + This predicate holds when the test string is a prefix of the Input. + In other words, if the input starts with the test. + When the optional predicate is specified, it is used for character-wise + comparison. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool starts_with( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(::boost::as_literal(Input)); + iterator_range::type> lit_test(::boost::as_literal(Test)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator2T; + + Iterator1T InputEnd=::boost::end(lit_input); + Iterator2T TestEnd=::boost::end(lit_test); + + Iterator1T it=::boost::begin(lit_input); + Iterator2T pit=::boost::begin(lit_test); + for(; + it!=InputEnd && pit!=TestEnd; + ++it,++pit) + { + if( !(Comp(*it,*pit)) ) + return false; + } + + return pit==TestEnd; + } + + //! 'Starts with' predicate + /*! + \overload + */ + template + inline bool starts_with( + const Range1T& Input, + const Range2T& Test) + { + return ::boost::algorithm::starts_with(Input, Test, is_equal()); + } + + //! 'Starts with' predicate ( case insensitive ) + /*! + This predicate holds when the test string is a prefix of the Input. + In other words, if the input starts with the test. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool istarts_with( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::starts_with(Input, Test, is_iequal(Loc)); + } + + +// ends_with predicate -----------------------------------------------// + + //! 'Ends with' predicate + /*! + This predicate holds when the test string is a suffix of the Input. + In other words, if the input ends with the test. + When the optional predicate is specified, it is used for character-wise + comparison. + + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool ends_with( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(::boost::as_literal(Input)); + iterator_range::type> lit_test(::boost::as_literal(Test)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + typedef BOOST_STRING_TYPENAME + std::iterator_traits::iterator_category category; + + return detail:: + ends_with_iter_select( + ::boost::begin(lit_input), + ::boost::end(lit_input), + ::boost::begin(lit_test), + ::boost::end(lit_test), + Comp, + category()); + } + + + //! 'Ends with' predicate + /*! + \overload + */ + template + inline bool ends_with( + const Range1T& Input, + const Range2T& Test) + { + return ::boost::algorithm::ends_with(Input, Test, is_equal()); + } + + //! 'Ends with' predicate ( case insensitive ) + /*! + This predicate holds when the test container is a suffix of the Input. + In other words, if the input ends with the test. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool iends_with( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::ends_with(Input, Test, is_iequal(Loc)); + } + +// contains predicate -----------------------------------------------// + + //! 'Contains' predicate + /*! + This predicate holds when the test container is contained in the Input. + When the optional predicate is specified, it is used for character-wise + comparison. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool contains( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(::boost::as_literal(Input)); + iterator_range::type> lit_test(::boost::as_literal(Test)); + + if (::boost::empty(lit_test)) + { + // Empty range is contained always + return true; + } + + // Use the temporary variable to make VACPP happy + bool bResult=(::boost::algorithm::first_finder(lit_test,Comp)(::boost::begin(lit_input), ::boost::end(lit_input))); + return bResult; + } + + //! 'Contains' predicate + /*! + \overload + */ + template + inline bool contains( + const Range1T& Input, + const Range2T& Test) + { + return ::boost::algorithm::contains(Input, Test, is_equal()); + } + + //! 'Contains' predicate ( case insensitive ) + /*! + This predicate holds when the test container is contained in the Input. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool icontains( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::contains(Input, Test, is_iequal(Loc)); + } + +// equals predicate -----------------------------------------------// + + //! 'Equals' predicate + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + When the optional predicate is specified, it is used for character-wise + comparison. + + \param Input An input sequence + \param Test A test sequence + \param Comp An element comparison predicate + \return The result of the test + + \note This is a two-way version of \c std::equal algorithm + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool equals( + const Range1T& Input, + const Range2T& Test, + PredicateT Comp) + { + iterator_range::type> lit_input(::boost::as_literal(Input)); + iterator_range::type> lit_test(::boost::as_literal(Test)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator2T; + + Iterator1T InputEnd=::boost::end(lit_input); + Iterator2T TestEnd=::boost::end(lit_test); + + Iterator1T it=::boost::begin(lit_input); + Iterator2T pit=::boost::begin(lit_test); + for(; + it!=InputEnd && pit!=TestEnd; + ++it,++pit) + { + if( !(Comp(*it,*pit)) ) + return false; + } + + return (pit==TestEnd) && (it==InputEnd); + } + + //! 'Equals' predicate + /*! + \overload + */ + template + inline bool equals( + const Range1T& Input, + const Range2T& Test) + { + return ::boost::algorithm::equals(Input, Test, is_equal()); + } + + //! 'Equals' predicate ( case insensitive ) + /*! + This predicate holds when the test container is equal to the + input container i.e. all elements in both containers are same. + Elements are compared case insensitively. + + \param Input An input sequence + \param Test A test sequence + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This is a two-way version of \c std::equal algorithm + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool iequals( + const Range1T& Input, + const Range2T& Test, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::equals(Input, Test, is_iequal(Loc)); + } + +// lexicographical_compare predicate -----------------------------// + + //! Lexicographical compare predicate + /*! + This predicate is an overload of std::lexicographical_compare + for range arguments + + It check whether the first argument is lexicographically less + then the second one. + + If the optional predicate is specified, it is used for character-wise + comparison + + \param Arg1 First argument + \param Arg2 Second argument + \param Pred Comparison predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool lexicographical_compare( + const Range1T& Arg1, + const Range2T& Arg2, + PredicateT Pred) + { + iterator_range::type> lit_arg1(::boost::as_literal(Arg1)); + iterator_range::type> lit_arg2(::boost::as_literal(Arg2)); + + return std::lexicographical_compare( + ::boost::begin(lit_arg1), + ::boost::end(lit_arg1), + ::boost::begin(lit_arg2), + ::boost::end(lit_arg2), + Pred); + } + + //! Lexicographical compare predicate + /*! + \overload + */ + template + inline bool lexicographical_compare( + const Range1T& Arg1, + const Range2T& Arg2) + { + return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_less()); + } + + //! Lexicographical compare predicate (case-insensitive) + /*! + This predicate is an overload of std::lexicographical_compare + for range arguments. + It check whether the first argument is lexicographically less + then the second one. + Elements are compared case insensitively + + + \param Arg1 First argument + \param Arg2 Second argument + \param Loc A locale used for case insensitive comparison + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool ilexicographical_compare( + const Range1T& Arg1, + const Range2T& Arg2, + const std::locale& Loc=std::locale()) + { + return ::boost::algorithm::lexicographical_compare(Arg1, Arg2, is_iless(Loc)); + } + + +// all predicate -----------------------------------------------// + + //! 'All' predicate + /*! + This predicate holds it all its elements satisfy a given + condition, represented by the predicate. + + \param Input An input sequence + \param Pred A predicate + \return The result of the test + + \note This function provides the strong exception-safety guarantee + */ + template + inline bool all( + const RangeT& Input, + PredicateT Pred) + { + iterator_range::type> lit_input(::boost::as_literal(Input)); + + typedef BOOST_STRING_TYPENAME + range_const_iterator::type Iterator1T; + + Iterator1T InputEnd=::boost::end(lit_input); + for( Iterator1T It=::boost::begin(lit_input); It!=InputEnd; ++It) + { + if (!Pred(*It)) + return false; + } + + return true; + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::starts_with; + using algorithm::istarts_with; + using algorithm::ends_with; + using algorithm::iends_with; + using algorithm::contains; + using algorithm::icontains; + using algorithm::equals; + using algorithm::iequals; + using algorithm::all; + using algorithm::lexicographical_compare; + using algorithm::ilexicographical_compare; + +} // namespace boost + + +#endif // BOOST_STRING_PREDICATE_HPP diff --git a/src/vendor/boost/algorithm/string/predicate_facade.hpp b/src/vendor/boost/algorithm/string/predicate_facade.hpp new file mode 100644 index 000000000..a9753fc2a --- /dev/null +++ b/src/vendor/boost/algorithm/string/predicate_facade.hpp @@ -0,0 +1,42 @@ +// Boost string_algo library predicate_facade.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_PREDICATE_FACADE_HPP +#define BOOST_STRING_PREDICATE_FACADE_HPP + +#include + +/* + \file boost/algorith/string/predicate_facade.hpp + This file contains predicate_facade definition. This template class is used + to identify classification predicates, so they can be combined using + composition operators. +*/ + +namespace boost { + namespace algorithm { + +// predicate facade ------------------------------------------------------// + + //! Predicate facade + /*! + This class allows to recognize classification + predicates, so that they can be combined using + composition operators. + Every classification predicate must be derived from this class. + */ + template + struct predicate_facade {}; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP diff --git a/src/vendor/boost/algorithm/string/replace.hpp b/src/vendor/boost/algorithm/string/replace.hpp new file mode 100644 index 000000000..2adb031c5 --- /dev/null +++ b/src/vendor/boost/algorithm/string/replace.hpp @@ -0,0 +1,926 @@ +// Boost string_algo library replace.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_REPLACE_HPP +#define BOOST_STRING_REPLACE_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/*! \file + Defines various replace algorithms. Each algorithm replaces + part(s) of the input according to set of searching and replace criteria. +*/ + +namespace boost { + namespace algorithm { + +// replace_range --------------------------------------------------------------------// + + //! Replace range algorithm + /*! + Replace the given range in the input string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param SearchRange A range in the input to be substituted + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT replace_range_copy( + OutputIteratorT Output, + const Range1T& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange, + const Range2T& Format) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::range_finder(SearchRange), + ::boost::algorithm::const_formatter(Format)); + } + + //! Replace range algorithm + /*! + \overload + */ + template + inline SequenceT replace_range_copy( + const SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_const_iterator::type>& SearchRange, + const RangeT& Format) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::range_finder(SearchRange), + ::boost::algorithm::const_formatter(Format)); + } + + //! Replace range algorithm + /*! + Replace the given range in the input string. + The input sequence is modified in-place. + + \param Input An input string + \param SearchRange A range in the input to be substituted + \param Format A substitute string + */ + template + inline void replace_range( + SequenceT& Input, + const iterator_range< + BOOST_STRING_TYPENAME + range_iterator::type>& SearchRange, + const RangeT& Format) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::range_finder(SearchRange), + ::boost::algorithm::const_formatter(Format)); + } + +// replace_first --------------------------------------------------------------------// + + //! Replace first algorithm + /*! + Replace the first match of the search substring in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace first algorithm + /*! + \overload + */ + template + inline SequenceT replace_first_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace first algorithm + /*! + replace the first match of the search substring in the input + with the format string. The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + */ + template + inline void replace_first( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_first ( case insensitive ) ---------------------------------------------// + + //! Replace first algorithm ( case insensitive ) + /*! + Replace the first match of the search substring in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_first_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace first algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_first_copy( + const SequenceT& Input, + const Range2T& Search, + const Range1T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace first algorithm ( case insensitive ) + /*! + Replace the first match of the search substring in the input + with the format string. Input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_first( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_last --------------------------------------------------------------------// + + //! Replace last algorithm + /*! + Replace the last match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::last_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace last algorithm + /*! + \overload + */ + template + inline SequenceT replace_last_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::last_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace last algorithm + /*! + Replace the last match of the search string in the input + with the format string. Input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + */ + template + inline void replace_last( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::last_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_last ( case insensitive ) -----------------------------------------------// + + //! Replace last algorithm ( case insensitive ) + /*! + Replace the last match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_last_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::last_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace last algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_last_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::last_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace last algorithm ( case insensitive ) + /*! + Replace the last match of the search string in the input + with the format string.The input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_last( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::last_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_nth --------------------------------------------------------------------// + + //! Replace nth algorithm + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth, + const Range3T& Format ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::nth_finder(Search, Nth), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace nth algorithm + /*! + \overload + */ + template + inline SequenceT replace_nth_copy( + const SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::nth_finder(Search, Nth), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace nth algorithm + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. Input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + */ + template + inline void replace_nth( + SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::nth_finder(Search, Nth), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_nth ( case insensitive ) -----------------------------------------------// + + //! Replace nth algorithm ( case insensitive ) + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_nth_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + int Nth, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc) ), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace nth algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_nth_copy( + const SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace nth algorithm ( case insensitive ) + /*! + Replace an Nth (zero-indexed) match of the search string in the input + with the format string. Input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Nth An index of the match to be replaced. The index is 0-based. + For negative N, matches are counted from the end of string. + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_nth( + SequenceT& Input, + const Range1T& Search, + int Nth, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::nth_finder(Search, Nth, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_all --------------------------------------------------------------------// + + //! Replace all algorithm + /*! + Replace all occurrences of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT replace_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format ) + { + return ::boost::algorithm::find_format_all_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace all algorithm + /*! + \overload + */ + template + inline SequenceT replace_all_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + return ::boost::algorithm::find_format_all_copy( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace all algorithm + /*! + Replace all occurrences of the search string in the input + with the format string. The input sequence is modified in-place. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + */ + template + inline void replace_all( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format ) + { + ::boost::algorithm::find_format_all( + Input, + ::boost::algorithm::first_finder(Search), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_all ( case insensitive ) -----------------------------------------------// + + //! Replace all algorithm ( case insensitive ) + /*! + Replace all occurrences of the search string in the input + with the format string. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + Searching is case insensitive. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T, + typename Range3T> + inline OutputIteratorT ireplace_all_copy( + OutputIteratorT Output, + const Range1T& Input, + const Range2T& Search, + const Range3T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_all_copy( + Output, + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace all algorithm ( case insensitive ) + /*! + \overload + */ + template + inline SequenceT ireplace_all_copy( + const SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::find_format_all_copy( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace all algorithm ( case insensitive ) + /*! + Replace all occurrences of the search string in the input + with the format string.The input sequence is modified in-place. + Searching is case insensitive. + + \param Input An input string + \param Search A substring to be searched for + \param Format A substitute string + \param Loc A locale used for case insensitive comparison + */ + template + inline void ireplace_all( + SequenceT& Input, + const Range1T& Search, + const Range2T& Format, + const std::locale& Loc=std::locale() ) + { + ::boost::algorithm::find_format_all( + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc)), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_head --------------------------------------------------------------------// + + //! Replace head algorithm + /*! + Replace the head of the input with the given format string. + The head is a prefix of a string of given size. + If the sequence is shorter then required, whole string if + considered to be the head. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT replace_head_copy( + OutputIteratorT Output, + const Range1T& Input, + int N, + const Range2T& Format ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::head_finder(N), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace head algorithm + /*! + \overload + */ + template + inline SequenceT replace_head_copy( + const SequenceT& Input, + int N, + const RangeT& Format ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::head_finder(N), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace head algorithm + /*! + Replace the head of the input with the given format string. + The head is a prefix of a string of given size. + If the sequence is shorter then required, the whole string is + considered to be the head. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the head. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + */ + template + inline void replace_head( + SequenceT& Input, + int N, + const RangeT& Format ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::head_finder(N), + ::boost::algorithm::const_formatter(Format) ); + } + +// replace_tail --------------------------------------------------------------------// + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format string. + The tail is a suffix of a string of given size. + If the sequence is shorter then required, whole string is + considered to be the tail. + The result is a modified copy of the input. It is returned as a sequence + or copied to the output iterator. + + \param Output An output iterator to which the result will be copied + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + \return An output iterator pointing just after the last inserted character or + a modified copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template< + typename OutputIteratorT, + typename Range1T, + typename Range2T> + inline OutputIteratorT replace_tail_copy( + OutputIteratorT Output, + const Range1T& Input, + int N, + const Range2T& Format ) + { + return ::boost::algorithm::find_format_copy( + Output, + Input, + ::boost::algorithm::tail_finder(N), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace tail algorithm + /*! + \overload + */ + template + inline SequenceT replace_tail_copy( + const SequenceT& Input, + int N, + const RangeT& Format ) + { + return ::boost::algorithm::find_format_copy( + Input, + ::boost::algorithm::tail_finder(N), + ::boost::algorithm::const_formatter(Format) ); + } + + //! Replace tail algorithm + /*! + Replace the tail of the input with the given format sequence. + The tail is a suffix of a string of given size. + If the sequence is shorter then required, the whole string is + considered to be the tail. The input sequence is modified in-place. + + \param Input An input string + \param N Length of the tail. + For N>=0, at most N characters are extracted. + For N<0, size(Input)-|N| characters are extracted. + \param Format A substitute string + */ + template + inline void replace_tail( + SequenceT& Input, + int N, + const RangeT& Format ) + { + ::boost::algorithm::find_format( + Input, + ::boost::algorithm::tail_finder(N), + ::boost::algorithm::const_formatter(Format) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::replace_range_copy; + using algorithm::replace_range; + using algorithm::replace_first_copy; + using algorithm::replace_first; + using algorithm::ireplace_first_copy; + using algorithm::ireplace_first; + using algorithm::replace_last_copy; + using algorithm::replace_last; + using algorithm::ireplace_last_copy; + using algorithm::ireplace_last; + using algorithm::replace_nth_copy; + using algorithm::replace_nth; + using algorithm::ireplace_nth_copy; + using algorithm::ireplace_nth; + using algorithm::replace_all_copy; + using algorithm::replace_all; + using algorithm::ireplace_all_copy; + using algorithm::ireplace_all; + using algorithm::replace_head_copy; + using algorithm::replace_head; + using algorithm::replace_tail_copy; + using algorithm::replace_tail; + +} // namespace boost + +#endif // BOOST_REPLACE_HPP diff --git a/src/vendor/boost/algorithm/string/sequence_traits.hpp b/src/vendor/boost/algorithm/string/sequence_traits.hpp new file mode 100644 index 000000000..be151f8d3 --- /dev/null +++ b/src/vendor/boost/algorithm/string/sequence_traits.hpp @@ -0,0 +1,120 @@ +// Boost string_algo library sequence_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_SEQUENCE_TRAITS_HPP +#define BOOST_STRING_SEQUENCE_TRAITS_HPP + +#include +#include +#include + +/*! \file + Traits defined in this header are used by various algorithms to achieve + better performance for specific containers. + Traits provide fail-safe defaults. If a container supports some of these + features, it is possible to specialize the specific trait for this container. + For lacking compilers, it is possible of define an override for a specific tester + function. + + Due to a language restriction, it is not currently possible to define specializations for + stl containers without including the corresponding header. To decrease the overhead + needed by this inclusion, user can selectively include a specialization + header for a specific container. They are located in boost/algorithm/string/stl + directory. Alternatively she can include boost/algorithm/string/std_collection_traits.hpp + header which contains specializations for all stl containers. +*/ + +namespace boost { + namespace algorithm { + +// sequence traits -----------------------------------------------// + + + //! Native replace trait + /*! + This trait specifies that the sequence has \c std::string like replace method + */ + template< typename T > + class has_native_replace + { + + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + + + typedef mpl::bool_::value> type; + }; + + + //! Stable iterators trait + /*! + This trait specifies that the sequence has stable iterators. It means + that operations like insert/erase/replace do not invalidate iterators. + */ + template< typename T > + class has_stable_iterators + { + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + + typedef mpl::bool_::value> type; + }; + + + //! Const time insert trait + /*! + This trait specifies that the sequence's insert method has + constant time complexity. + */ + template< typename T > + class has_const_time_insert + { + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + + typedef mpl::bool_::value> type; + }; + + + //! Const time erase trait + /*! + This trait specifies that the sequence's erase method has + constant time complexity. + */ + template< typename T > + class has_const_time_erase + { + public: +# if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = false }; +# else + BOOST_STATIC_CONSTANT(bool, value=false); +# endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + + typedef mpl::bool_::value> type; + }; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_SEQUENCE_TRAITS_HPP diff --git a/src/vendor/boost/algorithm/string/split.hpp b/src/vendor/boost/algorithm/string/split.hpp new file mode 100644 index 000000000..e0b30fb35 --- /dev/null +++ b/src/vendor/boost/algorithm/string/split.hpp @@ -0,0 +1,175 @@ +// Boost string_algo library split.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2006. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_SPLIT_HPP +#define BOOST_STRING_SPLIT_HPP + +#include + +#include +#include +#include + +/*! \file + Defines basic split algorithms. + Split algorithms can be used to divide a string + into several parts according to given criteria. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> +*/ + +namespace boost { + namespace algorithm { + +// find_all ------------------------------------------------------------// + + //! Find all algorithm + /*! + This algorithm finds all occurrences of the search string + in the input. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Search A substring to be searched for. + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename Range2T > + inline SequenceSequenceT& find_all( + SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + Range1T&& Input, +#else + Range1T& Input, +#endif + const Range2T& Search) + { + return ::boost::algorithm::iter_find( + Result, + Input, + ::boost::algorithm::first_finder(Search) ); + } + + //! Find all algorithm ( case insensitive ) + /*! + This algorithm finds all occurrences of the search string + in the input. + Each part is copied and added as a new element to the + output container. Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + Searching is case insensitive. + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Search A substring to be searched for. + \param Loc A locale used for case insensitive comparison + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename Range1T, typename Range2T > + inline SequenceSequenceT& ifind_all( + SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + Range1T&& Input, +#else + Range1T& Input, +#endif + const Range2T& Search, + const std::locale& Loc=std::locale() ) + { + return ::boost::algorithm::iter_find( + Result, + Input, + ::boost::algorithm::first_finder(Search, is_iequal(Loc) ) ); + } + + +// tokenize -------------------------------------------------------------// + + //! Split algorithm + /*! + Tokenize expression. This function is equivalent to C strtok. Input + sequence is split into tokens, separated by separators. Separators + are given by means of the predicate. + + Each part is copied and added as a new element to the + output container. + Thus the result container must be able to hold copies + of the matches (in a compatible structure like std::string) or + a reference to it (e.g. using the iterator range class). + Examples of such a container are \c std::vector + or \c std::list> + + \param Result A container that can hold copies of references to the substrings + \param Input A container which will be searched. + \param Pred A predicate to identify separators. This predicate is + supposed to return true if a given element is a separator. + \param eCompress If eCompress argument is set to token_compress_on, adjacent + separators are merged together. Otherwise, every two separators + delimit a token. + \return A reference the result + + \note Prior content of the result will be overwritten. + + \note This function provides the strong exception-safety guarantee + */ + template< typename SequenceSequenceT, typename RangeT, typename PredicateT > + inline SequenceSequenceT& split( + SequenceSequenceT& Result, +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + RangeT&& Input, +#else + RangeT& Input, +#endif + PredicateT Pred, + token_compress_mode_type eCompress=token_compress_off ) + { + return ::boost::algorithm::iter_split( + Result, + Input, + ::boost::algorithm::token_finder( Pred, eCompress ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::find_all; + using algorithm::ifind_all; + using algorithm::split; + +} // namespace boost + + +#endif // BOOST_STRING_SPLIT_HPP + diff --git a/src/vendor/boost/algorithm/string/std/list_traits.hpp b/src/vendor/boost/algorithm/string/std/list_traits.hpp new file mode 100644 index 000000000..a3cf7bb18 --- /dev/null +++ b/src/vendor/boost/algorithm/string/std/list_traits.hpp @@ -0,0 +1,68 @@ +// Boost string_algo library list_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_LIST_TRAITS_HPP +#define BOOST_STRING_STD_LIST_TRAITS_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + +// std::list<> traits -----------------------------------------------// + + + // stable iterators trait + template + class has_stable_iterators< ::std::list > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time insert trait + template + class has_const_time_insert< ::std::list > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time erase trait + template + class has_const_time_erase< ::std::list > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_STD_LIST_TRAITS_HPP diff --git a/src/vendor/boost/algorithm/string/std/slist_traits.hpp b/src/vendor/boost/algorithm/string/std/slist_traits.hpp new file mode 100644 index 000000000..c30b93c73 --- /dev/null +++ b/src/vendor/boost/algorithm/string/std/slist_traits.hpp @@ -0,0 +1,69 @@ +// Boost string_algo library slist_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_SLIST_TRAITS_HPP +#define BOOST_STRING_STD_SLIST_TRAITS_HPP + +#include +#include +#include BOOST_SLIST_HEADER +#include + +namespace boost { + namespace algorithm { + +// SGI's std::slist<> traits -----------------------------------------------// + + + // stable iterators trait + template + class has_stable_iterators< BOOST_STD_EXTENSION_NAMESPACE::slist > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time insert trait + template + class has_const_time_insert< BOOST_STD_EXTENSION_NAMESPACE::slist > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + // const time erase trait + template + class has_const_time_erase< BOOST_STD_EXTENSION_NAMESPACE::slist > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true }; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + typedef mpl::bool_::value> type; + }; + + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_STD_LIST_TRAITS_HPP diff --git a/src/vendor/boost/algorithm/string/std/string_traits.hpp b/src/vendor/boost/algorithm/string/std/string_traits.hpp new file mode 100644 index 000000000..c9408307d --- /dev/null +++ b/src/vendor/boost/algorithm/string/std/string_traits.hpp @@ -0,0 +1,44 @@ +// Boost string_algo library string_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_STRING_TRAITS_HPP +#define BOOST_STRING_STD_STRING_TRAITS_HPP + +#include +#include +#include + +namespace boost { + namespace algorithm { + +// std::basic_string<> traits -----------------------------------------------// + + + // native replace trait + template + class has_native_replace< std::basic_string > + { + public: +#if BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + enum { value = true } ; +#else + BOOST_STATIC_CONSTANT(bool, value=true); +#endif // BOOST_WORKAROUND( __IBMCPP__, <= 600 ) + + typedef mpl::bool_::value> type; + }; + + + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_LIST_TRAITS_HPP diff --git a/src/vendor/boost/algorithm/string/std_containers_traits.hpp b/src/vendor/boost/algorithm/string/std_containers_traits.hpp new file mode 100644 index 000000000..3f02246fd --- /dev/null +++ b/src/vendor/boost/algorithm/string/std_containers_traits.hpp @@ -0,0 +1,26 @@ +// Boost string_algo library std_containers_traits.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_STD_CONTAINERS_TRAITS_HPP +#define BOOST_STRING_STD_CONTAINERS_TRAITS_HPP + +/*!\file + This file includes sequence traits for stl containers. +*/ + +#include +#include +#include + +#ifdef BOOST_HAS_SLIST +# include +#endif + +#endif // BOOST_STRING_STD_CONTAINERS_TRAITS_HPP diff --git a/src/vendor/boost/algorithm/string/trim.hpp b/src/vendor/boost/algorithm/string/trim.hpp new file mode 100644 index 000000000..e740d57d9 --- /dev/null +++ b/src/vendor/boost/algorithm/string/trim.hpp @@ -0,0 +1,398 @@ +// Boost string_algo library trim.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_TRIM_HPP +#define BOOST_STRING_TRIM_HPP + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +/*! \file + Defines trim algorithms. + Trim algorithms are used to remove trailing and leading spaces from a + sequence (string). Space is recognized using given locales. + + Parametric (\c _if) variants use a predicate (functor) to select which characters + are to be trimmed.. + Functions take a selection predicate as a parameter, which is used to determine + whether a character is a space. Common predicates are provided in classification.hpp header. + +*/ + +namespace boost { + namespace algorithm { + + // left trim -----------------------------------------------// + + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace A unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_left_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace) + { + iterator_range::type> lit_range(::boost::as_literal(Input)); + + std::copy( + ::boost::algorithm::detail::trim_begin( + ::boost::begin(lit_range), + ::boost::end(lit_range), + IsSpace ), + ::boost::end(lit_range), + Output); + + return Output; + } + + //! Left trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_left_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + ::boost::algorithm::detail::trim_begin( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace ), + ::boost::end(Input)); + } + + //! Left trim - parametric + /*! + Remove all leading spaces from the input. + The result is a trimmed copy of the input. + + \param Input An input sequence + \param Loc a locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_left_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + ::boost::algorithm::trim_left_copy_if( + Input, + is_space(Loc)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. The supplied predicate is + used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace A unary predicate identifying spaces + */ + template + inline void trim_left_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + ::boost::begin(Input), + ::boost::algorithm::detail::trim_begin( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace)); + } + + //! Left trim + /*! + Remove all leading spaces from the input. + The Input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_left(SequenceT& Input, const std::locale& Loc=std::locale()) + { + ::boost::algorithm::trim_left_if( + Input, + is_space(Loc)); + } + + // right trim -----------------------------------------------// + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace A unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_right_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace ) + { + iterator_range::type> lit_range(::boost::as_literal(Input)); + + std::copy( + ::boost::begin(lit_range), + ::boost::algorithm::detail::trim_end( + ::boost::begin(lit_range), + ::boost::end(lit_range), + IsSpace ), + Output ); + + return Output; + } + + //! Right trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_right_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + return SequenceT( + ::boost::begin(Input), + ::boost::algorithm::detail::trim_end( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace) + ); + } + + //! Right trim + /*! + Remove all trailing spaces from the input. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_right_copy(const SequenceT& Input, const std::locale& Loc=std::locale()) + { + return + ::boost::algorithm::trim_right_copy_if( + Input, + is_space(Loc)); + } + + + //! Right trim - parametric + /*! + Remove all trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace A unary predicate identifying spaces + */ + template + inline void trim_right_if(SequenceT& Input, PredicateT IsSpace) + { + Input.erase( + ::boost::algorithm::detail::trim_end( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace ), + ::boost::end(Input) + ); + } + + + //! Right trim + /*! + Remove all trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim_right(SequenceT& Input, const std::locale& Loc=std::locale()) + { + ::boost::algorithm::trim_right_if( + Input, + is_space(Loc) ); + } + + // both side trim -----------------------------------------------// + + //! Trim - parametric + /*! + Remove all trailing and leading spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The result is a trimmed copy of the input. It is returned as a sequence + or copied to the output iterator + + \param Output An output iterator to which the result will be copied + \param Input An input range + \param IsSpace A unary predicate identifying spaces + \return + An output iterator pointing just after the last inserted character or + a copy of the input + + \note The second variant of this function provides the strong exception-safety guarantee + */ + template + inline OutputIteratorT trim_copy_if( + OutputIteratorT Output, + const RangeT& Input, + PredicateT IsSpace) + { + iterator_range::type> lit_range(::boost::as_literal(Input)); + + BOOST_STRING_TYPENAME + range_const_iterator::type TrimEnd= + ::boost::algorithm::detail::trim_end( + ::boost::begin(lit_range), + ::boost::end(lit_range), + IsSpace); + + std::copy( + detail::trim_begin( + ::boost::begin(lit_range), TrimEnd, IsSpace), + TrimEnd, + Output + ); + + return Output; + } + + //! Trim - parametric + /*! + \overload + */ + template + inline SequenceT trim_copy_if(const SequenceT& Input, PredicateT IsSpace) + { + BOOST_STRING_TYPENAME + range_const_iterator::type TrimEnd= + ::boost::algorithm::detail::trim_end( + ::boost::begin(Input), + ::boost::end(Input), + IsSpace); + + return SequenceT( + detail::trim_begin( + ::boost::begin(Input), + TrimEnd, + IsSpace), + TrimEnd + ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The result is a trimmed copy of the input + + \param Input An input sequence + \param Loc A locale used for 'space' classification + \return A trimmed copy of the input + + \note This function provides the strong exception-safety guarantee + */ + template + inline SequenceT trim_copy( const SequenceT& Input, const std::locale& Loc=std::locale() ) + { + return + ::boost::algorithm::trim_copy_if( + Input, + is_space(Loc) ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The supplied predicate is used to determine which characters are considered spaces. + The input sequence is modified in-place. + + \param Input An input sequence + \param IsSpace A unary predicate identifying spaces + */ + template + inline void trim_if(SequenceT& Input, PredicateT IsSpace) + { + ::boost::algorithm::trim_right_if( Input, IsSpace ); + ::boost::algorithm::trim_left_if( Input, IsSpace ); + } + + //! Trim + /*! + Remove all leading and trailing spaces from the input. + The input sequence is modified in-place. + + \param Input An input sequence + \param Loc A locale used for 'space' classification + */ + template + inline void trim(SequenceT& Input, const std::locale& Loc=std::locale()) + { + ::boost::algorithm::trim_if( + Input, + is_space( Loc ) ); + } + + } // namespace algorithm + + // pull names to the boost namespace + using algorithm::trim_left; + using algorithm::trim_left_if; + using algorithm::trim_left_copy; + using algorithm::trim_left_copy_if; + using algorithm::trim_right; + using algorithm::trim_right_if; + using algorithm::trim_right_copy; + using algorithm::trim_right_copy_if; + using algorithm::trim; + using algorithm::trim_if; + using algorithm::trim_copy; + using algorithm::trim_copy_if; + +} // namespace boost + +#endif // BOOST_STRING_TRIM_HPP diff --git a/src/vendor/boost/algorithm/string/yes_no_type.hpp b/src/vendor/boost/algorithm/string/yes_no_type.hpp new file mode 100644 index 000000000..b76cc6c15 --- /dev/null +++ b/src/vendor/boost/algorithm/string/yes_no_type.hpp @@ -0,0 +1,33 @@ +// Boost string_algo library yes_no_type.hpp header file ---------------------------// + +// Copyright Pavol Droba 2002-2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for updates, documentation, and revision history. + +#ifndef BOOST_STRING_YES_NO_TYPE_DETAIL_HPP +#define BOOST_STRING_YES_NO_TYPE_DETAIL_HPP + +namespace boost { + namespace algorithm { + + // taken from boost mailing-list + // when yes_no_type will become officially + // a part of boost distribution, this header + // will be deprecated + template struct size_descriptor + { + typedef char (& type)[I]; + }; + + typedef size_descriptor<1>::type yes_type; + typedef size_descriptor<2>::type no_type; + + } // namespace algorithm +} // namespace boost + + +#endif // BOOST_STRING_YES_NO_TYPE_DETAIL_HPP diff --git a/src/vendor/boost/array.hpp b/src/vendor/boost/array.hpp new file mode 100644 index 000000000..a32d1e99c --- /dev/null +++ b/src/vendor/boost/array.hpp @@ -0,0 +1,456 @@ +/* The following code declares class array, + * an STL container (as wrapper) for arrays of constant size. + * + * See + * http://www.boost.org/libs/array/ + * for documentation. + * + * The original author site is at: http://www.josuttis.com/ + * + * (C) Copyright Nicolai M. Josuttis 2001. + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * 9 Jan 2013 - (mtc) Added constexpr + * 14 Apr 2012 - (mtc) Added support for boost::hash + * 28 Dec 2010 - (mtc) Added cbegin and cend (and crbegin and crend) for C++Ox compatibility. + * 10 Mar 2010 - (mtc) fill method added, matching resolution of the standard library working group. + * See or Trac issue #3168 + * Eventually, we should remove "assign" which is now a synonym for "fill" (Marshall Clow) + * 10 Mar 2010 - added workaround for SUNCC and !STLPort [trac #3893] (Marshall Clow) + * 29 Jan 2004 - c_array() added, BOOST_NO_PRIVATE_IN_AGGREGATE removed (Nico Josuttis) + * 23 Aug 2002 - fix for Non-MSVC compilers combined with MSVC libraries. + * 05 Aug 2001 - minor update (Nico Josuttis) + * 20 Jan 2001 - STLport fix (Beman Dawes) + * 29 Sep 2000 - Initial Revision (Nico Josuttis) + * + * Jan 29, 2004 + */ +#ifndef BOOST_ARRAY_HPP +#define BOOST_ARRAY_HPP + +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(push) +# pragma warning(disable:4996) // 'std::equal': Function call with parameters that may be unsafe +# pragma warning(disable:4510) // boost::array' : default constructor could not be generated +# pragma warning(disable:4610) // warning C4610: class 'boost::array' can never be instantiated - user defined constructor required +#endif + +#include +#include +#include +#include +#include +#include + +#include +#include + +// FIXES for broken compilers +#include + + +namespace boost { + + template + class array { + public: + T elems[N]; // fixed-size array of elements of type T + + public: + // type definitions + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // iterator support + iterator begin() { return elems; } + const_iterator begin() const { return elems; } + const_iterator cbegin() const { return elems; } + + iterator end() { return elems+N; } + const_iterator end() const { return elems+N; } + const_iterator cend() const { return elems+N; } + + // reverse iterator support +#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#else + // workaround for broken reverse_iterator implementations + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const { + return const_reverse_iterator(begin()); + } + + // operator[] + reference operator[](size_type i) + { + return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; + } + + /*BOOST_CONSTEXPR*/ const_reference operator[](size_type i) const + { + return BOOST_ASSERT_MSG( i < N, "out of range" ), elems[i]; + } + + // at() with range check + reference at(size_type i) { return rangecheck(i), elems[i]; } + /*BOOST_CONSTEXPR*/ const_reference at(size_type i) const { return rangecheck(i), elems[i]; } + + // front() and back() + reference front() + { + return elems[0]; + } + + BOOST_CONSTEXPR const_reference front() const + { + return elems[0]; + } + + reference back() + { + return elems[N-1]; + } + + BOOST_CONSTEXPR const_reference back() const + { + return elems[N-1]; + } + + // size is constant + static BOOST_CONSTEXPR size_type size() { return N; } + static BOOST_CONSTEXPR bool empty() { return false; } + static BOOST_CONSTEXPR size_type max_size() { return N; } + enum { static_size = N }; + + // swap (note: linear complexity) + void swap (array& y) { + for (size_type i = 0; i < N; ++i) + boost::swap(elems[i],y.elems[i]); + } + + // direct access to data (read-only) + const T* data() const { return elems; } + T* data() { return elems; } + + // use array as C array (direct read/write access to data) + T* c_array() { return elems; } + + // assignment with type conversion + template + array& operator= (const array& rhs) { + std::copy(rhs.begin(),rhs.end(), begin()); + return *this; + } + + // assign one value to all elements + void assign (const T& value) { fill ( value ); } // A synonym for fill + void fill (const T& value) + { + std::fill_n(begin(),size(),value); + } + + // check range (may be private because it is static) + static BOOST_CONSTEXPR bool rangecheck (size_type i) { + return i >= size() ? boost::throw_exception(std::out_of_range ("array<>: index out of range")), true : true; + } + + }; + + template< class T > + class array< T, 0 > { + + public: + // type definitions + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + // iterator support + iterator begin() { return iterator( reinterpret_cast< T * >( this ) ); } + const_iterator begin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } + const_iterator cbegin() const { return const_iterator( reinterpret_cast< const T * >( this ) ); } + + iterator end() { return begin(); } + const_iterator end() const { return begin(); } + const_iterator cend() const { return cbegin(); } + + // reverse iterator support +#if !defined(BOOST_MSVC_STD_ITERATOR) && !defined(BOOST_NO_STD_ITERATOR_TRAITS) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#else + // workaround for broken reverse_iterator implementations + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; +#endif + + reverse_iterator rbegin() { return reverse_iterator(end()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + const_reverse_iterator crbegin() const { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() { return reverse_iterator(begin()); } + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + const_reverse_iterator crend() const { + return const_reverse_iterator(begin()); + } + + // operator[] + reference operator[](size_type /*i*/) + { + return failed_rangecheck(); + } + + /*BOOST_CONSTEXPR*/ const_reference operator[](size_type /*i*/) const + { + return failed_rangecheck(); + } + + // at() with range check + reference at(size_type /*i*/) { return failed_rangecheck(); } + /*BOOST_CONSTEXPR*/ const_reference at(size_type /*i*/) const { return failed_rangecheck(); } + + // front() and back() + reference front() + { + return failed_rangecheck(); + } + + BOOST_CONSTEXPR const_reference front() const + { + return failed_rangecheck(); + } + + reference back() + { + return failed_rangecheck(); + } + + BOOST_CONSTEXPR const_reference back() const + { + return failed_rangecheck(); + } + + // size is constant + static BOOST_CONSTEXPR size_type size() { return 0; } + static BOOST_CONSTEXPR bool empty() { return true; } + static BOOST_CONSTEXPR size_type max_size() { return 0; } + enum { static_size = 0 }; + + void swap (array& /*y*/) { + } + + // direct access to data (read-only) + const T* data() const { return 0; } + T* data() { return 0; } + + // use array as C array (direct read/write access to data) + T* c_array() { return 0; } + + // assignment with type conversion + template + array& operator= (const array& ) { + return *this; + } + + // assign one value to all elements + void assign (const T& value) { fill ( value ); } + void fill (const T& ) {} + + // check range (may be private because it is static) + static reference failed_rangecheck () { + std::out_of_range e("attempt to access element of an empty array"); + boost::throw_exception(e); +#if defined(BOOST_NO_EXCEPTIONS) || (!defined(BOOST_MSVC) && !defined(__PATHSCALE__)) + // + // We need to return something here to keep + // some compilers happy: however we will never + // actually get here.... + // + static T placeholder; + return placeholder; +#endif + } + }; + + // comparisons + template + bool operator== (const array& x, const array& y) { + return std::equal(x.begin(), x.end(), y.begin()); + } + template + bool operator< (const array& x, const array& y) { + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); + } + template + bool operator!= (const array& x, const array& y) { + return !(x==y); + } + template + bool operator> (const array& x, const array& y) { + return y + bool operator<= (const array& x, const array& y) { + return !(y + bool operator>= (const array& x, const array& y) { + return !(x + inline void swap (array& x, array& y) { + x.swap(y); + } + +#if defined(__SUNPRO_CC) +// Trac ticket #4757; the Sun Solaris compiler can't handle +// syntax like 'T(&get_c_array(boost::array& arg))[N]' +// +// We can't just use this for all compilers, because the +// borland compilers can't handle this form. + namespace detail { + template struct c_array + { + typedef T type[N]; + }; + } + + // Specific for boost::array: simply returns its elems data member. + template + typename detail::c_array::type& get_c_array(boost::array& arg) + { + return arg.elems; + } + + // Specific for boost::array: simply returns its elems data member. + template + typename detail::c_array::type const& get_c_array(const boost::array& arg) + { + return arg.elems; + } +#else +// Specific for boost::array: simply returns its elems data member. + template + T(&get_c_array(boost::array& arg))[N] + { + return arg.elems; + } + + // Const version. + template + const T(&get_c_array(const boost::array& arg))[N] + { + return arg.elems; + } +#endif + +#if 0 + // Overload for std::array, assuming that std::array will have + // explicit conversion functions as discussed at the WG21 meeting + // in Summit, March 2009. + template + T(&get_c_array(std::array& arg))[N] + { + return static_cast(arg); + } + + // Const version. + template + const T(&get_c_array(const std::array& arg))[N] + { + return static_cast(arg); + } +#endif + + template std::size_t hash_range(It, It); + + template + std::size_t hash_value(const array& arr) + { + return boost::hash_range(arr.begin(), arr.end()); + } + + template + T &get(boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(boost::array &) index out of range" ); + return arr[Idx]; + } + + template + const T &get(const boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "boost::get<>(const boost::array &) index out of range" ); + return arr[Idx]; + } + +} /* namespace boost */ + +#ifndef BOOST_NO_CXX11_HDR_ARRAY +// If we don't have std::array, I'm assuming that we don't have std::get +namespace std { + template + T &get(boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(boost::array &) index out of range" ); + return arr[Idx]; + } + + template + const T &get(const boost::array &arr) BOOST_NOEXCEPT { + BOOST_STATIC_ASSERT_MSG ( Idx < N, "std::get<>(const boost::array &) index out of range" ); + return arr[Idx]; + } +} +#endif + +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(pop) +#endif + +#endif /*BOOST_ARRAY_HPP*/ diff --git a/src/vendor/boost/assert.hpp b/src/vendor/boost/assert.hpp new file mode 100644 index 000000000..9650d7a29 --- /dev/null +++ b/src/vendor/boost/assert.hpp @@ -0,0 +1,85 @@ +// +// boost/assert.hpp - BOOST_ASSERT(expr) +// BOOST_ASSERT_MSG(expr, msg) +// BOOST_VERIFY(expr) +// BOOST_VERIFY_MSG(expr, msg) +// BOOST_ASSERT_IS_VOID +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2007, 2014 Peter Dimov +// Copyright (c) Beman Dawes 2011 +// Copyright (c) 2015 Ion Gaztanaga +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// Note: There are no include guards. This is intentional. +// +// See http://www.boost.org/libs/assert/assert.html for documentation. +// + +// +// Stop inspect complaining about use of 'assert': +// +// boostinspect:naassert_macro +// + +// +// BOOST_ASSERT, BOOST_ASSERT_MSG, BOOST_ASSERT_IS_VOID +// + +#undef BOOST_ASSERT +#undef BOOST_ASSERT_MSG +#undef BOOST_ASSERT_IS_VOID + +#if defined(BOOST_DISABLE_ASSERTS) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && defined(NDEBUG) ) + +# define BOOST_ASSERT(expr) ((void)0) +# define BOOST_ASSERT_MSG(expr, msg) ((void)0) +# define BOOST_ASSERT_IS_VOID + +#elif defined(BOOST_ENABLE_ASSERT_HANDLER) || ( defined(BOOST_ENABLE_ASSERT_DEBUG_HANDLER) && !defined(NDEBUG) ) + +#include // for BOOST_LIKELY +#include + +namespace boost +{ + void assertion_failed(char const * expr, char const * function, char const * file, long line); // user defined + void assertion_failed_msg(char const * expr, char const * msg, char const * function, char const * file, long line); // user defined +} // namespace boost + +#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) +#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr))? ((void)0): ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) + +#else + +# include // .h to support old libraries w/o - effect is the same + +# define BOOST_ASSERT(expr) assert(expr) +# define BOOST_ASSERT_MSG(expr, msg) assert((expr)&&(msg)) +#if defined(NDEBUG) +# define BOOST_ASSERT_IS_VOID +#endif + +#endif + +// +// BOOST_VERIFY, BOOST_VERIFY_MSG +// + +#undef BOOST_VERIFY +#undef BOOST_VERIFY_MSG + +#if defined(BOOST_DISABLE_ASSERTS) || ( !defined(BOOST_ENABLE_ASSERT_HANDLER) && defined(NDEBUG) ) + +# define BOOST_VERIFY(expr) ((void)(expr)) +# define BOOST_VERIFY_MSG(expr, msg) ((void)(expr)) + +#else + +# define BOOST_VERIFY(expr) BOOST_ASSERT(expr) +# define BOOST_VERIFY_MSG(expr, msg) BOOST_ASSERT_MSG(expr,msg) + +#endif diff --git a/src/vendor/boost/assert/source_location.hpp b/src/vendor/boost/assert/source_location.hpp new file mode 100644 index 000000000..a85e67952 --- /dev/null +++ b/src/vendor/boost/assert/source_location.hpp @@ -0,0 +1,93 @@ +#ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED +#define BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED + +// http://www.boost.org/libs/assert +// +// Copyright 2019 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include + +namespace boost +{ + +struct source_location +{ +private: + + char const * file_; + char const * function_; + boost::uint_least32_t line_; + boost::uint_least32_t column_; + +public: + + BOOST_CONSTEXPR source_location() BOOST_NOEXCEPT: file_( "(unknown)" ), function_( "(unknown)" ), line_( 0 ), column_( 0 ) + { + } + + BOOST_CONSTEXPR source_location( char const * file, boost::uint_least32_t ln, char const * function, boost::uint_least32_t col = 0 ) BOOST_NOEXCEPT: file_( file ), function_( function ), line_( ln ), column_( col ) + { + } + + BOOST_CONSTEXPR char const * file_name() const BOOST_NOEXCEPT + { + return file_; + } + + BOOST_CONSTEXPR char const * function_name() const BOOST_NOEXCEPT + { + return function_; + } + + BOOST_CONSTEXPR boost::uint_least32_t line() const BOOST_NOEXCEPT + { + return line_; + } + + BOOST_CONSTEXPR boost::uint_least32_t column() const BOOST_NOEXCEPT + { + return column_; + } +}; + +template std::basic_ostream & operator<<( std::basic_ostream & os, source_location const & loc ) +{ + os.width( 0 ); + + if( loc.line() == 0 ) + { + os << "(unknown source location)"; + } + else + { + os << loc.file_name() << ':' << loc.line(); + + if( loc.column() ) + { + os << ':' << loc.column(); + } + + os << ": in function '" << loc.function_name() << '\''; + } + + return os; +} + +} // namespace boost + +#if defined( BOOST_DISABLE_CURRENT_LOCATION ) + +# define BOOST_CURRENT_LOCATION ::boost::source_location() + +#else + +# define BOOST_CURRENT_LOCATION ::boost::source_location(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) + +#endif + +#endif // #ifndef BOOST_ASSERT_SOURCE_LOCATION_HPP_INCLUDED diff --git a/src/vendor/boost/bind.hpp b/src/vendor/boost/bind.hpp new file mode 100644 index 000000000..0f00ad358 --- /dev/null +++ b/src/vendor/boost/bind.hpp @@ -0,0 +1,60 @@ +#ifndef BOOST_BIND_HPP_INCLUDED +#define BOOST_BIND_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// bind.hpp - binds function objects to arguments +// +// Copyright (c) 2009, 2015 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// +// For backward compatibility, this header includes +// and then imports the placeholders _1, _2, +// _3, ... into the global namespace. Definitions in the global +// namespace are not a good practice and this use is deprecated. +// Please switch to including directly, +// adding the using directive locally where appropriate. +// Alternatively, the existing behavior may be preserved by defining +// the macro BOOST_BIND_GLOBAL_PLACEHOLDERS. + +#include +#include + +#ifndef BOOST_BIND_NO_PLACEHOLDERS + +#if !defined(BOOST_BIND_GLOBAL_PLACEHOLDERS) + +BOOST_PRAGMA_MESSAGE( + "The practice of declaring the Bind placeholders (_1, _2, ...) " + "in the global namespace is deprecated. Please use " + " + using namespace boost::placeholders, " + "or define BOOST_BIND_GLOBAL_PLACEHOLDERS to retain the current behavior." +) + +#endif + +#if defined(BOOST_CLANG) +# pragma clang diagnostic push +# if __has_warning("-Wheader-hygiene") +//# pragma clang diagnostic ignored "-Wheader-hygiene" +# endif +#endif + +using namespace boost::placeholders; + +#if defined(BOOST_CLANG) +# pragma clang diagnostic pop +#endif + +#endif // #ifndef BOOST_BIND_NO_PLACEHOLDERS + +#endif // #ifndef BOOST_BIND_HPP_INCLUDED diff --git a/src/vendor/boost/bind/arg.hpp b/src/vendor/boost/bind/arg.hpp new file mode 100644 index 000000000..cb52e6689 --- /dev/null +++ b/src/vendor/boost/bind/arg.hpp @@ -0,0 +1,69 @@ +#ifndef BOOST_BIND_ARG_HPP_INCLUDED +#define BOOST_BIND_ARG_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/arg.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +namespace boost +{ + +template struct _arg_eq +{ +}; + +template<> struct _arg_eq +{ + typedef void type; +}; + +template< int I > struct arg +{ + BOOST_CONSTEXPR arg() + { + } + + template< class T > BOOST_CONSTEXPR arg( T const & /* t */, typename _arg_eq< I == is_placeholder::value >::type * = 0 ) + { + } +}; + +template< int I > BOOST_CONSTEXPR bool operator==( arg const &, arg const & ) +{ + return true; +} + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< int I > struct is_placeholder< arg > +{ + enum _vt { value = I }; +}; + +template< int I > struct is_placeholder< arg (*) () > +{ + enum _vt { value = I }; +}; + +#endif + +} // namespace boost + +#endif // #ifndef BOOST_BIND_ARG_HPP_INCLUDED diff --git a/src/vendor/boost/bind/bind.hpp b/src/vendor/boost/bind/bind.hpp new file mode 100644 index 000000000..2301234c3 --- /dev/null +++ b/src/vendor/boost/bind/bind.hpp @@ -0,0 +1,2344 @@ +#ifndef BOOST_BIND_BIND_HPP_INCLUDED +#define BOOST_BIND_BIND_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind.hpp - binds function objects to arguments +// +// Copyright (c) 2001-2004 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2001 David Abrahams +// Copyright (c) 2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) +#include // std::forward +#endif + +// Borland-specific bug, visit_each() silently fails to produce code + +#if defined(BOOST_BORLANDC) +# define BOOST_BIND_VISIT_EACH boost::visit_each +#else +# define BOOST_BIND_VISIT_EACH visit_each +#endif + +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + +template class weak_ptr; + +namespace _bi // implementation details +{ + +// ref_compare + +template bool ref_compare( T const & a, T const & b, long ) +{ + return a == b; +} + +template bool ref_compare( arg const &, arg const &, int ) +{ + return true; +} + +template bool ref_compare( arg (*) (), arg (*) (), int ) +{ + return true; +} + +template bool ref_compare( reference_wrapper const & a, reference_wrapper const & b, int ) +{ + return a.get_pointer() == b.get_pointer(); +} + +// bind_t forward declaration for listN + +template class bind_t; + +template bool ref_compare( bind_t const & a, bind_t const & b, int ) +{ + return a.compare( b ); +} + +// value + +template class value +{ +public: + + value(T const & t): t_(t) {} + + T & get() { return t_; } + T const & get() const { return t_; } + + bool operator==(value const & rhs) const + { + return t_ == rhs.t_; + } + +private: + + T t_; +}; + +// ref_compare for weak_ptr + +template bool ref_compare( value< weak_ptr > const & a, value< weak_ptr > const & b, int ) +{ + return !(a.get() < b.get()) && !(b.get() < a.get()); +} + +// type + +template class type {}; + +// unwrap + +template struct unwrapper +{ + static inline F & unwrap( F & f, long ) + { + return f; + } + + template static inline F2 & unwrap( reference_wrapper rf, int ) + { + return rf.get(); + } + + template static inline _mfi::dm unwrap( R T::* pm, int ) + { + return _mfi::dm( pm ); + } +}; + +// listN + +class list0 +{ +public: + + list0() {} + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A &, long) + { + return unwrapper::unwrap(f, 0)(); + } + + template R operator()(type, F const & f, A &, long) const + { + return unwrapper::unwrap(f, 0)(); + } + + template void operator()(type, F & f, A &, int) + { + unwrapper::unwrap(f, 0)(); + } + + template void operator()(type, F const & f, A &, int) const + { + unwrapper::unwrap(f, 0)(); + } + + template void accept(V &) const + { + } + + bool operator==(list0 const &) const + { + return true; + } +}; + +#ifdef BOOST_MSVC +// MSVC is bright enough to realise that the parameter rhs +// in operator==may be unused for some template argument types: +#pragma warning(push) +#pragma warning(disable:4100) +#endif + +template< class A1 > class list1: private storage1< A1 > +{ +private: + + typedef storage1< A1 > base_type; + +public: + + explicit list1( A1 a1 ): base_type( a1 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list1 const & rhs) const + { + return ref_compare(base_type::a1_, rhs.a1_, 0); + } +}; + +struct logical_and; +struct logical_or; + +template< class A1, class A2 > class list2: private storage2< A1, A2 > +{ +private: + + typedef storage2< A1, A2 > base_type; + +public: + + list2( A1 a1, A2 a2 ): base_type( a1, a2 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]); + } + + template bool operator()( type, logical_and & /*f*/, A & a, int ) + { + return a[ base_type::a1_ ] && a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_and const & /*f*/, A & a, int ) const + { + return a[ base_type::a1_ ] && a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_or & /*f*/, A & a, int ) + { + return a[ base_type::a1_ ] || a[ base_type::a2_ ]; + } + + template bool operator()( type, logical_or const & /*f*/, A & a, int ) const + { + return a[ base_type::a1_ ] || a[ base_type::a2_ ]; + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list2 const & rhs) const + { + return ref_compare(base_type::a1_, rhs.a1_, 0) && ref_compare(base_type::a2_, rhs.a2_, 0); + } +}; + +template< class A1, class A2, class A3 > class list3: private storage3< A1, A2, A3 > +{ +private: + + typedef storage3< A1, A2, A3 > base_type; + +public: + + list3( A1 a1, A2 a2, A3 a3 ): base_type( a1, a2, a3 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list3 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4 > class list4: private storage4< A1, A2, A3, A4 > +{ +private: + + typedef storage4< A1, A2, A3, A4 > base_type; + +public: + + list4( A1 a1, A2 a2, A3 a3, A4 a4 ): base_type( a1, a2, a3, a4 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list4 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5 > class list5: private storage5< A1, A2, A3, A4, A5 > +{ +private: + + typedef storage5< A1, A2, A3, A4, A5 > base_type; + +public: + + list5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): base_type( a1, a2, a3, a4, a5 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list5 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ); + } +}; + +template class list6: private storage6< A1, A2, A3, A4, A5, A6 > +{ +private: + + typedef storage6< A1, A2, A3, A4, A5, A6 > base_type; + +public: + + list6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): base_type( a1, a2, a3, a4, a5, a6 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list6 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ); + } +}; + +template class list7: private storage7< A1, A2, A3, A4, A5, A6, A7 > +{ +private: + + typedef storage7< A1, A2, A3, A4, A5, A6, A7 > base_type; + +public: + + list7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): base_type( a1, a2, a3, a4, a5, a6, a7 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list7 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class list8: private storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ +private: + + typedef storage8< A1, A2, A3, A4, A5, A6, A7, A8 > base_type; + +public: + + list8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + A8 operator[] (boost::arg<8>) const { return base_type::a8_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list8 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ) && + ref_compare( base_type::a8_, rhs.a8_, 0 ); + } +}; + +template class list9: private storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > +{ +private: + + typedef storage9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > base_type; + +public: + + list9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): base_type( a1, a2, a3, a4, a5, a6, a7, a8, a9 ) {} + + A1 operator[] (boost::arg<1>) const { return base_type::a1_; } + A2 operator[] (boost::arg<2>) const { return base_type::a2_; } + A3 operator[] (boost::arg<3>) const { return base_type::a3_; } + A4 operator[] (boost::arg<4>) const { return base_type::a4_; } + A5 operator[] (boost::arg<5>) const { return base_type::a5_; } + A6 operator[] (boost::arg<6>) const { return base_type::a6_; } + A7 operator[] (boost::arg<7>) const { return base_type::a7_; } + A8 operator[] (boost::arg<8>) const { return base_type::a8_; } + A9 operator[] (boost::arg<9>) const { return base_type::a9_; } + + A1 operator[] (boost::arg<1> (*) ()) const { return base_type::a1_; } + A2 operator[] (boost::arg<2> (*) ()) const { return base_type::a2_; } + A3 operator[] (boost::arg<3> (*) ()) const { return base_type::a3_; } + A4 operator[] (boost::arg<4> (*) ()) const { return base_type::a4_; } + A5 operator[] (boost::arg<5> (*) ()) const { return base_type::a5_; } + A6 operator[] (boost::arg<6> (*) ()) const { return base_type::a6_; } + A7 operator[] (boost::arg<7> (*) ()) const { return base_type::a7_; } + A8 operator[] (boost::arg<8> (*) ()) const { return base_type::a8_; } + A9 operator[] (boost::arg<9> (*) ()) const { return base_type::a9_; } + + template T & operator[] (_bi::value & v) const { return v.get(); } + + template T const & operator[] (_bi::value const & v) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } + + template R operator()(type, F & f, A & a, long) + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template R operator()(type, F const & f, A & a, long) const + { + return unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void operator()(type, F & f, A & a, int) + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void operator()(type, F const & f, A & a, int) const + { + unwrapper::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_], a[base_type::a3_], a[base_type::a4_], a[base_type::a5_], a[base_type::a6_], a[base_type::a7_], a[base_type::a8_], a[base_type::a9_]); + } + + template void accept(V & v) const + { + base_type::accept(v); + } + + bool operator==(list9 const & rhs) const + { + return + + ref_compare( base_type::a1_, rhs.a1_, 0 ) && + ref_compare( base_type::a2_, rhs.a2_, 0 ) && + ref_compare( base_type::a3_, rhs.a3_, 0 ) && + ref_compare( base_type::a4_, rhs.a4_, 0 ) && + ref_compare( base_type::a5_, rhs.a5_, 0 ) && + ref_compare( base_type::a6_, rhs.a6_, 0 ) && + ref_compare( base_type::a7_, rhs.a7_, 0 ) && + ref_compare( base_type::a8_, rhs.a8_, 0 ) && + ref_compare( base_type::a9_, rhs.a9_, 0 ); + } +}; + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +// bind_t + +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) + +template< class A1 > class rrlist1 +{ +private: + + A1 & a1_; // not A1&& because of msvc-10.0 + +public: + + explicit rrlist1( A1 & a1 ): a1_( a1 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } // not static_cast because of g++ 4.9 + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist1 a( a1_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist1 a( a1_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2 > class rrlist2 +{ +private: + + A1 & a1_; + A2 & a2_; + +public: + + rrlist2( A1 & a1, A2 & a2 ): a1_( a1 ), a2_( a2 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist2 a( a1_, a2_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist2 a( a1_, a2_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3 > class rrlist3 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + +public: + + rrlist3( A1 & a1, A2 & a2, A3 & a3 ): a1_( a1 ), a2_( a2 ), a3_( a3 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist3 a( a1_, a2_, a3_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist3 a( a1_, a2_, a3_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4 > class rrlist4 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + +public: + + rrlist4( A1 & a1, A2 & a2, A3 & a3, A4 & a4 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist4 a( a1_, a2_, a3_, a4_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist4 a( a1_, a2_, a3_, a4_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5 > class rrlist5 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + +public: + + rrlist5( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist5 a( a1_, a2_, a3_, a4_, a5_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist5 a( a1_, a2_, a3_, a4_, a5_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6 > class rrlist6 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + +public: + + rrlist6( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist6 a( a1_, a2_, a3_, a4_, a5_, a6_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist6 a( a1_, a2_, a3_, a4_, a5_, a6_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7 > class rrlist7 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + +public: + + rrlist7( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist7 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist7 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class rrlist8 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + A8 & a8_; + +public: + + rrlist8( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8>) const { return std::forward( a8_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward( a8_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist8 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist8 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_ ); + return b.eval( a ); + } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > class rrlist9 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + A8 & a8_; + A9 & a9_; + +public: + + rrlist9( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ), a9_( a9 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8>) const { return std::forward( a8_ ); } + A9 && operator[] (boost::arg<9>) const { return std::forward( a9_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward( a8_ ); } + A9 && operator[] (boost::arg<9> (*) ()) const { return std::forward( a9_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const + { + rrlist9 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_ ); + return b.eval( a ); + } + + template typename result_traits::type operator[] (bind_t const & b) const + { + rrlist9 a( a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_ ); + return b.eval( a ); + } +}; + +template class bind_t +{ +private: + + F f_; + L l_; + +public: + + typedef typename result_traits::type result_type; + typedef bind_t this_type; + + bind_t( F f, L const & l ): f_( f ), l_( l ) {} + + // + + result_type operator()() + { + list0 a; + return l_( type(), f_, a, 0 ); + } + + result_type operator()() const + { + list0 a; + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1 ) + { + rrlist1< A1 > a( a1 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1 ) const + { + rrlist1< A1 > a( a1 ); + return l_(type(), f_, a, 0); + } + + template result_type operator()( A1 && a1, A2 && a2 ) + { + rrlist2< A1, A2 > a( a1, a2 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2 ) const + { + rrlist2< A1, A2 > a( a1, a2 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) + { + rrlist3< A1, A2, A3 > a( a1, a2, a3 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) const + { + rrlist3< A1, A2, A3 > a( a1, a2, a3 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) + { + rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) const + { + rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) + { + rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) const + { + rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) + { + rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) const + { + rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) + { + rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) const + { + rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) + { + rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) const + { + rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) + { + rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + return l_( type(), f_, a, 0 ); + } + + template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) const + { + rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); + return l_( type(), f_, a, 0 ); + } + + // + + template result_type eval( A & a ) + { + return l_( type(), f_, a, 0 ); + } + + template result_type eval( A & a ) const + { + return l_( type(), f_, a, 0 ); + } + + template void accept( V & v ) const + { +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( BOOST_BORLANDC ) + using boost::visit_each; +#endif + + BOOST_BIND_VISIT_EACH( v, f_, 0 ); + l_.accept( v ); + } + + bool compare( this_type const & rhs ) const + { + return ref_compare( f_, rhs.f_, 0 ) && l_ == rhs.l_; + } +}; + +#elif !defined( BOOST_NO_VOID_RETURNS ) + +template class bind_t +{ +public: + + typedef bind_t this_type; + + bind_t(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN return +#include +#undef BOOST_BIND_RETURN + +}; + +#else // no void returns + +template struct bind_t_generator +{ + +template class implementation +{ +public: + + typedef implementation this_type; + + implementation(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN return +#include +#undef BOOST_BIND_RETURN + +}; + +}; + +template<> struct bind_t_generator +{ + +template class implementation +{ +private: + + typedef void R; + +public: + + typedef implementation this_type; + + implementation(F f, L const & l): f_(f), l_(l) {} + +#define BOOST_BIND_RETURN +#include +#undef BOOST_BIND_RETURN + +}; + +}; + +template class bind_t: public bind_t_generator::BOOST_NESTED_TEMPLATE implementation +{ +public: + + bind_t(F f, L const & l): bind_t_generator::BOOST_NESTED_TEMPLATE implementation(f, l) {} + +}; + +#endif + +// function_equal + +#ifndef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// put overloads in _bi, rely on ADL + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template bool function_equal( bind_t const & a, bind_t const & b ) +{ + return a.compare(b); +} + +# else + +template bool function_equal_impl( bind_t const & a, bind_t const & b, int ) +{ + return a.compare(b); +} + +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +#else // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// put overloads in boost + +} // namespace _bi + +# ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +template bool function_equal( _bi::bind_t const & a, _bi::bind_t const & b ) +{ + return a.compare(b); +} + +# else + +template bool function_equal_impl( _bi::bind_t const & a, _bi::bind_t const & b, int ) +{ + return a.compare(b); +} + +# endif // #ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING + +namespace _bi +{ + +#endif // BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP + +// add_value + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || (__SUNPRO_CC >= 0x530) + +#if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x582) ) + +template struct add_value +{ + typedef _bi::value type; +}; + +#else + +template< class T, int I > struct add_value_2 +{ + typedef boost::arg type; +}; + +template< class T > struct add_value_2< T, 0 > +{ + typedef _bi::value< T > type; +}; + +template struct add_value +{ + typedef typename add_value_2< T, boost::is_placeholder< T >::value >::type type; +}; + +#endif + +template struct add_value< value > +{ + typedef _bi::value type; +}; + +template struct add_value< reference_wrapper > +{ + typedef reference_wrapper type; +}; + +template struct add_value< arg > +{ + typedef boost::arg type; +}; + +template struct add_value< arg (*) () > +{ + typedef boost::arg (*type) (); +}; + +template struct add_value< bind_t > +{ + typedef bind_t type; +}; + +#else + +template struct _avt_0; + +template<> struct _avt_0<1> +{ + template struct inner + { + typedef T type; + }; +}; + +template<> struct _avt_0<2> +{ + template struct inner + { + typedef value type; + }; +}; + +typedef char (&_avt_r1) [1]; +typedef char (&_avt_r2) [2]; + +template _avt_r1 _avt_f(value); +template _avt_r1 _avt_f(reference_wrapper); +template _avt_r1 _avt_f(arg); +template _avt_r1 _avt_f(arg (*) ()); +template _avt_r1 _avt_f(bind_t); + +_avt_r2 _avt_f(...); + +template struct add_value +{ + static T t(); + typedef typename _avt_0::template inner::type type; +}; + +#endif + +// list_av_N + +template struct list_av_1 +{ + typedef typename add_value::type B1; + typedef list1 type; +}; + +template struct list_av_2 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef list2 type; +}; + +template struct list_av_3 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef list3 type; +}; + +template struct list_av_4 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef list4 type; +}; + +template struct list_av_5 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef list5 type; +}; + +template struct list_av_6 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef list6 type; +}; + +template struct list_av_7 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef list7 type; +}; + +template struct list_av_8 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef typename add_value::type B8; + typedef list8 type; +}; + +template struct list_av_9 +{ + typedef typename add_value::type B1; + typedef typename add_value::type B2; + typedef typename add_value::type B3; + typedef typename add_value::type B4; + typedef typename add_value::type B5; + typedef typename add_value::type B6; + typedef typename add_value::type B7; + typedef typename add_value::type B8; + typedef typename add_value::type B9; + typedef list9 type; +}; + +// operator! + +struct logical_not +{ + template bool operator()(V const & v) const { return !v; } +}; + +template + bind_t< bool, logical_not, list1< bind_t > > + operator! (bind_t const & f) +{ + typedef list1< bind_t > list_type; + return bind_t ( logical_not(), list_type(f) ); +} + +// relational operators + +#define BOOST_BIND_OPERATOR( op, name ) \ +\ +struct name \ +{ \ + template bool operator()(V const & v, W const & w) const { return v op w; } \ +}; \ + \ +template \ + bind_t< bool, name, list2< bind_t, typename add_value::type > > \ + operator op (bind_t const & f, A2 a2) \ +{ \ + typedef typename add_value::type B2; \ + typedef list2< bind_t, B2> list_type; \ + return bind_t ( name(), list_type(f, a2) ); \ +} + +BOOST_BIND_OPERATOR( ==, equal ) +BOOST_BIND_OPERATOR( !=, not_equal ) + +BOOST_BIND_OPERATOR( <, less ) +BOOST_BIND_OPERATOR( <=, less_equal ) + +BOOST_BIND_OPERATOR( >, greater ) +BOOST_BIND_OPERATOR( >=, greater_equal ) + +BOOST_BIND_OPERATOR( &&, logical_and ) +BOOST_BIND_OPERATOR( ||, logical_or ) + +#undef BOOST_BIND_OPERATOR + +#if defined(__GNUC__) && BOOST_WORKAROUND(__GNUC__, < 3) + +// resolve ambiguity with rel_ops + +#define BOOST_BIND_OPERATOR( op, name ) \ +\ +template \ + bind_t< bool, name, list2< bind_t, bind_t > > \ + operator op (bind_t const & f, bind_t const & g) \ +{ \ + typedef list2< bind_t, bind_t > list_type; \ + return bind_t ( name(), list_type(f, g) ); \ +} + +BOOST_BIND_OPERATOR( !=, not_equal ) +BOOST_BIND_OPERATOR( <=, less_equal ) +BOOST_BIND_OPERATOR( >, greater ) +BOOST_BIND_OPERATOR( >=, greater_equal ) + +#endif + +// visit_each, ADL + +#if !defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) && !defined( BOOST_BORLANDC ) \ + && !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + +template void visit_each( V & v, value const & t, int ) +{ + using boost::visit_each; + BOOST_BIND_VISIT_EACH( v, t.get(), 0 ); +} + +template void visit_each( V & v, bind_t const & t, int ) +{ + t.accept( v ); +} + +#endif + +} // namespace _bi + +// visit_each, no ADL + +#if defined( BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP ) || defined( BOOST_BORLANDC ) \ + || (defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) + +template void visit_each( V & v, _bi::value const & t, int ) +{ + BOOST_BIND_VISIT_EACH( v, t.get(), 0 ); +} + +template void visit_each( V & v, _bi::bind_t const & t, int ) +{ + t.accept( v ); +} + +#endif + +// is_bind_expression + +template< class T > struct is_bind_expression +{ + enum _vt { value = 0 }; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template< class R, class F, class L > struct is_bind_expression< _bi::bind_t< R, F, L > > +{ + enum _vt { value = 1 }; +}; + +#endif + +// bind + +#ifndef BOOST_BIND +#define BOOST_BIND bind +#endif + +// generic function objects + +template + _bi::bind_t + BOOST_BIND(F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +// generic function objects, alternative syntax + +template + _bi::bind_t + BOOST_BIND(boost::type, F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(boost::type, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +// adaptable function objects + +template + _bi::bind_t<_bi::unspecified, F, _bi::list0> + BOOST_BIND(F f) +{ + typedef _bi::list0 list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type()); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_1::type> + BOOST_BIND(F f, A1 a1) +{ + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_2::type> + BOOST_BIND(F f, A1 a1, A2 a2) +{ + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type> (f, list_type(a1, a2)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_3::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3) +{ + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_4::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_5::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_6::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_7::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_8::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t<_bi::unspecified, F, typename _bi::list_av_9::type> + BOOST_BIND(F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t<_bi::unspecified, F, list_type>(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +#endif // !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) + +// function pointers + +#define BOOST_BIND_CC +#define BOOST_BIND_ST +#define BOOST_BIND_NOEXCEPT + +#include + +# if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) +# undef BOOST_BIND_NOEXCEPT +# define BOOST_BIND_NOEXCEPT noexcept +# include +# endif + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST +#undef BOOST_BIND_NOEXCEPT + +#if defined(BOOST_BIND_ENABLE_STDCALL) && !defined(_M_X64) + +#define BOOST_BIND_CC __stdcall +#define BOOST_BIND_ST +#define BOOST_BIND_NOEXCEPT + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST +#undef BOOST_BIND_NOEXCEPT + +#endif + +#if defined(BOOST_BIND_ENABLE_FASTCALL) && !defined(_M_X64) + +#define BOOST_BIND_CC __fastcall +#define BOOST_BIND_ST +#define BOOST_BIND_NOEXCEPT + +#include + +#undef BOOST_BIND_CC +#undef BOOST_BIND_ST +#undef BOOST_BIND_NOEXCEPT + +#endif + +#ifdef BOOST_BIND_ENABLE_PASCAL + +#define BOOST_BIND_ST pascal +#define BOOST_BIND_CC +#define BOOST_BIND_NOEXCEPT + +#include + +#undef BOOST_BIND_ST +#undef BOOST_BIND_CC +#undef BOOST_BIND_NOEXCEPT + +#endif + +// member function pointers + +#define BOOST_BIND_MF_NAME(X) X +#define BOOST_BIND_MF_CC +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +# if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) +# undef BOOST_BIND_MF_NOEXCEPT +# define BOOST_BIND_MF_NOEXCEPT noexcept +# include +# include +# endif + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) + +#define BOOST_BIND_MF_NAME(X) X##_cdecl +#define BOOST_BIND_MF_CC __cdecl +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64) + +#define BOOST_BIND_MF_NAME(X) X##_stdcall +#define BOOST_BIND_MF_CC __stdcall +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64) + +#define BOOST_BIND_MF_NAME(X) X##_fastcall +#define BOOST_BIND_MF_CC __fastcall +#define BOOST_BIND_MF_NOEXCEPT + +#include +#include + +#undef BOOST_BIND_MF_NAME +#undef BOOST_BIND_MF_CC +#undef BOOST_BIND_MF_NOEXCEPT + +#endif + +// data member pointers + +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) || defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) \ + || ( defined(BOOST_BORLANDC) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT( 0x620 ) ) ) + +template +_bi::bind_t< R, _mfi::dm, typename _bi::list_av_1::type > + BOOST_BIND(R T::*f, A1 a1) +{ + typedef _mfi::dm F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t( F(f), list_type(a1) ); +} + +#else + +namespace _bi +{ + +template< class Pm, int I > struct add_cref; + +template< class M, class T > struct add_cref< M T::*, 0 > +{ + typedef M type; +}; + +template< class M, class T > struct add_cref< M T::*, 1 > +{ +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4180) +#endif + typedef M const & type; +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +}; + +template< class R, class T > struct add_cref< R (T::*) (), 1 > +{ + typedef void type; +}; + +#if !defined(__IBMCPP__) || __IBMCPP_FUNC_CV_TMPL_ARG_DEDUCTION + +template< class R, class T > struct add_cref< R (T::*) () const, 1 > +{ + typedef void type; +}; + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) + +template< class R, class T > struct add_cref< R (T::*) () const noexcept, 1 > +{ + typedef void type; +}; + +#endif // __cpp_noexcept_function_type + +#endif // __IBMCPP__ + +template struct isref +{ + enum value_type { value = 0 }; +}; + +template struct isref< R& > +{ + enum value_type { value = 1 }; +}; + +template struct isref< R* > +{ + enum value_type { value = 1 }; +}; + +template struct dm_result +{ + typedef typename add_cref< Pm, 1 >::type type; +}; + +template struct dm_result< Pm, bind_t > +{ + typedef typename bind_t::result_type result_type; + typedef typename add_cref< Pm, isref< result_type >::value >::type type; +}; + +} // namespace _bi + +template< class A1, class M, class T > + +_bi::bind_t< + typename _bi::dm_result< M T::*, A1 >::type, + _mfi::dm, + typename _bi::list_av_1::type +> + +BOOST_BIND( M T::*f, A1 a1 ) +{ + typedef typename _bi::dm_result< M T::*, A1 >::type result_type; + typedef _mfi::dm F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t< result_type, F, list_type >( F( f ), list_type( a1 ) ); +} + +#endif + +} // namespace boost + +#ifndef BOOST_BIND_NO_PLACEHOLDERS + +# include + +#endif + +#ifdef BOOST_MSVC +# pragma warning(default: 4512) // assignment operator could not be generated +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_BIND_BIND_HPP_INCLUDED diff --git a/src/vendor/boost/bind/bind_cc.hpp b/src/vendor/boost/bind/bind_cc.hpp new file mode 100644 index 000000000..278aa9a2a --- /dev/null +++ b/src/vendor/boost/bind/bind_cc.hpp @@ -0,0 +1,117 @@ +// +// bind/bind_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +template + _bi::bind_t + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) () BOOST_BIND_NOEXCEPT) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) () BOOST_BIND_NOEXCEPT; + typedef _bi::list0 list_type; + return _bi::bind_t (f, list_type()); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1) BOOST_BIND_NOEXCEPT, A1 a1) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t (f, list_type(a1)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t (f, list_type(a1, a2)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t::type> + BOOST_BIND(BOOST_BIND_ST R (BOOST_BIND_CC *f) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef BOOST_BIND_ST R (BOOST_BIND_CC *F) (B1, B2, B3, B4, B5, B6, B7, B8, B9) BOOST_BIND_NOEXCEPT; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(f, list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/src/vendor/boost/bind/bind_mf2_cc.hpp b/src/vendor/boost/bind/bind_mf2_cc.hpp new file mode 100644 index 000000000..be20b1d90 --- /dev/null +++ b/src/vendor/boost/bind/bind_mf2_cc.hpp @@ -0,0 +1,228 @@ +// +// bind/bind_mf2_cc.hpp - member functions, type<> syntax +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +// 0 + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +// 1 + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +// 2 + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +// 3 + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +// 4 + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +// 5 + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +// 6 + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +// 7 + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +// 8 + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(boost::type, R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/src/vendor/boost/bind/bind_mf_cc.hpp b/src/vendor/boost/bind/bind_mf_cc.hpp new file mode 100644 index 000000000..bbfd3719b --- /dev/null +++ b/src/vendor/boost/bind/bind_mf_cc.hpp @@ -0,0 +1,441 @@ +// +// bind/bind_mf_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +// 0 + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + _bi::bind_t, typename _bi::list_av_1::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_1::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_1::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) () const BOOST_BIND_MF_NOEXCEPT, A1 a1) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf0) F; + typedef typename _bi::list_av_1::type list_type; + return _bi::bind_t(F(f), list_type(a1)); +} + +// 1 + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + _bi::bind_t, typename _bi::list_av_2::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_2::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_2::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf1) F; + typedef typename _bi::list_av_2::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2)); +} + +// 2 + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + _bi::bind_t, typename _bi::list_av_3::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_3::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_3::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf2) F; + typedef typename _bi::list_av_3::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3)); +} + +// 3 + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + _bi::bind_t, typename _bi::list_av_4::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_4::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_4::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf3) F; + typedef typename _bi::list_av_4::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4)); +} + +// 4 + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + _bi::bind_t, typename _bi::list_av_5::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_5::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_5::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf4) F; + typedef typename _bi::list_av_5::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5)); +} + +// 5 + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + _bi::bind_t, typename _bi::list_av_6::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_6::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_6::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf5) F; + typedef typename _bi::list_av_6::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6)); +} + +// 6 + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + _bi::bind_t, typename _bi::list_av_7::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_7::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_7::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf6) F; + typedef typename _bi::list_av_7::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7)); +} + +// 7 + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + _bi::bind_t, typename _bi::list_av_8::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_8::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_8::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf7) F; + typedef typename _bi::list_av_8::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8)); +} + +// 8 + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + _bi::bind_t, typename _bi::list_av_9::type> + BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_9::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(mf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template + typename boost::enable_if_c::value, + _bi::bind_t, typename _bi::list_av_9::type> + >::type BOOST_BIND(R (BOOST_BIND_MF_CC T::*f) (B1, B2, B3, B4, B5, B6, B7, B8) const BOOST_BIND_MF_NOEXCEPT, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) +{ + typedef _mfi::BOOST_BIND_MF_NAME(cmf8) F; + typedef typename _bi::list_av_9::type list_type; + return _bi::bind_t(F(f), list_type(a1, a2, a3, a4, a5, a6, a7, a8, a9)); +} diff --git a/src/vendor/boost/bind/detail/result_traits.hpp b/src/vendor/boost/bind/detail/result_traits.hpp new file mode 100644 index 000000000..e6b8a44e6 --- /dev/null +++ b/src/vendor/boost/bind/detail/result_traits.hpp @@ -0,0 +1,154 @@ +#ifndef BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED +#define BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/detail/result_traits.hpp +// +// boost/bind.hpp support header, return type deduction +// +// Copyright 2006, 2020 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#if defined(_MSVC_LANG) && _MSVC_LANG >= 17 +#include +#endif + +namespace boost +{ + +namespace _bi +{ + +template struct result_traits +{ + typedef R type; +}; + +struct unspecified {}; + +template struct result_traits +{ + typedef typename F::result_type type; +}; + +template struct result_traits< unspecified, reference_wrapper > +{ + typedef typename F::result_type type; +}; + +#if defined(_MSVC_LANG) && _MSVC_LANG >= 17 + +template struct result_traits< unspecified, std::plus > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::minus > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::multiplies > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::divides > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::modulus > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::negate > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::equal_to > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::not_equal_to > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::greater > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::less > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::greater_equal > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::less_equal > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::logical_and > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::logical_or > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::logical_not > +{ + typedef bool type; +}; + +template struct result_traits< unspecified, std::bit_and > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::bit_or > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::bit_xor > +{ + typedef T type; +}; + +template struct result_traits< unspecified, std::bit_not > +{ + typedef T type; +}; + +#endif + +} // namespace _bi + +} // namespace boost + +#endif // #ifndef BOOST_BIND_DETAIL_RESULT_TRAITS_HPP_INCLUDED diff --git a/src/vendor/boost/bind/mem_fn.hpp b/src/vendor/boost/bind/mem_fn.hpp new file mode 100644 index 000000000..5afb0a1a8 --- /dev/null +++ b/src/vendor/boost/bind/mem_fn.hpp @@ -0,0 +1,403 @@ +#ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED +#define BOOST_BIND_MEM_FN_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// mem_fn.hpp - a generalization of std::mem_fun[_ref] +// +// Copyright (c) 2001, 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2001 David Abrahams +// Copyright (c) 2003-2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +#include +#include +#include + +namespace boost +{ + +#if defined(BOOST_NO_VOID_RETURNS) + +#define BOOST_MEM_FN_CLASS_F , class F +#define BOOST_MEM_FN_TYPEDEF(X) + +namespace _mfi // mem_fun_impl +{ + +template struct mf +{ + +#define BOOST_MEM_FN_RETURN return + +#define BOOST_MEM_FN_NAME(X) inner_##X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) inner_##X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) inner_##X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#undef BOOST_MEM_FN_RETURN + +}; // struct mf + +template<> struct mf +{ + +#define BOOST_MEM_FN_RETURN + +#define BOOST_MEM_FN_NAME(X) inner_##X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) inner_##X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) inner_##X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#undef BOOST_MEM_FN_RETURN + +}; // struct mf + +#undef BOOST_MEM_FN_CLASS_F +#undef BOOST_MEM_FN_TYPEDEF_F + +#define BOOST_MEM_FN_NAME(X) X +#define BOOST_MEM_FN_NAME2(X) inner_##X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_cdecl +#define BOOST_MEM_FN_NAME2(X) inner_##X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_STDCALL + +#define BOOST_MEM_FN_NAME(X) X##_stdcall +#define BOOST_MEM_FN_NAME2(X) inner_##X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#endif + +#ifdef BOOST_MEM_FN_ENABLE_FASTCALL + +#define BOOST_MEM_FN_NAME(X) X##_fastcall +#define BOOST_MEM_FN_NAME2(X) inner_##X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_NAME2 +#undef BOOST_MEM_FN_CC + +#endif + +} // namespace _mfi + +#else // #ifdef BOOST_NO_VOID_RETURNS + +#define BOOST_MEM_FN_CLASS_F +#define BOOST_MEM_FN_TYPEDEF(X) typedef X; + +namespace _mfi +{ + +#define BOOST_MEM_FN_RETURN return + +#define BOOST_MEM_FN_NAME(X) X +#define BOOST_MEM_FN_CC + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_cdecl +#define BOOST_MEM_FN_CC __cdecl + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_stdcall +#define BOOST_MEM_FN_CC __stdcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_fastcall +#define BOOST_MEM_FN_CC __fastcall + +#include + +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NAME + +#endif + +#undef BOOST_MEM_FN_RETURN + +} // namespace _mfi + +#undef BOOST_MEM_FN_CLASS_F +#undef BOOST_MEM_FN_TYPEDEF + +#endif // #ifdef BOOST_NO_VOID_RETURNS + +#define BOOST_MEM_FN_NAME(X) X +#define BOOST_MEM_FN_CC +#define BOOST_MEM_FN_NOEXCEPT + +#include + +#if defined( __cpp_noexcept_function_type ) || defined( _NOEXCEPT_TYPES_SUPPORTED ) +# undef BOOST_MEM_FN_NOEXCEPT +# define BOOST_MEM_FN_NOEXCEPT noexcept +# include +#endif + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NOEXCEPT + +#if defined(BOOST_MEM_FN_ENABLE_CDECL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_cdecl +#define BOOST_MEM_FN_CC __cdecl +#define BOOST_MEM_FN_NOEXCEPT + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NOEXCEPT + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_STDCALL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_stdcall +#define BOOST_MEM_FN_CC __stdcall +#define BOOST_MEM_FN_NOEXCEPT + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NOEXCEPT + +#endif + +#if defined(BOOST_MEM_FN_ENABLE_FASTCALL) && !defined(_M_X64) + +#define BOOST_MEM_FN_NAME(X) X##_fastcall +#define BOOST_MEM_FN_CC __fastcall +#define BOOST_MEM_FN_NOEXCEPT + +#include + +#undef BOOST_MEM_FN_NAME +#undef BOOST_MEM_FN_CC +#undef BOOST_MEM_FN_NOEXCEPT + +#endif + +// data member support + +namespace _mfi +{ + +template class dm +{ +public: + + typedef R const & result_type; + typedef T const * argument_type; + +private: + + typedef R (T::*F); + F f_; + + template R const & call(U & u, T const *) const + { + return (u.*f_); + } + + template R const & call(U & u, void const *) const + { + return (get_pointer(u)->*f_); + } + +public: + + explicit dm(F f): f_(f) {} + + R & operator()(T * p) const + { + return (p->*f_); + } + + R const & operator()(T const * p) const + { + return (p->*f_); + } + + template R const & operator()(U const & u) const + { + return call(u, &u); + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && !BOOST_WORKAROUND(__MWERKS__, < 0x3200) + + R & operator()(T & t) const + { + return (t.*f_); + } + + R const & operator()(T const & t) const + { + return (t.*f_); + } + +#endif + + bool operator==(dm const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(dm const & rhs) const + { + return f_ != rhs.f_; + } +}; + +} // namespace _mfi + +template _mfi::dm mem_fn(R T::*f) +{ + return _mfi::dm(f); +} + +} // namespace boost + +#endif // #ifndef BOOST_BIND_MEM_FN_HPP_INCLUDED diff --git a/src/vendor/boost/bind/mem_fn_cc.hpp b/src/vendor/boost/bind/mem_fn_cc.hpp new file mode 100644 index 000000000..03e38300a --- /dev/null +++ b/src/vendor/boost/bind/mem_fn_cc.hpp @@ -0,0 +1,103 @@ +// +// bind/mem_fn_cc.hpp - support for different calling conventions +// +// Do not include this header directly. +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +template _mfi::BOOST_MEM_FN_NAME(mf0) mem_fn(R (BOOST_MEM_FN_CC T::*f) () BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf0)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf0) mem_fn(R (BOOST_MEM_FN_CC T::*f) () const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf0)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf1) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf1)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf1) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf1)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf2) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf2)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf2) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf2)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf3) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf3)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf3) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf3)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf4) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf4)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf4) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf4)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf5) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf5)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf5) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf5)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf6) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf6)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf6) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf6)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf7) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf7)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf7) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf7)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(mf8) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8) BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(mf8)(f); +} + +template _mfi::BOOST_MEM_FN_NAME(cmf8) mem_fn(R (BOOST_MEM_FN_CC T::*f) (A1, A2, A3, A4, A5, A6, A7, A8) const BOOST_MEM_FN_NOEXCEPT) +{ + return _mfi::BOOST_MEM_FN_NAME(cmf8)(f); +} diff --git a/src/vendor/boost/bind/mem_fn_template.hpp b/src/vendor/boost/bind/mem_fn_template.hpp new file mode 100644 index 000000000..b26d585db --- /dev/null +++ b/src/vendor/boost/bind/mem_fn_template.hpp @@ -0,0 +1,1047 @@ +// +// bind/mem_fn_template.hpp +// +// Do not include this header directly +// +// Copyright (c) 2001 Peter Dimov and Multi Media Ltd. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/bind/mem_fn.html for documentation. +// + +#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING) +# define BOOST_MEM_FN_ENABLE_CONST_OVERLOADS +#endif + +// mf0 + +template class BOOST_MEM_FN_NAME(mf0) +{ +public: + + typedef R result_type; + typedef T * argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) ()) + F f_; + + template R call(U & u, T const *) const + { + BOOST_MEM_FN_RETURN (u.*f_)(); + } + + template R call(U & u, void const *) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf0)(F f): f_(f) {} + + R operator()(T * p) const + { + BOOST_MEM_FN_RETURN (p->*f_)(); + } + + template R operator()(U & u) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p); + } + +#endif + + R operator()(T & t) const + { + BOOST_MEM_FN_RETURN (t.*f_)(); + } + + bool operator==(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf0) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf0 + +template class BOOST_MEM_FN_NAME(cmf0) +{ +public: + + typedef R result_type; + typedef T const * argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) () const) + F f_; + + template R call(U & u, T const *) const + { + BOOST_MEM_FN_RETURN (u.*f_)(); + } + + template R call(U & u, void const *) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf0)(F f): f_(f) {} + + template R operator()(U const & u) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p); + } + + R operator()(T const & t) const + { + BOOST_MEM_FN_RETURN (t.*f_)(); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf0) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf1 + +template class BOOST_MEM_FN_NAME(mf1) +{ +public: + + typedef R result_type; + typedef T * first_argument_type; + typedef A1 second_argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1)) + F f_; + + template R call(U & u, T const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1); + } + + template R call(U & u, void const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf1)(F f): f_(f) {} + + R operator()(T * p, A1 a1) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1); + } + + template R operator()(U & u, A1 a1) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1); + } + +#endif + + R operator()(T & t, A1 a1) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1); + } + + bool operator==(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf1) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf1 + +template class BOOST_MEM_FN_NAME(cmf1) +{ +public: + + typedef R result_type; + typedef T const * first_argument_type; + typedef A1 second_argument_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1) const) + F f_; + + template R call(U & u, T const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1); + } + + template R call(U & u, void const *, B1 & b1) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf1)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1); + } + + R operator()(T const & t, A1 a1) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf1) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf2 + +template class BOOST_MEM_FN_NAME(mf2) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf2)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2); + } + + template R operator()(U & u, A1 a1, A2 a2) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); + } + + bool operator==(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf2) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf2 + +template class BOOST_MEM_FN_NAME(cmf2) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf2)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2); + } + + R operator()(T const & t, A1 a1, A2 a2) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf2) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf3 + +template class BOOST_MEM_FN_NAME(mf3) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf3)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); + } + + bool operator==(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf3) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf3 + +template class BOOST_MEM_FN_NAME(cmf3) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf3)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf3) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf4 + +template class BOOST_MEM_FN_NAME(mf4) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf4)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); + } + + bool operator==(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf4) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf4 + +template class BOOST_MEM_FN_NAME(cmf4) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf4)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf4) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf5 + +template class BOOST_MEM_FN_NAME(mf5) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf5)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); + } + + bool operator==(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf5) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf5 + +template class BOOST_MEM_FN_NAME(cmf5) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf5)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf5) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf6 + +template class BOOST_MEM_FN_NAME(mf6) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf6)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); + } + + bool operator==(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf6) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf6 + +template class BOOST_MEM_FN_NAME(cmf6) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf6)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf6) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf7 + +template class BOOST_MEM_FN_NAME(mf7) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf7)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + bool operator==(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf7) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf7 + +template class BOOST_MEM_FN_NAME(cmf7) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf7)(F f): f_(f) {} + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf7) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// mf8 + +template class BOOST_MEM_FN_NAME(mf8) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8)) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + +public: + + explicit BOOST_MEM_FN_NAME(mf8)(F f): f_(f) {} + + R operator()(T * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template R operator()(U & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8); + } + +#ifdef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8); + } + +#endif + + R operator()(T & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + bool operator==(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(mf8) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +// cmf8 + +template class BOOST_MEM_FN_NAME(cmf8) +{ +public: + + typedef R result_type; + +private: + + BOOST_MEM_FN_TYPEDEF(R (BOOST_MEM_FN_CC T::*F) (A1, A2, A3, A4, A5, A6, A7, A8) const) + F f_; + + template R call(U & u, T const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (u.*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + + template R call(U & u, void const *, B1 & b1, B2 & b2, B3 & b3, B4 & b4, B5 & b5, B6 & b6, B7 & b7, B8 & b8) const + { + BOOST_MEM_FN_RETURN (get_pointer(u)->*f_)(b1, b2, b3, b4, b5, b6, b7, b8); + } + +public: + + explicit BOOST_MEM_FN_NAME(cmf8)(F f): f_(f) {} + + R operator()(T const * p, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (p->*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + template R operator()(U const & u, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + U const * p = 0; + BOOST_MEM_FN_RETURN call(u, p, a1, a2, a3, a4, a5, a6, a7, a8); + } + + R operator()(T const & t, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) const + { + BOOST_MEM_FN_RETURN (t.*f_)(a1, a2, a3, a4, a5, a6, a7, a8); + } + + bool operator==(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ == rhs.f_; + } + + bool operator!=(BOOST_MEM_FN_NAME(cmf8) const & rhs) const + { + return f_ != rhs.f_; + } +}; + +#undef BOOST_MEM_FN_ENABLE_CONST_OVERLOADS diff --git a/src/vendor/boost/bind/placeholders.hpp b/src/vendor/boost/bind/placeholders.hpp new file mode 100644 index 000000000..5e4b96d8d --- /dev/null +++ b/src/vendor/boost/bind/placeholders.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED +#define BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/placeholders.hpp - _N definitions +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright 2015 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +namespace boost +{ + +namespace placeholders +{ + +#if defined(BOOST_BORLANDC) || defined(__GNUC__) && (__GNUC__ < 4) + +inline boost::arg<1> _1() { return boost::arg<1>(); } +inline boost::arg<2> _2() { return boost::arg<2>(); } +inline boost::arg<3> _3() { return boost::arg<3>(); } +inline boost::arg<4> _4() { return boost::arg<4>(); } +inline boost::arg<5> _5() { return boost::arg<5>(); } +inline boost::arg<6> _6() { return boost::arg<6>(); } +inline boost::arg<7> _7() { return boost::arg<7>(); } +inline boost::arg<8> _8() { return boost::arg<8>(); } +inline boost::arg<9> _9() { return boost::arg<9>(); } + +#elif !defined(BOOST_NO_CXX17_INLINE_VARIABLES) + +BOOST_INLINE_CONSTEXPR boost::arg<1> _1; +BOOST_INLINE_CONSTEXPR boost::arg<2> _2; +BOOST_INLINE_CONSTEXPR boost::arg<3> _3; +BOOST_INLINE_CONSTEXPR boost::arg<4> _4; +BOOST_INLINE_CONSTEXPR boost::arg<5> _5; +BOOST_INLINE_CONSTEXPR boost::arg<6> _6; +BOOST_INLINE_CONSTEXPR boost::arg<7> _7; +BOOST_INLINE_CONSTEXPR boost::arg<8> _8; +BOOST_INLINE_CONSTEXPR boost::arg<9> _9; + +#else + +BOOST_STATIC_CONSTEXPR boost::arg<1> _1; +BOOST_STATIC_CONSTEXPR boost::arg<2> _2; +BOOST_STATIC_CONSTEXPR boost::arg<3> _3; +BOOST_STATIC_CONSTEXPR boost::arg<4> _4; +BOOST_STATIC_CONSTEXPR boost::arg<5> _5; +BOOST_STATIC_CONSTEXPR boost::arg<6> _6; +BOOST_STATIC_CONSTEXPR boost::arg<7> _7; +BOOST_STATIC_CONSTEXPR boost::arg<8> _8; +BOOST_STATIC_CONSTEXPR boost::arg<9> _9; + +#endif + +} // namespace placeholders + +} // namespace boost + +#endif // #ifndef BOOST_BIND_PLACEHOLDERS_HPP_INCLUDED diff --git a/src/vendor/boost/bind/storage.hpp b/src/vendor/boost/bind/storage.hpp new file mode 100644 index 000000000..5d84027b0 --- /dev/null +++ b/src/vendor/boost/bind/storage.hpp @@ -0,0 +1,475 @@ +#ifndef BOOST_BIND_STORAGE_HPP_INCLUDED +#define BOOST_BIND_STORAGE_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// bind/storage.hpp +// +// boost/bind.hpp support header, optimized storage +// +// Copyright (c) 2006 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// See http://www.boost.org/libs/bind/bind.html for documentation. +// + +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable: 4512) // assignment operator could not be generated +#endif + +namespace boost +{ + +namespace _bi +{ + +// 1 + +template struct storage1 +{ + explicit storage1( A1 a1 ): a1_( a1 ) {} + + template void accept(V & v) const + { + BOOST_BIND_VISIT_EACH(v, a1_, 0); + } + + A1 a1_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) && !defined( BOOST_BORLANDC ) + +template struct storage1< boost::arg > +{ + explicit storage1( boost::arg ) {} + + template void accept(V &) const { } + + static boost::arg a1_() { return boost::arg(); } +}; + +template struct storage1< boost::arg (*) () > +{ + explicit storage1( boost::arg (*) () ) {} + + template void accept(V &) const { } + + static boost::arg a1_() { return boost::arg(); } +}; + +#endif + +// 2 + +template struct storage2: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, A2 a2 ): storage1( a1 ), a2_( a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a2_, 0); + } + + A2 a2_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage2< A1, boost::arg >: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, boost::arg ): storage1( a1 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a2_() { return boost::arg(); } +}; + +template struct storage2< A1, boost::arg (*) () >: public storage1 +{ + typedef storage1 inherited; + + storage2( A1 a1, boost::arg (*) () ): storage1( a1 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a2_() { return boost::arg(); } +}; + +#endif + +// 3 + +template struct storage3: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, A3 a3 ): storage2( a1, a2 ), a3_( a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a3_, 0); + } + + A3 a3_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage3< A1, A2, boost::arg >: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, boost::arg ): storage2( a1, a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a3_() { return boost::arg(); } +}; + +template struct storage3< A1, A2, boost::arg (*) () >: public storage2< A1, A2 > +{ + typedef storage2 inherited; + + storage3( A1 a1, A2 a2, boost::arg (*) () ): storage2( a1, a2 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a3_() { return boost::arg(); } +}; + +#endif + +// 4 + +template struct storage4: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, A4 a4 ): storage3( a1, a2, a3 ), a4_( a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a4_, 0); + } + + A4 a4_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage4< A1, A2, A3, boost::arg >: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, boost::arg ): storage3( a1, a2, a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a4_() { return boost::arg(); } +}; + +template struct storage4< A1, A2, A3, boost::arg (*) () >: public storage3< A1, A2, A3 > +{ + typedef storage3 inherited; + + storage4( A1 a1, A2 a2, A3 a3, boost::arg (*) () ): storage3( a1, a2, a3 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a4_() { return boost::arg(); } +}; + +#endif + +// 5 + +template struct storage5: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 ): storage4( a1, a2, a3, a4 ), a5_( a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a5_, 0); + } + + A5 a5_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage5< A1, A2, A3, A4, boost::arg >: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg ): storage4( a1, a2, a3, a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a5_() { return boost::arg(); } +}; + +template struct storage5< A1, A2, A3, A4, boost::arg (*) () >: public storage4< A1, A2, A3, A4 > +{ + typedef storage4 inherited; + + storage5( A1 a1, A2 a2, A3 a3, A4 a4, boost::arg (*) () ): storage4( a1, a2, a3, a4 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a5_() { return boost::arg(); } +}; + +#endif + +// 6 + +template struct storage6: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 ): storage5( a1, a2, a3, a4, a5 ), a6_( a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a6_, 0); + } + + A6 a6_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage6< A1, A2, A3, A4, A5, boost::arg >: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg ): storage5( a1, a2, a3, a4, a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a6_() { return boost::arg(); } +}; + +template struct storage6< A1, A2, A3, A4, A5, boost::arg (*) () >: public storage5< A1, A2, A3, A4, A5 > +{ + typedef storage5 inherited; + + storage6( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, boost::arg (*) () ): storage5( a1, a2, a3, a4, a5 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a6_() { return boost::arg(); } +}; + +#endif + +// 7 + +template struct storage7: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 ): storage6( a1, a2, a3, a4, a5, a6 ), a7_( a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a7_, 0); + } + + A7 a7_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage7< A1, A2, A3, A4, A5, A6, boost::arg >: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg ): storage6( a1, a2, a3, a4, a5, a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a7_() { return boost::arg(); } +}; + +template struct storage7< A1, A2, A3, A4, A5, A6, boost::arg (*) () >: public storage6< A1, A2, A3, A4, A5, A6 > +{ + typedef storage6 inherited; + + storage7( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, boost::arg (*) () ): storage6( a1, a2, a3, a4, a5, a6 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a7_() { return boost::arg(); } +}; + +#endif + +// 8 + +template struct storage8: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 ): storage7( a1, a2, a3, a4, a5, a6, a7 ), a8_( a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a8_, 0); + } + + A8 a8_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg >: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg ): storage7( a1, a2, a3, a4, a5, a6, a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a8_() { return boost::arg(); } +}; + +template struct storage8< A1, A2, A3, A4, A5, A6, A7, boost::arg (*) () >: public storage7< A1, A2, A3, A4, A5, A6, A7 > +{ + typedef storage7 inherited; + + storage8( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, boost::arg (*) () ): storage7( a1, a2, a3, a4, a5, a6, a7 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a8_() { return boost::arg(); } +}; + +#endif + +// 9 + +template struct storage9: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ), a9_( a9 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + BOOST_BIND_VISIT_EACH(v, a9_, 0); + } + + A9 a9_; +}; + +#if !defined( BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION ) + +template struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a9_() { return boost::arg(); } +}; + +template struct storage9< A1, A2, A3, A4, A5, A6, A7, A8, boost::arg (*) () >: public storage8< A1, A2, A3, A4, A5, A6, A7, A8 > +{ + typedef storage8 inherited; + + storage9( A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, boost::arg (*) () ): storage8( a1, a2, a3, a4, a5, a6, a7, a8 ) {} + + template void accept(V & v) const + { + inherited::accept(v); + } + + static boost::arg a9_() { return boost::arg(); } +}; + +#endif + +} // namespace _bi + +} // namespace boost + +#ifdef BOOST_MSVC +# pragma warning(default: 4512) // assignment operator could not be generated +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_BIND_STORAGE_HPP_INCLUDED diff --git a/src/vendor/boost/call_traits.hpp b/src/vendor/boost/call_traits.hpp new file mode 100644 index 000000000..2c1328e94 --- /dev/null +++ b/src/vendor/boost/call_traits.hpp @@ -0,0 +1,20 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// See boost/detail/call_traits.hpp +// for full copyright notices. + +#ifndef BOOST_CALL_TRAITS_HPP +#define BOOST_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#include + +#endif // BOOST_CALL_TRAITS_HPP diff --git a/src/vendor/boost/checked_delete.hpp b/src/vendor/boost/checked_delete.hpp new file mode 100644 index 000000000..fb71c789c --- /dev/null +++ b/src/vendor/boost/checked_delete.hpp @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2014 Glen Fernandes + * + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_CHECKED_DELETE_HPP +#define BOOST_CHECKED_DELETE_HPP + +// The header file at this path is deprecated; +// use boost/core/checked_delete.hpp instead. + +#include + +#endif diff --git a/src/vendor/boost/compressed_pair.hpp b/src/vendor/boost/compressed_pair.hpp new file mode 100644 index 000000000..a7be0f2ba --- /dev/null +++ b/src/vendor/boost/compressed_pair.hpp @@ -0,0 +1,20 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// See boost/detail/compressed_pair.hpp +// for full copyright notices. + +#ifndef BOOST_COMPRESSED_PAIR_HPP +#define BOOST_COMPRESSED_PAIR_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#include + +#endif // BOOST_COMPRESSED_PAIR_HPP diff --git a/src/vendor/boost/concept/assert.hpp b/src/vendor/boost/concept/assert.hpp new file mode 100644 index 000000000..e37350826 --- /dev/null +++ b/src/vendor/boost/concept/assert.hpp @@ -0,0 +1,45 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_ASSERT_DWA2006430_HPP +# define BOOST_CONCEPT_ASSERT_DWA2006430_HPP + +# include +# include + +// The old protocol used a constraints() member function in concept +// checking classes. If the compiler supports SFINAE, we can detect +// that function and seamlessly support the old concept checking +// classes. In this release, backward compatibility with the old +// concept checking classes is enabled by default, where available. +// The old protocol is deprecated, though, and backward compatibility +// will no longer be the default in the next release. + +# if !defined(BOOST_NO_OLD_CONCEPT_SUPPORT) \ + && !defined(BOOST_NO_SFINAE) \ + \ + && !(BOOST_WORKAROUND(__GNUC__, == 3) && BOOST_WORKAROUND(__GNUC_MINOR__, < 4)) + +// Note: gcc-2.96 through 3.3.x have some SFINAE, but no ability to +// check for the presence of particularmember functions. + +# define BOOST_OLD_CONCEPT_SUPPORT + +# endif + +# ifdef BOOST_MSVC +# include +# elif BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) +# include +# else +# include +# endif + + // Usage, in class or function context: + // + // BOOST_CONCEPT_ASSERT((UnaryFunctionConcept)); + // +# define BOOST_CONCEPT_ASSERT(ModelInParens) \ + BOOST_CONCEPT_ASSERT_FN(void(*)ModelInParens) + +#endif // BOOST_CONCEPT_ASSERT_DWA2006430_HPP diff --git a/src/vendor/boost/concept/detail/backward_compatibility.hpp b/src/vendor/boost/concept/detail/backward_compatibility.hpp new file mode 100644 index 000000000..66d573ef4 --- /dev/null +++ b/src/vendor/boost/concept/detail/backward_compatibility.hpp @@ -0,0 +1,16 @@ +// Copyright David Abrahams 2009. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP +# define BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP + +namespace boost +{ + namespace concepts {} + +# if defined(BOOST_HAS_CONCEPTS) && !defined(BOOST_CONCEPT_NO_BACKWARD_KEYWORD) + namespace concept = concepts; +# endif +} // namespace boost::concept + +#endif // BOOST_CONCEPT_BACKWARD_COMPATIBILITY_DWA200968_HPP diff --git a/src/vendor/boost/concept/detail/concept_def.hpp b/src/vendor/boost/concept/detail/concept_def.hpp new file mode 100644 index 000000000..750561ee3 --- /dev/null +++ b/src/vendor/boost/concept/detail/concept_def.hpp @@ -0,0 +1,34 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# define BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP +# include +# include +# include +# include +#endif // BOOST_CONCEPT_DETAIL_CONCEPT_DEF_DWA200651_HPP + +// BOOST_concept(SomeName, (p1)(p2)...(pN)) +// +// Expands to "template struct SomeName" +// +// Also defines an equivalent SomeNameConcept for backward compatibility. +// Maybe in the next release we can kill off the "Concept" suffix for good. +# define BOOST_concept(name, params) \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name; /* forward declaration */ \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct BOOST_PP_CAT(name,Concept) \ + : name< BOOST_PP_SEQ_ENUM(params) > \ + { \ + }; \ + \ + template < BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONCEPT_typename,~,params) > \ + struct name + +// Helper for BOOST_concept, above. +# define BOOST_CONCEPT_typename(r, ignored, index, t) \ + BOOST_PP_COMMA_IF(index) typename t + diff --git a/src/vendor/boost/concept/detail/concept_undef.hpp b/src/vendor/boost/concept/detail/concept_undef.hpp new file mode 100644 index 000000000..713db8912 --- /dev/null +++ b/src/vendor/boost/concept/detail/concept_undef.hpp @@ -0,0 +1,5 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +# undef BOOST_concept_typename +# undef BOOST_concept diff --git a/src/vendor/boost/concept/detail/general.hpp b/src/vendor/boost/concept/detail/general.hpp new file mode 100644 index 000000000..eeb08750f --- /dev/null +++ b/src/vendor/boost/concept/detail/general.hpp @@ -0,0 +1,77 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP + +# include +# include +# include + +# ifdef BOOST_OLD_CONCEPT_SUPPORT +# include +# include +# endif + +// This implementation works on Comeau and GCC, all the way back to +// 2.95 +namespace boost { namespace concepts { + +template +struct requirement_; + +namespace detail +{ + template struct instantiate {}; +} + +template +struct requirement +{ + static void failed() { ((Model*)0)->~Model(); } +}; + +struct failed {}; + +template +struct requirement +{ + static void failed() { ((Model*)0)->~Model(); } +}; + +# ifdef BOOST_OLD_CONCEPT_SUPPORT + +template +struct constraint +{ + static void failed() { ((Model*)0)->constraints(); } +}; + +template +struct requirement_ + : boost::conditional< + concepts::not_satisfied::value + , constraint + , requirement + >::type +{}; + +# else + +// For GCC-2.x, these can't have exactly the same name +template +struct requirement_ + : requirement +{}; + +# endif + +# define BOOST_CONCEPT_ASSERT_FN( ModelFnPtr ) \ + typedef ::boost::concepts::detail::instantiate< \ + &::boost::concepts::requirement_::failed> \ + BOOST_PP_CAT(boost_concept_check,__LINE__) \ + BOOST_ATTRIBUTE_UNUSED + +}} + +#endif // BOOST_CONCEPT_DETAIL_GENERAL_DWA2006429_HPP diff --git a/src/vendor/boost/concept/detail/has_constraints.hpp b/src/vendor/boost/concept/detail/has_constraints.hpp new file mode 100644 index 000000000..dc2c20714 --- /dev/null +++ b/src/vendor/boost/concept/detail/has_constraints.hpp @@ -0,0 +1,50 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP +# define BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP + +# include +# include +# include + +namespace boost { namespace concepts { + +namespace detail +{ + +// Here we implement the metafunction that detects whether a +// constraints metafunction exists + typedef char yes; + typedef char (&no)[2]; + + template + struct wrap_constraints {}; + +#if BOOST_WORKAROUND(__SUNPRO_CC, <= 0x580) || defined(__CUDACC__) + // Work around the following bogus error in Sun Studio 11, by + // turning off the has_constraints function entirely: + // Error: complex expression not allowed in dependent template + // argument expression + inline no has_constraints_(...); +#else + template + inline yes has_constraints_(Model*, wrap_constraints* = 0); + inline no has_constraints_(...); +#endif +} + +// This would be called "detail::has_constraints," but it has a strong +// tendency to show up in error messages. +template +struct not_satisfied +{ + BOOST_STATIC_CONSTANT( + bool + , value = sizeof( detail::has_constraints_((Model*)0) ) == sizeof(detail::yes) ); + typedef boost::integral_constant type; +}; + +}} // namespace boost::concepts::detail + +#endif // BOOST_CONCEPT_DETAIL_HAS_CONSTRAINTS_DWA2006429_HPP diff --git a/src/vendor/boost/concept/usage.hpp b/src/vendor/boost/concept/usage.hpp new file mode 100644 index 000000000..373de63a9 --- /dev/null +++ b/src/vendor/boost/concept/usage.hpp @@ -0,0 +1,36 @@ +// Copyright David Abrahams 2006. Distributed under the Boost +// Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONCEPT_USAGE_DWA2006919_HPP +# define BOOST_CONCEPT_USAGE_DWA2006919_HPP + +# include +# include +# include + +namespace boost { namespace concepts { + +template +struct usage_requirements +{ + ~usage_requirements() { ((Model*)0)->~Model(); } +}; + +# if BOOST_WORKAROUND(__GNUC__, <= 3) + +# define BOOST_CONCEPT_USAGE(model) \ + model(); /* at least 2.96 and 3.4.3 both need this :( */ \ + BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \ + ~model() + +# else + +# define BOOST_CONCEPT_USAGE(model) \ + BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements)); \ + ~model() + +# endif + +}} // namespace boost::concepts + +#endif // BOOST_CONCEPT_USAGE_DWA2006919_HPP diff --git a/src/vendor/boost/concept_check.hpp b/src/vendor/boost/concept_check.hpp new file mode 100644 index 000000000..abbadb76b --- /dev/null +++ b/src/vendor/boost/concept_check.hpp @@ -0,0 +1,1082 @@ +// +// (C) Copyright Jeremy Siek 2000. +// Copyright 2002 The Trustees of Indiana University. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// Revision History: +// 05 May 2001: Workarounds for HP aCC from Thomas Matelich. (Jeremy Siek) +// 02 April 2001: Removed limits header altogether. (Jeremy Siek) +// 01 April 2001: Modified to use new header. (JMaddock) +// + +// See http://www.boost.org/libs/concept_check for documentation. + +#ifndef BOOST_CONCEPT_CHECKS_HPP +# define BOOST_CONCEPT_CHECKS_HPP + +# include + +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + +#if (defined _MSC_VER) +# pragma warning( push ) +# pragma warning( disable : 4510 ) // default constructor could not be generated +# pragma warning( disable : 4610 ) // object 'class' can never be instantiated - user-defined constructor required +#endif + +namespace boost +{ + + // + // Backward compatibility + // + + template + inline void function_requires(Model* = 0) + { + BOOST_CONCEPT_ASSERT((Model)); + } + template inline void ignore_unused_variable_warning(T const&) {} + +# define BOOST_CLASS_REQUIRE(type_var, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE2(type_var1, type_var2, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE3(tv1, tv2, tv3, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + +# define BOOST_CLASS_REQUIRE4(tv1, tv2, tv3, tv4, ns, concept) \ + BOOST_CONCEPT_ASSERT((ns::concept)) + + + // + // Begin concept definitions + // + BOOST_concept(Integer, (T)) + { + BOOST_CONCEPT_USAGE(Integer) + { + x.error_type_must_be_an_integer_type(); + } + private: + T x; + }; + + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; + template <> struct Integer {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct Integer< ::boost::long_long_type> {}; + template <> struct Integer< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct Integer<__int64> {}; + template <> struct Integer {}; +# endif + + BOOST_concept(SignedInteger,(T)) { + BOOST_CONCEPT_USAGE(SignedInteger) { + x.error_type_must_be_a_signed_integer_type(); + } + private: + T x; + }; + template <> struct SignedInteger { }; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; + template <> struct SignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct SignedInteger< ::boost::long_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct SignedInteger<__int64> {}; +# endif + + BOOST_concept(UnsignedInteger,(T)) { + BOOST_CONCEPT_USAGE(UnsignedInteger) { + x.error_type_must_be_an_unsigned_integer_type(); + } + private: + T x; + }; + + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; + template <> struct UnsignedInteger {}; +# if defined(BOOST_HAS_LONG_LONG) + template <> struct UnsignedInteger< ::boost::ulong_long_type> {}; +# elif defined(BOOST_HAS_MS_INT64) + template <> struct UnsignedInteger {}; +# endif + + //=========================================================================== + // Basic Concepts + + BOOST_concept(DefaultConstructible,(TT)) + { + BOOST_CONCEPT_USAGE(DefaultConstructible) { + TT a; // require default constructor + ignore_unused_variable_warning(a); + } + }; + + BOOST_concept(Assignable,(TT)) + { + BOOST_CONCEPT_USAGE(Assignable) { +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = b; // require assignment operator +#endif + const_constraints(b); + } + private: + void const_constraints(const TT& x) { +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = x; // const required for argument to assignment +#else + ignore_unused_variable_warning(x); +#endif + } + private: + TT a; + TT b; + }; + + + BOOST_concept(CopyConstructible,(TT)) + { + BOOST_CONCEPT_USAGE(CopyConstructible) { + TT a(b); // require copy constructor + TT* ptr = &a; // require address of operator + const_constraints(a); + ignore_unused_variable_warning(ptr); + } + private: + void const_constraints(const TT& a) { + TT c(a); // require const copy constructor + const TT* ptr = &a; // require const address of operator + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(ptr); + } + TT b; + }; + + // The SGI STL version of Assignable requires copy constructor and operator= + BOOST_concept(SGIAssignable,(TT)) + { + BOOST_CONCEPT_USAGE(SGIAssignable) { + TT c(a); +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = b; // require assignment operator +#endif + const_constraints(b); + ignore_unused_variable_warning(c); + } + private: + void const_constraints(const TT& x) { + TT c(x); +#if !defined(_ITERATOR_) // back_insert_iterator broken for VC++ STL + a = x; // const required for argument to assignment +#endif + ignore_unused_variable_warning(c); + } + TT a; + TT b; + }; + + BOOST_concept(Convertible,(X)(Y)) + { + BOOST_CONCEPT_USAGE(Convertible) { + Y y = x; + ignore_unused_variable_warning(y); + } + private: + X x; + }; + + // The C++ standard requirements for many concepts talk about return + // types that must be "convertible to bool". The problem with this + // requirement is that it leaves the door open for evil proxies that + // define things like operator|| with strange return types. Two + // possible solutions are: + // 1) require the return type to be exactly bool + // 2) stay with convertible to bool, and also + // specify stuff about all the logical operators. + // For now we just test for convertible to bool. + template + void require_boolean_expr(const TT& t) { + bool x = t; + ignore_unused_variable_warning(x); + } + + BOOST_concept(EqualityComparable,(TT)) + { + BOOST_CONCEPT_USAGE(EqualityComparable) { + require_boolean_expr(a == b); + require_boolean_expr(a != b); + } + private: + TT a, b; + }; + + BOOST_concept(LessThanComparable,(TT)) + { + BOOST_CONCEPT_USAGE(LessThanComparable) { + require_boolean_expr(a < b); + } + private: + TT a, b; + }; + + // This is equivalent to SGI STL's LessThanComparable. + BOOST_concept(Comparable,(TT)) + { + BOOST_CONCEPT_USAGE(Comparable) { + require_boolean_expr(a < b); + require_boolean_expr(a > b); + require_boolean_expr(a <= b); + require_boolean_expr(a >= b); + } + private: + TT a, b; + }; + +#define BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(OP,NAME) \ + BOOST_concept(NAME, (First)(Second)) \ + { \ + BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ + private: \ + bool constraints_() { return a OP b; } \ + First a; \ + Second b; \ + } + +#define BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(OP,NAME) \ + BOOST_concept(NAME, (Ret)(First)(Second)) \ + { \ + BOOST_CONCEPT_USAGE(NAME) { (void)constraints_(); } \ + private: \ + Ret constraints_() { return a OP b; } \ + First a; \ + Second b; \ + } + + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, EqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, NotEqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, LessThanOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, LessEqualOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, GreaterThanOp); + BOOST_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, GreaterEqualOp); + + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, PlusOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, TimesOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, DivideOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, SubtractOp); + BOOST_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, ModOp); + + //=========================================================================== + // Function Object Concepts + + BOOST_concept(Generator,(Func)(Return)) + { + BOOST_CONCEPT_USAGE(Generator) { test(is_void()); } + + private: + void test(boost::false_type) + { + // Do we really want a reference here? + const Return& r = f(); + ignore_unused_variable_warning(r); + } + + void test(boost::true_type) + { + f(); + } + + Func f; + }; + + BOOST_concept(UnaryFunction,(Func)(Return)(Arg)) + { + BOOST_CONCEPT_USAGE(UnaryFunction) { test(is_void()); } + + private: + void test(boost::false_type) + { + f(arg); // "priming the pump" this way keeps msvc6 happy (ICE) + Return r = f(arg); + ignore_unused_variable_warning(r); + } + + void test(boost::true_type) + { + f(arg); + } + +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type. + // (warning: non-static reference "const double& boost::UnaryFunction::arg" + // in class without a constructor [-Wuninitialized]) + UnaryFunction(); +#endif + + Func f; + Arg arg; + }; + + BOOST_concept(BinaryFunction,(Func)(Return)(First)(Second)) + { + BOOST_CONCEPT_USAGE(BinaryFunction) { test(is_void()); } + private: + void test(boost::false_type) + { + f(first,second); + Return r = f(first, second); // require operator() + (void)r; + } + + void test(boost::true_type) + { + f(first,second); + } + +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type. + // (warning: non-static reference "const double& boost::BinaryFunction::arg" + // in class without a constructor [-Wuninitialized]) + BinaryFunction(); +#endif + + Func f; + First first; + Second second; + }; + + BOOST_concept(UnaryPredicate,(Func)(Arg)) + { + BOOST_CONCEPT_USAGE(UnaryPredicate) { + require_boolean_expr(f(arg)); // require operator() returning bool + } + private: +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type. + // (warning: non-static reference "const double& boost::UnaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + UnaryPredicate(); +#endif + + Func f; + Arg arg; + }; + + BOOST_concept(BinaryPredicate,(Func)(First)(Second)) + { + BOOST_CONCEPT_USAGE(BinaryPredicate) { + require_boolean_expr(f(a, b)); // require operator() returning bool + } + private: +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type. + // (warning: non-static reference "const double& boost::BinaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + BinaryPredicate(); +#endif + Func f; + First a; + Second b; + }; + + // use this when functor is used inside a container class like std::set + BOOST_concept(Const_BinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + { + BOOST_CONCEPT_USAGE(Const_BinaryPredicate) { + const_constraints(f); + } + private: + void const_constraints(const Func& fun) { + // operator() must be a const member function + require_boolean_expr(fun(a, b)); + } +#if (BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(4) \ + && BOOST_WORKAROUND(__GNUC__, > 3))) + // Declare a dummy constructor to make gcc happy. + // It seems the compiler can not generate a sensible constructor when this is instantiated with a reference type. + // (warning: non-static reference "const double& boost::Const_BinaryPredicate::arg" + // in class without a constructor [-Wuninitialized]) + Const_BinaryPredicate(); +#endif + + Func f; + First a; + Second b; + }; + + BOOST_concept(AdaptableGenerator,(Func)(Return)) + : Generator + { + typedef typename Func::result_type result_type; + + BOOST_CONCEPT_USAGE(AdaptableGenerator) + { + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptableUnaryFunction,(Func)(Return)(Arg)) + : UnaryFunction + { + typedef typename Func::argument_type argument_type; + typedef typename Func::result_type result_type; + + ~AdaptableUnaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptableBinaryFunction,(Func)(Return)(First)(Second)) + : BinaryFunction< + Func + , typename Func::result_type + , typename Func::first_argument_type + , typename Func::second_argument_type + > + { + typedef typename Func::first_argument_type first_argument_type; + typedef typename Func::second_argument_type second_argument_type; + typedef typename Func::result_type result_type; + + ~AdaptableBinaryFunction() + { + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + BOOST_CONCEPT_ASSERT((Convertible)); + } + }; + + BOOST_concept(AdaptablePredicate,(Func)(Arg)) + : UnaryPredicate + , AdaptableUnaryFunction + { + }; + + BOOST_concept(AdaptableBinaryPredicate,(Func)(First)(Second)) + : BinaryPredicate + , AdaptableBinaryFunction + { + }; + + //=========================================================================== + // Iterator Concepts + + BOOST_concept(InputIterator,(TT)) + : Assignable + , EqualityComparable + { + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::reference reference; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::iterator_category iterator_category; + + BOOST_CONCEPT_USAGE(InputIterator) + { + BOOST_CONCEPT_ASSERT((SignedInteger)); + BOOST_CONCEPT_ASSERT((Convertible)); + + TT j(i); + (void)*i; // require dereference operator + ++j; // require preincrement operator + i++; // require postincrement operator + } + private: + TT i; + }; + + BOOST_concept(OutputIterator,(TT)(ValueT)) + : Assignable + { + BOOST_CONCEPT_USAGE(OutputIterator) { + + ++i; // require preincrement operator + i++; // require postincrement operator + *i++ = t; // require postincrement and assignment + } + private: + TT i, j; + ValueT t; + }; + + BOOST_concept(ForwardIterator,(TT)) + : InputIterator + { + BOOST_CONCEPT_USAGE(ForwardIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME ForwardIterator::iterator_category + , std::forward_iterator_tag + >)); + + typename InputIterator::reference r = *i; + ignore_unused_variable_warning(r); + } + + private: + TT i; + }; + + BOOST_concept(Mutable_ForwardIterator,(TT)) + : ForwardIterator + { + BOOST_CONCEPT_USAGE(Mutable_ForwardIterator) { + *i++ = *j; // require postincrement and assignment + } + private: + TT i, j; + }; + + BOOST_concept(BidirectionalIterator,(TT)) + : ForwardIterator + { + BOOST_CONCEPT_USAGE(BidirectionalIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category + , std::bidirectional_iterator_tag + >)); + + --i; // require predecrement operator + i--; // require postdecrement operator + } + private: + TT i; + }; + + BOOST_concept(Mutable_BidirectionalIterator,(TT)) + : BidirectionalIterator + , Mutable_ForwardIterator + { + BOOST_CONCEPT_USAGE(Mutable_BidirectionalIterator) + { + *i-- = *j; // require postdecrement and assignment + } + private: + TT i, j; + }; + + BOOST_concept(RandomAccessIterator,(TT)) + : BidirectionalIterator + , Comparable + { + BOOST_CONCEPT_USAGE(RandomAccessIterator) + { + BOOST_CONCEPT_ASSERT((Convertible< + BOOST_DEDUCED_TYPENAME BidirectionalIterator::iterator_category + , std::random_access_iterator_tag + >)); + + i += n; // require assignment addition operator + i = i + n; i = n + i; // require addition with difference type + i -= n; // require assignment subtraction operator + i = i - n; // require subtraction with difference type + n = i - j; // require difference operator + (void)i[n]; // require element access operator + } + + private: + TT a, b; + TT i, j; + typename std::iterator_traits::difference_type n; + }; + + BOOST_concept(Mutable_RandomAccessIterator,(TT)) + : RandomAccessIterator + , Mutable_BidirectionalIterator + { + BOOST_CONCEPT_USAGE(Mutable_RandomAccessIterator) + { + i[n] = *i; // require element access and assignment + } + private: + TT i; + typename std::iterator_traits::difference_type n; + }; + + //=========================================================================== + // Container s + + BOOST_concept(Container,(C)) + : Assignable + { + typedef typename C::value_type value_type; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; + typedef typename C::const_pointer const_pointer; + typedef typename C::const_iterator const_iterator; + + BOOST_CONCEPT_USAGE(Container) + { + BOOST_CONCEPT_ASSERT((InputIterator)); + const_constraints(c); + } + + private: + void const_constraints(const C& cc) { + i = cc.begin(); + i = cc.end(); + n = cc.size(); + n = cc.max_size(); + b = cc.empty(); + } + C c; + bool b; + const_iterator i; + size_type n; + }; + + BOOST_concept(Mutable_Container,(C)) + : Container + { + typedef typename C::reference reference; + typedef typename C::iterator iterator; + typedef typename C::pointer pointer; + + BOOST_CONCEPT_USAGE(Mutable_Container) + { + BOOST_CONCEPT_ASSERT(( + Assignable)); + + BOOST_CONCEPT_ASSERT((InputIterator)); + + i = c.begin(); + i = c.end(); + c.swap(c2); + } + + private: + iterator i; + C c, c2; + }; + + BOOST_concept(ForwardContainer,(C)) + : Container + { + BOOST_CONCEPT_USAGE(ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + ForwardIterator< + typename ForwardContainer::const_iterator + >)); + } + }; + + BOOST_concept(Mutable_ForwardContainer,(C)) + : ForwardContainer + , Mutable_Container + { + BOOST_CONCEPT_USAGE(Mutable_ForwardContainer) + { + BOOST_CONCEPT_ASSERT(( + Mutable_ForwardIterator< + typename Mutable_ForwardContainer::iterator + >)); + } + }; + + BOOST_concept(ReversibleContainer,(C)) + : ForwardContainer + { + typedef typename + C::const_reverse_iterator + const_reverse_iterator; + + BOOST_CONCEPT_USAGE(ReversibleContainer) + { + BOOST_CONCEPT_ASSERT(( + BidirectionalIterator< + typename ReversibleContainer::const_iterator>)); + + BOOST_CONCEPT_ASSERT((BidirectionalIterator)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reverse_iterator _i = cc.rbegin(); + _i = cc.rend(); + } + C c; + }; + + BOOST_concept(Mutable_ReversibleContainer,(C)) + : Mutable_ForwardContainer + , ReversibleContainer + { + typedef typename C::reverse_iterator reverse_iterator; + + BOOST_CONCEPT_USAGE(Mutable_ReversibleContainer) + { + typedef typename Mutable_ForwardContainer::iterator iterator; + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((Mutable_BidirectionalIterator)); + + reverse_iterator i = c.rbegin(); + i = c.rend(); + } + private: + C c; + }; + + BOOST_concept(RandomAccessContainer,(C)) + : ReversibleContainer + { + typedef typename C::size_type size_type; + typedef typename C::const_reference const_reference; + + BOOST_CONCEPT_USAGE(RandomAccessContainer) + { + BOOST_CONCEPT_ASSERT(( + RandomAccessIterator< + typename RandomAccessContainer::const_iterator + >)); + + const_constraints(c); + } + private: + void const_constraints(const C& cc) + { + const_reference r = cc[n]; + ignore_unused_variable_warning(r); + } + + C c; + size_type n; + }; + + BOOST_concept(Mutable_RandomAccessContainer,(C)) + : Mutable_ReversibleContainer + , RandomAccessContainer + { + private: + typedef Mutable_RandomAccessContainer self; + public: + BOOST_CONCEPT_USAGE(Mutable_RandomAccessContainer) + { + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + BOOST_CONCEPT_ASSERT((Mutable_RandomAccessIterator)); + + typename self::reference r = c[i]; + ignore_unused_variable_warning(r); + } + + private: + typename Mutable_ReversibleContainer::size_type i; + C c; + }; + + // A Sequence is inherently mutable + BOOST_concept(Sequence,(S)) + : Mutable_ForwardContainer + // Matt Austern's book puts DefaultConstructible here, the C++ + // standard places it in Container --JGS + // ... so why aren't we following the standard? --DWA + , DefaultConstructible + { + BOOST_CONCEPT_USAGE(Sequence) + { + S + c(n, t), + c2(first, last); + + c.insert(p, t); + c.insert(p, n, t); + c.insert(p, first, last); + + c.erase(p); + c.erase(p, q); + + typename Sequence::reference r = c.front(); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(c2); + ignore_unused_variable_warning(r); + const_constraints(c); + } + private: + void const_constraints(const S& c) { + typename Sequence::const_reference r = c.front(); + ignore_unused_variable_warning(r); + } + + typename S::value_type t; + typename S::size_type n; + typename S::value_type* first, *last; + typename S::iterator p, q; + }; + + BOOST_concept(FrontInsertionSequence,(S)) + : Sequence + { + BOOST_CONCEPT_USAGE(FrontInsertionSequence) + { + c.push_front(t); + c.pop_front(); + } + private: + S c; + typename S::value_type t; + }; + + BOOST_concept(BackInsertionSequence,(S)) + : Sequence + { + BOOST_CONCEPT_USAGE(BackInsertionSequence) + { + c.push_back(t); + c.pop_back(); + typename BackInsertionSequence::reference r = c.back(); + ignore_unused_variable_warning(r); + const_constraints(c); + } + private: + void const_constraints(const S& cc) { + typename BackInsertionSequence::const_reference + r = cc.back(); + ignore_unused_variable_warning(r); + } + S c; + typename S::value_type t; + }; + + BOOST_concept(AssociativeContainer,(C)) + : ForwardContainer + , DefaultConstructible + { + typedef typename C::key_type key_type; + typedef typename C::key_compare key_compare; + typedef typename C::value_compare value_compare; + typedef typename C::iterator iterator; + + BOOST_CONCEPT_USAGE(AssociativeContainer) + { + i = c.find(k); + r = c.equal_range(k); + c.erase(k); + c.erase(i); + c.erase(r.first, r.second); + const_constraints(c); + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + + typedef typename AssociativeContainer::value_type value_type_; + BOOST_CONCEPT_ASSERT((BinaryPredicate)); + } + + // Redundant with the base concept, but it helps below. + typedef typename C::const_iterator const_iterator; + private: + void const_constraints(const C& cc) + { + ci = cc.find(k); + n = cc.count(k); + cr = cc.equal_range(k); + } + + C c; + iterator i; + std::pair r; + const_iterator ci; + std::pair cr; + typename C::key_type k; + typename C::size_type n; + }; + + BOOST_concept(UniqueAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(UniqueAssociativeContainer) + { + C c(first, last); + + pos_flag = c.insert(t); + c.insert(first, last); + + ignore_unused_variable_warning(c); + } + private: + std::pair pos_flag; + typename C::value_type t; + typename C::value_type* first, *last; + }; + + BOOST_concept(MultipleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(MultipleAssociativeContainer) + { + C c(first, last); + + pos = c.insert(t); + c.insert(first, last); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(pos); + } + private: + typename C::iterator pos; + typename C::value_type t; + typename C::value_type* first, *last; + }; + + BOOST_concept(SimpleAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(SimpleAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + BOOST_STATIC_ASSERT((boost::is_same::value)); + } + }; + + BOOST_concept(PairAssociativeContainer,(C)) + : AssociativeContainer + { + BOOST_CONCEPT_USAGE(PairAssociativeContainer) + { + typedef typename C::key_type key_type; + typedef typename C::value_type value_type; + typedef typename C::mapped_type mapped_type; + typedef std::pair required_value_type; + BOOST_STATIC_ASSERT((boost::is_same::value)); + } + }; + + BOOST_concept(SortedAssociativeContainer,(C)) + : AssociativeContainer + , ReversibleContainer + { + BOOST_CONCEPT_USAGE(SortedAssociativeContainer) + { + C + c(kc), + c2(first, last), + c3(first, last, kc); + + p = c.upper_bound(k); + p = c.lower_bound(k); + r = c.equal_range(k); + + c.insert(p, t); + + ignore_unused_variable_warning(c); + ignore_unused_variable_warning(c2); + ignore_unused_variable_warning(c3); + const_constraints(c); + } + + void const_constraints(const C& c) + { + kc = c.key_comp(); + vc = c.value_comp(); + + cp = c.upper_bound(k); + cp = c.lower_bound(k); + cr = c.equal_range(k); + } + + private: + typename C::key_compare kc; + typename C::value_compare vc; + typename C::value_type t; + typename C::key_type k; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + + typedef SortedAssociativeContainer self; + iterator p; + const_iterator cp; + std::pair r; + std::pair cr; + typename C::value_type* first, *last; + }; + + // HashedAssociativeContainer + + BOOST_concept(Collection,(C)) + { + BOOST_CONCEPT_USAGE(Collection) + { + boost::function_requires >(); + boost::function_requires >(); + boost::function_requires >(); + const_constraints(c); + i = c.begin(); + i = c.end(); + c.swap(c); + } + + void const_constraints(const C& cc) { + ci = cc.begin(); + ci = cc.end(); + n = cc.size(); + b = cc.empty(); + } + + private: + typedef typename C::value_type value_type; + typedef typename C::iterator iterator; + typedef typename C::const_iterator const_iterator; + typedef typename C::reference reference; + typedef typename C::const_reference const_reference; + // typedef typename C::pointer pointer; + typedef typename C::difference_type difference_type; + typedef typename C::size_type size_type; + + C c; + bool b; + iterator i; + const_iterator ci; + size_type n; + }; +} // namespace boost + +#if (defined _MSC_VER) +# pragma warning( pop ) +#endif + +# include + +#endif // BOOST_CONCEPT_CHECKS_HPP + diff --git a/src/vendor/boost/config.hpp b/src/vendor/boost/config.hpp new file mode 100644 index 000000000..f00a98057 --- /dev/null +++ b/src/vendor/boost/config.hpp @@ -0,0 +1,67 @@ +// Boost config.hpp configuration header file ------------------------------// + +// (C) Copyright John Maddock 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/config for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config +// +// CAUTION: This file is intended to be completely stable - +// DO NOT MODIFY THIS FILE! +// + +#ifndef BOOST_CONFIG_HPP +#define BOOST_CONFIG_HPP + +// if we don't have a user config, then use the default location: +#if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) +# define BOOST_USER_CONFIG +#if 0 +// For dependency trackers: +# include +#endif +#endif +// include it first: +#ifdef BOOST_USER_CONFIG +# include BOOST_USER_CONFIG +#endif + +// if we don't have a compiler config set, try and find one: +#if !defined(BOOST_COMPILER_CONFIG) && !defined(BOOST_NO_COMPILER_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a compiler config, include it now: +#ifdef BOOST_COMPILER_CONFIG +# include BOOST_COMPILER_CONFIG +#endif + +// if we don't have a std library config set, try and find one: +#if !defined(BOOST_STDLIB_CONFIG) && !defined(BOOST_NO_STDLIB_CONFIG) && !defined(BOOST_NO_CONFIG) && defined(__cplusplus) +# include +#endif +// if we have a std library config, include it now: +#ifdef BOOST_STDLIB_CONFIG +# include BOOST_STDLIB_CONFIG +#endif + +// if we don't have a platform config set, try and find one: +#if !defined(BOOST_PLATFORM_CONFIG) && !defined(BOOST_NO_PLATFORM_CONFIG) && !defined(BOOST_NO_CONFIG) +# include +#endif +// if we have a platform config, include it now: +#ifdef BOOST_PLATFORM_CONFIG +# include BOOST_PLATFORM_CONFIG +#endif + +// get config suffix code: +#include + +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + +#endif // BOOST_CONFIG_HPP diff --git a/src/vendor/boost/config/auto_link.hpp b/src/vendor/boost/config/auto_link.hpp new file mode 100644 index 000000000..1ea6faa77 --- /dev/null +++ b/src/vendor/boost/config/auto_link.hpp @@ -0,0 +1,524 @@ +// (C) Copyright John Maddock 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE auto_link.hpp + * VERSION see + * DESCRIPTION: Automatic library inclusion for Borland/Microsoft compilers. + */ + +/************************************************************************* + +USAGE: +~~~~~~ + +Before including this header you must define one or more of define the following macros: + +BOOST_LIB_NAME: Required: A string containing the basename of the library, + for example boost_regex. +BOOST_LIB_TOOLSET: Optional: the base name of the toolset. +BOOST_DYN_LINK: Optional: when set link to dll rather than static library. +BOOST_LIB_DIAGNOSTIC: Optional: when set the header will print out the name + of the library selected (useful for debugging). +BOOST_AUTO_LINK_NOMANGLE: Specifies that we should link to BOOST_LIB_NAME.lib, + rather than a mangled-name version. +BOOST_AUTO_LINK_TAGGED: Specifies that we link to libraries built with the --layout=tagged option. + This is essentially the same as the default name-mangled version, but without + the compiler name and version, or the Boost version. Just the build options. +BOOST_AUTO_LINK_SYSTEM: Specifies that we link to libraries built with the --layout=system option. + This is essentially the same as the non-name-mangled version, but with + the prefix to differentiate static and dll builds + +These macros will be undef'ed at the end of the header, further this header +has no include guards - so be sure to include it only once from your library! + +Algorithm: +~~~~~~~~~~ + +Libraries for Borland and Microsoft compilers are automatically +selected here, the name of the lib is selected according to the following +formula: + +BOOST_LIB_PREFIX + + BOOST_LIB_NAME + + "_" + + BOOST_LIB_TOOLSET + + BOOST_LIB_THREAD_OPT + + BOOST_LIB_RT_OPT + + BOOST_LIB_ARCH_AND_MODEL_OPT + "-" + + BOOST_LIB_VERSION + + BOOST_LIB_SUFFIX + +These are defined as: + +BOOST_LIB_PREFIX: "lib" for static libraries otherwise "". + +BOOST_LIB_NAME: The base name of the lib ( for example boost_regex). + +BOOST_LIB_TOOLSET: The compiler toolset name (vc6, vc7, bcb5 etc). + +BOOST_LIB_THREAD_OPT: "-mt" for multithread builds, otherwise nothing. + +BOOST_LIB_RT_OPT: A suffix that indicates the runtime library used, + contains one or more of the following letters after + a hyphen: + + s static runtime (dynamic if not present). + g debug/diagnostic runtime (release if not present). + y Python debug/diagnostic runtime (release if not present). + d debug build (release if not present). + p STLport build. + n STLport build without its IOStreams. + +BOOST_LIB_ARCH_AND_MODEL_OPT: The architecture and address model + (-x32 or -x64 for x86/32 and x86/64 respectively) + +BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y. + +BOOST_LIB_SUFFIX: Static/import libraries extension (".lib", ".a") for the compiler. + +***************************************************************************/ + +#ifdef __cplusplus +# ifndef BOOST_CONFIG_HPP +# include +# endif +#elif defined(_MSC_VER) && !defined(__MWERKS__) && !defined(__EDG_VERSION__) +// +// C language compatability (no, honestly) +// +# define BOOST_MSVC _MSC_VER +# define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +# define BOOST_DO_STRINGIZE(X) #X +#endif +// +// Only include what follows for known and supported compilers: +// +#if defined(BOOST_MSVC) \ + || defined(BOOST_EMBTC_WINDOWS) \ + || defined(BOOST_BORLANDC) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS) && (_MSC_VER >= 1200)) \ + || (defined(BOOST_CLANG) && defined(BOOST_WINDOWS) && defined(_MSC_VER) && (__clang_major__ >= 4)) + +#ifndef BOOST_VERSION_HPP +# include +#endif + +#ifndef BOOST_LIB_NAME +# error "Macro BOOST_LIB_NAME not set (internal error)" +#endif + +// +// error check: +// +#if defined(__MSVC_RUNTIME_CHECKS) && !defined(_DEBUG) +# pragma message("Using the /RTC option without specifying a debug runtime will lead to linker errors") +# pragma message("Hint: go to the code generation options and switch to one of the debugging runtimes") +# error "Incompatible build options" +#endif +// +// select toolset if not defined already: +// +#ifndef BOOST_LIB_TOOLSET +# if defined(BOOST_MSVC) && (BOOST_MSVC < 1200) + // Note: no compilers before 1200 are supported +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1300) + +# ifdef UNDER_CE + // eVC4: +# define BOOST_LIB_TOOLSET "evc4" +# else + // vc6: +# define BOOST_LIB_TOOLSET "vc6" +# endif + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1310) + + // vc7: +# define BOOST_LIB_TOOLSET "vc7" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1400) + + // vc71: +# define BOOST_LIB_TOOLSET "vc71" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1500) + + // vc80: +# define BOOST_LIB_TOOLSET "vc80" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1600) + + // vc90: +# define BOOST_LIB_TOOLSET "vc90" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1700) + + // vc10: +# define BOOST_LIB_TOOLSET "vc100" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) + + // vc11: +# define BOOST_LIB_TOOLSET "vc110" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1900) + + // vc12: +# define BOOST_LIB_TOOLSET "vc120" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1910) + + // vc14: +# define BOOST_LIB_TOOLSET "vc140" + +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1920) + + // vc14.1: +# define BOOST_LIB_TOOLSET "vc141" + +# elif defined(BOOST_MSVC) + + // vc14.2: +# define BOOST_LIB_TOOLSET "vc142" + +# elif defined(BOOST_EMBTC_WINDOWS) + + // Embarcadero Clang based compilers: +# if defined(BOOST_EMBTC_WIN32C) +# define BOOST_LIB_TOOLSET "bcb32" +# elif defined(BOOST_EMBTC_WIN64) +# define BOOST_LIB_TOOLSET "bcb64" +# endif + +# elif defined(BOOST_BORLANDC) + + // CBuilder 6: +# define BOOST_LIB_TOOLSET "bcb" + +# elif defined(__ICL) + + // Intel C++, no version number: +# define BOOST_LIB_TOOLSET "iw" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x31FF ) + + // Metrowerks CodeWarrior 8.x +# define BOOST_LIB_TOOLSET "cw8" + +# elif defined(__MWERKS__) && (__MWERKS__ <= 0x32FF ) + + // Metrowerks CodeWarrior 9.x +# define BOOST_LIB_TOOLSET "cw9" + +# elif defined(BOOST_CLANG) && defined(BOOST_WINDOWS) && defined(_MSC_VER) && (__clang_major__ >= 4) + + // Clang on Windows +# define BOOST_LIB_TOOLSET "clangw" BOOST_STRINGIZE(__clang_major__) + +# endif +#endif // BOOST_LIB_TOOLSET + +// +// select thread opt: +// +#if defined(_MT) || defined(__MT__) +# define BOOST_LIB_THREAD_OPT "-mt" +#else +# define BOOST_LIB_THREAD_OPT +#endif + +#if defined(_MSC_VER) || defined(__MWERKS__) + +# ifdef _DLL + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-p" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-gdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-pn" +# endif + +# else + +# if defined(_DEBUG) && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-gyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-gd" +# else +# define BOOST_LIB_RT_OPT +# endif + +# endif + +# else + +# if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && (defined(_STLP_OWN_IOSTREAMS) || defined(__STL_OWN_IOSTREAMS)) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdp" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdp" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-sp" +# endif + +# elif defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) + +# if defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG))\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# elif defined(_DEBUG) && (defined(__STL_DEBUG) || defined(_STLP_DEBUG)) +# define BOOST_LIB_RT_OPT "-sgdpn" +# elif defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgydpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgdpn" +# pragma message("warning: STLport debug versions are built with /D_STLP_DEBUG=1") +# error "Build options aren't compatible with pre-built libraries" +# else +# define BOOST_LIB_RT_OPT "-spn" +# endif + +# else + +# if defined(_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sgyd" +# elif defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sgd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +# endif + +#elif defined(BOOST_EMBTC_WINDOWS) + +# ifdef _RTLDLL + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#elif defined(BOOST_BORLANDC) + +// +// figure out whether we want the debug builds or not: +// +#if BOOST_BORLANDC > 0x561 +#pragma defineonoption BOOST_BORLAND_DEBUG -v +#endif +// +// sanity check: +// +#if defined(__STL_DEBUG) || defined(_STLP_DEBUG) +#error "Pre-built versions of the Boost libraries are not provided in STLport-debug form" +#endif + +# ifdef _RTLDLL + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-yd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-d" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-y" +# else +# define BOOST_LIB_RT_OPT +# endif + +# else + +# if defined(BOOST_BORLAND_DEBUG)\ + && defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-syd" +# elif defined(BOOST_BORLAND_DEBUG) +# define BOOST_LIB_RT_OPT "-sd" +# elif defined(BOOST_DEBUG_PYTHON) && defined(BOOST_LINKING_PYTHON) +# define BOOST_LIB_RT_OPT "-sy" +# else +# define BOOST_LIB_RT_OPT "-s" +# endif + +# endif + +#endif + +// +// BOOST_LIB_ARCH_AND_MODEL_OPT +// + +#if defined( _M_IX86 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-x32" +#elif defined( _M_X64 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-x64" +#elif defined( _M_ARM ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-a32" +#elif defined( _M_ARM64 ) +# define BOOST_LIB_ARCH_AND_MODEL_OPT "-a64" +#endif + +// +// select linkage opt: +// +#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK) +# define BOOST_LIB_PREFIX +#elif defined(BOOST_DYN_LINK) +# error "Mixing a dll boost library with a static runtime is a really bad idea..." +#else +# define BOOST_LIB_PREFIX "lib" +#endif + +// +// now include the lib: +// +#if defined(BOOST_LIB_NAME) \ + && defined(BOOST_LIB_PREFIX) \ + && defined(BOOST_LIB_TOOLSET) \ + && defined(BOOST_LIB_THREAD_OPT) \ + && defined(BOOST_LIB_RT_OPT) \ + && defined(BOOST_LIB_ARCH_AND_MODEL_OPT) \ + && defined(BOOST_LIB_VERSION) + +#if defined(BOOST_EMBTC_WIN64) +# define BOOST_LIB_SUFFIX ".a" +#else +# define BOOST_LIB_SUFFIX ".lib" +#endif + +#ifdef BOOST_AUTO_LINK_NOMANGLE +# pragma comment(lib, BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_AUTO_LINK_TAGGED) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_AUTO_LINK_SYSTEM) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_SUFFIX) +# endif +#elif defined(BOOST_LIB_BUILDID) +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION "-" BOOST_STRINGIZE(BOOST_LIB_BUILDID) BOOST_LIB_SUFFIX) +# endif +#else +# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION BOOST_LIB_SUFFIX) +# ifdef BOOST_LIB_DIAGNOSTIC +# pragma message ("Linking to lib file: " BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT BOOST_LIB_ARCH_AND_MODEL_OPT "-" BOOST_LIB_VERSION BOOST_LIB_SUFFIX) +# endif +#endif + +#else +# error "some required macros where not defined (internal logic error)." +#endif + + +#endif // _MSC_VER || __BORLANDC__ + +// +// finally undef any macros we may have set: +// +#ifdef BOOST_LIB_PREFIX +# undef BOOST_LIB_PREFIX +#endif +#if defined(BOOST_LIB_NAME) +# undef BOOST_LIB_NAME +#endif +// Don't undef this one: it can be set by the user and should be the +// same for all libraries: +//#if defined(BOOST_LIB_TOOLSET) +//# undef BOOST_LIB_TOOLSET +//#endif +#if defined(BOOST_LIB_THREAD_OPT) +# undef BOOST_LIB_THREAD_OPT +#endif +#if defined(BOOST_LIB_RT_OPT) +# undef BOOST_LIB_RT_OPT +#endif +#if defined(BOOST_LIB_ARCH_AND_MODEL_OPT) +# undef BOOST_LIB_ARCH_AND_MODEL_OPT +#endif +#if defined(BOOST_LIB_LINK_OPT) +# undef BOOST_LIB_LINK_OPT +#endif +#if defined(BOOST_LIB_DEBUG_OPT) +# undef BOOST_LIB_DEBUG_OPT +#endif +#if defined(BOOST_DYN_LINK) +# undef BOOST_DYN_LINK +#endif +#if defined(BOOST_LIB_SUFFIX) +# undef BOOST_LIB_SUFFIX +#endif diff --git a/src/vendor/boost/config/compiler/gcc.hpp b/src/vendor/boost/config/compiler/gcc.hpp new file mode 100644 index 000000000..da1a43229 --- /dev/null +++ b/src/vendor/boost/config/compiler/gcc.hpp @@ -0,0 +1,375 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Darin Adler 2001 - 2002. +// (C) Copyright Jens Maurer 2001 - 2002. +// (C) Copyright Beman Dawes 2001 - 2003. +// (C) Copyright Douglas Gregor 2002. +// (C) Copyright David Abrahams 2002 - 2003. +// (C) Copyright Synge Todo 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// GNU C++ compiler setup. + +// +// Define BOOST_GCC so we know this is "real" GCC and not some pretender: +// +#define BOOST_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#if !defined(__CUDACC__) +#define BOOST_GCC BOOST_GCC_VERSION +#endif + +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L) +# define BOOST_GCC_CXX11 +#endif + +#if __GNUC__ == 3 +# if defined (__PATHSCALE__) +# define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# define BOOST_NO_IS_ABSTRACT +# endif + +# if __GNUC_MINOR__ < 4 +# define BOOST_NO_IS_ABSTRACT +# endif +# define BOOST_NO_CXX11_EXTERN_TEMPLATE +#endif +#if __GNUC__ < 4 +// +// All problems to gcc-3.x and earlier here: +// +#define BOOST_NO_TWO_PHASE_NAME_LOOKUP +# ifdef __OPEN64__ +# define BOOST_NO_IS_ABSTRACT +# endif +#endif + +// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links +#if BOOST_GCC_VERSION >= 30400 +#define BOOST_HAS_PRAGMA_ONCE +#endif + +#if BOOST_GCC_VERSION < 40400 +// Previous versions of GCC did not completely implement value-initialization: +// GCC Bug 30111, "Value-initialization of POD base class doesn't initialize +// members", reported by Jonathan Wakely in 2006, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30111 (fixed for GCC 4.4) +// GCC Bug 33916, "Default constructor fails to initialize array members", +// reported by Michael Elizabeth Chastain in 2007, +// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916 (fixed for GCC 4.2.4) +// See also: http://www.boost.org/libs/utility/value_init.htm#compiler_issues +#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION +#endif + +#if !defined(__EXCEPTIONS) && !defined(BOOST_NO_EXCEPTIONS) +# define BOOST_NO_EXCEPTIONS +#endif + + +// +// Threading support: Turn this on unconditionally here (except for +// those platforms where we can know for sure). It will get turned off again +// later if no threading API is detected. +// +#if !defined(__MINGW32__) && !defined(linux) && !defined(__linux) && !defined(__linux__) +# define BOOST_HAS_THREADS +#endif + +// +// gcc has "long long" +// Except on Darwin with standard compliance enabled (-pedantic) +// Apple gcc helpfully defines this macro we can query +// +#if !defined(__DARWIN_NO_LONG_LONG) +# define BOOST_HAS_LONG_LONG +#endif + +// +// gcc implements the named return value optimization since version 3.1 +// +#define BOOST_HAS_NRVO + +// Branch prediction hints +#define BOOST_LIKELY(x) __builtin_expect(x, 1) +#define BOOST_UNLIKELY(x) __builtin_expect(x, 0) + +// +// Dynamic shared object (DSO) and dynamic-link library (DLL) support +// +#if __GNUC__ >= 4 +# if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__) + // All Win32 development environments, including 64-bit Windows and MinGW, define + // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, + // so does not define _WIN32 or its variants, but still supports dllexport/dllimport. +# define BOOST_HAS_DECLSPEC +# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__)) +# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__)) +# else +# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default"))) +# define BOOST_SYMBOL_IMPORT +# endif +# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default"))) +#else +// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined +# define BOOST_SYMBOL_EXPORT +#endif + +// +// RTTI and typeinfo detection is possible post gcc-4.3: +// +#if BOOST_GCC_VERSION > 40300 +# ifndef __GXX_RTTI +# ifndef BOOST_NO_TYPEID +# define BOOST_NO_TYPEID +# endif +# ifndef BOOST_NO_RTTI +# define BOOST_NO_RTTI +# endif +# endif +#endif + +// +// Recent GCC versions have __int128 when in 64-bit mode. +// +// We disable this if the compiler is really nvcc with C++03 as it +// doesn't actually support __int128 as of CUDA_VERSION=7500 +// even though it defines __SIZEOF_INT128__. +// See https://svn.boost.org/trac/boost/ticket/8048 +// https://svn.boost.org/trac/boost/ticket/11852 +// Only re-enable this for nvcc if you're absolutely sure +// of the circumstances under which it's supported: +// +#if defined(__CUDACC__) +# if defined(BOOST_GCC_CXX11) +# define BOOST_NVCC_CXX11 +# else +# define BOOST_NVCC_CXX03 +# endif +#endif + +#if defined(__SIZEOF_INT128__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_INT128 +#endif +// +// Recent GCC versions have a __float128 native type, we need to +// include a std lib header to detect this - not ideal, but we'll +// be including later anyway when we select the std lib. +// +// Nevertheless, as of CUDA 7.5, using __float128 with the host +// compiler in pre-C++11 mode is still not supported. +// See https://svn.boost.org/trac/boost/ticket/11852 +// +#ifdef __cplusplus +#include +#else +#include +#endif +#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) && !defined(BOOST_NVCC_CXX03) +# define BOOST_HAS_FLOAT128 +#endif + +// C++0x features in 4.3.n and later +// +#if (BOOST_GCC_VERSION >= 40300) && defined(BOOST_GCC_CXX11) +// C++0x features are only enabled when -std=c++0x or -std=gnu++0x are +// passed on the command line, which in turn defines +// __GXX_EXPERIMENTAL_CXX0X__. +# define BOOST_HAS_DECLTYPE +# define BOOST_HAS_RVALUE_REFS +# define BOOST_HAS_STATIC_ASSERT +# define BOOST_HAS_VARIADIC_TMPL +#else +# define BOOST_NO_CXX11_DECLTYPE +# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS +# define BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_NO_CXX11_STATIC_ASSERT +#endif + +// C++0x features in 4.4.n and later +// +#if (BOOST_GCC_VERSION < 40400) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_AUTO_DECLARATIONS +# define BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS +# define BOOST_NO_CXX11_CHAR16_T +# define BOOST_NO_CXX11_CHAR32_T +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS +# define BOOST_NO_CXX11_DELETED_FUNCTIONS +# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES +# define BOOST_NO_CXX11_INLINE_NAMESPACES +# define BOOST_NO_CXX11_VARIADIC_TEMPLATES +#endif + +#if BOOST_GCC_VERSION < 40500 +# define BOOST_NO_SFINAE_EXPR +#endif + +// GCC 4.5 forbids declaration of defaulted functions in private or protected sections +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 5) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// C++0x features in 4.5.0 and later +// +#if (BOOST_GCC_VERSION < 40500) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +# define BOOST_NO_CXX11_LAMBDAS +# define BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS +# define BOOST_NO_CXX11_RAW_LITERALS +# define BOOST_NO_CXX11_UNICODE_LITERALS +#endif + +// C++0x features in 4.5.1 and later +// +#if (BOOST_GCC_VERSION < 40501) || !defined(BOOST_GCC_CXX11) +// scoped enums have a serious bug in 4.4.0, so define BOOST_NO_CXX11_SCOPED_ENUMS before 4.5.1 +// See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38064 +# define BOOST_NO_CXX11_SCOPED_ENUMS +#endif + +// C++0x features in 4.6.n and later +// +#if (BOOST_GCC_VERSION < 40600) || !defined(BOOST_GCC_CXX11) +#define BOOST_NO_CXX11_DEFAULTED_MOVES +#define BOOST_NO_CXX11_NOEXCEPT +#define BOOST_NO_CXX11_NULLPTR +#define BOOST_NO_CXX11_RANGE_BASED_FOR +#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +#endif + +// C++0x features in 4.7.n and later +// +#if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) +// Note that while constexpr is partly supported in gcc-4.6 it's a +// pre-std version with several bugs: +# define BOOST_NO_CXX11_CONSTEXPR +# define BOOST_NO_CXX11_FINAL +# define BOOST_NO_CXX11_TEMPLATE_ALIASES +# define BOOST_NO_CXX11_USER_DEFINED_LITERALS +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +# define BOOST_NO_CXX11_OVERRIDE +#endif + +// C++0x features in 4.8.n and later +// +#if (BOOST_GCC_VERSION < 40800) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_THREAD_LOCAL +# define BOOST_NO_CXX11_SFINAE_EXPR +#endif + +// C++0x features in 4.8.1 and later +// +#if (BOOST_GCC_VERSION < 40801) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_DECLTYPE_N3276 +# define BOOST_NO_CXX11_REF_QUALIFIERS +# define BOOST_NO_CXX14_BINARY_LITERALS +#endif + +// C++0x features in 4.9.n and later +// +#if (BOOST_GCC_VERSION < 40900) || !defined(BOOST_GCC_CXX11) +// Although alignas support is added in gcc 4.8, it does not accept +// constant expressions as an argument until gcc 4.9. +# define BOOST_NO_CXX11_ALIGNAS +#endif + +// C++0x features in 5.1 and later +// +#if (BOOST_GCC_VERSION < 50100) || !defined(BOOST_GCC_CXX11) +# define BOOST_NO_CXX11_UNRESTRICTED_UNION +#endif + +// C++14 features in 4.9.0 and later +// +#if (BOOST_GCC_VERSION < 40900) || (__cplusplus < 201300) +# define BOOST_NO_CXX14_RETURN_TYPE_DEDUCTION +# define BOOST_NO_CXX14_GENERIC_LAMBDAS +# define BOOST_NO_CXX14_DIGIT_SEPARATORS +# define BOOST_NO_CXX14_DECLTYPE_AUTO +# if !((BOOST_GCC_VERSION >= 40801) && (BOOST_GCC_VERSION < 40900) && defined(BOOST_GCC_CXX11)) +# define BOOST_NO_CXX14_INITIALIZED_LAMBDA_CAPTURES +# endif +#endif + + +// C++ 14: +#if !defined(__cpp_aggregate_nsdmi) || (__cpp_aggregate_nsdmi < 201304) +# define BOOST_NO_CXX14_AGGREGATE_NSDMI +#endif +#if !defined(__cpp_constexpr) || (__cpp_constexpr < 201304) +# define BOOST_NO_CXX14_CONSTEXPR +#endif +#if (BOOST_GCC_VERSION < 50200) || !defined(__cpp_variable_templates) || (__cpp_variable_templates < 201304) +# define BOOST_NO_CXX14_VARIABLE_TEMPLATES +#endif + +// C++17 +#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606) +# define BOOST_NO_CXX17_STRUCTURED_BINDINGS +#endif +#if !defined(__cpp_inline_variables) || (__cpp_inline_variables < 201606) +# define BOOST_NO_CXX17_INLINE_VARIABLES +#endif +#if !defined(__cpp_fold_expressions) || (__cpp_fold_expressions < 201603) +# define BOOST_NO_CXX17_FOLD_EXPRESSIONS +#endif +#if !defined(__cpp_if_constexpr) || (__cpp_if_constexpr < 201606) +# define BOOST_NO_CXX17_IF_CONSTEXPR +#endif + +#if __GNUC__ >= 7 +# define BOOST_FALLTHROUGH __attribute__((fallthrough)) +#endif + +#if defined(__MINGW32__) && !defined(__MINGW64__) +// Currently (March 2019) thread_local is broken on mingw for all current 32bit compiler releases, see +// https://sourceforge.net/p/mingw-w64/bugs/527/ +// Not setting this causes program termination on thread exit. +#define BOOST_NO_CXX11_THREAD_LOCAL +#endif + +// +// Unused attribute: +#if __GNUC__ >= 4 +# define BOOST_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#endif + +// Type aliasing hint. Supported since gcc 3.3. +#define BOOST_MAY_ALIAS __attribute__((__may_alias__)) + +// +// __builtin_unreachable: +#if BOOST_GCC_VERSION >= 40500 +#define BOOST_UNREACHABLE_RETURN(x) __builtin_unreachable(); +#endif + +#ifndef BOOST_COMPILER +# define BOOST_COMPILER "GNU C++ version " __VERSION__ +#endif + +// ConceptGCC compiler: +// http://www.generic-programming.org/software/ConceptGCC/ +#ifdef __GXX_CONCEPTS__ +# define BOOST_HAS_CONCEPTS +# define BOOST_COMPILER "ConceptGCC version " __VERSION__ +#endif + +// versions check: +// we don't know gcc prior to version 3.30: +#if (BOOST_GCC_VERSION< 30300) +# error "Compiler not configured - please reconfigure" +#endif +// +// last known and checked version is 8.1: +#if (BOOST_GCC_VERSION > 80100) +# if defined(BOOST_ASSERT_CONFIG) +# error "Boost.Config is older than your compiler - please check for an updated Boost release." +# else +// we don't emit warnings here anymore since there are no defect macros defined for +// gcc post 3.4, so any failures are gcc regressions... +//# warning "boost: Unknown compiler version - please run the configure tests and report the results" +# endif +#endif + diff --git a/src/vendor/boost/config/detail/posix_features.hpp b/src/vendor/boost/config/detail/posix_features.hpp new file mode 100644 index 000000000..d12954797 --- /dev/null +++ b/src/vendor/boost/config/detail/posix_features.hpp @@ -0,0 +1,95 @@ +// (C) Copyright John Maddock 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// All POSIX feature tests go in this file, +// Note that we test _POSIX_C_SOURCE and _XOPEN_SOURCE as well +// _POSIX_VERSION and _XOPEN_VERSION: on some systems POSIX API's +// may be present but none-functional unless _POSIX_C_SOURCE and +// _XOPEN_SOURCE have been defined to the right value (it's up +// to the user to do this *before* including any header, although +// in most cases the compiler will do this for you). + +# if defined(BOOST_HAS_UNISTD_H) +# include + + // XOpen has , but is this the correct version check? +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION >= 3) +# define BOOST_HAS_NL_TYPES_H +# endif + + // POSIX version 6 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 200100) +# define BOOST_HAS_STDINT_H +# endif + + // POSIX version 2 requires +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199009L) +# define BOOST_HAS_DIRENT_H +# endif + + // POSIX version 3 requires to have sigaction: +# if defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199506L) +# define BOOST_HAS_SIGACTION +# endif + // POSIX defines _POSIX_THREADS > 0 for pthread support, + // however some platforms define _POSIX_THREADS without + // a value, hence the (_POSIX_THREADS+0 >= 0) check. + // Strictly speaking this may catch platforms with a + // non-functioning stub , but such occurrences should + // occur very rarely if at all. +# if defined(_POSIX_THREADS) && (_POSIX_THREADS+0 >= 0) && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_MPTASKS) +# define BOOST_HAS_PTHREADS +# endif + + // BOOST_HAS_NANOSLEEP: + // This is predicated on _POSIX_TIMERS or _XOPEN_REALTIME: +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) \ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_NANOSLEEP +# endif + + // BOOST_HAS_CLOCK_GETTIME: + // This is predicated on _POSIX_TIMERS (also on _XOPEN_REALTIME + // but at least one platform - linux - defines that flag without + // defining clock_gettime): +# if (defined(_POSIX_TIMERS) && (_POSIX_TIMERS+0 >= 0)) +# define BOOST_HAS_CLOCK_GETTIME +# endif + + // BOOST_HAS_SCHED_YIELD: + // This is predicated on _POSIX_PRIORITY_SCHEDULING or + // on _POSIX_THREAD_PRIORITY_SCHEDULING or on _XOPEN_REALTIME. +# if defined(_POSIX_PRIORITY_SCHEDULING) && (_POSIX_PRIORITY_SCHEDULING+0 > 0)\ + || (defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING+0 > 0))\ + || (defined(_XOPEN_REALTIME) && (_XOPEN_REALTIME+0 >= 0)) +# define BOOST_HAS_SCHED_YIELD +# endif + + // BOOST_HAS_GETTIMEOFDAY: + // BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE: + // These are predicated on _XOPEN_VERSION, and appears to be first released + // in issue 4, version 2 (_XOPEN_VERSION > 500). + // Likewise for the functions log1p and expm1. +# if defined(_XOPEN_VERSION) && (_XOPEN_VERSION+0 >= 500) +# define BOOST_HAS_GETTIMEOFDAY +# if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE+0 >= 500) +# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# endif +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +# endif + + + + diff --git a/src/vendor/boost/config/detail/select_compiler_config.hpp b/src/vendor/boost/config/detail/select_compiler_config.hpp new file mode 100644 index 000000000..c3d99e1a4 --- /dev/null +++ b/src/vendor/boost/config/detail/select_compiler_config.hpp @@ -0,0 +1,157 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Martin Wille 2003. +// (C) Copyright Guillaume Melquiond 2003. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + +// locate which compiler we are using and define +// BOOST_COMPILER_CONFIG as needed: + +#if defined __CUDACC__ +// NVIDIA CUDA C++ compiler for GPU +# include "boost/config/compiler/nvcc.hpp" + +#endif + +#if defined(__GCCXML__) +// GCC-XML emulates other compilers, it has to appear first here! +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" + +#elif defined(_CRAYC) +// EDG based Cray compiler: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" + +#elif defined __COMO__ +// Comeau C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" + +#elif defined(__PATHSCALE__) && (__PATHCC__ >= 4) +// PathScale EKOPath compiler (has to come before clang and gcc) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pathscale.hpp" + +#elif defined(__INTEL_COMPILER) || defined(__ICL) || defined(__ICC) || defined(__ECC) +// Intel +# define BOOST_COMPILER_CONFIG "boost/config/compiler/intel.hpp" + +#elif defined __clang__ && !defined(__ibmxl__) && !defined(__CODEGEARC__) +// Clang C++ emulates GCC, so it has to appear early. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/clang.hpp" + +#elif defined __DMC__ +// Digital Mars C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/digitalmars.hpp" + +#elif defined __DCC__ +// Wind River Diab C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/diab.hpp" + +#elif defined(__PGI) +// Portland Group Inc. +# define BOOST_COMPILER_CONFIG "boost/config/compiler/pgi.hpp" + +# elif defined(__GNUC__) && !defined(__ibmxl__) +// GNU C++: +# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc.hpp" + +#elif defined __KCC +// Kai C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/kai.hpp" + +#elif defined __sgi +// SGI MIPSpro C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sgi_mipspro.hpp" + +#elif defined __DECCXX +// Compaq Tru64 Unix cxx +# define BOOST_COMPILER_CONFIG "boost/config/compiler/compaq_cxx.hpp" + +#elif defined __ghs +// Greenhills C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/greenhills.hpp" + +#elif defined __CODEGEARC__ +// CodeGear - must be checked for before Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/codegear.hpp" + +#elif defined __BORLANDC__ +// Borland +# define BOOST_COMPILER_CONFIG "boost/config/compiler/borland.hpp" + +#elif defined __MWERKS__ +// Metrowerks CodeWarrior +# define BOOST_COMPILER_CONFIG "boost/config/compiler/metrowerks.hpp" + +#elif defined __SUNPRO_CC +// Sun Workshop Compiler C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/sunpro_cc.hpp" + +#elif defined __HP_aCC +// HP aCC +# define BOOST_COMPILER_CONFIG "boost/config/compiler/hp_acc.hpp" + +#elif defined(__MRC__) || defined(__SC__) +// MPW MrCpp or SCpp +# define BOOST_COMPILER_CONFIG "boost/config/compiler/mpw.hpp" + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) +// IBM z/OS XL C/C++ +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp_zos.hpp" + +#elif defined(__ibmxl__) +// IBM XL C/C++ for Linux (Little Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/xlcpp.hpp" + +#elif defined(__IBMCPP__) +// IBM Visual Age or IBM XL C/C++ for Linux (Big Endian) +# define BOOST_COMPILER_CONFIG "boost/config/compiler/vacpp.hpp" + +#elif defined _MSC_VER +// Microsoft Visual C++ +// +// Must remain the last #elif since some other vendors (Metrowerks, for +// example) also #define _MSC_VER +# define BOOST_COMPILER_CONFIG "boost/config/compiler/visualc.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the compiler: +# error "Unknown compiler - please configure (http://www.boost.org/libs/config/config.htm#configuring) and report the results to the main boost mailing list (http://www.boost.org/more/mailing_lists.htm#main)" + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the headers we *might* include: +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif + diff --git a/src/vendor/boost/config/detail/select_platform_config.hpp b/src/vendor/boost/config/detail/select_platform_config.hpp new file mode 100644 index 000000000..b36eca57a --- /dev/null +++ b/src/vendor/boost/config/detail/select_platform_config.hpp @@ -0,0 +1,142 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2002. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// locate which platform we are on and define BOOST_PLATFORM_CONFIG as needed. +// Note that we define the headers to include using "header_name" not +// in order to prevent macro expansion within the header +// name (for example "linux" is a macro on linux systems). + +#if (defined(linux) || defined(__linux) || defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)) && !defined(_CRAYC) +// linux, also other platforms (Hurd etc) that use GLIBC, should these really have their own config headers though? +# define BOOST_PLATFORM_CONFIG "boost/config/platform/linux.hpp" + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +// BSD: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/bsd.hpp" + +#elif defined(sun) || defined(__sun) +// solaris: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/solaris.hpp" + +#elif defined(__sgi) +// SGI Irix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/irix.hpp" + +#elif defined(__hpux) +// hp unix: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/hpux.hpp" + +#elif defined(__CYGWIN__) +// cygwin is not win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cygwin.hpp" + +#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +// win32: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/win32.hpp" + +#elif defined(__HAIKU__) +// Haiku +# define BOOST_PLATFORM_CONFIG "boost/config/platform/haiku.hpp" + +#elif defined(__BEOS__) +// BeOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/beos.hpp" + +#elif defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) +// MacOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/macos.hpp" + +#elif defined(__TOS_MVS__) +// IBM z/OS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/zos.hpp" + +#elif defined(__IBMCPP__) || defined(_AIX) +// IBM AIX +# define BOOST_PLATFORM_CONFIG "boost/config/platform/aix.hpp" + +#elif defined(__amigaos__) +// AmigaOS +# define BOOST_PLATFORM_CONFIG "boost/config/platform/amigaos.hpp" + +#elif defined(__QNXNTO__) +// QNX: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/qnxnto.hpp" + +#elif defined(__VXWORKS__) +// vxWorks: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vxworks.hpp" + +#elif defined(__SYMBIAN32__) +// Symbian: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/symbian.hpp" + +#elif defined(_CRAYC) +// Cray: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cray.hpp" + +#elif defined(__VMS) +// VMS: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/vms.hpp" + +#elif defined(__CloudABI__) +// Nuxi CloudABI: +# define BOOST_PLATFORM_CONFIG "boost/config/platform/cloudabi.hpp" +#else + +# if defined(unix) \ + || defined(__unix) \ + || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) + + // generic unix platform: + +# ifndef BOOST_HAS_UNISTD_H +# define BOOST_HAS_UNISTD_H +# endif + +# include + +# endif + +# if defined (BOOST_ASSERT_CONFIG) + // this must come last - generate an error if we don't + // recognise the platform: +# error "Unknown platform - please configure and report the results to boost.org" +# endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/platform/linux.hpp" +# include "boost/config/platform/bsd.hpp" +# include "boost/config/platform/solaris.hpp" +# include "boost/config/platform/irix.hpp" +# include "boost/config/platform/hpux.hpp" +# include "boost/config/platform/cygwin.hpp" +# include "boost/config/platform/win32.hpp" +# include "boost/config/platform/beos.hpp" +# include "boost/config/platform/macos.hpp" +# include "boost/config/platform/zos.hpp" +# include "boost/config/platform/aix.hpp" +# include "boost/config/platform/amigaos.hpp" +# include "boost/config/platform/qnxnto.hpp" +# include "boost/config/platform/vxworks.hpp" +# include "boost/config/platform/symbian.hpp" +# include "boost/config/platform/cray.hpp" +# include "boost/config/platform/vms.hpp" +# include + + + +#endif + diff --git a/src/vendor/boost/config/detail/select_stdlib_config.hpp b/src/vendor/boost/config/detail/select_stdlib_config.hpp new file mode 100644 index 000000000..1a09dda12 --- /dev/null +++ b/src/vendor/boost/config/detail/select_stdlib_config.hpp @@ -0,0 +1,121 @@ +// Boost compiler configuration selection header file + +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2002. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + + +// See http://www.boost.org for most recent version. + +// locate which std lib we are using and define BOOST_STDLIB_CONFIG as needed: + +// First, check if __has_include is available and include can be located, +// otherwise include to determine if some version of STLport is in use as the std lib +// (do not rely on this header being included since users can short-circuit this header +// if they know whose std lib they are using.) +#if defined(__cplusplus) && defined(__has_include) +# if __has_include() +// It should be safe to include `` when it is present without checking +// the actual C++ language version as it consists solely of macro definitions. +// [version.syn] p1: The header supplies implementation-dependent +// information about the C++ standard library (e.g., version number and release date). +# include +# else +# include +# endif +#elif defined(__cplusplus) +# include +#else +# include +#endif + +#if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) +// STLPort library; this _must_ come first, otherwise since +// STLport typically sits on top of some other library, we +// can end up detecting that first rather than STLport: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/stlport.hpp" + +#else + +// If our std lib was not some version of STLport, and has not otherwise +// been detected, then include as it is about +// the smallest of the std lib headers that includes real C++ stuff. +// Some std libs do not include their C++-related macros in +// so this additional include makes sure we get those definitions. +// Note: do not rely on this header being included since users can short-circuit this +// #include if they know whose std lib they are using. +#if !defined(__LIBCOMO__) && !defined(__STD_RWCOMPILER_H__) && !defined(_RWSTD_VER)\ + && !defined(_LIBCPP_VERSION) && !defined(__GLIBCPP__) && !defined(__GLIBCXX__)\ + && !defined(__STL_CONFIG_H) && !defined(__MSL_CPP__) && !defined(__IBMCPP__)\ + && !defined(MSIPL_COMPILE_H) && !defined(_YVALS) && !defined(_CPPLIB_VER) +#include +#endif + +#if defined(__LIBCOMO__) +// Comeau STL: +#define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcomo.hpp" + +#elif defined(__STD_RWCOMPILER_H__) || defined(_RWSTD_VER) +// Rogue Wave library: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/roguewave.hpp" + +#elif defined(_LIBCPP_VERSION) +// libc++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libcpp.hpp" + +#elif defined(__GLIBCPP__) || defined(__GLIBCXX__) +// GNU libstdc++ 3 +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/libstdcpp3.hpp" + +#elif defined(__STL_CONFIG_H) +// generic SGI STL +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/sgi.hpp" + +#elif defined(__MSL_CPP__) +// MSL standard lib: +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/msl.hpp" + +#elif defined(__IBMCPP__) && defined(__COMPILER_VER__) && defined(__MVS__) +// IBM z/OS XL C/C++ +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/xlcpp_zos.hpp" + +#elif defined(__IBMCPP__) +// take the default VACPP std lib +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/vacpp.hpp" + +#elif defined(MSIPL_COMPILE_H) +// Modena C++ standard library +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/modena.hpp" + +#elif (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +// Dinkumware Library (this has to appear after any possible replacement libraries): +# define BOOST_STDLIB_CONFIG "boost/config/stdlib/dinkumware.hpp" + +#elif defined (BOOST_ASSERT_CONFIG) +// this must come last - generate an error if we don't +// recognise the library: +# error "Unknown standard library - please configure and report the results to boost.org" + +#endif + +#endif + +#if 0 +// +// This section allows dependency scanners to find all the files we *might* include: +// +# include "boost/config/stdlib/stlport.hpp" +# include "boost/config/stdlib/libcomo.hpp" +# include "boost/config/stdlib/roguewave.hpp" +# include "boost/config/stdlib/libcpp.hpp" +# include "boost/config/stdlib/libstdcpp3.hpp" +# include "boost/config/stdlib/sgi.hpp" +# include "boost/config/stdlib/msl.hpp" +# include "boost/config/stdlib/xlcpp_zos.hpp" +# include "boost/config/stdlib/vacpp.hpp" +# include "boost/config/stdlib/modena.hpp" +# include "boost/config/stdlib/dinkumware.hpp" +#endif + diff --git a/src/vendor/boost/config/detail/suffix.hpp b/src/vendor/boost/config/detail/suffix.hpp new file mode 100644 index 000000000..994dce928 --- /dev/null +++ b/src/vendor/boost/config/detail/suffix.hpp @@ -0,0 +1,1116 @@ +// Boost config.hpp configuration header file ------------------------------// +// boostinspect:ndprecated_macros -- tell the inspect tool to ignore this file + +// Copyright (c) 2001-2003 John Maddock +// Copyright (c) 2001 Darin Adler +// Copyright (c) 2001 Peter Dimov +// Copyright (c) 2002 Bill Kempf +// Copyright (c) 2002 Jens Maurer +// Copyright (c) 2002-2003 David Abrahams +// Copyright (c) 2003 Gennaro Prota +// Copyright (c) 2003 Eric Friedman +// Copyright (c) 2010 Eric Jourdanneau, Joel Falcou +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/ for most recent version. + +// Boost config.hpp policy and rationale documentation has been moved to +// http://www.boost.org/libs/config/ +// +// This file is intended to be stable, and relatively unchanging. +// It should contain boilerplate code only - no compiler specific +// code unless it is unavoidable - no changes unless unavoidable. + +#ifndef BOOST_CONFIG_SUFFIX_HPP +#define BOOST_CONFIG_SUFFIX_HPP + +#if defined(__GNUC__) && (__GNUC__ >= 4) +// +// Some GCC-4.x versions issue warnings even when __extension__ is used, +// so use this as a workaround: +// +#pragma GCC system_header +#endif + +// +// ensure that visibility macros are always defined, thus simplifying use +// +#ifndef BOOST_SYMBOL_EXPORT +# define BOOST_SYMBOL_EXPORT +#endif +#ifndef BOOST_SYMBOL_IMPORT +# define BOOST_SYMBOL_IMPORT +#endif +#ifndef BOOST_SYMBOL_VISIBLE +# define BOOST_SYMBOL_VISIBLE +#endif + +// +// look for long long by looking for the appropriate macros in . +// Note that we use limits.h rather than climits for maximal portability, +// remember that since these just declare a bunch of macros, there should be +// no namespace issues from this. +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG) \ + && !defined(BOOST_MSVC) && !defined(BOOST_BORLANDC) +# include +# if (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# define BOOST_HAS_LONG_LONG +# else +# define BOOST_NO_LONG_LONG +# endif +#endif + +// GCC 3.x will clean up all of those nasty macro definitions that +// BOOST_NO_CTYPE_FUNCTIONS is intended to help work around, so undefine +// it under GCC 3.x. +#if defined(__GNUC__) && (__GNUC__ >= 3) && defined(BOOST_NO_CTYPE_FUNCTIONS) +# undef BOOST_NO_CTYPE_FUNCTIONS +#endif + +// +// Assume any extensions are in namespace std:: unless stated otherwise: +// +# ifndef BOOST_STD_EXTENSION_NAMESPACE +# define BOOST_STD_EXTENSION_NAMESPACE std +# endif + +// +// If cv-qualified specializations are not allowed, then neither are cv-void ones: +// +# if defined(BOOST_NO_CV_SPECIALIZATIONS) \ + && !defined(BOOST_NO_CV_VOID_SPECIALIZATIONS) +# define BOOST_NO_CV_VOID_SPECIALIZATIONS +# endif + +// +// If there is no numeric_limits template, then it can't have any compile time +// constants either! +// +# if defined(BOOST_NO_LIMITS) \ + && !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) +# define BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +# endif + +// +// if there is no long long then there is no specialisation +// for numeric_limits either: +// +#if !defined(BOOST_HAS_LONG_LONG) && !defined(BOOST_NO_LONG_LONG_NUMERIC_LIMITS) +# define BOOST_NO_LONG_LONG_NUMERIC_LIMITS +#endif + +// +// if there is no __int64 then there is no specialisation +// for numeric_limits<__int64> either: +// +#if !defined(BOOST_HAS_MS_INT64) && !defined(BOOST_NO_MS_INT64_NUMERIC_LIMITS) +# define BOOST_NO_MS_INT64_NUMERIC_LIMITS +#endif + +// +// if member templates are supported then so is the +// VC6 subset of member templates: +// +# if !defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) +# define BOOST_MSVC6_MEMBER_TEMPLATES +# endif + +// +// Without partial specialization, can't test for partial specialisation bugs: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) +# define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG +# endif + +// +// Without partial specialization, we can't have array-type partial specialisations: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +# define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS +# endif + +// +// Without partial specialization, std::iterator_traits can't work: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_STD_ITERATOR_TRAITS) +# define BOOST_NO_STD_ITERATOR_TRAITS +# endif + +// +// Without partial specialization, partial +// specialization with default args won't work either: +// +# if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \ + && !defined(BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS) +# define BOOST_NO_PARTIAL_SPECIALIZATION_IMPLICIT_DEFAULT_ARGS +# endif + +// +// Without member template support, we can't have template constructors +// in the standard library either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) +# define BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS +# endif + +// +// Without member template support, we can't have a conforming +// std::allocator template either: +// +# if defined(BOOST_NO_MEMBER_TEMPLATES) \ + && !defined(BOOST_MSVC6_MEMBER_TEMPLATES) \ + && !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_NO_STD_ALLOCATOR +# endif + +// +// without ADL support then using declarations will break ADL as well: +// +#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP) && !defined(BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL) +# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL +#endif + +// +// Without typeid support we have no dynamic RTTI either: +// +#if defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI) +# define BOOST_NO_RTTI +#endif + +// +// If we have a standard allocator, then we have a partial one as well: +// +#if !defined(BOOST_NO_STD_ALLOCATOR) +# define BOOST_HAS_PARTIAL_STD_ALLOCATOR +#endif + +// +// We can't have a working std::use_facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_USE_FACET) +# define BOOST_NO_STD_USE_FACET +# endif + +// +// We can't have a std::messages facet if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_MESSAGES) +# define BOOST_NO_STD_MESSAGES +# endif + +// +// We can't have a working std::wstreambuf if there is no std::locale: +// +# if defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_STD_WSTREAMBUF) +# define BOOST_NO_STD_WSTREAMBUF +# endif + +// +// We can't have a if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_CWCTYPE) +# define BOOST_NO_CWCTYPE +# endif + +// +// We can't have a swprintf if there is no : +// +# if defined(BOOST_NO_CWCHAR) && !defined(BOOST_NO_SWPRINTF) +# define BOOST_NO_SWPRINTF +# endif + +// +// If Win32 support is turned off, then we must turn off +// threading support also, unless there is some other +// thread API enabled: +// +#if defined(BOOST_DISABLE_WIN32) && defined(_WIN32) \ + && !defined(BOOST_DISABLE_THREADS) && !defined(BOOST_HAS_PTHREADS) +# define BOOST_DISABLE_THREADS +#endif + +// +// Turn on threading support if the compiler thinks that it's in +// multithreaded mode. We put this here because there are only a +// limited number of macros that identify this (if there's any missing +// from here then add to the appropriate compiler section): +// +#if (defined(__MT__) || defined(_MT) || defined(_REENTRANT) \ + || defined(_PTHREADS) || defined(__APPLE__) || defined(__DragonFly__)) \ + && !defined(BOOST_HAS_THREADS) +# define BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if BOOST_DISABLE_THREADS is defined: +// +#if defined(BOOST_DISABLE_THREADS) && defined(BOOST_HAS_THREADS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading support off if we don't recognise the threading API: +// +#if defined(BOOST_HAS_THREADS) && !defined(BOOST_HAS_PTHREADS)\ + && !defined(BOOST_HAS_WINTHREADS) && !defined(BOOST_HAS_BETHREADS)\ + && !defined(BOOST_HAS_MPTASKS) +# undef BOOST_HAS_THREADS +#endif + +// +// Turn threading detail macros off if we don't (want to) use threading +// +#ifndef BOOST_HAS_THREADS +# undef BOOST_HAS_PTHREADS +# undef BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE +# undef BOOST_HAS_PTHREAD_YIELD +# undef BOOST_HAS_PTHREAD_DELAY_NP +# undef BOOST_HAS_WINTHREADS +# undef BOOST_HAS_BETHREADS +# undef BOOST_HAS_MPTASKS +#endif + +// +// If the compiler claims to be C99 conformant, then it had better +// have a : +// +# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define BOOST_HAS_STDINT_H +# ifndef BOOST_HAS_LOG1P +# define BOOST_HAS_LOG1P +# endif +# ifndef BOOST_HAS_EXPM1 +# define BOOST_HAS_EXPM1 +# endif +# endif + +// +// Define BOOST_NO_SLIST and BOOST_NO_HASH if required. +// Note that this is for backwards compatibility only. +// +# if !defined(BOOST_HAS_SLIST) && !defined(BOOST_NO_SLIST) +# define BOOST_NO_SLIST +# endif + +# if !defined(BOOST_HAS_HASH) && !defined(BOOST_NO_HASH) +# define BOOST_NO_HASH +# endif + +// +// Set BOOST_SLIST_HEADER if not set already: +// +#if defined(BOOST_HAS_SLIST) && !defined(BOOST_SLIST_HEADER) +# define BOOST_SLIST_HEADER +#endif + +// +// Set BOOST_HASH_SET_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_SET_HEADER) +# define BOOST_HASH_SET_HEADER +#endif + +// +// Set BOOST_HASH_MAP_HEADER if not set already: +// +#if defined(BOOST_HAS_HASH) && !defined(BOOST_HASH_MAP_HEADER) +# define BOOST_HASH_MAP_HEADER +#endif + +// BOOST_HAS_ABI_HEADERS +// This macro gets set if we have headers that fix the ABI, +// and prevent ODR violations when linking to external libraries: +#if defined(BOOST_ABI_PREFIX) && defined(BOOST_ABI_SUFFIX) && !defined(BOOST_HAS_ABI_HEADERS) +# define BOOST_HAS_ABI_HEADERS +#endif + +#if defined(BOOST_HAS_ABI_HEADERS) && defined(BOOST_DISABLE_ABI_HEADERS) +# undef BOOST_HAS_ABI_HEADERS +#endif + +// BOOST_NO_STDC_NAMESPACE workaround --------------------------------------// +// Because std::size_t usage is so common, even in boost headers which do not +// otherwise use the C library, the workaround is included here so +// that ugly workaround code need not appear in many other boost headers. +// NOTE WELL: This is a workaround for non-conforming compilers; +// must still be #included in the usual places so that inclusion +// works as expected with standard conforming compilers. The resulting +// double inclusion of is harmless. + +# if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus) +# include + namespace std { using ::ptrdiff_t; using ::size_t; } +# endif + +// Workaround for the unfortunate min/max macros defined by some platform headers + +#define BOOST_PREVENT_MACRO_SUBSTITUTION + +#ifndef BOOST_USING_STD_MIN +# define BOOST_USING_STD_MIN() using std::min +#endif + +#ifndef BOOST_USING_STD_MAX +# define BOOST_USING_STD_MAX() using std::max +#endif + +// BOOST_NO_STD_MIN_MAX workaround -----------------------------------------// + +# if defined(BOOST_NO_STD_MIN_MAX) && defined(__cplusplus) + +namespace std { + template + inline const _Tp& min BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __b < __a ? __b : __a; + } + template + inline const _Tp& max BOOST_PREVENT_MACRO_SUBSTITUTION (const _Tp& __a, const _Tp& __b) { + return __a < __b ? __b : __a; + } +} + +# endif + +// BOOST_STATIC_CONSTANT workaround --------------------------------------- // +// On compilers which don't allow in-class initialization of static integral +// constant members, we must use enums as a workaround if we want the constants +// to be available at compile-time. This macro gives us a convenient way to +// declare such constants. + +# ifdef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +# define BOOST_STATIC_CONSTANT(type, assignment) enum { assignment } +# else +# define BOOST_STATIC_CONSTANT(type, assignment) static const type assignment +# endif + +// BOOST_USE_FACET / HAS_FACET workaround ----------------------------------// +// When the standard library does not have a conforming std::use_facet there +// are various workarounds available, but they differ from library to library. +// The same problem occurs with has_facet. +// These macros provide a consistent way to access a locale's facets. +// Usage: +// replace +// std::use_facet(loc); +// with +// BOOST_USE_FACET(Type, loc); +// Note do not add a std:: prefix to the front of BOOST_USE_FACET! +// Use for BOOST_HAS_FACET is analogous. + +#if defined(BOOST_NO_STD_USE_FACET) +# ifdef BOOST_HAS_TWO_ARG_USE_FACET +# define BOOST_USE_FACET(Type, loc) std::use_facet(loc, static_cast(0)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet(loc, static_cast(0)) +# elif defined(BOOST_HAS_MACRO_USE_FACET) +# define BOOST_USE_FACET(Type, loc) std::_USE(loc, Type) +# define BOOST_HAS_FACET(Type, loc) std::_HAS(loc, Type) +# elif defined(BOOST_HAS_STLP_USE_FACET) +# define BOOST_USE_FACET(Type, loc) (*std::_Use_facet(loc)) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +# endif +#else +# define BOOST_USE_FACET(Type, loc) std::use_facet< Type >(loc) +# define BOOST_HAS_FACET(Type, loc) std::has_facet< Type >(loc) +#endif + +// BOOST_NESTED_TEMPLATE workaround ------------------------------------------// +// Member templates are supported by some compilers even though they can't use +// the A::template member syntax, as a workaround replace: +// +// typedef typename A::template rebind binder; +// +// with: +// +// typedef typename A::BOOST_NESTED_TEMPLATE rebind binder; + +#ifndef BOOST_NO_MEMBER_TEMPLATE_KEYWORD +# define BOOST_NESTED_TEMPLATE template +#else +# define BOOST_NESTED_TEMPLATE +#endif + +// BOOST_UNREACHABLE_RETURN(x) workaround -------------------------------------// +// Normally evaluates to nothing, unless BOOST_NO_UNREACHABLE_RETURN_DETECTION +// is defined, in which case it evaluates to return x; Use when you have a return +// statement that can never be reached. + +#ifndef BOOST_UNREACHABLE_RETURN +# ifdef BOOST_NO_UNREACHABLE_RETURN_DETECTION +# define BOOST_UNREACHABLE_RETURN(x) return x; +# else +# define BOOST_UNREACHABLE_RETURN(x) +# endif +#endif + +// BOOST_DEDUCED_TYPENAME workaround ------------------------------------------// +// +// Some compilers don't support the use of `typename' for dependent +// types in deduced contexts, e.g. +// +// template void f(T, typename T::type); +// ^^^^^^^^ +// Replace these declarations with: +// +// template void f(T, BOOST_DEDUCED_TYPENAME T::type); + +#ifndef BOOST_NO_DEDUCED_TYPENAME +# define BOOST_DEDUCED_TYPENAME typename +#else +# define BOOST_DEDUCED_TYPENAME +#endif + +#ifndef BOOST_NO_TYPENAME_WITH_CTOR +# define BOOST_CTOR_TYPENAME typename +#else +# define BOOST_CTOR_TYPENAME +#endif + +// long long workaround ------------------------------------------// +// On gcc (and maybe other compilers?) long long is alway supported +// but it's use may generate either warnings (with -ansi), or errors +// (with -pedantic -ansi) unless it's use is prefixed by __extension__ +// +#if defined(BOOST_HAS_LONG_LONG) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef long long long_long_type; + __extension__ typedef unsigned long long ulong_long_type; +# else + typedef long long long_long_type; + typedef unsigned long long ulong_long_type; +# endif +} +#endif +// same again for __int128: +#if defined(BOOST_HAS_INT128) && defined(__cplusplus) +namespace boost{ +# ifdef __GNUC__ + __extension__ typedef __int128 int128_type; + __extension__ typedef unsigned __int128 uint128_type; +# else + typedef __int128 int128_type; + typedef unsigned __int128 uint128_type; +# endif +} +#endif +// same again for __float128: +#if defined(BOOST_HAS_FLOAT128) && defined(__cplusplus) +namespace boost { +# ifdef __GNUC__ + __extension__ typedef __float128 float128_type; +# else + typedef __float128 float128_type; +# endif +} +#endif + +// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// + +// These macros are obsolete. Port away and remove. + +# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) +# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) + +// When BOOST_NO_STD_TYPEINFO is defined, we can just import +// the global definition into std namespace, +// see https://svn.boost.org/trac10/ticket/4115 +#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) && defined(BOOST_MSVC) +#include +namespace std{ using ::type_info; } +// Since we do now have typeinfo, undef the macro: +#undef BOOST_NO_STD_TYPEINFO +#endif + +// ---------------------------------------------------------------------------// + +// Helper macro BOOST_STRINGIZE: +// Helper macro BOOST_JOIN: + +#include + +// +// Set some default values for compiler/library/platform names. +// These are for debugging config setup only: +// +# ifndef BOOST_COMPILER +# define BOOST_COMPILER "Unknown ISO C++ Compiler" +# endif +# ifndef BOOST_STDLIB +# define BOOST_STDLIB "Unknown ISO standard library" +# endif +# ifndef BOOST_PLATFORM +# if defined(unix) || defined(__unix) || defined(_XOPEN_SOURCE) \ + || defined(_POSIX_SOURCE) +# define BOOST_PLATFORM "Generic Unix" +# else +# define BOOST_PLATFORM "Unknown" +# endif +# endif + +// +// Set some default values GPU support +// +# ifndef BOOST_GPU_ENABLED +# define BOOST_GPU_ENABLED +# endif + +// BOOST_RESTRICT ---------------------------------------------// +// Macro to use in place of 'restrict' keyword variants +#if !defined(BOOST_RESTRICT) +# if defined(_MSC_VER) +# define BOOST_RESTRICT __restrict +# if !defined(BOOST_NO_RESTRICT_REFERENCES) && (_MSC_FULL_VER < 190023026) +# define BOOST_NO_RESTRICT_REFERENCES +# endif +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_RESTRICT __restrict__ +# else +# define BOOST_RESTRICT +# if !defined(BOOST_NO_RESTRICT_REFERENCES) +# define BOOST_NO_RESTRICT_REFERENCES +# endif +# endif +#endif + +// BOOST_MAY_ALIAS -----------------------------------------------// +// The macro expands to an attribute to mark a type that is allowed to alias other types. +// The macro is defined in the compiler-specific headers. +#if !defined(BOOST_MAY_ALIAS) +# define BOOST_NO_MAY_ALIAS +# define BOOST_MAY_ALIAS +#endif + +// BOOST_FORCEINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to force a function to be inline +#if !defined(BOOST_FORCEINLINE) +# if defined(_MSC_VER) +# define BOOST_FORCEINLINE __forceinline +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# define BOOST_FORCEINLINE inline __attribute__ ((__always_inline__)) +# else +# define BOOST_FORCEINLINE inline +# endif +#endif + +// BOOST_NOINLINE ---------------------------------------------// +// Macro to use in place of 'inline' to prevent a function to be inlined +#if !defined(BOOST_NOINLINE) +# if defined(_MSC_VER) +# define BOOST_NOINLINE __declspec(noinline) +# elif defined(__GNUC__) && __GNUC__ > 3 + // Clang also defines __GNUC__ (as 4) +# if defined(__CUDACC__) + // nvcc doesn't always parse __noinline__, + // see: https://svn.boost.org/trac/boost/ticket/9392 +# define BOOST_NOINLINE __attribute__ ((noinline)) +# else +# define BOOST_NOINLINE __attribute__ ((__noinline__)) +# endif +# else +# define BOOST_NOINLINE +# endif +#endif + +// BOOST_NORETURN ---------------------------------------------// +// Macro to use before a function declaration/definition to designate +// the function as not returning normally (i.e. with a return statement +// or by leaving the function scope, if the function return type is void). +#if !defined(BOOST_NORETURN) +# if defined(_MSC_VER) +# define BOOST_NORETURN __declspec(noreturn) +# elif defined(__GNUC__) || defined(__CODEGEARC__) && defined(__clang__) +# define BOOST_NORETURN __attribute__ ((__noreturn__)) +# elif defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +# if __has_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# elif defined(__has_cpp_attribute) +# if __has_cpp_attribute(noreturn) +# define BOOST_NORETURN [[noreturn]] +# endif +# endif +#endif + +#if !defined(BOOST_NORETURN) +# define BOOST_NO_NORETURN +# define BOOST_NORETURN +#endif + +// Branch prediction hints +// These macros are intended to wrap conditional expressions that yield true or false +// +// if (BOOST_LIKELY(var == 10)) +// { +// // the most probable code here +// } +// +#if !defined(BOOST_LIKELY) +# define BOOST_LIKELY(x) x +#endif +#if !defined(BOOST_UNLIKELY) +# define BOOST_UNLIKELY(x) x +#endif + +#if !defined(BOOST_NO_CXX11_OVERRIDE) +# define BOOST_OVERRIDE override +#else +# define BOOST_OVERRIDE +#endif + +// Type and data alignment specification +// +#if !defined(BOOST_ALIGNMENT) +# if !defined(BOOST_NO_CXX11_ALIGNAS) +# define BOOST_ALIGNMENT(x) alignas(x) +# elif defined(_MSC_VER) +# define BOOST_ALIGNMENT(x) __declspec(align(x)) +# elif defined(__GNUC__) +# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x))) +# else +# define BOOST_NO_ALIGNMENT +# define BOOST_ALIGNMENT(x) +# endif +#endif + +// Lack of non-public defaulted functions is implied by the lack of any defaulted functions +#if !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) && defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) +# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS +#endif + +// Lack of defaulted moves is implied by the lack of either rvalue references or any defaulted functions +#if !defined(BOOST_NO_CXX11_DEFAULTED_MOVES) && (defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_RVALUE_REFERENCES)) +# define BOOST_NO_CXX11_DEFAULTED_MOVES +#endif + +// Defaulted and deleted function declaration helpers +// These macros are intended to be inside a class definition. +// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its +// body, which will be used if the compiler doesn't support defaulted functions. +// BOOST_DELETED_FUNCTION only accepts the function declaration. It +// will expand to a private function declaration, if the compiler doesn't support +// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION +// in the end of the class definition. +// +// class my_class +// { +// public: +// // Default-constructible +// BOOST_DEFAULTED_FUNCTION(my_class(), {}) +// // Copying prohibited +// BOOST_DELETED_FUNCTION(my_class(my_class const&)) +// BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&)) +// }; +// +#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS)) +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default; +#else +# define BOOST_DEFAULTED_FUNCTION(fun, body) fun body +#endif + +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_DELETED_FUNCTION(fun) fun = delete; +#else +# define BOOST_DELETED_FUNCTION(fun) private: fun; +#endif + +// +// Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined +// +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_CXX11_DECLTYPE_N3276) +#define BOOST_NO_CXX11_DECLTYPE_N3276 BOOST_NO_CXX11_DECLTYPE +#endif + +// -------------------- Deprecated macros for 1.50 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET or BOOST_NO_CXX11_HDR_UNORDERED_MAP +// instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) || defined (BOOST_NO_CXX11_HDR_UNORDERED_SET) +# ifndef BOOST_NO_CXX11_STD_UNORDERED +# define BOOST_NO_CXX11_STD_UNORDERED +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST instead of BOOST_NO_INITIALIZER_LISTS +#if defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_INITIALIZER_LISTS) +# define BOOST_NO_INITIALIZER_LISTS +#endif + +// Use BOOST_NO_CXX11_HDR_ARRAY instead of BOOST_NO_0X_HDR_ARRAY +#if defined(BOOST_NO_CXX11_HDR_ARRAY) && !defined(BOOST_NO_0X_HDR_ARRAY) +# define BOOST_NO_0X_HDR_ARRAY +#endif +// Use BOOST_NO_CXX11_HDR_CHRONO instead of BOOST_NO_0X_HDR_CHRONO +#if defined(BOOST_NO_CXX11_HDR_CHRONO) && !defined(BOOST_NO_0X_HDR_CHRONO) +# define BOOST_NO_0X_HDR_CHRONO +#endif +// Use BOOST_NO_CXX11_HDR_CODECVT instead of BOOST_NO_0X_HDR_CODECVT +#if defined(BOOST_NO_CXX11_HDR_CODECVT) && !defined(BOOST_NO_0X_HDR_CODECVT) +# define BOOST_NO_0X_HDR_CODECVT +#endif +// Use BOOST_NO_CXX11_HDR_CONDITION_VARIABLE instead of BOOST_NO_0X_HDR_CONDITION_VARIABLE +#if defined(BOOST_NO_CXX11_HDR_CONDITION_VARIABLE) && !defined(BOOST_NO_0X_HDR_CONDITION_VARIABLE) +# define BOOST_NO_0X_HDR_CONDITION_VARIABLE +#endif +// Use BOOST_NO_CXX11_HDR_FORWARD_LIST instead of BOOST_NO_0X_HDR_FORWARD_LIST +#if defined(BOOST_NO_CXX11_HDR_FORWARD_LIST) && !defined(BOOST_NO_0X_HDR_FORWARD_LIST) +# define BOOST_NO_0X_HDR_FORWARD_LIST +#endif +// Use BOOST_NO_CXX11_HDR_FUTURE instead of BOOST_NO_0X_HDR_FUTURE +#if defined(BOOST_NO_CXX11_HDR_FUTURE) && !defined(BOOST_NO_0X_HDR_FUTURE) +# define BOOST_NO_0X_HDR_FUTURE +#endif + +// Use BOOST_NO_CXX11_HDR_INITIALIZER_LIST +// instead of BOOST_NO_0X_HDR_INITIALIZER_LIST or BOOST_NO_INITIALIZER_LISTS +#ifdef BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# ifndef BOOST_NO_0X_HDR_INITIALIZER_LIST +# define BOOST_NO_0X_HDR_INITIALIZER_LIST +# endif +# ifndef BOOST_NO_INITIALIZER_LISTS +# define BOOST_NO_INITIALIZER_LISTS +# endif +#endif + +// Use BOOST_NO_CXX11_HDR_MUTEX instead of BOOST_NO_0X_HDR_MUTEX +#if defined(BOOST_NO_CXX11_HDR_MUTEX) && !defined(BOOST_NO_0X_HDR_MUTEX) +# define BOOST_NO_0X_HDR_MUTEX +#endif +// Use BOOST_NO_CXX11_HDR_RANDOM instead of BOOST_NO_0X_HDR_RANDOM +#if defined(BOOST_NO_CXX11_HDR_RANDOM) && !defined(BOOST_NO_0X_HDR_RANDOM) +# define BOOST_NO_0X_HDR_RANDOM +#endif +// Use BOOST_NO_CXX11_HDR_RATIO instead of BOOST_NO_0X_HDR_RATIO +#if defined(BOOST_NO_CXX11_HDR_RATIO) && !defined(BOOST_NO_0X_HDR_RATIO) +# define BOOST_NO_0X_HDR_RATIO +#endif +// Use BOOST_NO_CXX11_HDR_REGEX instead of BOOST_NO_0X_HDR_REGEX +#if defined(BOOST_NO_CXX11_HDR_REGEX) && !defined(BOOST_NO_0X_HDR_REGEX) +# define BOOST_NO_0X_HDR_REGEX +#endif +// Use BOOST_NO_CXX11_HDR_SYSTEM_ERROR instead of BOOST_NO_0X_HDR_SYSTEM_ERROR +#if defined(BOOST_NO_CXX11_HDR_SYSTEM_ERROR) && !defined(BOOST_NO_0X_HDR_SYSTEM_ERROR) +# define BOOST_NO_0X_HDR_SYSTEM_ERROR +#endif +// Use BOOST_NO_CXX11_HDR_THREAD instead of BOOST_NO_0X_HDR_THREAD +#if defined(BOOST_NO_CXX11_HDR_THREAD) && !defined(BOOST_NO_0X_HDR_THREAD) +# define BOOST_NO_0X_HDR_THREAD +#endif +// Use BOOST_NO_CXX11_HDR_TUPLE instead of BOOST_NO_0X_HDR_TUPLE +#if defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_0X_HDR_TUPLE) +# define BOOST_NO_0X_HDR_TUPLE +#endif +// Use BOOST_NO_CXX11_HDR_TYPE_TRAITS instead of BOOST_NO_0X_HDR_TYPE_TRAITS +#if defined(BOOST_NO_CXX11_HDR_TYPE_TRAITS) && !defined(BOOST_NO_0X_HDR_TYPE_TRAITS) +# define BOOST_NO_0X_HDR_TYPE_TRAITS +#endif +// Use BOOST_NO_CXX11_HDR_TYPEINDEX instead of BOOST_NO_0X_HDR_TYPEINDEX +#if defined(BOOST_NO_CXX11_HDR_TYPEINDEX) && !defined(BOOST_NO_0X_HDR_TYPEINDEX) +# define BOOST_NO_0X_HDR_TYPEINDEX +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_MAP instead of BOOST_NO_0X_HDR_UNORDERED_MAP +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_MAP) && !defined(BOOST_NO_0X_HDR_UNORDERED_MAP) +# define BOOST_NO_0X_HDR_UNORDERED_MAP +#endif +// Use BOOST_NO_CXX11_HDR_UNORDERED_SET instead of BOOST_NO_0X_HDR_UNORDERED_SET +#if defined(BOOST_NO_CXX11_HDR_UNORDERED_SET) && !defined(BOOST_NO_0X_HDR_UNORDERED_SET) +# define BOOST_NO_0X_HDR_UNORDERED_SET +#endif + +// ------------------ End of deprecated macros for 1.50 --------------------------- + +// -------------------- Deprecated macros for 1.51 --------------------------- +// These will go away in a future release + +// Use BOOST_NO_CXX11_AUTO_DECLARATIONS instead of BOOST_NO_AUTO_DECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && !defined(BOOST_NO_AUTO_DECLARATIONS) +# define BOOST_NO_AUTO_DECLARATIONS +#endif +// Use BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS instead of BOOST_NO_AUTO_MULTIDECLARATIONS +#if defined(BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS) && !defined(BOOST_NO_AUTO_MULTIDECLARATIONS) +# define BOOST_NO_AUTO_MULTIDECLARATIONS +#endif +// Use BOOST_NO_CXX11_CHAR16_T instead of BOOST_NO_CHAR16_T +#if defined(BOOST_NO_CXX11_CHAR16_T) && !defined(BOOST_NO_CHAR16_T) +# define BOOST_NO_CHAR16_T +#endif +// Use BOOST_NO_CXX11_CHAR32_T instead of BOOST_NO_CHAR32_T +#if defined(BOOST_NO_CXX11_CHAR32_T) && !defined(BOOST_NO_CHAR32_T) +# define BOOST_NO_CHAR32_T +#endif +// Use BOOST_NO_CXX11_TEMPLATE_ALIASES instead of BOOST_NO_TEMPLATE_ALIASES +#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) && !defined(BOOST_NO_TEMPLATE_ALIASES) +# define BOOST_NO_TEMPLATE_ALIASES +#endif +// Use BOOST_NO_CXX11_CONSTEXPR instead of BOOST_NO_CONSTEXPR +#if defined(BOOST_NO_CXX11_CONSTEXPR) && !defined(BOOST_NO_CONSTEXPR) +# define BOOST_NO_CONSTEXPR +#endif +// Use BOOST_NO_CXX11_DECLTYPE_N3276 instead of BOOST_NO_DECLTYPE_N3276 +#if defined(BOOST_NO_CXX11_DECLTYPE_N3276) && !defined(BOOST_NO_DECLTYPE_N3276) +# define BOOST_NO_DECLTYPE_N3276 +#endif +// Use BOOST_NO_CXX11_DECLTYPE instead of BOOST_NO_DECLTYPE +#if defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_DECLTYPE) +# define BOOST_NO_DECLTYPE +#endif +// Use BOOST_NO_CXX11_DEFAULTED_FUNCTIONS instead of BOOST_NO_DEFAULTED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_DEFAULTED_FUNCTIONS) +# define BOOST_NO_DEFAULTED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_DELETED_FUNCTIONS instead of BOOST_NO_DELETED_FUNCTIONS +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) && !defined(BOOST_NO_DELETED_FUNCTIONS) +# define BOOST_NO_DELETED_FUNCTIONS +#endif +// Use BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS instead of BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#if defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) && !defined(BOOST_NO_EXPLICIT_CONVERSION_OPERATORS) +# define BOOST_NO_EXPLICIT_CONVERSION_OPERATORS +#endif +// Use BOOST_NO_CXX11_EXTERN_TEMPLATE instead of BOOST_NO_EXTERN_TEMPLATE +#if defined(BOOST_NO_CXX11_EXTERN_TEMPLATE) && !defined(BOOST_NO_EXTERN_TEMPLATE) +# define BOOST_NO_EXTERN_TEMPLATE +#endif +// Use BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS instead of BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#if defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) && !defined(BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) +# define BOOST_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +#endif +// Use BOOST_NO_CXX11_LAMBDAS instead of BOOST_NO_LAMBDAS +#if defined(BOOST_NO_CXX11_LAMBDAS) && !defined(BOOST_NO_LAMBDAS) +# define BOOST_NO_LAMBDAS +#endif +// Use BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS instead of BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#if defined(BOOST_NO_CXX11_LOCAL_CLASS_TEMPLATE_PARAMETERS) && !defined(BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) +# define BOOST_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +#endif +// Use BOOST_NO_CXX11_NOEXCEPT instead of BOOST_NO_NOEXCEPT +#if defined(BOOST_NO_CXX11_NOEXCEPT) && !defined(BOOST_NO_NOEXCEPT) +# define BOOST_NO_NOEXCEPT +#endif +// Use BOOST_NO_CXX11_NULLPTR instead of BOOST_NO_NULLPTR +#if defined(BOOST_NO_CXX11_NULLPTR) && !defined(BOOST_NO_NULLPTR) +# define BOOST_NO_NULLPTR +#endif +// Use BOOST_NO_CXX11_RAW_LITERALS instead of BOOST_NO_RAW_LITERALS +#if defined(BOOST_NO_CXX11_RAW_LITERALS) && !defined(BOOST_NO_RAW_LITERALS) +# define BOOST_NO_RAW_LITERALS +#endif +// Use BOOST_NO_CXX11_RVALUE_REFERENCES instead of BOOST_NO_RVALUE_REFERENCES +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_RVALUE_REFERENCES) +# define BOOST_NO_RVALUE_REFERENCES +#endif +// Use BOOST_NO_CXX11_SCOPED_ENUMS instead of BOOST_NO_SCOPED_ENUMS +#if defined(BOOST_NO_CXX11_SCOPED_ENUMS) && !defined(BOOST_NO_SCOPED_ENUMS) +# define BOOST_NO_SCOPED_ENUMS +#endif +// Use BOOST_NO_CXX11_STATIC_ASSERT instead of BOOST_NO_STATIC_ASSERT +#if defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_NO_STATIC_ASSERT) +# define BOOST_NO_STATIC_ASSERT +#endif +// Use BOOST_NO_CXX11_STD_UNORDERED instead of BOOST_NO_STD_UNORDERED +#if defined(BOOST_NO_CXX11_STD_UNORDERED) && !defined(BOOST_NO_STD_UNORDERED) +# define BOOST_NO_STD_UNORDERED +#endif +// Use BOOST_NO_CXX11_UNICODE_LITERALS instead of BOOST_NO_UNICODE_LITERALS +#if defined(BOOST_NO_CXX11_UNICODE_LITERALS) && !defined(BOOST_NO_UNICODE_LITERALS) +# define BOOST_NO_UNICODE_LITERALS +#endif +// Use BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX instead of BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX) +# define BOOST_NO_UNIFIED_INITIALIZATION_SYNTAX +#endif +// Use BOOST_NO_CXX11_VARIADIC_TEMPLATES instead of BOOST_NO_VARIADIC_TEMPLATES +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_VARIADIC_TEMPLATES) +# define BOOST_NO_VARIADIC_TEMPLATES +#endif +// Use BOOST_NO_CXX11_VARIADIC_MACROS instead of BOOST_NO_VARIADIC_MACROS +#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) && !defined(BOOST_NO_VARIADIC_MACROS) +# define BOOST_NO_VARIADIC_MACROS +#endif +// Use BOOST_NO_CXX11_NUMERIC_LIMITS instead of BOOST_NO_NUMERIC_LIMITS_LOWEST +#if defined(BOOST_NO_CXX11_NUMERIC_LIMITS) && !defined(BOOST_NO_NUMERIC_LIMITS_LOWEST) +# define BOOST_NO_NUMERIC_LIMITS_LOWEST +#endif +// ------------------ End of deprecated macros for 1.51 --------------------------- + + +// +// Helper macro for marking types and methods final +// +#if !defined(BOOST_NO_CXX11_FINAL) +# define BOOST_FINAL final +#else +# define BOOST_FINAL +#endif + +// +// Helper macros BOOST_NOEXCEPT, BOOST_NOEXCEPT_IF, BOOST_NOEXCEPT_EXPR +// These aid the transition to C++11 while still supporting C++03 compilers +// +#ifdef BOOST_NO_CXX11_NOEXCEPT +# define BOOST_NOEXCEPT +# define BOOST_NOEXCEPT_OR_NOTHROW throw() +# define BOOST_NOEXCEPT_IF(Predicate) +# define BOOST_NOEXCEPT_EXPR(Expression) false +#else +# define BOOST_NOEXCEPT noexcept +# define BOOST_NOEXCEPT_OR_NOTHROW noexcept +# define BOOST_NOEXCEPT_IF(Predicate) noexcept((Predicate)) +# define BOOST_NOEXCEPT_EXPR(Expression) noexcept((Expression)) +#endif +// +// Helper macro BOOST_FALLTHROUGH +// Fallback definition of BOOST_FALLTHROUGH macro used to mark intended +// fall-through between case labels in a switch statement. We use a definition +// that requires a semicolon after it to avoid at least one type of misuse even +// on unsupported compilers. +// +#ifndef BOOST_FALLTHROUGH +# define BOOST_FALLTHROUGH ((void)0) +#endif + +// +// constexpr workarounds +// +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_CONSTEXPR +#define BOOST_CONSTEXPR_OR_CONST const +#else +#define BOOST_CONSTEXPR constexpr +#define BOOST_CONSTEXPR_OR_CONST constexpr +#endif +#if defined(BOOST_NO_CXX14_CONSTEXPR) +#define BOOST_CXX14_CONSTEXPR +#else +#define BOOST_CXX14_CONSTEXPR constexpr +#endif + +// +// C++17 inline variables +// +#if !defined(BOOST_NO_CXX17_INLINE_VARIABLES) +#define BOOST_INLINE_VARIABLE inline +#else +#define BOOST_INLINE_VARIABLE +#endif +// +// C++17 if constexpr +// +#if !defined(BOOST_NO_CXX17_IF_CONSTEXPR) +# define BOOST_IF_CONSTEXPR if constexpr +#else +# define BOOST_IF_CONSTEXPR if +#endif + +#define BOOST_INLINE_CONSTEXPR BOOST_INLINE_VARIABLE BOOST_CONSTEXPR_OR_CONST + +// +// Unused variable/typedef workarounds: +// +#ifndef BOOST_ATTRIBUTE_UNUSED +# define BOOST_ATTRIBUTE_UNUSED +#endif +// +// [[nodiscard]]: +// +#if defined(__has_attribute) && defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x5130) +#if __has_attribute(nodiscard) +# define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] +#endif +#if __has_attribute(no_unique_address) +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif +#elif defined(__has_cpp_attribute) +// clang-6 accepts [[nodiscard]] with -std=c++14, but warns about it -pedantic +#if __has_cpp_attribute(nodiscard) && !(defined(__clang__) && (__cplusplus < 201703L)) +# define BOOST_ATTRIBUTE_NODISCARD [[nodiscard]] +#endif +#if __has_cpp_attribute(no_unique_address) && !(defined(__GNUC__) && (__cplusplus < 201100)) +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] +#endif +#endif +#ifndef BOOST_ATTRIBUTE_NODISCARD +# define BOOST_ATTRIBUTE_NODISCARD +#endif +#ifndef BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS +# define BOOST_ATTRIBUTE_NO_UNIQUE_ADDRESS +#endif + +#define BOOST_STATIC_CONSTEXPR static BOOST_CONSTEXPR_OR_CONST + +// +// Set BOOST_HAS_STATIC_ASSERT when BOOST_NO_CXX11_STATIC_ASSERT is not defined +// +#if !defined(BOOST_NO_CXX11_STATIC_ASSERT) && !defined(BOOST_HAS_STATIC_ASSERT) +# define BOOST_HAS_STATIC_ASSERT +#endif + +// +// Set BOOST_HAS_RVALUE_REFS when BOOST_NO_CXX11_RVALUE_REFERENCES is not defined +// +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_HAS_RVALUE_REFS) +#define BOOST_HAS_RVALUE_REFS +#endif + +// +// Set BOOST_HAS_VARIADIC_TMPL when BOOST_NO_CXX11_VARIADIC_TEMPLATES is not defined +// +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_HAS_VARIADIC_TMPL) +#define BOOST_HAS_VARIADIC_TMPL +#endif +// +// Set BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS when +// BOOST_NO_CXX11_VARIADIC_TEMPLATES is set: +// +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS) +# define BOOST_NO_CXX11_FIXED_LENGTH_VARIADIC_TEMPLATE_EXPANSION_PACKS +#endif + +// This is a catch all case for obsolete compilers / std libs: +#if !defined(_YVALS) && !defined(_CPPLIB_VER) // msvc std lib already configured +#if (!defined(__has_include) || (__cplusplus < 201700)) +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +#else +#if !__has_include() +# define BOOST_NO_CXX17_HDR_OPTIONAL +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_STRING_VIEW +#endif +#if !__has_include() +# define BOOST_NO_CXX17_HDR_VARIANT +#endif +#endif +#endif + +// +// Finish off with checks for macros that are depricated / no longer supported, +// if any of these are set then it's very likely that much of Boost will no +// longer work. So stop with a #error for now, but give the user a chance +// to continue at their own risk if they really want to: +// +#if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_CONFIG_ALLOW_DEPRECATED) +# error "You are using a compiler which lacks features which are now a minimum requirement in order to use Boost, define BOOST_CONFIG_ALLOW_DEPRECATED if you want to continue at your own risk!!!" +#endif + +#endif diff --git a/src/vendor/boost/config/helper_macros.hpp b/src/vendor/boost/config/helper_macros.hpp new file mode 100644 index 000000000..3e79526df --- /dev/null +++ b/src/vendor/boost/config/helper_macros.hpp @@ -0,0 +1,37 @@ +#ifndef BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED +#define BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED + +// Copyright 2001 John Maddock. +// Copyright 2017 Peter Dimov. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// BOOST_STRINGIZE(X) +// BOOST_JOIN(X, Y) +// +// Note that this header is C compatible. + +// +// Helper macro BOOST_STRINGIZE: +// Converts the parameter X to a string after macro replacement +// on X has been performed. +// +#define BOOST_STRINGIZE(X) BOOST_DO_STRINGIZE(X) +#define BOOST_DO_STRINGIZE(X) #X + +// +// Helper macro BOOST_JOIN: +// The following piece of macro magic joins the two +// arguments together, even when one of the arguments is +// itself a macro (see 16.3.1 in C++ standard). The key +// is that macro expansion of macro arguments does not +// occur in BOOST_DO_JOIN2 but does in BOOST_DO_JOIN. +// +#define BOOST_JOIN(X, Y) BOOST_DO_JOIN(X, Y) +#define BOOST_DO_JOIN(X, Y) BOOST_DO_JOIN2(X,Y) +#define BOOST_DO_JOIN2(X, Y) X##Y + +#endif // BOOST_CONFIG_HELPER_MACROS_HPP_INCLUDED diff --git a/src/vendor/boost/config/no_tr1/cmath.hpp b/src/vendor/boost/config/no_tr1/cmath.hpp new file mode 100644 index 000000000..d8268d842 --- /dev/null +++ b/src/vendor/boost/config/no_tr1/cmath.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2008. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/cmath is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_CMATH +# define BOOST_CONFIG_CMATH + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_CMATH_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_CMATH_RECURSION +# endif + +#endif diff --git a/src/vendor/boost/config/no_tr1/complex.hpp b/src/vendor/boost/config/no_tr1/complex.hpp new file mode 100644 index 000000000..ca200922b --- /dev/null +++ b/src/vendor/boost/config/no_tr1/complex.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/complex is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_COMPLEX +# define BOOST_CONFIG_COMPLEX + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_COMPLEX_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_COMPLEX_RECURSION +# endif + +#endif diff --git a/src/vendor/boost/config/no_tr1/functional.hpp b/src/vendor/boost/config/no_tr1/functional.hpp new file mode 100644 index 000000000..e395efc19 --- /dev/null +++ b/src/vendor/boost/config/no_tr1/functional.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/functional is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_FUNCTIONAL +# define BOOST_CONFIG_FUNCTIONAL + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_FUNCTIONAL_RECURSION +# endif + +#endif diff --git a/src/vendor/boost/config/no_tr1/memory.hpp b/src/vendor/boost/config/no_tr1/memory.hpp new file mode 100644 index 000000000..2b5d20802 --- /dev/null +++ b/src/vendor/boost/config/no_tr1/memory.hpp @@ -0,0 +1,28 @@ +// (C) Copyright John Maddock 2005. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// The aim of this header is just to include but to do +// so in a way that does not result in recursive inclusion of +// the Boost TR1 components if boost/tr1/tr1/memory is in the +// include search path. We have to do this to avoid circular +// dependencies: +// + +#ifndef BOOST_CONFIG_MEMORY +# define BOOST_CONFIG_MEMORY + +# ifndef BOOST_TR1_NO_RECURSION +# define BOOST_TR1_NO_RECURSION +# define BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +# include + +# ifdef BOOST_CONFIG_NO_MEMORY_RECURSION +# undef BOOST_TR1_NO_RECURSION +# undef BOOST_CONFIG_NO_MEMORY_RECURSION +# endif + +#endif diff --git a/src/vendor/boost/config/platform/linux.hpp b/src/vendor/boost/config/platform/linux.hpp new file mode 100644 index 000000000..c4eef8f80 --- /dev/null +++ b/src/vendor/boost/config/platform/linux.hpp @@ -0,0 +1,106 @@ +// (C) Copyright John Maddock 2001 - 2003. +// (C) Copyright Jens Maurer 2001 - 2003. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// linux specific config options: + +#define BOOST_PLATFORM "linux" + +// make sure we have __GLIBC_PREREQ if available at all +#ifdef __cplusplus +#include +#else +#include +#endif + +// +// added to glibc 2.1.1 +// We can only test for 2.1 though: +// +#if defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))) + // defines int64_t unconditionally, but defines + // int64_t only if __GNUC__. Thus, assume a fully usable + // only when using GCC. Update 2017: this appears not to be the case for + // recent glibc releases, see bug report: https://svn.boost.org/trac/boost/ticket/13045 +# if defined(__GNUC__) || ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 5))) +# define BOOST_HAS_STDINT_H +# endif +#endif + +#if defined(__LIBCOMO__) + // + // como on linux doesn't have std:: c functions: + // NOTE: versions of libcomo prior to beta28 have octal version numbering, + // e.g. version 25 is 21 (dec) + // +# if __LIBCOMO_VERSION__ <= 20 +# define BOOST_NO_STDC_NAMESPACE +# endif + +# if __LIBCOMO_VERSION__ <= 21 +# define BOOST_NO_SWPRINTF +# endif + +#endif + +// +// If glibc is past version 2 then we definitely have +// gettimeofday, earlier versions may or may not have it: +// +#if defined(__GLIBC__) && (__GLIBC__ >= 2) +# define BOOST_HAS_GETTIMEOFDAY +#endif + +#ifdef __USE_POSIX199309 +# define BOOST_HAS_NANOSLEEP +#endif + +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +// __GLIBC_PREREQ is available since 2.1.2 + + // swprintf is available since glibc 2.2.0 +# if !__GLIBC_PREREQ(2,2) || (!defined(__USE_ISOC99) && !defined(__USE_UNIX98)) +# define BOOST_NO_SWPRINTF +# endif +#else +# define BOOST_NO_SWPRINTF +#endif + +// boilerplate code: +#define BOOST_HAS_UNISTD_H +#include +#if defined(__USE_GNU) && !defined(__ANDROID__) && !defined(ANDROID) +#define BOOST_HAS_PTHREAD_YIELD +#endif + +#ifndef __GNUC__ +// +// if the compiler is not gcc we still need to be able to parse +// the GNU system headers, some of which (mainly ) +// use GNU specific extensions: +// +# ifndef __extension__ +# define __extension__ +# endif +# ifndef __const__ +# define __const__ const +# endif +# ifndef __volatile__ +# define __volatile__ volatile +# endif +# ifndef __signed__ +# define __signed__ signed +# endif +# ifndef __typeof__ +# define __typeof__ typeof +# endif +# ifndef __inline__ +# define __inline__ inline +# endif +#endif + + diff --git a/src/vendor/boost/config/pragma_message.hpp b/src/vendor/boost/config/pragma_message.hpp new file mode 100644 index 000000000..b2c5ff2e8 --- /dev/null +++ b/src/vendor/boost/config/pragma_message.hpp @@ -0,0 +1,31 @@ +#ifndef BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED +#define BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED + +// Copyright 2017 Peter Dimov. +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// BOOST_PRAGMA_MESSAGE("message") +// +// Expands to the equivalent of #pragma message("message") +// +// Note that this header is C compatible. + +#include + +#if defined(BOOST_DISABLE_PRAGMA_MESSAGE) +# define BOOST_PRAGMA_MESSAGE(x) +#elif defined(__INTEL_COMPILER) +# define BOOST_PRAGMA_MESSAGE(x) __pragma(message(__FILE__ "(" BOOST_STRINGIZE(__LINE__) "): note: " x)) +#elif defined(__GNUC__) +# define BOOST_PRAGMA_MESSAGE(x) _Pragma(BOOST_STRINGIZE(message(x))) +#elif defined(_MSC_VER) +# define BOOST_PRAGMA_MESSAGE(x) __pragma(message(__FILE__ "(" BOOST_STRINGIZE(__LINE__) "): note: " x)) +#else +# define BOOST_PRAGMA_MESSAGE(x) +#endif + +#endif // BOOST_CONFIG_PRAGMA_MESSAGE_HPP_INCLUDED diff --git a/src/vendor/boost/config/stdlib/libstdcpp3.hpp b/src/vendor/boost/config/stdlib/libstdcpp3.hpp new file mode 100644 index 000000000..ee8f2a20a --- /dev/null +++ b/src/vendor/boost/config/stdlib/libstdcpp3.hpp @@ -0,0 +1,359 @@ +// (C) Copyright John Maddock 2001. +// (C) Copyright Jens Maurer 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org for most recent version. + +// config for libstdc++ v3 +// not much to go in here: + +#define BOOST_GNU_STDLIB 1 + +#ifdef __GLIBCXX__ +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCXX__) +#else +#define BOOST_STDLIB "GNU libstdc++ version " BOOST_STRINGIZE(__GLIBCPP__) +#endif + +#if !defined(_GLIBCPP_USE_WCHAR_T) && !defined(_GLIBCXX_USE_WCHAR_T) +# define BOOST_NO_CWCHAR +# define BOOST_NO_CWCTYPE +# define BOOST_NO_STD_WSTRING +# define BOOST_NO_STD_WSTREAMBUF +#endif + +#if defined(__osf__) && !defined(_REENTRANT) \ + && ( defined(_GLIBCXX_HAVE_GTHR_DEFAULT) || defined(_GLIBCPP_HAVE_GTHR_DEFAULT) ) +// GCC 3 on Tru64 forces the definition of _REENTRANT when any std lib header +// file is included, therefore for consistency we define it here as well. +# define _REENTRANT +#endif + +#ifdef __GLIBCXX__ // gcc 3.4 and greater: +# if defined(_GLIBCXX_HAVE_GTHR_DEFAULT) \ + || defined(_GLIBCXX__PTHREADS) \ + || defined(_GLIBCXX_HAS_GTHREADS) \ + || defined(_WIN32) \ + || defined(_AIX) \ + || defined(__HAIKU__) + // + // If the std lib has thread support turned on, then turn it on in Boost + // as well. We do this because some gcc-3.4 std lib headers define _REENTANT + // while others do not... + // +# define BOOST_HAS_THREADS +# else +# define BOOST_DISABLE_THREADS +# endif +#elif defined(__GLIBCPP__) \ + && !defined(_GLIBCPP_HAVE_GTHR_DEFAULT) \ + && !defined(_GLIBCPP__PTHREADS) + // disable thread support if the std lib was built single threaded: +# define BOOST_DISABLE_THREADS +#endif + +#if (defined(linux) || defined(__linux) || defined(__linux__)) && defined(__arm__) && defined(_GLIBCPP_HAVE_GTHR_DEFAULT) +// linux on arm apparently doesn't define _REENTRANT +// so just turn on threading support whenever the std lib is thread safe: +# define BOOST_HAS_THREADS +#endif + +#if !defined(_GLIBCPP_USE_LONG_LONG) \ + && !defined(_GLIBCXX_USE_LONG_LONG)\ + && defined(BOOST_HAS_LONG_LONG) +// May have been set by compiler/*.hpp, but "long long" without library +// support is useless. +# undef BOOST_HAS_LONG_LONG +#endif + +// Apple doesn't seem to reliably defined a *unix* macro +#if !defined(CYGWIN) && ( defined(__unix__) \ + || defined(__unix) \ + || defined(unix) \ + || defined(__APPLE__) \ + || defined(__APPLE) \ + || defined(APPLE)) +# include +#endif + +#ifndef __VXWORKS__ // VxWorks uses Dinkum, not GNU STL with GCC +#if defined(__GLIBCXX__) || (defined(__GLIBCPP__) && __GLIBCPP__>=20020514) // GCC >= 3.1.0 +# define BOOST_STD_EXTENSION_NAMESPACE __gnu_cxx +# define BOOST_HAS_SLIST +# define BOOST_HAS_HASH +# define BOOST_SLIST_HEADER +# if !defined(__GNUC__) || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 3) +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# else +# define BOOST_HASH_SET_HEADER +# define BOOST_HASH_MAP_HEADER +# endif +#endif +#endif + +// +// Decide whether we have C++11 support turned on: +// +#if defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103) +# define BOOST_LIBSTDCXX11 +#endif + +// +// Decide which version of libstdc++ we have, normally +// libstdc++ C++0x support is detected via __GNUC__, __GNUC_MINOR__, and possibly +// __GNUC_PATCHLEVEL__ at the suggestion of Jonathan Wakely, one of the libstdc++ +// developers. He also commented: +// +// "I'm not sure how useful __GLIBCXX__ is for your purposes, for instance in +// GCC 4.2.4 it is set to 20080519 but in GCC 4.3.0 it is set to 20080305. +// Although 4.3.0 was released earlier than 4.2.4, it has better C++0x support +// than any release in the 4.2 series." +// +// Another resource for understanding libstdc++ features is: +// http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#manual.intro.status.standard.200x +// +// However, using the GCC version number fails when the compiler is clang since this +// only ever claims to emulate GCC-4.2, see https://svn.boost.org/trac/boost/ticket/7473 +// for a long discussion on this issue. What we can do though is use clang's __has_include +// to detect the presence of a C++11 header that was introduced with a specific GCC release. +// We still have to be careful though as many such headers were buggy and/or incomplete when +// first introduced, so we only check for headers that were fully featured from day 1, and then +// use that to infer the underlying GCC version: +// +#ifdef __clang__ + +#if __has_include() +# define BOOST_LIBSTDCXX_VERSION 100100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 90100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 80100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 70100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 60100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 50100 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40900 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40800 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40700 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40600 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40500 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40400 +#elif __has_include() +# define BOOST_LIBSTDCXX_VERSION 40300 +#endif + +#if (BOOST_LIBSTDCXX_VERSION < 50100) +// libstdc++ does not define this function as it's deprecated in C++11, but clang still looks for it, +// defining it here is a terrible cludge, but should get things working: +extern "C" char *gets (char *__s); +#endif +// +// clang is unable to parse some GCC headers, add those workarounds here: +// +#if BOOST_LIBSTDCXX_VERSION < 50000 +# define BOOST_NO_CXX11_HDR_REGEX +#endif +// +// GCC 4.7.x has no __cxa_thread_atexit which +// thread_local objects require for cleanup: +// +#if BOOST_LIBSTDCXX_VERSION < 40800 +# define BOOST_NO_CXX11_THREAD_LOCAL +#endif +// +// Early clang versions can handle , not exactly sure which versions +// but certainly up to clang-3.8 and gcc-4.6: +// +#if (__clang_major__ < 5) +# if BOOST_LIBSTDCXX_VERSION < 40800 +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CHRONO +# endif +#endif + +// +// GCC 4.8 and 9 add working versions of and respectively. +// However, we have no test for these as the headers were present but broken +// in early GCC versions. +// +#endif + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC >= 0x5130) && (__cplusplus >= 201103L) +// +// Oracle Solaris compiler uses it's own verison of libstdc++ but doesn't +// set __GNUC__ +// +#if __SUNPRO_CC >= 0x5140 +#define BOOST_LIBSTDCXX_VERSION 50100 +#else +#define BOOST_LIBSTDCXX_VERSION 40800 +#endif +#endif + +#if !defined(BOOST_LIBSTDCXX_VERSION) +# define BOOST_LIBSTDCXX_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +// std::auto_ptr isn't provided with _GLIBCXX_DEPRECATED=0 (GCC 4.5 and earlier) +// or _GLIBCXX_USE_DEPRECATED=0 (GCC 4.6 and later). +#if defined(BOOST_LIBSTDCXX11) +# if BOOST_LIBSTDCXX_VERSION < 40600 +# if !_GLIBCXX_DEPRECATED +# define BOOST_NO_AUTO_PTR +# endif +# elif !_GLIBCXX_USE_DEPRECATED +# define BOOST_NO_AUTO_PTR +# endif +#endif + +// C++0x headers in GCC 4.3.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40300) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_ARRAY +# define BOOST_NO_CXX11_HDR_TUPLE +# define BOOST_NO_CXX11_HDR_UNORDERED_MAP +# define BOOST_NO_CXX11_HDR_UNORDERED_SET +# define BOOST_NO_CXX11_HDR_FUNCTIONAL +#endif + +// C++0x headers in GCC 4.4.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40400) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_FORWARD_LIST +# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST +# define BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_RATIO +# define BOOST_NO_CXX11_HDR_SYSTEM_ERROR +# define BOOST_NO_CXX11_SMART_PTR +# define BOOST_NO_CXX11_HDR_EXCEPTION +#else +# define BOOST_HAS_TR1_COMPLEX_INVERSE_TRIG +# define BOOST_HAS_TR1_COMPLEX_OVERLOADS +#endif + +// C++0x features in GCC 4.5.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40500) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_NUMERIC_LIMITS +# define BOOST_NO_CXX11_HDR_FUTURE +# define BOOST_NO_CXX11_HDR_RANDOM +#endif + +// C++0x features in GCC 4.6.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40600) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPEINDEX +# define BOOST_NO_CXX11_ADDRESSOF +# define BOOST_NO_CXX17_ITERATOR_TRAITS +#endif + +// C++0x features in GCC 4.7.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40700) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to 4.7, "steady_clock" is spelled "monotonic_clock" +// so 4.7.0 is the first truly conforming one. +# define BOOST_NO_CXX11_HDR_CHRONO +# define BOOST_NO_CXX11_ALLOCATOR +# define BOOST_NO_CXX11_POINTER_TRAITS +#endif +// C++0x features in GCC 4.8.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40800) || !defined(BOOST_LIBSTDCXX11) +// Note that although existed prior to gcc 4.8 it was largely unimplemented for many types: +# define BOOST_NO_CXX11_HDR_ATOMIC +# define BOOST_NO_CXX11_HDR_THREAD +#endif +// C++0x features in GCC 4.9.0 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +// Although is present and compilable against, the actual implementation is not functional +// even for the simplest patterns such as "\d" or "[0-9]". This is the case at least in gcc up to 4.8, inclusively. +# define BOOST_NO_CXX11_HDR_REGEX +#endif +#if (BOOST_LIBSTDCXX_VERSION < 40900) || (__cplusplus <= 201103) +# define BOOST_NO_CXX14_STD_EXCHANGE +#endif + +#if defined(__clang_major__) && ((__clang_major__ < 3) || ((__clang_major__ == 3) && (__clang_minor__ < 7))) +// As of clang-3.6, libstdc++ header throws up errors with clang: +# define BOOST_NO_CXX11_HDR_ATOMIC +#endif +// +// C++0x features in GCC 5.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 50100) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX11_HDR_TYPE_TRAITS +# define BOOST_NO_CXX11_HDR_CODECVT +# define BOOST_NO_CXX11_ATOMIC_SMART_PTR +# define BOOST_NO_CXX11_STD_ALIGN +#endif + +// +// C++17 features in GCC 7.1 and later +// +#if (BOOST_LIBSTDCXX_VERSION < 70100) || (__cplusplus <= 201402L) +# define BOOST_NO_CXX17_STD_INVOKE +# define BOOST_NO_CXX17_STD_APPLY +# define BOOST_NO_CXX17_HDR_OPTIONAL +# define BOOST_NO_CXX17_HDR_STRING_VIEW +# define BOOST_NO_CXX17_HDR_VARIANT +#endif + +#if defined(__has_include) +#if !__has_include() +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#elif __cplusplus <= 201103 +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif +#elif __cplusplus < 201402 || (BOOST_LIBSTDCXX_VERSION < 40900) || !defined(BOOST_LIBSTDCXX11) +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +#endif + +// +// Headers not present on Solaris with the Oracle compiler: +#if defined(__SUNPRO_CC) && (__SUNPRO_CC < 0x5140) +#define BOOST_NO_CXX11_HDR_FUTURE +#define BOOST_NO_CXX11_HDR_FORWARD_LIST +#define BOOST_NO_CXX11_HDR_ATOMIC +// shared_ptr is present, but is not convertible to bool +// which causes all kinds of problems especially in Boost.Thread +// but probably elsewhere as well. +#define BOOST_NO_CXX11_SMART_PTR +#endif + +#if (!defined(_GLIBCXX_HAS_GTHREADS) || !defined(_GLIBCXX_USE_C99_STDINT_TR1)) + // Headers not always available: +# ifndef BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# define BOOST_NO_CXX11_HDR_CONDITION_VARIABLE +# endif +# ifndef BOOST_NO_CXX11_HDR_MUTEX +# define BOOST_NO_CXX11_HDR_MUTEX +# endif +# ifndef BOOST_NO_CXX11_HDR_THREAD +# define BOOST_NO_CXX11_HDR_THREAD +# endif +# ifndef BOOST_NO_CXX14_HDR_SHARED_MUTEX +# define BOOST_NO_CXX14_HDR_SHARED_MUTEX +# endif +#endif + +#if (!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK) || (_GTHREAD_USE_MUTEX_TIMEDLOCK == 0)) && !defined(BOOST_NO_CXX11_HDR_MUTEX) +// Timed mutexes are not always available: +# define BOOST_NO_CXX11_HDR_MUTEX +#endif + +// --- end --- diff --git a/src/vendor/boost/config/user.hpp b/src/vendor/boost/config/user.hpp new file mode 100644 index 000000000..8160fcae2 --- /dev/null +++ b/src/vendor/boost/config/user.hpp @@ -0,0 +1,133 @@ +// boost/config/user.hpp ---------------------------------------------------// + +// (C) Copyright John Maddock 2001. +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Do not check in modified versions of this file, +// This file may be customized by the end user, but not by boost. + +// +// Use this file to define a site and compiler specific +// configuration policy: +// + +// define this to locate a compiler config file: +// #define BOOST_COMPILER_CONFIG + +// define this to locate a stdlib config file: +// #define BOOST_STDLIB_CONFIG + +// define this to locate a platform config file: +// #define BOOST_PLATFORM_CONFIG + +// define this to disable compiler config, +// use if your compiler config has nothing to set: +// #define BOOST_NO_COMPILER_CONFIG + +// define this to disable stdlib config, +// use if your stdlib config has nothing to set: +// #define BOOST_NO_STDLIB_CONFIG + +// define this to disable platform config, +// use if your platform config has nothing to set: +// #define BOOST_NO_PLATFORM_CONFIG + +// define this to disable all config options, +// excluding the user config. Use if your +// setup is fully ISO compliant, and has no +// useful extensions, or for autoconf generated +// setups: +// #define BOOST_NO_CONFIG + +// define this to make the config "optimistic" +// about unknown compiler versions. Normally +// unknown compiler versions are assumed to have +// all the defects of the last known version, however +// setting this flag, causes the config to assume +// that unknown compiler versions are fully conformant +// with the standard: +// #define BOOST_STRICT_CONFIG + +// define this to cause the config to halt compilation +// with an #error if it encounters anything unknown -- +// either an unknown compiler version or an unknown +// compiler/platform/library: +// #define BOOST_ASSERT_CONFIG + + +// define if you want to disable threading support, even +// when available: +// #define BOOST_DISABLE_THREADS + +// define when you want to disable Win32 specific features +// even when available: +// #define BOOST_DISABLE_WIN32 + +// BOOST_DISABLE_ABI_HEADERS: Stops boost headers from including any +// prefix/suffix headers that normally control things like struct +// packing and alignment. +// #define BOOST_DISABLE_ABI_HEADERS + +// BOOST_ABI_PREFIX: A prefix header to include in place of whatever +// boost.config would normally select, any replacement should set up +// struct packing and alignment options as required. +// #define BOOST_ABI_PREFIX my-header-name + +// BOOST_ABI_SUFFIX: A suffix header to include in place of whatever +// boost.config would normally select, any replacement should undo +// the effects of the prefix header. +// #define BOOST_ABI_SUFFIX my-header-name + +// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, +// to be linked as dll's rather than static libraries on Microsoft Windows +// (this macro is used to turn on __declspec(dllimport) modifiers, so that +// the compiler knows which symbols to look for in a dll rather than in a +// static library). Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), in these cases this +// macro has no effect. +// #define BOOST_ALL_DYN_LINK + +// BOOST_WHATEVER_DYN_LINK: Forces library "whatever" to be linked as a dll +// rather than a static library on Microsoft Windows: replace the WHATEVER +// part of the macro name with the name of the library that you want to +// dynamically link to, for example use BOOST_DATE_TIME_DYN_LINK or +// BOOST_REGEX_DYN_LINK etc (this macro is used to turn on __declspec(dllimport) +// modifiers, so that the compiler knows which symbols to look for in a dll +// rather than in a static library). +// Note that there may be some libraries that can only +// be linked in one way (statically or dynamically), +// in these cases this macro is unsupported. +// #define BOOST_WHATEVER_DYN_LINK + +// BOOST_ALL_NO_LIB: Tells the config system not to automatically select +// which libraries to link against. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, +// simply by the act of including one of that library's headers. +// This macro turns that feature off. +// #define BOOST_ALL_NO_LIB + +// BOOST_WHATEVER_NO_LIB: Tells the config system not to automatically +// select which library to link against for library "whatever", +// replace WHATEVER in the macro name with the name of the library; +// for example BOOST_DATE_TIME_NO_LIB or BOOST_REGEX_NO_LIB. +// Normally if a compiler supports #pragma lib, then the correct library +// build variant will be automatically selected and linked against, simply +// by the act of including one of that library's headers. This macro turns +// that feature off. +// #define BOOST_WHATEVER_NO_LIB + +// BOOST_LIB_BUILDID: Set to the same value as the value passed to Boost.Build's +// --buildid command line option. For example if you built using: +// +// bjam address-model=64 --buildid=amd64 +// +// then compile your code with: +// +// -DBOOST_LIB_BUILDID = amd64 +// +// to ensure the correct libraries are selected at link time. +// #define BOOST_LIB_BUILDID amd64 + diff --git a/src/vendor/boost/config/workaround.hpp b/src/vendor/boost/config/workaround.hpp new file mode 100644 index 000000000..7c6a2e62f --- /dev/null +++ b/src/vendor/boost/config/workaround.hpp @@ -0,0 +1,294 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef BOOST_CONFIG_WORKAROUND_HPP +#define BOOST_CONFIG_WORKAROUND_HPP + +// Compiler/library version workaround macro +// +// Usage: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, < 1300) +// // workaround for eVC4 and VC6 +// ... // workaround code here +// #endif +// +// When BOOST_STRICT_CONFIG is defined, expands to 0. Otherwise, the +// first argument must be undefined or expand to a numeric +// value. The above expands to: +// +// (BOOST_MSVC) != 0 && (BOOST_MSVC) < 1300 +// +// When used for workarounds that apply to the latest known version +// and all earlier versions of a compiler, the following convention +// should be observed: +// +// #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1301)) +// +// The version number in this case corresponds to the last version in +// which the workaround was known to have been required. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is not the defined, the macro +// BOOST_TESTED_AT(x) expands to "!= 0", which effectively activates +// the workaround for any version of the compiler. When +// BOOST_DETECT_OUTDATED_WORKAROUNDS is defined, a compiler warning or +// error will be issued if the compiler version exceeds the argument +// to BOOST_TESTED_AT(). This can be used to locate workarounds which +// may be obsoleted by newer versions. + +#ifndef BOOST_STRICT_CONFIG + +#include + +#ifndef __BORLANDC__ +#define __BORLANDC___WORKAROUND_GUARD 1 +#else +#define __BORLANDC___WORKAROUND_GUARD 0 +#endif +#ifndef __CODEGEARC__ +#define __CODEGEARC___WORKAROUND_GUARD 1 +#else +#define __CODEGEARC___WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_BORLANDC +#define BOOST_BORLANDC_WORKAROUND_GUARD 1 +#else +#define BOOST_BORLANDC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_CODEGEARC +#define BOOST_CODEGEARC_WORKAROUND_GUARD 1 +#else +#define BOOST_CODEGEARC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_EMBTC +#define BOOST_EMBTC_WORKAROUND_GUARD 1 +#else +#define BOOST_EMBTC_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_VER +#define _MSC_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_VER_WORKAROUND_GUARD 0 +#endif +#ifndef _MSC_FULL_VER +#define _MSC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define _MSC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC +#define BOOST_MSVC_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_MSVC_FULL_VER +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_MSVC_FULL_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC__ +#define __GNUC___WORKAROUND_GUARD 1 +#else +#define __GNUC___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_MINOR__ +#define __GNUC_MINOR___WORKAROUND_GUARD 1 +#else +#define __GNUC_MINOR___WORKAROUND_GUARD 0 +#endif +#ifndef __GNUC_PATCHLEVEL__ +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 1 +#else +#define __GNUC_PATCHLEVEL___WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_GCC +#define BOOST_GCC_WORKAROUND_GUARD 1 +#define BOOST_GCC_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_GCC_WORKAROUND_GUARD 0 +#define BOOST_GCC_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_XLCPP_ZOS +#define BOOST_XLCPP_ZOS_WORKAROUND_GUARD 1 +#else +#define BOOST_XLCPP_ZOS_WORKAROUND_GUARD 0 +#endif +#ifndef __IBMCPP__ +#define __IBMCPP___WORKAROUND_GUARD 1 +#else +#define __IBMCPP___WORKAROUND_GUARD 0 +#endif +#ifndef __SUNPRO_CC +#define __SUNPRO_CC_WORKAROUND_GUARD 1 +#else +#define __SUNPRO_CC_WORKAROUND_GUARD 0 +#endif +#ifndef __DECCXX_VER +#define __DECCXX_VER_WORKAROUND_GUARD 1 +#else +#define __DECCXX_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __MWERKS__ +#define __MWERKS___WORKAROUND_GUARD 1 +#else +#define __MWERKS___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG__ +#define __EDG___WORKAROUND_GUARD 1 +#else +#define __EDG___WORKAROUND_GUARD 0 +#endif +#ifndef __EDG_VERSION__ +#define __EDG_VERSION___WORKAROUND_GUARD 1 +#else +#define __EDG_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __HP_aCC +#define __HP_aCC_WORKAROUND_GUARD 1 +#else +#define __HP_aCC_WORKAROUND_GUARD 0 +#endif +#ifndef __hpxstd98 +#define __hpxstd98_WORKAROUND_GUARD 1 +#else +#define __hpxstd98_WORKAROUND_GUARD 0 +#endif +#ifndef _CRAYC +#define _CRAYC_WORKAROUND_GUARD 1 +#else +#define _CRAYC_WORKAROUND_GUARD 0 +#endif +#ifndef __DMC__ +#define __DMC___WORKAROUND_GUARD 1 +#else +#define __DMC___WORKAROUND_GUARD 0 +#endif +#ifndef MPW_CPLUS +#define MPW_CPLUS_WORKAROUND_GUARD 1 +#else +#define MPW_CPLUS_WORKAROUND_GUARD 0 +#endif +#ifndef __COMO__ +#define __COMO___WORKAROUND_GUARD 1 +#else +#define __COMO___WORKAROUND_GUARD 0 +#endif +#ifndef __COMO_VERSION__ +#define __COMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __COMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef __INTEL_COMPILER +#define __INTEL_COMPILER_WORKAROUND_GUARD 1 +#else +#define __INTEL_COMPILER_WORKAROUND_GUARD 0 +#endif +#ifndef __ICL +#define __ICL_WORKAROUND_GUARD 1 +#else +#define __ICL_WORKAROUND_GUARD 0 +#endif +#ifndef _COMPILER_VERSION +#define _COMPILER_VERSION_WORKAROUND_GUARD 1 +#else +#define _COMPILER_VERSION_WORKAROUND_GUARD 0 +#endif + +#ifndef _RWSTD_VER +#define _RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define _RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_RWSTD_VER +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 1 +#else +#define BOOST_RWSTD_VER_WORKAROUND_GUARD 0 +#endif +#ifndef __GLIBCPP__ +#define __GLIBCPP___WORKAROUND_GUARD 1 +#else +#define __GLIBCPP___WORKAROUND_GUARD 0 +#endif +#ifndef _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 1 +#else +#define _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC_WORKAROUND_GUARD 0 +#endif +#ifndef __SGI_STL_PORT +#define __SGI_STL_PORT_WORKAROUND_GUARD 1 +#else +#define __SGI_STL_PORT_WORKAROUND_GUARD 0 +#endif +#ifndef _STLPORT_VERSION +#define _STLPORT_VERSION_WORKAROUND_GUARD 1 +#else +#define _STLPORT_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef __LIBCOMO_VERSION__ +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 1 +#else +#define __LIBCOMO_VERSION___WORKAROUND_GUARD 0 +#endif +#ifndef _CPPLIB_VER +#define _CPPLIB_VER_WORKAROUND_GUARD 1 +#else +#define _CPPLIB_VER_WORKAROUND_GUARD 0 +#endif + +#ifndef BOOST_INTEL_CXX_VERSION +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_CXX_VERSION_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL_WIN +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WIN_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_DINKUMWARE_STDLIB +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 1 +#else +#define BOOST_DINKUMWARE_STDLIB_WORKAROUND_GUARD 0 +#endif +#ifndef BOOST_INTEL +#define BOOST_INTEL_WORKAROUND_GUARD 1 +#else +#define BOOST_INTEL_WORKAROUND_GUARD 0 +#endif +// Always define to zero, if it's used it'll be defined my MPL: +#define BOOST_MPL_CFG_GCC_WORKAROUND_GUARD 0 + +#define BOOST_WORKAROUND(symbol, test) \ + ((symbol ## _WORKAROUND_GUARD + 0 == 0) && \ + (symbol != 0) && (1 % (( (symbol test) ) + 1))) +// ^ ^ ^ ^ +// The extra level of parenthesis nesting above, along with the +// BOOST_OPEN_PAREN indirection below, is required to satisfy the +// broken preprocessor in MWCW 8.3 and earlier. +// +// The basic mechanism works as follows: +// (symbol test) + 1 => if (symbol test) then 2 else 1 +// 1 % ((symbol test) + 1) => if (symbol test) then 1 else 0 +// +// The complication with % is for cooperation with BOOST_TESTED_AT(). +// When "test" is BOOST_TESTED_AT(x) and +// BOOST_DETECT_OUTDATED_WORKAROUNDS is #defined, +// +// symbol test => if (symbol <= x) then 1 else -1 +// (symbol test) + 1 => if (symbol <= x) then 2 else 0 +// 1 % ((symbol test) + 1) => if (symbol <= x) then 1 else divide-by-zero +// + +#ifdef BOOST_DETECT_OUTDATED_WORKAROUNDS +# define BOOST_OPEN_PAREN ( +# define BOOST_TESTED_AT(value) > value) ?(-1): BOOST_OPEN_PAREN 1 +#else +# define BOOST_TESTED_AT(value) != ((value)-(value)) +#endif + +#else + +#define BOOST_WORKAROUND(symbol, test) 0 + +#endif + +#endif // BOOST_CONFIG_WORKAROUND_HPP diff --git a/src/vendor/boost/container/allocator_traits.hpp b/src/vendor/boost/container/allocator_traits.hpp new file mode 100644 index 000000000..72d90d1b4 --- /dev/null +++ b/src/vendor/boost/container/allocator_traits.hpp @@ -0,0 +1,493 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Pablo Halpern 2009. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2011-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP +#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +#include +#include //is_empty +#include +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP +#include +#endif +// intrusive +#include +#include +// move +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +// other boost +#include + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME allocate +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 2 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 2 +#include + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME destroy +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 1 +#include + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME construct +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG namespace boost { namespace container { namespace dtl { +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END }}} +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN 1 +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX 9 +#include + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +template +class small_vector_allocator; + +namespace allocator_traits_detail { + +BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_max_size, max_size) +BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(has_select_on_container_copy_construction, select_on_container_copy_construction) + +} //namespace allocator_traits_detail { + +namespace dtl { + +//workaround needed for C++03 compilers with no construct() +//supporting rvalue references +template +struct is_std_allocator +{ static const bool value = false; }; + +template +struct is_std_allocator< std::allocator > +{ static const bool value = true; }; + +template +struct is_std_allocator< small_vector_allocator, Options > > +{ static const bool value = true; }; + +template +struct is_not_std_allocator +{ static const bool value = !is_std_allocator::value; }; + +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_pointer) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(reference) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(const_reference) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(void_pointer) +BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(const_void_pointer) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(size_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_copy_assignment) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_move_assignment) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(propagate_on_container_swap) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_always_equal) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(difference_type) +BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(is_partially_propagable) + +} //namespace dtl { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! The class template allocator_traits supplies a uniform interface to all allocator types. +//! This class is a C++03-compatible implementation of std::allocator_traits +template +struct allocator_traits +{ + //allocator_type + typedef Allocator allocator_type; + //value_type + typedef typename allocator_type::value_type value_type; + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Allocator::pointer if such a type exists; otherwise, value_type* + //! + typedef unspecified pointer; + //! Allocator::const_pointer if such a type exists ; otherwise, pointer_traits::rebind::rebind. + //! + typedef see_documentation void_pointer; + //! Allocator::const_void_pointer if such a type exists ; otherwise, pointer_traits::rebind::difference_type. + //! + typedef see_documentation difference_type; + //! Allocator::size_type if such a type exists ; otherwise, make_unsigned::type + //! + typedef see_documentation size_type; + //! Allocator::propagate_on_container_copy_assignment if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. + typedef see_documentation propagate_on_container_copy_assignment; + //! Allocator::propagate_on_container_move_assignment if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. + typedef see_documentation propagate_on_container_move_assignment; + //! Allocator::propagate_on_container_swap if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false. + typedef see_documentation propagate_on_container_swap; + //! Allocator::is_always_equal if such a type exists, otherwise a type + //! with an internal constant static boolean member value == is_empty::value + typedef see_documentation is_always_equal; + //! Allocator::is_partially_propagable if such a type exists, otherwise a type + //! with an internal constant static boolean member value == false + //! Note: Non-standard extension used to implement `small_vector_allocator`. + typedef see_documentation is_partially_propagable; + //! Defines an allocator: Allocator::rebind::other if such a type exists; otherwise, Allocator + //! if Allocator is a class template instantiation of the form Allocator, where Args is zero or + //! more type arguments ; otherwise, the instantiation of rebind_alloc is ill-formed. + //! + //! In C++03 compilers rebind_alloc is a struct derived from an allocator + //! deduced by previously detailed rules. + template using rebind_alloc = see_documentation; + + //! In C++03 compilers rebind_traits is a struct derived from + //! allocator_traits, where OtherAlloc is + //! the allocator deduced by rules explained in rebind_alloc. + template using rebind_traits = allocator_traits >; + + //! Non-standard extension: Portable allocator rebind for C++03 and C++11 compilers. + //! type is an allocator related to Allocator deduced deduced by rules explained in rebind_alloc. + template + struct portable_rebind_alloc + { typedef see_documentation type; }; + #else + //pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + pointer, value_type*) + pointer; + //const_pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, + const_pointer, typename boost::intrusive::pointer_traits::template + rebind_pointer) + const_pointer; + //reference + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + reference, typename dtl::unvoid_ref::type) + reference; + //const_reference + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + const_reference, typename dtl::unvoid_ref::type) + const_reference; + //void_pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, + void_pointer, typename boost::intrusive::pointer_traits::template + rebind_pointer) + void_pointer; + //const_void_pointer + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(boost::container::dtl::, Allocator, + const_void_pointer, typename boost::intrusive::pointer_traits::template + rebind_pointer) + const_void_pointer; + //difference_type + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + difference_type, std::ptrdiff_t) + difference_type; + //size_type + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + size_type, std::size_t) + size_type; + //propagate_on_container_copy_assignment + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + propagate_on_container_copy_assignment, dtl::false_type) + propagate_on_container_copy_assignment; + //propagate_on_container_move_assignment + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + propagate_on_container_move_assignment, dtl::false_type) + propagate_on_container_move_assignment; + //propagate_on_container_swap + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + propagate_on_container_swap, dtl::false_type) + propagate_on_container_swap; + //is_always_equal + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + is_always_equal, dtl::is_empty) + is_always_equal; + //is_partially_propagable + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(boost::container::dtl::, Allocator, + is_partially_propagable, dtl::false_type) + is_partially_propagable; + + //rebind_alloc & rebind_traits + #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + //C++11 + template using rebind_alloc = typename boost::intrusive::pointer_rebind::type; + template using rebind_traits = allocator_traits< rebind_alloc >; + #else // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + //Some workaround for C++03 or C++11 compilers with no template aliases + template + struct rebind_alloc : boost::intrusive::pointer_rebind::type + { + typedef typename boost::intrusive::pointer_rebind::type Base; + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + rebind_alloc(BOOST_FWD_REF(Args)... args) : Base(boost::forward(args)...) {} + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N\ + explicit rebind_alloc(BOOST_MOVE_UREF##N) : Base(BOOST_MOVE_FWD##N){}\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_REBIND_ALLOC + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + }; + + template + struct rebind_traits + : allocator_traits::type> + {}; + #endif // #if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + + //portable_rebind_alloc + template + struct portable_rebind_alloc + { typedef typename boost::intrusive::pointer_rebind::type type; }; + #endif //BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Returns: a.allocate(n) + //! + BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n) + { return a.allocate(n); } + + //! Returns: a.deallocate(p, n) + //! + //! Throws: Nothing + BOOST_CONTAINER_FORCEINLINE static void deallocate(Allocator &a, pointer p, size_type n) + { a.deallocate(p, n); } + + //! Effects: calls a.allocate(n, p) if that call is well-formed; + //! otherwise, invokes a.allocate(n) + BOOST_CONTAINER_FORCEINLINE static pointer allocate(Allocator &a, size_type n, const_void_pointer p) + { + const bool value = boost::container::dtl:: + has_member_function_callable_with_allocate + ::value; + dtl::bool_ flag; + return allocator_traits::priv_allocate(flag, a, n, p); + } + + //! Effects: calls a.destroy(p) if that call is well-formed; + //! otherwise, invokes p->~T(). + template + BOOST_CONTAINER_FORCEINLINE static void destroy(Allocator &a, T*p) BOOST_NOEXCEPT_OR_NOTHROW + { + typedef T* destroy_pointer; + const bool value = boost::container::dtl:: + has_member_function_callable_with_destroy + ::value; + dtl::bool_ flag; + allocator_traits::priv_destroy(flag, a, p); + } + + //! Returns: a.max_size() if that expression is well-formed; otherwise, + //! numeric_limits::max(). + BOOST_CONTAINER_FORCEINLINE static size_type max_size(const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW + { + const bool value = allocator_traits_detail::has_max_size::value; + dtl::bool_ flag; + return allocator_traits::priv_max_size(flag, a); + } + + //! Returns: a.select_on_container_copy_construction() if that expression is well-formed; + //! otherwise, a. + BOOST_CONTAINER_FORCEINLINE static BOOST_CONTAINER_DOC1ST(Allocator, + typename dtl::if_c + < allocator_traits_detail::has_select_on_container_copy_construction::value + BOOST_MOVE_I Allocator BOOST_MOVE_I const Allocator & >::type) + select_on_container_copy_construction(const Allocator &a) + { + const bool value = allocator_traits_detail::has_select_on_container_copy_construction + ::value; + dtl::bool_ flag; + return allocator_traits::priv_select_on_container_copy_construction(flag, a); + } + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: calls a.construct(p, std::forward(args)...) if that call is well-formed; + //! otherwise, invokes `placement new` (static_cast(p)) T(std::forward(args)...) + template + BOOST_CONTAINER_FORCEINLINE static void construct(Allocator & a, T* p, BOOST_FWD_REF(Args)... args) + { + static const bool value = ::boost::move_detail::and_ + < dtl::is_not_std_allocator + , boost::container::dtl::has_member_function_callable_with_construct + < Allocator, T*, Args... > + >::value; + dtl::bool_ flag; + allocator_traits::priv_construct(flag, a, p, ::boost::forward(args)...); + } + #endif + + //! Returns: a.storage_is_unpropagable(p) if is_partially_propagable::value is true; otherwise, + //! false. + BOOST_CONTAINER_FORCEINLINE static bool storage_is_unpropagable(const Allocator &a, pointer p) BOOST_NOEXCEPT_OR_NOTHROW + { + dtl::bool_ flag; + return allocator_traits::priv_storage_is_unpropagable(flag, a, p); + } + + //! Returns: true if is_always_equal::value == true, otherwise, + //! a == b. + BOOST_CONTAINER_FORCEINLINE static bool equal(const Allocator &a, const Allocator &b) BOOST_NOEXCEPT_OR_NOTHROW + { + dtl::bool_ flag; + return allocator_traits::priv_equal(flag, a, b); + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + private: + BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::true_type, Allocator &a, size_type n, const_void_pointer p) + { return a.allocate(n, p); } + + BOOST_CONTAINER_FORCEINLINE static pointer priv_allocate(dtl::false_type, Allocator &a, size_type n, const_void_pointer) + { return a.allocate(n); } + + template + BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::true_type, Allocator &a, T* p) BOOST_NOEXCEPT_OR_NOTHROW + { a.destroy(p); } + + template + BOOST_CONTAINER_FORCEINLINE static void priv_destroy(dtl::false_type, Allocator &, T* p) BOOST_NOEXCEPT_OR_NOTHROW + { p->~T(); (void)p; } + + BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::true_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW + { return a.max_size(); } + + BOOST_CONTAINER_FORCEINLINE static size_type priv_max_size(dtl::false_type, const Allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return size_type(-1)/sizeof(value_type); } + + BOOST_CONTAINER_FORCEINLINE static Allocator priv_select_on_container_copy_construction(dtl::true_type, const Allocator &a) + { return a.select_on_container_copy_construction(); } + + BOOST_CONTAINER_FORCEINLINE static const Allocator &priv_select_on_container_copy_construction(dtl::false_type, const Allocator &a) BOOST_NOEXCEPT_OR_NOTHROW + { return a; } + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + template + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p, BOOST_FWD_REF(Args) ...args) + { a.construct( p, ::boost::forward(args)...); } + + template + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, BOOST_FWD_REF(Args) ...args) + { ::new((void*)p, boost_container_new_t()) T(::boost::forward(args)...); } + #else // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + public: + + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL(N) \ + template\ + BOOST_CONTAINER_FORCEINLINE static void construct(Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + static const bool value = ::boost::move_detail::and_ \ + < dtl::is_not_std_allocator \ + , boost::container::dtl::has_member_function_callable_with_construct \ + < Allocator, T* BOOST_MOVE_I##N BOOST_MOVE_FWD_T##N > \ + >::value; \ + dtl::bool_ flag;\ + (priv_construct)(flag, a, p BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + }\ + // + BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_CONSTRUCT_IMPL + + private: + ///////////////////////////////// + // priv_construct + ///////////////////////////////// + #define BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL(N) \ + template\ + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::true_type, Allocator &a, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { a.construct( p BOOST_MOVE_I##N BOOST_MOVE_FWD##N ); }\ + \ + template\ + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + { ::new((void*)p, boost_container_new_t()) T(BOOST_MOVE_FWD##N); }\ + // + BOOST_MOVE_ITERATE_0TO8(BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL) + #undef BOOST_CONTAINER_ALLOCATOR_TRAITS_PRIV_CONSTRUCT_IMPL + + #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + template + BOOST_CONTAINER_FORCEINLINE static void priv_construct(dtl::false_type, Allocator &, T *p, const ::boost::container::default_init_t&) + { ::new((void*)p, boost_container_new_t()) T; } + + BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::true_type, const Allocator &a, pointer p) + { return a.storage_is_unpropagable(p); } + + BOOST_CONTAINER_FORCEINLINE static bool priv_storage_is_unpropagable(dtl::false_type, const Allocator &, pointer) + { return false; } + + BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::true_type, const Allocator &, const Allocator &) + { return true; } + + BOOST_CONTAINER_FORCEINLINE static bool priv_equal(dtl::false_type, const Allocator &a, const Allocator &b) + { return a == b; } + + #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) +}; + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct real_allocator +{ + typedef AllocatorOrVoid type; +}; + +template +struct real_allocator +{ + typedef new_allocator type; +}; + +#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +} //namespace container { +} //namespace boost { + +#include + +#endif // ! defined(BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP) diff --git a/src/vendor/boost/container/container_fwd.hpp b/src/vendor/boost/container/container_fwd.hpp new file mode 100644 index 000000000..7855257e5 --- /dev/null +++ b/src/vendor/boost/container/container_fwd.hpp @@ -0,0 +1,390 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP +#define BOOST_CONTAINER_CONTAINER_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//! \file +//! This header file forward declares the following containers: +//! - boost::container::vector +//! - boost::container::stable_vector +//! - boost::container::static_vector +//! - boost::container::small_vector_base +//! - boost::container::small_vector +//! - boost::container::devector +//! - boost::container::slist +//! - boost::container::list +//! - boost::container::set +//! - boost::container::multiset +//! - boost::container::map +//! - boost::container::multimap +//! - boost::container::flat_set +//! - boost::container::flat_multiset +//! - boost::container::flat_map +//! - boost::container::flat_multimap +//! - boost::container::basic_string +//! - boost::container::string +//! - boost::container::wstring +//! +//! Forward declares the following allocators: +//! - boost::container::allocator +//! - boost::container::node_allocator +//! - boost::container::adaptive_pool +//! +//! Forward declares the following polymorphic resource classes: +//! - boost::container::pmr::memory_resource +//! - boost::container::pmr::polymorphic_allocator +//! - boost::container::pmr::monotonic_buffer_resource +//! - boost::container::pmr::pool_options +//! - boost::container::pmr::unsynchronized_pool_resource +//! - boost::container::pmr::synchronized_pool_resource +//! +//! And finally it defines the following types + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//Std forward declarations +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP + #include +#endif + +namespace boost{ +namespace intrusive{ +namespace detail{ + //Create namespace to avoid compilation errors +}}} + +namespace boost{ namespace container{ namespace dtl{ + namespace bi = boost::intrusive; + namespace bid = boost::intrusive::detail; +}}} + +namespace boost{ namespace container{ namespace pmr{ + namespace bi = boost::intrusive; + namespace bid = boost::intrusive::detail; +}}} + +#include + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +////////////////////////////////////////////////////////////////////////////// +// Containers +////////////////////////////////////////////////////////////////////////////// + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +template +struct pair; + +template +class new_allocator; + +template +class vector; + +template +class stable_vector; + +template < class T + , std::size_t Capacity + , class Options = void> +class static_vector; + +template < class T + , class Allocator = void + , class Options = void > +class small_vector_base; + +template < class T + , std::size_t N + , class Allocator = void + , class Options = void > +class small_vector; + +template +class devector; + +template +class deque; + +template +class list; + +template +class slist; + +template + ,class Allocator = void + ,class Options = void> +class set; + +template + ,class Allocator = void + ,class Options = void > +class multiset; + +template + ,class Allocator = void + ,class Options = void > +class map; + +template + ,class Allocator = void + ,class Options = void > +class multimap; + +template + ,class Allocator = void > +class flat_set; + +template + ,class Allocator = void > +class flat_multiset; + +template + ,class Allocator = void > +class flat_map; + +template + ,class Allocator = void > +class flat_multimap; + +#ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES + +//! Alias templates for small_flat_[multi]{set|map} using small_vector as container + +template < class Key + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_set = flat_set>; + +template < class Key + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_multiset = flat_multiset>; + +template < class Key + , class T + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_map = flat_map, N, SmallVectorAllocator, SmallVectorOptions>>; + +template < class Key + , class T + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +using small_flat_multimap = flat_multimap, N, SmallVectorAllocator, SmallVectorOptions>>; + +#endif // #ifndef BOOST_NO_CXX11_TEMPLATE_ALIASES + + +//! A portable metafunction to obtain a small_flat_set +template < class Key + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_set_of +{ + typedef flat_set > type; +}; + +//! A portable metafunction to obtain a small_flat_multiset +template < class Key + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_multiset_of +{ + typedef flat_multiset > type; +}; + +//! A portable metafunction to obtain a small_flat_map +template < class Key + , class T + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_map_of +{ + typedef flat_map, N, SmallVectorAllocator, SmallVectorOptions> > type; +}; + +//! A portable metafunction to obtain a small_flat_multimap +template < class Key + , class T + , std::size_t N + , class Compare = std::less + , class SmallVectorAllocator = void + , class SmallVectorOptions = void > +struct small_flat_multimap_of +{ + typedef flat_multimap, N, SmallVectorAllocator, SmallVectorOptions> > type; +}; + +template + ,class Allocator = void > +class basic_string; + +typedef basic_string string; +typedef basic_string wstring; + +static const std::size_t ADP_nodes_per_block = 256u; +static const std::size_t ADP_max_free_blocks = 2u; +static const std::size_t ADP_overhead_percent = 1u; +static const std::size_t ADP_only_alignment = 0u; + +template < class T + , std::size_t NodesPerBlock = ADP_nodes_per_block + , std::size_t MaxFreeBlocks = ADP_max_free_blocks + , std::size_t OverheadPercent = ADP_overhead_percent + , unsigned Version = 2 + > +class adaptive_pool; + +template < class T + , unsigned Version = 2 + , unsigned int AllocationDisableMask = 0> +class allocator; + +static const std::size_t NodeAlloc_nodes_per_block = 256u; + +template + < class T + , std::size_t NodesPerBlock = NodeAlloc_nodes_per_block + , std::size_t Version = 2> +class node_allocator; + +namespace pmr { + +class memory_resource; + +template +class polymorphic_allocator; + +class monotonic_buffer_resource; + +struct pool_options; + +template +class resource_adaptor_imp; + +class unsynchronized_pool_resource; + +class synchronized_pool_resource; + +} //namespace pmr { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! Type used to tag that the input range is +//! guaranteed to be ordered +struct ordered_range_t +{}; + +//! Value used to tag that the input range is +//! guaranteed to be ordered +static const ordered_range_t ordered_range = ordered_range_t(); + +//! Type used to tag that the input range is +//! guaranteed to be ordered and unique +struct ordered_unique_range_t + : public ordered_range_t +{}; + +//! Value used to tag that the input range is +//! guaranteed to be ordered and unique +static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); + +//! Type used to tag that the inserted values +//! should be default initialized +struct default_init_t +{}; + +//! Value used to tag that the inserted values +//! should be default initialized +static const default_init_t default_init = default_init_t(); +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! Type used to tag that the inserted values +//! should be value initialized +struct value_init_t +{}; + +//! Value used to tag that the inserted values +//! should be value initialized +static const value_init_t value_init = value_init_t(); + +namespace container_detail_really_deep_namespace { + +//Otherwise, gcc issues a warning of previously defined +//anonymous_instance and unique_instance +struct dummy +{ + dummy() + { + (void)ordered_range; + (void)ordered_unique_range; + (void)default_init; + } +}; + +} //detail_really_deep_namespace { + + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +}} //namespace boost { namespace container { + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP diff --git a/src/vendor/boost/container/detail/addressof.hpp b/src/vendor/boost/container/detail/addressof.hpp new file mode 100644 index 000000000..b3b8a4dd6 --- /dev/null +++ b/src/vendor/boost/container/detail/addressof.hpp @@ -0,0 +1,41 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP +#define BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace container { +namespace dtl { + +template +BOOST_CONTAINER_FORCEINLINE T* addressof(T& obj) +{ + return static_cast( + static_cast( + const_cast( + &reinterpret_cast(obj) + ))); +} + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ADDRESSOF_HPP diff --git a/src/vendor/boost/container/detail/advanced_insert_int.hpp b/src/vendor/boost/container/detail/advanced_insert_int.hpp new file mode 100644 index 000000000..585b8ce0e --- /dev/null +++ b/src/vendor/boost/container/detail/advanced_insert_int.hpp @@ -0,0 +1,567 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP +#define BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +// container/detail +#include +#include +#include +#include +#include +#include +#include +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +// move +#include +// other +#include +#include + +namespace boost { namespace container { namespace dtl { + +template +struct move_insert_range_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE explicit move_insert_range_proxy(FwdIt first) + : first_(first) + {} + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_move_alloc_n_source + (a, this->first_, n, p); + } + + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) + { + this->first_ = ::boost::container::move_n_source(this->first_, n, p); + } + + FwdIt first_; +}; + + +template +struct insert_range_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE explicit insert_range_proxy(FwdIt first) + : first_(first) + {} + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + { + this->first_ = ::boost::container::uninitialized_copy_alloc_n_source(a, this->first_, n, p); + } + + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) + { + this->first_ = ::boost::container::copy_n_source(this->first_, n, p); + } + + FwdIt first_; +}; + + +template +struct insert_n_copies_proxy +{ + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE explicit insert_n_copies_proxy(const value_type &v) + : v_(v) + {} + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { boost::container::uninitialized_fill_alloc_n(a, v_, n, p); } + + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const + { + while (n){ + --n; + *p = v_; + ++p; + } + } + + const value_type &v_; +}; + +template +struct insert_value_initialized_n_proxy +{ + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + typedef typename dtl::aligned_storage::value>::type storage_t; + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { boost::container::uninitialized_value_init_alloc_n(a, n, p); } + + void copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { + while (n){ + --n; + storage_t v; + value_type *vp = reinterpret_cast(v.data); + alloc_traits::construct(a, vp); + value_destructor on_exit(a, *vp); (void)on_exit; + *p = ::boost::move(*vp); + ++p; + } + } +}; + +template +struct insert_default_initialized_n_proxy +{ + typedef ::boost::container::allocator_traits alloc_traits; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::value_type value_type; + typedef typename dtl::aligned_storage::value>::type storage_t; + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { boost::container::uninitialized_default_init_alloc_n(a, n, p); } + + void copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { + if(!is_pod::value){ + while (n){ + --n; + typename dtl::aligned_storage::value>::type v; + value_type *vp = reinterpret_cast(v.data); + alloc_traits::construct(a, vp, default_init); + value_destructor on_exit(a, *vp); (void)on_exit; + *p = ::boost::move(*vp); + ++p; + } + } + } +}; + +template +struct insert_copy_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_copy_proxy(const value_type &v) + : v_(v) + {} + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), v_); + } + + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + *p = v_; + } + + const value_type &v_; +}; + + +template +struct insert_move_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_move_proxy(value_type &v) + : v_(v) + {} + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::move(v_) ); + } + + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator p, size_type n) const + { + BOOST_ASSERT(n == 1); (void)n; + *p = ::boost::move(v_); + } + + value_type &v_; +}; + +template +BOOST_CONTAINER_FORCEINLINE insert_move_proxy get_insert_value_proxy(BOOST_RV_REF(typename boost::container::iterator_traits::value_type) v) +{ + return insert_move_proxy(v); +} + +template +BOOST_CONTAINER_FORCEINLINE insert_copy_proxy get_insert_value_proxy(const typename boost::container::iterator_traits::value_type &v) +{ + return insert_copy_proxy(v); +} + +}}} //namespace boost { namespace container { namespace dtl { + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +template +struct insert_nonmovable_emplace_proxy +{ + typedef boost::container::allocator_traits alloc_traits; + typedef typename alloc_traits::size_type size_type; + typedef typename alloc_traits::value_type value_type; + typedef typename build_number_seq::type index_tuple_t; + + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy(BOOST_FWD_REF(Args)... args) + : args_(args...) + {} + + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n) + { this->priv_uninitialized_copy_some_and_update(a, index_tuple_t(), p, n); } + + private: + template + BOOST_CONTAINER_FORCEINLINE void priv_uninitialized_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) + { + BOOST_ASSERT(n == 1); (void)n; + alloc_traits::construct( a, boost::movelib::iterator_to_raw_pointer(p), ::boost::forward(get(this->args_))... ); + } + + protected: + tuple args_; +}; + +template +struct insert_emplace_proxy + : public insert_nonmovable_emplace_proxy +{ + typedef insert_nonmovable_emplace_proxy base_t; + typedef boost::container::allocator_traits alloc_traits; + typedef typename base_t::value_type value_type; + typedef typename base_t::size_type size_type; + typedef typename base_t::index_tuple_t index_tuple_t; + + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(BOOST_FWD_REF(Args)... args) + : base_t(::boost::forward(args)...) + {} + + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n) + { this->priv_copy_some_and_update(a, index_tuple_t(), p, n); } + + private: + + template + BOOST_CONTAINER_FORCEINLINE void priv_copy_some_and_update(Allocator &a, const index_tuple&, Iterator p, size_type n) + { + BOOST_ASSERT(n ==1); (void)n; + typename dtl::aligned_storage::value>::type v; + value_type *vp = reinterpret_cast(v.data); + alloc_traits::construct(a, vp, ::boost::forward(get(this->args_))...); + BOOST_TRY{ + *p = ::boost::move(*vp); + } + BOOST_CATCH(...){ + alloc_traits::destroy(a, vp); + BOOST_RETHROW + } + BOOST_CATCH_END + alloc_traits::destroy(a, vp); + } +}; + +//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type +template +struct insert_emplace_proxy::value_type> + : public insert_move_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(typename boost::container::allocator_traits::value_type &&v) + : insert_move_proxy(v) + {} +}; + +//We use "add_const" here as adding "const" only confuses MSVC12(and maybe later) provoking +//compiler error C2752 ("more than one partial specialization matches"). +//Any problem is solvable with an extra layer of indirection? ;-) +template +struct insert_emplace_proxy::value_type>::type + > + : public insert_copy_proxy +{ + + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy::value_type &> + : public insert_copy_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy::value_type>::type & + > + : public insert_copy_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +}}} //namespace boost { namespace container { namespace dtl { + +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include + +namespace boost { +namespace container { +namespace dtl { + +#define BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE(N) \ +template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +struct insert_nonmovable_emplace_proxy##N\ +{\ + typedef boost::container::allocator_traits alloc_traits;\ + typedef typename alloc_traits::size_type size_type;\ + typedef typename alloc_traits::value_type value_type;\ + \ + static const bool single_value = true;\ + \ + BOOST_CONTAINER_FORCEINLINE explicit insert_nonmovable_emplace_proxy##N(BOOST_MOVE_UREF##N)\ + BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N {}\ + \ + BOOST_CONTAINER_FORCEINLINE void uninitialized_copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + {\ + BOOST_ASSERT(n == 1); (void)n;\ + alloc_traits::construct(a, boost::movelib::iterator_to_raw_pointer(p) BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + }\ + \ + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &, Iterator, size_type)\ + { BOOST_ASSERT(false); }\ + \ + protected:\ + BOOST_MOVE_MREF##N\ +};\ +\ +template< class Allocator, class Iterator BOOST_MOVE_I##N BOOST_MOVE_CLASS##N >\ +struct insert_emplace_proxy_arg##N\ + : insert_nonmovable_emplace_proxy##N< Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N >\ +{\ + typedef insert_nonmovable_emplace_proxy##N\ + < Allocator, Iterator BOOST_MOVE_I##N BOOST_MOVE_TARG##N > base_t;\ + typedef typename base_t::value_type value_type;\ + typedef typename base_t::size_type size_type;\ + typedef boost::container::allocator_traits alloc_traits;\ + \ + static const bool single_value = true;\ + \ + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg##N(BOOST_MOVE_UREF##N)\ + : base_t(BOOST_MOVE_FWD##N){}\ + \ + BOOST_CONTAINER_FORCEINLINE void copy_n_and_update(Allocator &a, Iterator p, size_type n)\ + {\ + BOOST_ASSERT(n == 1); (void)n;\ + typename dtl::aligned_storage::value>::type v;\ + value_type *vp = reinterpret_cast(v.data);\ + alloc_traits::construct(a, vp BOOST_MOVE_I##N BOOST_MOVE_MFWD##N);\ + BOOST_TRY{\ + *p = ::boost::move(*vp);\ + }\ + BOOST_CATCH(...){\ + alloc_traits::destroy(a, vp);\ + BOOST_RETHROW\ + }\ + BOOST_CATCH_END\ + alloc_traits::destroy(a, vp);\ + }\ +};\ +// +BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE) +#undef BOOST_CONTAINER_ADVANCED_INSERT_INT_CODE + +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type +template +struct insert_emplace_proxy_arg1::value_type> > + : public insert_move_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &v) + : insert_move_proxy(v) + {} +}; + +template +struct insert_emplace_proxy_arg1::value_type> + : public insert_copy_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +#else //e.g. MSVC10 & MSVC11 + +//Specializations to avoid an unneeded temporary when emplacing from a single argument o type value_type +template +struct insert_emplace_proxy_arg1::value_type> + : public insert_move_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(typename boost::container::allocator_traits::value_type &&v) + : insert_move_proxy(v) + {} +}; + +//We use "add_const" here as adding "const" only confuses MSVC10&11 provoking +//compiler error C2752 ("more than one partial specialization matches"). +//Any problem is solvable with an extra layer of indirection? ;-) +template +struct insert_emplace_proxy_arg1::value_type>::type + > + : public insert_copy_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy_arg1::value_type &> + : public insert_copy_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +template +struct insert_emplace_proxy_arg1::value_type>::type & + > + : public insert_copy_proxy +{ + static const bool single_value = true; + + BOOST_CONTAINER_FORCEINLINE explicit insert_emplace_proxy_arg1(const typename boost::container::allocator_traits::value_type &v) + : insert_copy_proxy(v) + {} +}; + +#endif + +}}} //namespace boost { namespace container { namespace dtl { + +#endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +namespace boost { namespace container { namespace dtl { + +template +struct has_single_value +{ + private: + struct two {char array_[2];}; + template struct wrapper; + template static two test(int, ...); + template static char test(int, const wrapper*); + public: + static const bool value = sizeof(test(0, 0)) == 1; + void dummy(){} +}; + +template::value> +struct is_single_value_proxy_impl +{ + static const bool value = InsertionProxy::single_value; +}; + +template +struct is_single_value_proxy_impl +{ + static const bool value = false; +}; + +template +struct is_single_value_proxy + : is_single_value_proxy_impl +{}; + +}}} //namespace boost { namespace container { namespace dtl { + +#include + +#endif //#ifndef BOOST_CONTAINER_ADVANCED_INSERT_INT_HPP diff --git a/src/vendor/boost/container/detail/algorithm.hpp b/src/vendor/boost/container/detail/algorithm.hpp new file mode 100644 index 000000000..11844220e --- /dev/null +++ b/src/vendor/boost/container/detail/algorithm.hpp @@ -0,0 +1,157 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP +#define BOOST_CONTAINER_DETAIL_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace container { + +using boost::intrusive::algo_equal; +using boost::intrusive::algo_lexicographical_compare; + +template +class binder1st +{ + public: + typedef typename Func::second_argument_type argument_type; + typedef typename Func::result_type result_type; + + binder1st(const Func& func, const typename Func::first_argument_type& arg) + : op(func), value(arg) + {} + + result_type operator()(const argument_type& arg) const + { return op(value, arg); } + + result_type operator()(argument_type& arg) const + { return op(value, arg); } + + private: + Func op; + typename Func::first_argument_type value; +}; + +template +inline binder1st bind1st(const Func& func, const T& arg) +{ return boost::container::binder1st(func, arg); } + +template +class binder2nd +{ + public: + typedef typename Func::first_argument_type argument_type; + typedef typename Func::result_type result_type; + + binder2nd(const Func& func, const typename Func::second_argument_type& arg) + : op(func), value(arg) + {} + + result_type operator()(const argument_type& arg) const + { return op(arg, value); } + + result_type operator()(argument_type& arg) const + { return op(arg, value); } + + private: + Func op; + typename Func::second_argument_type value; +}; + +template +inline binder2nd bind2nd(const Func& func, const T& arg) +{ + return (boost::container::binder2nd(func, arg)); +} + +template +class unary_negate +{ + public: + typedef typename Func::argument_type argument_type; + typedef typename Func::result_type result_type; + + explicit unary_negate(const Func& func) + : m_func(func) + {} + + bool operator()(const typename Func::argument_type& arg) const + { return !m_func(arg); } + + private: + Func m_func; +}; + +template inline +unary_negate not1(const Func& func) +{ + return boost::container::unary_negate(func); +} + +template +InputIt find_if(InputIt first, InputIt last, UnaryPredicate p) +{ + for (; first != last; ++first) { + if (p(*first)) { + return first; + } + } + return last; +} + +template +InputIt find_first_of(InputIt first1, InputIt last1, ForwardIt first2, ForwardIt last2, BinaryPredicate p) +{ + for (; first1 != last1; ++first1) { + for (ForwardIt it = first2; it != last2; ++it) { + if (p(*first1, *it)) { + return first1; + } + } + } + return last1; +} + +template +ForwardIt1 search(ForwardIt1 first1, ForwardIt1 last1, + ForwardIt2 first2, ForwardIt2 last2, BinaryPredicate p) +{ + for (; ; ++first1) { + ForwardIt1 it = first1; + for (ForwardIt2 it2 = first2; ; ++it, ++it2) { + if (it2 == last2) { + return first1; + } + if (it == last1) { + return last1; + } + if (!p(*it, *it2)) { + break; + } + } + } +} + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ALGORITHM_HPP diff --git a/src/vendor/boost/container/detail/alloc_helpers.hpp b/src/vendor/boost/container/detail/alloc_helpers.hpp new file mode 100644 index 000000000..5ca2ca727 --- /dev/null +++ b/src/vendor/boost/container/detail/alloc_helpers.hpp @@ -0,0 +1,60 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP +#define BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// move +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +template +BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &, AllocatorType &, dtl::false_type) + BOOST_NOEXCEPT_OR_NOTHROW +{} + +template +BOOST_CONTAINER_FORCEINLINE void swap_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) +{ boost::adl_move_swap(l, r); } + +template +BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &, const AllocatorType &, dtl::false_type) + BOOST_NOEXCEPT_OR_NOTHROW +{} + +template +BOOST_CONTAINER_FORCEINLINE void assign_alloc(AllocatorType &l, const AllocatorType &r, dtl::true_type) +{ l = r; } + +template +BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &, AllocatorType &, dtl::false_type) + BOOST_NOEXCEPT_OR_NOTHROW +{} + +template +BOOST_CONTAINER_FORCEINLINE void move_alloc(AllocatorType &l, AllocatorType &r, dtl::true_type) +{ l = ::boost::move(r); } + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ALLOC_TRAITS_HPP diff --git a/src/vendor/boost/container/detail/allocation_type.hpp b/src/vendor/boost/container/detail/allocation_type.hpp new file mode 100644 index 000000000..1e8aa6731 --- /dev/null +++ b/src/vendor/boost/container/detail/allocation_type.hpp @@ -0,0 +1,58 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP +#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +enum allocation_type_v +{ + // constants for allocation commands + allocate_new_v = 0x01, + expand_fwd_v = 0x02, + expand_bwd_v = 0x04, +// expand_both = expand_fwd | expand_bwd, +// expand_or_new = allocate_new | expand_both, + shrink_in_place_v = 0x08, + nothrow_allocation_v = 0x10, + zero_memory_v = 0x20, + try_shrink_in_place_v = 0x40 +}; + +typedef unsigned int allocation_type; +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +static const allocation_type allocate_new = (allocation_type)allocate_new_v; +static const allocation_type expand_fwd = (allocation_type)expand_fwd_v; +static const allocation_type expand_bwd = (allocation_type)expand_bwd_v; +static const allocation_type shrink_in_place = (allocation_type)shrink_in_place_v; +static const allocation_type try_shrink_in_place= (allocation_type)try_shrink_in_place_v; +static const allocation_type nothrow_allocation = (allocation_type)nothrow_allocation_v; +static const allocation_type zero_memory = (allocation_type)zero_memory_v; + +} //namespace container { +} //namespace boost { + +#include + +#endif //BOOST_CONTAINER_ALLOCATION_TYPE_HPP diff --git a/src/vendor/boost/container/detail/allocator_version_traits.hpp b/src/vendor/boost/container/detail/allocator_version_traits.hpp new file mode 100644 index 000000000..d037e0e39 --- /dev/null +++ b/src/vendor/boost/container/detail/allocator_version_traits.hpp @@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP +#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include //allocator_traits +#include +#include //multiallocation_chain +#include //version_type +#include //allocation_type +#include //integral_constant +#include //pointer_traits +#include //BOOST_TRY + +namespace boost { +namespace container { +namespace dtl { + +template::value> +struct allocator_version_traits +{ + typedef ::boost::container::dtl::integral_constant + alloc_version; + + typedef typename Allocator::multiallocation_chain multiallocation_chain; + + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::size_type size_type; + + //Node allocation interface + static pointer allocate_one(Allocator &a) + { return a.allocate_one(); } + + static void deallocate_one(Allocator &a, const pointer &p) + { a.deallocate_one(p); } + + static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) + { return a.allocate_individual(n, m); } + + static void deallocate_individual(Allocator &a, multiallocation_chain &holder) + { a.deallocate_individual(holder); } + + static pointer allocation_command(Allocator &a, allocation_type command, + size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) + { return a.allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); } +}; + +template +struct allocator_version_traits +{ + typedef ::boost::container::dtl::integral_constant + alloc_version; + + typedef typename boost::container::allocator_traits::pointer pointer; + typedef typename boost::container::allocator_traits::size_type size_type; + typedef typename boost::container::allocator_traits::value_type value_type; + + typedef typename boost::intrusive::pointer_traits:: + template rebind_pointer::type void_ptr; + typedef dtl::basic_multiallocation_chain + multialloc_cached_counted; + typedef boost::container::dtl:: + transform_multiallocation_chain + < multialloc_cached_counted, value_type> multiallocation_chain; + + //Node allocation interface + static pointer allocate_one(Allocator &a) + { return a.allocate(1); } + + static void deallocate_one(Allocator &a, const pointer &p) + { a.deallocate(p, 1); } + + static void deallocate_individual(Allocator &a, multiallocation_chain &holder) + { + size_type n = holder.size(); + typename multiallocation_chain::iterator it = holder.begin(); + while(n){ + --n; + pointer p = boost::intrusive::pointer_traits::pointer_to(*it); + ++it; + a.deallocate(p, 1); + } + } + + struct allocate_individual_rollback + { + allocate_individual_rollback(Allocator &a, multiallocation_chain &chain) + : mr_a(a), mp_chain(&chain) + {} + + ~allocate_individual_rollback() + { + if(mp_chain) + allocator_version_traits::deallocate_individual(mr_a, *mp_chain); + } + + void release() + { + mp_chain = 0; + } + + Allocator &mr_a; + multiallocation_chain * mp_chain; + }; + + static void allocate_individual(Allocator &a, size_type n, multiallocation_chain &m) + { + allocate_individual_rollback rollback(a, m); + while(n--){ + m.push_front(a.allocate(1)); + } + rollback.release(); + } + + static pointer allocation_command(Allocator &a, allocation_type command, + size_type, size_type &prefer_in_recvd_out_size, pointer &reuse) + { + pointer ret = pointer(); + if(BOOST_UNLIKELY(!(command & allocate_new) && !(command & nothrow_allocation))){ + throw_logic_error("version 1 allocator without allocate_new flag"); + } + else{ + BOOST_TRY{ + ret = a.allocate(prefer_in_recvd_out_size); + } + BOOST_CATCH(...){ + if(!(command & nothrow_allocation)){ + BOOST_RETHROW + } + } + BOOST_CATCH_END + reuse = pointer(); + } + return ret; + } +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif // ! defined(BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP) diff --git a/src/vendor/boost/container/detail/config_begin.hpp b/src/vendor/boost/container/detail/config_begin.hpp new file mode 100644 index 000000000..172e685c7 --- /dev/null +++ b/src/vendor/boost/container/detail/config_begin.hpp @@ -0,0 +1,50 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED +#define BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#endif //BOOST_CONTAINER_CONTAINER_DETAIL_CONFIG_INCLUDED + +#ifdef BOOST_MSVC + #pragma warning (push) + #pragma warning (disable : 4127) // conditional expression is constant + #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning (disable : 4197) // top-level volatile in cast is ignored + #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" + #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) + #pragma warning (disable : 4324) // structure was padded due to __declspec(align( + #pragma warning (disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized + #pragma warning (disable : 4355) // "this" : used in base member initializer list + #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated + #pragma warning (disable : 4510) // default constructor could not be generated + #pragma warning (disable : 4511) // copy constructor could not be generated + #pragma warning (disable : 4512) // assignment operator could not be generated + #pragma warning (disable : 4514) // unreferenced inline removed + #pragma warning (disable : 4521) // Disable "multiple copy constructors specified" + #pragma warning (disable : 4522) // "class" : multiple assignment operators specified + #pragma warning (disable : 4541) // 'typeid' used on polymorphic type '' with /GR-; unpredictable behavior may result + #pragma warning (disable : 4584) // X is already a base-class of Y + #pragma warning (disable : 4610) // struct can never be instantiated - user defined constructor required + #pragma warning (disable : 4671) // the copy constructor is inaccessible + #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site + #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter + #pragma warning (disable : 4706) // assignment within conditional expression + #pragma warning (disable : 4710) // function not inlined + #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined + #pragma warning (disable : 4711) // function selected for automatic inline expansion + #pragma warning (disable : 4786) // identifier truncated in debug info + #pragma warning (disable : 4996) // "function": was declared deprecated + +#endif //BOOST_MSVC diff --git a/src/vendor/boost/container/detail/config_end.hpp b/src/vendor/boost/container/detail/config_end.hpp new file mode 100644 index 000000000..f93c8f6f7 --- /dev/null +++ b/src/vendor/boost/container/detail/config_end.hpp @@ -0,0 +1,13 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#if defined BOOST_MSVC + #pragma warning (pop) +#endif + diff --git a/src/vendor/boost/container/detail/construct_in_place.hpp b/src/vendor/boost/container/detail/construct_in_place.hpp new file mode 100644 index 000000000..b131f06a8 --- /dev/null +++ b/src/vendor/boost/container/detail/construct_in_place.hpp @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP +#define BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace container { + +//In place construction + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* dest, InpIt source) +{ boost::container::allocator_traits::construct(a, dest, *source); } + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, value_init_construct_iterator) +{ + boost::container::allocator_traits::construct(a, dest); +} + +template +class default_init_construct_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, default_init_construct_iterator) +{ + boost::container::allocator_traits::construct(a, dest, default_init); +} + +template +class emplace_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T *dest, emplace_iterator ei) +{ + ei.construct_in_place(a, dest); +} + +//Assignment + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, InpIt source) +{ *dest = *source; } + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, value_init_construct_iterator) +{ + dtl::value_init val; + *dest = boost::move(val.get()); +} + +template +class default_init_construct_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, default_init_construct_iterator) +{ + U u; + *dest = boost::move(u); +} + +template +class emplace_iterator; + +template +BOOST_CONTAINER_FORCEINLINE void assign_in_place(DstIt dest, emplace_iterator ei) +{ + ei.assign_in_place(dest); +} + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_CONSTRUCT_IN_PLACE_HPP diff --git a/src/vendor/boost/container/detail/copy_move_algo.hpp b/src/vendor/boost/container/detail/copy_move_algo.hpp new file mode 100644 index 000000000..3479e1676 --- /dev/null +++ b/src/vendor/boost/container/detail/copy_move_algo.hpp @@ -0,0 +1,1278 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP +#define BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// container +#include +// container/detail +#include +#include +#include +#include +#include +#include + +// move +#include +#include +#include +// other +#include +// std +#include //for memmove/memcpy + +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +#pragma GCC diagnostic push +//pair memcpy optimizations rightfully detected by GCC +# if defined(BOOST_GCC) && (BOOST_GCC >= 80000) +//# pragma GCC diagnostic ignored "-Wclass-memaccess" +# endif +//GCC 8 seems a bit confused about array access error with static_vector +//when out of bound exceptions are being thrown. +# if defined(BOOST_GCC) && (BOOST_GCC >= 80000) && (BOOST_GCC < 80200) +//# pragma GCC diagnostic ignored "-Wstringop-overflow" +# endif +//# pragma GCC diagnostic ignored "-Warray-bounds" +#endif + +namespace boost { +namespace container { +namespace dtl { + +template +struct are_elements_contiguous +{ + static const bool value = false; +}; + +///////////////////////// +// raw pointers +///////////////////////// + +template +struct are_elements_contiguous +{ + static const bool value = true; +}; + +///////////////////////// +// move iterators +///////////////////////// + +template +struct are_elements_contiguous< ::boost::move_iterator > + : are_elements_contiguous +{}; + +} //namespace dtl { + +///////////////////////// +// predeclarations +///////////////////////// + +template +class vec_iterator; + +} //namespace container { + +namespace interprocess { + +template +class offset_ptr; + +} //namespace interprocess { + +namespace container { + +namespace dtl { + +///////////////////////// +//vector_[const_]iterator +///////////////////////// + +template +struct are_elements_contiguous > +{ + static const bool value = true; +}; + +///////////////////////// +// offset_ptr +///////////////////////// + +template +struct are_elements_contiguous< ::boost::interprocess::offset_ptr > +{ + static const bool value = true; +}; + +template +struct are_contiguous_and_same + : boost::move_detail::and_ + < are_elements_contiguous + , are_elements_contiguous + , is_same< typename remove_const< typename ::boost::container::iterator_traits::value_type >::type + , typename ::boost::container::iterator_traits::value_type + > + > +{}; + +template +struct is_memtransfer_copy_assignable + : boost::move_detail::and_ + < are_contiguous_and_same + , dtl::is_trivially_copy_assignable< typename ::boost::container::iterator_traits::value_type > + > +{}; + +template +struct is_memtransfer_copy_constructible + : boost::move_detail::and_ + < are_contiguous_and_same + , dtl::is_trivially_copy_constructible< typename ::boost::container::iterator_traits::value_type > + > +{}; + +template +struct enable_if_memtransfer_copy_constructible + : enable_if, R> +{}; + +template +struct disable_if_memtransfer_copy_constructible + : disable_if, R> +{}; + +template +struct enable_if_memtransfer_copy_assignable + : enable_if, R> +{}; + +template +struct disable_if_memtransfer_copy_assignable + : disable_if, R> +{}; + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE F memmove(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + value_type *const dest_raw = boost::movelib::iterator_to_raw_pointer(r); + const value_type *const beg_raw = boost::movelib::iterator_to_raw_pointer(f); + const value_type *const end_raw = boost::movelib::iterator_to_raw_pointer(l); + if(BOOST_LIKELY(beg_raw != end_raw && dest_raw && beg_raw)){ + const typename boost::container::iterator_traits::difference_type n = end_raw - beg_raw; + std::memmove(dest_raw, beg_raw, sizeof(value_type)*n); + r += n; + } + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE F memmove_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + if(BOOST_LIKELY(n)){ + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + r += n; + } + + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE I memmove_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + if(BOOST_LIKELY(n)){ + typedef typename boost::container::iterator_traits::value_type value_type; + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + f += n; + } + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE I memmove_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + if(BOOST_LIKELY(n)){ + std::memmove(boost::movelib::iterator_to_raw_pointer(r), boost::movelib::iterator_to_raw_pointer(f), sizeof(value_type)*n); + f += n; + r += n; + } + return f; +} + +template +struct is_memzero_initializable +{ + typedef typename ::boost::container::iterator_traits::value_type value_type; + static const bool value = are_elements_contiguous::value && + ( dtl::is_integral::value || dtl::is_enum::value + #if defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) + || dtl::is_pointer::value + #endif + #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) + || dtl::is_floating_point::value + #endif + #if defined(BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO) && defined(BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL) + || dtl::is_pod::value + #endif + ); +}; + +template +struct enable_if_memzero_initializable + : enable_if_c::value, R> +{}; + +template +struct disable_if_memzero_initializable + : enable_if_c::value, R> +{}; + +template +struct enable_if_trivially_destructible + : enable_if_c < dtl::is_trivially_destructible + ::value_type>::value + , R> +{}; + +template +struct disable_if_trivially_destructible + : enable_if_c ::value_type>::value + , R> +{}; + +} //namespace dtl { + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move_alloc +// +////////////////////////////////////////////////////////////////////////////// + + +//! Effects: +//! \code +//! for (; f != l; ++r, ++f) +//! allocator_traits::construct(a, &*r, boost::move(*f)); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc(Allocator &a, I f, I l, F r) +{ + F back = r; + BOOST_TRY{ + while (f != l) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, boost::move(*f)); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + --n; + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_move_alloc_n_source +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, boost::move(*f)); +//! \endcode +//! +//! Returns: f (after incremented) +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + --n; + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), boost::move(*f)); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_move_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_alloc +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; f != l; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc(Allocator &a, I f, I l, F r) +{ + F back = r; + BOOST_TRY{ + while (f != l) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc(Allocator &, I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + --n; + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), *f); + ++f; ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_copy_alloc_n_source +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: f (after incremented) +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n_source(Allocator &a, I f, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + boost::container::construct_in_place(a, boost::movelib::iterator_to_raw_pointer(r), f); + ++f; ++r; --n; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_constructible::type + uninitialized_copy_alloc_n_source(Allocator &, I f, typename boost::container::allocator_traits::size_type n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_value_init_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline typename dtl::disable_if_memzero_initializable::type + uninitialized_value_init_alloc_n(Allocator &a, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + --n; + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r)); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memzero_initializable::type + uninitialized_value_init_alloc_n(Allocator &, typename boost::container::allocator_traits::size_type n, F r) +{ + typedef typename boost::container::iterator_traits::value_type value_type; + if (BOOST_LIKELY(n)){ + std::memset((void*)boost::movelib::iterator_to_raw_pointer(r), 0, sizeof(value_type)*n); + r += n; + } + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_default_init_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline F uninitialized_default_init_alloc_n(Allocator &a, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + --n; + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), default_init); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_fill_alloc +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; f != l; ++r, ++f) +//! allocator_traits::construct(a, &*r, *f); +//! \endcode +//! +//! Returns: r +template + +inline void uninitialized_fill_alloc(Allocator &a, F f, F l, const T &t) +{ + F back = f; + BOOST_TRY{ + while (f != l) { + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(f), t); + ++f; + } + } + BOOST_CATCH(...){ + for (; back != l; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END +} + + +////////////////////////////////////////////////////////////////////////////// +// +// uninitialized_fill_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +//! Effects: +//! \code +//! for (; n--; ++r, ++f) +//! allocator_traits::construct(a, &*r, v); +//! \endcode +//! +//! Returns: r +template + // F models ForwardIterator +inline F uninitialized_fill_alloc_n(Allocator &a, const T &v, typename boost::container::allocator_traits::size_type n, F r) +{ + F back = r; + BOOST_TRY{ + while (n) { + --n; + allocator_traits::construct(a, boost::movelib::iterator_to_raw_pointer(r), v); + ++r; + } + } + BOOST_CATCH(...){ + for (; back != r; ++back){ + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(back)); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// copy +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy(I f, I l, F r) +{ + while (f != l) { + *r = *f; + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + copy(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// copy_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy_n(I f, U n, F r) +{ + while (n) { + --n; + *r = *f; + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + copy_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// copy_n_source +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy_n_source(I f, U n, F r) +{ + while (n) { + --n; + boost::container::assign_in_place(r, f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + copy_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// copy_n_source_dest +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + copy_n_source_dest(I f, U n, F &r) +{ + while (n) { + --n; + *r = *f; + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + copy_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source_dest(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// move +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move(I f, I l, F r) +{ + while (f != l) { + *r = ::boost::move(*f); + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +inline typename dtl::enable_if_memtransfer_copy_assignable::type + move(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove(f, l, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// move_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_n(I f, U n, F r) +{ + while (n) { + --n; + *r = ::boost::move(*f); + ++f; ++r; + } + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + move_n(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n(f, n, r); } + + +////////////////////////////////////////////////////////////////////////////// +// +// move_backward +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_backward(I f, I l, F r) +{ + while (f != l) { + --l; --r; + *r = ::boost::move(*l); + } + return r; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + move_backward(I f, I l, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ + typedef typename boost::container::iterator_traits::value_type value_type; + const typename boost::container::iterator_traits::difference_type n = boost::container::iterator_distance(f, l); + if (BOOST_LIKELY(n)){ + r -= n; + std::memmove((boost::movelib::iterator_to_raw_pointer)(r), (boost::movelib::iterator_to_raw_pointer)(f), sizeof(value_type)*n); + } + return r; +} + +////////////////////////////////////////////////////////////////////////////// +// +// move_n_source_dest +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_n_source_dest(I f, U n, F &r) +{ + while (n) { + --n; + *r = ::boost::move(*f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + move_n_source_dest(I f, U n, F &r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source_dest(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// move_n_source +// +////////////////////////////////////////////////////////////////////////////// + +template + // F models ForwardIterator +inline typename dtl::disable_if_memtransfer_copy_assignable::type + move_n_source(I f, U n, F r) +{ + while (n) { + --n; + *r = ::boost::move(*f); + ++f; ++r; + } + return f; +} + +template + // F models ForwardIterator +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_memtransfer_copy_assignable::type + move_n_source(I f, U n, F r) BOOST_NOEXCEPT_OR_NOTHROW +{ return dtl::memmove_n_source(f, n, r); } + +////////////////////////////////////////////////////////////////////////////// +// +// destroy_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + // U models unsigned integral constant +inline typename dtl::disable_if_trivially_destructible::type + destroy_alloc_n(Allocator &a, I f, U n) +{ + while(n){ + --n; + allocator_traits::destroy(a, boost::movelib::iterator_to_raw_pointer(f)); + ++f; + } +} + +template + // U models unsigned integral constant +BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_trivially_destructible::type + destroy_alloc_n(Allocator &, I, U) +{} + +////////////////////////////////////////////////////////////////////////////// +// +// deep_swap_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + +inline typename dtl::disable_if_memtransfer_copy_assignable::type + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) +{ + typename allocator_traits::size_type n = 0; + for (; n != n_i ; ++short_range_f, ++large_range_f, ++n){ + boost::adl_move_swap(*short_range_f, *large_range_f); + } + boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); +} + +static const std::size_t DeepSwapAllocNMaxStorage = std::size_t(1) << std::size_t(11); //2K bytes + +template + +inline typename dtl::enable_if_c + < dtl::is_memtransfer_copy_assignable::value && (MaxTmpBytes <= DeepSwapAllocNMaxStorage) && false + , void>::type + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) +{ + typedef typename allocator_traits::value_type value_type; + typedef typename dtl::aligned_storage + ::value>::type storage_type; + storage_type storage; + + const std::size_t n_i_bytes = sizeof(value_type)*n_i; + void *const large_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(large_range_f)); + void *const short_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(short_range_f)); + void *const stora_ptr = static_cast(boost::movelib::iterator_to_raw_pointer(storage.data)); + std::memcpy(stora_ptr, large_ptr, n_i_bytes); + std::memcpy(large_ptr, short_ptr, n_i_bytes); + std::memcpy(short_ptr, stora_ptr, n_i_bytes); + boost::container::iterator_advance(large_range_f, n_i); + boost::container::iterator_advance(short_range_f, n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); +} + +template + +inline typename dtl::enable_if_c + < dtl::is_memtransfer_copy_assignable::value && true//(MaxTmpBytes > DeepSwapAllocNMaxStorage) + , void>::type + deep_swap_alloc_n( Allocator &a, F short_range_f, typename allocator_traits::size_type n_i + , G large_range_f, typename allocator_traits::size_type n_j) +{ + typedef typename allocator_traits::value_type value_type; + typedef typename dtl::aligned_storage + ::value>::type storage_type; + storage_type storage; + const std::size_t sizeof_storage = sizeof(storage); + + std::size_t n_i_bytes = sizeof(value_type)*n_i; + char *large_ptr = static_cast(static_cast(boost::movelib::iterator_to_raw_pointer(large_range_f))); + char *short_ptr = static_cast(static_cast(boost::movelib::iterator_to_raw_pointer(short_range_f))); + char *stora_ptr = static_cast(static_cast(storage.data)); + + std::size_t szt_times = n_i_bytes/sizeof_storage; + const std::size_t szt_rem = n_i_bytes%sizeof_storage; + + //Loop unrolling using Duff's device, as it seems it helps on some architectures + const std::size_t Unroll = 4; + std::size_t n = (szt_times + (Unroll-1))/Unroll; + const std::size_t branch_number = (!szt_times)*Unroll + (szt_times % Unroll); + switch(branch_number){ + case 4: + break; + case 0: do{ + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + BOOST_FALLTHROUGH; + case 3: + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + BOOST_FALLTHROUGH; + case 2: + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + BOOST_FALLTHROUGH; + case 1: + std::memcpy(stora_ptr, large_ptr, sizeof_storage); + std::memcpy(large_ptr, short_ptr, sizeof_storage); + std::memcpy(short_ptr, stora_ptr, sizeof_storage); + large_ptr += sizeof_storage; + short_ptr += sizeof_storage; + } while(--n); + } + std::memcpy(stora_ptr, large_ptr, szt_rem); + std::memcpy(large_ptr, short_ptr, szt_rem); + std::memcpy(short_ptr, stora_ptr, szt_rem); + boost::container::iterator_advance(large_range_f, n_i); + boost::container::iterator_advance(short_range_f, n_i); + boost::container::uninitialized_move_alloc_n(a, large_range_f, n_j - n_i, short_range_f); // may throw + boost::container::destroy_alloc_n(a, large_range_f, n_j - n_i); +} + + +////////////////////////////////////////////////////////////////////////////// +// +// copy_assign_range_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + +void copy_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits::size_type n_i + , O out_start, typename allocator_traits::size_type n_o ) +{ + if (n_o < n_i){ + inp_start = boost::container::copy_n_source_dest(inp_start, n_o, out_start); // may throw + boost::container::uninitialized_copy_alloc_n(a, inp_start, n_i - n_o, out_start);// may throw + } + else{ + out_start = boost::container::copy_n(inp_start, n_i, out_start); // may throw + boost::container::destroy_alloc_n(a, out_start, n_o - n_i); + } +} + +////////////////////////////////////////////////////////////////////////////// +// +// move_assign_range_alloc_n +// +////////////////////////////////////////////////////////////////////////////// + +template + +void move_assign_range_alloc_n( Allocator &a, I inp_start, typename allocator_traits::size_type n_i + , O out_start, typename allocator_traits::size_type n_o ) +{ + if (n_o < n_i){ + inp_start = boost::container::move_n_source_dest(inp_start, n_o, out_start); // may throw + boost::container::uninitialized_move_alloc_n(a, inp_start, n_i - n_o, out_start); // may throw + } + else{ + out_start = boost::container::move_n(inp_start, n_i, out_start); // may throw + boost::container::destroy_alloc_n(a, out_start, n_o - n_i); + } +} + +template +struct array_destructor +{ + typedef typename ::boost::container::iterator_traits::value_type value_type; + typedef typename dtl::if_c + ::value + ,dtl::null_scoped_destructor_range + ,dtl::scoped_destructor_range + >::type type; +}; + +template + +void uninitialized_move_and_insert_alloc + ( Allocator &a + , F first + , F pos + , F last + , O d_first + , typename allocator_traits::size_type n + , InsertionProxy insert_range_proxy) +{ + typedef typename array_destructor::type array_destructor_t; + + //Anti-exception rollbacks + array_destructor_t new_values_destroyer(d_first, d_first, a); + + //Initialize with [begin(), pos) old buffer + //the start of the new buffer + O d_last = ::boost::container::uninitialized_move_alloc(a, first, pos, d_first); + new_values_destroyer.set_end(d_last); + //Initialize new objects, starting from previous point + insert_range_proxy.uninitialized_copy_n_and_update(a, d_last, n); + d_last += n; + new_values_destroyer.set_end(d_last); + //Initialize from the rest of the old buffer, + //starting from previous point + (void) ::boost::container::uninitialized_move_alloc(a, pos, last, d_last); + //All construction successful, disable rollbacks + new_values_destroyer.release(); +} + +template + +void expand_forward_and_insert_alloc + ( Allocator &a + , F pos + , F last + , typename allocator_traits::size_type n + , InsertionProxy insert_range_proxy) +{ + typedef typename array_destructor::type array_destructor_t; + + if (BOOST_UNLIKELY(!n)){ + return; + } + else if (last == pos){ + insert_range_proxy.uninitialized_copy_n_and_update(a, last, n); + } + else{ + typedef typename allocator_traits::size_type alloc_size_type; + const alloc_size_type elems_after = static_cast(last - pos); + if(elems_after >= n){ + //New elements can be just copied. + //Move to uninitialized memory last objects + ::boost::container::uninitialized_move_alloc_n(a, last - n, n, last); + array_destructor_t on_exception(last, last, a); + //Copy previous to last objects to the initialized end + boost::container::move_backward(pos, last - n, last); + //Insert new objects in the pos + insert_range_proxy.copy_n_and_update(a, pos, n); + on_exception.release(); + } + else { + //The new elements don't fit in the [pos, end()) range. + //Copy old [pos, end()) elements to the uninitialized memory (a gap is created) + F new_last = ::boost::container::uninitialized_move_alloc(a, pos, last, pos + n); + array_destructor_t on_exception(pos + n, new_last, a); + //Copy first new elements in pos (gap is still there) + insert_range_proxy.copy_n_and_update(a, pos, elems_after); + //Copy to the beginning of the unallocated zone the last new elements (the gap is closed). + insert_range_proxy.uninitialized_copy_n_and_update(a, last, n - elems_after); + on_exception.release(); + } + } +} + +} //namespace container { +} //namespace boost { + +//#pragma GCC diagnostic ignored "-Wclass-memaccess" +#if defined(BOOST_GCC) && (BOOST_GCC >= 40600) +#pragma GCC diagnostic pop +#endif + +#endif //#ifndef BOOST_CONTAINER_DETAIL_COPY_MOVE_ALGO_HPP diff --git a/src/vendor/boost/container/detail/destroyers.hpp b/src/vendor/boost/container/detail/destroyers.hpp new file mode 100644 index 000000000..604c2b963 --- /dev/null +++ b/src/vendor/boost/container/detail/destroyers.hpp @@ -0,0 +1,447 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DESTROYERS_HPP +#define BOOST_CONTAINER_DESTROYERS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an object using a STL allocator. +template +struct scoped_deallocator +{ + typedef allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef dtl::integral_constant::value> alloc_version; + + private: + void priv_deallocate(version_1) + { m_alloc.deallocate(m_ptr, 1); } + + void priv_deallocate(version_2) + { m_alloc.deallocate_one(m_ptr); } + + BOOST_MOVABLE_BUT_NOT_COPYABLE(scoped_deallocator) + + public: + + pointer m_ptr; + Allocator& m_alloc; + + scoped_deallocator(pointer p, Allocator& a) + : m_ptr(p), m_alloc(a) + {} + + ~scoped_deallocator() + { if (m_ptr)priv_deallocate(alloc_version()); } + + scoped_deallocator(BOOST_RV_REF(scoped_deallocator) o) + : m_ptr(o.m_ptr), m_alloc(o.m_alloc) + { o.release(); } + + pointer get() const + { return m_ptr; } + + void set(const pointer &p) + { m_ptr = p; } + + void release() + { m_ptr = 0; } +}; + +template +struct null_scoped_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + null_scoped_deallocator(pointer, Allocator&, size_type) + {} + + void release() + {} + + pointer get() const + { return pointer(); } + + void set(const pointer &) + {} +}; + +//!A deleter for scoped_ptr that deallocates the memory +//!allocated for an array of objects using a STL allocator. +template +struct scoped_array_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + scoped_array_deallocator(pointer p, Allocator& a, size_type length) + : m_ptr(p), m_alloc(a), m_length(length) {} + + ~scoped_array_deallocator() + { if (m_ptr) m_alloc.deallocate(m_ptr, m_length); } + + void release() + { m_ptr = 0; } + + private: + pointer m_ptr; + Allocator& m_alloc; + size_type m_length; +}; + +template +struct null_scoped_array_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + null_scoped_array_deallocator(pointer, Allocator&, size_type) + {} + + void release() + {} +}; + +template +struct scoped_destroy_deallocator +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + typedef dtl::integral_constant::value> alloc_version; + + scoped_destroy_deallocator(pointer p, Allocator& a) + : m_ptr(p), m_alloc(a) {} + + ~scoped_destroy_deallocator() + { + if(m_ptr){ + AllocTraits::destroy(m_alloc, boost::movelib::to_raw_pointer(m_ptr)); + priv_deallocate(m_ptr, alloc_version()); + } + } + + void release() + { m_ptr = 0; } + + private: + + void priv_deallocate(const pointer &p, version_1) + { AllocTraits::deallocate(m_alloc, p, 1); } + + void priv_deallocate(const pointer &p, version_2) + { m_alloc.deallocate_one(p); } + + pointer m_ptr; + Allocator& m_alloc; +}; + + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct scoped_destructor_n +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::value_type value_type; + typedef typename AllocTraits::size_type size_type; + + BOOST_CONTAINER_FORCEINLINE scoped_destructor_n(pointer p, Allocator& a, size_type n) + : m_p(p), m_a(a), m_n(n) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + { m_p = 0; m_n = 0; } + + BOOST_CONTAINER_FORCEINLINE void increment_size(size_type inc) + { m_n += inc; } + + BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(size_type inc) + { m_n += inc; m_p -= inc; } + + BOOST_CONTAINER_FORCEINLINE void shrink_forward(size_type inc) + { m_n -= inc; m_p += inc; } + + ~scoped_destructor_n() + { + if(m_n){ + value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); + do { + --m_n; + AllocTraits::destroy(m_a, raw_ptr); + ++raw_ptr; + } while(m_n); + } + } + + private: + pointer m_p; + Allocator & m_a; + size_type m_n; +}; + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct null_scoped_destructor_n +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::size_type size_type; + + BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_n(pointer, Allocator&, size_type) + {} + + BOOST_CONTAINER_FORCEINLINE void increment_size(size_type) + {} + + BOOST_CONTAINER_FORCEINLINE void increment_size_backwards(size_type) + {} + + BOOST_CONTAINER_FORCEINLINE void shrink_forward(size_type) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + {} +}; + + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct scoped_destructor_range +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + typedef typename AllocTraits::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE scoped_destructor_range(pointer p, pointer e, Allocator& a) + : m_p(p), m_e(e), m_a(a) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + { m_p = pointer(); m_e = pointer(); } + + BOOST_CONTAINER_FORCEINLINE void set_end(pointer e) + { m_e = e; } + + BOOST_CONTAINER_FORCEINLINE void set_begin(pointer b) + { m_p = b; } + + BOOST_CONTAINER_FORCEINLINE void set_range(pointer b, pointer e) + { m_p = b; m_e = e; } + + ~scoped_destructor_range() + { + while(m_p != m_e){ + value_type *raw_ptr = boost::movelib::to_raw_pointer(m_p); + AllocTraits::destroy(m_a, raw_ptr); + ++m_p; + } + } + + private: + pointer m_p; + pointer m_e; + Allocator & m_a; +}; + +//!A deleter for scoped_ptr that destroys +//!an object using a STL allocator. +template +struct null_scoped_destructor_range +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::pointer pointer; + + BOOST_CONTAINER_FORCEINLINE null_scoped_destructor_range(pointer, pointer, Allocator&) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + {} + + BOOST_CONTAINER_FORCEINLINE void set_end(pointer) + {} + + BOOST_CONTAINER_FORCEINLINE void set_begin(pointer) + {} + + BOOST_CONTAINER_FORCEINLINE void set_range(pointer, pointer) + {} +}; + + +template +class scoped_destructor +{ + typedef boost::container::allocator_traits AllocTraits; + public: + typedef typename Allocator::value_type value_type; + BOOST_CONTAINER_FORCEINLINE scoped_destructor(Allocator &a, value_type *pv) + : pv_(pv), a_(a) + {} + + BOOST_CONTAINER_FORCEINLINE ~scoped_destructor() + { + if(pv_){ + AllocTraits::destroy(a_, pv_); + } + } + + BOOST_CONTAINER_FORCEINLINE void release() + { pv_ = 0; } + + + BOOST_CONTAINER_FORCEINLINE void set(value_type *ptr) { pv_ = ptr; } + + BOOST_CONTAINER_FORCEINLINE value_type *get() const { return pv_; } + + private: + value_type *pv_; + Allocator &a_; +}; + + +template +class value_destructor +{ + typedef boost::container::allocator_traits AllocTraits; + public: + typedef Value value_type; + BOOST_CONTAINER_FORCEINLINE value_destructor(Allocator &a, value_type &rv) + : rv_(rv), a_(a) + {} + + BOOST_CONTAINER_FORCEINLINE ~value_destructor() + { + AllocTraits::destroy(a_, &rv_); + } + + private: + value_type &rv_; + Allocator &a_; +}; + +template +class allocator_destroyer +{ + typedef boost::container::allocator_traits AllocTraits; + typedef typename AllocTraits::value_type value_type; + typedef typename AllocTraits::pointer pointer; + typedef dtl::integral_constant::value> alloc_version; + + private: + Allocator & a_; + + private: + BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_1) + { AllocTraits::deallocate(a_,p, 1); } + + BOOST_CONTAINER_FORCEINLINE void priv_deallocate(const pointer &p, version_2) + { a_.deallocate_one(p); } + + public: + BOOST_CONTAINER_FORCEINLINE explicit allocator_destroyer(Allocator &a) + : a_(a) + {} + + BOOST_CONTAINER_FORCEINLINE void operator()(const pointer &p) + { + AllocTraits::destroy(a_, boost::movelib::to_raw_pointer(p)); + this->priv_deallocate(p, alloc_version()); + } +}; + +template +class allocator_destroyer_and_chain_builder +{ + typedef allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::value_type value_type; + typedef typename Allocator::multiallocation_chain multiallocation_chain; + + Allocator & a_; + multiallocation_chain &c_; + + public: + BOOST_CONTAINER_FORCEINLINE allocator_destroyer_and_chain_builder(Allocator &a, multiallocation_chain &c) + : a_(a), c_(c) + {} + + BOOST_CONTAINER_FORCEINLINE void operator()(const typename Allocator::pointer &p) + { + allocator_traits::destroy(a_, boost::movelib::to_raw_pointer(p)); + c_.push_back(p); + } +}; + +template +class allocator_multialloc_chain_node_deallocator +{ + typedef allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::value_type value_type; + typedef typename Allocator::multiallocation_chain multiallocation_chain; + typedef allocator_destroyer_and_chain_builder chain_builder; + + Allocator & a_; + multiallocation_chain c_; + + public: + BOOST_CONTAINER_FORCEINLINE allocator_multialloc_chain_node_deallocator(Allocator &a) + : a_(a), c_() + {} + + BOOST_CONTAINER_FORCEINLINE chain_builder get_chain_builder() + { return chain_builder(a_, c_); } + + BOOST_CONTAINER_FORCEINLINE ~allocator_multialloc_chain_node_deallocator() + { + a_.deallocate_individual(c_); + } +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DESTROYERS_HPP diff --git a/src/vendor/boost/container/detail/iterator.hpp b/src/vendor/boost/container/detail/iterator.hpp new file mode 100644 index 000000000..800cef3d9 --- /dev/null +++ b/src/vendor/boost/container/detail/iterator.hpp @@ -0,0 +1,86 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ITERATOR_HPP +#define BOOST_CONTAINER_DETAIL_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace container { + +using ::boost::intrusive::iterator_traits; +using ::boost::intrusive::iterator_distance; +using ::boost::intrusive::iterator_advance; +using ::boost::intrusive::iterator; +using ::boost::intrusive::iterator_enable_if_tag; +using ::boost::intrusive::iterator_disable_if_tag; +using ::boost::intrusive::iterator_arrow_result; + +template +class back_emplacer +{ + private: + Container& container; + + public: + typedef std::output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + back_emplacer(Container& x) + : container(x) + {} + + template + back_emplacer& operator=(BOOST_FWD_REF(U) value) + { + container.emplace_back(boost::forward(value)); + return *this; + } + back_emplacer& operator*() { return *this; } + back_emplacer& operator++() { return *this; } + back_emplacer& operator++(int){ return *this; } +}; + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template +using it_based_non_const_first_type_t = typename dtl::remove_const::value_type::first_type>::type; + +template +using it_based_const_first_type_t = const typename dtl::remove_const::value_type::first_type>::type; + +template +using it_based_second_type_t = typename iterator_traits::value_type::second_type; + +template +using it_based_value_type_t = typename iterator_traits::value_type; + +#endif + +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP diff --git a/src/vendor/boost/container/detail/iterators.hpp b/src/vendor/boost/container/detail/iterators.hpp new file mode 100644 index 000000000..4ac7d492a --- /dev/null +++ b/src/vendor/boost/container/detail/iterators.hpp @@ -0,0 +1,891 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP +#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#else +#include +#endif +#include + +namespace boost { +namespace container { + +template +class constant_iterator + : public ::boost::container::iterator + +{ + typedef constant_iterator this_type; + + public: + BOOST_CONTAINER_FORCEINLINE explicit constant_iterator(const T &ref, Difference range_size) + : m_ptr(&ref), m_num(range_size){} + + //Constructors + BOOST_CONTAINER_FORCEINLINE constant_iterator() + : m_ptr(0), m_num(0){} + + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator++() + { increment(); return *this; } + + BOOST_CONTAINER_FORCEINLINE constant_iterator operator++(int) + { + constant_iterator result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator--() + { decrement(); return *this; } + + BOOST_CONTAINER_FORCEINLINE constant_iterator operator--(int) + { + constant_iterator result (*this); + decrement(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const constant_iterator& i, const constant_iterator& i2) + { return i.equal(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const constant_iterator& i, const constant_iterator& i2) + { return !(i == i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const constant_iterator& i, const constant_iterator& i2) + { return i.less(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const constant_iterator& i, const constant_iterator& i2) + { return i2 < i; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const constant_iterator& i, const constant_iterator& i2) + { return !(i > i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const constant_iterator& i, const constant_iterator& i2) + { return !(i < i2); } + + BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const constant_iterator& i, const constant_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + BOOST_CONTAINER_FORCEINLINE constant_iterator operator+(Difference off) const + { + constant_iterator other(*this); + other.advance(off); + return other; + } + + BOOST_CONTAINER_FORCEINLINE friend constant_iterator operator+(Difference off, const constant_iterator& right) + { return right + off; } + + BOOST_CONTAINER_FORCEINLINE constant_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + BOOST_CONTAINER_FORCEINLINE constant_iterator operator-(Difference off) const + { return *this + (-off); } + + BOOST_CONTAINER_FORCEINLINE const T& operator*() const + { return dereference(); } + + BOOST_CONTAINER_FORCEINLINE const T& operator[] (Difference ) const + { return dereference(); } + + BOOST_CONTAINER_FORCEINLINE const T* operator->() const + { return &(dereference()); } + + private: + const T * m_ptr; + Difference m_num; + + BOOST_CONTAINER_FORCEINLINE void increment() + { --m_num; } + + BOOST_CONTAINER_FORCEINLINE void decrement() + { ++m_num; } + + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const + { return m_num == other.m_num; } + + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const + { return other.m_num < m_num; } + + BOOST_CONTAINER_FORCEINLINE const T & dereference() const + { return *m_ptr; } + + BOOST_CONTAINER_FORCEINLINE void advance(Difference n) + { m_num -= n; } + + BOOST_CONTAINER_FORCEINLINE Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class value_init_construct_iterator + : public ::boost::container::iterator + +{ + typedef value_init_construct_iterator this_type; + + public: + BOOST_CONTAINER_FORCEINLINE explicit value_init_construct_iterator(Difference range_size) + : m_num(range_size){} + + //Constructors + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator() + : m_num(0){} + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator++() + { increment(); return *this; } + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator++(int) + { + value_init_construct_iterator result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator--() + { decrement(); return *this; } + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator--(int) + { + value_init_construct_iterator result (*this); + decrement(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i.equal(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return !(i == i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i.less(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i2 < i; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return !(i > i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return !(i < i2); } + + BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator+(Difference off) const + { + value_init_construct_iterator other(*this); + other.advance(off); + return other; + } + + BOOST_CONTAINER_FORCEINLINE friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right) + { return right + off; } + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + BOOST_CONTAINER_FORCEINLINE value_init_construct_iterator operator-(Difference off) const + { return *this + (-off); } + + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + //const T& operator*() const; + //const T& operator[](difference_type) const; + //const T* operator->() const; + + private: + Difference m_num; + + BOOST_CONTAINER_FORCEINLINE void increment() + { --m_num; } + + BOOST_CONTAINER_FORCEINLINE void decrement() + { ++m_num; } + + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const + { return m_num == other.m_num; } + + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const + { return other.m_num < m_num; } + + BOOST_CONTAINER_FORCEINLINE const T & dereference() const + { + static T dummy; + return dummy; + } + + BOOST_CONTAINER_FORCEINLINE void advance(Difference n) + { m_num -= n; } + + BOOST_CONTAINER_FORCEINLINE Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class default_init_construct_iterator + : public ::boost::container::iterator + +{ + typedef default_init_construct_iterator this_type; + + public: + BOOST_CONTAINER_FORCEINLINE explicit default_init_construct_iterator(Difference range_size) + : m_num(range_size){} + + //Constructors + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator() + : m_num(0){} + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator++() + { increment(); return *this; } + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator++(int) + { + default_init_construct_iterator result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator--() + { decrement(); return *this; } + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator--(int) + { + default_init_construct_iterator result (*this); + decrement(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i.equal(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i == i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i.less(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i2 < i; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i > i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return !(i < i2); } + + BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator+=(Difference off) + { this->advance(off); return *this; } + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator+(Difference off) const + { + default_init_construct_iterator other(*this); + other.advance(off); + return other; + } + + BOOST_CONTAINER_FORCEINLINE friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right) + { return right + off; } + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator& operator-=(Difference off) + { this->advance(-off); return *this; } + + BOOST_CONTAINER_FORCEINLINE default_init_construct_iterator operator-(Difference off) const + { return *this + (-off); } + + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + //const T& operator*() const; + //const T& operator[](difference_type) const; + //const T* operator->() const; + + private: + Difference m_num; + + BOOST_CONTAINER_FORCEINLINE void increment() + { --m_num; } + + BOOST_CONTAINER_FORCEINLINE void decrement() + { ++m_num; } + + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const + { return m_num == other.m_num; } + + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const + { return other.m_num < m_num; } + + BOOST_CONTAINER_FORCEINLINE const T & dereference() const + { + static T dummy; + return dummy; + } + + BOOST_CONTAINER_FORCEINLINE void advance(Difference n) + { m_num -= n; } + + BOOST_CONTAINER_FORCEINLINE Difference distance_to(const this_type &other) const + { return m_num - other.m_num; } +}; + + +template +class repeat_iterator + : public ::boost::container::iterator + +{ + typedef repeat_iterator this_type; + public: + BOOST_CONTAINER_FORCEINLINE explicit repeat_iterator(T &ref, Difference range_size) + : m_ptr(&ref), m_num(range_size){} + + //Constructors + BOOST_CONTAINER_FORCEINLINE repeat_iterator() + : m_ptr(0), m_num(0){} + + BOOST_CONTAINER_FORCEINLINE this_type& operator++() + { increment(); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator++(int) + { + this_type result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE this_type& operator--() + { increment(); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator--(int) + { + this_type result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2) + { return i.equal(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2) + { return !(i == i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2) + { return i.less(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2) + { return i2 < i; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2) + { return !(i > i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2) + { return !(i < i2); } + + BOOST_CONTAINER_FORCEINLINE friend Difference operator- (const this_type& i, const this_type& i2) + { return i2.distance_to(i); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE this_type& operator+=(Difference off) + { this->advance(off); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator+(Difference off) const + { + this_type other(*this); + other.advance(off); + return other; + } + + BOOST_CONTAINER_FORCEINLINE friend this_type operator+(Difference off, const this_type& right) + { return right + off; } + + BOOST_CONTAINER_FORCEINLINE this_type& operator-=(Difference off) + { this->advance(-off); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator-(Difference off) const + { return *this + (-off); } + + BOOST_CONTAINER_FORCEINLINE T& operator*() const + { return dereference(); } + + BOOST_CONTAINER_FORCEINLINE T& operator[] (Difference ) const + { return dereference(); } + + BOOST_CONTAINER_FORCEINLINE T *operator->() const + { return &(dereference()); } + + private: + T * m_ptr; + Difference m_num; + + BOOST_CONTAINER_FORCEINLINE void increment() + { --m_num; } + + BOOST_CONTAINER_FORCEINLINE void decrement() + { ++m_num; } + + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const + { return m_num == other.m_num; } + + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const + { return other.m_num < m_num; } + + BOOST_CONTAINER_FORCEINLINE T & dereference() const + { return *m_ptr; } + + BOOST_CONTAINER_FORCEINLINE void advance(Difference n) + { m_num -= n; } + + BOOST_CONTAINER_FORCEINLINE Difference distance_to(const this_type &other)const + { return m_num - other.m_num; } +}; + +template +class emplace_iterator + : public ::boost::container::iterator + +{ + typedef emplace_iterator this_type; + + public: + typedef Difference difference_type; + BOOST_CONTAINER_FORCEINLINE explicit emplace_iterator(EmplaceFunctor&e) + : m_num(1), m_pe(&e){} + + BOOST_CONTAINER_FORCEINLINE emplace_iterator() + : m_num(0), m_pe(0){} + + BOOST_CONTAINER_FORCEINLINE this_type& operator++() + { increment(); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator++(int) + { + this_type result (*this); + increment(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE this_type& operator--() + { decrement(); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator--(int) + { + this_type result (*this); + decrement(); + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const this_type& i, const this_type& i2) + { return i.equal(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const this_type& i, const this_type& i2) + { return !(i == i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const this_type& i, const this_type& i2) + { return i.less(i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const this_type& i, const this_type& i2) + { return i2 < i; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const this_type& i, const this_type& i2) + { return !(i > i2); } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const this_type& i, const this_type& i2) + { return !(i < i2); } + + BOOST_CONTAINER_FORCEINLINE friend difference_type operator- (const this_type& i, const this_type& i2) + { return i2.distance_to(i); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE this_type& operator+=(difference_type off) + { this->advance(off); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator+(difference_type off) const + { + this_type other(*this); + other.advance(off); + return other; + } + + BOOST_CONTAINER_FORCEINLINE friend this_type operator+(difference_type off, const this_type& right) + { return right + off; } + + BOOST_CONTAINER_FORCEINLINE this_type& operator-=(difference_type off) + { this->advance(-off); return *this; } + + BOOST_CONTAINER_FORCEINLINE this_type operator-(difference_type off) const + { return *this + (-off); } + + private: + //This pseudo-iterator's dereference operations have no sense since value is not + //constructed until ::boost::container::construct_in_place is called. + //So comment them to catch bad uses + const T& operator*() const; + const T& operator[](difference_type) const; + const T* operator->() const; + + public: + template + BOOST_CONTAINER_FORCEINLINE void construct_in_place(Allocator &a, T* ptr) + { (*m_pe)(a, ptr); } + + template + BOOST_CONTAINER_FORCEINLINE void assign_in_place(DestIt dest) + { (*m_pe)(dest); } + + private: + difference_type m_num; + EmplaceFunctor * m_pe; + + BOOST_CONTAINER_FORCEINLINE void increment() + { --m_num; } + + BOOST_CONTAINER_FORCEINLINE void decrement() + { ++m_num; } + + BOOST_CONTAINER_FORCEINLINE bool equal(const this_type &other) const + { return m_num == other.m_num; } + + BOOST_CONTAINER_FORCEINLINE bool less(const this_type &other) const + { return other.m_num < m_num; } + + BOOST_CONTAINER_FORCEINLINE const T & dereference() const + { + static T dummy; + return dummy; + } + + BOOST_CONTAINER_FORCEINLINE void advance(difference_type n) + { m_num -= n; } + + BOOST_CONTAINER_FORCEINLINE difference_type distance_to(const this_type &other)const + { return difference_type(m_num - other.m_num); } +}; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +struct emplace_functor +{ + typedef typename dtl::build_number_seq::type index_tuple_t; + + BOOST_CONTAINER_FORCEINLINE emplace_functor(BOOST_FWD_REF(Args)... args) + : args_(args...) + {} + + template + BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr) + { emplace_functor::inplace_impl(a, ptr, index_tuple_t()); } + + template + BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest) + { emplace_functor::inplace_impl(dest, index_tuple_t()); } + + private: + template + BOOST_CONTAINER_FORCEINLINE void inplace_impl(Allocator &a, T* ptr, const dtl::index_tuple&) + { + allocator_traits::construct + (a, ptr, ::boost::forward(dtl::get(args_))...); + } + + template + BOOST_CONTAINER_FORCEINLINE void inplace_impl(DestIt dest, const dtl::index_tuple&) + { + typedef typename boost::container::iterator_traits::value_type value_type; + value_type && tmp= value_type(::boost::forward(dtl::get(args_))...); + *dest = ::boost::move(tmp); + } + + dtl::tuple args_; +}; + +template +struct emplace_functor_type +{ + typedef emplace_functor type; +}; + +#else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +//Partial specializations cannot match argument list for primary template, so add an extra argument +template +struct emplace_functor_type; + +#define BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE(N) \ +BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ +struct emplace_functor##N\ +{\ + BOOST_CONTAINER_FORCEINLINE explicit emplace_functor##N( BOOST_MOVE_UREF##N )\ + BOOST_MOVE_COLON##N BOOST_MOVE_FWD_INIT##N{}\ + \ + template\ + BOOST_CONTAINER_FORCEINLINE void operator()(Allocator &a, T *ptr)\ + { allocator_traits::construct(a, ptr BOOST_MOVE_I##N BOOST_MOVE_MFWD##N); }\ + \ + template\ + BOOST_CONTAINER_FORCEINLINE void operator()(DestIt dest)\ + {\ + typedef typename boost::container::iterator_traits::value_type value_type;\ + BOOST_MOVE_IF(N, value_type tmp(BOOST_MOVE_MFWD##N), dtl::value_init tmp) ;\ + *dest = ::boost::move(const_cast(BOOST_MOVE_IF(N, tmp, tmp.get())));\ + }\ + \ + BOOST_MOVE_MREF##N\ +};\ +\ +template \ +struct emplace_functor_type\ +{\ + typedef emplace_functor##N BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N type;\ +};\ +// + +BOOST_MOVE_ITERATE_0TO9(BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE) + +#undef BOOST_MOVE_ITERATOR_EMPLACE_FUNCTOR_CODE + +#endif + +namespace dtl { + +template +struct has_iterator_category +{ + struct two { char _[2]; }; + + template + static char test(int, typename X::iterator_category*); + + template + static two test(int, ...); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + + +template::value > +struct is_input_iterator +{ + static const bool value = is_same::value; +}; + +template +struct is_input_iterator +{ + static const bool value = false; +}; + +template +struct is_not_input_iterator +{ + static const bool value = !is_input_iterator::value; +}; + +template::value > +struct is_forward_iterator +{ + static const bool value = is_same::value; +}; + +template +struct is_forward_iterator +{ + static const bool value = false; +}; + +template::value > +struct is_bidirectional_iterator +{ + static const bool value = is_same::value; +}; + +template +struct is_bidirectional_iterator +{ + static const bool value = false; +}; + +template +struct iiterator_node_value_type { + typedef typename IINodeType::value_type type; +}; + +template +struct iiterator_types +{ + typedef typename IIterator::value_type it_value_type; + typedef typename iiterator_node_value_type::type value_type; + typedef typename boost::container::iterator_traits::pointer it_pointer; + typedef typename boost::container::iterator_traits::difference_type difference_type; + typedef typename ::boost::intrusive::pointer_traits:: + template rebind_pointer::type pointer; + typedef typename ::boost::intrusive::pointer_traits:: + template rebind_pointer::type const_pointer; + typedef typename ::boost::intrusive:: + pointer_traits::reference reference; + typedef typename ::boost::intrusive:: + pointer_traits::reference const_reference; + typedef typename IIterator::iterator_category iterator_category; +}; + +template +struct iterator_types +{ + typedef typename ::boost::container::iterator + < typename iiterator_types::iterator_category + , typename iiterator_types::value_type + , typename iiterator_types::difference_type + , typename iiterator_types::const_pointer + , typename iiterator_types::const_reference> type; +}; + +template +struct iterator_types +{ + typedef typename ::boost::container::iterator + < typename iiterator_types::iterator_category + , typename iiterator_types::value_type + , typename iiterator_types::difference_type + , typename iiterator_types::pointer + , typename iiterator_types::reference> type; +}; + +template +class iterator_from_iiterator +{ + typedef typename iterator_types::type types_t; + class nat + { + public: + IIterator get() const + { return IIterator(); } + }; + typedef typename dtl::if_c< IsConst + , iterator_from_iiterator + , nat>::type nonconst_iterator; + + public: + typedef typename types_t::pointer pointer; + typedef typename types_t::reference reference; + typedef typename types_t::difference_type difference_type; + typedef typename types_t::iterator_category iterator_category; + typedef typename types_t::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator() + : m_iit() + {} + + BOOST_CONTAINER_FORCEINLINE explicit iterator_from_iiterator(IIterator iit) BOOST_NOEXCEPT_OR_NOTHROW + : m_iit(iit) + {} + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_iit(other.get()) + {} + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator(const nonconst_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_iit(other.get()) + {} + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator=(const iterator_from_iiterator& other) BOOST_NOEXCEPT_OR_NOTHROW + { m_iit = other.get(); return *this; } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW + { ++this->m_iit; return *this; } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW + { + iterator_from_iiterator result (*this); + ++this->m_iit; + return result; + } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW + { + //If the iterator_from_iiterator is not a bidirectional iterator, operator-- should not exist + BOOST_STATIC_ASSERT((is_bidirectional_iterator::value)); + --this->m_iit; return *this; + } + + BOOST_CONTAINER_FORCEINLINE iterator_from_iiterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW + { + iterator_from_iiterator result (*this); + --this->m_iit; + return result; + } + + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_iit == r.m_iit; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const iterator_from_iiterator& l, const iterator_from_iiterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return !(l == r); } + + BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_iit->get_data(); } + + BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW + { return ::boost::intrusive::pointer_traits::pointer_to(this->operator*()); } + + BOOST_CONTAINER_FORCEINLINE const IIterator &get() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_iit; } + + private: + IIterator m_iit; +}; + +} //namespace dtl { + +using ::boost::intrusive::reverse_iterator; + +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP diff --git a/src/vendor/boost/container/detail/min_max.hpp b/src/vendor/boost/container/detail/min_max.hpp new file mode 100644 index 000000000..35cf06617 --- /dev/null +++ b/src/vendor/boost/container/detail/min_max.hpp @@ -0,0 +1,37 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP +#define BOOST_CONTAINER_DETAIL_MIN_MAX_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace container { +namespace dtl { + +template +const T &max_value(const T &a, const T &b) +{ return a > b ? a : b; } + +template +const T &min_value(const T &a, const T &b) +{ return a < b ? a : b; } + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_DETAIL_MIN_MAX_HPP diff --git a/src/vendor/boost/container/detail/mpl.hpp b/src/vendor/boost/container/detail/mpl.hpp new file mode 100644 index 000000000..ffae180c8 --- /dev/null +++ b/src/vendor/boost/container/detail/mpl.hpp @@ -0,0 +1,144 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP +#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +#include + +namespace boost { +namespace container { +namespace dtl { + +using boost::move_detail::integral_constant; +using boost::move_detail::true_type; +using boost::move_detail::false_type; +using boost::move_detail::enable_if_c; +using boost::move_detail::enable_if; +using boost::move_detail::enable_if_convertible; +using boost::move_detail::disable_if_c; +using boost::move_detail::disable_if; +using boost::move_detail::disable_if_convertible; +using boost::move_detail::is_convertible; +using boost::move_detail::if_c; +using boost::move_detail::if_; +using boost::move_detail::identity; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::yes_type; +using boost::move_detail::no_type; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::unvoid_ref; +using boost::move_detail::and_; +using boost::move_detail::or_; +using boost::move_detail::not_; +using boost::move_detail::enable_if_and; +using boost::move_detail::disable_if_and; +using boost::move_detail::enable_if_or; +using boost::move_detail::disable_if_or; +using boost::move_detail::remove_const; + +template +struct select1st +{ + typedef FirstType type; + + template + BOOST_CONTAINER_FORCEINLINE const type& operator()(const T& x) const + { return x.first; } + + template + BOOST_CONTAINER_FORCEINLINE type& operator()(T& x) + { return const_cast(x.first); } +}; + + +template +struct void_t { typedef void type; }; + +template +struct is_transparent_base +{ + static const bool value = false; +}; + +template +struct is_transparent_base::type> +{ + static const bool value = true; +}; + +template +struct is_transparent + : is_transparent_base +{}; + +template +struct enable_if_transparent + : boost::move_detail::enable_if_c::value, R> +{}; + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +// void_t (void_t for C++11) +template using variadic_void_t = void; + +// Trait to detect Allocator-like types. +template +struct is_allocator +{ + static const bool value = false; +}; + +template +T&& ctad_declval(); + +template +struct is_allocator < Allocator, + variadic_void_t< typename Allocator::value_type + , decltype(ctad_declval().allocate(size_t{})) >> +{ + static const bool value = true; +}; + +template +using require_allocator_t = typename enable_if_c::value, T>::type; + +template +using require_nonallocator_t = typename enable_if_c::value, T>::type; + +#endif + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP + diff --git a/src/vendor/boost/container/detail/multiallocation_chain.hpp b/src/vendor/boost/container/detail/multiallocation_chain.hpp new file mode 100644 index 000000000..20f588f7c --- /dev/null +++ b/src/vendor/boost/container/detail/multiallocation_chain.hpp @@ -0,0 +1,304 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP +#define BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +// container +#include +// container/detail +#include +#include +#include +#include +// intrusive +#include +#include +// move +#include + +namespace boost { +namespace container { +namespace dtl { + +template +class basic_multiallocation_chain +{ + private: + typedef bi::slist_base_hook + ,bi::link_mode + > node; + + typedef typename boost::intrusive::pointer_traits + ::template rebind_pointer::type char_ptr; + typedef typename boost::intrusive:: + pointer_traits::difference_type difference_type; + + typedef bi::slist< node + , bi::linear + , bi::cache_last + , bi::size_type::type> + > slist_impl_t; + slist_impl_t slist_impl_; + + typedef typename boost::intrusive::pointer_traits + ::template rebind_pointer::type node_ptr; + typedef typename boost::intrusive:: + pointer_traits node_ptr_traits; + + static node & to_node(const VoidPointer &p) + { return *static_cast(static_cast(boost::movelib::to_raw_pointer(p))); } + + static VoidPointer from_node(node &n) + { return node_ptr_traits::pointer_to(n); } + + static node_ptr to_node_ptr(const VoidPointer &p) + { return node_ptr_traits::static_cast_from(p); } + + BOOST_MOVABLE_BUT_NOT_COPYABLE(basic_multiallocation_chain) + + public: + + typedef VoidPointer void_pointer; + typedef typename slist_impl_t::iterator iterator; + typedef typename slist_impl_t::size_type size_type; + + basic_multiallocation_chain() + : slist_impl_() + {} + + basic_multiallocation_chain(const void_pointer &b, const void_pointer &before_e, size_type n) + : slist_impl_(to_node_ptr(b), to_node_ptr(before_e), n) + {} + + basic_multiallocation_chain(BOOST_RV_REF(basic_multiallocation_chain) other) + : slist_impl_(::boost::move(other.slist_impl_)) + {} + + basic_multiallocation_chain& operator=(BOOST_RV_REF(basic_multiallocation_chain) other) + { + slist_impl_ = ::boost::move(other.slist_impl_); + return *this; + } + + bool empty() const + { return slist_impl_.empty(); } + + size_type size() const + { return slist_impl_.size(); } + + iterator before_begin() + { return slist_impl_.before_begin(); } + + iterator begin() + { return slist_impl_.begin(); } + + iterator end() + { return slist_impl_.end(); } + + iterator last() + { return slist_impl_.last(); } + + void clear() + { slist_impl_.clear(); } + + iterator insert_after(iterator it, void_pointer m) + { return slist_impl_.insert_after(it, to_node(m)); } + + void push_front(const void_pointer &m) + { return slist_impl_.push_front(to_node(m)); } + + void push_back(const void_pointer &m) + { return slist_impl_.push_back(to_node(m)); } + + void_pointer pop_front() + { + node & n = slist_impl_.front(); + void_pointer ret = from_node(n); + slist_impl_.pop_front(); + return ret; + } + + void splice_after(iterator after_this, basic_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) + { slist_impl_.splice_after(after_this, x.slist_impl_, before_b, before_e, n); } + + void splice_after(iterator after_this, basic_multiallocation_chain &x) + { slist_impl_.splice_after(after_this, x.slist_impl_); } + + void erase_after(iterator before_b, iterator e, size_type n) + { slist_impl_.erase_after(before_b, e, n); } + + void_pointer incorporate_after(iterator after_this, const void_pointer &b, size_type unit_bytes, size_type num_units) + { + typedef typename boost::intrusive::pointer_traits char_pointer_traits; + char_ptr elem = char_pointer_traits::static_cast_from(b); + if(num_units){ + char_ptr prev_elem = elem; + elem += unit_bytes; + for(size_type i = 0; i != num_units-1; ++i, elem += unit_bytes){ + ::new (boost::movelib::to_raw_pointer(prev_elem), boost_container_new_t()) void_pointer(elem); + prev_elem = elem; + } + slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(prev_elem), num_units); + } + return elem; + } + + void incorporate_after(iterator after_this, void_pointer b, void_pointer before_e, size_type n) + { slist_impl_.incorporate_after(after_this, to_node_ptr(b), to_node_ptr(before_e), n); } + + void swap(basic_multiallocation_chain &x) + { slist_impl_.swap(x.slist_impl_); } + + static iterator iterator_to(const void_pointer &p) + { return slist_impl_t::s_iterator_to(to_node(p)); } + + std::pair extract_data() + { + if(BOOST_LIKELY(!slist_impl_.empty())){ + std::pair ret + (slist_impl_.begin().operator->() + ,slist_impl_.last().operator->()); + slist_impl_.clear(); + return ret; + } + else { + return std::pair(); + } + } +}; + +template +struct cast_functor +{ + typedef typename dtl::add_reference::type result_type; + template + result_type operator()(U &ptr) const + { return *static_cast(static_cast(&ptr)); } +}; + +template +class transform_multiallocation_chain + : public MultiallocationChain +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(transform_multiallocation_chain) + //transform_multiallocation_chain(const transform_multiallocation_chain &); + //transform_multiallocation_chain & operator=(const transform_multiallocation_chain &); + + typedef typename MultiallocationChain::void_pointer void_pointer; + typedef typename boost::intrusive::pointer_traits + void_pointer_traits; + typedef typename void_pointer_traits::template + rebind_pointer::type pointer; + typedef typename boost::intrusive::pointer_traits + pointer_traits; + + static pointer cast(const void_pointer &p) + { return pointer_traits::static_cast_from(p); } + + public: + typedef transform_iterator + < typename MultiallocationChain::iterator + , dtl::cast_functor > iterator; + typedef typename MultiallocationChain::size_type size_type; + + transform_multiallocation_chain() + : MultiallocationChain() + {} + + transform_multiallocation_chain(BOOST_RV_REF(transform_multiallocation_chain) other) + : MultiallocationChain(::boost::move(static_cast(other))) + {} + + transform_multiallocation_chain(BOOST_RV_REF(MultiallocationChain) other) + : MultiallocationChain(::boost::move(static_cast(other))) + {} + + transform_multiallocation_chain& operator=(BOOST_RV_REF(transform_multiallocation_chain) other) + { + return static_cast + (this->MultiallocationChain::operator=(::boost::move(static_cast(other)))); + } + + void push_front(const pointer &mem) + { this->MultiallocationChain::push_front(mem); } + + void push_back(const pointer &mem) + { return this->MultiallocationChain::push_back(mem); } + + void swap(transform_multiallocation_chain &other_chain) + { this->MultiallocationChain::swap(other_chain); } + + void splice_after(iterator after_this, transform_multiallocation_chain &x, iterator before_b, iterator before_e, size_type n) + { this->MultiallocationChain::splice_after(after_this.base(), x, before_b.base(), before_e.base(), n); } + + void incorporate_after(iterator after_this, pointer b, pointer before_e, size_type n) + { this->MultiallocationChain::incorporate_after(after_this.base(), b, before_e, n); } + + pointer pop_front() + { return cast(this->MultiallocationChain::pop_front()); } + + bool empty() const + { return this->MultiallocationChain::empty(); } + + iterator before_begin() + { return iterator(this->MultiallocationChain::before_begin()); } + + iterator begin() + { return iterator(this->MultiallocationChain::begin()); } + + iterator last() + { return iterator(this->MultiallocationChain::last()); } + + iterator end() + { return iterator(this->MultiallocationChain::end()); } + + size_type size() const + { return this->MultiallocationChain::size(); } + + void clear() + { this->MultiallocationChain::clear(); } + + iterator insert_after(iterator it, pointer m) + { return iterator(this->MultiallocationChain::insert_after(it.base(), m)); } + + static iterator iterator_to(const pointer &p) + { return iterator(MultiallocationChain::iterator_to(p)); } + + std::pair extract_data() + { + std::pair data(this->MultiallocationChain::extract_data()); + return std::pair(cast(data.first), cast(data.second)); + } +/* + MultiallocationChain &extract_multiallocation_chain() + { return holder_; }*/ +}; + +}}} + +// namespace dtl { +// namespace container { +// namespace boost { + +#include + +#endif //BOOST_CONTAINER_DETAIL_MULTIALLOCATION_CHAIN_HPP diff --git a/src/vendor/boost/container/detail/next_capacity.hpp b/src/vendor/boost/container/detail/next_capacity.hpp new file mode 100644 index 000000000..0ad62ba99 --- /dev/null +++ b/src/vendor/boost/container/detail/next_capacity.hpp @@ -0,0 +1,98 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP +#define BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +// container/detail +#include + +#include + +namespace boost { +namespace container { +namespace dtl { + +template +struct grow_factor_ratio +{ + BOOST_STATIC_ASSERT(Numerator > Denominator); + BOOST_STATIC_ASSERT(Numerator < 100); + BOOST_STATIC_ASSERT(Denominator < 100); + BOOST_STATIC_ASSERT(Denominator == 1 || (0 != Numerator % Denominator)); + + template + SizeType operator()(const SizeType cur_cap, const SizeType add_min_cap, const SizeType max_cap) const + { + const SizeType overflow_limit = ((SizeType)-1) / Numerator; + + SizeType new_cap = 0; + + if(cur_cap <= overflow_limit){ + new_cap = cur_cap * Numerator / Denominator; + } + else if(Denominator == 1 || (SizeType(new_cap = cur_cap) / Denominator) > overflow_limit){ + new_cap = (SizeType)-1; + } + else{ + new_cap *= Numerator; + } + return max_value + ( SizeType(Minimum) + , max_value + ( SizeType(cur_cap+add_min_cap) + , min_value(max_cap, new_cap)) + ); + } +}; + +} //namespace dtl { + +struct growth_factor_50 + : dtl::grow_factor_ratio<0, 3, 2> +{}; + +struct growth_factor_60 + : dtl::grow_factor_ratio<0, 8, 5> +{}; + +struct growth_factor_100 + : dtl::grow_factor_ratio<0, 2, 1> +{}; + +template +BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &, SizeType) +{} + +template +BOOST_CONTAINER_FORCEINLINE void clamp_by_stored_size_type(SizeType &s, SomeStoredSizeType) +{ + if (s >= SomeStoredSizeType(-1) ) + s = SomeStoredSizeType(-1); +} + +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_NEXT_CAPACITY_HPP diff --git a/src/vendor/boost/container/detail/placement_new.hpp b/src/vendor/boost/container/detail/placement_new.hpp new file mode 100644 index 000000000..c50981f68 --- /dev/null +++ b/src/vendor/boost/container/detail/placement_new.hpp @@ -0,0 +1,30 @@ +#ifndef BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP +#define BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +struct boost_container_new_t{}; + +//avoid including +inline void *operator new(std::size_t, void *p, boost_container_new_t) +{ return p; } + +inline void operator delete(void *, void *, boost_container_new_t) +{} + +#endif //BOOST_CONTAINER_DETAIL_PLACEMENT_NEW_HPP diff --git a/src/vendor/boost/container/detail/std_fwd.hpp b/src/vendor/boost/container/detail/std_fwd.hpp new file mode 100644 index 000000000..a25c411e8 --- /dev/null +++ b/src/vendor/boost/container/detail/std_fwd.hpp @@ -0,0 +1,59 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP +#define BOOST_CONTAINER_DETAIL_STD_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +////////////////////////////////////////////////////////////////////////////// +// Standard predeclarations +////////////////////////////////////////////////////////////////////////////// + +#include +BOOST_MOVE_STD_NS_BEG + +template +class allocator; + +template +struct less; + +template +struct equal_to; + +template +struct pair; + +template +struct char_traits; + +struct input_iterator_tag; +struct forward_iterator_tag; +struct bidirectional_iterator_tag; +struct random_access_iterator_tag; + +template +class insert_iterator; + +struct allocator_arg_t; + +struct piecewise_construct_t; + +BOOST_MOVE_STD_NS_END +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_STD_FWD_HPP diff --git a/src/vendor/boost/container/detail/transform_iterator.hpp b/src/vendor/boost/container/detail/transform_iterator.hpp new file mode 100644 index 000000000..ce81813eb --- /dev/null +++ b/src/vendor/boost/container/detail/transform_iterator.hpp @@ -0,0 +1,180 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// (C) Copyright Gennaro Prota 2003 - 2004. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP +#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { +namespace container { + +template +struct operator_arrow_proxy +{ + operator_arrow_proxy(const PseudoReference &px) + : m_value(px) + {} + + typedef PseudoReference element_type; + + PseudoReference* operator->() const { return &m_value; } + + mutable PseudoReference m_value; +}; + +template +struct operator_arrow_proxy +{ + operator_arrow_proxy(T &px) + : m_value(px) + {} + + typedef T element_type; + + T* operator->() const { return const_cast(&m_value); } + + T &m_value; +}; + +template +class transform_iterator + : public UnaryFunction + , public boost::container::iterator + < typename Iterator::iterator_category + , typename dtl::remove_reference::type + , typename Iterator::difference_type + , operator_arrow_proxy + , typename UnaryFunction::result_type> +{ + public: + explicit transform_iterator(const Iterator &it, const UnaryFunction &f = UnaryFunction()) + : UnaryFunction(f), m_it(it) + {} + + explicit transform_iterator() + : UnaryFunction(), m_it() + {} + + //Constructors + transform_iterator& operator++() + { increment(); return *this; } + + transform_iterator operator++(int) + { + transform_iterator result (*this); + increment(); + return result; + } + + friend bool operator== (const transform_iterator& i, const transform_iterator& i2) + { return i.equal(i2); } + + friend bool operator!= (const transform_iterator& i, const transform_iterator& i2) + { return !(i == i2); } + +/* + friend bool operator> (const transform_iterator& i, const transform_iterator& i2) + { return i2 < i; } + + friend bool operator<= (const transform_iterator& i, const transform_iterator& i2) + { return !(i > i2); } + + friend bool operator>= (const transform_iterator& i, const transform_iterator& i2) + { return !(i < i2); } +*/ + friend typename Iterator::difference_type operator- (const transform_iterator& i, const transform_iterator& i2) + { return i2.distance_to(i); } + + //Arithmetic + transform_iterator& operator+=(typename Iterator::difference_type off) + { this->advance(off); return *this; } + + transform_iterator operator+(typename Iterator::difference_type off) const + { + transform_iterator other(*this); + other.advance(off); + return other; + } + + friend transform_iterator operator+(typename Iterator::difference_type off, const transform_iterator& right) + { return right + off; } + + transform_iterator& operator-=(typename Iterator::difference_type off) + { this->advance(-off); return *this; } + + transform_iterator operator-(typename Iterator::difference_type off) const + { return *this + (-off); } + + typename UnaryFunction::result_type operator*() const + { return dereference(); } + + operator_arrow_proxy + operator->() const + { return operator_arrow_proxy(dereference()); } + + Iterator & base() + { return m_it; } + + const Iterator & base() const + { return m_it; } + + private: + Iterator m_it; + + void increment() + { ++m_it; } + + void decrement() + { --m_it; } + + bool equal(const transform_iterator &other) const + { return m_it == other.m_it; } + + bool less(const transform_iterator &other) const + { return other.m_it < m_it; } + + typename UnaryFunction::result_type dereference() const + { return UnaryFunction::operator()(*m_it); } + + void advance(typename Iterator::difference_type n) + { boost::container::iterator_advance(m_it, n); } + + typename Iterator::difference_type distance_to(const transform_iterator &other)const + { return boost::container::iterator_distance(other.m_it, m_it); } +}; + +template +transform_iterator +make_transform_iterator(Iterator it, UnaryFunc fun) +{ + return transform_iterator(it, fun); +} + +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP diff --git a/src/vendor/boost/container/detail/type_traits.hpp b/src/vendor/boost/container/detail/type_traits.hpp new file mode 100644 index 000000000..b5250d6a1 --- /dev/null +++ b/src/vendor/boost/container/detail/type_traits.hpp @@ -0,0 +1,73 @@ +////////////////////////////////////////////////////////////////////////////// +// (C) Copyright John Maddock 2000. +// (C) Copyright Ion Gaztanaga 2005-2015. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +// The alignment and Type traits implementation comes from +// John Maddock's TypeTraits library. +// +// Some other tricks come from Howard Hinnant's papers and StackOverflow replies +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP +#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace container { +namespace dtl { + +using ::boost::move_detail::enable_if; +using ::boost::move_detail::enable_if_and; +using ::boost::move_detail::is_same; +using ::boost::move_detail::is_different; +using ::boost::move_detail::is_pointer; +using ::boost::move_detail::add_reference; +using ::boost::move_detail::add_const; +using ::boost::move_detail::add_const_reference; +using ::boost::move_detail::remove_const; +using ::boost::move_detail::remove_reference; +using ::boost::move_detail::remove_cvref; +using ::boost::move_detail::make_unsigned; +using ::boost::move_detail::is_floating_point; +using ::boost::move_detail::is_integral; +using ::boost::move_detail::is_enum; +using ::boost::move_detail::is_pod; +using ::boost::move_detail::is_empty; +using ::boost::move_detail::is_trivially_destructible; +using ::boost::move_detail::is_trivially_default_constructible; +using ::boost::move_detail::is_trivially_copy_constructible; +using ::boost::move_detail::is_trivially_move_constructible; +using ::boost::move_detail::is_trivially_copy_assignable; +using ::boost::move_detail::is_trivially_move_assignable; +using ::boost::move_detail::is_nothrow_default_constructible; +using ::boost::move_detail::is_nothrow_copy_constructible; +using ::boost::move_detail::is_nothrow_move_constructible; +using ::boost::move_detail::is_nothrow_copy_assignable; +using ::boost::move_detail::is_nothrow_move_assignable; +using ::boost::move_detail::is_nothrow_swappable; +using ::boost::move_detail::alignment_of; +using ::boost::move_detail::aligned_storage; +using ::boost::move_detail::nat; +using ::boost::move_detail::nat2; +using ::boost::move_detail::nat3; +using ::boost::move_detail::max_align_t; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#endif //#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP diff --git a/src/vendor/boost/container/detail/value_functors.hpp b/src/vendor/boost/container/detail/value_functors.hpp new file mode 100644 index 000000000..961c9a874 --- /dev/null +++ b/src/vendor/boost/container/detail/value_functors.hpp @@ -0,0 +1,42 @@ +#ifndef BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP +#define BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP +/////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2017-2017. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace container { + +//Functors for member algorithm defaults +template +struct value_less +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a < b; } +}; + +template +struct value_equal +{ + bool operator()(const ValueType &a, const ValueType &b) const + { return a == b; } +}; + +} //namespace container { +} //namespace boost { + +#endif //BOOST_CONTAINER_DETAIL_VALUE_FUNCTORS_HPP diff --git a/src/vendor/boost/container/detail/value_init.hpp b/src/vendor/boost/container/detail/value_init.hpp new file mode 100644 index 000000000..35b0aa11d --- /dev/null +++ b/src/vendor/boost/container/detail/value_init.hpp @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP +#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace container { +namespace dtl { + +template +struct value_init +{ + value_init() + : m_t() + {} + + operator T &() { return m_t; } + + T &get() { return m_t; } + + T m_t; +}; + +} //namespace dtl { +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP diff --git a/src/vendor/boost/container/detail/variadic_templates_tools.hpp b/src/vendor/boost/container/detail/variadic_templates_tools.hpp new file mode 100644 index 000000000..4f16fb045 --- /dev/null +++ b/src/vendor/boost/container/detail/variadic_templates_tools.hpp @@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2008-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP +#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +#include +#include //std::size_t + +namespace boost { +namespace container { +namespace dtl { + +template +class tuple; + +template<> class tuple<> +{}; + +template +class tuple + : private tuple +{ + typedef tuple inherited; + + public: + tuple() + : inherited(), m_head() + {} + + template + tuple(U &&u, Args && ...args) + : inherited(::boost::forward(args)...), m_head(::boost::forward(u)) + {} + + // Construct tuple from another tuple. + template + tuple(const tuple& other) + : inherited(other.tail()), m_head(other.head()) + {} + + template + tuple& operator=(const tuple& other) + { + m_head = other.head(); + tail() = other.tail(); + return this; + } + + typename add_reference::type head() { return m_head; } + typename add_reference::type head() const { return m_head; } + + inherited& tail() { return *this; } + const inherited& tail() const { return *this; } + + protected: + Head m_head; +}; + + +template +tuple forward_as_tuple_impl(Values&&... values) +{ return tuple(::boost::forward(values)...); } + +template +struct tuple_element; + +template +struct tuple_element > +{ + typedef typename tuple_element >::type type; +}; + +template +struct tuple_element<0, tuple > +{ + typedef Head type; +}; + +template +class get_impl; + +template +class get_impl > +{ + typedef typename tuple_element >::type Element; + typedef get_impl > Next; + + public: + typedef typename add_reference::type type; + typedef typename add_const_reference::type const_type; + static type get(tuple& t) { return Next::get(t.tail()); } + static const_type get(const tuple& t) { return Next::get(t.tail()); } +}; + +template +class get_impl<0, tuple > +{ + public: + typedef typename add_reference::type type; + typedef typename add_const_reference::type const_type; + static type get(tuple& t) { return t.head(); } + static const_type get(const tuple& t){ return t.head(); } +}; + +template +typename get_impl >::type get(tuple& t) +{ return get_impl >::get(t); } + +template +typename get_impl >::const_type get(const tuple& t) +{ return get_impl >::get(t); } + +//////////////////////////////////////////////////// +// Builds an index_tuple<0, 1, 2, ..., Num-1>, that will +// be used to "unpack" into comma-separated values +// in a function call. +//////////////////////////////////////////////////// + +template struct index_tuple{ typedef index_tuple type; }; + +template struct concat_index_tuple; + +template +struct concat_index_tuple, index_tuple> + : index_tuple{}; + +template struct build_number_seq; + +template +struct build_number_seq + : concat_index_tuple::type + ,typename build_number_seq::type + >::type +{}; + +template<> struct build_number_seq<0> : index_tuple<>{}; +template<> struct build_number_seq<1> : index_tuple<0>{}; + +}}} //namespace boost { namespace container { namespace dtl { + +#include + +#endif //#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP diff --git a/src/vendor/boost/container/detail/version_type.hpp b/src/vendor/boost/container/detail/version_type.hpp new file mode 100644 index 000000000..389606a56 --- /dev/null +++ b/src/vendor/boost/container/detail/version_type.hpp @@ -0,0 +1,101 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// +// This code comes from N1953 document by Howard E. Hinnant +// +////////////////////////////////////////////////////////////////////////////// + + +#ifndef BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP +#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +#include +#include + +namespace boost{ +namespace container { +namespace dtl { + +template +struct version_type + : public dtl::integral_constant +{ + typedef T type; +}; + +namespace impl{ + +template +struct extract_version +{ + typedef typename T::version type; +}; + +template +struct has_version +{ + private: + struct two {char _[2];}; + template static two test(...); + template static char test(const typename U::version*); + public: + static const bool value = sizeof(test(0)) == 1; + void dummy(){} +}; + +template ::value> +struct version +{ + static const unsigned value = 1; +}; + +template +struct version +{ + static const unsigned value = extract_version::type::value; +}; + +} //namespace impl + +template +struct version + : public dtl::integral_constant::value> +{}; + +template +struct is_version +{ + static const bool value = + is_same< typename version::type, integral_constant >::value; +}; + +} //namespace dtl { + +typedef dtl::integral_constant version_0; +typedef dtl::integral_constant version_1; +typedef dtl::integral_constant version_2; + +} //namespace container { +} //namespace boost{ + +#include + +#endif //#define BOOST_CONTAINER_DETAIL_VERSION_TYPE_HPP diff --git a/src/vendor/boost/container/detail/workaround.hpp b/src/vendor/boost/container/detail/workaround.hpp new file mode 100644 index 000000000..b74e0fc31 --- /dev/null +++ b/src/vendor/boost/container/detail/workaround.hpp @@ -0,0 +1,142 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP +#define BOOST_CONTAINER_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)\ + && !defined(BOOST_INTERPROCESS_DISABLE_VARIADIC_TMPL) + #define BOOST_CONTAINER_PERFECT_FORWARDING +#endif + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && defined(__GXX_EXPERIMENTAL_CXX0X__)\ + && (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40700) + #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST +#endif + +#if defined(BOOST_GCC_VERSION) +# if (BOOST_GCC_VERSION < 40700) || !defined(BOOST_GCC_CXX11) +# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS +# endif +#elif defined(BOOST_MSVC) +# if _MSC_FULL_VER < 180020827 +# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS +# endif +#elif defined(BOOST_CLANG) +# if !__has_feature(cxx_delegating_constructors) +# define BOOST_CONTAINER_NO_CXX11_DELEGATING_CONSTRUCTORS +# endif +#endif + +#if defined(BOOST_MSVC) && (_MSC_VER < 1400) + #define BOOST_CONTAINER_TEMPLATED_CONVERSION_OPERATOR_BROKEN +#endif + +#if !defined(BOOST_NO_CXX11_HDR_TUPLE) || (defined(BOOST_MSVC) && (BOOST_MSVC == 1700 || BOOST_MSVC == 1600)) +#define BOOST_CONTAINER_PAIR_TEST_HAS_HEADER_TUPLE +#endif + +//Macros for documentation purposes. For code, expands to the argument +#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE +#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE + +//Macros for memset optimization. In most platforms +//memsetting pointers and floatings is safe and faster. +// +//If your platform does not offer these guarantees +//define these to value zero. +#ifndef BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_NOT_ZERO +#define BOOST_CONTAINER_MEMZEROED_FLOATING_POINT_IS_ZERO 1 +#endif + +#ifndef BOOST_CONTAINER_MEMZEROED_POINTER_IS_NOT_NULL +#define BOOST_CONTAINER_MEMZEROED_POINTER_IS_NULL +#endif + +#define BOOST_CONTAINER_DOC1ST(TYPE1, TYPE2) TYPE2 +#define BOOST_CONTAINER_I , +#define BOOST_CONTAINER_DOCIGN(T) T +#define BOOST_CONTAINER_DOCONLY(T) + +/* + we need to import/export our code only if the user has specifically + asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost + libraries to be dynamically linked, or BOOST_CONTAINER_DYN_LINK + if they want just this one to be dynamically liked: +*/ +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTAINER_DYN_LINK) + + /* export if this is our own source, otherwise import: */ + #ifdef BOOST_CONTAINER_SOURCE + # define BOOST_CONTAINER_DECL BOOST_SYMBOL_EXPORT + #else + # define BOOST_CONTAINER_DECL BOOST_SYMBOL_IMPORT + + #endif /* BOOST_CONTAINER_SOURCE */ +#else + #define BOOST_CONTAINER_DECL +#endif /* DYN_LINK */ + +//#define BOOST_CONTAINER_DISABLE_FORCEINLINE + +#if defined(BOOST_CONTAINER_DISABLE_FORCEINLINE) + #define BOOST_CONTAINER_FORCEINLINE inline +#elif defined(BOOST_CONTAINER_FORCEINLINE_IS_BOOST_FORCELINE) + #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE +#elif defined(BOOST_MSVC) && defined(_DEBUG) + //"__forceinline" and MSVC seems to have some bugs in debug mode + #define BOOST_CONTAINER_FORCEINLINE inline +#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) + //Older GCCs have problems with forceinline + #define BOOST_CONTAINER_FORCEINLINE inline +#else + #define BOOST_CONTAINER_FORCEINLINE BOOST_FORCEINLINE +#endif + +//#define BOOST_CONTAINER_DISABLE_NOINLINE + +#if defined(BOOST_CONTAINER_DISABLE_NOINLINE) + #define BOOST_CONTAINER_NOINLINE +#else + #define BOOST_CONTAINER_NOINLINE BOOST_NOINLINE +#endif + + +#if !defined(__has_feature) +#define BOOST_CONTAINER_HAS_FEATURE(feature) 0 +#else +#define BOOST_CONTAINER_HAS_FEATURE(feature) __has_feature(feature) +#endif + +//Detect address sanitizer +#if defined(__SANITIZE_ADDRESS__) || BOOST_CONTAINER_HAS_FEATURE(address_sanitizer) +#define BOOST_CONTAINER_ASAN +#endif + + +#if (__cplusplus >= 201703L) + //CTAD supported + #ifdef __INTEL_COMPILER + //Intel compilers do not offer this feature yet + #define BOOST_CONTAINER_NO_CXX17_CTAD + #endif +#else + #define BOOST_CONTAINER_NO_CXX17_CTAD +#endif + +#endif //#ifndef BOOST_CONTAINER_DETAIL_WORKAROUND_HPP diff --git a/src/vendor/boost/container/new_allocator.hpp b/src/vendor/boost/container/new_allocator.hpp new file mode 100644 index 000000000..4801f7082 --- /dev/null +++ b/src/vendor/boost/container/new_allocator.hpp @@ -0,0 +1,194 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_NEW_ALLOCATOR_HPP +#define BOOST_CONTAINER_NEW_ALLOCATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +//!\file + +namespace boost { +namespace container { + +/// @cond + +template +struct new_allocator_bool +{ static const bool value = Value; }; + +template +class new_allocator; + +/// @endcond + +//! Specialization of new_allocator for void types +template<> +class new_allocator +{ + public: + typedef void value_type; + typedef void * pointer; + typedef const void* const_pointer; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) propagate_on_container_move_assignment; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) is_always_equal; + // reference-to-void members are impossible + + //!Obtains an new_allocator that allocates + //!objects of type T2 + template + struct rebind + { + typedef new_allocator< T2> other; + }; + + //!Default constructor + //!Never throws + new_allocator() BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Constructor from other new_allocator. + //!Never throws + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Copy assignment operator from other new_allocator. + //!Never throws + new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { + return *this; + } + + //!Constructor from related new_allocator. + //!Never throws + template + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Swaps two allocators, does nothing + //!because this new_allocator is stateless + friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!An new_allocator always compares to true, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return true; } + + //!An new_allocator always compares to false, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return false; } +}; + + +//! This class is a reduced STL-compatible allocator that allocates memory using operator new +template +class new_allocator +{ + public: + typedef T value_type; + typedef T * pointer; + typedef const T * const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) propagate_on_container_move_assignment; + //!A integral constant of type bool with value true + typedef BOOST_CONTAINER_IMPDEF(new_allocator_bool) is_always_equal; + + //!Obtains an new_allocator that allocates + //!objects of type T2 + template + struct rebind + { + typedef new_allocator other; + }; + + //!Default constructor + //!Never throws + new_allocator() BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Constructor from other new_allocator. + //!Never throws + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Copy assignment operator from other new_allocator. + //!Never throws + new_allocator& operator=(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { + return *this; + } + + //!Constructor from related new_allocator. + //!Never throws + template + new_allocator(const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!Allocates memory for an array of count elements. + //!Throws std::bad_alloc if there is no enough memory + pointer allocate(size_type count) + { + const std::size_t max_count = std::size_t(-1)/(2*sizeof(T)); + if(BOOST_UNLIKELY(count > max_count)) + throw_bad_alloc(); + return static_cast(::operator new(count*sizeof(T))); + } + + //!Deallocates previously allocated memory. + //!Never throws + void deallocate(pointer ptr, size_type) BOOST_NOEXCEPT_OR_NOTHROW + { ::operator delete((void*)ptr); } + + //!Returns the maximum number of elements that could be allocated. + //!Never throws + size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return std::size_t(-1)/(2*sizeof(T)); } + + //!Swaps two allocators, does nothing + //!because this new_allocator is stateless + friend void swap(new_allocator &, new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + {} + + //!An new_allocator always compares to true, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator==(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return true; } + + //!An new_allocator always compares to false, as memory allocated with one + //!instance can be deallocated by another instance + friend bool operator!=(const new_allocator &, const new_allocator &) BOOST_NOEXCEPT_OR_NOTHROW + { return false; } +}; + +} //namespace container { +} //namespace boost { + +#include + +#endif //BOOST_CONTAINER_NEW_ALLOCATOR_HPP diff --git a/src/vendor/boost/container/options.hpp b/src/vendor/boost/container/options.hpp new file mode 100644 index 000000000..893c0df59 --- /dev/null +++ b/src/vendor/boost/container/options.hpp @@ -0,0 +1,562 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_OPTIONS_HPP +#define BOOST_CONTAINER_OPTIONS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { +namespace container { + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR ASSOCIATIVE TREE-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +//! Enumeration used to configure ordered associative containers +//! with a concrete tree implementation. +enum tree_type_enum +{ + red_black_tree, + avl_tree, + scapegoat_tree, + splay_tree +}; + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct tree_opt +{ + static const boost::container::tree_type_enum tree_type = TreeType; + static const bool optimize_size = OptimizeSize; +}; + +typedef tree_opt tree_assoc_defaults; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This option setter specifies the underlying tree type +//!(red-black, AVL, Scapegoat or Splay) for ordered associative containers +BOOST_INTRUSIVE_OPTION_CONSTANT(tree_type, tree_type_enum, TreeType, tree_type) + +//!This option setter specifies if node size is optimized +//!storing rebalancing data masked into pointers for ordered associative containers +BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::set, \c boost::container::multiset +//! \c boost::container::map and \c boost::container::multimap. +//! Supported options are: \c boost::container::optimize_size and \c boost::container::tree_type +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct tree_assoc_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < tree_assoc_defaults, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef tree_opt implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by tree-based associative containers +template +using tree_assoc_options_t = typename boost::container::tree_assoc_options::type; + +#endif + + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR ASSOCIATIVE HASH-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct hash_opt +{ + static const bool store_hash = StoreHash; +}; + +typedef hash_opt hash_assoc_defaults; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This option setter specifies if node size is optimized +//!storing rebalancing data masked into pointers for ordered associative containers +BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::hash_set, \c boost::container::hash_multiset +//! \c boost::container::hash_map and \c boost::container::hash_multimap. +//! Supported options are: \c boost::container::store_hash +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct hash_assoc_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < hash_assoc_defaults, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef hash_opt implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by hash-based associative containers +template +using hash_assoc_options_t = typename boost::container::hash_assoc_options::type; + +#endif + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR VECTOR-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct default_if_void +{ + typedef T type; +}; + +template +struct default_if_void +{ + typedef Default type; +}; + +#endif + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct get_stored_size_type_with_alloctraits +{ + typedef StoredSizeType type; +}; + +template +struct get_stored_size_type_with_alloctraits +{ + typedef typename AllocTraits::size_type type; +}; + +template +struct vector_opt +{ + typedef GrowthType growth_factor_type; + typedef StoredSizeType stored_size_type; + + template + struct get_stored_size_type + : get_stored_size_type_with_alloctraits + {}; +}; + +class default_next_capacity; + +typedef vector_opt vector_null_opt; + +template +struct devector_opt + : vector_opt +{}; + +typedef devector_opt devector_null_opt; + +#else //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This growth factor argument specifies that the container should increase it's +//!capacity a 50% when existing capacity is exhausted. +struct growth_factor_50{}; + +//!This growth factor argument specifies that the container should increase it's +//!capacity a 60% when existing capacity is exhausted. +struct growth_factor_60{}; + +//!This growth factor argument specifies that the container should increase it's +//!capacity a 100% (doubling its capacity) when existing capacity is exhausted. +struct growth_factor_100{}; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//!This option setter specifies the growth factor strategy of the underlying vector. +//! +//!\tparam GrowthFactor A function object that has the following signature:

    +//!`template`
    +//!`SizeType operator()(SizeType cur_cap, SizeType add_min_cap, SizeType max_cap) const;`.

    +//!`cur_cap` is the current capacity, `add_min_cap` is the minimum additional capacity +//!we want to achieve and `max_cap` is the maximum capacity that the allocator or other +//!factors allow. The implementation should return a value between `cur_cap` + `add_min_cap` +//!and `max_cap`. `cur_cap` + `add_min_cap` is guaranteed not to overflow/wraparound, +//! but the implementation should handle wraparound produced by the growth factor. +//! +//!Predefined growth factors that can be passed as arguments to this option are: +//!\c boost::container::growth_factor_50 +//!\c boost::container::growth_factor_60 +//!\c boost::container::growth_factor_100 +//! +//!If this option is not specified, a default will be used by the container. +BOOST_INTRUSIVE_OPTION_TYPE(growth_factor, GrowthFactor, GrowthFactor, growth_factor_type) + +//!This option specifies the unsigned integer type that a user wants the container +//!to use to hold size-related information inside a container (e.g. current size, current capacity). +//! +//!\tparam StoredSizeType An unsigned integer type. It shall be smaller than than the size +//! of the size_type deduced from `allocator_traits::size_type` or the same type. +//! +//!If the maximum capacity() to be used is limited, a user can try to use 8-bit, 16-bit +//!(e.g. in 32-bit machines), or 32-bit size types (e.g. in a 64 bit machine) to see if some +//!memory can be saved for empty vectors. This could potentially performance benefits due to better +//!cache usage. +//! +//!Note that alignment requirements can disallow theoretical space savings. Example: +//!\c vector holds a pointer and two size types (for size and capacity), in a 32 bit machine +//!a 8 bit size type (total size: 4 byte pointer + 2 x 1 byte sizes = 6 bytes) +//!will not save space when comparing two 16-bit size types because usually +//!a 32 bit alignment is required for vector and the size will be rounded to 8 bytes. In a 64-bit +//!machine a 16 bit size type does not usually save memory when comparing to a 32-bit size type. +//!Measure the size of the resulting container and do not assume a smaller \c stored_size +//!will always lead to a smaller sizeof(container). +//! +//!If a user tries to insert more elements than representable by \c stored_size, vector +//!will throw a length_error. +//! +//!If this option is not specified, `allocator_traits::size_type` (usually std::size_t) will +//!be used to store size-related information inside the container. +BOOST_INTRUSIVE_OPTION_TYPE(stored_size, StoredSizeType, StoredSizeType, stored_size_type) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct vector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < vector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef vector_opt< typename packed_options::growth_factor_type + , typename packed_options::stored_size_type> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template +using vector_options_t = typename boost::container::vector_options::type; + +#endif + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR SMALL-VECTOR CONTAINER +// +// +//////////////////////////////////////////////////////////////// + +//! This option specifies the desired alignment for the value_type stored +//! in the container. +//! A value zero represents the natural alignment. +//! +//!\tparam Alignment An unsigned integer value. Must be power of two. +BOOST_INTRUSIVE_OPTION_CONSTANT(inplace_alignment, std::size_t, Alignment, inplace_alignment) + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct small_vector_opt +{ + typedef GrowthType growth_factor_type; + static const std::size_t inplace_alignment = InplaceAlignment; +}; + +typedef small_vector_opt small_vector_null_opt; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::small_vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::inplace_alignment +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct small_vector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < small_vector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef small_vector_opt< typename packed_options::growth_factor_type + , packed_options::inplace_alignment> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::small_vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template +using small_vector_options_t = typename boost::container::small_vector_options::type; + +#endif + + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR STATIC-VECTOR CONTAINER +// +// +//////////////////////////////////////////////////////////////// + +//!This option specifies if the container will throw if in +//!the static capacity is not sufficient to hold the required +//!values. If false is specified, insufficient capacity will +//!lead to BOOST_ASSERT, and if this assertion returns, to undefined behaviour, +//!which potentially can lead to better static_vector performance. +//!The default value is true. +//! +//!\tparam ThrowOnExhaustion A boolean value. True if throw is required. +BOOST_INTRUSIVE_OPTION_CONSTANT(throw_on_overflow, bool, ThrowOnOverflow, throw_on_overflow) + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct static_vector_opt +{ + static const bool throw_on_overflow = ThrowOnOverflow; + static const std::size_t inplace_alignment = InplaceAlignment; +}; + +typedef static_vector_opt static_vector_null_opt; + +#endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::static_vector. +//! Supported options are: \c boost::container::throw_on_overflow and \c boost::container::inplace_alignment +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct static_vector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < static_vector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef static_vector_opt< packed_options::throw_on_overflow + , packed_options::inplace_alignment> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::static_vector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template +using static_vector_options_t = typename boost::container::static_vector_options::type; + +#endif + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::devector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct devector_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < devector_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef devector_opt< typename packed_options::growth_factor_type + , typename packed_options::stored_size_type> implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::devector. +//! Supported options are: \c boost::container::growth_factor and \c boost::container::stored_size +template +using devector_options_t = typename boost::container::devector_options::type; + +#endif + +//////////////////////////////////////////////////////////////// +// +// +// OPTIONS FOR DEQUE-BASED CONTAINERS +// +// +//////////////////////////////////////////////////////////////// + +#if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + +template +struct deque_opt +{ + static const std::size_t block_bytes = BlockBytes; + static const std::size_t block_size = BlockSize; + BOOST_STATIC_ASSERT_MSG(!(block_bytes && block_size), "block_bytes and block_size can't be specified at the same time"); +}; + +typedef deque_opt<0u, 0u> deque_null_opt; + +#endif + +//! Helper metafunction to combine options into a single type to be used +//! by \c boost::container::deque. +//! Supported options are: \c boost::container::block_bytes +#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) || defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) +template +#else +template +#endif +struct deque_options +{ + /// @cond + typedef typename ::boost::intrusive::pack_options + < deque_null_opt, + #if !defined(BOOST_CONTAINER_VARIADIC_TEMPLATES) + O1, O2, O3, O4 + #else + Options... + #endif + >::type packed_options; + typedef deque_opt< packed_options::block_bytes, packed_options::block_size > implementation_defined; + /// @endcond + typedef implementation_defined type; +}; + +#if !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + +//! Helper alias metafunction to combine options into a single type to be used +//! by \c boost::container::deque. +//! Supported options are: \c boost::container::block_bytes +template +using deque_options_t = typename boost::container::deque_options::type; + +#endif + +//!This option specifies the maximum size of a block in bytes: this delimites the number of contiguous elements +//!that will be allocated by deque as min(1u, BlockBytes/sizeof(value_type)) +//!A value zero represents the default value. +//! +//!\tparam BlockBytes An unsigned integer value. +BOOST_INTRUSIVE_OPTION_CONSTANT(block_bytes, std::size_t, BlockBytes, block_bytes) + +//!This option specifies the size of a block, delimites the number of contiguous elements +//!that will be allocated by deque as BlockSize. +//!A value zero represents the default value. +//! +//!\tparam BlockBytes An unsigned integer value. +BOOST_INTRUSIVE_OPTION_CONSTANT(block_size, std::size_t, BlockSize, block_size) + +} //namespace container { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_CONTAINER_OPTIONS_HPP diff --git a/src/vendor/boost/container/stable_vector.hpp b/src/vendor/boost/container/stable_vector.hpp new file mode 100644 index 000000000..55809573b --- /dev/null +++ b/src/vendor/boost/container/stable_vector.hpp @@ -0,0 +1,2200 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2008-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +// Stable vector. +// +// Copyright 2008 Joaquin M Lopez Munoz. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_STABLE_VECTOR_HPP +#define BOOST_CONTAINER_STABLE_VECTOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +#include +#include //new_allocator +#include +// container/detail +#include +#include //algo_equal(), algo_lexicographical_compare +#include +#include +#include +#include +#include +#include +#include +#include +// intrusive +#include +// intrusive/detail +#include //pair +// move +#include +#include +#include +// move/detail +#include +// other +#include +#include +// std +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include +#endif + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + #include + //#define STABLE_VECTOR_ENABLE_INVARIANT_CHECKING +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace stable_vector_detail{ + +template +class clear_on_destroy +{ + public: + BOOST_CONTAINER_FORCEINLINE clear_on_destroy(C &c) + : c_(c), do_clear_(true) + {} + + BOOST_CONTAINER_FORCEINLINE void release() + { do_clear_ = false; } + + BOOST_CONTAINER_FORCEINLINE ~clear_on_destroy() + { + if(do_clear_){ + c_.clear(); + c_.priv_clear_pool(); + } + } + + private: + clear_on_destroy(const clear_on_destroy &); + clear_on_destroy &operator=(const clear_on_destroy &); + C &c_; + bool do_clear_; +}; + +template +struct node; + +template +struct node_base +{ + private: + typedef typename boost::intrusive:: + pointer_traits void_ptr_traits; + typedef typename void_ptr_traits:: + template rebind_pointer + ::type node_base_ptr; + + public: + typedef typename void_ptr_traits:: + template rebind_pointer + ::type node_base_ptr_ptr; + + public: + BOOST_CONTAINER_FORCEINLINE explicit node_base(const node_base_ptr_ptr &n) + : up(n) + {} + + BOOST_CONTAINER_FORCEINLINE node_base() + : up() + {} + + node_base_ptr_ptr up; +}; + + +template +struct node + : public node_base + ::template + rebind_pointer::type + > +{ + public: + typedef typename ::boost::intrusive::pointer_traits::element_type T; + typedef node_base + ::template + rebind_pointer::type + > hook_type; + + typedef typename boost::container::dtl::aligned_storage + ::value>::type storage_t; + storage_t m_storage; + + BOOST_CONTAINER_FORCEINLINE explicit node(const typename hook_type::node_base_ptr_ptr &n) + : hook_type(n) + {} + + BOOST_CONTAINER_FORCEINLINE node() + {} + + #if defined(BOOST_GCC) && (BOOST_GCC >= 40600) && (BOOST_GCC < 80000) + #pragma GCC diagnostic push + // #pragma GCC diagnostic ignored "-Wstrict-aliasing" + #define BOOST_CONTAINER_DISABLE_ALIASING_WARNING + # endif + + BOOST_CONTAINER_FORCEINLINE T &get_data() + { return *reinterpret_cast(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE const T &get_data() const + { return *reinterpret_cast(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE T *get_data_ptr() + { return reinterpret_cast(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE const T *get_data_ptr() const + { return reinterpret_cast(this->m_storage.data); } + + BOOST_CONTAINER_FORCEINLINE ~node() + { reinterpret_cast(this->m_storage.data)->~T(); } + + #if defined(BOOST_CONTAINER_DISABLE_ALIASING_WARNING) + #pragma GCC diagnostic pop + #undef BOOST_CONTAINER_DISABLE_ALIASING_WARNING + # endif + + BOOST_CONTAINER_FORCEINLINE void destroy_header() + { static_cast(this)->~hook_type(); } +}; + +template +struct index_traits +{ + typedef boost::intrusive:: + pointer_traits + void_ptr_traits; + typedef stable_vector_detail:: + node_base node_base_type; + typedef typename void_ptr_traits::template + rebind_pointer::type node_base_ptr; + typedef typename void_ptr_traits::template + rebind_pointer::type node_base_ptr_ptr; + typedef boost::intrusive:: + pointer_traits node_base_ptr_traits; + typedef boost::intrusive:: + pointer_traits node_base_ptr_ptr_traits; + typedef typename allocator_traits:: + template portable_rebind_alloc + ::type node_base_ptr_allocator; + typedef ::boost::container::vector + index_type; + typedef typename index_type::iterator index_iterator; + typedef typename index_type::const_iterator const_index_iterator; + typedef typename index_type::size_type size_type; + + static const size_type ExtraPointers = 3; + //Stable vector stores metadata at the end of the index (node_base_ptr vector) with additional 3 pointers: + // back() is this->index.back() - ExtraPointers; + // end node index is *(this->index.end() - 3) + // Node cache first is *(this->index.end() - 2); + // Node cache last is this->index.back(); + + BOOST_CONTAINER_FORCEINLINE static node_base_ptr_ptr ptr_to_node_base_ptr(node_base_ptr &n) + { return node_base_ptr_ptr_traits::pointer_to(n); } + + static void fix_up_pointers(index_iterator first, index_iterator last) + { + while(first != last){ + typedef typename index_type::reference node_base_ptr_ref; + node_base_ptr_ref nbp = *first; + nbp->up = index_traits::ptr_to_node_base_ptr(nbp); + ++first; + } + } + + BOOST_CONTAINER_FORCEINLINE static index_iterator get_fix_up_end(index_type &index) + { return index.end() - (ExtraPointers - 1); } + + BOOST_CONTAINER_FORCEINLINE static void fix_up_pointers_from(index_type & index, index_iterator first) + { index_traits::fix_up_pointers(first, index_traits::get_fix_up_end(index)); } + + static void readjust_end_node(index_type &index, node_base_type &end_node) + { + if(!index.empty()){ + index_iterator end_node_it(index_traits::get_fix_up_end(index)); + node_base_ptr &end_node_idx_ref = *(--end_node_it); + end_node_idx_ref = node_base_ptr_traits::pointer_to(end_node); + end_node.up = node_base_ptr_ptr_traits::pointer_to(end_node_idx_ref); + } + else{ + end_node.up = node_base_ptr_ptr(); + } + } + + static void initialize_end_node(index_type &index, node_base_type &end_node, const size_type index_capacity_if_empty) + { + if(index.empty()){ + index.reserve(index_capacity_if_empty + ExtraPointers); + index.resize(ExtraPointers); + node_base_ptr &end_node_ref = *index.data(); + end_node_ref = node_base_ptr_traits::pointer_to(end_node); + end_node.up = index_traits::ptr_to_node_base_ptr(end_node_ref); + } + } + + #ifdef STABLE_VECTOR_ENABLE_INVARIANT_CHECKING + static bool invariants(index_type &index) + { + for( index_iterator it = index.begin() + , it_end = index_traits::get_fix_up_end(index) + ; it != it_end + ; ++it){ + if((*it)->up != index_traits::ptr_to_node_base_ptr(*it)){ + return false; + } + } + return true; + } + #endif //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING +}; + +} //namespace stable_vector_detail + +template +class stable_vector_iterator +{ + typedef boost::intrusive::pointer_traits non_const_ptr_traits; + public: + typedef std::random_access_iterator_tag iterator_category; + typedef typename non_const_ptr_traits::element_type value_type; + typedef typename non_const_ptr_traits::difference_type difference_type; + typedef typename ::boost::container::dtl::if_c + < IsConst + , typename non_const_ptr_traits::template + rebind_pointer::type + , Pointer + >::type pointer; + typedef boost::intrusive::pointer_traits ptr_traits; + typedef typename ptr_traits::reference reference; + + typedef typename non_const_ptr_traits::template + rebind_pointer::type void_ptr; + typedef stable_vector_detail::node node_type; + typedef stable_vector_detail::node_base node_base_type; + typedef typename non_const_ptr_traits::template + rebind_pointer::type node_ptr; + typedef boost::intrusive:: + pointer_traits node_ptr_traits; + typedef typename non_const_ptr_traits::template + rebind_pointer::type node_base_ptr; + typedef typename non_const_ptr_traits::template + rebind_pointer::type node_base_ptr_ptr; + + class nat + { + public: + node_base_ptr node_pointer() const + { return node_base_ptr(); } + }; + typedef typename dtl::if_c< IsConst + , stable_vector_iterator + , nat>::type nonconst_iterator; + + node_base_ptr m_pn; + + public: + + BOOST_CONTAINER_FORCEINLINE explicit stable_vector_iterator(node_base_ptr p) BOOST_NOEXCEPT_OR_NOTHROW + : m_pn(p) + {} + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator() BOOST_NOEXCEPT_OR_NOTHROW + : m_pn() //Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator(const stable_vector_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_pn(other.node_pointer()) + {} + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator(const nonconst_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_pn(other.node_pointer()) + {} + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator & operator=(const stable_vector_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW + { m_pn = other.node_pointer(); return *this; } + + BOOST_CONTAINER_FORCEINLINE node_ptr node_pointer() const BOOST_NOEXCEPT_OR_NOTHROW + { return node_ptr_traits::static_cast_from(m_pn); } + + public: + //Pointer like operators + BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW + { return node_pointer()->get_data(); } + + BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW + { return ptr_traits::pointer_to(this->operator*()); } + + //Increment / Decrement + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW + { + node_base_ptr_ptr p(this->m_pn->up); + this->m_pn = *(++p); + return *this; + } + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW + { stable_vector_iterator tmp(*this); ++*this; return stable_vector_iterator(tmp); } + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW + { + node_base_ptr_ptr p(this->m_pn->up); + this->m_pn = *(--p); + return *this; + } + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW + { stable_vector_iterator tmp(*this); --*this; return stable_vector_iterator(tmp); } + + BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW + { return node_ptr_traits::static_cast_from(this->m_pn->up[off])->get_data(); } + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { + if(off) this->m_pn = this->m_pn->up[off]; + return *this; + } + + BOOST_CONTAINER_FORCEINLINE friend stable_vector_iterator operator+(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { + stable_vector_iterator tmp(left); + tmp += off; + return tmp; + } + + BOOST_CONTAINER_FORCEINLINE friend stable_vector_iterator operator+(difference_type off, const stable_vector_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW + { + stable_vector_iterator tmp(right); + tmp += off; + return tmp; + } + + BOOST_CONTAINER_FORCEINLINE stable_vector_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { *this += -off; return *this; } + + BOOST_CONTAINER_FORCEINLINE friend stable_vector_iterator operator-(const stable_vector_iterator &left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { + stable_vector_iterator tmp(left); + tmp -= off; + return tmp; + } + + BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const stable_vector_iterator &left, const stable_vector_iterator &right) BOOST_NOEXCEPT_OR_NOTHROW + { return left.m_pn->up - right.m_pn->up; } + + //Comparison operators + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_pn == r.m_pn; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_pn != r.m_pn; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_pn->up < r.m_pn->up; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_pn->up <= r.m_pn->up; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_pn->up > r.m_pn->up; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const stable_vector_iterator& l, const stable_vector_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_pn->up >= r.m_pn->up; } +}; + + #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) + + #define BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT \ + invariant_checker BOOST_JOIN(check_invariant_,__LINE__)(*this); \ + BOOST_JOIN(check_invariant_,__LINE__).touch(); + + #else //STABLE_VECTOR_ENABLE_INVARIANT_CHECKING + + #define BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT + + #endif //#if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! Originally developed by Joaquin M. Lopez Munoz, stable_vector is a std::vector +//! drop-in replacement implemented as a node container, offering iterator and reference +//! stability. +//! +//! Here are the details taken from the author's blog +//! ( +//! Introducing stable_vector): +//! +//! We present stable_vector, a fully STL-compliant stable container that provides +//! most of the features of std::vector except element contiguity. +//! +//! General properties: stable_vector satisfies all the requirements of a container, +//! a reversible container and a sequence and provides all the optional operations +//! present in std::vector. Like std::vector, iterators are random access. +//! stable_vector does not provide element contiguity; in exchange for this absence, +//! the container is stable, i.e. references and iterators to an element of a stable_vector +//! remain valid as long as the element is not erased, and an iterator that has been +//! assigned the return value of end() always remain valid until the destruction of +//! the associated stable_vector. +//! +//! Operation complexity: The big-O complexities of stable_vector operations match +//! exactly those of std::vector. In general, insertion/deletion is constant time at +//! the end of the sequence and linear elsewhere. Unlike std::vector, stable_vector +//! does not internally perform any value_type destruction, copy or assignment +//! operations other than those exactly corresponding to the insertion of new +//! elements or deletion of stored elements, which can sometimes compensate in terms +//! of performance for the extra burden of doing more pointer manipulation and an +//! additional allocation per element. +//! +//! Exception safety: As stable_vector does not internally copy elements around, some +//! operations provide stronger exception safety guarantees than in std::vector. +//! +//! \tparam T The type of object that is stored in the stable_vector +//! \tparam Allocator The allocator used for all internal memory management +#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED +template +#else +template +#endif +class stable_vector +{ + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + typedef typename real_allocator::type ValueAllocator; + typedef allocator_traits allocator_traits_type; + typedef boost::intrusive:: + pointer_traits + ptr_traits; + typedef typename ptr_traits:: + template rebind_pointer::type void_ptr; + typedef typename allocator_traits_type:: + template portable_rebind_alloc + ::type void_allocator_type; + typedef stable_vector_detail::index_traits + index_traits_type; + typedef typename index_traits_type::node_base_type node_base_type; + typedef typename index_traits_type::node_base_ptr node_base_ptr; + typedef typename index_traits_type:: + node_base_ptr_ptr node_base_ptr_ptr; + typedef typename index_traits_type:: + node_base_ptr_traits node_base_ptr_traits; + typedef typename index_traits_type:: + node_base_ptr_ptr_traits node_base_ptr_ptr_traits; + typedef typename index_traits_type::index_type index_type; + typedef typename index_traits_type::index_iterator index_iterator; + typedef typename index_traits_type:: + const_index_iterator const_index_iterator; + typedef stable_vector_detail::node + node_type; + typedef typename ptr_traits::template + rebind_pointer::type node_ptr; + typedef boost::intrusive:: + pointer_traits node_ptr_traits; + typedef typename ptr_traits::template + rebind_pointer::type const_node_ptr; + typedef boost::intrusive:: + pointer_traits const_node_ptr_traits; + typedef typename node_ptr_traits::reference node_reference; + typedef typename const_node_ptr_traits::reference const_node_reference; + + typedef ::boost::container::dtl::integral_constant + ::value> alloc_version; + typedef typename allocator_traits_type:: + template portable_rebind_alloc + ::type node_allocator_type; + + typedef ::boost::container::dtl:: + allocator_version_traits allocator_version_traits_t; + typedef typename allocator_version_traits_t::multiallocation_chain multiallocation_chain; + + BOOST_CONTAINER_FORCEINLINE node_ptr allocate_one() + { return allocator_version_traits_t::allocate_one(this->priv_node_alloc()); } + + BOOST_CONTAINER_FORCEINLINE void deallocate_one(const node_ptr &p) + { allocator_version_traits_t::deallocate_one(this->priv_node_alloc(), p); } + + BOOST_CONTAINER_FORCEINLINE void allocate_individual(typename allocator_traits_type::size_type n, multiallocation_chain &m) + { allocator_version_traits_t::allocate_individual(this->priv_node_alloc(), n, m); } + + BOOST_CONTAINER_FORCEINLINE void deallocate_individual(multiallocation_chain &holder) + { allocator_version_traits_t::deallocate_individual(this->priv_node_alloc(), holder); } + + friend class stable_vector_detail::clear_on_destroy; + typedef stable_vector_iterator + < typename allocator_traits::pointer + , false> iterator_impl; + typedef stable_vector_iterator + < typename allocator_traits::pointer + , true> const_iterator_impl; + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + public: + + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef T value_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + typedef typename ::boost::container::allocator_traits::const_pointer const_pointer; + typedef typename ::boost::container::allocator_traits::reference reference; + typedef typename ::boost::container::allocator_traits::const_reference const_reference; + typedef typename ::boost::container::allocator_traits::size_type size_type; + typedef typename ::boost::container::allocator_traits::difference_type difference_type; + typedef ValueAllocator allocator_type; + typedef node_allocator_type stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(iterator_impl) iterator; + typedef BOOST_CONTAINER_IMPDEF(const_iterator_impl) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + private: + BOOST_COPYABLE_AND_MOVABLE(stable_vector) + static const size_type ExtraPointers = index_traits_type::ExtraPointers; + + class insert_rollback; + friend class insert_rollback; + + class push_back_rollback; + friend class push_back_rollback; + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + public: + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// + + //! Effects: Default constructs a stable_vector. + //! + //! Throws: If allocator_type's default constructor throws. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE stable_vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : internal_data(), index() + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + } + + //! Effects: Constructs a stable_vector taking the allocator as parameter. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE explicit stable_vector(const allocator_type& al) BOOST_NOEXCEPT_OR_NOTHROW + : internal_data(al), index(al) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + } + + //! Effects: Constructs a stable_vector + //! and inserts n value initialized values. + //! + //! Throws: If allocator_type's default constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + explicit stable_vector(size_type n) + : internal_data(), index() + { + stable_vector_detail::clear_on_destroy cod(*this); + this->resize(n); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Constructs a stable_vector + //! and inserts n default initialized values. + //! + //! Throws: If allocator_type's default constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Non-standard extension + stable_vector(size_type n, default_init_t) + : internal_data(), index() + { + stable_vector_detail::clear_on_destroy cod(*this); + this->resize(n, default_init); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Constructs a stable_vector that will use a copy of allocator a + //! and inserts n value initialized values. + //! + //! Throws: If allocator_type's default constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + explicit stable_vector(size_type n, const allocator_type &a) + : internal_data(), index(a) + { + stable_vector_detail::clear_on_destroy cod(*this); + this->resize(n); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Constructs a stable_vector that will use a copy of allocator a + //! and inserts n default initialized values. + //! + //! Throws: If allocator_type's default constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Non-standard extension + stable_vector(size_type n, default_init_t, const allocator_type &a) + : internal_data(), index(a) + { + stable_vector_detail::clear_on_destroy cod(*this); + this->resize(n, default_init); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Constructs a stable_vector that will use a copy of allocator a + //! and inserts n copies of value. + //! + //! Throws: If allocator_type's default constructor + //! throws or T's default or copy constructor throws. + //! + //! Complexity: Linear to n. + stable_vector(size_type n, const T& t, const allocator_type& al = allocator_type()) + : internal_data(al), index(al) + { + stable_vector_detail::clear_on_destroy cod(*this); + this->insert(this->cend(), n, t); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Constructs a stable_vector that will use a copy of allocator a + //! and inserts a copy of the range [first, last) in the stable_vector. + //! + //! Throws: If allocator_type's default constructor + //! throws or T's constructor taking a dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + stable_vector(InputIterator first,InputIterator last, const allocator_type& al = allocator_type()) + : internal_data(al), index(al) + { + stable_vector_detail::clear_on_destroy cod(*this); + this->insert(this->cend(), first, last); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Copy constructs a stable_vector. + //! + //! Postcondition: x == *this. + //! + //! Complexity: Linear to the elements x contains. + stable_vector(const stable_vector& x) + : internal_data(allocator_traits:: + select_on_container_copy_construction(x.priv_node_alloc())) + , index(allocator_traits:: + select_on_container_copy_construction(x.index.get_stored_allocator())) + { + stable_vector_detail::clear_on_destroy cod(*this); + this->insert(this->cend(), x.begin(), x.end()); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Constructs a stable_vector that will use a copy of allocator a + //! and inserts a copy of the range [il.begin(), il.last()) in the stable_vector + //! + //! Throws: If allocator_type's default constructor + //! throws or T's constructor taking a dereferenced initializer_list iterator throws. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + stable_vector(std::initializer_list il, const allocator_type& l = allocator_type()) + : internal_data(l), index(l) + { + stable_vector_detail::clear_on_destroy cod(*this); + insert(cend(), il.begin(), il.end()); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } +#endif + + //! Effects: Move constructor. Moves x's resources to *this. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE stable_vector(BOOST_RV_REF(stable_vector) x) BOOST_NOEXCEPT_OR_NOTHROW + : internal_data(boost::move(x.priv_node_alloc())), index(boost::move(x.index)) + { + this->priv_swap_members(x); + } + + //! Effects: Copy constructs a stable_vector using the specified allocator. + //! + //! Postcondition: x == *this. + //! + //! Complexity: Linear to the elements x contains. + stable_vector(const stable_vector& x, const allocator_type &a) + : internal_data(a), index(a) + { + stable_vector_detail::clear_on_destroy cod(*this); + this->insert(this->cend(), x.begin(), x.end()); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + + //! Effects: Move constructor using the specified allocator. + //! Moves x's resources to *this. + //! + //! Throws: If allocator_type's copy constructor throws. + //! + //! Complexity: Constant if a == x.get_allocator(), linear otherwise + stable_vector(BOOST_RV_REF(stable_vector) x, const allocator_type &a) + : internal_data(a), index(a) + { + if(this->priv_node_alloc() == x.priv_node_alloc()){ + this->index.swap(x.index); + this->priv_swap_members(x); + } + else{ + stable_vector_detail::clear_on_destroy cod(*this); + this->insert(this->cend(), boost::make_move_iterator(x.begin()), boost::make_move_iterator(x.end())); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + cod.release(); + } + } + + //! Effects: Destroys the stable_vector. All stored values are destroyed + //! and used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements. + ~stable_vector() + { + this->clear(); + this->priv_clear_pool(); + } + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to the number of elements in x. + stable_vector& operator=(BOOST_COPY_ASSIGN_REF(stable_vector) x) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + if (BOOST_LIKELY(this != &x)) { + node_allocator_type &this_alloc = this->priv_node_alloc(); + const node_allocator_type &x_alloc = x.priv_node_alloc(); + dtl::bool_ flag; + if(flag && this_alloc != x_alloc){ + this->clear(); + this->shrink_to_fit(); + } + dtl::assign_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag); + dtl::assign_alloc(this->index.get_stored_allocator(), x.index.get_stored_allocator(), flag); + this->assign(x.begin(), x.end()); + } + return *this; + } + + //! Effects: Move assignment. All x's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If allocator_traits_type::propagate_on_container_move_assignment + //! is false and (allocation throws or T's move constructor throws) + //! + //! Complexity: Constant if allocator_traits_type:: + //! propagate_on_container_move_assignment is true or + //! this->get>allocator() == x.get_allocator(). Linear otherwise. + stable_vector& operator=(BOOST_RV_REF(stable_vector) x) + BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value + || allocator_traits_type::is_always_equal::value) + { + //for move constructor, no aliasing (&x != this) is assumed. + if (BOOST_LIKELY(this != &x)) { + node_allocator_type &this_alloc = this->priv_node_alloc(); + node_allocator_type &x_alloc = x.priv_node_alloc(); + const bool propagate_alloc = allocator_traits_type:: + propagate_on_container_move_assignment::value; + dtl::bool_ flag; + const bool allocators_equal = this_alloc == x_alloc; (void)allocators_equal; + //Resources can be transferred if both allocators are + //going to be equal after this function (either propagated or already equal) + if(propagate_alloc || allocators_equal){ + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT + //Destroy objects but retain memory in case x reuses it in the future + this->clear(); + //Move allocator if needed + dtl::move_alloc(this_alloc, x_alloc, flag); + //Take resources + this->index.swap(x.index); + this->priv_swap_members(x); + } + //Else do a one by one move + else{ + this->assign( boost::make_move_iterator(x.begin()) + , boost::make_move_iterator(x.end())); + } + } + return *this; + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Make *this container contains elements from il. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + stable_vector& operator=(std::initializer_list il) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + assign(il.begin(), il.end()); + return *this; + } +#endif + + //! Effects: Assigns the n copies of val to *this. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const T& t) + { + typedef constant_iterator cvalue_iterator; + this->assign(cvalue_iterator(t, n), cvalue_iterator()); + } + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + typename dtl::disable_if_convertible::type + #else + void + #endif + assign(InputIterator first,InputIterator last) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + iterator first1 = this->begin(); + iterator last1 = this->end(); + for ( ; first1 != last1 && first != last; ++first1, ++first) + *first1 = *first; + if (first == last){ + this->erase(first1, last1); + } + else{ + this->insert(last1, first, last); + } + } + +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Assigns the the range [il.begin(), il.end()) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing initializer_list iterator throws. + //! + BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + assign(il.begin(), il.end()); + } +#endif + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE allocator_type get_allocator() const + { return this->priv_node_alloc(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_node_alloc(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_node_alloc(); } + + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// + + //! Effects: Returns an iterator to the first element contained in the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW + { return (this->index.empty()) ? this->end(): iterator(node_ptr_traits::static_cast_from(this->index.front())); } + + //! Effects: Returns a const_iterator to the first element contained in the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW + { return (this->index.empty()) ? this->cend() : const_iterator(node_ptr_traits::static_cast_from(this->index.front())) ; } + + //! Effects: Returns an iterator to the end of the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW + { return iterator(this->priv_get_end_node()); } + + //! Effects: Returns a const_iterator to the end of the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_iterator(this->priv_get_end_node()); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW + { return reverse_iterator(this->end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_reverse_iterator(this->end()); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW + { return reverse_iterator(this->begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_reverse_iterator(this->begin()); } + + //! Effects: Returns a const_iterator to the first element contained in the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->begin(); } + + //! Effects: Returns a const_iterator to the end of the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->end(); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->rbegin(); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend()const BOOST_NOEXCEPT_OR_NOTHROW + { return this->rend(); } + + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + + //! Effects: Returns true if the stable_vector contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->index.size() <= ExtraPointers; } + + //! Effects: Returns the number of the elements contained in the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW + { + const size_type index_size = this->index.size(); + return (index_size - ExtraPointers) & (size_type(0u) -size_type(index_size != 0)); + } + + //! Effects: Returns the largest possible size of the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->index.max_size() - ExtraPointers; } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are value initialized. + //! + //! Throws: If memory allocation throws, or T's value initialization throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type n) + { + typedef value_init_construct_iterator value_init_iterator; + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + if(n > this->size()) + this->insert(this->cend(), value_init_iterator(n - this->size()), value_init_iterator()); + else if(n < this->size()) + this->erase(this->cbegin() + n, this->cend()); + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default initialized. + //! + //! Throws: If memory allocation throws, or T's default initialization throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + //! + //! Note: Non-standard extension + void resize(size_type n, default_init_t) + { + typedef default_init_construct_iterator default_init_iterator; + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + if(n > this->size()) + this->insert(this->cend(), default_init_iterator(n - this->size()), default_init_iterator()); + else if(n < this->size()) + this->erase(this->cbegin() + n, this->cend()); + } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + void resize(size_type n, const T& t) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + if(n > this->size()) + this->insert(this->cend(), n - this->size(), t); + else if(n < this->size()) + this->erase(this->cbegin() + n, this->cend()); + } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { + const size_type index_size = this->index.size(); + BOOST_ASSERT(!index_size || index_size >= ExtraPointers); + const size_type node_extra_capacity = this->internal_data.pool_size; + //Pool count must be less than index capacity, as index is a vector + BOOST_ASSERT(node_extra_capacity <= (this->index.capacity()- index_size)); + const size_type index_offset = + (node_extra_capacity - ExtraPointers) & (size_type(0u) - size_type(index_size != 0)); + return index_size + index_offset; + } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws. + void reserve(size_type n) + { + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + if(n > this->max_size()){ + throw_length_error("stable_vector::reserve max_size() exceeded"); + } + + size_type sz = this->size(); + size_type old_capacity = this->capacity(); + if(n > old_capacity){ + index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, n); + const void * old_ptr = &index[0]; + this->index.reserve(n + ExtraPointers); + bool realloced = &index[0] != old_ptr; + //Fix the pointers for the newly allocated buffer + if(realloced){ + index_traits_type::fix_up_pointers_from(this->index, this->index.begin()); + } + //Now fill pool if data is not enough + if((n - sz) > this->internal_data.pool_size){ + this->priv_increase_pool((n - sz) - this->internal_data.pool_size); + } + } + } + + //! Effects: Tries to deallocate the excess of memory created + //! with previous allocations. The size of the stable_vector is unchanged + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Linear to size(). + void shrink_to_fit() + { + if(this->capacity()){ + //First empty allocated node pool + this->priv_clear_pool(); + //If empty completely destroy the index, let's recover default-constructed state + if(this->empty()){ + this->index.clear(); + this->index.shrink_to_fit(); + this->internal_data.end_node.up = node_base_ptr_ptr(); + } + //Otherwise, try to shrink-to-fit the index and readjust pointers if necessary + else{ + const void* old_ptr = &index[0]; + this->index.shrink_to_fit(); + bool realloced = &index[0] != old_ptr; + //Fix the pointers for the newly allocated buffer + if(realloced){ + index_traits_type::fix_up_pointers_from(this->index, this->index.begin()); + } + } + } + } + + ////////////////////////////////////////////// + // + // element access + // + ////////////////////////////////////////////// + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference front() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return static_cast(*this->index.front()).get_data(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return static_cast(*this->index.front()).get_data(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the last + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference back() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return static_cast(*this->index[this->size()-1u]).get_data(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the last + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return static_cast(*this->index[this->size()-1u]).get_data(); + } + + //! Requires: size() > n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->size() > n); + return static_cast(*this->index[n]).get_data(); + } + + //! Requires: size() > n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->size() > n); + return static_cast(*this->index[n]).get_data(); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->size() >= n); + return (this->index.empty()) ? this->end() : iterator(node_ptr_traits::static_cast_from(this->index[n])); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->size() >= n); + return (this->index.empty()) ? this->cend() : iterator(node_ptr_traits::static_cast_from(this->index[n])); + } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_index_of(p.node_pointer()); } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_index_of(p.node_pointer()); } + + //! Requires: size() > n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + reference at(size_type n) + { + if(n >= this->size()){ + throw_out_of_range("vector::at invalid subscript"); + } + return operator[](n); + } + + //! Requires: size() > n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + const_reference at(size_type n)const + { + if(n >= this->size()){ + throw_out_of_range("vector::at invalid subscript"); + } + return operator[](n); + } + + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the end of the stable_vector. + //! + //! Returns: A reference to the created object. + //! + //! Throws: If memory allocation throws or the in-place constructor throws. + //! + //! Complexity: Amortized constant time. + template + reference emplace_back(Args &&...args) + { + typedef emplace_functor EmplaceFunctor; + typedef emplace_iterator EmplaceIterator; + EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...); + return *this->insert(this->cend(), EmplaceIterator(ef), EmplaceIterator()); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... before p + //! + //! Throws: If memory allocation throws or the in-place constructor throws. + //! + //! Complexity: If p is end(), amortized constant time + //! Linear time otherwise. + template + iterator emplace(const_iterator p, Args && ...args) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + size_type pos_n = p - cbegin(); + typedef emplace_functor EmplaceFunctor; + typedef emplace_iterator EmplaceIterator; + EmplaceFunctor &&ef = EmplaceFunctor(boost::forward(args)...); + this->insert(p, EmplaceIterator(ef), EmplaceIterator()); + return iterator(this->begin() + pos_n); + } + + #else + + #define BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + reference emplace_back(BOOST_MOVE_UREF##N)\ + {\ + typedef emplace_functor##N\ + BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ + typedef emplace_iterator EmplaceIterator;\ + EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\ + return *this->insert(this->cend() , EmplaceIterator(ef), EmplaceIterator());\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + iterator emplace(const_iterator p BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + BOOST_ASSERT(this->priv_in_range_or_end(p));\ + typedef emplace_functor##N\ + BOOST_MOVE_LT##N BOOST_MOVE_TARG##N BOOST_MOVE_GT##N EmplaceFunctor;\ + typedef emplace_iterator EmplaceIterator;\ + EmplaceFunctor ef BOOST_MOVE_LP##N BOOST_MOVE_FWD##N BOOST_MOVE_RP##N;\ + const size_type pos_n = p - this->cbegin();\ + this->insert(p, EmplaceIterator(ef), EmplaceIterator());\ + return this->begin() += pos_n;\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE) + #undef BOOST_CONTAINER_STABLE_VECTOR_EMPLACE_CODE + + #endif // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x at the end of the stable_vector. + //! + //! Throws: If memory allocation throws or + //! T's copy constructor throws. + //! + //! Complexity: Amortized constant time. + void push_back(const T &x); + + //! Effects: Constructs a new element in the end of the stable_vector + //! and moves the resources of x to this new element. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: Amortized constant time. + void push_back(T &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of x before p. + //! + //! Returns: An iterator to the inserted element. + //! + //! Throws: If memory allocation throws or x's copy constructor throws. + //! + //! Complexity: If p is end(), amortized constant time + //! Linear time otherwise. + iterator insert(const_iterator p, const T &x); + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a new element before p with x's resources. + //! + //! Returns: an iterator to the inserted element. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: If p is end(), amortized constant time + //! Linear time otherwise. + iterator insert(const_iterator p, T &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) + #endif + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert n copies of x before p. + //! + //! Returns: an iterator to the first inserted element or p if n is 0. + //! + //! Throws: If memory allocation throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + iterator insert(const_iterator p, size_type n, const T& t) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + typedef constant_iterator cvalue_iterator; + return this->insert(p, cvalue_iterator(t, n), cvalue_iterator()); + } + + //! Requires: p must be a valid iterator of *this. +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [il.begin(), il.end()) range before p. + //! + //! Returns: an iterator to the first inserted element or p if first == last. + //! + //! Complexity: Linear to distance [il.begin(), il.end()). + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, std::initializer_list il) + { + //Position checks done by insert() + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + return insert(p, il.begin(), il.end()); + } +#endif + + //! Requires: pos must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [first, last) range before p. + //! + //! Returns: an iterator to the first inserted element or p if first == last. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws or T's copy constructor throws. + //! + //! Complexity: Linear to distance [first, last). + template + iterator insert(const_iterator p, InputIterator first, InputIterator last + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //Put this as argument instead of the return type as old GCC's like 3.4 + //detect this and the next disable_if_or as overloads + , typename dtl::disable_if_or + < void + , dtl::is_convertible + , dtl::is_not_input_iterator + >::type* = 0 + #endif + ) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + const size_type pos_n = p - this->cbegin(); + for(; first != last; ++first){ + this->emplace(p, *first); + } + return this->begin() + pos_n; + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + template + typename dtl::disable_if_or + < iterator + , dtl::is_convertible + , dtl::is_input_iterator + >::type + insert(const_iterator p, FwdIt first, FwdIt last) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + const size_type num_new = static_cast(boost::container::iterator_distance(first, last)); + const size_type idx = static_cast(p - this->cbegin()); + if(num_new){ + //Fills the node pool and inserts num_new null pointers in idx. + //If a new buffer was needed fixes up pointers up to idx so + //past-new nodes are not aligned until the end of this function + //or in a rollback in case of exception + index_iterator it_past_newly_constructed(this->priv_insert_forward_non_templated(idx, num_new)); + const index_iterator it_past_new(it_past_newly_constructed + num_new); + { + //Prepare rollback + insert_rollback rollback(*this, it_past_newly_constructed, it_past_new); + while(first != last){ + const node_ptr n = this->priv_get_from_pool(); + BOOST_ASSERT(!!n); + //Put it in the index so rollback can return it in pool if construct_in_place throws + *it_past_newly_constructed = n; + //Constructs and fixes up pointers This can throw + this->priv_build_node_from_it(n, it_past_newly_constructed, first); + ++first; + ++it_past_newly_constructed; + } + //rollback.~insert_rollback() called in case of exception + } + //Fix up pointers for past-new nodes (new nodes were fixed during construction) and + //nodes before insertion p in priv_insert_forward_non_templated(...) + index_traits_type::fix_up_pointers_from(this->index, it_past_newly_constructed); + } + return this->begin() + idx; + } + #endif + + //! Effects: Removes the last element from the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + BOOST_CONTAINER_FORCEINLINE void pop_back() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + this->erase(--this->cend()); + } + + //! Effects: Erases the element at p. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements between p and the + //! last element. Constant if p is the last element. + BOOST_CONTAINER_FORCEINLINE iterator erase(const_iterator p) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->priv_in_range(p)); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + const size_type d = p - this->cbegin(); + index_iterator it = this->index.begin() + d; + this->priv_delete_node(p.node_pointer()); + it = this->index.erase(it); + index_traits_type::fix_up_pointers_from(this->index, it); + return iterator(node_ptr_traits::static_cast_from(*it)); + } + + //! Effects: Erases the elements pointed by [first, last). + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the distance between first and last + //! plus linear to the elements between p and the last element. + iterator erase(const_iterator first, const_iterator last) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(first == last || + (first < last && this->priv_in_range(first) && this->priv_in_range_or_end(last))); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + const const_iterator cbeg(this->cbegin()); + const size_type d1 = static_cast(first - cbeg), + d2 = static_cast(last - cbeg); + size_type d_dif = d2 - d1; + if(d_dif){ + multiallocation_chain holder; + const index_iterator it1(this->index.begin() + d1); + const index_iterator it2(it1 + d_dif); + index_iterator it(it1); + while(d_dif--){ + node_base_ptr &nb = *it; + ++it; + node_type &n = *node_ptr_traits::static_cast_from(nb); + this->priv_destroy_node(n); + holder.push_back(node_ptr_traits::pointer_to(n)); + } + this->priv_put_in_pool(holder); + const index_iterator e = this->index.erase(it1, it2); + index_traits_type::fix_up_pointers_from(this->index, e); + } + return iterator(last.node_pointer()); + } + + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + void swap(stable_vector & x) + BOOST_NOEXCEPT_IF( allocator_traits_type::propagate_on_container_swap::value + || allocator_traits_type::is_always_equal::value) + { + BOOST_ASSERT(allocator_traits_type::propagate_on_container_swap::value || + allocator_traits_type::is_always_equal::value || + this->get_stored_allocator() == x.get_stored_allocator()); + BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT; + dtl::bool_ flag; + dtl::swap_alloc(this->priv_node_alloc(), x.priv_node_alloc(), flag); + //vector's allocator is swapped here + this->index.swap(x.index); + this->priv_swap_members(x); + } + + //! Effects: Erases all the elements of the stable_vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the stable_vector. + BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW + { this->erase(this->cbegin(),this->cend()); } + + //! Effects: Returns true if x and y are equal + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator==(const stable_vector& x, const stable_vector& y) + { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } + + //! Effects: Returns true if x and y are unequal + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const stable_vector& x, const stable_vector& y) + { return !(x == y); } + + //! Effects: Returns true if x is less than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator<(const stable_vector& x, const stable_vector& y) + { return ::boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + + //! Effects: Returns true if x is greater than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator>(const stable_vector& x, const stable_vector& y) + { return y < x; } + + //! Effects: Returns true if x is equal or less than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const stable_vector& x, const stable_vector& y) + { return !(y < x); } + + //! Effects: Returns true if x is equal or greater than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const stable_vector& x, const stable_vector& y) + { return !(x < y); } + + //! Effects: x.swap(y) + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE friend void swap(stable_vector& x, stable_vector& y) + { x.swap(y); } + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + private: + + bool priv_in_range(const_iterator pos) const + { + return (this->begin() <= pos) && (pos < this->end()); + } + + BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const + { + return (this->begin() <= pos) && (pos <= this->end()); + } + + BOOST_CONTAINER_FORCEINLINE size_type priv_index_of(node_ptr p) const + { + //Check range + BOOST_ASSERT(this->index.empty() || (this->index.data() <= p->up)); + BOOST_ASSERT(this->index.empty() || p->up <= (this->index.data() + this->index.size())); + return this->index.empty() ? 0 : p->up - this->index.data(); + } + + class insert_rollback + { + public: + + insert_rollback(stable_vector &sv, index_iterator &it_past_constructed, const index_iterator &it_past_new) + : m_sv(sv), m_it_past_constructed(it_past_constructed), m_it_past_new(it_past_new) + {} + + ~insert_rollback() + { + if(m_it_past_constructed != m_it_past_new){ + m_sv.priv_put_in_pool(node_ptr_traits::static_cast_from(*m_it_past_constructed)); + index_iterator e = m_sv.index.erase(m_it_past_constructed, m_it_past_new); + index_traits_type::fix_up_pointers_from(m_sv.index, e); + } + } + + private: + stable_vector &m_sv; + index_iterator &m_it_past_constructed; + const index_iterator &m_it_past_new; + }; + + class push_back_rollback + { + public: + BOOST_CONTAINER_FORCEINLINE push_back_rollback(stable_vector &sv, const node_ptr &p) + : m_sv(sv), m_p(p) + {} + + BOOST_CONTAINER_FORCEINLINE ~push_back_rollback() + { + if(m_p){ + m_sv.priv_put_in_pool(m_p); + } + } + + BOOST_CONTAINER_FORCEINLINE void release() + { m_p = node_ptr(); } + + private: + stable_vector &m_sv; + node_ptr m_p; + }; + + index_iterator priv_insert_forward_non_templated(size_type idx, size_type num_new) + { + index_traits_type::initialize_end_node(this->index, this->internal_data.end_node, num_new); + + //Now try to fill the pool with new data + if(this->internal_data.pool_size < num_new){ + this->priv_increase_pool(num_new - this->internal_data.pool_size); + } + + //Now try to make room in the vector + const node_base_ptr_ptr old_buffer = this->index.data(); + this->index.insert(this->index.begin() + idx, num_new, node_ptr()); + bool new_buffer = this->index.data() != old_buffer; + + //Fix the pointers for the newly allocated buffer + const index_iterator index_beg = this->index.begin(); + if(new_buffer){ + index_traits_type::fix_up_pointers(index_beg, index_beg + idx); + } + return index_beg + idx; + } + + BOOST_CONTAINER_FORCEINLINE bool priv_capacity_bigger_than_size() const + { + return this->index.capacity() > this->index.size() && + this->internal_data.pool_size > 0; + } + + template + void priv_push_back(BOOST_MOVE_CATCH_FWD(U) x) + { + if(BOOST_LIKELY(this->priv_capacity_bigger_than_size())){ + //Enough memory in the pool and in the index + const node_ptr p = this->priv_get_from_pool(); + BOOST_ASSERT(!!p); + { + push_back_rollback rollback(*this, p); + //This might throw + this->priv_build_node_from_convertible(p, ::boost::forward(x)); + rollback.release(); + } + //This can't throw as there is room for a new elements in the index + index_iterator new_index = this->index.insert(this->index.end() - ExtraPointers, p); + index_traits_type::fix_up_pointers_from(this->index, new_index); + } + else{ + this->insert(this->cend(), ::boost::forward(x)); + } + } + + iterator priv_insert(const_iterator p, const value_type &t) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + typedef constant_iterator cvalue_iterator; + return this->insert(p, cvalue_iterator(t, 1), cvalue_iterator()); + } + + iterator priv_insert(const_iterator p, BOOST_RV_REF(T) x) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + typedef repeat_iterator repeat_it; + typedef boost::move_iterator repeat_move_it; + //Just call more general insert(p, size, value) and return iterator + return this->insert(p, repeat_move_it(repeat_it(x, 1)), repeat_move_it(repeat_it())); + } + + void priv_clear_pool() + { + if(!this->index.empty() && this->index.back()){ + node_base_ptr &pool_first_ref = *(this->index.end() - 2); + node_base_ptr &pool_last_ref = this->index.back(); + + multiallocation_chain holder; + holder.incorporate_after( holder.before_begin() + , node_ptr_traits::static_cast_from(pool_first_ref) + , node_ptr_traits::static_cast_from(pool_last_ref) + , internal_data.pool_size); + this->deallocate_individual(holder); + pool_first_ref = pool_last_ref = 0; + this->internal_data.pool_size = 0; + } + } + + void priv_increase_pool(size_type n) + { + node_base_ptr &pool_first_ref = *(this->index.end() - 2); + node_base_ptr &pool_last_ref = this->index.back(); + multiallocation_chain holder; + holder.incorporate_after( holder.before_begin() + , node_ptr_traits::static_cast_from(pool_first_ref) + , node_ptr_traits::static_cast_from(pool_last_ref) + , internal_data.pool_size); + multiallocation_chain m; + this->allocate_individual(n, m); + holder.splice_after(holder.before_begin(), m, m.before_begin(), m.last(), n); + this->internal_data.pool_size += n; + std::pair data(holder.extract_data()); + pool_first_ref = data.first; + pool_last_ref = data.second; + } + + void priv_put_in_pool(const node_ptr &p) + { + node_base_ptr &pool_first_ref = *(this->index.end()-2); + node_base_ptr &pool_last_ref = this->index.back(); + multiallocation_chain holder; + holder.incorporate_after( holder.before_begin() + , node_ptr_traits::static_cast_from(pool_first_ref) + , node_ptr_traits::static_cast_from(pool_last_ref) + , internal_data.pool_size); + holder.push_front(p); + ++this->internal_data.pool_size; + std::pair ret(holder.extract_data()); + pool_first_ref = ret.first; + pool_last_ref = ret.second; + } + + void priv_put_in_pool(multiallocation_chain &ch) + { + node_base_ptr &pool_first_ref = *(this->index.end()-(ExtraPointers-1)); + node_base_ptr &pool_last_ref = this->index.back(); + ch.incorporate_after( ch.before_begin() + , node_ptr_traits::static_cast_from(pool_first_ref) + , node_ptr_traits::static_cast_from(pool_last_ref) + , internal_data.pool_size); + this->internal_data.pool_size = ch.size(); + const std::pair ret(ch.extract_data()); + pool_first_ref = ret.first; + pool_last_ref = ret.second; + } + + node_ptr priv_get_from_pool() + { + //Precondition: index is not empty + BOOST_ASSERT(!this->index.empty()); + node_base_ptr &pool_first_ref = *(this->index.end() - (ExtraPointers-1)); + node_base_ptr &pool_last_ref = this->index.back(); + multiallocation_chain holder; + holder.incorporate_after( holder.before_begin() + , node_ptr_traits::static_cast_from(pool_first_ref) + , node_ptr_traits::static_cast_from(pool_last_ref) + , internal_data.pool_size); + node_ptr ret = holder.pop_front(); + --this->internal_data.pool_size; + if(!internal_data.pool_size){ + pool_first_ref = pool_last_ref = node_ptr(); + } + else{ + const std::pair data(holder.extract_data()); + pool_first_ref = data.first; + pool_last_ref = data.second; + } + return ret; + } + + BOOST_CONTAINER_FORCEINLINE node_base_ptr priv_get_end_node() const + { return node_base_ptr_traits::pointer_to(const_cast(this->internal_data.end_node)); } + + BOOST_CONTAINER_FORCEINLINE void priv_destroy_node(const node_type &n) + { + allocator_traits:: + destroy(this->priv_node_alloc(), &n); + } + + BOOST_CONTAINER_FORCEINLINE void priv_delete_node(const node_ptr &n) + { + this->priv_destroy_node(*n); + this->priv_put_in_pool(n); + } + + template + void priv_build_node_from_it(const node_ptr &p, const index_iterator &up_index, const Iterator &it) + { + node_type *praw = ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) + node_type(index_traits_type::ptr_to_node_base_ptr(*up_index)); + BOOST_TRY{ + //This can throw + boost::container::construct_in_place + ( this->priv_node_alloc() + , praw->get_data_ptr() + , it); + } + BOOST_CATCH(...) { + praw->destroy_header(); + this->priv_node_alloc().deallocate(p, 1); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + template + void priv_build_node_from_convertible(const node_ptr &p, BOOST_FWD_REF(ValueConvertible) value_convertible) + { + node_type *praw = ::new(boost::movelib::iterator_to_raw_pointer(p), boost_container_new_t()) node_type; + BOOST_TRY{ + //This can throw + boost::container::allocator_traits::construct + ( this->priv_node_alloc() + , p->get_data_ptr() + , ::boost::forward(value_convertible)); + } + BOOST_CATCH(...) { + praw->destroy_header(); + this->priv_node_alloc().deallocate(p, 1); + BOOST_RETHROW + } + BOOST_CATCH_END + } + + void priv_swap_members(stable_vector &x) + { + boost::adl_move_swap(this->internal_data.pool_size, x.internal_data.pool_size); + index_traits_type::readjust_end_node(this->index, this->internal_data.end_node); + index_traits_type::readjust_end_node(x.index, x.internal_data.end_node); + } + + #if defined(STABLE_VECTOR_ENABLE_INVARIANT_CHECKING) + bool priv_invariant()const + { + index_type & index_ref = const_cast(this->index); + + const size_type index_size = this->index.size(); + if(!index_size) + return !this->capacity() && !this->size(); + + if(index_size < ExtraPointers) + return false; + + const size_type bucket_extra_capacity = this->index.capacity()- index_size; + const size_type node_extra_capacity = this->internal_data.pool_size; + if(bucket_extra_capacity < node_extra_capacity){ + return false; + } + + if(this->priv_get_end_node() != *(index.end() - ExtraPointers)){ + return false; + } + + if(!index_traits_type::invariants(index_ref)){ + return false; + } + + size_type n = this->capacity() - this->size(); + node_base_ptr &pool_first_ref = *(index_ref.end() - (ExtraPointers-1)); + node_base_ptr &pool_last_ref = index_ref.back(); + multiallocation_chain holder; + holder.incorporate_after( holder.before_begin() + , node_ptr_traits::static_cast_from(pool_first_ref) + , node_ptr_traits::static_cast_from(pool_last_ref) + , internal_data.pool_size); + typename multiallocation_chain::iterator beg(holder.begin()), end(holder.end()); + size_type num_pool = 0; + while(beg != end){ + ++num_pool; + ++beg; + } + return n >= num_pool && num_pool == internal_data.pool_size; + } + + class invariant_checker + { + invariant_checker(const invariant_checker &); + invariant_checker & operator=(const invariant_checker &); + const stable_vector* p; + + public: + invariant_checker(const stable_vector& v):p(&v){} + ~invariant_checker(){BOOST_ASSERT(p->priv_invariant());} + void touch(){} + }; + #endif + + class ebo_holder + : public node_allocator_type + { + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(ebo_holder) + + public: + template + explicit ebo_holder(BOOST_FWD_REF(AllocatorRLValue) a) + : node_allocator_type(boost::forward(a)) + , pool_size(0) + , end_node() + {} + + ebo_holder() + : node_allocator_type() + , pool_size(0) + , end_node() + {} + + size_type pool_size; + node_base_type end_node; + } internal_data; + + node_allocator_type &priv_node_alloc() { return internal_data; } + const node_allocator_type &priv_node_alloc() const { return internal_data; } + + index_type index; + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +}; + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template +stable_vector(InputIterator, InputIterator) -> + stable_vector::value_type>; + +template +stable_vector(InputIterator, InputIterator, Allocator const&) -> + stable_vector::value_type, Allocator>; + +#endif + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +#undef BOOST_CONTAINER_STABLE_VECTOR_CHECK_INVARIANT + +} //namespace container { + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + typedef typename boost::container::stable_vector::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; + +namespace container { + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +}} //namespace boost{ namespace container { + +#include + +#endif //BOOST_CONTAINER_STABLE_VECTOR_HPP diff --git a/src/vendor/boost/container/throw_exception.hpp b/src/vendor/boost/container/throw_exception.hpp new file mode 100644 index 000000000..e2a0f6a47 --- /dev/null +++ b/src/vendor/boost/container/throw_exception.hpp @@ -0,0 +1,176 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2012-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP +#define BOOST_CONTAINER_THROW_EXCEPTION_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +#ifndef BOOST_NO_EXCEPTIONS + #include //for std exception types + #include //for implicit std::string conversion + #include //for std::bad_alloc +#else + #include + #include //for std::abort +#endif + +namespace boost { +namespace container { + +#if defined(BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS) + //The user must provide definitions for the following functions + + BOOST_NORETURN void throw_bad_alloc(); + + BOOST_NORETURN void throw_out_of_range(const char* str); + + BOOST_NORETURN void throw_length_error(const char* str); + + BOOST_NORETURN void throw_logic_error(const char* str); + + BOOST_NORETURN void throw_runtime_error(const char* str); + +#elif defined(BOOST_NO_EXCEPTIONS) + + BOOST_NORETURN inline void throw_bad_alloc() + { + BOOST_ASSERT(!"boost::container bad_alloc thrown"); + std::abort(); + } + + BOOST_NORETURN inline void throw_out_of_range(const char* str) + { + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str); + std::abort(); + } + + BOOST_NORETURN inline void throw_length_error(const char* str) + { + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container length_error thrown", str); + std::abort(); + } + + BOOST_NORETURN inline void throw_logic_error(const char* str) + { + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str); + std::abort(); + } + + BOOST_NORETURN inline void throw_runtime_error(const char* str) + { + boost::ignore_unused(str); + BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str); + std::abort(); + } + +#else //defined(BOOST_NO_EXCEPTIONS) + + //! Exception callback called by Boost.Container when fails to allocate the requested storage space. + //!
      + //!
    • If BOOST_NO_EXCEPTIONS is NOT defined std::bad_alloc() is thrown.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT(!"boost::container bad_alloc thrown") is called + //! and std::abort() if the former returns.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
    • + //!
    + BOOST_NORETURN inline void throw_bad_alloc() + { + throw std::bad_alloc(); + } + + //! Exception callback called by Boost.Container to signal arguments out of range. + //!
      + //!
    • If BOOST_NO_EXCEPTIONS is NOT defined std::out_of_range(str) is thrown.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container out_of_range thrown", str) is called + //! and std::abort() if the former returns.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
    • + //!
    + BOOST_NORETURN inline void throw_out_of_range(const char* str) + { + throw std::out_of_range(str); + } + + //! Exception callback called by Boost.Container to signal errors resizing. + //!
      + //!
    • If BOOST_NO_EXCEPTIONS is NOT defined std::length_error(str) is thrown.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container length_error thrown", str) is called + //! and std::abort() if the former returns.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
    • + //!
    + BOOST_NORETURN inline void throw_length_error(const char* str) + { + throw std::length_error(str); + } + + //! Exception callback called by Boost.Container to report errors in the internal logical + //! of the program, such as violation of logical preconditions or class invariants. + //!
      + //!
    • If BOOST_NO_EXCEPTIONS is NOT defined std::logic_error(str) is thrown.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container logic_error thrown", str) is called + //! and std::abort() if the former returns.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
    • + //!
    + BOOST_NORETURN inline void throw_logic_error(const char* str) + { + throw std::logic_error(str); + } + + //! Exception callback called by Boost.Container to report errors that can only be detected during runtime. + //!
      + //!
    • If BOOST_NO_EXCEPTIONS is NOT defined std::runtime_error(str) is thrown.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS is defined and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS + //! is NOT defined BOOST_ASSERT_MSG(!"boost::container runtime_error thrown", str) is called + //! and std::abort() if the former returns.
    • + //! + //!
    • If BOOST_NO_EXCEPTIONS and BOOST_CONTAINER_USER_DEFINED_THROW_CALLBACKS are defined + //! the user must provide an implementation and the function should not return.
    • + //!
    + BOOST_NORETURN inline void throw_runtime_error(const char* str) + { + throw std::runtime_error(str); + } + +#endif + +}} //namespace boost { namespace container { + +#include + +#endif //#ifndef BOOST_CONTAINER_THROW_EXCEPTION_HPP diff --git a/src/vendor/boost/container/vector.hpp b/src/vendor/boost/container/vector.hpp new file mode 100644 index 000000000..3bf405ad5 --- /dev/null +++ b/src/vendor/boost/container/vector.hpp @@ -0,0 +1,3360 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP +#define BOOST_CONTAINER_CONTAINER_VECTOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +// container +#include +#include +#include //new_allocator +#include +#include +// container detail +#include +#include //equal() +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// intrusive +#include +// move +#include +#include +#include +#include +// move/detail +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#include +#endif +#include +// move/algo +#include +#include +#include +#include +// other +#include +#include +#include + +//std +#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) +#include //for std::initializer_list +#endif + +namespace boost { +namespace container { + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + +template +class vec_iterator +{ + public: + typedef std::random_access_iterator_tag iterator_category; + typedef typename boost::intrusive::pointer_traits::element_type value_type; + typedef typename boost::intrusive::pointer_traits::difference_type difference_type; + typedef typename dtl::if_c + < IsConst + , typename boost::intrusive::pointer_traits::template + rebind_pointer::type + , Pointer + >::type pointer; + typedef typename boost::intrusive::pointer_traits ptr_traits; + typedef typename ptr_traits::reference reference; + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + private: + Pointer m_ptr; + + class nat + { + public: + Pointer get_ptr() const + { return Pointer(); } + }; + typedef typename dtl::if_c< IsConst + , vec_iterator + , nat>::type nonconst_iterator; + + public: + BOOST_CONTAINER_FORCEINLINE const Pointer &get_ptr() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr; } + + BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr() BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr; } + + BOOST_CONTAINER_FORCEINLINE explicit vec_iterator(Pointer ptr) BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr(ptr) + {} + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + public: + + //Constructors + BOOST_CONTAINER_FORCEINLINE vec_iterator() BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr() //Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_CONTAINER_FORCEINLINE vec_iterator(const vec_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr(other.get_ptr()) + {} + + BOOST_CONTAINER_FORCEINLINE vec_iterator(const nonconst_iterator &other) BOOST_NOEXCEPT_OR_NOTHROW + : m_ptr(other.get_ptr()) + {} + + BOOST_CONTAINER_FORCEINLINE vec_iterator & operator=(const vec_iterator& other) BOOST_NOEXCEPT_OR_NOTHROW + { m_ptr = other.get_ptr(); return *this; } + + //Pointer like operators + BOOST_CONTAINER_FORCEINLINE reference operator*() const BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); return *m_ptr; } + + BOOST_CONTAINER_FORCEINLINE pointer operator->() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_ptr; } + + BOOST_CONTAINER_FORCEINLINE reference operator[](difference_type off) const BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); return m_ptr[off]; } + + //Increment / Decrement + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator++() BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); ++m_ptr; return *this; } + + BOOST_CONTAINER_FORCEINLINE vec_iterator operator++(int) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr++); } + + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator--() BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); --m_ptr; return *this; } + + BOOST_CONTAINER_FORCEINLINE vec_iterator operator--(int) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(!!m_ptr); return vec_iterator(m_ptr--); } + + //Arithmetic + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator+=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(m_ptr || !off); m_ptr += off; return *this; } + + BOOST_CONTAINER_FORCEINLINE vec_iterator& operator-=(difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(m_ptr || !off); m_ptr -= off; return *this; } + + BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(const vec_iterator &x, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(x.m_ptr || !off); return vec_iterator(x.m_ptr+off); } + + BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator+(difference_type off, vec_iterator right) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(right.m_ptr || !off); right.m_ptr += off; return right; } + + BOOST_CONTAINER_FORCEINLINE friend vec_iterator operator-(vec_iterator left, difference_type off) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT(left.m_ptr || !off); left.m_ptr -= off; return left; } + + BOOST_CONTAINER_FORCEINLINE friend difference_type operator-(const vec_iterator &left, const vec_iterator& right) BOOST_NOEXCEPT_OR_NOTHROW + { return left.m_ptr - right.m_ptr; } + + //Comparison operators + BOOST_CONTAINER_FORCEINLINE friend bool operator== (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr == r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator!= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr != r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator< (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr < r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator<= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr <= r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator> (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr > r.m_ptr; } + + BOOST_CONTAINER_FORCEINLINE friend bool operator>= (const vec_iterator& l, const vec_iterator& r) BOOST_NOEXCEPT_OR_NOTHROW + { return l.m_ptr >= r.m_ptr; } +}; + +template +struct vector_insert_ordered_cursor +{ + typedef typename iterator_traits::value_type size_type; + typedef typename iterator_traits::reference reference; + + BOOST_CONTAINER_FORCEINLINE vector_insert_ordered_cursor(BiDirPosConstIt posit, BiDirValueIt valueit) + : last_position_it(posit), last_value_it(valueit) + {} + + void operator --() + { + --last_value_it; + --last_position_it; + while(this->get_pos() == size_type(-1)){ + --last_value_it; + --last_position_it; + } + } + + BOOST_CONTAINER_FORCEINLINE size_type get_pos() const + { return *last_position_it; } + + BOOST_CONTAINER_FORCEINLINE reference get_val() + { return *last_value_it; } + + BiDirPosConstIt last_position_it; + BiDirValueIt last_value_it; +}; + +struct initial_capacity_t{}; + +template +BOOST_CONTAINER_FORCEINLINE const Pointer &vector_iterator_get_ptr(const vec_iterator &it) BOOST_NOEXCEPT_OR_NOTHROW +{ return it.get_ptr(); } + +template +BOOST_CONTAINER_FORCEINLINE Pointer &get_ptr(vec_iterator &it) BOOST_NOEXCEPT_OR_NOTHROW +{ return it.get_ptr(); } + +struct vector_uninitialized_size_t {}; +static const vector_uninitialized_size_t vector_uninitialized_size = vector_uninitialized_size_t(); + +template +struct vector_value_traits_base +{ + static const bool trivial_dctr = dtl::is_trivially_destructible::value; + static const bool trivial_dctr_after_move = has_trivial_destructor_after_move::value; +}; + +template +struct vector_value_traits + : public vector_value_traits_base +{ + typedef vector_value_traits_base base_t; + //This is the anti-exception array destructor + //to deallocate values already constructed + typedef typename dtl::if_c + + ,dtl::scoped_destructor_n + >::type ArrayDestructor; + //This is the anti-exception array deallocator + typedef dtl::scoped_array_deallocator ArrayDeallocator; +}; + +//!This struct deallocates and allocated memory +template < class Allocator + , class StoredSizeType + , class AllocatorVersion = typename dtl::version::type + > +struct vector_alloc_holder + : public Allocator +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) + + public: + typedef Allocator allocator_type; + typedef StoredSizeType stored_size_type; + typedef boost::container::allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef typename allocator_traits_type::size_type size_type; + typedef typename allocator_traits_type::value_type value_type; + + BOOST_CONTAINER_FORCEINLINE static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator) + { + (void)propagate_allocator; (void)p; (void)to_alloc; (void)from_alloc; + const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || + !allocator_traits_type::storage_is_unpropagable(from_alloc, p); + return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(from_alloc, to_alloc)); + } + + BOOST_CONTAINER_FORCEINLINE static bool are_swap_propagable(const allocator_type &l_a, pointer l_p, const allocator_type &r_a, pointer r_p, bool const propagate_allocator) + { + (void)propagate_allocator; (void)l_p; (void)r_p; (void)l_a; (void)r_a; + const bool all_storage_propagable = !allocator_traits_type::is_partially_propagable::value || + !(allocator_traits_type::storage_is_unpropagable(l_a, l_p) || allocator_traits_type::storage_is_unpropagable(r_a, r_p)); + return all_storage_propagable && (propagate_allocator || allocator_traits_type::equal(l_a, r_a)); + } + + //Constructor, does not throw + vector_alloc_holder() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : allocator_type(), m_start(), m_size(), m_capacity() + {} + + //Constructor, does not throw + template + explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW + : allocator_type(boost::forward(a)), m_start(), m_size(), m_capacity() + {} + + //Constructor, does not throw + template + vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, SizeType initial_size) + : allocator_type(boost::forward(a)) + , m_start() + //Size is initialized here so vector should only call uninitialized_xxx after this + , m_size(static_cast(initial_size)) + , m_capacity() + { + if (initial_size > size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + else if(initial_size){ + pointer reuse = pointer(); + size_type final_cap = static_cast(initial_size); + m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse); + this->set_stored_capacity(final_cap); + } + } + + //Constructor, does not throw + template + vector_alloc_holder(vector_uninitialized_size_t, SizeType initial_size) + : allocator_type() + , m_start() + //Size is initialized here so vector should only call uninitialized_xxx after this + , m_size(static_cast(initial_size)) + , m_capacity() + { + if (initial_size > size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + else if(initial_size){ + pointer reuse = pointer(); + size_type final_cap = initial_size; + m_start = this->allocation_command(allocate_new, final_cap, final_cap, reuse); + this->set_stored_capacity(final_cap); + } + } + + vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) BOOST_NOEXCEPT_OR_NOTHROW + : allocator_type(BOOST_MOVE_BASE(allocator_type, holder)) + , m_start(holder.m_start) + , m_size(holder.m_size) + , m_capacity(holder.m_capacity) + { + holder.m_start = pointer(); + holder.m_size = holder.m_capacity = 0; + } + + vector_alloc_holder(initial_capacity_t, pointer p, size_type n) + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : allocator_type() + , m_start(p) + , m_size() + //n is guaranteed to fit into stored_size_type + , m_capacity(static_cast(n)) + {} + + template + vector_alloc_holder(initial_capacity_t, pointer p, size_type n, BOOST_FWD_REF(AllocFwd) a) + : allocator_type(::boost::forward(a)) + , m_start(p) + , m_size() + , m_capacity(n) + {} + + BOOST_CONTAINER_FORCEINLINE ~vector_alloc_holder() BOOST_NOEXCEPT_OR_NOTHROW + { + if(this->m_capacity){ + this->deallocate(this->m_start, this->m_capacity); + } + } + + BOOST_CONTAINER_FORCEINLINE void set_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast(s); } + + BOOST_CONTAINER_FORCEINLINE void dec_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size -= static_cast(s); } + + BOOST_CONTAINER_FORCEINLINE void inc_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size += static_cast(s); } + + BOOST_CONTAINER_FORCEINLINE void set_stored_capacity(size_type c) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_capacity = static_cast(c); } + + BOOST_CONTAINER_FORCEINLINE pointer allocation_command(boost::container::allocation_type command, + size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse) + { + typedef typename dtl::version::type alloc_version; + return this->priv_allocation_command(alloc_version(), command, limit_size, prefer_in_recvd_out_size, reuse); + } + + BOOST_CONTAINER_FORCEINLINE pointer allocate(size_type n) + { + const size_type max_alloc = allocator_traits_type::max_size(this->alloc()); + const size_type max = max_alloc <= stored_size_type(-1) ? max_alloc : stored_size_type(-1); + if ( max < n ) + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + + return allocator_traits_type::allocate(this->alloc(), n); + } + + BOOST_CONTAINER_FORCEINLINE void deallocate(const pointer &p, size_type n) + { + allocator_traits_type::deallocate(this->alloc(), p, n); + } + + bool try_expand_fwd(size_type at_least) + { + //There is not enough memory, try to expand the old one + const size_type new_cap = this->capacity() + at_least; + size_type real_cap = new_cap; + pointer reuse = this->start(); + bool const success = !!this->allocation_command(expand_fwd, new_cap, real_cap, reuse); + //Check for forward expansion + if(success){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->capacity(real_cap); + } + return success; + } + + template + size_type next_capacity(size_type additional_objects) const + { + BOOST_ASSERT(additional_objects > size_type(this->m_capacity - this->m_size)); + size_type max = allocator_traits_type::max_size(this->alloc()); + (clamp_by_stored_size_type)(max, stored_size_type()); + const size_type remaining_cap = max - size_type(this->m_capacity); + const size_type min_additional_cap = additional_objects - size_type(this->m_capacity - this->m_size); + + if ( remaining_cap < min_additional_cap ) + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + + return GrowthFactorType()( size_type(this->m_capacity), min_additional_cap, max); + } + + pointer m_start; + stored_size_type m_size; + stored_size_type m_capacity; + + void swap_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW + { + boost::adl_move_swap(this->m_start, x.m_start); + boost::adl_move_swap(this->m_size, x.m_size); + boost::adl_move_swap(this->m_capacity, x.m_capacity); + } + + void steal_resources(vector_alloc_holder &x) BOOST_NOEXCEPT_OR_NOTHROW + { + this->m_start = x.m_start; + this->m_size = x.m_size; + this->m_capacity = x.m_capacity; + x.m_start = pointer(); + x.m_size = x.m_capacity = 0; + } + + BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE const pointer &start() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_start; } + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { return m_capacity; } + BOOST_CONTAINER_FORCEINLINE void start(const pointer &p) BOOST_NOEXCEPT_OR_NOTHROW + { m_start = p; } + BOOST_CONTAINER_FORCEINLINE void capacity(const size_type &c) BOOST_NOEXCEPT_OR_NOTHROW + { BOOST_ASSERT( c <= stored_size_type(-1)); this->set_stored_capacity(c); } + + static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow() + { } + + private: + void priv_first_allocation(size_type cap) + { + if(cap){ + pointer reuse = pointer(); + m_start = this->allocation_command(allocate_new, cap, cap, reuse); + m_capacity = cap; + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + } + } + + BOOST_CONTAINER_FORCEINLINE pointer priv_allocation_command(version_1, boost::container::allocation_type command, + size_type limit_size, + size_type &prefer_in_recvd_out_size, + pointer &reuse) + { + (void)command; + BOOST_ASSERT( (command & allocate_new)); + BOOST_ASSERT(!(command & nothrow_allocation)); + //First detect overflow on smaller stored_size_types + if (limit_size > stored_size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + pointer const p = this->allocate(prefer_in_recvd_out_size); + reuse = pointer(); + return p; + } + + pointer priv_allocation_command(version_2, boost::container::allocation_type command, + size_type limit_size, + size_type &prefer_in_recvd_out_size, + pointer &reuse) + { + //First detect overflow on smaller stored_size_types + if (limit_size > stored_size_type(-1)){ + boost::container::throw_length_error("get_next_capacity, allocator's max size reached"); + } + (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + //Allocate memory + pointer p = this->alloc().allocation_command(command, limit_size, prefer_in_recvd_out_size, reuse); + //If after allocation prefer_in_recvd_out_size is not representable by stored_size_type, truncate it. + (clamp_by_stored_size_type)(prefer_in_recvd_out_size, stored_size_type()); + return p; + } +}; + +//!This struct deallocates and allocated memory +template +struct vector_alloc_holder + : public Allocator +{ + private: + BOOST_MOVABLE_BUT_NOT_COPYABLE(vector_alloc_holder) + + public: + typedef Allocator allocator_type; + typedef boost::container:: + allocator_traits allocator_traits_type; + typedef typename allocator_traits_type::pointer pointer; + typedef typename allocator_traits_type::size_type size_type; + typedef typename allocator_traits_type::value_type value_type; + typedef StoredSizeType stored_size_type; + + template + friend struct vector_alloc_holder; + + //Constructor, does not throw + vector_alloc_holder() + BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : allocator_type(), m_size() + {} + + //Constructor, does not throw + template + explicit vector_alloc_holder(BOOST_FWD_REF(AllocConvertible) a) BOOST_NOEXCEPT_OR_NOTHROW + : allocator_type(boost::forward(a)), m_size() + {} + + //Constructor, does not throw + template + vector_alloc_holder(vector_uninitialized_size_t, BOOST_FWD_REF(AllocConvertible) a, size_type initial_size) + : allocator_type(boost::forward(a)) + , m_size(initial_size) //Size is initialized here... + { + //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor + this->priv_first_allocation(initial_size); + } + + //Constructor, does not throw + vector_alloc_holder(vector_uninitialized_size_t, size_type initial_size) + : allocator_type() + , m_size(initial_size) //Size is initialized here... + { + //... and capacity here, so vector, must call uninitialized_xxx in the derived constructor + this->priv_first_allocation(initial_size); + } + + vector_alloc_holder(BOOST_RV_REF(vector_alloc_holder) holder) + : allocator_type(BOOST_MOVE_BASE(allocator_type, holder)) + , m_size(holder.m_size) //Size is initialized here so vector should only call uninitialized_xxx after this + { + ::boost::container::uninitialized_move_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size, boost::movelib::to_raw_pointer(this->start())); + ::boost::container::destroy_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), m_size); + holder.m_size = 0; + } + + template + vector_alloc_holder(BOOST_RV_REF_BEG vector_alloc_holder BOOST_RV_REF_END holder) + : allocator_type() + , m_size(holder.m_size) //Initialize it to m_size as first_allocation can only succeed or abort + { + //Different allocator type so we must check we have enough storage + const size_type n = holder.m_size; + this->priv_first_allocation(n); + ::boost::container::uninitialized_move_alloc_n + (this->alloc(), boost::movelib::to_raw_pointer(holder.start()), n, boost::movelib::to_raw_pointer(this->start())); + } + + static BOOST_CONTAINER_FORCEINLINE void on_capacity_overflow() + { allocator_type::on_capacity_overflow(); } + + BOOST_CONTAINER_FORCEINLINE void set_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size = static_cast(s); } + + BOOST_CONTAINER_FORCEINLINE void dec_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size -= static_cast(s); } + + BOOST_CONTAINER_FORCEINLINE void inc_stored_size(size_type s) BOOST_NOEXCEPT_OR_NOTHROW + { this->m_size += static_cast(s); } + + BOOST_CONTAINER_FORCEINLINE void priv_first_allocation(size_type cap) + { + if(cap > allocator_type::internal_capacity){ + on_capacity_overflow(); + } + } + + BOOST_CONTAINER_FORCEINLINE void deep_swap(vector_alloc_holder &x) + { + this->priv_deep_swap(x); + } + + template + void deep_swap(vector_alloc_holder &x) + { + typedef typename real_allocator::type other_allocator_type; + if(this->m_size > other_allocator_type::internal_capacity || x.m_size > allocator_type::internal_capacity){ + on_capacity_overflow(); + } + this->priv_deep_swap(x); + } + + BOOST_CONTAINER_FORCEINLINE void swap_resources(vector_alloc_holder &) BOOST_NOEXCEPT_OR_NOTHROW + { //Containers with version 0 allocators can't be moved without moving elements one by one + on_capacity_overflow(); + } + + + BOOST_CONTAINER_FORCEINLINE void steal_resources(vector_alloc_holder &) + { //Containers with version 0 allocators can't be moved without moving elements one by one + on_capacity_overflow(); + } + + BOOST_CONTAINER_FORCEINLINE allocator_type &alloc() BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE const allocator_type &alloc() const BOOST_NOEXCEPT_OR_NOTHROW + { return *this; } + + BOOST_CONTAINER_FORCEINLINE bool try_expand_fwd(size_type at_least) + { return !at_least; } + + BOOST_CONTAINER_FORCEINLINE pointer start() const BOOST_NOEXCEPT_OR_NOTHROW + { return allocator_type::internal_storage(); } + + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { return allocator_type::internal_capacity; } + + stored_size_type m_size; + + private: + + template + void priv_deep_swap(vector_alloc_holder &x) + { + const size_type MaxTmpStorage = sizeof(value_type)*allocator_type::internal_capacity; + value_type *const first_this = boost::movelib::to_raw_pointer(this->start()); + value_type *const first_x = boost::movelib::to_raw_pointer(x.start()); + + if(this->m_size < x.m_size){ + boost::container::deep_swap_alloc_n(this->alloc(), first_this, this->m_size, first_x, x.m_size); + } + else{ + boost::container::deep_swap_alloc_n(this->alloc(), first_x, x.m_size, first_this, this->m_size); + } + boost::adl_move_swap(this->m_size, x.m_size); + } +}; + +struct growth_factor_60; + +template +struct get_vector_opt +{ + typedef vector_opt< typename default_if_void::type + , typename default_if_void::type + > type; +}; + +template +struct get_vector_opt +{ + typedef vector_opt type; +}; + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +//! A vector is a sequence that supports random access to elements, constant +//! time insertion and removal of elements at the end, and linear time insertion +//! and removal of elements at the beginning or in the middle. The number of +//! elements in a vector may vary dynamically; memory management is automatic. +//! +//! \tparam T The type of object that is stored in the vector +//! \tparam A The allocator used for all internal memory management, use void +//! for the default allocator +//! \tparam Options A type produced from \c boost::container::vector_options. +template +class vector +{ +public: + ////////////////////////////////////////////// + // + // types + // + ////////////////////////////////////////////// + typedef T value_type; + typedef BOOST_CONTAINER_IMPDEF + (typename real_allocator::type) allocator_type; + typedef ::boost::container::allocator_traits allocator_traits_t; + typedef typename allocator_traits::pointer pointer; + typedef typename allocator_traits::const_pointer const_pointer; + typedef typename allocator_traits::reference reference; + typedef typename allocator_traits::const_reference const_reference; + typedef typename allocator_traits::size_type size_type; + typedef typename allocator_traits::difference_type difference_type; + typedef allocator_type stored_allocator_type; + typedef BOOST_CONTAINER_IMPDEF(vec_iterator) iterator; + typedef BOOST_CONTAINER_IMPDEF(vec_iterator) const_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) reverse_iterator; + typedef BOOST_CONTAINER_IMPDEF(boost::container::reverse_iterator) const_reverse_iterator; + +private: + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + typedef typename boost::container:: + allocator_traits::size_type alloc_size_type; + typedef typename get_vector_opt::type options_type; + typedef typename options_type::growth_factor_type growth_factor_type; + typedef typename options_type::stored_size_type stored_size_type; + typedef value_less value_less_t; + + //If provided the stored_size option must specify a type that is equal or a type that is smaller. + BOOST_STATIC_ASSERT( (sizeof(stored_size_type) < sizeof(alloc_size_type) || + dtl::is_same::value) ); + + typedef typename dtl::version::type alloc_version; + typedef boost::container::vector_alloc_holder + alloc_holder_t; + + alloc_holder_t m_holder; + + typedef allocator_traits allocator_traits_type; + template + friend class vector; + + + protected: + BOOST_CONTAINER_FORCEINLINE + static bool is_propagable_from(const allocator_type &from_alloc, pointer p, const allocator_type &to_alloc, bool const propagate_allocator) + { return alloc_holder_t::is_propagable_from(from_alloc, p, to_alloc, propagate_allocator); } + + BOOST_CONTAINER_FORCEINLINE + static bool are_swap_propagable( const allocator_type &l_a, pointer l_p + , const allocator_type &r_a, pointer r_p, bool const propagate_allocator) + { return alloc_holder_t::are_swap_propagable(l_a, l_p, r_a, r_p, propagate_allocator); } + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + private: + BOOST_COPYABLE_AND_MOVABLE(vector) + typedef vector_value_traits value_traits; + typedef constant_iterator cvalue_iterator; + + protected: + + BOOST_CONTAINER_FORCEINLINE void steal_resources(vector &x) + { return this->m_holder.steal_resources(x.m_holder); } + + template + BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity, BOOST_FWD_REF(AllocFwd) a) + : m_holder(initial_capacity_t(), initial_memory, capacity, ::boost::forward(a)) + {} + + BOOST_CONTAINER_FORCEINLINE vector(initial_capacity_t, pointer initial_memory, size_type capacity) + : m_holder(initial_capacity_t(), initial_memory, capacity) + {} + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + public: + ////////////////////////////////////////////// + // + // construct/copy/destroy + // + ////////////////////////////////////////////// + + //! Effects: Constructs a vector taking the allocator as parameter. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + vector() BOOST_NOEXCEPT_IF(dtl::is_nothrow_default_constructible::value) + : m_holder() + {} + + //! Effects: Constructs a vector taking the allocator as parameter. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + explicit vector(const allocator_type& a) BOOST_NOEXCEPT_OR_NOTHROW + : m_holder(a) + {} + + //! Effects: Constructs a vector and inserts n value initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's value initialization throws. + //! + //! Complexity: Linear to n. + explicit vector(size_type n) + : m_holder(vector_uninitialized_size, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_value_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n value initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's value initialization throws. + //! + //! Complexity: Linear to n. + explicit vector(size_type n, const allocator_type &a) + : m_holder(vector_uninitialized_size, a, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_value_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n default initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's default initialization throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Non-standard extension + vector(size_type n, default_init_t) + : m_holder(vector_uninitialized_size, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_default_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n default initialized values. + //! + //! Throws: If allocator_type's allocation + //! throws or T's default initialization throws. + //! + //! Complexity: Linear to n. + //! + //! Note: Non-standard extension + vector(size_type n, default_init_t, const allocator_type &a) + : m_holder(vector_uninitialized_size, a, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_default_init_alloc_n + (this->m_holder.alloc(), n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector + //! and inserts n copies of value. + //! + //! Throws: If allocator_type's allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + vector(size_type n, const T& value) + : m_holder(vector_uninitialized_size, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_fill_alloc_n + (this->m_holder.alloc(), value, n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts n copies of value. + //! + //! Throws: If allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to n. + vector(size_type n, const T& value, const allocator_type& a) + : m_holder(vector_uninitialized_size, a, n) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + boost::container::uninitialized_fill_alloc_n + (this->m_holder.alloc(), value, n, this->priv_raw_begin()); + } + + //! Effects: Constructs a vector + //! and inserts a copy of the range [first, last) in the vector. + //! + //! Throws: If allocator_type's allocation + //! throws or T's constructor taking a dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). +// template +// vector(InIt first, InIt last +// BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c +// < dtl::is_convertible::value +// BOOST_MOVE_I dtl::nat >::type * = 0) +// ) -> vector::value_type, new_allocator::value_type>>; + template + vector(InIt first, InIt last + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c + < dtl::is_convertible::value + BOOST_MOVE_I dtl::nat >::type * = 0) + ) + : m_holder() + { this->assign(first, last); } + + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts a copy of the range [first, last) in the vector. + //! + //! Throws: If allocator_type's allocation + //! throws or T's constructor taking a dereferenced InIt throws. + //! + //! Complexity: Linear to the range [first, last). + template + vector(InIt first, InIt last, const allocator_type& a + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_c + < dtl::is_convertible::value + BOOST_MOVE_I dtl::nat >::type * = 0) + ) + : m_holder(a) + { this->assign(first, last); } + + //! Effects: Copy constructs a vector. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocator_type's allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to the elements x contains. + vector(const vector &x) + : m_holder( vector_uninitialized_size + , allocator_traits_type::select_on_container_copy_construction(x.m_holder.alloc()) + , x.size()) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += x.size() != 0; + #endif + ::boost::container::uninitialized_copy_alloc_n + ( this->m_holder.alloc(), x.priv_raw_begin() + , x.size(), this->priv_raw_begin()); + } + + //! Effects: Move constructor. Moves x's resources to *this. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + vector(BOOST_RV_REF(vector) x) BOOST_NOEXCEPT_OR_NOTHROW + : m_holder(boost::move(x.m_holder)) + { BOOST_STATIC_ASSERT((!allocator_traits_type::is_partially_propagable::value)); } + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Constructs a vector that will use a copy of allocator a + //! and inserts a copy of the range [il.begin(), il.last()) in the vector + //! + //! Throws: If T's constructor taking a dereferenced initializer_list iterator throws. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + vector(std::initializer_list il, const allocator_type& a = allocator_type()) + : m_holder(vector_uninitialized_size, a, il.size()) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += il.size() != 0; + #endif + ::boost::container::uninitialized_copy_alloc_n_source + ( this->m_holder.alloc(), il.begin() + , static_cast(il.size()), this->priv_raw_begin()); + } + #endif + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Move constructor. Moves x's resources to *this. + //! + //! Throws: If T's move constructor or allocation throws + //! + //! Complexity: Linear. + //! + //! Note: Non-standard extension to support static_vector + template + vector(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x + , typename dtl::enable_if_c + < dtl::is_version::type, 0>::value>::type * = 0 + ) + : m_holder(boost::move(x.m_holder)) + {} + + #endif //!defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Copy constructs a vector using the specified allocator. + //! + //! Postcondition: x == *this. + //! + //! Throws: If allocation + //! throws or T's copy constructor throws. + //! + //! Complexity: Linear to the elements x contains. + vector(const vector &x, const allocator_type &a) + : m_holder(vector_uninitialized_size, a, x.size()) + { + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += x.size() != 0; + #endif + ::boost::container::uninitialized_copy_alloc_n_source + ( this->m_holder.alloc(), x.priv_raw_begin() + , x.size(), this->priv_raw_begin()); + } + + //! Effects: Move constructor using the specified allocator. + //! Moves x's resources to *this if a == allocator_type(). + //! Otherwise copies values from x to *this. + //! + //! Throws: If allocation or T's copy constructor throws. + //! + //! Complexity: Constant if a == x.get_allocator(), linear otherwise. + vector(BOOST_RV_REF(vector) x, const allocator_type &a) + : m_holder( vector_uninitialized_size, a + //In this allocator move constructor the allocator won't be propagated --v + , is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, false) ? 0 : x.size() + ) + { + //In this allocator move constructor the allocator won't be propagated ---v + if(is_propagable_from(x.get_stored_allocator(), x.m_holder.start(), a, false)){ + this->m_holder.steal_resources(x.m_holder); + } + else{ + const size_type n = x.size(); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + this->num_alloc += n != 0; + #endif + ::boost::container::uninitialized_move_alloc_n_source + ( this->m_holder.alloc(), x.priv_raw_begin() + , n, this->priv_raw_begin()); + } + } + + //! Effects: Destroys the vector. All stored values are destroyed + //! and used memory is deallocated. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements. + ~vector() BOOST_NOEXCEPT_OR_NOTHROW + { + boost::container::destroy_alloc_n + (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size); + //vector_alloc_holder deallocates the data + } + + //! Effects: Makes *this contain the same elements as x. + //! + //! Postcondition: this->size() == x.size(). *this contains a copy + //! of each of x's elements. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to the number of elements in x. + BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_COPY_ASSIGN_REF(vector) x) + { + if (BOOST_LIKELY(&x != this)){ + this->priv_copy_assign(x); + } + return *this; + } + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Make *this container contains elements from il. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + BOOST_CONTAINER_FORCEINLINE vector& operator=(std::initializer_list il) + { + this->assign(il.begin(), il.end()); + return *this; + } + #endif + + //! Effects: Move assignment. All x's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If allocator_traits_type::propagate_on_container_move_assignment + //! is false and (allocation throws or value_type's move constructor throws) + //! + //! Complexity: Constant if allocator_traits_type:: + //! propagate_on_container_move_assignment is true or + //! this->get>allocator() == x.get_allocator(). Linear otherwise. + BOOST_CONTAINER_FORCEINLINE vector& operator=(BOOST_RV_REF(vector) x) + BOOST_NOEXCEPT_IF(allocator_traits_type::propagate_on_container_move_assignment::value + || allocator_traits_type::is_always_equal::value) + { + if (BOOST_LIKELY(&x != this)){ + this->priv_move_assign(boost::move(x)); + } + return *this; + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + + //! Effects: Move assignment. All x's values are transferred to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If move constructor/assignment of T throws or allocation throws + //! + //! Complexity: Linear. + //! + //! Note: Non-standard extension to support static_vector + template + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and + < vector& + , dtl::is_version::type, 0> + , dtl::is_different::type, allocator_type> + >::type + operator=(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x) + { + this->priv_move_assign(boost::move(x)); + return *this; + } + + //! Effects: Copy assignment. All x's values are copied to *this. + //! + //! Postcondition: x.empty(). *this contains a the elements x had + //! before the function. + //! + //! Throws: If move constructor/assignment of T throws or allocation throws + //! + //! Complexity: Linear. + //! + //! Note: Non-standard extension to support static_vector + template + BOOST_CONTAINER_FORCEINLINE typename dtl::enable_if_and + < vector& + , dtl::is_version::type, 0> + , dtl::is_different::type, allocator_type> + >::type + operator=(const vector &x) + { + this->priv_copy_assign(x); + return *this; + } + + #endif + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment or + //! T's constructor/assignment from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(InIt first, InIt last + //Input iterators or version 0 allocator + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or + < void + BOOST_MOVE_I dtl::is_convertible + BOOST_MOVE_I dtl::and_ + < dtl::is_different + BOOST_MOVE_I dtl::is_not_input_iterator + > + >::type * = 0) + ) + { + //Overwrite all elements we can from [first, last) + iterator cur = this->begin(); + const iterator end_it = this->end(); + for ( ; first != last && cur != end_it; ++cur, ++first){ + *cur = *first; + } + + if (first == last){ + //There are no more elements in the sequence, erase remaining + T* const end_pos = this->priv_raw_end(); + const size_type n = static_cast(end_pos - boost::movelib::iterator_to_raw_pointer(cur)); + this->priv_destroy_last_n(n); + } + else{ + //There are more elements in the range, insert the remaining ones + this->insert(this->cend(), first, last); + } + } + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Effects: Assigns the the range [il.begin(), il.end()) to *this. + //! + //! Throws: If memory allocation throws or + //! T's constructor from dereferencing iniializer_list iterator throws. + //! + BOOST_CONTAINER_FORCEINLINE void assign(std::initializer_list il) + { + this->assign(il.begin(), il.end()); + } + #endif + + //! Effects: Assigns the the range [first, last) to *this. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment or + //! T's constructor/assignment from dereferencing InpIt throws. + //! + //! Complexity: Linear to n. + template + void assign(FwdIt first, FwdIt last + //Forward iterators and version > 0 allocator + BOOST_CONTAINER_DOCIGN(BOOST_MOVE_I typename dtl::disable_if_or + < void + BOOST_MOVE_I dtl::is_same + BOOST_MOVE_I dtl::is_convertible + BOOST_MOVE_I dtl::is_input_iterator + >::type * = 0) + ) + { + //For Fwd iterators the standard only requires EmplaceConstructible and assignable from *first + //so we can't do any backwards allocation + const typename iterator_traits::size_type sz = boost::container::iterator_distance(first, last); + if (sz > size_type(-1)){ + boost::container::throw_length_error("vector::assign, FwdIt's max length reached"); + } + + const size_type input_sz = static_cast(sz); + const size_type old_capacity = this->capacity(); + if(input_sz > old_capacity){ //If input range is too big, we need to reallocate + size_type real_cap = 0; + pointer reuse(this->m_holder.start()); + pointer const ret(this->m_holder.allocation_command(allocate_new|expand_fwd, input_sz, real_cap = input_sz, reuse)); + if(!reuse){ //New allocation, just emplace new values + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + pointer const old_p = this->m_holder.start(); + if(old_p){ + this->priv_destroy_all(); + this->m_holder.deallocate(old_p, old_capacity); + } + this->m_holder.start(ret); + this->m_holder.capacity(real_cap); + this->m_holder.m_size = 0; + this->priv_uninitialized_construct_at_end(first, last); + return; + } + else{ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->m_holder.capacity(real_cap); + //Forward expansion, use assignment + back deletion/construction that comes later + } + } + + boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), first, input_sz, this->priv_raw_begin(), this->size()); + m_holder.set_stored_size(input_sz); + } + + //! Effects: Assigns the n copies of val to *this. + //! + //! Throws: If memory allocation throws or + //! T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to n. + BOOST_CONTAINER_FORCEINLINE void assign(size_type n, const value_type& val) + { this->assign(cvalue_iterator(val, n), cvalue_iterator()); } + + //! Effects: Returns a copy of the internal allocator. + //! + //! Throws: If allocator's copy constructor throws. + //! + //! Complexity: Constant. + allocator_type get_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.alloc(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + BOOST_CONTAINER_FORCEINLINE stored_allocator_type &get_stored_allocator() BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.alloc(); } + + //! Effects: Returns a reference to the internal allocator. + //! + //! Throws: Nothing + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension. + BOOST_CONTAINER_FORCEINLINE const stored_allocator_type &get_stored_allocator() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.alloc(); } + + ////////////////////////////////////////////// + // + // iterators + // + ////////////////////////////////////////////// + + //! Effects: Returns an iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE iterator begin() BOOST_NOEXCEPT_OR_NOTHROW + { return iterator(this->m_holder.start()); } + + //! Effects: Returns a const_iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator begin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_iterator(this->m_holder.start()); } + + //! Effects: Returns an iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE iterator end() BOOST_NOEXCEPT_OR_NOTHROW + { + iterator it (this->m_holder.start()); + it += this->m_holder.m_size; + return it; //Adding zero to null pointer is allowed (non-UB) + } + + //! Effects: Returns a const_iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator end() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->cend(); } + + //! Effects: Returns a reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reverse_iterator rbegin() BOOST_NOEXCEPT_OR_NOTHROW + { return reverse_iterator(this->end()); } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->crbegin(); } + + //! Effects: Returns a reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reverse_iterator rend() BOOST_NOEXCEPT_OR_NOTHROW + { return reverse_iterator(this->begin()); } + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator rend() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->crend(); } + + //! Effects: Returns a const_iterator to the first element contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator cbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_iterator(this->m_holder.start()); } + + //! Effects: Returns a const_iterator to the end of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_iterator cend() const BOOST_NOEXCEPT_OR_NOTHROW + { + const_iterator it (this->m_holder.start()); + it += this->m_holder.m_size; + return it; //Adding zero to null pointer is allowed (non-UB) + } + + //! Effects: Returns a const_reverse_iterator pointing to the beginning + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crbegin() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_reverse_iterator(this->end());} + + //! Effects: Returns a const_reverse_iterator pointing to the end + //! of the reversed vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reverse_iterator crend() const BOOST_NOEXCEPT_OR_NOTHROW + { return const_reverse_iterator(this->begin()); } + + ////////////////////////////////////////////// + // + // capacity + // + ////////////////////////////////////////////// + + //! Effects: Returns true if the vector contains no elements. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE bool empty() const BOOST_NOEXCEPT_OR_NOTHROW + { return !this->m_holder.m_size; } + + //! Effects: Returns the number of the elements contained in the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type size() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.m_size; } + + //! Effects: Returns the largest possible size of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type max_size() const BOOST_NOEXCEPT_OR_NOTHROW + { return allocator_traits_type::max_size(this->m_holder.alloc()); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are value initialized. + //! + //! Throws: If memory allocation throws, or T's copy/move or value initialization throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + BOOST_CONTAINER_FORCEINLINE void resize(size_type new_size) + { this->priv_resize(new_size, value_init, alloc_version()); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are default initialized. + //! + //! Throws: If memory allocation throws, or T's copy/move or default initialization throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE void resize(size_type new_size, default_init_t) + { this->priv_resize(new_size, default_init, alloc_version()); } + + //! Effects: Inserts or erases elements at the end such that + //! the size becomes n. New elements are copy constructed from x. + //! + //! Throws: If memory allocation throws, or T's copy/move constructor throws. + //! + //! Complexity: Linear to the difference between size() and new_size. + BOOST_CONTAINER_FORCEINLINE void resize(size_type new_size, const T& x) + { this->priv_resize(new_size, x, alloc_version()); } + + //! Effects: Number of elements for which memory has been allocated. + //! capacity() is always greater than or equal to size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE size_type capacity() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->m_holder.capacity(); } + + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy/move constructor throws. + BOOST_CONTAINER_FORCEINLINE void reserve(size_type new_cap) + { + if (this->capacity() < new_cap){ + this->priv_move_to_new_buffer(new_cap, alloc_version()); + } + } + + //! Effects: Tries to deallocate the excess of memory created + //! with previous allocations. The size of the vector is unchanged + //! + //! Throws: If memory allocation throws, or T's copy/move constructor throws. + //! + //! Complexity: Linear to size(). + BOOST_CONTAINER_FORCEINLINE void shrink_to_fit() + { this->priv_shrink_to_fit(alloc_version()); } + + ////////////////////////////////////////////// + // + // element access + // + ////////////////////////////////////////////// + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the first + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference front() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return *this->m_holder.start(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the first + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reference front() const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return *this->m_holder.start(); + } + + //! Requires: !empty() + //! + //! Effects: Returns a reference to the last + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference back() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return this->m_holder.start()[this->m_holder.m_size - 1]; + } + + //! Requires: !empty() + //! + //! Effects: Returns a const reference to the last + //! element of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reference back() const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + return this->m_holder.start()[this->m_holder.m_size - 1]; + } + + //! Requires: size() > n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference operator[](size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size > n); + return this->m_holder.start()[n]; + } + + //! Requires: size() > n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reference operator[](size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size > n); + return this->m_holder.start()[n]; + } + + //! Requires: size() >= n. + //! + //! Effects: Returns an iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE iterator nth(size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size >= n); + return iterator(this->m_holder.start()+n); + } + + //! Requires: size() >= n. + //! + //! Effects: Returns a const_iterator to the nth element + //! from the beginning of the container. Returns end() + //! if n == size(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE const_iterator nth(size_type n) const BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(this->m_holder.m_size >= n); + return const_iterator(this->m_holder.start()+n); + } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE size_type index_of(iterator p) BOOST_NOEXCEPT_OR_NOTHROW + { + //Range check assert done in priv_index_of + return this->priv_index_of(vector_iterator_get_ptr(p)); + } + + //! Requires: begin() <= p <= end(). + //! + //! Effects: Returns the index of the element pointed by p + //! and size() if p == end(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + //! + //! Note: Non-standard extension + BOOST_CONTAINER_FORCEINLINE size_type index_of(const_iterator p) const BOOST_NOEXCEPT_OR_NOTHROW + { + //Range check assert done in priv_index_of + return this->priv_index_of(vector_iterator_get_ptr(p)); + } + + //! Requires: size() > n. + //! + //! Effects: Returns a reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE reference at(size_type n) + { + this->priv_throw_if_out_of_range(n); + return this->m_holder.start()[n]; + } + + //! Requires: size() > n. + //! + //! Effects: Returns a const reference to the nth element + //! from the beginning of the container. + //! + //! Throws: std::range_error if n >= size() + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const_reference at(size_type n) const + { + this->priv_throw_if_out_of_range(n); + return this->m_holder.start()[n]; + } + + ////////////////////////////////////////////// + // + // data access + // + ////////////////////////////////////////////// + + //! Returns: A pointer such that [data(),data() + size()) is a valid range. + //! For a non-empty vector, data() == &front(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE T* data() BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_raw_begin(); } + + //! Returns: A pointer such that [data(),data() + size()) is a valid range. + //! For a non-empty vector, data() == &front(). + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE const T * data() const BOOST_NOEXCEPT_OR_NOTHROW + { return this->priv_raw_begin(); } + + ////////////////////////////////////////////// + // + // modifiers + // + ////////////////////////////////////////////// + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the end of the vector. + //! + //! Returns: A reference to the created object. + //! + //! Throws: If memory allocation throws or the in-place constructor throws or + //! T's copy/move constructor throws. + //! + //! Complexity: Amortized constant time. + template + BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_FWD_REF(Args)...args) + { + T* const p = this->priv_raw_end(); + if (BOOST_LIKELY(this->room_enough())){ + //There is more memory, just construct a new object at the end + allocator_traits_type::construct(this->m_holder.alloc(), p, ::boost::forward(args)...); + ++this->m_holder.m_size; + return *p; + } + else{ + typedef dtl::insert_emplace_proxy proxy_t; + return *this->priv_insert_forward_range_no_capacity + (p, 1, proxy_t(::boost::forward(args)...), alloc_version()); + } + } + + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... in the end of the vector. + //! + //! Throws: If the in-place constructor throws. + //! + //! Complexity: Constant time. + //! + //! Note: Non-standard extension. + template + BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_FWD_REF(Args)...args) + { + const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u)); + if (BOOST_LIKELY(is_room_enough)){ + //There is more memory, just construct a new object at the end + allocator_traits_type::construct(this->m_holder.alloc(), this->priv_raw_end(), ::boost::forward(args)...); + ++this->m_holder.m_size; + } + return is_room_enough; + } + + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Inserts an object of type T constructed with + //! std::forward(args)... before position + //! + //! Throws: If memory allocation throws or the in-place constructor throws or + //! T's copy/move constructor/assignment throws. + //! + //! Complexity: If position is end(), amortized constant time + //! Linear time otherwise. + template + BOOST_CONTAINER_FORCEINLINE iterator emplace(const_iterator position, BOOST_FWD_REF(Args) ...args) + { + BOOST_ASSERT(this->priv_in_range_or_end(position)); + //Just call more general insert(pos, size, value) and return iterator + typedef dtl::insert_emplace_proxy proxy_t; + return this->priv_insert_forward_range( vector_iterator_get_ptr(position), 1 + , proxy_t(::boost::forward(args)...)); + } + + #else // !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + #define BOOST_CONTAINER_VECTOR_EMPLACE_CODE(N) \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + BOOST_CONTAINER_FORCEINLINE reference emplace_back(BOOST_MOVE_UREF##N)\ + {\ + T* const p = this->priv_raw_end();\ + if (BOOST_LIKELY(this->room_enough())){\ + allocator_traits_type::construct (this->m_holder.alloc()\ + , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + ++this->m_holder.m_size;\ + return *p;\ + }\ + else{\ + typedef dtl::insert_emplace_proxy_arg##N proxy_t;\ + return *this->priv_insert_forward_range_no_capacity\ + ( p, 1, proxy_t(BOOST_MOVE_FWD##N), alloc_version());\ + }\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + BOOST_CONTAINER_FORCEINLINE bool stable_emplace_back(BOOST_MOVE_UREF##N)\ + {\ + const bool is_room_enough = this->room_enough() || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(1u));\ + if (BOOST_LIKELY(is_room_enough)){\ + allocator_traits_type::construct (this->m_holder.alloc()\ + , this->priv_raw_end() BOOST_MOVE_I##N BOOST_MOVE_FWD##N);\ + ++this->m_holder.m_size;\ + }\ + return is_room_enough;\ + }\ + \ + BOOST_MOVE_TMPL_LT##N BOOST_MOVE_CLASS##N BOOST_MOVE_GT##N \ + BOOST_CONTAINER_FORCEINLINE iterator emplace(const_iterator pos BOOST_MOVE_I##N BOOST_MOVE_UREF##N)\ + {\ + BOOST_ASSERT(this->priv_in_range_or_end(pos));\ + typedef dtl::insert_emplace_proxy_arg##N proxy_t;\ + return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), 1, proxy_t(BOOST_MOVE_FWD##N));\ + }\ + // + BOOST_MOVE_ITERATE_0TO9(BOOST_CONTAINER_VECTOR_EMPLACE_CODE) + #undef BOOST_CONTAINER_VECTOR_EMPLACE_CODE + + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Effects: Inserts a copy of x at the end of the vector. + //! + //! Throws: If memory allocation throws or + //! T's copy/move constructor throws. + //! + //! Complexity: Amortized constant time. + void push_back(const T &x); + + //! Effects: Constructs a new element in the end of the vector + //! and moves the resources of x to this new element. + //! + //! Throws: If memory allocation throws or + //! T's copy/move constructor throws. + //! + //! Complexity: Amortized constant time. + void push_back(T &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH(push_back, T, void, priv_push_back) + #endif + + #if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a copy of x before position. + //! + //! Throws: If memory allocation throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: If position is end(), amortized constant time + //! Linear time otherwise. + iterator insert(const_iterator position, const T &x); + + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a new element before position with x's resources. + //! + //! Throws: If memory allocation throws. + //! + //! Complexity: If position is end(), amortized constant time + //! Linear time otherwise. + iterator insert(const_iterator position, T &&x); + #else + BOOST_MOVE_CONVERSION_AWARE_CATCH_1ARG(insert, T, iterator, priv_insert, const_iterator, const_iterator) + #endif + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert n copies of x before pos. + //! + //! Returns: an iterator to the first inserted element or p if n is 0. + //! + //! Throws: If memory allocation throws or T's copy/move constructor throws. + //! + //! Complexity: Linear to n. + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator p, size_type n, const T& x) + { + BOOST_ASSERT(this->priv_in_range_or_end(p)); + dtl::insert_n_copies_proxy proxy(x); + return this->priv_insert_forward_range(vector_iterator_get_ptr(p), n, proxy); + } + + //! Requires: p must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [first, last) range before pos. + //! + //! Returns: an iterator to the first inserted element or pos if first == last. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to boost::container::iterator_distance [first, last). + template + iterator insert(const_iterator pos, InIt first, InIt last + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + , typename dtl::disable_if_or + < void + , dtl::is_convertible + , dtl::is_not_input_iterator + >::type * = 0 + #endif + ) + { + BOOST_ASSERT(this->priv_in_range_or_end(pos)); + const size_type n_pos = pos - this->cbegin(); + iterator it(vector_iterator_get_ptr(pos)); + for(;first != last; ++first){ + it = this->emplace(it, *first); + ++it; + } + return iterator(this->m_holder.start() + n_pos); + } + + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + template + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, FwdIt first, FwdIt last + , typename dtl::disable_if_or + < void + , dtl::is_convertible + , dtl::is_input_iterator + >::type * = 0 + ) + { + BOOST_ASSERT(this->priv_in_range_or_end(pos)); + const typename iterator_traits::size_type sz = boost::container::iterator_distance(first, last); + if (sz > size_type(-1)){ + boost::container::throw_length_error("vector::insert, FwdIt's max length reached"); + } + + dtl::insert_range_proxy proxy(first); + return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), static_cast(sz), proxy); + } + #endif + + //! Requires: p must be a valid iterator of *this. num, must + //! be equal to boost::container::iterator_distance(first, last) + //! + //! Effects: Insert a copy of the [first, last) range before pos. + //! + //! Returns: an iterator to the first inserted element or pos if first == last. + //! + //! Throws: If memory allocation throws, T's constructor from a + //! dereferenced InpIt throws or T's copy/move constructor/assignment throws. + //! + //! Complexity: Linear to boost::container::iterator_distance [first, last). + //! + //! Note: This function avoids a linear operation to calculate boost::container::iterator_distance[first, last) + //! for forward and bidirectional iterators, and a one by one insertion for input iterators. This is a + //! a non-standard extension. + #if !defined(BOOST_CONTAINER_DOXYGEN_INVOKED) + template + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator pos, size_type num, InIt first, InIt last) + { + BOOST_ASSERT(this->priv_in_range_or_end(pos)); + BOOST_ASSERT(dtl::is_input_iterator::value || + num == static_cast(boost::container::iterator_distance(first, last))); + (void)last; + dtl::insert_range_proxy proxy(first); + return this->priv_insert_forward_range(vector_iterator_get_ptr(pos), num, proxy); + } + #endif + + #if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) + //! Requires: position must be a valid iterator of *this. + //! + //! Effects: Insert a copy of the [il.begin(), il.end()) range before position. + //! + //! Returns: an iterator to the first inserted element or position if first == last. + //! + //! Complexity: Linear to the range [il.begin(), il.end()). + BOOST_CONTAINER_FORCEINLINE iterator insert(const_iterator position, std::initializer_list il) + { + //Assertion done in insert() + return this->insert(position, il.begin(), il.end()); + } + #endif + + //! Effects: Removes the last element from the container. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant time. + BOOST_CONTAINER_FORCEINLINE void pop_back() BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(!this->empty()); + //Destroy last element + allocator_traits_type::destroy(this->get_stored_allocator(), this->priv_raw_end() - 1); + --this->m_holder.m_size; + } + + //! Effects: Erases the element at position pos. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the elements between pos and the + //! last element. Constant if pos is the last element. + iterator erase(const_iterator position) + { + BOOST_ASSERT(this->priv_in_range(position)); + const pointer p = vector_iterator_get_ptr(position); + T *const pos_ptr = boost::movelib::to_raw_pointer(p); + T *const end_ptr = this->priv_raw_end(); + + //Move elements forward and destroy last + (void)::boost::container::move(pos_ptr + 1, end_ptr, pos_ptr); + + T *const last_ptr = end_ptr-1; + if(!value_traits::trivial_dctr_after_move || pos_ptr == last_ptr){ + allocator_traits_type::destroy(this->get_stored_allocator(), last_ptr); + } + --this->m_holder.m_size; + return iterator(p); + } + + //! Effects: Erases the elements pointed by [first, last). + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the distance between first and last + //! plus linear to the elements between pos and the last element. + iterator erase(const_iterator first, const_iterator last) + { + BOOST_ASSERT(this->priv_in_range_or_end(first)); + BOOST_ASSERT(this->priv_in_range_or_end(last)); + BOOST_ASSERT(first <= last); + if(first != last){ + T* const old_end_ptr = this->priv_raw_end(); + T* const first_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(first)); + T* const last_ptr = boost::movelib::to_raw_pointer(vector_iterator_get_ptr(last)); + T* const new_last_ptr = boost::movelib::to_raw_pointer(boost::container::move(last_ptr, old_end_ptr, first_ptr)); + const size_type n = static_cast(old_end_ptr - new_last_ptr); + if(!value_traits::trivial_dctr_after_move || old_end_ptr == last_ptr){ + boost::container::destroy_alloc_n(this->get_stored_allocator(), new_last_ptr, n); + } + this->m_holder.dec_stored_size(n); + } + return iterator(vector_iterator_get_ptr(first)); + } + + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE void swap(vector& x) + BOOST_NOEXCEPT_IF( ((allocator_traits_type::propagate_on_container_swap::value + || allocator_traits_type::is_always_equal::value) && + !dtl::is_version::value)) + { + this->priv_swap(x, dtl::bool_::value>()); + } + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Effects: Swaps the contents of *this and x. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear + //! + //! Note: Non-standard extension to support static_vector + template + BOOST_CONTAINER_FORCEINLINE void swap(vector & x + , typename dtl::enable_if_and + < void + , dtl::is_version::type, 0> + , dtl::is_different::type, allocator_type> + >::type * = 0 + ) + { this->m_holder.deep_swap(x.m_holder); } + + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + + //! Effects: Erases all the elements of the vector. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE void clear() BOOST_NOEXCEPT_OR_NOTHROW + { this->priv_destroy_all(); } + + //! Effects: Returns true if x and y are equal + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator==(const vector& x, const vector& y) + { return x.size() == y.size() && ::boost::container::algo_equal(x.begin(), x.end(), y.begin()); } + + //! Effects: Returns true if x and y are unequal + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator!=(const vector& x, const vector& y) + { return !(x == y); } + + //! Effects: Returns true if x is less than y + //! + //! Complexity: Linear to the number of elements in the container. + friend bool operator<(const vector& x, const vector& y) + { return boost::container::algo_lexicographical_compare(x.begin(), x.end(), y.begin(), y.end()); } + + //! Effects: Returns true if x is greater than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator>(const vector& x, const vector& y) + { return y < x; } + + //! Effects: Returns true if x is equal or less than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator<=(const vector& x, const vector& y) + { return !(y < x); } + + //! Effects: Returns true if x is equal or greater than y + //! + //! Complexity: Linear to the number of elements in the container. + BOOST_CONTAINER_FORCEINLINE friend bool operator>=(const vector& x, const vector& y) + { return !(x < y); } + + //! Effects: x.swap(y) + //! + //! Complexity: Constant. + BOOST_CONTAINER_FORCEINLINE friend void swap(vector& x, vector& y) + { x.swap(y); } + + #ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + //! Effects: If n is less than or equal to capacity(), this call has no + //! effect. Otherwise, it is a request for allocation of additional memory + //! (memory expansion) that will not invalidate iterators. + //! If the request is successful, then capacity() is greater than or equal to + //! n; otherwise, capacity() is unchanged. In either case, size() is unchanged. + //! + //! Throws: If memory allocation allocation throws or T's copy/move constructor throws. + //! + //! Note: Non-standard extension. + bool stable_reserve(size_type new_cap) + { + const size_type cp = this->capacity(); + return cp >= new_cap || (alloc_version::value == 2 && this->m_holder.try_expand_fwd(new_cap - cp)); + } + + //Absolutely experimental. This function might change, disappear or simply crash! + template + BOOST_CONTAINER_FORCEINLINE void insert_ordered_at(const size_type element_count, BiDirPosConstIt last_position_it, BiDirValueIt last_value_it) + { + typedef vector_insert_ordered_cursor inserter_t; + return this->priv_insert_ordered_at(element_count, inserter_t(last_position_it, last_value_it)); + } + + template + BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last) + { this->merge(first, last, value_less_t()); } + + template + BOOST_CONTAINER_FORCEINLINE void merge(InputIt first, InputIt last, Compare comp) + { + size_type const s = this->size(); + size_type const c = this->capacity(); + size_type n = 0; + size_type const free_cap = c - s; + //If not input iterator and new elements don't fit in the remaining capacity, merge in new buffer + if(!dtl::is_input_iterator::value && + free_cap < (n = static_cast(boost::container::iterator_distance(first, last)))){ + this->priv_merge_in_new_buffer(first, n, comp, alloc_version()); + } + else{ + this->insert(this->cend(), first, last); + T *const raw_beg = this->priv_raw_begin(); + T *const raw_end = this->priv_raw_end(); + T *const raw_pos = raw_beg + s; + boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, free_cap - n); + } + } + + template + BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last) + { this->merge_unique(first, last, value_less_t()); } + + template + BOOST_CONTAINER_FORCEINLINE void merge_unique(InputIt first, InputIt last, Compare comp) + { + size_type const old_size = this->size(); + this->priv_set_difference_back(first, last, comp); + T *const raw_beg = this->priv_raw_begin(); + T *const raw_end = this->priv_raw_end(); + T *raw_pos = raw_beg + old_size; + boost::movelib::adaptive_merge(raw_beg, raw_pos, raw_end, comp, raw_end, this->capacity() - this->size()); + } + + private: + template + void priv_insert_ordered_at(const size_type element_count, PositionValue position_value) + { + const size_type old_size_pos = this->size(); + this->reserve(old_size_pos + element_count); + T* const begin_ptr = this->priv_raw_begin(); + size_type insertions_left = element_count; + size_type prev_pos = old_size_pos; + size_type old_hole_size = element_count; + + //Exception rollback. If any copy throws before the hole is filled, values + //already inserted/copied at the end of the buffer will be destroyed. + typename value_traits::ArrayDestructor past_hole_values_destroyer + (begin_ptr + old_size_pos + element_count, this->m_holder.alloc(), size_type(0u)); + //Loop for each insertion backwards, first moving the elements after the insertion point, + //then inserting the element. + while(insertions_left){ + --position_value; + size_type const pos = position_value.get_pos(); + BOOST_ASSERT(pos != size_type(-1) && pos <= old_size_pos && pos <= prev_pos); + //If needed shift the range after the insertion point and the previous insertion point. + //Function will take care if the shift crosses the size() boundary, using copy/move + //or uninitialized copy/move if necessary. + size_type new_hole_size = (pos != prev_pos) + ? priv_insert_ordered_at_shift_range(pos, prev_pos, this->size(), insertions_left) + : old_hole_size + ; + if(new_hole_size){ + //The hole was reduced by priv_insert_ordered_at_shift_range so expand exception rollback range backwards + past_hole_values_destroyer.increment_size_backwards(prev_pos - pos); + //Insert the new value in the hole + allocator_traits_type::construct(this->m_holder.alloc(), begin_ptr + pos + insertions_left - 1, position_value.get_val()); + if(--new_hole_size){ + //The hole was reduced by the new insertion by one + past_hole_values_destroyer.increment_size_backwards(size_type(1u)); + } + else{ + //Hole was just filled, disable exception rollback and change vector size + past_hole_values_destroyer.release(); + this->m_holder.inc_stored_size(element_count); + } + } + else{ + if(old_hole_size){ + //Hole was just filled by priv_insert_ordered_at_shift_range, disable exception rollback and change vector size + past_hole_values_destroyer.release(); + this->m_holder.inc_stored_size(element_count); + } + //Insert the new value in the already constructed range + begin_ptr[pos + insertions_left - 1] = position_value.get_val(); + } + --insertions_left; + old_hole_size = new_hole_size; + prev_pos = pos; + } + } + + template + void priv_set_difference_back(InputIt first1, InputIt last1, Compare comp) + { + T * old_first2 = this->priv_raw_begin(); + T * first2 = old_first2; + T * last2 = this->priv_raw_end(); + + while (first1 != last1) { + if (first2 == last2){ + this->insert(this->cend(), first1, last1); + return; + } + + if (comp(*first1, *first2)) { + this->emplace_back(*first1); + T * const raw_begin = this->priv_raw_begin(); + if(old_first2 != raw_begin) + { + //Reallocation happened, update range + first2 = raw_begin + (first2 - old_first2); + last2 = raw_begin + (last2 - old_first2); + old_first2 = raw_begin; + } + ++first1; + } + else { + if (!comp(*first2, *first1)) { + ++first1; + } + ++first2; + } + } + } + + template + BOOST_CONTAINER_FORCEINLINE void priv_merge_in_new_buffer(FwdIt, size_type, Compare, version_0) + { + alloc_holder_t::on_capacity_overflow(); + } + + template + void priv_merge_in_new_buffer(FwdIt first, size_type n, Compare comp, Version) + { + size_type const new_size = this->size() + n; + size_type new_cap = new_size; + pointer p = pointer(); + pointer const new_storage = this->m_holder.allocation_command(allocate_new, new_size, new_cap, p); + + BOOST_ASSERT((new_cap >= this->size() ) && (new_cap - this->size()) >= n); + allocator_type &a = this->m_holder.alloc(); + typename value_traits::ArrayDeallocator new_buffer_deallocator(new_storage, a, new_cap); + typename value_traits::ArrayDestructor new_values_destroyer(new_storage, a, 0u); + T* pbeg = this->priv_raw_begin(); + size_type const old_size = this->size(); + T* const pend = pbeg + old_size; + T* d_first = boost::movelib::to_raw_pointer(new_storage); + size_type added = n; + //Merge in new buffer loop + while(1){ + if(!n) { + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), pbeg, pend, d_first); + break; + } + else if(pbeg == pend) { + ::boost::container::uninitialized_move_alloc_n(this->m_holder.alloc(), first, n, d_first); + break; + } + //maintain stability moving external values only if they are strictly less + else if(comp(*first, *pbeg)) { + allocator_traits_type::construct( this->m_holder.alloc(), d_first, *first ); + new_values_destroyer.increment_size(1u); + ++first; + --n; + ++d_first; + } + else{ + allocator_traits_type::construct( this->m_holder.alloc(), d_first, boost::move(*pbeg) ); + new_values_destroyer.increment_size(1u); + ++pbeg; + ++d_first; + } + } + + //Nothrow operations + pointer const old_p = this->m_holder.start(); + size_type const old_cap = this->m_holder.capacity(); + boost::container::destroy_alloc_n(a, boost::movelib::to_raw_pointer(old_p), old_size); + if (old_cap > 0) { + this->m_holder.deallocate(old_p, old_cap); + } + m_holder.set_stored_size(old_size + added); + this->m_holder.start(new_storage); + this->m_holder.capacity(new_cap); + new_buffer_deallocator.release(); + new_values_destroyer.release(); + } + + BOOST_CONTAINER_FORCEINLINE bool room_enough() const + { return this->m_holder.m_size != this->m_holder.capacity(); } + + BOOST_CONTAINER_FORCEINLINE pointer back_ptr() const + { return this->m_holder.start() + this->m_holder.m_size; } + + BOOST_CONTAINER_FORCEINLINE size_type priv_index_of(pointer p) const + { + BOOST_ASSERT(this->m_holder.start() <= p); + BOOST_ASSERT(p <= (this->m_holder.start()+this->size())); + return static_cast(p - this->m_holder.start()); + } + + template + void priv_move_assign(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x + , typename dtl::enable_if_c + < dtl::is_version::type, 0>::value >::type * = 0) + { + if(!dtl::is_same::type, allocator_type>::value && + this->capacity() < x.size()){ + alloc_holder_t::on_capacity_overflow(); + } + T* const this_start = this->priv_raw_begin(); + T* const other_start = x.priv_raw_begin(); + const size_type this_sz = m_holder.m_size; + const size_type other_sz = static_cast(x.m_holder.m_size); + boost::container::move_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); + m_holder.set_stored_size(other_sz); + //Not emptying the source container seems to be confusing for users as drop-in + //replacement for non-static vectors, so clear it. + x.clear(); + } + + template + void priv_move_assign(BOOST_RV_REF_BEG vector BOOST_RV_REF_END x + , typename dtl::disable_if_or + < void + , dtl::is_version::type, 0> + , dtl::is_different::type, allocator_type> + >::type * = 0) + { + //for move assignment, no aliasing (&x != this) is assumed. + //x.size() == 0 is allowed for buggy std libraries. + BOOST_ASSERT(this != &x || x.size() == 0); + allocator_type &this_alloc = this->m_holder.alloc(); + allocator_type &x_alloc = x.m_holder.alloc(); + const bool propagate_alloc = allocator_traits_type::propagate_on_container_move_assignment::value; + + //In this allocator move constructor the allocator maybe will be propagated -----------------------v + const bool is_propagable_from_x = is_propagable_from(x_alloc, x.m_holder.start(), this_alloc, propagate_alloc); + + //Resources can be transferred if both allocators are + //going to be equal after this function (either propagated or already equal) + if(is_propagable_from_x){ + this->clear(); + if(BOOST_LIKELY(!!this->m_holder.m_start)) + this->m_holder.deallocate(this->m_holder.m_start, this->m_holder.m_capacity); + this->m_holder.steal_resources(x.m_holder); + } + //Else do a one by one move. Also, clear the source as users find confusing + //elements are still alive in the source container. + else{ + this->assign( boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.begin())) + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(x.end() )) + ); + x.clear(); + } + //Move allocator if needed + dtl::move_alloc(this_alloc, x_alloc, dtl::bool_()); + } + + template + void priv_copy_assign(const vector &x + , typename dtl::enable_if_c + < dtl::is_version::type, 0>::value >::type * = 0) + { + if(!dtl::is_same::type, allocator_type>::value && + this->capacity() < x.size()){ + alloc_holder_t::on_capacity_overflow(); + } + T* const this_start = this->priv_raw_begin(); + T* const other_start = x.priv_raw_begin(); + const size_type this_sz = m_holder.m_size; + const size_type other_sz = static_cast(x.m_holder.m_size); + boost::container::copy_assign_range_alloc_n(this->m_holder.alloc(), other_start, other_sz, this_start, this_sz); + m_holder.set_stored_size(other_sz); + } + + template + typename dtl::disable_if_or + < void + , dtl::is_version::type, 0> + , dtl::is_different::type, allocator_type> + >::type + priv_copy_assign(const vector &x) + { + allocator_type &this_alloc = this->m_holder.alloc(); + const allocator_type &x_alloc = x.m_holder.alloc(); + dtl::bool_ flag; + if(flag && this_alloc != x_alloc){ + this->clear(); + this->shrink_to_fit(); + } + dtl::assign_alloc(this_alloc, x_alloc, flag); + this->assign( x.priv_raw_begin(), x.priv_raw_end() ); + } + + template //Template it to avoid it in explicit instantiations + BOOST_CONTAINER_FORCEINLINE void priv_swap(Vector &x, dtl::true_type) //version_0 + { this->m_holder.deep_swap(x.m_holder); } + + template //Template it to avoid it in explicit instantiations + void priv_swap(Vector &x, dtl::false_type) //version_N + { + const bool propagate_alloc = allocator_traits_type::propagate_on_container_swap::value; + if(are_swap_propagable( this->get_stored_allocator(), this->m_holder.start() + , x.get_stored_allocator(), x.m_holder.start(), propagate_alloc)){ + //Just swap internals + this->m_holder.swap_resources(x.m_holder); + } + else{ + if (BOOST_UNLIKELY(&x == this)) + return; + + //Else swap element by element... + bool const t_smaller = this->size() < x.size(); + vector &sml = t_smaller ? *this : x; + vector &big = t_smaller ? x : *this; + + size_type const common_elements = sml.size(); + for(size_type i = 0; i != common_elements; ++i){ + boost::adl_move_swap(sml[i], big[i]); + } + //... and move-insert the remaining range + sml.insert( sml.cend() + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.nth(common_elements))) + , boost::make_move_iterator(boost::movelib::iterator_to_raw_pointer(big.end())) + ); + //Destroy remaining elements + big.erase(big.nth(common_elements), big.cend()); + } + //And now swap the allocator + dtl::swap_alloc(this->m_holder.alloc(), x.m_holder.alloc(), dtl::bool_()); + } + + BOOST_CONTAINER_FORCEINLINE void priv_move_to_new_buffer(size_type, version_0) + { alloc_holder_t::on_capacity_overflow(); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_range_proxy, T*> priv_dummy_empty_proxy() + { + return dtl::insert_range_proxy, T*> + (::boost::make_move_iterator((T *)0)); + } + + BOOST_CONTAINER_FORCEINLINE void priv_move_to_new_buffer(size_type new_cap, version_1) + { + //There is not enough memory, allocate a new buffer + //Pass the hint so that allocators can take advantage of this. + pointer const p = this->m_holder.allocate(new_cap); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + //We will reuse insert code, so create a dummy input iterator + this->priv_insert_forward_range_new_allocation + ( boost::movelib::to_raw_pointer(p), new_cap, this->priv_raw_end(), 0, this->priv_dummy_empty_proxy()); + } + + void priv_move_to_new_buffer(size_type new_cap, version_2) + { + //There is not enough memory, allocate a new + //buffer or expand the old one. + bool same_buffer_start; + size_type real_cap = 0; + pointer reuse(this->m_holder.start()); + pointer const ret(this->m_holder.allocation_command(allocate_new | expand_fwd | expand_bwd, new_cap, real_cap = new_cap, reuse)); + + //Check for forward expansion + same_buffer_start = reuse && this->m_holder.start() == ret; + if(same_buffer_start){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->m_holder.capacity(real_cap); + } + else{ //If there is no forward expansion, move objects, we will reuse insertion code + T * const new_mem = boost::movelib::to_raw_pointer(ret); + T * const ins_pos = this->priv_raw_end(); + if(reuse){ //Backwards (and possibly forward) expansion + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_bwd; + #endif + this->priv_insert_forward_range_expand_backwards + ( new_mem , real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); + } + else{ //New buffer + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_insert_forward_range_new_allocation + ( new_mem, real_cap, ins_pos, 0, this->priv_dummy_empty_proxy()); + } + } + } + + void priv_destroy_last_n(const size_type n) BOOST_NOEXCEPT_OR_NOTHROW + { + BOOST_ASSERT(n <= this->m_holder.m_size); + boost::container::destroy_alloc_n(this->get_stored_allocator(), this->priv_raw_end() - n, n); + this->m_holder.dec_stored_size(n); + } + + template + void priv_uninitialized_construct_at_end(InpIt first, InpIt last) + { + T* const old_end_pos = this->priv_raw_end(); + T* const new_end_pos = boost::container::uninitialized_copy_alloc(this->m_holder.alloc(), first, last, old_end_pos); + this->m_holder.inc_stored_size(static_cast(new_end_pos - old_end_pos)); + } + + void priv_destroy_all() BOOST_NOEXCEPT_OR_NOTHROW + { + boost::container::destroy_alloc_n + (this->get_stored_allocator(), this->priv_raw_begin(), this->m_holder.m_size); + this->m_holder.m_size = 0; + } + + template + BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const const_iterator &p, BOOST_FWD_REF(U) u) + { + return this->emplace(p, ::boost::forward(u)); + } + + template + BOOST_CONTAINER_FORCEINLINE void priv_push_back(BOOST_FWD_REF(U) u) + { + this->emplace_back(::boost::forward(u)); + } + + //Overload to support compiler errors that instantiate too much + BOOST_CONTAINER_FORCEINLINE void priv_push_back(::boost::move_detail::nat) + {} + + BOOST_CONTAINER_FORCEINLINE iterator priv_insert(const_iterator, ::boost::move_detail::nat) + { return iterator(); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_n_copies_proxy priv_resize_proxy(const T &x) + { return dtl::insert_n_copies_proxy(x); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_default_initialized_n_proxy priv_resize_proxy(default_init_t) + { return dtl::insert_default_initialized_n_proxy(); } + + BOOST_CONTAINER_FORCEINLINE dtl::insert_value_initialized_n_proxy priv_resize_proxy(value_init_t) + { return dtl::insert_value_initialized_n_proxy(); } + + BOOST_CONTAINER_FORCEINLINE void priv_shrink_to_fit(version_0) BOOST_NOEXCEPT_OR_NOTHROW + {} + + void priv_shrink_to_fit(version_1) + { + const size_type cp = this->m_holder.capacity(); + if(cp){ + const size_type sz = this->size(); + if(!sz){ + if(BOOST_LIKELY(!!this->m_holder.m_start)) + this->m_holder.deallocate(this->m_holder.m_start, cp); + this->m_holder.m_start = pointer(); + this->m_holder.m_capacity = 0; + } + else if(sz < cp){ + this->priv_move_to_new_buffer(sz, alloc_version()); + } + } + } + + void priv_shrink_to_fit(version_2) BOOST_NOEXCEPT_OR_NOTHROW + { + const size_type cp = this->m_holder.capacity(); + if(cp){ + const size_type sz = this->size(); + if(!sz){ + if(BOOST_LIKELY(!!this->m_holder.m_start)) + this->m_holder.deallocate(this->m_holder.m_start, cp); + this->m_holder.m_start = pointer(); + this->m_holder.m_capacity = 0; + } + else{ + size_type received_size = sz; + pointer reuse(this->m_holder.start()); + if(this->m_holder.allocation_command + (shrink_in_place | nothrow_allocation, cp, received_size, reuse)){ + this->m_holder.capacity(received_size); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_shrink; + #endif + } + } + } + } + + template + BOOST_CONTAINER_FORCEINLINE iterator priv_insert_forward_range_no_capacity + (T * const, const size_type, const InsertionProxy , version_0) + { + return alloc_holder_t::on_capacity_overflow(), iterator(); + } + + template + BOOST_CONTAINER_NOINLINE iterator priv_insert_forward_range_no_capacity + (T *const raw_pos, const size_type n, const InsertionProxy insert_range_proxy, version_1) + { + //Check if we have enough memory or try to expand current memory + const size_type n_pos = static_cast(raw_pos - this->priv_raw_begin()); + + const size_type new_cap = this->m_holder.template next_capacity(n); + //Pass the hint so that allocators can take advantage of this. + T * const new_buf = boost::movelib::to_raw_pointer(this->m_holder.allocate(new_cap)); + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_insert_forward_range_new_allocation(new_buf, new_cap, raw_pos, n, insert_range_proxy); + return iterator(this->m_holder.start() + n_pos); + } + + template + BOOST_CONTAINER_NOINLINE iterator priv_insert_forward_range_no_capacity + (T *const raw_pos, const size_type n, const InsertionProxy insert_range_proxy, version_2) + { + //Check if we have enough memory or try to expand current memory + const size_type n_pos = raw_pos - this->priv_raw_begin(); + + //There is not enough memory, allocate a new + //buffer or expand the old one. + size_type real_cap = this->m_holder.template next_capacity(n); + pointer reuse(this->m_holder.start()); + pointer const ret (this->m_holder.allocation_command + (allocate_new | expand_fwd | expand_bwd, this->m_holder.m_size + n, real_cap, reuse)); + + //Buffer reallocated + if(reuse){ + //Forward expansion, delay insertion + if(this->m_holder.start() == ret){ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_fwd; + #endif + this->m_holder.capacity(real_cap); + //Expand forward + this->priv_insert_forward_range_expand_forward + (raw_pos, n, insert_range_proxy, dtl::bool_::value>()); + } + //Backwards (and possibly forward) expansion + else{ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_expand_bwd; + #endif + this->priv_insert_forward_range_expand_backwards + (boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); + } + } + //New buffer + else{ + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + ++this->num_alloc; + #endif + this->priv_insert_forward_range_new_allocation + ( boost::movelib::to_raw_pointer(ret), real_cap, raw_pos, n, insert_range_proxy); + } + + return iterator(this->m_holder.start() + n_pos); + } + + template + BOOST_CONTAINER_FORCEINLINE iterator priv_insert_forward_range + (const pointer &pos, const size_type n, const InsertionProxy insert_range_proxy) + { + BOOST_ASSERT(this->m_holder.capacity() >= this->m_holder.m_size); + T *const p = boost::movelib::to_raw_pointer(pos); + //Check if we have enough memory or try to expand current memory + if (BOOST_LIKELY(n <= (this->m_holder.capacity() - this->m_holder.m_size))){ + //Expand forward + this->priv_insert_forward_range_expand_forward + (p, n, insert_range_proxy, dtl::bool_::value>()); + return iterator(pos); + } + else{ + return this->priv_insert_forward_range_no_capacity(p, n, insert_range_proxy, alloc_version()); + } + } + + template + void priv_resize(const size_type new_size, const U &u, version_0) + { + const size_type sz = this->m_holder.m_size; + if (new_size > this->capacity()){ + //This will trigger an error + alloc_holder_t::on_capacity_overflow(); + } + else if (new_size < sz){ + //Destroy last elements + this->priv_destroy_last_n(sz - new_size); + } + else{ + T* const old_finish = this->priv_raw_end(); + this->priv_resize_proxy(u).uninitialized_copy_n_and_update(this->m_holder.alloc(), old_finish, new_size - sz); + this->m_holder.set_stored_size(new_size); + } + } + + template + void priv_resize(const size_type new_size, const U &u, AllocVersion) + { + const size_type sz = this->m_holder.m_size; + if (new_size < sz){ + //Destroy last elements + this->priv_destroy_last_n(sz - new_size); + } + else { + this->priv_insert_forward_range(this->back_ptr(), new_size - sz, this->priv_resize_proxy(u)); + } + } + + //Takes the range pointed by [first_pos, last_pos) and shifts it to the right + //by 'shift_count'. 'limit_pos' marks the end of constructed elements. + // + //Precondition: first_pos <= last_pos <= limit_pos + // + //The shift operation might cross limit_pos so elements to moved beyond limit_pos + //are uninitialized_moved with an allocator. Other elements are moved. + // + //The shift operation might left uninitialized elements after limit_pos + //and the number of uninitialized elements is returned by the function. + // + //Old situation: + // first_pos last_pos old_limit + // | | | + // ____________V_______V__________________V_____________ + //| prefix | range | suffix |raw_mem ~ + //|____________|_______|__________________|_____________~ + // + //New situation in Case A (hole_size == 0): + // range is moved through move assignments + // + // first_pos last_pos limit_pos + // | | | + // ____________V_______V__________________V_____________ + //| prefix' | | | range |suffix'|raw_mem ~ + //|________________+______|___^___|_______|_____________~ + // | | + // |_>_>_>_>_>^ + // + // + //New situation in Case B (hole_size >= 0): + // range is moved through uninitialized moves + // + // first_pos last_pos limit_pos + // | | | + // ____________V_______V__________________V________________ + //| prefix' | | | [hole] | range | + //|_______________________________________|________|___^___| + // | | + // |_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_>_^ + // + //New situation in Case C (hole_size == 0): + // range is moved through move assignments and uninitialized moves + // + // first_pos last_pos limit_pos + // | | | + // ____________V_______V__________________V___ + //| prefix' | | | range | + //|___________________________________|___^___| + // | | + // |_>_>_>_>_>_>_>_>_>_>_>^ + size_type priv_insert_ordered_at_shift_range + (size_type first_pos, size_type last_pos, size_type limit_pos, size_type shift_count) + { + BOOST_ASSERT(first_pos <= last_pos); + BOOST_ASSERT(last_pos <= limit_pos); + // + T* const begin_ptr = this->priv_raw_begin(); + T* const first_ptr = begin_ptr + first_pos; + T* const last_ptr = begin_ptr + last_pos; + + size_type hole_size = 0; + //Case A: + if((last_pos + shift_count) <= limit_pos){ + //All move assigned + boost::container::move_backward(first_ptr, last_ptr, last_ptr + shift_count); + } + //Case B: + else if((first_pos + shift_count) >= limit_pos){ + //All uninitialized_moved + ::boost::container::uninitialized_move_alloc + (this->m_holder.alloc(), first_ptr, last_ptr, first_ptr + shift_count); + hole_size = first_pos + shift_count - limit_pos; + } + //Case C: + else{ + //Some uninitialized_moved + T* const limit_ptr = begin_ptr + limit_pos; + T* const boundary_ptr = limit_ptr - shift_count; + ::boost::container::uninitialized_move_alloc(this->m_holder.alloc(), boundary_ptr, last_ptr, limit_ptr); + //The rest is move assigned + boost::container::move_backward(first_ptr, boundary_ptr, limit_ptr); + } + return hole_size; + } + + private: + BOOST_CONTAINER_FORCEINLINE T *priv_raw_begin() const + { return boost::movelib::to_raw_pointer(m_holder.start()); } + + BOOST_CONTAINER_FORCEINLINE T* priv_raw_end() const + { return this->priv_raw_begin() + this->m_holder.m_size; } + + template //inline single-element version as it is significantly smaller + BOOST_CONTAINER_FORCEINLINE void priv_insert_forward_range_expand_forward + (T* const raw_pos, const size_type, InsertionProxy insert_range_proxy, dtl::true_type) + { + BOOST_ASSERT(this->room_enough()); + //There is enough memory + T* const old_finish = this->priv_raw_end(); + allocator_type & a = this->m_holder.alloc(); + + if (old_finish == raw_pos){ + insert_range_proxy.uninitialized_copy_n_and_update(a, old_finish, 1); + ++this->m_holder.m_size; + } + else{ + //New elements can be just copied. + //Move to uninitialized memory last objects + T * const before_old_finish = old_finish-1; + + allocator_traits_type::construct(a, old_finish, ::boost::move(*before_old_finish)); + ++this->m_holder.m_size; + //Copy previous to last objects to the initialized end + boost::container::move_backward(raw_pos, before_old_finish, old_finish); + //Insert new objects in the raw_pos + insert_range_proxy.copy_n_and_update(a, raw_pos, 1); + } + } + + template + BOOST_CONTAINER_FORCEINLINE void priv_insert_forward_range_expand_forward(T* const raw_pos, const size_type n, InsertionProxy insert_range_proxy, dtl::false_type) + { + //There is enough memory + boost::container::expand_forward_and_insert_alloc + ( this->m_holder.alloc(), raw_pos, this->priv_raw_end(), n, insert_range_proxy); + this->m_holder.inc_stored_size(n); + } + + template + void priv_insert_forward_range_new_allocation + (T* const new_start, size_type new_cap, T* const pos, const size_type n, InsertionProxy insert_range_proxy) + { + //n can be zero, if we want to reallocate! + allocator_type &a = this->m_holder.alloc(); + T * const raw_old_buffer = this->priv_raw_begin(); + + typename value_traits::ArrayDeallocator new_buffer_deallocator(new_start, a, new_cap); + boost::container::uninitialized_move_and_insert_alloc + (a, raw_old_buffer, pos, this->priv_raw_end(), new_start, n, insert_range_proxy); + new_buffer_deallocator.release(); + + //Destroy and deallocate old elements + if(raw_old_buffer){ + BOOST_IF_CONSTEXPR(!has_trivial_destructor_after_move::value) + boost::container::destroy_alloc_n(a, raw_old_buffer, this->m_holder.m_size); + this->m_holder.deallocate(this->m_holder.start(), this->m_holder.capacity()); + } + + this->m_holder.start(new_start); + this->m_holder.inc_stored_size(n); + this->m_holder.capacity(new_cap); + } + + template + void priv_insert_forward_range_expand_backwards + (T* const new_start, const size_type new_capacity, + T* const pos, const size_type n, InsertionProxy insert_range_proxy) + { + //n can be zero to just expand capacity + //Backup old data + T* const old_start = this->priv_raw_begin(); + const size_type old_size = this->m_holder.m_size; + T* const old_finish = old_start + old_size; + allocator_type &a = this->m_holder.alloc(); + + //Update the vector buffer information to a safe state + this->m_holder.start(new_start); + this->m_holder.capacity(new_capacity); + this->m_holder.m_size = 0; + + //We can have 8 possibilities: + const size_type elemsbefore = static_cast(pos - old_start); + const size_type s_before = static_cast(old_start - new_start); + const size_type before_plus_new = elemsbefore + n; + + typedef typename value_traits::ArrayDestructor array_destructor_t; + + //If anything goes wrong, this object will destroy + //all the old objects to fulfill previous vector state + array_destructor_t old_values_destroyer(old_start, a, old_size); + //Check if s_before is big enough to hold the beginning of old data + new data + if(s_before >= before_plus_new){ + //Copy first old values before pos, after that the new objects + T *const new_elem_pos = + ::boost::container::uninitialized_move_alloc(a, old_start, pos, new_start); + this->m_holder.set_stored_size(elemsbefore); + insert_range_proxy.uninitialized_copy_n_and_update(a, new_elem_pos, n); + this->m_holder.set_stored_size(before_plus_new); + const size_type new_size = old_size + n; + //Check if s_before is so big that even copying the old data + new data + //there is a gap between the new data and the old data + if(s_before >= new_size){ + //Old situation: + // _________________________________________________________ + //| raw_mem | old_begin | old_end | + //| __________________________________|___________|_________| + // + //New situation: + // _________________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|__________|_________|________________________| + // + //Now initialize the rest of memory with the last old values + if(before_plus_new != new_size){ //Special case to avoid operations in back insertion + ::boost::container::uninitialized_move_alloc(a, pos, old_finish, new_start + before_plus_new); + //All new elements correctly constructed, avoid new element destruction + this->m_holder.set_stored_size(new_size); + } + //Old values destroyed automatically with "old_values_destroyer" + //when "old_values_destroyer" goes out of scope unless the have trivial + //destructor after move. + BOOST_IF_CONSTEXPR(value_traits::trivial_dctr_after_move) + old_values_destroyer.release(); + } + //s_before is so big that divides old_end + else{ + //Old situation: + // __________________________________________________ + //| raw_mem | old_begin | old_end | + //| ___________________________|___________|_________| + // + //New situation: + // __________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|__________|_________|_________________| + // + //Now initialize the rest of memory with the last old values + //All new elements correctly constructed, avoid new element destruction + BOOST_IF_CONSTEXPR(!value_traits::trivial_dctr){ + const size_type raw_gap = s_before - before_plus_new; + //Now initialize the rest of s_before memory with the + //first of elements after new values + ::boost::container::uninitialized_move_alloc_n(a, pos, raw_gap, new_start + before_plus_new); + //Now we have a contiguous buffer so program trailing element destruction + //and update size to the final size. + old_values_destroyer.shrink_forward(new_size-s_before); + this->m_holder.set_stored_size(new_size); + //Now move remaining last objects in the old buffer begin + T * const remaining_pos = pos + raw_gap; + if(remaining_pos != old_start){ //Make sure data has to be moved + ::boost::container::move(remaining_pos, old_finish, old_start); + } + //Once moved, avoid calling the destructors if trivial after move + BOOST_IF_CONSTEXPR(value_traits::trivial_dctr_after_move){ + old_values_destroyer.release(); + } + } + else{ //If trivial destructor, we can uninitialized copy + copy in a single uninitialized copy + ::boost::container::uninitialized_move_alloc_n + (a, pos, static_cast(old_finish - pos), new_start + before_plus_new); + this->m_holder.set_stored_size(new_size); + old_values_destroyer.release(); + } + } + } + else{ + //Check if we have to do the insertion in two phases + //since maybe s_before is not big enough and + //the buffer was expanded both sides + // + //Old situation: + // _________________________________________________ + //| raw_mem | old_begin + old_end | raw_mem | + //|_________|_____________________|_________________| + // + //New situation with do_after: + // _________________________________________________ + //| old_begin + new + old_end | raw_mem | + //|___________________________________|_____________| + // + //New without do_after: + // _________________________________________________ + //| old_begin + new + old_end | raw_mem | + //|____________________________|____________________| + // + const bool do_after = n > s_before; + + //Now we can have two situations: the raw_mem of the + //beginning divides the old_begin, or the new elements: + if (s_before <= elemsbefore) { + //The raw memory divides the old_begin group: + // + //If we need two phase construction (do_after) + //new group is divided in new = new_beg + new_end groups + //In this phase only new_beg will be inserted + // + //Old situation: + // _________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|_________|___________|_________|_________________| + // + //New situation with do_after(1): + //This is not definitive situation, the second phase + //will include + // _________________________________________________ + //| old_begin | new_beg | old_end | raw_mem | + //|___________|_________|_________|_________________| + // + //New situation without do_after: + // _________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|_____|_________|_____________________| + // + //Copy the first part of old_begin to raw_mem + ::boost::container::uninitialized_move_alloc_n(a, old_start, s_before, new_start); + //The buffer is all constructed until old_end, + //so program trailing destruction and assign final size + //if !do_after, s_before+n otherwise. + size_type new_1st_range; + if(do_after){ + new_1st_range = s_before; + //release destroyer and update size + old_values_destroyer.release(); + } + else{ + new_1st_range = n; + BOOST_IF_CONSTEXPR(value_traits::trivial_dctr_after_move){ + old_values_destroyer.release(); + } + else{ + old_values_destroyer.shrink_forward(old_size - (s_before - n)); + } + } + this->m_holder.set_stored_size(old_size + new_1st_range); + //Now copy the second part of old_begin overwriting itself + T *const next = ::boost::container::move(old_start + s_before, pos, old_start); + //Now copy the new_beg elements + insert_range_proxy.copy_n_and_update(a, next, new_1st_range); + + //If there is no after work and the last old part needs to be moved to front, do it + if(!do_after && (n != s_before)){ + //Now displace old_end elements + ::boost::container::move(pos, old_finish, next + new_1st_range); + } + } + else { + //If we have to expand both sides, + //we will play if the first new values so + //calculate the upper bound of new values + + //The raw memory divides the new elements + // + //If we need two phase construction (do_after) + //new group is divided in new = new_beg + new_end groups + //In this phase only new_beg will be inserted + // + //Old situation: + // _______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|_______________|___________|_________|_________________| + // + //New situation with do_after(): + // ____________________________________________________ + //| old_begin | new_beg | old_end | raw_mem | + //|___________|_______________|_________|______________| + // + //New situation without do_after: + // ______________________________________________________ + //| old_begin | new | old_end | raw_mem | + //|___________|_____|_________|__________________________| + // + //First copy whole old_begin and part of new to raw_mem + T * const new_pos = ::boost::container::uninitialized_move_alloc + (a, old_start, pos, new_start); + this->m_holder.set_stored_size(elemsbefore); + const size_type mid_n = s_before - elemsbefore; + insert_range_proxy.uninitialized_copy_n_and_update(a, new_pos, mid_n); + //The buffer is all constructed until old_end, + //release destroyer + this->m_holder.set_stored_size(old_size + s_before); + old_values_destroyer.release(); + + if(do_after){ + //Copy new_beg part + insert_range_proxy.copy_n_and_update(a, old_start, elemsbefore); + } + else{ + //Copy all new elements + const size_type rest_new = n - mid_n; + insert_range_proxy.copy_n_and_update(a, old_start, rest_new); + + T* const move_start = old_start + rest_new; + //Displace old_end, but make sure data has to be moved + T* const move_end = move_start != pos ? ::boost::container::move(pos, old_finish, move_start) + : old_finish; + (void)move_end; //To avoid warnings of unused initialization for move_end in case + //trivial_dctr_after_move is true + //Destroy remaining moved elements from old_end except if they + //have trivial destructor after being moved + const size_type n_destroy = s_before - n; + BOOST_IF_CONSTEXPR(!value_traits::trivial_dctr_after_move){ + boost::container::destroy_alloc_n(a, move_end, n_destroy); + } + this->m_holder.dec_stored_size(n_destroy); + } + } + + //This is only executed if two phase construction is needed + if(do_after){ + //The raw memory divides the new elements + // + //Old situation: + // ______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|______________| + // + //New situation with do_after(1): + // _______________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_________|________|_________| + // + //New situation with do_after(2): + // ______________________________________________________ + //| old_begin + new | old_end |raw | + //|_______________________________________|_________|____| + // + const size_type n_after = n - s_before; + const size_type elemsafter = old_size - elemsbefore; + + //We can have two situations: + if (elemsafter >= n_after){ + //The raw_mem from end will divide displaced old_end + // + //Old situation: + // ______________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|______________| + // + //New situation with do_after(1): + // _______________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_________|________|_________| + // + //First copy the part of old_end raw_mem + T* finish_n = old_finish - n_after; + ::boost::container::uninitialized_move_alloc(a, finish_n, old_finish, old_finish); + this->m_holder.inc_stored_size(n_after); + //Displace the rest of old_end to the new position + boost::container::move_backward(pos, finish_n, old_finish); + //Now overwrite with new_end + //The new_end part is [first + (n - n_after), last) + insert_range_proxy.copy_n_and_update(a, pos, n_after); + } + else { + //The raw_mem from end will divide new_end part + // + //Old situation: + // _____________________________________________________________ + //| raw_mem | old_begin | old_end | raw_mem | + //|______________|___________|____________|_____________________| + // + //New situation with do_after(2): + // _____________________________________________________________ + //| old_begin + new_beg | new_end |old_end | raw_mem | + //|__________________________|_______________|________|_________| + + //First initialize data in raw memory + const size_type mid_last_dist = n_after - elemsafter; + + //Copy to the old_end part to the uninitialized zone leaving a gap. + ::boost::container::uninitialized_move_alloc(a, pos, old_finish, old_finish + mid_last_dist); + + array_destructor_t old_end_destroyer(old_finish + mid_last_dist, a, static_cast(old_finish - pos)); + + //Copy the first part to the already constructed old_end zone + insert_range_proxy.copy_n_and_update(a, pos, elemsafter); + //Copy the rest to the uninitialized zone filling the gap + insert_range_proxy.uninitialized_copy_n_and_update(a, old_finish, mid_last_dist); + this->m_holder.inc_stored_size(n_after); + old_end_destroyer.release(); + } + } + } + } + + void priv_throw_if_out_of_range(size_type n) const + { + //If n is out of range, throw an out_of_range exception + if (n >= this->size()){ + throw_out_of_range("vector::at out of range"); + } + } + + BOOST_CONTAINER_FORCEINLINE bool priv_in_range(const_iterator pos) const + { + return (this->begin() <= pos) && (pos < this->end()); + } + + BOOST_CONTAINER_FORCEINLINE bool priv_in_range_or_end(const_iterator pos) const + { + return (this->begin() <= pos) && (pos <= this->end()); + } + + #ifdef BOOST_CONTAINER_VECTOR_ALLOC_STATS + public: + unsigned int num_expand_fwd; + unsigned int num_expand_bwd; + unsigned int num_shrink; + unsigned int num_alloc; + void reset_alloc_stats() + { num_expand_fwd = num_expand_bwd = num_alloc = 0, num_shrink = 0; } + #endif + #endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED +}; + +#ifndef BOOST_CONTAINER_NO_CXX17_CTAD + +template +vector(InputIterator, InputIterator) -> + vector::value_type>; + +template +vector(InputIterator, InputIterator, Allocator const&) -> + vector::value_type, Allocator>; + +#endif + + +}} //namespace boost::container + +#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +namespace boost { + +//!has_trivial_destructor_after_move<> == true_type +//!specialization for optimizations +template +struct has_trivial_destructor_after_move > +{ + typedef typename boost::container::vector::allocator_type allocator_type; + typedef typename ::boost::container::allocator_traits::pointer pointer; + static const bool value = ::boost::has_trivial_destructor_after_move::value && + ::boost::has_trivial_destructor_after_move::value; +}; + +} + +#endif //#ifndef BOOST_CONTAINER_DOXYGEN_INVOKED + +#include + +#endif // #ifndef BOOST_CONTAINER_CONTAINER_VECTOR_HPP diff --git a/src/vendor/boost/container_hash/hash_fwd.hpp b/src/vendor/boost/container_hash/hash_fwd.hpp new file mode 100644 index 000000000..46340b3f4 --- /dev/null +++ b/src/vendor/boost/container_hash/hash_fwd.hpp @@ -0,0 +1,36 @@ + +// Copyright 2005-2009 Daniel James. +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// Based on Peter Dimov's proposal +// http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1756.pdf +// issue 6.18. + +#if !defined(BOOST_FUNCTIONAL_HASH_FWD_HPP) +#define BOOST_FUNCTIONAL_HASH_FWD_HPP + +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + + +namespace boost +{ + template struct hash; + + template void hash_combine(std::size_t& seed, T const& v); + + template std::size_t hash_range(It, It); + template void hash_range(std::size_t&, It, It); + +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x551)) + template inline std::size_t hash_range(T*, T*); + template inline void hash_range(std::size_t&, T*, T*); +#endif +} + +#endif diff --git a/src/vendor/boost/core/addressof.hpp b/src/vendor/boost/core/addressof.hpp new file mode 100644 index 000000000..5473c36a5 --- /dev/null +++ b/src/vendor/boost/core/addressof.hpp @@ -0,0 +1,274 @@ +/* +Copyright (C) 2002 Brad King (brad.king@kitware.com) + Douglas Gregor (gregod@cs.rpi.edu) + +Copyright (C) 2002, 2008, 2013 Peter Dimov + +Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE_1_0.txt or copy at +http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_CORE_ADDRESSOF_HPP +#define BOOST_CORE_ADDRESSOF_HPP + +#include + +#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215 +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#elif defined(BOOST_GCC) && BOOST_GCC >= 70000 +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#elif defined(__has_builtin) +#if __has_builtin(__builtin_addressof) +#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF +#endif +#endif + +#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF) +#if defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF +#endif + +namespace boost { + +template +BOOST_CONSTEXPR inline T* +addressof(T& o) BOOST_NOEXCEPT +{ + return __builtin_addressof(o); +} + +} /* boost */ +#else +#include +#include + +namespace boost { +namespace detail { + +template +class addrof_ref { +public: + BOOST_FORCEINLINE addrof_ref(T& o) BOOST_NOEXCEPT + : o_(o) { } + BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT { + return o_; + } +private: + addrof_ref& operator=(const addrof_ref&); + T& o_; +}; + +template +struct addrof { + static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT { + return reinterpret_cast(& + const_cast(reinterpret_cast(o))); + } + static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT { + return p; + } +}; + +#if !defined(BOOST_NO_CXX11_NULLPTR) +#if !defined(BOOST_NO_CXX11_DECLTYPE) && \ + (defined(__INTEL_COMPILER) || \ + (defined(__clang__) && !defined(_LIBCPP_VERSION))) +typedef decltype(nullptr) addrof_null_t; +#else +typedef std::nullptr_t addrof_null_t; +#endif + +template<> +struct addrof { + typedef addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; + +template<> +struct addrof { + typedef const addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; + +template<> +struct addrof { + typedef volatile addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; + +template<> +struct addrof { + typedef const volatile addrof_null_t type; + static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT { + return &o; + } +}; +#endif + +} /* detail */ + +#if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \ + defined(BOOST_NO_CXX11_CONSTEXPR) || \ + defined(BOOST_NO_CXX11_DECLTYPE) +#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF + +template +BOOST_FORCEINLINE T* +addressof(T& o) BOOST_NOEXCEPT +{ +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x610)) || \ + BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120) + return boost::detail::addrof::get(o, 0); +#else + return boost::detail::addrof::get(boost::detail::addrof_ref(o), 0); +#endif +} + +#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) +namespace detail { + +template +struct addrof_result { + typedef T* type; +}; + +} /* detail */ + +template +BOOST_FORCEINLINE typename boost::detail::addrof_result::type +addressof(T (&o)[N]) BOOST_NOEXCEPT +{ + return &o; +} +#endif + +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) +template +BOOST_FORCEINLINE +T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N] +{ + return reinterpret_cast(&o); +} + +template +BOOST_FORCEINLINE +const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N] +{ + return reinterpret_cast(&o); +} +#endif +#else +namespace detail { + +template +T addrof_declval() BOOST_NOEXCEPT; + +template +struct addrof_void { + typedef void type; +}; + +template +struct addrof_member_operator { + static constexpr bool value = false; +}; + +template +struct addrof_member_operator().operator&())>::type> { + static constexpr bool value = true; +}; + +#if BOOST_WORKAROUND(BOOST_INTEL, < 1600) +struct addrof_addressable { }; + +addrof_addressable* +operator&(addrof_addressable&) BOOST_NOEXCEPT; +#endif + +template +struct addrof_non_member_operator { + static constexpr bool value = false; +}; + +template +struct addrof_non_member_operator()))>::type> { + static constexpr bool value = true; +}; + +template +struct addrof_expression { + static constexpr bool value = false; +}; + +template +struct addrof_expression())>::type> { + static constexpr bool value = true; +}; + +template +struct addrof_is_constexpr { + static constexpr bool value = addrof_expression::value && + !addrof_member_operator::value && + !addrof_non_member_operator::value; +}; + +template +struct addrof_if { }; + +template +struct addrof_if { + typedef T* type; +}; + +template +BOOST_FORCEINLINE +typename addrof_if::value, T>::type +addressof(T& o) BOOST_NOEXCEPT +{ + return addrof::get(addrof_ref(o), 0); +} + +template +constexpr BOOST_FORCEINLINE +typename addrof_if::value, T>::type +addressof(T& o) BOOST_NOEXCEPT +{ + return &o; +} + +} /* detail */ + +template +constexpr BOOST_FORCEINLINE T* +addressof(T& o) BOOST_NOEXCEPT +{ + return boost::detail::addressof(o); +} +#endif + +} /* boost */ +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +namespace boost { + +template +const T* addressof(const T&&) = delete; + +} /* boost */ +#endif + +#endif diff --git a/src/vendor/boost/core/checked_delete.hpp b/src/vendor/boost/core/checked_delete.hpp new file mode 100644 index 000000000..6af5c1411 --- /dev/null +++ b/src/vendor/boost/core/checked_delete.hpp @@ -0,0 +1,71 @@ +#ifndef BOOST_CORE_CHECKED_DELETE_HPP +#define BOOST_CORE_CHECKED_DELETE_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include + +// +// boost/checked_delete.hpp +// +// Copyright (c) 2002, 2003 Peter Dimov +// Copyright (c) 2003 Daniel Frey +// Copyright (c) 2003 Howard Hinnant +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/core/doc/html/core/checked_delete.html for documentation. +// + +namespace boost +{ + +// verify that types are complete for increased safety + +template inline void checked_delete(T * x) BOOST_NOEXCEPT +{ + // intentionally complex - simplification causes regressions + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete x; +} + +template inline void checked_array_delete(T * x) BOOST_NOEXCEPT +{ + typedef char type_must_be_complete[ sizeof(T)? 1: -1 ]; + (void) sizeof(type_must_be_complete); + delete [] x; +} + +template struct checked_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const BOOST_NOEXCEPT + { + // boost:: disables ADL + boost::checked_delete(x); + } +}; + +template struct checked_array_deleter +{ + typedef void result_type; + typedef T * argument_type; + + void operator()(T * x) const BOOST_NOEXCEPT + { + boost::checked_array_delete(x); + } +}; + +} // namespace boost + +#endif // #ifndef BOOST_CORE_CHECKED_DELETE_HPP diff --git a/src/vendor/boost/core/demangle.hpp b/src/vendor/boost/core/demangle.hpp new file mode 100644 index 000000000..dc714d806 --- /dev/null +++ b/src/vendor/boost/core/demangle.hpp @@ -0,0 +1,126 @@ +#ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED +#define BOOST_CORE_DEMANGLE_HPP_INCLUDED + +// core::demangle +// +// Copyright 2014 Peter Dimov +// Copyright 2014 Andrey Semashev +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +// __has_include is currently supported by GCC and Clang. However GCC 4.9 may have issues and +// returns 1 for 'defined( __has_include )', while '__has_include' is actually not supported: +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63662 +#if defined( __has_include ) && (!defined( BOOST_GCC ) || (__GNUC__ + 0) >= 5) +# if __has_include() +# define BOOST_CORE_HAS_CXXABI_H +# endif +#elif defined( __GLIBCXX__ ) || defined( __GLIBCPP__ ) +# define BOOST_CORE_HAS_CXXABI_H +#endif + +#if defined( BOOST_CORE_HAS_CXXABI_H ) +# include +// For some archtectures (mips, mips64, x86, x86_64) cxxabi.h in Android NDK is implemented by gabi++ library +// (https://android.googlesource.com/platform/ndk/+/master/sources/cxx-stl/gabi++/), which does not implement +// abi::__cxa_demangle(). We detect this implementation by checking the include guard here. +# if defined( __GABIXX_CXXABI_H__ ) +# undef BOOST_CORE_HAS_CXXABI_H +# else +# include +# include +# endif +#endif + +namespace boost +{ + +namespace core +{ + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT; +inline void demangle_free( char const * name ) BOOST_NOEXCEPT; + +class scoped_demangled_name +{ +private: + char const * m_p; + +public: + explicit scoped_demangled_name( char const * name ) BOOST_NOEXCEPT : + m_p( demangle_alloc( name ) ) + { + } + + ~scoped_demangled_name() BOOST_NOEXCEPT + { + demangle_free( m_p ); + } + + char const * get() const BOOST_NOEXCEPT + { + return m_p; + } + + BOOST_DELETED_FUNCTION(scoped_demangled_name( scoped_demangled_name const& )) + BOOST_DELETED_FUNCTION(scoped_demangled_name& operator= ( scoped_demangled_name const& )) +}; + + +#if defined( BOOST_CORE_HAS_CXXABI_H ) + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT +{ + int status = 0; + std::size_t size = 0; + return abi::__cxa_demangle( name, NULL, &size, &status ); +} + +inline void demangle_free( char const * name ) BOOST_NOEXCEPT +{ + std::free( const_cast< char* >( name ) ); +} + +inline std::string demangle( char const * name ) +{ + scoped_demangled_name demangled_name( name ); + char const * p = demangled_name.get(); + if( !p ) + p = name; + return p; +} + +#else + +inline char const * demangle_alloc( char const * name ) BOOST_NOEXCEPT +{ + return name; +} + +inline void demangle_free( char const * ) BOOST_NOEXCEPT +{ +} + +inline std::string demangle( char const * name ) +{ + return name; +} + +#endif + +} // namespace core + +} // namespace boost + +#undef BOOST_CORE_HAS_CXXABI_H + +#endif // #ifndef BOOST_CORE_DEMANGLE_HPP_INCLUDED diff --git a/src/vendor/boost/core/enable_if.hpp b/src/vendor/boost/core/enable_if.hpp new file mode 100644 index 000000000..5dcef1e03 --- /dev/null +++ b/src/vendor/boost/core/enable_if.hpp @@ -0,0 +1,128 @@ +// Boost enable_if library + +// Copyright 2003 (c) The Trustees of Indiana University. + +// Use, modification, and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// Authors: Jaakko Jarvi (jajarvi at osl.iu.edu) +// Jeremiah Willcock (jewillco at osl.iu.edu) +// Andrew Lumsdaine (lums at osl.iu.edu) + + +#ifndef BOOST_CORE_ENABLE_IF_HPP +#define BOOST_CORE_ENABLE_IF_HPP + +#include "boost/config.hpp" + +// Even the definition of enable_if causes problems on some compilers, +// so it's macroed out for all compilers that do not support SFINAE + +#ifndef BOOST_NO_SFINAE + +namespace boost +{ + template + struct enable_if_has_type + { + typedef R type; + }; + + template + struct enable_if_c { + typedef T type; + }; + + template + struct enable_if_c {}; + + template + struct enable_if : public enable_if_c {}; + + template + struct lazy_enable_if_c { + typedef typename T::type type; + }; + + template + struct lazy_enable_if_c {}; + + template + struct lazy_enable_if : public lazy_enable_if_c {}; + + + template + struct disable_if_c { + typedef T type; + }; + + template + struct disable_if_c {}; + + template + struct disable_if : public disable_if_c {}; + + template + struct lazy_disable_if_c { + typedef typename T::type type; + }; + + template + struct lazy_disable_if_c {}; + + template + struct lazy_disable_if : public lazy_disable_if_c {}; + +} // namespace boost + +#else + +namespace boost { + + namespace detail { typedef void enable_if_default_T; } + + template + struct enable_if_does_not_work_on_this_compiler; + + template + struct enable_if_has_type : enable_if_does_not_work_on_this_compiler + { }; + + template + struct enable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct disable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_enable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_disable_if_c : enable_if_does_not_work_on_this_compiler + { }; + + template + struct enable_if : enable_if_does_not_work_on_this_compiler + { }; + + template + struct disable_if : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_enable_if : enable_if_does_not_work_on_this_compiler + { }; + + template + struct lazy_disable_if : enable_if_does_not_work_on_this_compiler + { }; + +} // namespace boost + +#endif // BOOST_NO_SFINAE + +#endif diff --git a/src/vendor/boost/core/ignore_unused.hpp b/src/vendor/boost/core/ignore_unused.hpp new file mode 100644 index 000000000..994e5f647 --- /dev/null +++ b/src/vendor/boost/core/ignore_unused.hpp @@ -0,0 +1,70 @@ +// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. +// +// Use, modification and distribution is subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_CORE_IGNORE_UNUSED_HPP +#define BOOST_CORE_IGNORE_UNUSED_HPP + +#include + +namespace boost { + +#ifndef BOOST_NO_CXX11_VARIADIC_TEMPLATES + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(Ts const& ...) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +#else + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused(T1 const&, T2 const&, T3 const&, T4 const&, T5 const&) +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +template +BOOST_FORCEINLINE BOOST_CXX14_CONSTEXPR void ignore_unused() +{} + +#endif + +} // namespace boost + +#endif // BOOST_CORE_IGNORE_UNUSED_HPP diff --git a/src/vendor/boost/core/is_same.hpp b/src/vendor/boost/core/is_same.hpp new file mode 100644 index 000000000..f373c654d --- /dev/null +++ b/src/vendor/boost/core/is_same.hpp @@ -0,0 +1,40 @@ +#ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED +#define BOOST_CORE_IS_SAME_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// is_same::value is true when T1 == T2 +// +// Copyright 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include + +namespace boost +{ + +namespace core +{ + +template< class T1, class T2 > struct is_same +{ + BOOST_STATIC_CONSTANT( bool, value = false ); +}; + +template< class T > struct is_same< T, T > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +} // namespace core + +} // namespace boost + +#endif // #ifndef BOOST_CORE_IS_SAME_HPP_INCLUDED diff --git a/src/vendor/boost/core/no_exceptions_support.hpp b/src/vendor/boost/core/no_exceptions_support.hpp new file mode 100644 index 000000000..1278e8568 --- /dev/null +++ b/src/vendor/boost/core/no_exceptions_support.hpp @@ -0,0 +1,56 @@ +#ifndef BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP +#define BOOST_CORE_NO_EXCEPTIONS_SUPPORT_HPP + +#if defined(_MSC_VER) +# pragma once +#endif + +//---------------------------------------------------------------------- +// (C) Copyright 2004 Pavel Vozenilek. +// Use, modification and distribution is subject to the Boost Software +// License, Version 1.0. (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// +// This file contains helper macros used when exception support may be +// disabled (as indicated by macro BOOST_NO_EXCEPTIONS). +// +// Before picking up these macros you may consider using RAII techniques +// to deal with exceptions - their syntax can be always the same with +// or without exception support enabled. +//---------------------------------------------------------------------- + +#include +#include + +#if !(defined BOOST_NO_EXCEPTIONS) +# define BOOST_TRY { try +# define BOOST_CATCH(x) catch(x) +# define BOOST_RETHROW throw; +# define BOOST_CATCH_END } +#else +# if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) +# define BOOST_TRY { if ("") +# define BOOST_CATCH(x) else if (!"") +# elif !defined(BOOST_MSVC) || BOOST_MSVC >= 1900 +# define BOOST_TRY { if (true) +# define BOOST_CATCH(x) else if (false) +# else + // warning C4127: conditional expression is constant +# define BOOST_TRY { \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (true) \ + __pragma(warning(pop)) +# define BOOST_CATCH(x) else \ + __pragma(warning(push)) \ + __pragma(warning(disable: 4127)) \ + if (false) \ + __pragma(warning(pop)) +# endif +# define BOOST_RETHROW +# define BOOST_CATCH_END } +#endif + + +#endif diff --git a/src/vendor/boost/core/noncopyable.hpp b/src/vendor/boost/core/noncopyable.hpp new file mode 100644 index 000000000..4a4f8baba --- /dev/null +++ b/src/vendor/boost/core/noncopyable.hpp @@ -0,0 +1,63 @@ +// Boost noncopyable.hpp header file --------------------------------------// + +// (C) Copyright Beman Dawes 1999-2003. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/utility for documentation. + +#ifndef BOOST_CORE_NONCOPYABLE_HPP +#define BOOST_CORE_NONCOPYABLE_HPP + +#include + +namespace boost { + +// Private copy constructor and copy assignment ensure classes derived from +// class noncopyable cannot be copied. + +// Contributed by Dave Abrahams + +namespace noncopyable_ // protection from unintended ADL +{ +#ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED +#define BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED + +// noncopyable derives from base_token to enable Type Traits to detect +// whether a type derives from noncopyable without needing the definition +// of noncopyable itself. +// +// The definition of base_token is macro-guarded so that Type Trais can +// define it locally without including this header, to avoid a dependency +// on Core. + + struct base_token {}; + +#endif // #ifndef BOOST_NONCOPYABLE_BASE_TOKEN_DEFINED + + class noncopyable: base_token + { + protected: +#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && !defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS) + BOOST_CONSTEXPR noncopyable() = default; + ~noncopyable() = default; +#else + noncopyable() {} + ~noncopyable() {} +#endif +#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) + noncopyable( const noncopyable& ) = delete; + noncopyable& operator=( const noncopyable& ) = delete; +#else + private: // emphasize the following members are private + noncopyable( const noncopyable& ); + noncopyable& operator=( const noncopyable& ); +#endif + }; +} + +typedef noncopyable_::noncopyable noncopyable; + +} // namespace boost + +#endif // BOOST_CORE_NONCOPYABLE_HPP diff --git a/src/vendor/boost/core/ref.hpp b/src/vendor/boost/core/ref.hpp new file mode 100644 index 000000000..79f0b63c8 --- /dev/null +++ b/src/vendor/boost/core/ref.hpp @@ -0,0 +1,302 @@ +#ifndef BOOST_CORE_REF_HPP +#define BOOST_CORE_REF_HPP + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +#include +#include +#include + +// +// ref.hpp - ref/cref, useful helper functions +// +// Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi) +// Copyright (C) 2001, 2002 Peter Dimov +// Copyright (C) 2002 David Abrahams +// +// Copyright (C) 2014 Glen Joseph Fernandes +// (glenjofe@gmail.com) +// +// Copyright (C) 2014 Agustin Berge +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/core/doc/html/core/ref.html for documentation. +// + +/** + @file +*/ + +/** + Boost namespace. +*/ +namespace boost +{ + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + struct ref_workaround_tag {}; + +#endif + +// reference_wrapper + +/** + @brief Contains a reference to an object of type `T`. + + `reference_wrapper` is primarily used to "feed" references to + function templates (algorithms) that take their parameter by + value. It provides an implicit conversion to `T&`, which + usually allows the function templates to work on references + unmodified. +*/ +template class reference_wrapper +{ +public: + /** + Type `T`. + */ + typedef T type; + + /** + Constructs a `reference_wrapper` object that stores a + reference to `t`. + + @remark Does not throw. + */ + BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + BOOST_FORCEINLINE explicit reference_wrapper( T & t, ref_workaround_tag ): t_( boost::addressof( t ) ) {} + +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + /** + @remark Construction from a temporary object is disabled. + */ + BOOST_DELETED_FUNCTION(reference_wrapper(T&& t)) +public: +#endif + + /** + @return The stored reference. + @remark Does not throw. + */ + BOOST_FORCEINLINE operator T& () const { return *t_; } + + /** + @return The stored reference. + @remark Does not throw. + */ + BOOST_FORCEINLINE T& get() const { return *t_; } + + /** + @return A pointer to the object referenced by the stored + reference. + @remark Does not throw. + */ + BOOST_FORCEINLINE T* get_pointer() const { return t_; } + +private: + + T* t_; +}; + +// ref + +/** + @cond +*/ +#if defined( BOOST_BORLANDC ) && BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) ) +# define BOOST_REF_CONST +#else +# define BOOST_REF_CONST const +#endif +/** + @endcond +*/ + +/** + @return `reference_wrapper(t)` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST ref( T & t ) +{ +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, == 1600 ) + + return reference_wrapper( t, ref_workaround_tag() ); + +#else + + return reference_wrapper( t ); + +#endif +} + +// cref + +/** + @return `reference_wrapper(t)` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST cref( T const & t ) +{ + return reference_wrapper(t); +} + +#undef BOOST_REF_CONST + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +/** + @cond +*/ +#if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_REF_DELETE +#else +# define BOOST_REF_DELETE = delete +#endif +/** + @endcond +*/ + +/** + @remark Construction from a temporary object is disabled. +*/ +template void ref(T const&&) BOOST_REF_DELETE; + +/** + @remark Construction from a temporary object is disabled. +*/ +template void cref(T const&&) BOOST_REF_DELETE; + +#undef BOOST_REF_DELETE + +#endif + +// is_reference_wrapper + +/** + @brief Determine if a type `T` is an instantiation of + `reference_wrapper`. + + The value static constant will be true if the type `T` is a + specialization of `reference_wrapper`. +*/ +template struct is_reference_wrapper +{ + BOOST_STATIC_CONSTANT( bool, value = false ); +}; + +/** + @cond +*/ +template struct is_reference_wrapper< reference_wrapper > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +#if !defined(BOOST_NO_CV_SPECIALIZATIONS) + +template struct is_reference_wrapper< reference_wrapper const > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +template struct is_reference_wrapper< reference_wrapper volatile > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +template struct is_reference_wrapper< reference_wrapper const volatile > +{ + BOOST_STATIC_CONSTANT( bool, value = true ); +}; + +#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS) + +/** + @endcond +*/ + + +// unwrap_reference + +/** + @brief Find the type in a `reference_wrapper`. + + The `typedef` type is `T::type` if `T` is a + `reference_wrapper`, `T` otherwise. +*/ +template struct unwrap_reference +{ + typedef T type; +}; + +/** + @cond +*/ +template struct unwrap_reference< reference_wrapper > +{ + typedef T type; +}; + +#if !defined(BOOST_NO_CV_SPECIALIZATIONS) + +template struct unwrap_reference< reference_wrapper const > +{ + typedef T type; +}; + +template struct unwrap_reference< reference_wrapper volatile > +{ + typedef T type; +}; + +template struct unwrap_reference< reference_wrapper const volatile > +{ + typedef T type; +}; + +#endif // !defined(BOOST_NO_CV_SPECIALIZATIONS) + +/** + @endcond +*/ + +// unwrap_ref + +/** + @return `unwrap_reference::type&(t)` + @remark Does not throw. +*/ +template BOOST_FORCEINLINE typename unwrap_reference::type& unwrap_ref( T & t ) +{ + return t; +} + +// get_pointer + +/** + @cond +*/ +template BOOST_FORCEINLINE T* get_pointer( reference_wrapper const & r ) +{ + return r.get_pointer(); +} +/** + @endcond +*/ + +} // namespace boost + +#endif // #ifndef BOOST_CORE_REF_HPP diff --git a/src/vendor/boost/core/swap.hpp b/src/vendor/boost/core/swap.hpp new file mode 100644 index 000000000..49e1b2dbb --- /dev/null +++ b/src/vendor/boost/core/swap.hpp @@ -0,0 +1,70 @@ +// Copyright (C) 2007, 2008 Steven Watanabe, Joseph Gauterin, Niels Dekker +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// For more information, see http://www.boost.org + + +#ifndef BOOST_CORE_SWAP_HPP +#define BOOST_CORE_SWAP_HPP + +// Note: the implementation of this utility contains various workarounds: +// - swap_impl is put outside the boost namespace, to avoid infinite +// recursion (causing stack overflow) when swapping objects of a primitive +// type. +// - swap_impl has a using-directive, rather than a using-declaration, +// because some compilers (including MSVC 7.1, Borland 5.9.3, and +// Intel 8.1) don't do argument-dependent lookup when it has a +// using-declaration instead. +// - boost::swap has two template arguments, instead of one, to +// avoid ambiguity when swapping objects of a Boost type that does +// not have its own boost::swap overload. + +#include +#include +#if __cplusplus >= 201103L || defined(BOOST_DINKUMWARE_STDLIB) +#include // for std::swap (C++11) +#else +#include // for std::swap (C++98) +#endif +#include // for std::size_t + +namespace boost_swap_impl +{ + // we can't use type_traits here + + template struct is_const { enum _vt { value = 0 }; }; + template struct is_const { enum _vt { value = 1 }; }; + + template + BOOST_GPU_ENABLED + void swap_impl(T& left, T& right) + { + using namespace std;//use std::swap if argument dependent lookup fails + swap(left,right); + } + + template + BOOST_GPU_ENABLED + void swap_impl(T (& left)[N], T (& right)[N]) + { + for (std::size_t i = 0; i < N; ++i) + { + ::boost_swap_impl::swap_impl(left[i], right[i]); + } + } +} + +namespace boost +{ + template + BOOST_GPU_ENABLED + typename enable_if_c< !boost_swap_impl::is_const::value && !boost_swap_impl::is_const::value >::type + swap(T1& left, T2& right) + { + ::boost_swap_impl::swap_impl(left, right); + } +} + +#endif diff --git a/src/vendor/boost/core/use_default.hpp b/src/vendor/boost/core/use_default.hpp new file mode 100644 index 000000000..9d9be79d8 --- /dev/null +++ b/src/vendor/boost/core/use_default.hpp @@ -0,0 +1,17 @@ +/* +Copyright 2019 Glen Joseph Fernandes +(glenjofe@gmail.com) + +Distributed under the Boost Software License, Version 1.0. +(http://www.boost.org/LICENSE_1_0.txt) +*/ +#ifndef BOOST_CORE_USE_DEFAULT_HPP +#define BOOST_CORE_USE_DEFAULT_HPP + +namespace boost { + +struct use_default { }; + +} /* boost */ + +#endif diff --git a/src/vendor/boost/cstdint.hpp b/src/vendor/boost/cstdint.hpp new file mode 100644 index 000000000..967aacfd3 --- /dev/null +++ b/src/vendor/boost/cstdint.hpp @@ -0,0 +1,556 @@ +// boost cstdint.hpp header file ------------------------------------------// + +// (C) Copyright Beman Dawes 1999. +// (C) Copyright Jens Mauer 2001 +// (C) Copyright John Maddock 2001 +// Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 31 Oct 01 use BOOST_HAS_LONG_LONG to check for "long long" (Jens M.) +// 16 Apr 01 check LONGLONG_MAX when looking for "long long" (Jens Maurer) +// 23 Jan 01 prefer "long" over "int" for int32_t and intmax_t (Jens Maurer) +// 12 Nov 00 Merged (Jens Maurer) +// 23 Sep 00 Added INTXX_C macro support (John Maddock). +// 22 Sep 00 Better 64-bit support (John Maddock) +// 29 Jun 00 Reimplement to avoid including stdint.h within namespace boost +// 8 Aug 99 Initial version (Beman Dawes) + + +#ifndef BOOST_CSTDINT_HPP +#define BOOST_CSTDINT_HPP + +// +// Since we always define the INT#_C macros as per C++0x, +// define __STDC_CONSTANT_MACROS so that does the right +// thing if possible, and so that the user knows that the macros +// are actually defined as per C99. +// +#ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS +#endif + +#include +// +// For the following code we get several warnings along the lines of: +// +// boost/cstdint.hpp:428:35: error: use of C99 long long integer constant +// +// So we declare this a system header to suppress these warnings. +// See also https://github.com/boostorg/config/issues/190 +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +// +// Note that GLIBC is a bit inconsistent about whether int64_t is defined or not +// depending upon what headers happen to have been included first... +// so we disable use of stdint.h when GLIBC does not define __GLIBC_HAVE_LONG_LONG. +// See https://svn.boost.org/trac/boost/ticket/3548 and http://sources.redhat.com/bugzilla/show_bug.cgi?id=10990 +// +#if defined(BOOST_HAS_STDINT_H) \ + && (!defined(__GLIBC__) \ + || defined(__GLIBC_HAVE_LONG_LONG) \ + || (defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 17))))) + +// The following #include is an implementation artifact; not part of interface. +# ifdef __hpux +// HP-UX has a vaguely nice in a non-standard location +# include +# ifdef __STDC_32_MODE__ + // this is triggered with GCC, because it defines __cplusplus < 199707L +# define BOOST_NO_INT64_T +# endif +# elif defined(__FreeBSD__) || defined(__IBMCPP__) || defined(_AIX) +# include +# else +# include + +// There is a bug in Cygwin two _C macros +# if defined(INTMAX_C) && defined(__CYGWIN__) +# undef INTMAX_C +# undef UINTMAX_C +# define INTMAX_C(c) c##LL +# define UINTMAX_C(c) c##ULL +# endif + +# endif + +#if defined(__QNX__) && defined(__EXT_QNX) + +// QNX (Dinkumware stdlib) defines these as non-standard names. +// Reflect to the standard names. + +typedef ::intleast8_t int_least8_t; +typedef ::intfast8_t int_fast8_t; +typedef ::uintleast8_t uint_least8_t; +typedef ::uintfast8_t uint_fast8_t; + +typedef ::intleast16_t int_least16_t; +typedef ::intfast16_t int_fast16_t; +typedef ::uintleast16_t uint_least16_t; +typedef ::uintfast16_t uint_fast16_t; + +typedef ::intleast32_t int_least32_t; +typedef ::intfast32_t int_fast32_t; +typedef ::uintleast32_t uint_least32_t; +typedef ::uintfast32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + +typedef ::intleast64_t int_least64_t; +typedef ::intfast64_t int_fast64_t; +typedef ::uintleast64_t uint_least64_t; +typedef ::uintfast64_t uint_fast64_t; + +# endif + +#endif + +namespace boost +{ + + using ::int8_t; + using ::int_least8_t; + using ::int_fast8_t; + using ::uint8_t; + using ::uint_least8_t; + using ::uint_fast8_t; + + using ::int16_t; + using ::int_least16_t; + using ::int_fast16_t; + using ::uint16_t; + using ::uint_least16_t; + using ::uint_fast16_t; + + using ::int32_t; + using ::int_least32_t; + using ::int_fast32_t; + using ::uint32_t; + using ::uint_least32_t; + using ::uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + using ::int_least64_t; + using ::int_fast64_t; + using ::uint64_t; + using ::uint_least64_t; + using ::uint_fast64_t; + +# endif + + using ::intmax_t; + using ::uintmax_t; + +} // namespace boost + +#elif defined(__FreeBSD__) && (__FreeBSD__ <= 4) || defined(__osf__) || defined(__VMS) || defined(__SOLARIS9__) || defined(__NetBSD__) +// FreeBSD and Tru64 have an that contains much of what we need. +# include + +namespace boost { + + using ::int8_t; + typedef int8_t int_least8_t; + typedef int8_t int_fast8_t; + using ::uint8_t; + typedef uint8_t uint_least8_t; + typedef uint8_t uint_fast8_t; + + using ::int16_t; + typedef int16_t int_least16_t; + typedef int16_t int_fast16_t; + using ::uint16_t; + typedef uint16_t uint_least16_t; + typedef uint16_t uint_fast16_t; + + using ::int32_t; + typedef int32_t int_least32_t; + typedef int32_t int_fast32_t; + using ::uint32_t; + typedef uint32_t uint_least32_t; + typedef uint32_t uint_fast32_t; + +# ifndef BOOST_NO_INT64_T + + using ::int64_t; + typedef int64_t int_least64_t; + typedef int64_t int_fast64_t; + using ::uint64_t; + typedef uint64_t uint_least64_t; + typedef uint64_t uint_fast64_t; + + typedef int64_t intmax_t; + typedef uint64_t uintmax_t; + +# else + + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; + +# endif + +} // namespace boost + +#else // BOOST_HAS_STDINT_H + +# include // implementation artifact; not part of interface +# include // needed for limits macros + + +namespace boost +{ + +// These are fairly safe guesses for some 16-bit, and most 32-bit and 64-bit +// platforms. For other systems, they will have to be hand tailored. +// +// Because the fast types are assumed to be the same as the undecorated types, +// it may be possible to hand tailor a more efficient implementation. Such +// an optimization may be illusionary; on the Intel x86-family 386 on, for +// example, byte arithmetic and load/stores are as fast as "int" sized ones. + +// 8-bit types ------------------------------------------------------------// + +# if UCHAR_MAX == 0xff + typedef signed char int8_t; + typedef signed char int_least8_t; + typedef signed char int_fast8_t; + typedef unsigned char uint8_t; + typedef unsigned char uint_least8_t; + typedef unsigned char uint_fast8_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 16-bit types -----------------------------------------------------------// + +# if USHRT_MAX == 0xffff +# if defined(__crayx1) + // The Cray X1 has a 16-bit short, however it is not recommend + // for use in performance critical code. + typedef short int16_t; + typedef short int_least16_t; + typedef int int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned int uint_fast16_t; +# else + typedef short int16_t; + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# endif +# elif (USHRT_MAX == 0xffffffff) && defined(__MTA__) + // On MTA / XMT short is 32 bits unless the -short16 compiler flag is specified + // MTA / XMT does support the following non-standard integer types + typedef __short16 int16_t; + typedef __short16 int_least16_t; + typedef __short16 int_fast16_t; + typedef unsigned __short16 uint16_t; + typedef unsigned __short16 uint_least16_t; + typedef unsigned __short16 uint_fast16_t; +# elif (USHRT_MAX == 0xffffffff) && defined(CRAY) + // no 16-bit types on Cray: + typedef short int_least16_t; + typedef short int_fast16_t; + typedef unsigned short uint_least16_t; + typedef unsigned short uint_fast16_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 32-bit types -----------------------------------------------------------// + +# if UINT_MAX == 0xffffffff + typedef int int32_t; + typedef int int_least32_t; + typedef int int_fast32_t; + typedef unsigned int uint32_t; + typedef unsigned int uint_least32_t; + typedef unsigned int uint_fast32_t; +# elif (USHRT_MAX == 0xffffffff) + typedef short int32_t; + typedef short int_least32_t; + typedef short int_fast32_t; + typedef unsigned short uint32_t; + typedef unsigned short uint_least32_t; + typedef unsigned short uint_fast32_t; +# elif ULONG_MAX == 0xffffffff + typedef long int32_t; + typedef long int_least32_t; + typedef long int_fast32_t; + typedef unsigned long uint32_t; + typedef unsigned long uint_least32_t; + typedef unsigned long uint_fast32_t; +# elif (UINT_MAX == 0xffffffffffffffff) && defined(__MTA__) + // Integers are 64 bits on the MTA / XMT + typedef __int32 int32_t; + typedef __int32 int_least32_t; + typedef __int32 int_fast32_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int32 uint_least32_t; + typedef unsigned __int32 uint_fast32_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// + +# if defined(BOOST_HAS_LONG_LONG) && \ + !defined(BOOST_MSVC) && !defined(BOOST_BORLANDC) && \ + (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX)) +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) + // 2**64 - 1 +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + + typedef ::boost::long_long_type intmax_t; + typedef ::boost::ulong_long_type uintmax_t; + typedef ::boost::long_long_type int64_t; + typedef ::boost::long_long_type int_least64_t; + typedef ::boost::long_long_type int_fast64_t; + typedef ::boost::ulong_long_type uint64_t; + typedef ::boost::ulong_long_type uint_least64_t; + typedef ::boost::ulong_long_type uint_fast64_t; + +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615 // 2**64 - 1 + typedef long intmax_t; + typedef unsigned long uintmax_t; + typedef long int64_t; + typedef long int_least64_t; + typedef long int_fast64_t; + typedef unsigned long uint64_t; + typedef unsigned long uint_least64_t; + typedef unsigned long uint_fast64_t; +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(__GNUC__) && defined(BOOST_HAS_LONG_LONG) + __extension__ typedef long long intmax_t; + __extension__ typedef unsigned long long uintmax_t; + __extension__ typedef long long int64_t; + __extension__ typedef long long int_least64_t; + __extension__ typedef long long int_fast64_t; + __extension__ typedef unsigned long long uint64_t; + __extension__ typedef unsigned long long uint_least64_t; + __extension__ typedef unsigned long long uint_fast64_t; +# elif defined(BOOST_HAS_MS_INT64) + // + // we have Borland/Intel/Microsoft __int64: + // + typedef __int64 intmax_t; + typedef unsigned __int64 uintmax_t; + typedef __int64 int64_t; + typedef __int64 int_least64_t; + typedef __int64 int_fast64_t; + typedef unsigned __int64 uint64_t; + typedef unsigned __int64 uint_least64_t; + typedef unsigned __int64 uint_fast64_t; +# else // assume no 64-bit integers +# define BOOST_NO_INT64_T + typedef int32_t intmax_t; + typedef uint32_t uintmax_t; +# endif + +} // namespace boost + + +#endif // BOOST_HAS_STDINT_H + +// intptr_t/uintptr_t are defined separately because they are optional and not universally available +#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H) +// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h +#include +#endif + +#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \ + || (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \ + || defined(__CYGWIN__) || defined(__VXWORKS__) \ + || defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \ + || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || (defined(sun) && !defined(BOOST_HAS_STDINT_H)) || defined(INTPTR_MAX) + +namespace boost { + using ::intptr_t; + using ::uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +// Clang pretends to be GCC, so it'll match this condition +#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__) + +namespace boost { + typedef __INTPTR_TYPE__ intptr_t; + typedef __UINTPTR_TYPE__ uintptr_t; +} +#define BOOST_HAS_INTPTR_T + +#endif + +#endif // BOOST_CSTDINT_HPP + + +/**************************************************** + +Macro definition section: + +Added 23rd September 2000 (John Maddock). +Modified 11th September 2001 to be excluded when +BOOST_HAS_STDINT_H is defined (John Maddock). +Modified 11th Dec 2009 to always define the +INT#_C macros if they're not already defined (John Maddock). + +******************************************************/ + +#if !defined(BOOST__STDC_CONSTANT_MACROS_DEFINED) && \ + (!defined(INT8_C) || !defined(INT16_C) || !defined(INT32_C) || !defined(INT64_C)) +// +// Undef the macros as a precaution, since we may get here if has failed +// to define them all, see https://svn.boost.org/trac/boost/ticket/12786 +// +#undef INT8_C +#undef INT16_C +#undef INT32_C +#undef INT64_C +#undef INTMAX_C +#undef UINT8_C +#undef UINT16_C +#undef UINT32_C +#undef UINT64_C +#undef UINTMAX_C + +#include +# define BOOST__STDC_CONSTANT_MACROS_DEFINED +# if defined(BOOST_HAS_MS_INT64) +// +// Borland/Intel/Microsoft compilers have width specific suffixes: +// +#ifndef INT8_C +# define INT8_C(value) value##i8 +#endif +#ifndef INT16_C +# define INT16_C(value) value##i16 +#endif +#ifndef INT32_C +# define INT32_C(value) value##i32 +#endif +#ifndef INT64_C +# define INT64_C(value) value##i64 +#endif +# ifdef BOOST_BORLANDC + // Borland bug: appending ui8 makes the type a signed char +# define UINT8_C(value) static_cast(value##u) +# else +# define UINT8_C(value) value##ui8 +# endif +#ifndef UINT16_C +# define UINT16_C(value) value##ui16 +#endif +#ifndef UINT32_C +# define UINT32_C(value) value##ui32 +#endif +#ifndef UINT64_C +# define UINT64_C(value) value##ui64 +#endif +#ifndef INTMAX_C +# define INTMAX_C(value) value##i64 +# define UINTMAX_C(value) value##ui64 +#endif + +# else +// do it the old fashioned way: + +// 8-bit types ------------------------------------------------------------// + +# if (UCHAR_MAX == 0xff) && !defined(INT8_C) +# define INT8_C(value) static_cast(value) +# define UINT8_C(value) static_cast(value##u) +# endif + +// 16-bit types -----------------------------------------------------------// + +# if (USHRT_MAX == 0xffff) && !defined(INT16_C) +# define INT16_C(value) static_cast(value) +# define UINT16_C(value) static_cast(value##u) +# endif + +// 32-bit types -----------------------------------------------------------// +#ifndef INT32_C +# if (UINT_MAX == 0xffffffff) +# define INT32_C(value) value +# define UINT32_C(value) value##u +# elif ULONG_MAX == 0xffffffff +# define INT32_C(value) value##L +# define UINT32_C(value) value##uL +# endif +#endif + +// 64-bit types + intmax_t and uintmax_t ----------------------------------// +#ifndef INT64_C +# if defined(BOOST_HAS_LONG_LONG) && \ + (defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) || defined(ULONGLONG_MAX) || defined(_ULLONG_MAX) || defined(_LLONG_MAX)) + +# if defined(__hpux) + // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# elif (defined(ULLONG_MAX) && ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONG_LONG_MAX) && ULONG_LONG_MAX == 18446744073709551615ULL) || \ + (defined(ULONGLONG_MAX) && ULONGLONG_MAX == 18446744073709551615ULL) || \ + (defined(_ULLONG_MAX) && _ULLONG_MAX == 18446744073709551615ULL) || \ + (defined(_LLONG_MAX) && _LLONG_MAX == 9223372036854775807LL) + +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif ULONG_MAX != 0xffffffff + +# if ULONG_MAX == 18446744073709551615U // 2**64 - 1 +# define INT64_C(value) value##L +# define UINT64_C(value) value##uL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# elif defined(BOOST_HAS_LONG_LONG) + // Usual macros not defined, work things out for ourselves: +# if(~0uLL == 18446744073709551615ULL) +# define INT64_C(value) value##LL +# define UINT64_C(value) value##uLL +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif +# else +# error defaults not correct; you must hand modify boost/cstdint.hpp +# endif + +# ifdef BOOST_NO_INT64_T +# define INTMAX_C(value) INT32_C(value) +# define UINTMAX_C(value) UINT32_C(value) +# else +# define INTMAX_C(value) INT64_C(value) +# define UINTMAX_C(value) UINT64_C(value) +# endif +#endif +# endif // Borland/Microsoft specific width suffixes + +#endif // INT#_C macros. + + + + diff --git a/src/vendor/boost/current_function.hpp b/src/vendor/boost/current_function.hpp new file mode 100644 index 000000000..731d1b13e --- /dev/null +++ b/src/vendor/boost/current_function.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED +#define BOOST_CURRENT_FUNCTION_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/current_function.hpp - BOOST_CURRENT_FUNCTION +// +// Copyright 2002-2018 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// +// http://www.boost.org/libs/assert +// + +namespace boost +{ + +namespace detail +{ + +inline void current_function_helper() +{ + +#if defined( BOOST_DISABLE_CURRENT_FUNCTION ) + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#elif defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) || defined(__clang__) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__DMC__) && (__DMC__ >= 0x810) + +# define BOOST_CURRENT_FUNCTION __PRETTY_FUNCTION__ + +#elif defined(__FUNCSIG__) + +# define BOOST_CURRENT_FUNCTION __FUNCSIG__ + +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + +# define BOOST_CURRENT_FUNCTION __FUNCTION__ + +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + +# define BOOST_CURRENT_FUNCTION __FUNC__ + +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + +# define BOOST_CURRENT_FUNCTION __func__ + +#elif defined(__cplusplus) && (__cplusplus >= 201103) + +# define BOOST_CURRENT_FUNCTION __func__ + +#else + +# define BOOST_CURRENT_FUNCTION "(unknown)" + +#endif + +} + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_CURRENT_FUNCTION_HPP_INCLUDED diff --git a/src/vendor/boost/date_time/adjust_functors.hpp b/src/vendor/boost/date_time/adjust_functors.hpp new file mode 100644 index 000000000..ec2a70765 --- /dev/null +++ b/src/vendor/boost/date_time/adjust_functors.hpp @@ -0,0 +1,164 @@ +#ifndef _DATE_TIME_ADJUST_FUNCTORS_HPP___ +#define _DATE_TIME_ADJUST_FUNCTORS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/wrapping_int.hpp" + +namespace boost { +namespace date_time { + + + //! Functor to iterate a fixed number of days + template + class day_functor + { + public: + typedef typename date_type::duration_type duration_type; + day_functor(int f) : f_(f) {} + duration_type get_offset(const date_type&) const + { + return duration_type(f_); + } + duration_type get_neg_offset(const date_type&) const + { + return duration_type(-f_); + } + private: + int f_; + }; + + + //! Provides calculation to find next nth month given a date + /*! This adjustment function provides the logic for 'month-based' + * advancement on a ymd based calendar. The policy it uses + * to handle the non existant end of month days is to back + * up to the last day of the month. Also, if the starting + * date is the last day of a month, this functor will attempt + * to adjust to the end of the month. + + */ + template + class month_functor + { + public: + typedef typename date_type::duration_type duration_type; + typedef typename date_type::calendar_type cal_type; + typedef typename cal_type::ymd_type ymd_type; + typedef typename cal_type::day_type day_type; + + month_functor(int f) : f_(f), origDayOfMonth_(0) {} + duration_type get_offset(const date_type& d) const + { + ymd_type ymd(d.year_month_day()); + if (origDayOfMonth_ == 0) { + origDayOfMonth_ = ymd.day; + day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month)); + if (endOfMonthDay == ymd.day) { + origDayOfMonth_ = -1; //force the value to the end of month + } + } + typedef date_time::wrapping_int2 wrap_int2; + wrap_int2 wi(ymd.month); + //calc the year wrap around, add() returns 0 or 1 if wrapped + const typename ymd_type::year_type year(static_cast(ymd.year + wi.add(f_))); +// std::cout << "trace wi: " << wi.as_int() << std::endl; +// std::cout << "trace year: " << year << std::endl; + //find the last day for the new month + day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int())); + //original was the end of month -- force to last day of month + if (origDayOfMonth_ == -1) { + return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d; + } + day_type dayOfMonth = origDayOfMonth_; + if (dayOfMonth > resultingEndOfMonthDay) { + dayOfMonth = resultingEndOfMonthDay; + } + return date_type(year, wi.as_int(), dayOfMonth) - d; + } + //! Returns a negative duration_type + duration_type get_neg_offset(const date_type& d) const + { + ymd_type ymd(d.year_month_day()); + if (origDayOfMonth_ == 0) { + origDayOfMonth_ = ymd.day; + day_type endOfMonthDay(cal_type::end_of_month_day(ymd.year,ymd.month)); + if (endOfMonthDay == ymd.day) { + origDayOfMonth_ = -1; //force the value to the end of month + } + } + typedef date_time::wrapping_int2 wrap_int2; + wrap_int2 wi(ymd.month); + //calc the year wrap around, add() returns 0 or 1 if wrapped + const typename ymd_type::year_type year(static_cast(ymd.year + wi.subtract(f_))); + //find the last day for the new month + day_type resultingEndOfMonthDay(cal_type::end_of_month_day(year, wi.as_int())); + //original was the end of month -- force to last day of month + if (origDayOfMonth_ == -1) { + return date_type(year, wi.as_int(), resultingEndOfMonthDay) - d; + } + day_type dayOfMonth = origDayOfMonth_; + if (dayOfMonth > resultingEndOfMonthDay) { + dayOfMonth = resultingEndOfMonthDay; + } + return date_type(year, wi.as_int(), dayOfMonth) - d; + } + private: + int f_; + mutable short origDayOfMonth_; + }; + + + //! Functor to iterate a over weeks + template + class week_functor + { + public: + typedef typename date_type::duration_type duration_type; + typedef typename date_type::calendar_type calendar_type; + week_functor(int f) : f_(f) {} + duration_type get_offset(const date_type&) const + { + return duration_type(f_*static_cast(calendar_type::days_in_week())); + } + duration_type get_neg_offset(const date_type&) const + { + return duration_type(-f_*static_cast(calendar_type::days_in_week())); + } + private: + int f_; + }; + + //! Functor to iterate by a year adjusting for leap years + template + class year_functor + { + public: + //typedef typename date_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + year_functor(int f) : _mf(f * 12) {} + duration_type get_offset(const date_type& d) const + { + return _mf.get_offset(d); + } + duration_type get_neg_offset(const date_type& d) const + { + return _mf.get_neg_offset(d); + } + private: + month_functor _mf; + }; + + +} }//namespace date_time + + +#endif + diff --git a/src/vendor/boost/date_time/c_time.hpp b/src/vendor/boost/date_time/c_time.hpp new file mode 100644 index 000000000..e23960b7a --- /dev/null +++ b/src/vendor/boost/date_time/c_time.hpp @@ -0,0 +1,128 @@ +#ifndef DATE_TIME_C_TIME_HPP___ +#define DATE_TIME_C_TIME_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +/*! @file c_time.hpp + Provide workarounds related to the ctime header +*/ + +#include +#include // to be able to convert from string literals to exceptions +#include +#include +#include + +//Work around libraries that don't put time_t and time in namespace std +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::time_t; using ::time; using ::localtime; + using ::tm; using ::gmtime; } +#endif // BOOST_NO_STDC_NAMESPACE + +//The following is used to support high precision time clocks +#ifdef BOOST_HAS_GETTIMEOFDAY +#include +#endif + +#ifdef BOOST_HAS_FTIME +#include +#endif + +namespace boost { +namespace date_time { + //! Provides a uniform interface to some 'ctime' functions + /*! Provides a uniform interface to some ctime functions and + * their '_r' counterparts. The '_r' functions require a pointer to a + * user created std::tm struct whereas the regular functions use a + * staticly created struct and return a pointer to that. These wrapper + * functions require the user to create a std::tm struct and send in a + * pointer to it. This struct may be used to store the resulting time. + * The returned pointer may or may not point to this struct, however, + * it will point to the result of the corresponding function. + * All functions do proper checking of the C function results and throw + * exceptions on error. Therefore the functions will never return NULL. + */ + struct c_time { + public: +#if defined(BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS) + //! requires a pointer to a user created std::tm struct + inline + static std::tm* localtime(const std::time_t* t, std::tm* result) + { + // localtime_r() not in namespace std??? +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + std::tm tmp; + if(!localtime_r(t,&tmp)) + result = 0; + else + *result = tmp; +#else + result = localtime_r(t, result); +#endif + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); + return result; + } + //! requires a pointer to a user created std::tm struct + inline + static std::tm* gmtime(const std::time_t* t, std::tm* result) + { + // gmtime_r() not in namespace std??? +#if defined(__VMS) && __INITIAL_POINTER_SIZE == 64 + std::tm tmp; + if(!gmtime_r(t,&tmp)) + result = 0; + else + *result = tmp; +#else + result = gmtime_r(t, result); +#endif + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time")); + return result; + } +#else // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS + +#if defined(__clang__) // Clang has to be checked before MSVC +#pragma clang diagnostic push +//#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) +#pragma warning(push) // preserve warning settings +#pragma warning(disable : 4996) // disable depricated localtime/gmtime warning on vc8 +#endif + //! requires a pointer to a user created std::tm struct + inline + static std::tm* localtime(const std::time_t* t, std::tm* result) + { + result = std::localtime(t); + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to local time")); + return result; + } + //! requires a pointer to a user created std::tm struct + inline + static std::tm* gmtime(const std::time_t* t, std::tm* result) + { + result = std::gmtime(t); + if (!result) + boost::throw_exception(std::runtime_error("could not convert calendar time to UTC time")); + return result; + } +#if defined(__clang__) // Clang has to be checked before MSVC +#pragma clang diagnostic pop +#elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) +#pragma warning(pop) // restore warnings to previous state +#endif + +#endif // BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS + }; +}} // namespaces + +#endif // DATE_TIME_C_TIME_HPP___ diff --git a/src/vendor/boost/date_time/compiler_config.hpp b/src/vendor/boost/date_time/compiler_config.hpp new file mode 100644 index 000000000..1a9f84b0b --- /dev/null +++ b/src/vendor/boost/date_time/compiler_config.hpp @@ -0,0 +1,161 @@ +#ifndef DATE_TIME_COMPILER_CONFIG_HPP___ +#define DATE_TIME_COMPILER_CONFIG_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include + + +// This file performs some local compiler configurations + +#include //set up locale configurations + +//Set up a configuration parameter for platforms that have +//GetTimeOfDay +#if defined(BOOST_HAS_GETTIMEOFDAY) || defined(BOOST_HAS_FTIME) +#define BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK +#endif + +// To Force no default constructors for date & ptime, un-comment following +//#define DATE_TIME_NO_DEFAULT_CONSTRUCTOR + +// Include extensions to date_duration - comment out to remove this feature +#define BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +// these extensions are known to cause problems with gcc295 +#if defined(__GNUC__) && (__GNUC__ < 3) +#undef BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES +#endif + +#if (defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) || BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) ) ) +#define BOOST_DATE_TIME_NO_MEMBER_INIT +#endif + +// include these types before we try to re-define them +#include + +//Define INT64_C for compilers that don't have it +#if (!defined(INT64_C)) +#define INT64_C(value) int64_t(value) +#endif + + +/* Workaround for Borland iterator error. Error was "Cannot convert 'istream *' to 'wistream *' in function istream_iterator<>::istream_iterator() */ +#if defined(BOOST_BORLANDC) && defined(BOOST_BCB_WITH_RW_LIB) +#define BOOST_DATE_TIME_NO_WISTREAM_ITERATOR +#endif + + +// Borland v5.64 does not have the following in std namespace; v5.5.1 does +#if defined(BOOST_BORLANDC) && defined(BOOST_BCB_WITH_STLPORT) +#include +namespace std { + using stlport::tolower; + using stlport::ctype; + using stlport::use_facet; +} +#endif + +// workaround for errors associated with output for date classes +// modifications and input streaming for time classes. +// Compilers affected are: +// gcc295, msvc (neither with STLPort), any borland +// +#if (((defined(__GNUC__) && (__GNUC__ < 3)) || \ + (defined(_MSC_VER) && (_MSC_VER < 1300)) ) && \ + !defined(_STLP_OWN_IOSTREAMS) ) || \ + BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) ) +#define BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS +#endif + +// The macro marks up places where compiler complains for missing return statement or +// uninitialized variables after calling to boost::throw_exception. +// BOOST_UNREACHABLE_RETURN doesn't work since even compilers that support +// unreachable statements detection emit such warnings. +#if defined(_MSC_VER) +// Use special MSVC extension to markup unreachable code +# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) __assume(false) +#elif !defined(BOOST_NO_UNREACHABLE_RETURN_DETECTION) +// Call to a non-returning function should suppress the warning +# if defined(BOOST_NO_STDC_NAMESPACE) +namespace std { + using ::abort; +} +# endif // defined(BOOST_NO_STDC_NAMESPACE) +# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) std::abort() +#else +// For other poor compilers the specified expression is compiled. Usually, this would be a return statement. +# define BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(x) x +#endif + +/* The following handles the definition of the necessary macros + * for dll building on Win32 platforms. + * + * For code that will be placed in the date_time .dll, + * it must be properly prefixed with BOOST_DATE_TIME_DECL. + * The corresponding .cpp file must have BOOST_DATE_TIME_SOURCE + * defined before including its header. For examples see: + * greg_month.hpp & greg_month.cpp + * + */ + +// we need to import/export our code only if the user has specifically +// asked for it by defining either BOOST_ALL_DYN_LINK if they want all boost +// libraries to be dynamically linked, or BOOST_DATE_TIME_DYN_LINK +// if they want just this one to be dynamically liked: +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK) + // export if this is our own source, otherwise import: +# ifdef BOOST_DATE_TIME_SOURCE +# define BOOST_DATE_TIME_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_DATE_TIME_DECL BOOST_SYMBOL_IMPORT +# endif // BOOST_DATE_TIME_SOURCE +#endif // DYN_LINK +// +// if BOOST_WHATEVER_DECL isn't defined yet define it now: +#ifndef BOOST_DATE_TIME_DECL +# define BOOST_DATE_TIME_DECL +#endif + +// +// Automatically link to the correct build variant where possible. +// +#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_DATE_TIME_NO_LIB) && !defined(BOOST_DATE_TIME_SOURCE) +// +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it: +// +#define BOOST_LIB_NAME boost_date_time +// +// If we're importing code from a dll, then tell auto_link.hpp about it: +// +#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_DATE_TIME_DYN_LINK) +# define BOOST_DYN_LINK +#endif +// +// And include the header that does the work: +// +#include +#endif // auto-linking disabled + +#if defined(BOOST_HAS_THREADS) +# if defined(_MSC_VER) || defined(__MWERKS__) || defined(__MINGW32__) || defined(__BORLANDC__) + //no reentrant posix functions (eg: localtime_r) +# elif (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT))) +# define BOOST_DATE_TIME_HAS_REENTRANT_STD_FUNCTIONS +# endif +#endif + +#if defined(BOOST_NO_CXX11_NULLPTR) +# define BOOST_DATE_TIME_NULLPTR 0 +#else +# define BOOST_DATE_TIME_NULLPTR nullptr +#endif + +#endif diff --git a/src/vendor/boost/date_time/constrained_value.hpp b/src/vendor/boost/date_time/constrained_value.hpp new file mode 100644 index 000000000..5b898bf80 --- /dev/null +++ b/src/vendor/boost/date_time/constrained_value.hpp @@ -0,0 +1,129 @@ +#ifndef CONSTRAINED_VALUE_HPP___ +#define CONSTRAINED_VALUE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include + +namespace boost { + +//! Namespace containing constrained_value template and types +namespace CV { + //! Represent a min or max violation type + enum violation_enum {min_violation, max_violation}; + + //! A template to specify a constrained basic value type + /*! This template provides a quick way to generate + * an integer type with a constrained range. The type + * provides for the ability to specify the min, max, and + * and error handling policy. + * + * value policies + * A class that provides the range limits via the min and + * max functions as well as a function on_error that + * determines how errors are handled. A common strategy + * would be to assert or throw and exception. The on_error + * is passed both the current value and the new value that + * is in error. + * + */ + template + class BOOST_SYMBOL_VISIBLE constrained_value { + public: + typedef typename value_policies::value_type value_type; + // typedef except_type exception_type; + BOOST_CXX14_CONSTEXPR constrained_value(value_type value) : value_((min)()) + { + assign(value); + } + BOOST_CXX14_CONSTEXPR constrained_value& operator=(value_type v) + { + assign(v); + return *this; + } + //! Return the max allowed value (traits method) + static BOOST_CONSTEXPR value_type + max BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::max)();} + + //! Return the min allowed value (traits method) + static BOOST_CONSTEXPR value_type + min BOOST_PREVENT_MACRO_SUBSTITUTION () {return (value_policies::min)();} + + //! Coerce into the representation type + BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;} + protected: + value_type value_; + private: + BOOST_CXX14_CONSTEXPR void assign(value_type value) + { + //adding 1 below gets rid of a compiler warning which occurs when the + //min_value is 0 and the type is unsigned.... + if (value+1 < (min)()+1) { + value_policies::on_error(value_, value, min_violation); + return; + } + if (value > (max)()) { + value_policies::on_error(value_, value, max_violation); + return; + } + value_ = value; + } +}; + + //! Template to shortcut the constrained_value policy creation process + template + class BOOST_SYMBOL_VISIBLE simple_exception_policy + { + struct BOOST_SYMBOL_VISIBLE exception_wrapper : public exception_type + { + // In order to support throw_exception mechanism in the BOOST_NO_EXCEPTIONS mode, + // we'll have to provide a way to acquire std::exception from the exception being thrown. + // However, we cannot derive from it, since it would make it interceptable by this class, + // which might not be what the user wanted. + operator std::out_of_range () const + { + // TODO: Make the message more descriptive by using arguments to on_error + return std::out_of_range("constrained value boundary has been violated"); + } + }; + + typedef typename conditional< + is_base_of< std::exception, exception_type >::value, + exception_type, + exception_wrapper + >::type actual_exception_type; + + public: + typedef rep_type value_type; + static BOOST_CONSTEXPR rep_type + min BOOST_PREVENT_MACRO_SUBSTITUTION () { return min_value; } + + static BOOST_CONSTEXPR rep_type + max BOOST_PREVENT_MACRO_SUBSTITUTION () { return max_value; } + + static void on_error(rep_type, rep_type, violation_enum) + { + boost::throw_exception(actual_exception_type()); + } + }; + + + +} } //namespace CV + + + + +#endif diff --git a/src/vendor/boost/date_time/date.hpp b/src/vendor/boost/date_time/date.hpp new file mode 100644 index 000000000..ef98cb289 --- /dev/null +++ b/src/vendor/boost/date_time/date.hpp @@ -0,0 +1,209 @@ +#ifndef DATE_TIME_DATE_HPP___ +#define DATE_TIME_DATE_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //!Representation of timepoint at the one day level resolution. + /*! + The date template represents an interface shell for a date class + that is based on a year-month-day system such as the gregorian + or iso systems. It provides basic operations to enable calculation + and comparisons. + + Theory + + This date representation fundamentally departs from the C tm struct + approach. The goal for this type is to provide efficient date + operations (add, subtract) and storage (minimize space to represent) + in a concrete class. Thus, the date uses a count internally to + represent a particular date. The calendar parameter defines + the policies for converting the the year-month-day and internal + counted form here. Applications that need to perform heavy + formatting of the same date repeatedly will perform better + by using the year-month-day representation. + + Internally the date uses a day number to represent the date. + This is a monotonic time representation. This representation + allows for fast comparison as well as simplifying + the creation of writing numeric operations. Essentially, the + internal day number is like adjusted julian day. The adjustment + is determined by the Epoch date which is represented as day 1 of + the calendar. Day 0 is reserved for negative infinity so that + any actual date is automatically greater than negative infinity. + When a date is constructed from a date or formatted for output, + the appropriate conversions are applied to create the year, month, + day representations. + */ + + + template + class BOOST_SYMBOL_VISIBLE date : private + boost::less_than_comparable > + { + public: + typedef T date_type; + typedef calendar calendar_type; + typedef typename calendar::date_traits_type traits_type; + typedef duration_type_ duration_type; + typedef typename calendar::year_type year_type; + typedef typename calendar::month_type month_type; + typedef typename calendar::day_type day_type; + typedef typename calendar::ymd_type ymd_type; + typedef typename calendar::date_rep_type date_rep_type; + typedef typename calendar::date_int_type date_int_type; + typedef typename calendar::day_of_week_type day_of_week_type; + BOOST_CXX14_CONSTEXPR date(year_type y, month_type m, day_type d) + : days_(calendar::day_number(ymd_type(y, m, d))) + {} + BOOST_CXX14_CONSTEXPR date(const ymd_type& ymd) + : days_(calendar::day_number(ymd)) + {} + //let the compiler write copy, assignment, and destructor + BOOST_CXX14_CONSTEXPR year_type year() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.year; + } + BOOST_CXX14_CONSTEXPR month_type month() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.month; + } + BOOST_CXX14_CONSTEXPR day_type day() const + { + ymd_type ymd = calendar::from_day_number(days_); + return ymd.day; + } + BOOST_CXX14_CONSTEXPR day_of_week_type day_of_week() const + { + ymd_type ymd = calendar::from_day_number(days_); + return calendar::day_of_week(ymd); + } + BOOST_CXX14_CONSTEXPR ymd_type year_month_day() const + { + return calendar::from_day_number(days_); + } + BOOST_CONSTEXPR bool operator<(const date_type& rhs) const + { + return days_ < rhs.days_; + } + BOOST_CONSTEXPR bool operator==(const date_type& rhs) const + { + return days_ == rhs.days_; + } + //! check to see if date is a special value + BOOST_CONSTEXPR bool is_special()const + { + return(is_not_a_date() || is_infinity()); + } + //! check to see if date is not a value + BOOST_CONSTEXPR bool is_not_a_date() const + { + return traits_type::is_not_a_number(days_); + } + //! check to see if date is one of the infinity values + BOOST_CONSTEXPR bool is_infinity() const + { + return traits_type::is_inf(days_); + } + //! check to see if date is greater than all possible dates + BOOST_CONSTEXPR bool is_pos_infinity() const + { + return traits_type::is_pos_inf(days_); + } + //! check to see if date is greater than all possible dates + BOOST_CONSTEXPR bool is_neg_infinity() const + { + return traits_type::is_neg_inf(days_); + } + //! return as a special value or a not_special if a normal date + BOOST_CXX14_CONSTEXPR special_values as_special() const + { + return traits_type::to_special(days_); + } + BOOST_CXX14_CONSTEXPR duration_type operator-(const date_type& d) const + { + if (!this->is_special() && !d.is_special()) + { + // The duration underlying type may be wider than the date underlying type. + // Thus we calculate the difference in terms of two durations from some common fixed base date. + typedef typename duration_type::duration_rep_type duration_rep_type; + return duration_type(static_cast< duration_rep_type >(days_) - static_cast< duration_rep_type >(d.days_)); + } + else + { + // In this case the difference will be a special value, too + date_rep_type val = date_rep_type(days_) - date_rep_type(d.days_); + return duration_type(val.as_special()); + } + } + + BOOST_CXX14_CONSTEXPR date_type operator-(const duration_type& dd) const + { + if(dd.is_special()) + { + return date_type(date_rep_type(days_) - dd.get_rep()); + } + return date_type(date_rep_type(days_) - static_cast(dd.days())); + } + BOOST_CXX14_CONSTEXPR date_type operator-=(const duration_type& dd) + { + *this = *this - dd; + return date_type(days_); + } + BOOST_CONSTEXPR date_rep_type day_count() const + { + return days_; + } + //allow internal access from operators + BOOST_CXX14_CONSTEXPR date_type operator+(const duration_type& dd) const + { + if(dd.is_special()) + { + return date_type(date_rep_type(days_) + dd.get_rep()); + } + return date_type(date_rep_type(days_) + static_cast(dd.days())); + } + BOOST_CXX14_CONSTEXPR date_type operator+=(const duration_type& dd) + { + *this = *this + dd; + return date_type(days_); + } + + //see reference + protected: + /*! This is a private constructor which allows for the creation of new + dates. It is not exposed to users since that would require class + users to understand the inner workings of the date class. + */ + BOOST_CONSTEXPR explicit date(date_int_type days) : days_(days) {} + BOOST_CXX14_CONSTEXPR explicit date(date_rep_type days) : days_(days.as_number()) {} + date_int_type days_; + + }; + + + + +} } // namespace date_time + + + + +#endif diff --git a/src/vendor/boost/date_time/date_clock_device.hpp b/src/vendor/boost/date_time/date_clock_device.hpp new file mode 100644 index 000000000..2145d65fd --- /dev/null +++ b/src/vendor/boost/date_time/date_clock_device.hpp @@ -0,0 +1,77 @@ +#ifndef DATE_CLOCK_DEVICE_HPP___ +#define DATE_CLOCK_DEVICE_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/c_time.hpp" + + +namespace boost { +namespace date_time { + + //! A clock providing day level services based on C time_t capabilities + /*! This clock uses Posix interfaces as its implementation and hence + * uses the timezone settings of the operating system. Incorrect + * user settings will result in incorrect results for the calls + * to local_day. + */ + template + class day_clock + { + public: + typedef typename date_type::ymd_type ymd_type; + //! Get the local day as a date type + static date_type local_day() + { + return date_type(local_day_ymd()); + } + //! Get the local day as a ymd_type + static typename date_type::ymd_type local_day_ymd() + { + ::std::tm result; + ::std::tm* curr = get_local_time(result); + return ymd_type(static_cast(curr->tm_year + 1900), + static_cast(curr->tm_mon + 1), + static_cast(curr->tm_mday)); + } + //! Get the current day in universal date as a ymd_type + static typename date_type::ymd_type universal_day_ymd() + { + ::std::tm result; + ::std::tm* curr = get_universal_time(result); + return ymd_type(static_cast(curr->tm_year + 1900), + static_cast(curr->tm_mon + 1), + static_cast(curr->tm_mday)); + } + //! Get the UTC day as a date type + static date_type universal_day() + { + return date_type(universal_day_ymd()); + } + + private: + static ::std::tm* get_local_time(std::tm& result) + { + ::std::time_t t; + ::std::time(&t); + return c_time::localtime(&t, &result); + } + static ::std::tm* get_universal_time(std::tm& result) + { + ::std::time_t t; + ::std::time(&t); + return c_time::gmtime(&t, &result); + } + + }; + +} } //namespace date_time + + +#endif diff --git a/src/vendor/boost/date_time/date_defs.hpp b/src/vendor/boost/date_time/date_defs.hpp new file mode 100644 index 000000000..6c80db3a8 --- /dev/null +++ b/src/vendor/boost/date_time/date_defs.hpp @@ -0,0 +1,26 @@ +#ifndef DATE_TIME_DATE_DEFS_HPP +#define DATE_TIME_DATE_DEFS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + + +namespace boost { +namespace date_time { + + //! An enumeration of weekday names + enum weekdays {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday}; + + //! Simple enum to allow for nice programming with Jan, Feb, etc + enum months_of_year {Jan=1,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec,NotAMonth,NumMonths}; + +} } //namespace date_time + + + +#endif diff --git a/src/vendor/boost/date_time/date_duration.hpp b/src/vendor/boost/date_time/date_duration.hpp new file mode 100644 index 000000000..44abf7940 --- /dev/null +++ b/src/vendor/boost/date_time/date_duration.hpp @@ -0,0 +1,146 @@ +#ifndef DATE_TIME_DATE_DURATION__ +#define DATE_TIME_DATE_DURATION__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Duration type with date level resolution + template + class BOOST_SYMBOL_VISIBLE date_duration : private + boost::less_than_comparable1< date_duration< duration_rep_traits > + , boost::equality_comparable1< date_duration< duration_rep_traits > + , boost::addable1< date_duration< duration_rep_traits > + , boost::subtractable1< date_duration< duration_rep_traits > + , boost::dividable2< date_duration< duration_rep_traits >, int + > > > > > + { + public: + typedef typename duration_rep_traits::int_type duration_rep_type; + typedef typename duration_rep_traits::impl_type duration_rep; + + //! Construct from a day count + BOOST_CXX14_CONSTEXPR explicit date_duration(duration_rep day_count) : days_(day_count) {} + + /*! construct from special_values - only works when + * instantiated with duration_traits_adapted */ + BOOST_CXX14_CONSTEXPR date_duration(special_values sv) : + days_(duration_rep::from_special(sv)) + {} + + //! returns days_ as it's instantiated type - used for streaming + BOOST_CXX14_CONSTEXPR duration_rep get_rep()const + { + return days_; + } + BOOST_CXX14_CONSTEXPR special_values as_special() const + { + return days_.as_special(); + } + BOOST_CXX14_CONSTEXPR bool is_special()const + { + return days_.is_special(); + } + //! returns days as value, not object. + BOOST_CXX14_CONSTEXPR duration_rep_type days() const + { + return duration_rep_traits::as_number(days_); + } + //! Returns the smallest duration -- used by to calculate 'end' + static BOOST_CXX14_CONSTEXPR date_duration unit() + { + return date_duration(1); + } + //! Equality + BOOST_CXX14_CONSTEXPR bool operator==(const date_duration& rhs) const + { + return days_ == rhs.days_; + } + //! Less + BOOST_CXX14_CONSTEXPR bool operator<(const date_duration& rhs) const + { + return days_ < rhs.days_; + } + + /* For shortcut operators (+=, -=, etc) simply using + * "days_ += days_" may not work. If instantiated with + * an int_adapter, shortcut operators are not present, + * so this will not compile */ + + //! Subtract another duration -- result is signed + BOOST_CXX14_CONSTEXPR date_duration& operator-=(const date_duration& rhs) + { + //days_ -= rhs.days_; + days_ = days_ - rhs.days_; + return *this; + } + //! Add a duration -- result is signed + BOOST_CXX14_CONSTEXPR date_duration& operator+=(const date_duration& rhs) + { + days_ = days_ + rhs.days_; + return *this; + } + + //! unary- Allows for dd = -date_duration(2); -> dd == -2 + BOOST_CXX14_CONSTEXPR date_duration operator-() const + { + return date_duration(get_rep() * (-1)); + } + //! Division operations on a duration with an integer. + BOOST_CXX14_CONSTEXPR date_duration& operator/=(int divisor) + { + days_ = days_ / divisor; + return *this; + } + + //! return sign information + BOOST_CXX14_CONSTEXPR bool is_negative() const + { + return days_ < 0; + } + + private: + duration_rep days_; + }; + + + /*! Struct for instantiating date_duration with NO special values + * functionality. Allows for transparent implementation of either + * date_duration or date_duration > */ + struct BOOST_SYMBOL_VISIBLE duration_traits_long + { + typedef long int_type; + typedef long impl_type; + static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i) { return i; } + }; + + /*! Struct for instantiating date_duration WITH special values + * functionality. Allows for transparent implementation of either + * date_duration or date_duration > */ + struct BOOST_SYMBOL_VISIBLE duration_traits_adapted + { + typedef long int_type; + typedef boost::date_time::int_adapter impl_type; + static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i) { return i.as_number(); } + }; + + +} } //namspace date_time + + +#endif + diff --git a/src/vendor/boost/date_time/date_duration_types.hpp b/src/vendor/boost/date_time/date_duration_types.hpp new file mode 100644 index 000000000..4a9de596b --- /dev/null +++ b/src/vendor/boost/date_time/date_duration_types.hpp @@ -0,0 +1,265 @@ +#ifndef DATE_DURATION_TYPES_HPP___ +#define DATE_DURATION_TYPES_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Additional duration type that represents a number of n*7 days + template + class BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration { + public: + BOOST_CXX14_CONSTEXPR weeks_duration(typename duration_config::impl_type w) + : date_duration(w * 7) {} + BOOST_CXX14_CONSTEXPR weeks_duration(special_values sv) + : date_duration(sv) {} + }; + + // predeclare + template + class BOOST_SYMBOL_VISIBLE years_duration; + + //! additional duration type that represents a logical month + /*! A logical month enables things like: "date(2002,Mar,2) + months(2) -> + * 2002-May2". If the date is a last day-of-the-month, the result will + * also be a last-day-of-the-month. + */ + template + class BOOST_SYMBOL_VISIBLE months_duration + { + private: + typedef typename base_config::int_rep int_rep; + typedef typename int_rep::int_type int_type; + typedef typename base_config::date_type date_type; + typedef typename date_type::duration_type duration_type; + typedef typename base_config::month_adjustor_type month_adjustor_type; + typedef months_duration months_type; + typedef years_duration years_type; + public: + BOOST_CXX14_CONSTEXPR months_duration(int_rep num) : _m(num) {} + BOOST_CXX14_CONSTEXPR months_duration(special_values sv) : _m(sv) + { + _m = int_rep::from_special(sv); + } + int_rep number_of_months() const { return _m; } + //! returns a negative duration + BOOST_CXX14_CONSTEXPR duration_type get_neg_offset(const date_type& d) const + { + month_adjustor_type m_adj(_m.as_number()); + return duration_type(m_adj.get_neg_offset(d)); + } + BOOST_CXX14_CONSTEXPR duration_type get_offset(const date_type& d) const + { + month_adjustor_type m_adj(_m.as_number()); + return duration_type(m_adj.get_offset(d)); + } + BOOST_CONSTEXPR bool operator==(const months_type& rhs) const + { + return(_m == rhs._m); + } + BOOST_CONSTEXPR bool operator!=(const months_type& rhs) const + { + return(_m != rhs._m); + } + BOOST_CXX14_CONSTEXPR months_type operator+(const months_type& rhs)const + { + return months_type(_m + rhs._m); + } + BOOST_CXX14_CONSTEXPR months_type& operator+=(const months_type& rhs) + { + _m = _m + rhs._m; + return *this; + } + BOOST_CXX14_CONSTEXPR months_type operator-(const months_type& rhs)const + { + return months_type(_m - rhs._m); + } + BOOST_CXX14_CONSTEXPR months_type& operator-=(const months_type& rhs) + { + _m = _m - rhs._m; + return *this; + } + BOOST_CXX14_CONSTEXPR months_type operator*(const int_type rhs)const + { + return months_type(_m * rhs); + } + BOOST_CXX14_CONSTEXPR months_type& operator*=(const int_type rhs) + { + _m = _m * rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR months_type operator/(const int_type rhs)const + { + return months_type(_m / rhs); + } + BOOST_CXX14_CONSTEXPR months_type& operator/=(const int_type rhs) + { + _m = _m / rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR months_type operator+(const years_type& y)const + { + return months_type(y.number_of_years() * 12 + _m); + } + BOOST_CXX14_CONSTEXPR months_type& operator+=(const years_type& y) + { + _m = y.number_of_years() * 12 + _m; + return *this; + } + BOOST_CXX14_CONSTEXPR months_type operator-(const years_type& y) const + { + return months_type(_m - y.number_of_years() * 12); + } + BOOST_CXX14_CONSTEXPR months_type& operator-=(const years_type& y) + { + _m = _m - y.number_of_years() * 12; + return *this; + } + // + BOOST_CXX14_CONSTEXPR friend date_type operator+(const date_type& d, const months_type& m) + { + return d + m.get_offset(d); + } + BOOST_CXX14_CONSTEXPR friend date_type operator+=(date_type& d, const months_type& m) + { + return d += m.get_offset(d); + } + BOOST_CXX14_CONSTEXPR friend date_type operator-(const date_type& d, const months_type& m) + { + // get_neg_offset returns a negative duration, so we add + return d + m.get_neg_offset(d); + } + BOOST_CXX14_CONSTEXPR friend date_type operator-=(date_type& d, const months_type& m) + { + // get_neg_offset returns a negative duration, so we add + return d += m.get_neg_offset(d); + } + private: + int_rep _m; + }; + + //! additional duration type that represents a logical year + /*! A logical year enables things like: "date(2002,Mar,2) + years(2) -> + * 2004-Mar-2". If the date is a last day-of-the-month, the result will + * also be a last-day-of-the-month (ie date(2001-Feb-28) + years(3) -> + * 2004-Feb-29). + */ + template + class BOOST_SYMBOL_VISIBLE years_duration + { + private: + typedef typename base_config::int_rep int_rep; + typedef typename int_rep::int_type int_type; + typedef typename base_config::date_type date_type; + typedef typename date_type::duration_type duration_type; + typedef typename base_config::month_adjustor_type month_adjustor_type; + typedef years_duration years_type; + typedef months_duration months_type; + public: + BOOST_CXX14_CONSTEXPR years_duration(int_rep num) : _y(num) {} + BOOST_CXX14_CONSTEXPR years_duration(special_values sv) : _y(sv) + { + _y = int_rep::from_special(sv); + } + BOOST_CXX14_CONSTEXPR int_rep number_of_years() const { return _y; } + //! returns a negative duration + BOOST_CXX14_CONSTEXPR duration_type get_neg_offset(const date_type& d) const + { + month_adjustor_type m_adj(_y.as_number() * 12); + return duration_type(m_adj.get_neg_offset(d)); + } + BOOST_CXX14_CONSTEXPR duration_type get_offset(const date_type& d) const + { + month_adjustor_type m_adj(_y.as_number() * 12); + return duration_type(m_adj.get_offset(d)); + } + BOOST_CXX14_CONSTEXPR bool operator==(const years_type& rhs) const + { + return(_y == rhs._y); + } + bool operator!=(const years_type& rhs) const + { + return(_y != rhs._y); + } + BOOST_CXX14_CONSTEXPR years_type operator+(const years_type& rhs)const + { + return years_type(_y + rhs._y); + } + BOOST_CXX14_CONSTEXPR years_type& operator+=(const years_type& rhs) + { + _y = _y + rhs._y; + return *this; + } + BOOST_CXX14_CONSTEXPR years_type operator-(const years_type& rhs)const + { + return years_type(_y - rhs._y); + } + BOOST_CXX14_CONSTEXPR years_type& operator-=(const years_type& rhs) + { + _y = _y - rhs._y; + return *this; + } + BOOST_CXX14_CONSTEXPR years_type operator*(const int_type rhs)const + { + return years_type(_y * rhs); + } + BOOST_CXX14_CONSTEXPR years_type& operator*=(const int_type rhs) + { + _y = _y * rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR years_type operator/(const int_type rhs)const + { + return years_type(_y / rhs); + } + BOOST_CXX14_CONSTEXPR years_type& operator/=(const int_type rhs) + { + _y = _y / rhs; + return *this; + } + BOOST_CXX14_CONSTEXPR months_type operator+(const months_type& m) const + { + return(months_type(_y * 12 + m.number_of_months())); + } + BOOST_CXX14_CONSTEXPR months_type operator-(const months_type& m) const + { + return(months_type(_y * 12 - m.number_of_months())); + } + // + BOOST_CXX14_CONSTEXPR friend date_type operator+(const date_type& d, const years_type& y) + { + return d + y.get_offset(d); + } + BOOST_CXX14_CONSTEXPR friend date_type operator+=(date_type& d, const years_type& y) + { + return d += y.get_offset(d); + } + BOOST_CXX14_CONSTEXPR friend date_type operator-(const date_type& d, const years_type& y) + { + // get_neg_offset returns a negative duration, so we add + return d + y.get_neg_offset(d); + } + BOOST_CXX14_CONSTEXPR friend date_type operator-=(date_type& d, const years_type& y) + { + // get_neg_offset returns a negative duration, so we add + return d += y.get_neg_offset(d); + } + private: + int_rep _y; + }; +}} // namespace boost::date_time + +#endif // DATE_DURATION_TYPES_HPP___ diff --git a/src/vendor/boost/date_time/date_facet.hpp b/src/vendor/boost/date_time/date_facet.hpp new file mode 100644 index 000000000..4ab49236f --- /dev/null +++ b/src/vendor/boost/date_time/date_facet.hpp @@ -0,0 +1,766 @@ +#ifndef _DATE_TIME_DATE_FACET__HPP___ +#define _DATE_TIME_DATE_FACET__HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Martin Andrian, Jeff Garland, Bart Garst + * $Date$ + */ + +#include // ostreambuf_iterator +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace date_time { + + + /*! Class that provides format based I/O facet for date types. + * + * This class allows the formatting of dates by using format string. + * Format strings are: + * + * - %A => long_weekday_format - Full name Ex: Tuesday + * - %a => short_weekday_format - Three letter abbreviation Ex: Tue + * - %B => long_month_format - Full name Ex: October + * - %b => short_month_format - Three letter abbreviation Ex: Oct + * - %x => standard_format_specifier - defined by the locale + * - %Y-%b-%d => default_date_format - YYYY-Mon-dd + * + * Default month format == %b + * Default weekday format == %a + */ + template > > + class BOOST_SYMBOL_VISIBLE date_facet : public std::locale::facet { + public: + typedef typename date_type::duration_type duration_type; + // greg_weekday is gregorian_calendar::day_of_week_type + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_type day_type; + typedef typename date_type::month_type month_type; + typedef boost::date_time::period period_type; + typedef std::basic_string string_type; + typedef CharT char_type; + typedef boost::date_time::period_formatter period_formatter_type; + typedef boost::date_time::special_values_formatter special_values_formatter_type; + typedef std::vector > input_collection_type; + // used for the output of the date_generators + typedef date_generator_formatter date_gen_formatter_type; + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + static const char_type long_weekday_format[3]; + static const char_type short_weekday_format[3]; + static const char_type long_month_format[3]; + static const char_type short_month_format[3]; + static const char_type default_period_separator[4]; + static const char_type standard_format_specifier[3]; + static const char_type iso_format_specifier[7]; + static const char_type iso_format_extended_specifier[9]; + static const char_type default_date_format[9]; // YYYY-Mon-DD + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + explicit date_facet(::size_t a_ref = 0) + : std::locale::facet(a_ref), + //m_format(standard_format_specifier) + m_format(default_date_format), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format) + {} + + explicit date_facet(const char_type* format_str, + const input_collection_type& short_names, + ::size_t ref_count = 0) + : std::locale::facet(ref_count), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_month_short_names(short_names) + {} + + + explicit date_facet(const char_type* format_str, + period_formatter_type per_formatter = period_formatter_type(), + special_values_formatter_type sv_formatter = special_values_formatter_type(), + date_gen_formatter_type dg_formatter = date_gen_formatter_type(), + ::size_t ref_count = 0) + : std::locale::facet(ref_count), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_period_formatter(per_formatter), + m_date_gen_formatter(dg_formatter), + m_special_values_formatter(sv_formatter) + {} + void format(const char_type* const format_str) { + m_format = format_str; + } + virtual void set_iso_format() + { + m_format = iso_format_specifier; + } + virtual void set_iso_extended_format() + { + m_format = iso_format_extended_specifier; + } + void month_format(const char_type* const format_str) { + m_month_format = format_str; + } + void weekday_format(const char_type* const format_str) { + m_weekday_format = format_str; + } + + void period_formatter(period_formatter_type per_formatter) { + m_period_formatter= per_formatter; + } + void special_values_formatter(const special_values_formatter_type& svf) + { + m_special_values_formatter = svf; + } + void short_weekday_names(const input_collection_type& short_names) + { + m_weekday_short_names = short_names; + } + void long_weekday_names(const input_collection_type& long_names) + { + m_weekday_long_names = long_names; + } + + void short_month_names(const input_collection_type& short_names) + { + m_month_short_names = short_names; + } + + void long_month_names(const input_collection_type& long_names) + { + m_month_long_names = long_names; + } + + void date_gen_phrase_strings(const input_collection_type& new_strings, + typename date_gen_formatter_type::phrase_elements beg_pos=date_gen_formatter_type::first) + { + m_date_gen_formatter.elements(new_strings, beg_pos); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const date_type& d) const + { + if (d.is_special()) { + return do_put_special(next, a_ios, fill_char, d.as_special()); + } + //The following line of code required the date to support a to_tm function + return do_put_tm(next, a_ios, fill_char, to_tm(d), m_format); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const duration_type& dd) const + { + if (dd.is_special()) { + return do_put_special(next, a_ios, fill_char, dd.get_rep().as_special()); + } + + typedef std::num_put num_put; + if (std::has_facet(a_ios.getloc())) { + return std::use_facet(a_ios.getloc()).put(next, a_ios, fill_char, dd.get_rep().as_number()); + } + else { + num_put* f = new num_put(); + std::locale l = std::locale(a_ios.getloc(), f); + a_ios.imbue(l); + return f->put(next, a_ios, fill_char, dd.get_rep().as_number()); + } + + } + + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const month_type& m) const + { + //if (d.is_special()) { + // return do_put_special(next, a_ios, fill_char, d.as_special()); + //} + //The following line of code required the date to support a to_tm function + std::tm dtm; + std::memset(&dtm, 0, sizeof(dtm)); + dtm.tm_mon = m - 1; + return do_put_tm(next, a_ios, fill_char, dtm, m_month_format); + } + + //! puts the day of month + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const day_type& day) const + { + std::tm dtm; + std::memset(&dtm, 0, sizeof(dtm)); + dtm.tm_mday = day.as_number(); + char_type tmp[3] = {'%','d'}; + string_type temp_format(tmp); + return do_put_tm(next, a_ios, fill_char, dtm, temp_format); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const day_of_week_type& dow) const + { + //if (d.is_special()) { + // return do_put_special(next, a_ios, fill_char, d.as_special()); + //} + //The following line of code required the date to support a to_tm function + std::tm dtm; + std::memset(&dtm, 0, sizeof(dtm)); + dtm.tm_wday = dow; + return do_put_tm(next, a_ios, fill_char, dtm, m_weekday_format); + } + + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const period_type& p) const + { + return m_period_formatter.put_period(next, a_ios, fill_char, p, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const partial_date_type& pd) const + { + return m_date_gen_formatter.put_partial_date(next, a_ios, fill_char, pd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const nth_kday_type& nkd) const + { + return m_date_gen_formatter.put_nth_kday(next, a_ios, fill_char, nkd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const first_kday_type& fkd) const + { + return m_date_gen_formatter.put_first_kday(next, a_ios, fill_char, fkd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const last_kday_type& lkd) const + { + return m_date_gen_formatter.put_last_kday(next, a_ios, fill_char, lkd, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const kday_before_type& fkb) const + { + return m_date_gen_formatter.put_kday_before(next, a_ios, fill_char, fkb, *this); + } + + OutItrT put(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const kday_after_type& fka) const + { + return m_date_gen_formatter.put_kday_after(next, a_ios, fill_char, fka, *this); + } + + protected: + virtual OutItrT do_put_special(OutItrT next, + std::ios_base& /*a_ios*/, + char_type /*fill_char*/, + const boost::date_time::special_values sv) const + { + m_special_values_formatter.put_special(next, sv); + return next; + } + virtual OutItrT do_put_tm(OutItrT next, + std::ios_base& a_ios, + char_type fill_char, + const tm& tm_value, + string_type a_format) const + { + // update format string with custom names + if (!m_weekday_long_names.empty()) { + boost::algorithm::replace_all(a_format, + long_weekday_format, + m_weekday_long_names[tm_value.tm_wday]); + } + if (!m_weekday_short_names.empty()) { + boost::algorithm::replace_all(a_format, + short_weekday_format, + m_weekday_short_names[tm_value.tm_wday]); + + } + if (!m_month_long_names.empty()) { + boost::algorithm::replace_all(a_format, + long_month_format, + m_month_long_names[tm_value.tm_mon]); + } + if (!m_month_short_names.empty()) { + boost::algorithm::replace_all(a_format, + short_month_format, + m_month_short_names[tm_value.tm_mon]); + } + // use time_put facet to create final string + const char_type* p_format = a_format.c_str(); + return std::use_facet >(a_ios.getloc()).put(next, a_ios, + fill_char, + &tm_value, + p_format, + p_format + a_format.size()); + } + protected: + string_type m_format; + string_type m_month_format; + string_type m_weekday_format; + period_formatter_type m_period_formatter; + date_gen_formatter_type m_date_gen_formatter; + special_values_formatter_type m_special_values_formatter; + input_collection_type m_month_short_names; + input_collection_type m_month_long_names; + input_collection_type m_weekday_short_names; + input_collection_type m_weekday_long_names; + private: + }; + + template + std::locale::id date_facet::id; + + template + const typename date_facet::char_type + date_facet::long_weekday_format[3] = {'%','A'}; + + template + const typename date_facet::char_type + date_facet::short_weekday_format[3] = {'%','a'}; + + template + const typename date_facet::char_type + date_facet::long_month_format[3] = {'%','B'}; + + template + const typename date_facet::char_type + date_facet::short_month_format[3] = {'%','b'}; + + template + const typename date_facet::char_type + date_facet::default_period_separator[4] = { ' ', '/', ' '}; + + template + const typename date_facet::char_type + date_facet::standard_format_specifier[3] = + {'%', 'x' }; + + template + const typename date_facet::char_type + date_facet::iso_format_specifier[7] = + {'%', 'Y', '%', 'm', '%', 'd' }; + + template + const typename date_facet::char_type + date_facet::iso_format_extended_specifier[9] = + {'%', 'Y', '-', '%', 'm', '-', '%', 'd' }; + + template + const typename date_facet::char_type + date_facet::default_date_format[9] = + {'%','Y','-','%','b','-','%','d'}; + + + + //! Input facet + template > > + class BOOST_SYMBOL_VISIBLE date_input_facet : public std::locale::facet { + public: + typedef typename date_type::duration_type duration_type; + // greg_weekday is gregorian_calendar::day_of_week_type + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_type day_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::year_type year_type; + typedef boost::date_time::period period_type; + typedef std::basic_string string_type; + typedef CharT char_type; + typedef boost::date_time::period_parser period_parser_type; + typedef boost::date_time::special_values_parser special_values_parser_type; + typedef std::vector > input_collection_type; + typedef format_date_parser format_date_parser_type; + // date_generators stuff goes here + typedef date_generator_parser date_gen_parser_type; + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + + static const char_type long_weekday_format[3]; + static const char_type short_weekday_format[3]; + static const char_type long_month_format[3]; + static const char_type short_month_format[3]; + static const char_type four_digit_year_format[3]; + static const char_type two_digit_year_format[3]; + static const char_type default_period_separator[4]; + static const char_type standard_format_specifier[3]; + static const char_type iso_format_specifier[7]; + static const char_type iso_format_extended_specifier[9]; + static const char_type default_date_format[9]; // YYYY-Mon-DD + static std::locale::id id; + + explicit date_input_facet(::size_t a_ref = 0) + : std::locale::facet(a_ref), + m_format(default_date_format), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_year_format(four_digit_year_format), + m_parser(m_format, std::locale::classic()) + // default period_parser & special_values_parser used + {} + + explicit date_input_facet(const string_type& format_str, + ::size_t a_ref = 0) + : std::locale::facet(a_ref), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_year_format(four_digit_year_format), + m_parser(m_format, std::locale::classic()) + // default period_parser & special_values_parser used + {} + + explicit date_input_facet(const string_type& format_str, + const format_date_parser_type& date_parser, + const special_values_parser_type& sv_parser, + const period_parser_type& per_parser, + const date_gen_parser_type& date_gen_parser, + ::size_t ref_count = 0) + : std::locale::facet(ref_count), + m_format(format_str), + m_month_format(short_month_format), + m_weekday_format(short_weekday_format), + m_year_format(four_digit_year_format), + m_parser(date_parser), + m_date_gen_parser(date_gen_parser), + m_period_parser(per_parser), + m_sv_parser(sv_parser) + {} + + + void format(const char_type* const format_str) { + m_format = format_str; + } + virtual void set_iso_format() + { + m_format = iso_format_specifier; + } + virtual void set_iso_extended_format() + { + m_format = iso_format_extended_specifier; + } + void month_format(const char_type* const format_str) { + m_month_format = format_str; + } + void weekday_format(const char_type* const format_str) { + m_weekday_format = format_str; + } + void year_format(const char_type* const format_str) { + m_year_format = format_str; + } + + void period_parser(period_parser_type per_parser) { + m_period_parser = per_parser; + } + void short_weekday_names(const input_collection_type& weekday_names) + { + m_parser.short_weekday_names(weekday_names); + } + void long_weekday_names(const input_collection_type& weekday_names) + { + m_parser.long_weekday_names(weekday_names); + } + + void short_month_names(const input_collection_type& month_names) + { + m_parser.short_month_names(month_names); + } + + void long_month_names(const input_collection_type& month_names) + { + m_parser.long_month_names(month_names); + } + + void date_gen_element_strings(const input_collection_type& col) + { + m_date_gen_parser.element_strings(col); + } + void date_gen_element_strings(const string_type& first, + const string_type& second, + const string_type& third, + const string_type& fourth, + const string_type& fifth, + const string_type& last, + const string_type& before, + const string_type& after, + const string_type& of) + + { + m_date_gen_parser.element_strings(first,second,third,fourth,fifth,last,before,after,of); + } + + void special_values_parser(special_values_parser_type sv_parser) + { + m_sv_parser = sv_parser; + } + + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + date_type& d) const + { + d = m_parser.parse_date(from, to, m_format, m_sv_parser); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + month_type& m) const + { + m = m_parser.parse_month(from, to, m_month_format); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + day_of_week_type& wd) const + { + wd = m_parser.parse_weekday(from, to, m_weekday_format); + return from; + } + //! Expects 1 or 2 digit day range: 1-31 + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + day_type& d) const + { + d = m_parser.parse_var_day_of_month(from, to); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& /*a_ios*/, + year_type& y) const + { + y = m_parser.parse_year(from, to, m_year_format); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + duration_type& dd) const + { + // skip leading whitespace + while(std::isspace(*from) && from != to) { ++from; } + + /* num_get.get() will always consume the first character if it + * is a sign indicator (+/-). Special value strings may begin + * with one of these signs so we'll need a copy of it + * in case num_get.get() fails. */ + char_type c = '\0'; + // TODO Are these characters somewhere in the locale? + if(*from == '-' || *from == '+') { + c = *from; + } + typedef std::num_get num_get; + typename duration_type::duration_rep_type val = 0; + std::ios_base::iostate err = std::ios_base::goodbit; + + if (std::has_facet(a_ios.getloc())) { + from = std::use_facet(a_ios.getloc()).get(from, to, a_ios, err, val); + } + else { + num_get* ng = new num_get(); + std::locale l = std::locale(a_ios.getloc(), ng); + a_ios.imbue(l); + from = ng->get(from, to, a_ios, err, val); + } + if(err & std::ios_base::failbit){ + typedef typename special_values_parser_type::match_results match_results; + match_results mr; + if(c == '-' || c == '+') { // was the first character consumed? + mr.cache += c; + } + m_sv_parser.match(from, to, mr); + if(mr.current_match == match_results::PARSE_ERROR) { + boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'")); + BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return from); // should never reach + } + dd = duration_type(static_cast(mr.current_match)); + } + else { + dd = duration_type(val); + } + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + period_type& p) const + { + p = m_period_parser.get_period(from, to, a_ios, p, duration_type::unit(), *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + nth_kday_type& nkd) const + { + nkd = m_date_gen_parser.get_nth_kday_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + partial_date_type& pd) const + { + + pd = m_date_gen_parser.get_partial_date_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + first_kday_type& fkd) const + { + fkd = m_date_gen_parser.get_first_kday_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + last_kday_type& lkd) const + { + lkd = m_date_gen_parser.get_last_kday_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + kday_before_type& fkb) const + { + fkb = m_date_gen_parser.get_kday_before_type(from, to, a_ios, *this); + return from; + } + InItrT get(InItrT& from, + InItrT& to, + std::ios_base& a_ios, + kday_after_type& fka) const + { + fka = m_date_gen_parser.get_kday_after_type(from, to, a_ios, *this); + return from; + } + + protected: + string_type m_format; + string_type m_month_format; + string_type m_weekday_format; + string_type m_year_format; + format_date_parser_type m_parser; + date_gen_parser_type m_date_gen_parser; + period_parser_type m_period_parser; + special_values_parser_type m_sv_parser; + private: + }; + + + template + std::locale::id date_input_facet::id; + + template + const typename date_input_facet::char_type + date_input_facet::long_weekday_format[3] = {'%','A'}; + + template + const typename date_input_facet::char_type + date_input_facet::short_weekday_format[3] = {'%','a'}; + + template + const typename date_input_facet::char_type + date_input_facet::long_month_format[3] = {'%','B'}; + + template + const typename date_input_facet::char_type + date_input_facet::short_month_format[3] = {'%','b'}; + + template + const typename date_input_facet::char_type + date_input_facet::four_digit_year_format[3] = {'%','Y'}; + + template + const typename date_input_facet::char_type + date_input_facet::two_digit_year_format[3] = {'%','y'}; + + template + const typename date_input_facet::char_type + date_input_facet::default_period_separator[4] = { ' ', '/', ' '}; + + template + const typename date_input_facet::char_type + date_input_facet::standard_format_specifier[3] = + {'%', 'x' }; + + template + const typename date_input_facet::char_type + date_input_facet::iso_format_specifier[7] = + {'%', 'Y', '%', 'm', '%', 'd' }; + + template + const typename date_input_facet::char_type + date_input_facet::iso_format_extended_specifier[9] = + {'%', 'Y', '-', '%', 'm', '-', '%', 'd' }; + + template + const typename date_input_facet::char_type + date_input_facet::default_date_format[9] = + {'%','Y','-','%','b','-','%','d'}; + +} } // namespaces + +#endif diff --git a/src/vendor/boost/date_time/date_format_simple.hpp b/src/vendor/boost/date_time/date_format_simple.hpp new file mode 100644 index 000000000..452990379 --- /dev/null +++ b/src/vendor/boost/date_time/date_format_simple.hpp @@ -0,0 +1,159 @@ +#ifndef DATE_TIME_SIMPLE_FORMAT_HPP___ +#define DATE_TIME_SIMPLE_FORMAT_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/parse_format_base.hpp" + +namespace boost { +namespace date_time { + +//! Class to provide simple basic formatting rules +template +class simple_format { +public: + + //! String used printed is date is invalid + static const charT* not_a_date() + { + return "not-a-date-time"; + } + //! String used to for positive infinity value + static const charT* pos_infinity() + { + return "+infinity"; + } + //! String used to for positive infinity value + static const charT* neg_infinity() + { + return "-infinity"; + } + //! Describe month format + static month_format_spec month_format() + { + return month_as_short_string; + } + static ymd_order_spec date_order() + { + return ymd_order_iso; //YYYY-MM-DD + } + //! This format uses '-' to separate date elements + static bool has_date_sep_chars() + { + return true; + } + //! Char to sep? + static charT year_sep_char() + { + return '-'; + } + //! char between year-month + static charT month_sep_char() + { + return '-'; + } + //! Char to separate month-day + static charT day_sep_char() + { + return '-'; + } + //! char between date-hours + static charT hour_sep_char() + { + return ' '; + } + //! char between hour and minute + static charT minute_sep_char() + { + return ':'; + } + //! char for second + static charT second_sep_char() + { + return ':'; + } + +}; + +#ifndef BOOST_NO_STD_WSTRING + +//! Specialization of formmating rules for wchar_t +template<> +class simple_format { +public: + + //! String used printed is date is invalid + static const wchar_t* not_a_date() + { + return L"not-a-date-time"; + } + //! String used to for positive infinity value + static const wchar_t* pos_infinity() + { + return L"+infinity"; + } + //! String used to for positive infinity value + static const wchar_t* neg_infinity() + { + return L"-infinity"; + } + //! Describe month format + static month_format_spec month_format() + { + return month_as_short_string; + } + static ymd_order_spec date_order() + { + return ymd_order_iso; //YYYY-MM-DD + } + //! This format uses '-' to separate date elements + static bool has_date_sep_chars() + { + return true; + } + //! Char to sep? + static wchar_t year_sep_char() + { + return '-'; + } + //! char between year-month + static wchar_t month_sep_char() + { + return '-'; + } + //! Char to separate month-day + static wchar_t day_sep_char() + { + return '-'; + } + //! char between date-hours + static wchar_t hour_sep_char() + { + return ' '; + } + //! char between hour and minute + static wchar_t minute_sep_char() + { + return ':'; + } + //! char for second + static wchar_t second_sep_char() + { + return ':'; + } + +}; + +#endif // BOOST_NO_STD_WSTRING +} } //namespace date_time + + + + +#endif diff --git a/src/vendor/boost/date_time/date_formatting.hpp b/src/vendor/boost/date_time/date_formatting.hpp new file mode 100644 index 000000000..c1b69a8c7 --- /dev/null +++ b/src/vendor/boost/date_time/date_formatting.hpp @@ -0,0 +1,137 @@ +#ifndef DATE_TIME_DATE_FORMATTING_HPP___ +#define DATE_TIME_DATE_FORMATTING_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/compiler_config.hpp" +#include +#include +#include +#include + +/* NOTE: "formatter" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * date_formatting_limited.hpp + */ + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class month_formatter + { + typedef std::basic_ostream ostream_type; + public: + //! Formats a month as as string into an ostream + /*! This function demands that month_type provide + * functions for converting to short and long strings + * if that capability is used. + */ + static ostream_type& format_month(const month_type& month, + ostream_type &os) + { + switch (format_type::month_format()) + { + case month_as_short_string: + { + os << month.as_short_string(); + break; + } + case month_as_long_string: + { + os << month.as_long_string(); + break; + } + case month_as_integer: + { + boost::io::basic_ios_fill_saver ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); + break; + } + default: + break; + + } + return os; + } // format_month + }; + + + //! Convert ymd to a standard string formatting policies + template + class ymd_formatter + { + public: + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + static std::basic_string ymd_to_string(ymd_type ymd) + { + typedef typename ymd_type::month_type month_type; + std::basic_ostringstream ss; + + // Temporarily switch to classic locale to prevent possible formatting + // of year with comma or other character (for example 2,008). + ss.imbue(std::locale::classic()); + ss << ymd.year; + ss.imbue(std::locale()); + + if (format_type::has_date_sep_chars()) { + ss << format_type::month_sep_char(); + } + //this name is a bit ugly, oh well.... + month_formatter::format_month(ymd.month, ss); + if (format_type::has_date_sep_chars()) { + ss << format_type::day_sep_char(); + } + ss << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.day; + return ss.str(); + } + }; + + + //! Convert a date to string using format policies + template + class date_formatter + { + public: + typedef std::basic_string string_type; + //! Convert to a date to standard string using format policies + static string_type date_to_string(date_type d) + { + typedef typename date_type::ymd_type ymd_type; + if (d.is_not_a_date()) { + return string_type(format_type::not_a_date()); + } + if (d.is_neg_infinity()) { + return string_type(format_type::neg_infinity()); + } + if (d.is_pos_infinity()) { + return string_type(format_type::pos_infinity()); + } + ymd_type ymd = d.year_month_day(); + return ymd_formatter::ymd_to_string(ymd); + } + }; + + +} } //namespace date_time + + +#endif + diff --git a/src/vendor/boost/date_time/date_formatting_locales.hpp b/src/vendor/boost/date_time/date_formatting_locales.hpp new file mode 100644 index 000000000..a1daad33a --- /dev/null +++ b/src/vendor/boost/date_time/date_formatting_locales.hpp @@ -0,0 +1,234 @@ +#ifndef DATE_TIME_DATE_FORMATTING_LOCALES_HPP___ +#define DATE_TIME_DATE_FORMATTING_LOCALES_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include "boost/date_time/locale_config.hpp" // set BOOST_DATE_TIME_NO_LOCALE + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_names_put.hpp" +#include "boost/date_time/parse_format_base.hpp" +#include +//#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Formats a month as as string into an ostream + template + class ostream_month_formatter + { + public: + typedef typename facet_type::month_type month_type; + typedef std::basic_ostream ostream_type; + + //! Formats a month as as string into an output iterator + static void format_month(const month_type& month, + ostream_type& os, + const facet_type& f) + { + + switch (f.month_format()) + { + case month_as_short_string: + { + std::ostreambuf_iterator oitr(os); + f.put_month_short(oitr, month.as_enum()); + break; + } + case month_as_long_string: + { + std::ostreambuf_iterator oitr(os); + f.put_month_long(oitr, month.as_enum()); + break; + } + case month_as_integer: + { + boost::io::basic_ios_fill_saver ifs(os); + os << std::setw(2) << std::setfill(os.widen('0')) << month.as_number(); + break; + } + + } + } // format_month + + }; + + + //! Formats a weekday + template + class ostream_weekday_formatter + { + public: + typedef typename facet_type::month_type month_type; + typedef std::basic_ostream ostream_type; + + //! Formats a month as as string into an output iterator + static void format_weekday(const weekday_type& wd, + ostream_type& os, + const facet_type& f, + bool as_long_string) + { + + std::ostreambuf_iterator oitr(os); + if (as_long_string) { + f.put_weekday_long(oitr, wd.as_enum()); + } + else { + f.put_weekday_short(oitr, wd.as_enum()); + } + + } // format_weekday + + }; + + + //! Convert ymd to a standard string formatting policies + template + class ostream_ymd_formatter + { + public: + typedef typename ymd_type::month_type month_type; + typedef ostream_month_formatter month_formatter_type; + typedef std::basic_ostream ostream_type; + typedef std::basic_string foo_type; + + //! Convert ymd to a standard string formatting policies + /*! This is standard code for handling date formatting with + * year-month-day based date information. This function + * uses the format_type to control whether the string will + * contain separator characters, and if so what the character + * will be. In addtion, it can format the month as either + * an integer or a string as controled by the formatting + * policy + */ + // static string_type ymd_to_string(ymd_type ymd) +// { +// std::ostringstream ss; +// facet_type dnp; +// ymd_put(ymd, ss, dnp); +// return ss.str(); +// } + + + // Put ymd to ostream -- part of ostream refactor + static void ymd_put(ymd_type ymd, + ostream_type& os, + const facet_type& f) + { + boost::io::basic_ios_fill_saver ifs(os); + std::ostreambuf_iterator oitr(os); + switch (f.date_order()) { + case ymd_order_iso: { + os << ymd.year; + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + os << std::setw(2) << std::setfill(os.widen('0')) + << ymd.day; + break; + } + case ymd_order_us: { + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + os << std::setw(2) << std::setfill(os.widen('0')) + << ymd.day; + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + os << ymd.year; + break; + } + case ymd_order_dmy: { + os << std::setw(2) << std::setfill(os.widen('0')) + << ymd.day; + if (f.has_date_sep_chars()) { + f.day_sep_char(oitr); + } + month_formatter_type::format_month(ymd.month, os, f); + if (f.has_date_sep_chars()) { + f.month_sep_char(oitr); + } + os << ymd.year; + break; + } + } + } + }; + + + //! Convert a date to string using format policies + template + class ostream_date_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename date_type::ymd_type ymd_type; + + //! Put date into an ostream + static void date_put(const date_type& d, + ostream_type& os, + const facet_type& f) + { + special_values sv = d.as_special(); + if (sv == not_special) { + ymd_type ymd = d.year_month_day(); + ostream_ymd_formatter::ymd_put(ymd, os, f); + } + else { // output a special value + std::ostreambuf_iterator coi(os); + f.put_special_value(coi, sv); + } + } + + + //! Put date into an ostream + static void date_put(const date_type& d, + ostream_type& os) + { + //retrieve the local from the ostream + std::locale locale = os.getloc(); + if (std::has_facet(locale)) { + const facet_type& f = std::use_facet(locale); + date_put(d, os, f); + } + else { + //default to something sensible if no facet installed + facet_type default_facet; + date_put(d, os, default_facet); + } + } // date_to_ostream + }; //class date_formatter + + +} } //namespace date_time + +#endif + +#endif + diff --git a/src/vendor/boost/date_time/date_generator_formatter.hpp b/src/vendor/boost/date_time/date_generator_formatter.hpp new file mode 100644 index 000000000..42c396b2c --- /dev/null +++ b/src/vendor/boost/date_time/date_generator_formatter.hpp @@ -0,0 +1,265 @@ +#ifndef _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___ +#define _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include "boost/date_time/date_generators.hpp" + +namespace boost { +namespace date_time { + + //! Formats date_generators for output + /*! Formatting of date_generators follows specific orders for the + * various types of date_generators. + * - partial_date => "dd Month" + * - nth_day_of_the_week_in_month => "nth weekday of month" + * - first_day_of_the_week_in_month => "first weekday of month" + * - last_day_of_the_week_in_month => "last weekday of month" + * - first_day_of_the_week_after => "weekday after" + * - first_day_of_the_week_before => "weekday before" + * While the order of the elements in these phrases cannot be changed, + * the elements themselves can be. Weekday and Month get their formats + * and names from the date_facet. The remaining elements are stored in + * the date_generator_formatter and can be customized upon construction + * or via a member function. The default elements are those shown in the + * examples above. + */ + template > > + class date_generator_formatter { + public: + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + + typedef CharT char_type; + typedef std::basic_string string_type; + typedef std::vector collection_type; + static const char_type first_string[6]; + static const char_type second_string[7]; + static const char_type third_string[6]; + static const char_type fourth_string[7]; + static const char_type fifth_string[6]; + static const char_type last_string[5]; + static const char_type before_string[8]; + static const char_type after_string[6]; + static const char_type of_string[3]; + + enum phrase_elements {first=0, second, third, fourth, fifth, last, + before, after, of, number_of_phrase_elements}; + + //! Default format elements used + date_generator_formatter() + { + phrase_strings.reserve(number_of_phrase_elements); + phrase_strings.push_back(string_type(first_string)); + phrase_strings.push_back(string_type(second_string)); + phrase_strings.push_back(string_type(third_string)); + phrase_strings.push_back(string_type(fourth_string)); + phrase_strings.push_back(string_type(fifth_string)); + phrase_strings.push_back(string_type(last_string)); + phrase_strings.push_back(string_type(before_string)); + phrase_strings.push_back(string_type(after_string)); + phrase_strings.push_back(string_type(of_string)); + } + + //! Constructor that allows for a custom set of phrase elements + date_generator_formatter(const string_type& first_str, + const string_type& second_str, + const string_type& third_str, + const string_type& fourth_str, + const string_type& fifth_str, + const string_type& last_str, + const string_type& before_str, + const string_type& after_str, + const string_type& of_str) + { + phrase_strings.reserve(number_of_phrase_elements); + phrase_strings.push_back(first_str); + phrase_strings.push_back(second_str); + phrase_strings.push_back(third_str); + phrase_strings.push_back(fourth_str); + phrase_strings.push_back(fifth_str); + phrase_strings.push_back(last_str); + phrase_strings.push_back(before_str); + phrase_strings.push_back(after_str); + phrase_strings.push_back(of_str); + } + + //! Replace the set of phrase elements with those contained in new_strings + /*! The order of the strings in the given collection is important. + * They must follow: + * - first, second, third, fourth, fifth, last, before, after, of. + * + * It is not necessary to send in a complete set if only a few + * elements are to be replaced as long as the correct beg_pos is used. + * + * Ex: To keep the default first through fifth elements, but replace + * the rest with a collection of: + * - "final", "prior", "following", "in". + * The beg_pos of date_generator_formatter::last would be used. + */ + void elements(const collection_type& new_strings, + phrase_elements beg_pos=first) + { + if(beg_pos < number_of_phrase_elements) { + typename collection_type::iterator itr = phrase_strings.begin(); + itr += beg_pos; + std::copy(new_strings.begin(), new_strings.end(), + itr); + //phrase_strings.begin()); + } + } + + //!Put a partial_date => "dd Month" + template + OutItrT put_partial_date(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const partial_date_type& pd, + const facet_type& facet) const + { + facet.put(next, a_ios, a_fill, pd.day()); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, pd.month()); + return next; + } + + //! Put an nth_day_of_the_week_in_month => "nth weekday of month" + template + OutItrT put_nth_kday(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const nth_kday_type& nkd, + const facet_type& facet) const + { + put_string(next, phrase_strings[nkd.nth_week() -1]); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, nkd.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, string_type(of_string)); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, nkd.month()); + return next; + } + + //! Put a first_day_of_the_week_in_month => "first weekday of month" + template + OutItrT put_first_kday(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const first_kday_type& fkd, + const facet_type& facet) const + { + put_string(next, phrase_strings[first]); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, fkd.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, string_type(of_string)); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, fkd.month()); + return next; + } + + //! Put a last_day_of_the_week_in_month => "last weekday of month" + template + OutItrT put_last_kday(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const last_kday_type& lkd, + const facet_type& facet) const + { + put_string(next, phrase_strings[last]); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, lkd.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, string_type(of_string)); + next = a_fill; //TODO change this ??? + facet.put(next, a_ios, a_fill, lkd.month()); + return next; + } + + //! Put a first_day_of_the_week_before => "weekday before" + template + OutItrT put_kday_before(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const kday_before_type& fkb, + const facet_type& facet) const + { + facet.put(next, a_ios, a_fill, fkb.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, phrase_strings[before]); + return next; + } + + //! Put a first_day_of_the_week_after => "weekday after" + template + OutItrT put_kday_after(OutItrT next, std::ios_base& a_ios, + CharT a_fill, const kday_after_type& fka, + const facet_type& facet) const + { + facet.put(next, a_ios, a_fill, fka.day_of_week()); + next = a_fill; //TODO change this ??? + put_string(next, phrase_strings[after]); + return next; + } + + + private: + collection_type phrase_strings; + + //! helper function to put the various member string into stream + OutItrT put_string(OutItrT next, const string_type& str) const + { + typename string_type::const_iterator itr = str.begin(); + while(itr != str.end()) { + *next = *itr; + ++itr; + ++next; + } + return next; + } + }; + + template + const typename date_generator_formatter::char_type + date_generator_formatter::first_string[6] = + {'f','i','r','s','t'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::second_string[7] = + {'s','e','c','o','n','d'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::third_string[6] = + {'t','h','i','r','d'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::fourth_string[7] = + {'f','o','u','r','t','h'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::fifth_string[6] = + {'f','i','f','t','h'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::last_string[5] = + {'l','a','s','t'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::before_string[8] = + {'b','e','f','o','r','e'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::after_string[6] = + {'a','f','t','e','r'}; + template + const typename date_generator_formatter::char_type + date_generator_formatter::of_string[3] = + {'o','f'}; +} } // namespaces + +#endif // _DATE_TIME_DATE_GENERATOR_FORMATTER__HPP___ diff --git a/src/vendor/boost/date_time/date_generator_parser.hpp b/src/vendor/boost/date_time/date_generator_parser.hpp new file mode 100644 index 000000000..f4d7b27a7 --- /dev/null +++ b/src/vendor/boost/date_time/date_generator_parser.hpp @@ -0,0 +1,330 @@ + +#ifndef DATE_TIME_DATE_GENERATOR_PARSER_HPP__ +#define DATE_TIME_DATE_GENERATOR_PARSER_HPP__ + +/* Copyright (c) 2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include // istreambuf_iterator +#include +#include +#include +#include +#include + +namespace boost { namespace date_time { + + //! Class for date_generator parsing + /*! The elements of a date_generator "phrase" are parsed from the input stream in a + * particular order. All elements are required and the order in which they appear + * cannot change, however, the elements themselves can be changed. The default + * elements and their order are as follows: + * + * - partial_date => "dd Month" + * - nth_day_of_the_week_in_month => "nth weekday of month" + * - first_day_of_the_week_in_month => "first weekday of month" + * - last_day_of_the_week_in_month => "last weekday of month" + * - first_day_of_the_week_after => "weekday after" + * - first_day_of_the_week_before => "weekday before" + * + * Weekday and Month names and formats are handled via the date_input_facet. + * + */ + template + class date_generator_parser + { + public: + typedef std::basic_string string_type; + typedef std::istreambuf_iterator stream_itr_type; + + typedef typename date_type::month_type month_type; + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_type day_type; + + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > collection_type; + + typedef partial_date partial_date_type; + typedef nth_kday_of_month nth_kday_type; + typedef first_kday_of_month first_kday_type; + typedef last_kday_of_month last_kday_type; + typedef first_kday_after kday_after_type; + typedef first_kday_before kday_before_type; + + typedef charT char_type; + static const char_type first_string[6]; + static const char_type second_string[7]; + static const char_type third_string[6]; + static const char_type fourth_string[7]; + static const char_type fifth_string[6]; + static const char_type last_string[5]; + static const char_type before_string[8]; + static const char_type after_string[6]; + static const char_type of_string[3]; + + enum phrase_elements {first=0, second, third, fourth, fifth, last, + before, after, of, number_of_phrase_elements}; + + //! Creates a date_generator_parser with the default set of "element_strings" + date_generator_parser() + { + element_strings(string_type(first_string), + string_type(second_string), + string_type(third_string), + string_type(fourth_string), + string_type(fifth_string), + string_type(last_string), + string_type(before_string), + string_type(after_string), + string_type(of_string)); + } + + //! Creates a date_generator_parser using a user defined set of element strings + date_generator_parser(const string_type& first_str, + const string_type& second_str, + const string_type& third_str, + const string_type& fourth_str, + const string_type& fifth_str, + const string_type& last_str, + const string_type& before_str, + const string_type& after_str, + const string_type& of_str) + { + element_strings(first_str, second_str, third_str, fourth_str, fifth_str, + last_str, before_str, after_str, of_str); + } + + //! Replace strings that determine nth week for generator + void element_strings(const string_type& first_str, + const string_type& second_str, + const string_type& third_str, + const string_type& fourth_str, + const string_type& fifth_str, + const string_type& last_str, + const string_type& before_str, + const string_type& after_str, + const string_type& of_str) + { + collection_type phrases; + phrases.push_back(first_str); + phrases.push_back(second_str); + phrases.push_back(third_str); + phrases.push_back(fourth_str); + phrases.push_back(fifth_str); + phrases.push_back(last_str); + phrases.push_back(before_str); + phrases.push_back(after_str); + phrases.push_back(of_str); + m_element_strings = parse_tree_type(phrases, this->first); // enum first + } + + void element_strings(const collection_type& col) + { + m_element_strings = parse_tree_type(col, this->first); // enum first + } + + //! returns partial_date parsed from stream + template + partial_date_type + get_partial_date_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_type d(1); + month_type m(1); + facet.get(sitr, stream_end, a_ios, d); + facet.get(sitr, stream_end, a_ios, m); + + return partial_date_type(d,m); + } + + //! returns nth_kday_of_week parsed from stream + template + nth_kday_type + get_nth_kday_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + typename nth_kday_type::week_num wn; + day_of_week_type wd(0); // no default constructor + month_type m(1); // no default constructor + + match_results mr = m_element_strings.match(sitr, stream_end); + switch(mr.current_match) { + case first : { wn = nth_kday_type::first; break; } + case second : { wn = nth_kday_type::second; break; } + case third : { wn = nth_kday_type::third; break; } + case fourth : { wn = nth_kday_type::fourth; break; } + case fifth : { wn = nth_kday_type::fifth; break; } + default: + { + boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'")); + BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(wn = nth_kday_type::first); + } + } // week num + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, of); // "of" element + facet.get(sitr, stream_end, a_ios, m); // month + + return nth_kday_type(wn, wd, m); + } + + //! returns first_kday_of_week parsed from stream + template + first_kday_type + get_first_kday_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + month_type m(1); // no default constructor + + extract_element(sitr, stream_end, first); // "first" element + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, of); // "of" element + facet.get(sitr, stream_end, a_ios, m); // month + + + return first_kday_type(wd, m); + } + + //! returns last_kday_of_week parsed from stream + template + last_kday_type + get_last_kday_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + month_type m(1); // no default constructor + + extract_element(sitr, stream_end, last); // "last" element + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, of); // "of" element + facet.get(sitr, stream_end, a_ios, m); // month + + + return last_kday_type(wd, m); + } + + //! returns first_kday_of_week parsed from stream + template + kday_before_type + get_kday_before_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, before);// "before" element + + return kday_before_type(wd); + } + + //! returns first_kday_of_week parsed from stream + template + kday_after_type + get_kday_after_type(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + day_of_week_type wd(0); // no default constructor + + facet.get(sitr, stream_end, a_ios, wd); // day_of_week + extract_element(sitr, stream_end, after); // "after" element + + return kday_after_type(wd); + } + + private: + parse_tree_type m_element_strings; + + //! Extracts phrase element from input. Throws ios_base::failure on error. + void extract_element(stream_itr_type& sitr, + stream_itr_type& stream_end, + typename date_generator_parser::phrase_elements ele) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + match_results mr = m_element_strings.match(sitr, stream_end); + if(mr.current_match != ele) { + boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + mr.cache + "'")); + } + } + + }; + + template + const typename date_generator_parser::char_type + date_generator_parser::first_string[6] = + {'f','i','r','s','t'}; + template + const typename date_generator_parser::char_type + date_generator_parser::second_string[7] = + {'s','e','c','o','n','d'}; + template + const typename date_generator_parser::char_type + date_generator_parser::third_string[6] = + {'t','h','i','r','d'}; + template + const typename date_generator_parser::char_type + date_generator_parser::fourth_string[7] = + {'f','o','u','r','t','h'}; + template + const typename date_generator_parser::char_type + date_generator_parser::fifth_string[6] = + {'f','i','f','t','h'}; + template + const typename date_generator_parser::char_type + date_generator_parser::last_string[5] = + {'l','a','s','t'}; + template + const typename date_generator_parser::char_type + date_generator_parser::before_string[8] = + {'b','e','f','o','r','e'}; + template + const typename date_generator_parser::char_type + date_generator_parser::after_string[6] = + {'a','f','t','e','r'}; + template + const typename date_generator_parser::char_type + date_generator_parser::of_string[3] = + {'o','f'}; + +} } //namespace + +#endif // DATE_TIME_DATE_GENERATOR_PARSER_HPP__ + diff --git a/src/vendor/boost/date_time/date_generators.hpp b/src/vendor/boost/date_time/date_generators.hpp new file mode 100644 index 000000000..386b554f0 --- /dev/null +++ b/src/vendor/boost/date_time/date_generators.hpp @@ -0,0 +1,514 @@ +#ifndef DATE_TIME_DATE_GENERATORS_HPP__ +#define DATE_TIME_DATE_GENERATORS_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file date_generators.hpp + Definition and implementation of date algorithm templates +*/ + +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! Base class for all generators that take a year and produce a date. + /*! This class is a base class for polymorphic function objects that take + a year and produce a concrete date. + @tparam date_type The type representing a date. This type must + export a calender_type which defines a year_type. + */ + template + class year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::year_type year_type; + year_based_generator() {} + virtual ~year_based_generator() {} + virtual date_type get_date(year_type y) const = 0; + //! Returns a string for use in a POSIX time_zone string + virtual std::string to_string() const = 0; + }; + + //! Generates a date by applying the year to the given month and day. + /*! + Example usage: + @code + partial_date pd(1, Jan); + partial_date pd2(70); + date d = pd.get_date(2002); //2002-Jan-01 + date d2 = pd2.get_date(2002); //2002-Mar-10 + @endcode + \ingroup date_alg + */ + template + class partial_date : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_type day_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + typedef typename duration_type::duration_rep duration_rep; + partial_date(day_type d, month_type m) : + day_(d), + month_(m) + {} + //! Partial date created from number of days into year. Range 1-366 + /*! Allowable values range from 1 to 366. 1=Jan1, 366=Dec31. If argument + * exceeds range, partial_date will be created with closest in-range value. + * 60 will always be Feb29, if get_date() is called with a non-leap year + * an exception will be thrown */ + partial_date(duration_rep days) : + day_(1), // default values + month_(1) + { + date_type d1(2000,1,1); + if(days > 1) { + if(days > 366) // prevents wrapping + { + days = 366; + } + days = days - 1; + duration_type dd(days); + d1 = d1 + dd; + } + day_ = d1.day(); + month_ = d1.month(); + } + //! Return a concrete date when provided with a year specific year. + /*! Will throw an 'invalid_argument' exception if a partial_date object, + * instantiated with Feb-29, has get_date called with a non-leap year. + * Example: + * @code + * partial_date pd(29, Feb); + * pd.get_date(2003); // throws invalid_argument exception + * pg.get_date(2000); // returns 2000-2-29 + * @endcode + */ + date_type get_date(year_type y) const BOOST_OVERRIDE + { + if((day_ == 29) && (month_ == 2) && !(calendar_type::is_leap_year(y))) { + std::ostringstream ss; + ss << "No Feb 29th in given year of " << y << "."; + boost::throw_exception(std::invalid_argument(ss.str())); + } + return date_type(y, month_, day_); + } + date_type operator()(year_type y) const + { + return get_date(y); + //return date_type(y, month_, day_); + } + bool operator==(const partial_date& rhs) const + { + return (month_ == rhs.month_) && (day_ == rhs.day_); + } + bool operator<(const partial_date& rhs) const + { + if (month_ < rhs.month_) return true; + if (month_ > rhs.month_) return false; + //months are equal + return (day_ < rhs.day_); + } + + // added for streaming purposes + month_type month() const + { + return month_; + } + day_type day() const + { + return day_; + } + + //! Returns string suitable for use in POSIX time zone string + /*! Returns string formatted with up to 3 digits: + * Jan-01 == "0" + * Feb-29 == "58" + * Dec-31 == "365" */ + std::string to_string() const BOOST_OVERRIDE + { + std::ostringstream ss; + date_type d(2004, month_, day_); + unsigned short c = d.day_of_year(); + c--; // numbered 0-365 while day_of_year is 1 based... + ss << c; + return ss.str(); + } + private: + day_type day_; + month_type month_; + }; + + //! Returns nth arg as string. 1 -> "first", 2 -> "second", max is 5. + inline const char* nth_as_str(int ele) + { + static const char* const _nth_as_str[] = {"out of range", "first", "second", + "third", "fourth", "fifth"}; + if(ele >= 1 && ele <= 5) { + return _nth_as_str[ele]; + } + else { + return _nth_as_str[0]; + } + } + + //! Useful generator functor for finding holidays + /*! Based on the idea in Cal. Calc. for finding holidays that are + * the 'first Monday of September'. When instantiated with + * 'fifth' kday of month, the result will be the last kday of month + * which can be the fourth or fifth depending on the structure of + * the month. + * + * The algorithm here basically guesses for the first + * day of the month. Then finds the first day of the correct + * type. That is, if the first of the month is a Tuesday + * and it needs Wednesday then we simply increment by a day + * and then we can add the length of a week until we get + * to the 'nth kday'. There are probably more efficient + * algorithms based on using a mod 7, but this one works + * reasonably well for basic applications. + * \ingroup date_alg + */ + template + class nth_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + enum week_num {first=1, second, third, fourth, fifth}; + nth_kday_of_month(week_num week_no, + day_of_week_type dow, + month_type m) : + month_(m), + wn_(week_no), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type y) const BOOST_OVERRIDE + { + date_type d(y, month_, 1); //first day of month + duration_type one_day(1); + duration_type one_week(7); + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + int week = 1; + while (week < wn_) { + d = d + one_week; + week++; + } + // remove wrapping to next month behavior + if(d.month() != month_) { + d = d - one_week; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + week_num nth_week() const + { + return wn_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + const char* nth_week_as_str() const + { + return nth_as_str(wn_); + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.3.0" ==> 3rd Sunday in April. */ + std::string to_string() const BOOST_OVERRIDE + { + std::ostringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << static_cast(wn_) << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + week_num wn_; + day_of_week_type dow_; + }; + + //! Useful generator functor for finding holidays and daylight savings + /*! Similar to nth_kday_of_month, but requires less paramters + * \ingroup date_alg + */ + template + class first_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + //!Specify the first 'Sunday' in 'April' spec + /*!@param dow The day of week, eg: Sunday, Monday, etc + * @param m The month of the year, eg: Jan, Feb, Mar, etc + */ + first_kday_of_month(day_of_week_type dow, month_type m) : + month_(m), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type year) const BOOST_OVERRIDE + { + date_type d(year, month_,1); + duration_type one_day(1); + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.1.0" ==> 1st Sunday in April. */ + std::string to_string() const BOOST_OVERRIDE + { + std::ostringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << 1 << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + day_of_week_type dow_; + }; + + + + //! Calculate something like Last Sunday of January + /*! Useful generator functor for finding holidays and daylight savings + * Get the last day of the month and then calculate the difference + * to the last previous day. + * @tparam date_type A date class that exports day_of_week, month_type, etc. + * \ingroup date_alg + */ + template + class last_kday_of_month : public year_based_generator + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename calendar_type::month_type month_type; + typedef typename calendar_type::year_type year_type; + typedef typename date_type::duration_type duration_type; + //!Specify the date spec like last 'Sunday' in 'April' spec + /*!@param dow The day of week, eg: Sunday, Monday, etc + * @param m The month of the year, eg: Jan, Feb, Mar, etc + */ + last_kday_of_month(day_of_week_type dow, month_type m) : + month_(m), + dow_(dow) + {} + //! Return a concrete date when provided with a year specific year. + date_type get_date(year_type year) const BOOST_OVERRIDE + { + date_type d(year, month_, calendar_type::end_of_month_day(year,month_)); + duration_type one_day(1); + while (dow_ != d.day_of_week()) { + d = d - one_day; + } + return d; + } + // added for streaming + month_type month() const + { + return month_; + } + day_of_week_type day_of_week() const + { + return dow_; + } + //! Returns string suitable for use in POSIX time zone string + /*! Returns a string formatted as "M4.5.0" ==> last Sunday in April. */ + std::string to_string() const BOOST_OVERRIDE + { + std::ostringstream ss; + ss << 'M' + << static_cast(month_) << '.' + << 5 << '.' + << static_cast(dow_); + return ss.str(); + } + private: + month_type month_; + day_of_week_type dow_; + }; + + + //! Calculate something like "First Sunday after Jan 1,2002 + /*! Date generator that takes a date and finds kday after + *@code + typedef boost::date_time::first_kday_after firstkdayafter; + firstkdayafter fkaf(Monday); + fkaf.get_date(date(2002,Feb,1)); + @endcode + * \ingroup date_alg + */ + template + class first_kday_after + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename date_type::duration_type duration_type; + first_kday_after(day_of_week_type dow) : + dow_(dow) + {} + //! Return next kday given. + date_type get_date(date_type start_day) const + { + duration_type one_day(1); + date_type d = start_day + one_day; + while (dow_ != d.day_of_week()) { + d = d + one_day; + } + return d; + } + // added for streaming + day_of_week_type day_of_week() const + { + return dow_; + } + private: + day_of_week_type dow_; + }; + + //! Calculate something like "First Sunday before Jan 1,2002 + /*! Date generator that takes a date and finds kday after + *@code + typedef boost::date_time::first_kday_before firstkdaybefore; + firstkdaybefore fkbf(Monday); + fkbf.get_date(date(2002,Feb,1)); + @endcode + * \ingroup date_alg + */ + template + class first_kday_before + { + public: + typedef typename date_type::calendar_type calendar_type; + typedef typename calendar_type::day_of_week_type day_of_week_type; + typedef typename date_type::duration_type duration_type; + first_kday_before(day_of_week_type dow) : + dow_(dow) + {} + //! Return next kday given. + date_type get_date(date_type start_day) const + { + duration_type one_day(1); + date_type d = start_day - one_day; + while (dow_ != d.day_of_week()) { + d = d - one_day; + } + return d; + } + // added for streaming + day_of_week_type day_of_week() const + { + return dow_; + } + private: + day_of_week_type dow_; + }; + + //! Calculates the number of days until the next weekday + /*! Calculates the number of days until the next weekday. + * If the date given falls on a Sunday and the given weekday + * is Tuesday the result will be 2 days */ + template + inline + typename date_type::duration_type days_until_weekday(const date_type& d, const weekday_type& wd) + { + typedef typename date_type::duration_type duration_type; + duration_type wks(0); + duration_type dd(wd.as_number() - d.day_of_week().as_number()); + if(dd.is_negative()){ + wks = duration_type(7); + } + return dd + wks; + } + + //! Calculates the number of days since the previous weekday + /*! Calculates the number of days since the previous weekday + * If the date given falls on a Sunday and the given weekday + * is Tuesday the result will be 5 days. The answer will be a positive + * number because Tuesday is 5 days before Sunday, not -5 days before. */ + template + inline + typename date_type::duration_type days_before_weekday(const date_type& d, const weekday_type& wd) + { + typedef typename date_type::duration_type duration_type; + duration_type wks(0); + duration_type dd(wd.as_number() - d.day_of_week().as_number()); + if(dd.days() > 0){ + wks = duration_type(7); + } + // we want a number of days, not an offset. The value returned must + // be zero or larger. + return (-dd + wks); + } + + //! Generates a date object representing the date of the following weekday from the given date + /*! Generates a date object representing the date of the following + * weekday from the given date. If the date given is 2004-May-9 + * (a Sunday) and the given weekday is Tuesday then the resulting date + * will be 2004-May-11. */ + template + inline + date_type next_weekday(const date_type& d, const weekday_type& wd) + { + return d + days_until_weekday(d, wd); + } + + //! Generates a date object representing the date of the previous weekday from the given date + /*! Generates a date object representing the date of the previous + * weekday from the given date. If the date given is 2004-May-9 + * (a Sunday) and the given weekday is Tuesday then the resulting date + * will be 2004-May-4. */ + template + inline + date_type previous_weekday(const date_type& d, const weekday_type& wd) + { + return d - days_before_weekday(d, wd); + } + +} } //namespace date_time + +#endif diff --git a/src/vendor/boost/date_time/date_iterator.hpp b/src/vendor/boost/date_time/date_iterator.hpp new file mode 100644 index 000000000..3526ba18b --- /dev/null +++ b/src/vendor/boost/date_time/date_iterator.hpp @@ -0,0 +1,101 @@ +#ifndef DATE_ITERATOR_HPP___ +#define DATE_ITERATOR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + //! An iterator over dates with varying resolution (day, week, month, year, etc) + enum date_resolutions {day, week, months, year, decade, century, NumDateResolutions}; + + //! Base date iterator type + /*! This class provides the skeleton for the creation of iterators. + * New and interesting interators can be created by plugging in a new + * function that derives the next value from the current state. + * generation of various types of -based information. + * + * Template Parameters + * + * date_type + * + * The date_type is a concrete date_type. The date_type must + * define a duration_type and a calendar_type. + */ + template + class date_itr_base { + // works, but benefit unclear at the moment + // class date_itr_base : public std::iterator{ + public: + typedef typename date_type::duration_type duration_type; + typedef date_type value_type; + typedef std::input_iterator_tag iterator_category; + + date_itr_base(date_type d) : current_(d) {} + virtual ~date_itr_base() {} + date_itr_base& operator++() + { + current_ = current_ + get_offset(current_); + return *this; + } + date_itr_base& operator--() + { + current_ = current_ + get_neg_offset(current_); + return *this; + } + virtual duration_type get_offset(const date_type& current) const=0; + virtual duration_type get_neg_offset(const date_type& current) const=0; + date_type operator*() {return current_;} + date_type* operator->() {return ¤t_;} + bool operator< (const date_type& d) {return current_ < d;} + bool operator<= (const date_type& d) {return current_ <= d;} + bool operator> (const date_type& d) {return current_ > d;} + bool operator>= (const date_type& d) {return current_ >= d;} + bool operator== (const date_type& d) {return current_ == d;} + bool operator!= (const date_type& d) {return current_ != d;} + private: + date_type current_; + }; + + //! Overrides the base date iterator providing hook for functors + /* + * offset_functor + * + * The offset functor must define a get_offset function that takes the + * current point in time and calculates and offset. + * + */ + template + class date_itr : public date_itr_base { + public: + typedef typename date_type::duration_type duration_type; + date_itr(date_type d, int factor=1) : + date_itr_base(d), + of_(factor) + {} + private: + virtual duration_type get_offset(const date_type& current) const + { + return of_.get_offset(current); + } + virtual duration_type get_neg_offset(const date_type& current) const + { + return of_.get_neg_offset(current); + } + offset_functor of_; + }; + + + +} } //namespace date_time + + +#endif diff --git a/src/vendor/boost/date_time/date_names_put.hpp b/src/vendor/boost/date_time/date_names_put.hpp new file mode 100644 index 000000000..20da2d2ed --- /dev/null +++ b/src/vendor/boost/date_time/date_names_put.hpp @@ -0,0 +1,321 @@ +#ifndef DATE_TIME_DATE_NAMES_PUT_HPP___ +#define DATE_TIME_DATE_NAMES_PUT_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include // set BOOST_DATE_TIME_NO_LOCALE + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include +#include +#include +#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Output facet base class for gregorian dates. + /*! This class is a base class for date facets used to localize the + * names of months and the names of days in the week. + * + * Requirements of Config + * - define an enumeration month_enum that enumerates the months. + * The enumeration should be '1' based eg: Jan==1 + * - define as_short_string and as_long_string + * + * (see langer & kreft p334). + * + */ + template > + class BOOST_SYMBOL_VISIBLE date_names_put : public std::locale::facet + { + public: + date_names_put() {} + typedef OutputIterator iter_type; + typedef typename Config::month_type month_type; + typedef typename Config::month_enum month_enum; + typedef typename Config::weekday_enum weekday_enum; + typedef typename Config::special_value_enum special_value_enum; + //typedef typename Config::format_type format_type; + typedef std::basic_string string_type; + typedef charT char_type; + static const char_type default_special_value_names[3][17]; + static const char_type separator[2]; + + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + void put_special_value(iter_type& oitr, special_value_enum sv) const + { + do_put_special_value(oitr, sv); + } + void put_month_short(iter_type& oitr, month_enum moy) const + { + do_put_month_short(oitr, moy); + } + void put_month_long(iter_type& oitr, month_enum moy) const + { + do_put_month_long(oitr, moy); + } + void put_weekday_short(iter_type& oitr, weekday_enum wd) const + { + do_put_weekday_short(oitr, wd); + } + void put_weekday_long(iter_type& oitr, weekday_enum wd) const + { + do_put_weekday_long(oitr, wd); + } + bool has_date_sep_chars() const + { + return do_has_date_sep_chars(); + } + void year_sep_char(iter_type& oitr) const + { + do_year_sep_char(oitr); + } + //! char between year-month + void month_sep_char(iter_type& oitr) const + { + do_month_sep_char(oitr); + } + //! Char to separate month-day + void day_sep_char(iter_type& oitr) const + { + do_day_sep_char(oitr); + } + //! Determines the order to put the date elements + ymd_order_spec date_order() const + { + return do_date_order(); + } + //! Determines if month is displayed as integer, short or long string + month_format_spec month_format() const + { + return do_month_format(); + } + + protected: + //! Default facet implementation uses month_type defaults + virtual void do_put_month_short(iter_type& oitr, month_enum moy) const + { + month_type gm(moy); + charT c = '\0'; + put_string(oitr, gm.as_short_string(c)); + } + //! Default facet implementation uses month_type defaults + virtual void do_put_month_long(iter_type& oitr, + month_enum moy) const + { + month_type gm(moy); + charT c = '\0'; + put_string(oitr, gm.as_long_string(c)); + } + //! Default facet implementation for special value types + virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const + { + if(sv <= 2) { // only output not_a_date_time, neg_infin, or pos_infin + string_type s(default_special_value_names[sv]); + put_string(oitr, s); + } + } + virtual void do_put_weekday_short(iter_type&, weekday_enum) const + { + } + virtual void do_put_weekday_long(iter_type&, weekday_enum) const + { + } + virtual bool do_has_date_sep_chars() const + { + return true; + } + virtual void do_year_sep_char(iter_type& oitr) const + { + string_type s(separator); + put_string(oitr, s); + } + //! char between year-month + virtual void do_month_sep_char(iter_type& oitr) const + { + string_type s(separator); + put_string(oitr, s); + } + //! Char to separate month-day + virtual void do_day_sep_char(iter_type& oitr) const + { + string_type s(separator); //put in '-' + put_string(oitr, s); + } + //! Default for date order + virtual ymd_order_spec do_date_order() const + { + return ymd_order_iso; + } + //! Default month format + virtual month_format_spec do_month_format() const + { + return month_as_short_string; + } + void put_string(iter_type& oi, const charT* const s) const + { + string_type s1(boost::lexical_cast(s)); + typename string_type::iterator si,end; + for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) { + *oi = *si; + } + } + void put_string(iter_type& oi, const string_type& s1) const + { + typename string_type::const_iterator si,end; + for (si=s1.begin(), end=s1.end(); si!=end; si++, oi++) { + *oi = *si; + } + } + }; + + template + const typename date_names_put::char_type + date_names_put::default_special_value_names[3][17] = { + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}, + {'-','i','n','f','i','n','i','t','y'}, + {'+','i','n','f','i','n','i','t','y'} }; + + template + const typename date_names_put::char_type + date_names_put::separator[2] = + {'-', '\0'} ; + + + //! Generate storage location for a std::locale::id + template + std::locale::id date_names_put::id; + + //! A date name output facet that takes an array of char* to define strings + template > + class BOOST_SYMBOL_VISIBLE all_date_names_put : public date_names_put + { + public: + all_date_names_put(const charT* const month_short_names[], + const charT* const month_long_names[], + const charT* const special_value_names[], + const charT* const weekday_short_names[], + const charT* const weekday_long_names[], + charT separator_char = '-', + ymd_order_spec order_spec = ymd_order_iso, + month_format_spec month_format = month_as_short_string) : + month_short_names_(month_short_names), + month_long_names_(month_long_names), + special_value_names_(special_value_names), + weekday_short_names_(weekday_short_names), + weekday_long_names_(weekday_long_names), + order_spec_(order_spec), + month_format_spec_(month_format) + { + separator_char_[0] = separator_char; + separator_char_[1] = '\0'; + + } + typedef OutputIterator iter_type; + typedef typename Config::month_enum month_enum; + typedef typename Config::weekday_enum weekday_enum; + typedef typename Config::special_value_enum special_value_enum; + + const charT* const* get_short_month_names() const + { + return month_short_names_; + } + const charT* const* get_long_month_names() const + { + return month_long_names_; + } + const charT* const* get_special_value_names() const + { + return special_value_names_; + } + const charT* const* get_short_weekday_names()const + { + return weekday_short_names_; + } + const charT* const* get_long_weekday_names()const + { + return weekday_long_names_; + } + + protected: + //! Generic facet that takes array of chars + virtual void do_put_month_short(iter_type& oitr, month_enum moy) const + { + this->put_string(oitr, month_short_names_[moy-1]); + } + //! Long month names + virtual void do_put_month_long(iter_type& oitr, month_enum moy) const + { + this->put_string(oitr, month_long_names_[moy-1]); + } + //! Special values names + virtual void do_put_special_value(iter_type& oitr, special_value_enum sv) const + { + this->put_string(oitr, special_value_names_[sv]); + } + virtual void do_put_weekday_short(iter_type& oitr, weekday_enum wd) const + { + this->put_string(oitr, weekday_short_names_[wd]); + } + virtual void do_put_weekday_long(iter_type& oitr, weekday_enum wd) const + { + this->put_string(oitr, weekday_long_names_[wd]); + } + //! char between year-month + virtual void do_month_sep_char(iter_type& oitr) const + { + this->put_string(oitr, separator_char_); + } + //! Char to separate month-day + virtual void do_day_sep_char(iter_type& oitr) const + { + this->put_string(oitr, separator_char_); + } + //! Set the date ordering + virtual ymd_order_spec do_date_order() const + { + return order_spec_; + } + //! Set the date ordering + virtual month_format_spec do_month_format() const + { + return month_format_spec_; + } + + private: + const charT* const* month_short_names_; + const charT* const* month_long_names_; + const charT* const* special_value_names_; + const charT* const* weekday_short_names_; + const charT* const* weekday_long_names_; + charT separator_char_[2]; + ymd_order_spec order_spec_; + month_format_spec month_format_spec_; + }; + +} } //namespace boost::date_time + +#endif //BOOST_NO_STD_LOCALE + +#endif diff --git a/src/vendor/boost/date_time/date_parsing.hpp b/src/vendor/boost/date_time/date_parsing.hpp new file mode 100644 index 000000000..34e39bd9c --- /dev/null +++ b/src/vendor/boost/date_time/date_parsing.hpp @@ -0,0 +1,342 @@ +#ifndef _DATE_TIME_DATE_PARSING_HPP___ +#define _DATE_TIME_DATE_PARSING_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(BOOST_DATE_TIME_NO_LOCALE) +#include // ::tolower(int) +#else +#include // std::tolower(char, locale) +#endif + +namespace boost { +namespace date_time { + + //! A function to replace the std::transform( , , ,tolower) construct + /*! This function simply takes a string, and changes all the characters + * in that string to lowercase (according to the default system locale). + * In the event that a compiler does not support locales, the old + * C style tolower() is used. + */ + inline + std::string + convert_to_lower(std::string inp) + { +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + const std::locale loc(std::locale::classic()); +#endif + std::string::size_type i = 0, n = inp.length(); + for (; i < n; ++i) { + inp[i] = +#if defined(BOOST_DATE_TIME_NO_LOCALE) + static_cast(std::tolower(inp[i])); +#else + // tolower and others were brought in to std for borland >= v564 + // in compiler_config.hpp + std::tolower(inp[i], loc); +#endif + } + return inp; + } + + //! Helper function for parse_date. + template + inline unsigned short + month_str_to_ushort(std::string const& s) { + if((s.at(0) >= '0') && (s.at(0) <= '9')) { + return boost::lexical_cast(s); + } + else { + std::string str = convert_to_lower(s); + //c++98 support +#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) + static std::map month_map; + typedef std::map::value_type vtype; + if( month_map.empty() ) { + month_map.insert( vtype("jan", static_cast(1)) ); + month_map.insert( vtype("january", static_cast(1)) ); + month_map.insert( vtype("feb", static_cast(2)) ); + month_map.insert( vtype("february", static_cast(2)) ); + month_map.insert( vtype("mar", static_cast(3)) ); + month_map.insert( vtype("march", static_cast(3)) ); + month_map.insert( vtype("apr", static_cast(4)) ); + month_map.insert( vtype("april", static_cast(4)) ); + month_map.insert( vtype("may", static_cast(5)) ); + month_map.insert( vtype("jun", static_cast(6)) ); + month_map.insert( vtype("june", static_cast(6)) ); + month_map.insert( vtype("jul", static_cast(7)) ); + month_map.insert( vtype("july", static_cast(7)) ); + month_map.insert( vtype("aug", static_cast(8)) ); + month_map.insert( vtype("august", static_cast(8)) ); + month_map.insert( vtype("sep", static_cast(9)) ); + month_map.insert( vtype("september", static_cast(9)) ); + month_map.insert( vtype("oct", static_cast(10)) ); + month_map.insert( vtype("october", static_cast(10)) ); + month_map.insert( vtype("nov", static_cast(11)) ); + month_map.insert( vtype("november", static_cast(11)) ); + month_map.insert( vtype("dec", static_cast(12)) ); + month_map.insert( vtype("december", static_cast(12)) ); + } +#else //c+11 and beyond + static std::map month_map = + { { "jan", static_cast(1) }, { "january", static_cast(1) }, + { "feb", static_cast(2) }, { "february", static_cast(2) }, + { "mar", static_cast(3) }, { "march", static_cast(3) }, + { "apr", static_cast(4) }, { "april", static_cast(4) }, + { "may", static_cast(5) }, + { "jun", static_cast(6) }, { "june", static_cast(6) }, + { "jul", static_cast(7) }, { "july", static_cast(7) }, + { "aug", static_cast(8) }, { "august", static_cast(8) }, + { "sep", static_cast(9) }, { "september", static_cast(9) }, + { "oct", static_cast(10) }, { "october", static_cast(10)}, + { "nov", static_cast(11) }, { "november", static_cast(11)}, + { "dec", static_cast(12) }, { "december", static_cast(12)} + }; +#endif + std::map::const_iterator mitr = month_map.find( str ); + if ( mitr != month_map.end() ) { + return mitr->second; + } + } + return 13; // intentionally out of range - name not found + } + + + //! Generic function to parse a delimited date (eg: 2002-02-10) + /*! Accepted formats are: "2003-02-10" or " 2003-Feb-10" or + * "2003-Feburary-10" + * The order in which the Month, Day, & Year appear in the argument + * string can be accomodated by passing in the appropriate ymd_order_spec + */ + template + date_type + parse_date(const std::string& s, int order_spec = ymd_order_iso) { + std::string spec_str; + if(order_spec == ymd_order_iso) { + spec_str = "ymd"; + } + else if(order_spec == ymd_order_dmy) { + spec_str = "dmy"; + } + else { // (order_spec == ymd_order_us) + spec_str = "mdy"; + } + + typedef typename date_type::month_type month_type; + unsigned pos = 0; + unsigned short year(0), month(0), day(0); + typedef typename std::basic_string::traits_type traits_type; + typedef boost::char_separator char_separator_type; + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef boost::tokenizer::const_iterator, + std::basic_string >::iterator tokenizer_iterator; + // may need more delimiters, these work for the regression tests + const char sep_char[] = {',','-','.',' ','/','\0'}; + char_separator_type sep(sep_char); + tokenizer tok(s,sep); + for(tokenizer_iterator beg=tok.begin(); + beg!=tok.end() && pos < spec_str.size(); + ++beg, ++pos) { + switch(spec_str.at(pos)) { + case 'y': + { + year = boost::lexical_cast(*beg); + break; + } + case 'm': + { + month = month_str_to_ushort(*beg); + break; + } + case 'd': + { + day = boost::lexical_cast(*beg); + break; + } + default: break; + } //switch + } + return date_type(year, month, day); + } + + //! Generic function to parse undelimited date (eg: 20020201) + template + date_type + parse_undelimited_date(const std::string& s) { + int offsets[] = {4,2,2}; + int pos = 0; + //typename date_type::ymd_type ymd((year_type::min)(),1,1); + unsigned short y = 0, m = 0, d = 0; + + /* The two bool arguments state that parsing will not wrap + * (only the first 8 characters will be parsed) and partial + * strings will not be parsed. + * Ex: + * "2005121" will parse 2005 & 12, but not the "1" */ + boost::offset_separator osf(offsets, offsets+3, false, false); + + typedef typename boost::tokenizer::const_iterator, + std::basic_string > tokenizer_type; + tokenizer_type tok(s, osf); + for(typename tokenizer_type::iterator ti=tok.begin(); ti!=tok.end();++ti) { + unsigned short i = boost::lexical_cast(*ti); + switch(pos) { + case 0: y = i; break; + case 1: m = i; break; + case 2: d = i; break; + default: break; + } + pos++; + } + return date_type(y,m,d); + } + + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the iterators that reference the + * begining & end of a char[] or string. All elements are + * used in output string */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type const& end, + char) + { + std::ostringstream ss; + while(beg != end) { + ss << *beg++; + } + return parse_date(ss.str()); + } + + //! Helper function for 'date gregorian::from_stream()' + /*! Returns the first string found in the stream referenced by the + * begining & end iterators */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type const& /* end */, + std::string const&) + { + return parse_date(*beg); + } + + /* I believe the wchar stuff would be best elsewhere, perhaps in + * parse_date<>()? In the mean time this gets us started... */ + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the iterators that reference the + * begining & end of a wstring. All elements are + * used in output string */ + template + inline + date_type from_stream_type(iterator_type& beg, + iterator_type const& end, + wchar_t) + { + std::ostringstream ss; +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + std::locale loc; + std::ctype const& fac = std::use_facet >(loc); + while(beg != end) { + ss << fac.narrow(*beg++, 'X'); // 'X' will cause exception to be thrown + } +#else + while(beg != end) { + char c = 'X'; // 'X' will cause exception to be thrown + const wchar_t wc = *beg++; + if (wc >= 0 && wc <= 127) + c = static_cast< char >(wc); + ss << c; + } +#endif + return parse_date(ss.str()); + } +#ifndef BOOST_NO_STD_WSTRING + //! Helper function for 'date gregorian::from_stream()' + /*! Creates a string from the first wstring found in the stream + * referenced by the begining & end iterators */ + template + inline + date_type + from_stream_type(iterator_type& beg, + iterator_type const& /* end */, + std::wstring const&) { + std::wstring ws = *beg; + std::ostringstream ss; + std::wstring::iterator wsb = ws.begin(), wse = ws.end(); +#if !defined(BOOST_DATE_TIME_NO_LOCALE) + std::locale loc; + std::ctype const& fac = std::use_facet >(loc); + while(wsb != wse) { + ss << fac.narrow(*wsb++, 'X'); // 'X' will cause exception to be thrown + } +#else + while(wsb != wse) { + char c = 'X'; // 'X' will cause exception to be thrown + const wchar_t wc = *wsb++; + if (wc >= 0 && wc <= 127) + c = static_cast< char >(wc); + ss << c; + } +#endif + return parse_date(ss.str()); + } +#endif // BOOST_NO_STD_WSTRING +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings +#else + //! function called by wrapper functions: date_period_from_(w)string() + template + period + from_simple_string_type(const std::basic_string& s){ + typedef typename std::basic_string::traits_type traits_type; + typedef typename boost::char_separator char_separator; + typedef typename boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + const charT sep_list[4] = {'[','/',']','\0'}; + char_separator sep(sep_list); + tokenizer tokens(s, sep); + typename tokenizer::iterator tok_it = tokens.begin(); + std::basic_string date_string = *tok_it; + // get 2 string iterators and generate a date from them + typename std::basic_string::iterator date_string_start = date_string.begin(), + date_string_end = date_string.end(); + typedef typename std::iterator_traits::iterator>::value_type value_type; + date_type d1 = from_stream_type(date_string_start, date_string_end, value_type()); + date_string = *(++tok_it); // next token + date_string_start = date_string.begin(), date_string_end = date_string.end(); + date_type d2 = from_stream_type(date_string_start, date_string_end, value_type()); + return period(d1, d2); + } +#endif + +} } //namespace date_time + + + + +#endif + diff --git a/src/vendor/boost/date_time/dst_rules.hpp b/src/vendor/boost/date_time/dst_rules.hpp new file mode 100644 index 000000000..760d9cc41 --- /dev/null +++ b/src/vendor/boost/date_time/dst_rules.hpp @@ -0,0 +1,391 @@ +#ifndef DATE_TIME_DST_RULES_HPP__ +#define DATE_TIME_DST_RULES_HPP__ + +/* Copyright (c) 2002,2003, 2007 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file dst_rules.hpp + Contains template class to provide static dst rule calculations +*/ + +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/date_defs.hpp" +#include + +namespace boost { + namespace date_time { + + enum time_is_dst_result {is_not_in_dst, is_in_dst, + ambiguous, invalid_time_label}; + + + //! Dynamic class used to caluclate dst transition information + template + class dst_calculator + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + + //! Check the local time offset when on dst start day + /*! On this dst transition, the time label between + * the transition boundary and the boudary + the offset + * are invalid times. If before the boundary then still + * not in dst. + *@param time_of_day Time offset in the day for the local time + *@param dst_start_offset_minutes Local day offset for start of dst + *@param dst_length_minutes Number of minutes to adjust clock forward + *@retval status of time label w.r.t. dst + */ + static time_is_dst_result + process_local_dst_start_day(const time_duration_type& time_of_day, + unsigned int dst_start_offset_minutes, + long dst_length_minutes) + { + //std::cout << "here" << std::endl; + if (time_of_day < time_duration_type(0,dst_start_offset_minutes,0)) { + return is_not_in_dst; + } + long offset = dst_start_offset_minutes + dst_length_minutes; + if (time_of_day >= time_duration_type(0,offset,0)) { + return is_in_dst; + } + return invalid_time_label; + } + + //! Check the local time offset when on the last day of dst + /*! This is the calculation for the DST end day. On that day times + * prior to the conversion time - dst_length (1 am in US) are still + * in dst. Times between the above and the switch time are + * ambiguous. Times after the start_offset are not in dst. + *@param time_of_day Time offset in the day for the local time + *@param dst_end_offset_minutes Local time of day for end of dst + *@retval status of time label w.r.t. dst + */ + static time_is_dst_result + process_local_dst_end_day(const time_duration_type& time_of_day, + unsigned int dst_end_offset_minutes, + long dst_length_minutes) + { + //in US this will be 60 so offset in day is 1,0,0 + int offset = dst_end_offset_minutes-dst_length_minutes; + if (time_of_day < time_duration_type(0,offset,0)) { + return is_in_dst; + } + if (time_of_day >= time_duration_type(0,dst_end_offset_minutes,0)) { + return is_not_in_dst; + } + return ambiguous; + } + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @param current_day The day to check for dst + * @param time_of_day Time offset within the day to check + * @param dst_start_day Starting day of dst for the given locality + * @param dst_start_offset Time offset within day for dst boundary + * @param dst_end_day Ending day of dst for the given locality + * @param dst_end_offset Time offset within day given in dst for dst boundary + * @param dst_length_minutes length of dst adjusment + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result + local_is_dst(const date_type& current_day, + const time_duration_type& time_of_day, + const date_type& dst_start_day, + const time_duration_type& dst_start_offset, + const date_type& dst_end_day, + const time_duration_type& dst_end_offset, + const time_duration_type& dst_length) + { + unsigned int start_minutes = static_cast( + dst_start_offset.hours() * 60 + dst_start_offset.minutes()); + unsigned int end_minutes = static_cast( + dst_end_offset.hours() * 60 + dst_end_offset.minutes()); + long length_minutes = static_cast( + dst_length.hours() * 60 + dst_length.minutes()); + + return local_is_dst(current_day, time_of_day, + dst_start_day, start_minutes, + dst_end_day, end_minutes, + length_minutes); + } + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @param current_day The day to check for dst + * @param time_of_day Time offset within the day to check + * @param dst_start_day Starting day of dst for the given locality + * @param dst_start_offset_minutes Offset within day for dst + * boundary (eg 120 for US which is 02:00:00) + * @param dst_end_day Ending day of dst for the given locality + * @param dst_end_offset_minutes Offset within day given in dst for dst + * boundary (eg 120 for US which is 02:00:00) + * @param dst_length_minutes Length of dst adjusment (eg: 60 for US) + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result + local_is_dst(const date_type& current_day, + const time_duration_type& time_of_day, + const date_type& dst_start_day, + unsigned int dst_start_offset_minutes, + const date_type& dst_end_day, + unsigned int dst_end_offset_minutes, + long dst_length_minutes) + { + //in northern hemisphere dst is in the middle of the year + if (dst_start_day < dst_end_day) { + if ((current_day > dst_start_day) && (current_day < dst_end_day)) { + return is_in_dst; + } + if ((current_day < dst_start_day) || (current_day > dst_end_day)) { + return is_not_in_dst; + } + } + else {//southern hemisphere dst is at begining /end of year + if ((current_day < dst_start_day) && (current_day > dst_end_day)) { + return is_not_in_dst; + } + if ((current_day > dst_start_day) || (current_day < dst_end_day)) { + return is_in_dst; + } + } + + if (current_day == dst_start_day) { + return process_local_dst_start_day(time_of_day, + dst_start_offset_minutes, + dst_length_minutes); + } + + if (current_day == dst_end_day) { + return process_local_dst_end_day(time_of_day, + dst_end_offset_minutes, + dst_length_minutes); + } + //you should never reach this statement + return invalid_time_label; + } + + }; + + + //! Compile-time configurable daylight savings time calculation engine + /* This template provides the ability to configure a daylight savings + * calculation at compile time covering all the cases. Unfortunately + * because of the number of dimensions related to daylight savings + * calculation the number of parameters is high. In addition, the + * start and end transition rules are complex types that specify + * an algorithm for calculation of the starting day and ending + * day of daylight savings time including the month and day + * specifications (eg: last sunday in October). + * + * @param date_type A type that represents dates, typically gregorian::date + * @param time_duration_type Used for the offset in the day calculations + * @param dst_traits A set of traits that define the rules of dst + * calculation. The dst_trait must include the following: + * start_rule_functor - Rule to calculate the starting date of a + * dst transition (eg: last_kday_of_month). + * start_day - static function that returns month of dst start for + * start_rule_functor + * start_month -static function that returns day or day of week for + * dst start of dst + * end_rule_functor - Rule to calculate the end of dst day. + * end_day - static fucntion that returns end day for end_rule_functor + * end_month - static function that returns end month for end_rule_functor + * dst_start_offset_minutes - number of minutes from start of day to transition to dst -- 120 (or 2:00 am) is typical for the U.S. and E.U. + * dst_start_offset_minutes - number of minutes from start of day to transition off of dst -- 180 (or 3:00 am) is typical for E.U. + * dst_length_minutes - number of minutes that dst shifts clock + */ + template + class dst_calc_engine + { + public: + typedef typename date_type::year_type year_type; + typedef typename date_type::calendar_type calendar_type; + typedef dst_calculator dstcalc; + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result local_is_dst(const date_type& d, + const time_duration_type& td) + { + + year_type y = d.year(); + date_type dst_start = local_dst_start_day(y); + date_type dst_end = local_dst_end_day(y); + return dstcalc::local_is_dst(d,td, + dst_start, + dst_traits::dst_start_offset_minutes(), + dst_end, + dst_traits::dst_end_offset_minutes(), + dst_traits::dst_shift_length_minutes()); + + } + + static bool is_dst_boundary_day(date_type d) + { + year_type y = d.year(); + return ((d == local_dst_start_day(y)) || + (d == local_dst_end_day(y))); + } + + //! The time of day for the dst transition (eg: typically 01:00:00 or 02:00:00) + static time_duration_type dst_offset() + { + return time_duration_type(0,dst_traits::dst_shift_length_minutes(),0); + } + + static date_type local_dst_start_day(year_type year) + { + return dst_traits::local_dst_start_day(year); + } + + static date_type local_dst_end_day(year_type year) + { + return dst_traits::local_dst_end_day(year); + } + + + }; + + //! Depricated: Class to calculate dst boundaries for US time zones + /* Use dst_calc_engine instead. + * In 2007 US/Canada DST rules changed + * (http://en.wikipedia.org/wiki/Energy_Policy_Act_of_2005#Change_to_daylight_saving_time). + */ + template //1 hour == 60 min in US + class us_dst_rules + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + typedef typename date_type::year_type year_type; + typedef typename date_type::calendar_type calendar_type; + typedef date_time::last_kday_of_month lkday; + typedef date_time::first_kday_of_month fkday; + typedef date_time::nth_kday_of_month nkday; + typedef dst_calculator dstcalc; + + //! Calculates if the given local time is dst or not + /*! Determines if the time is really in DST or not. Also checks for + * invalid and ambiguous. + * @retval The time is either ambiguous, invalid, in dst, or not in dst + */ + static time_is_dst_result local_is_dst(const date_type& d, + const time_duration_type& td) + { + + year_type y = d.year(); + date_type dst_start = local_dst_start_day(y); + date_type dst_end = local_dst_end_day(y); + return dstcalc::local_is_dst(d,td, + dst_start,dst_start_offset_minutes, + dst_end, dst_start_offset_minutes, + dst_length_minutes); + + } + + + static bool is_dst_boundary_day(date_type d) + { + year_type y = d.year(); + return ((d == local_dst_start_day(y)) || + (d == local_dst_end_day(y))); + } + + static date_type local_dst_start_day(year_type year) + { + if (year >= year_type(2007)) { + //second sunday in march + nkday ssim(nkday::second, Sunday, date_time::Mar); + return ssim.get_date(year); + } else { + //first sunday in april + fkday fsia(Sunday, date_time::Apr); + return fsia.get_date(year); + } + } + + static date_type local_dst_end_day(year_type year) + { + if (year >= year_type(2007)) { + //first sunday in november + fkday fsin(Sunday, date_time::Nov); + return fsin.get_date(year); + } else { + //last sunday in october + lkday lsio(Sunday, date_time::Oct); + return lsio.get_date(year); + } + } + + static time_duration_type dst_offset() + { + return time_duration_type(0,dst_length_minutes,0); + } + + private: + + + }; + + //! Used for local time adjustments in places that don't use dst + template + class null_dst_rules + { + public: + typedef time_duration_type_ time_duration_type; + typedef date_type_ date_type; + + + //! Calculates if the given local time is dst or not + /*! @retval Always is_not_in_dst since this is for zones without dst + */ + static time_is_dst_result local_is_dst(const date_type&, + const time_duration_type&) + { + return is_not_in_dst; + } + + //! Calculates if the given utc time is in dst + static time_is_dst_result utc_is_dst(const date_type&, + const time_duration_type&) + { + return is_not_in_dst; + } + + static bool is_dst_boundary_day(date_type /*d*/) + { + return false; + } + + static time_duration_type dst_offset() + { + return time_duration_type(0,0,0); + } + + }; + + + } } //namespace date_time + + + +#endif diff --git a/src/vendor/boost/date_time/filetime_functions.hpp b/src/vendor/boost/date_time/filetime_functions.hpp new file mode 100644 index 000000000..f5ef7bfb5 --- /dev/null +++ b/src/vendor/boost/date_time/filetime_functions.hpp @@ -0,0 +1,84 @@ +#ifndef DATE_TIME_FILETIME_FUNCTIONS_HPP__ +#define DATE_TIME_FILETIME_FUNCTIONS_HPP__ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file filetime_functions.hpp + * Function(s) for converting between a FILETIME structure and a + * time object. This file is only available on systems that have + * BOOST_HAS_FTIME defined. + */ + +#include + +#if defined(BOOST_HAS_FTIME) // skip this file if no FILETIME + +#include +#include +#include + +namespace boost { + +namespace date_time { + +//! Create a time object from an initialized FILETIME struct. +/*! + * Create a time object from an initialized FILETIME struct. + * A FILETIME struct holds 100-nanosecond units (0.0000001). When + * built with microsecond resolution the file_time's sub second value + * will be truncated. Nanosecond resolution has no truncation. + * + * \note The function is templated on the FILETIME type, so that + * it can be used with both native FILETIME and the ad-hoc + * boost::detail::winapi::FILETIME_ type. + */ +template< typename TimeT, typename FileTimeT > +inline +TimeT time_from_ftime(const FileTimeT& ft) +{ + typedef typename TimeT::date_type date_type; + typedef typename TimeT::date_duration_type date_duration_type; + typedef typename TimeT::time_duration_type time_duration_type; + + // https://svn.boost.org/trac/boost/ticket/2523 + // Since this function can be called with arbitrary times, including ones that + // are before 1970-Jan-01, we'll have to cast the time a bit differently, + // than it is done in the microsec_clock::file_time_to_microseconds function. This allows to + // avoid integer wrapping for dates before 1970-Jan-01. + + // 100-nanos since 1601-Jan-01 + uint64_t ft_as_integer = (static_cast< uint64_t >(ft.dwHighDateTime) << 32) | static_cast< uint64_t >(ft.dwLowDateTime); + uint64_t sec = ft_as_integer / 10000000UL; + uint32_t sub_sec = static_cast< uint32_t >(ft_as_integer % 10000000UL) // 100-nanoseconds since the last second +#if !defined(BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG) + / 10U; // microseconds since the last second +#else + * 100U; // nanoseconds since the last second +#endif + + // split sec into usable chunks: days, hours, minutes, & seconds + const uint32_t sec_per_day = 86400; // seconds per day + uint32_t days = static_cast< uint32_t >(sec / sec_per_day); + uint32_t tmp = static_cast< uint32_t >(sec % sec_per_day); + uint32_t hours = tmp / 3600; // sec_per_hour + tmp %= 3600; + uint32_t minutes = tmp / 60; // sec_per_min + tmp %= 60; + uint32_t seconds = tmp; // seconds + + date_duration_type dd(days); + date_type d = date_type(1601, Jan, 01) + dd; + return TimeT(d, time_duration_type(hours, minutes, seconds, sub_sec)); +} + +}} // boost::date_time + +#endif // BOOST_HAS_FTIME + +#endif // DATE_TIME_FILETIME_FUNCTIONS_HPP__ diff --git a/src/vendor/boost/date_time/find_match.hpp b/src/vendor/boost/date_time/find_match.hpp new file mode 100644 index 000000000..72c81ce5c --- /dev/null +++ b/src/vendor/boost/date_time/find_match.hpp @@ -0,0 +1,42 @@ +#ifndef _BOOST_DATE_TIME_FIND_MATCH_HPP___ +#define _BOOST_DATE_TIME_FIND_MATCH_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + + + //! Find index of a string in either of 2 arrays + /*! find_match searches both arrays for a match to 's'. Both arrays + * must contain 'size' elements. The index of the match is returned. + * If no match is found, 'size' is returned. + * Ex. "Jan" returns 0, "Dec" returns 11, "Tue" returns 2. + * 'size' can be sent in with: (greg_month::max)() (which 12), + * (greg_weekday::max)() + 1 (which is 7) or date_time::NumSpecialValues */ + template + short find_match(const charT* const* short_names, + const charT* const* long_names, + short size, + const std::basic_string& s) { + for(short i = 0; i < size; ++i){ + if(short_names[i] == s || long_names[i] == s){ + return i; + } + } + return size; // not-found, return a value out of range + } + + +} } //namespace date_time + + +#endif diff --git a/src/vendor/boost/date_time/format_date_parser.hpp b/src/vendor/boost/date_time/format_date_parser.hpp new file mode 100644 index 000000000..2269a4897 --- /dev/null +++ b/src/vendor/boost/date_time/format_date_parser.hpp @@ -0,0 +1,724 @@ + +#ifndef DATE_TIME_FORMAT_DATE_PARSER_HPP__ +#define DATE_TIME_FORMAT_DATE_PARSER_HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include "boost/lexical_cast.hpp" +#include "boost/date_time/string_parse_tree.hpp" +#include "boost/date_time/strings_from_facet.hpp" +#include "boost/date_time/special_values_parser.hpp" +#include +#include +#include +#include +#ifndef BOOST_NO_STDC_NAMESPACE +# include +#else +# include +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { + using ::isspace; + using ::isdigit; +} +#endif +namespace boost { namespace date_time { + +//! Helper function for parsing fixed length strings into integers +/*! Will consume 'length' number of characters from stream. Consumed + * character are transfered to parse_match_result struct. + * Returns '-1' if no number can be parsed or incorrect number of + * digits in stream. */ +template +inline +int_type +fixed_string_to_int(std::istreambuf_iterator& itr, + std::istreambuf_iterator& stream_end, + parse_match_result& mr, + unsigned int length, + const charT& fill_char) +{ + //typedef std::basic_string string_type; + unsigned int j = 0; + //string_type s; + while (j < length && itr != stream_end && + (std::isdigit(*itr) || *itr == fill_char)) { + if(*itr == fill_char) { + /* Since a fill_char can be anything, we convert it to a zero. + * lexical_cast will behave predictably when zero is used as fill. */ + mr.cache += ('0'); + } + else { + mr.cache += (*itr); + } + itr++; + j++; + } + int_type i = static_cast(-1); + // mr.cache will hold leading zeros. size() tells us when input is too short. + if(mr.cache.size() < length) { + return i; + } + try { + i = boost::lexical_cast(mr.cache); + }catch(bad_lexical_cast&){ + // we want to return -1 if the cast fails so nothing to do here + } + return i; +} + +//! Helper function for parsing fixed length strings into integers +/*! Will consume 'length' number of characters from stream. Consumed + * character are transfered to parse_match_result struct. + * Returns '-1' if no number can be parsed or incorrect number of + * digits in stream. */ +template +inline +int_type +fixed_string_to_int(std::istreambuf_iterator& itr, + std::istreambuf_iterator& stream_end, + parse_match_result& mr, + unsigned int length) +{ + return fixed_string_to_int(itr, stream_end, mr, length, '0'); +} + +//! Helper function for parsing varied length strings into integers +/*! Will consume 'max_length' characters from stream only if those + * characters are digits. Returns '-1' if no number can be parsed. + * Will not parse a number preceeded by a '+' or '-'. */ +template +inline +int_type +var_string_to_int(std::istreambuf_iterator& itr, + const std::istreambuf_iterator& stream_end, + unsigned int max_length) +{ + typedef std::basic_string string_type; + unsigned int j = 0; + string_type s; + while (itr != stream_end && (j < max_length) && std::isdigit(*itr)) { + s += (*itr); + ++itr; + ++j; + } + int_type i = static_cast(-1); + if(!s.empty()) { + i = boost::lexical_cast(s); + } + return i; +} + + +//! Class with generic date parsing using a format string +/*! The following is the set of recognized format specifiers + - %a - Short weekday name + - %A - Long weekday name + - %b - Abbreviated month name + - %B - Full month name + - %d - Day of the month as decimal 01 to 31 + - %j - Day of year as decimal from 001 to 366 + - %m - Month name as a decimal 01 to 12 + - %U - Week number 00 to 53 with first Sunday as the first day of week 1? + - %w - Weekday as decimal number 0 to 6 where Sunday == 0 + - %W - Week number 00 to 53 where Monday is first day of week 1 + - %x - facet default date representation + - %y - Year without the century - eg: 04 for 2004 + - %Y - Year with century + + The weekday specifiers (%a and %A) do not add to the date construction, + but they provide a way to skip over the weekday names for formats that + provide them. + + todo -- Another interesting feature that this approach could provide is + an option to fill in any missing fields with the current values + from the clock. So if you have %m-%d the parser would detect + the missing year value and fill it in using the clock. + + todo -- What to do with the %x. %x in the classic facet is just bad... + + */ +template +class format_date_parser +{ + public: + typedef std::basic_string string_type; + typedef std::basic_istringstream stringstream_type; + typedef std::istreambuf_iterator stream_itr_type; + typedef typename string_type::const_iterator const_itr; + typedef typename date_type::year_type year_type; + typedef typename date_type::month_type month_type; + typedef typename date_type::day_type day_type; + typedef typename date_type::duration_type duration_type; + typedef typename date_type::day_of_week_type day_of_week_type; + typedef typename date_type::day_of_year_type day_of_year_type; + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > input_collection_type; + + // TODO sv_parser uses its default constructor - write the others + + format_date_parser(const string_type& format_str, + const input_collection_type& month_short_names, + const input_collection_type& month_long_names, + const input_collection_type& weekday_short_names, + const input_collection_type& weekday_long_names) : + m_format(format_str), + m_month_short_names(month_short_names, 1), + m_month_long_names(month_long_names, 1), + m_weekday_short_names(weekday_short_names), + m_weekday_long_names(weekday_long_names) + {} + + format_date_parser(const string_type& format_str, + const std::locale& locale) : + m_format(format_str), + m_month_short_names(gather_month_strings(locale), 1), + m_month_long_names(gather_month_strings(locale, false), 1), + m_weekday_short_names(gather_weekday_strings(locale)), + m_weekday_long_names(gather_weekday_strings(locale, false)) + {} + + format_date_parser(const format_date_parser& fdp) + { + this->m_format = fdp.m_format; + this->m_month_short_names = fdp.m_month_short_names; + this->m_month_long_names = fdp.m_month_long_names; + this->m_weekday_short_names = fdp.m_weekday_short_names; + this->m_weekday_long_names = fdp.m_weekday_long_names; + } + + string_type format() const + { + return m_format; + } + + void format(string_type format_str) + { + m_format = format_str; + } + + void short_month_names(const input_collection_type& month_names) + { + m_month_short_names = parse_tree_type(month_names, 1); + } + void long_month_names(const input_collection_type& month_names) + { + m_month_long_names = parse_tree_type(month_names, 1); + } + void short_weekday_names(const input_collection_type& weekday_names) + { + m_weekday_short_names = parse_tree_type(weekday_names); + } + void long_weekday_names(const input_collection_type& weekday_names) + { + m_weekday_long_names = parse_tree_type(weekday_names); + } + + date_type + parse_date(const string_type& value, + const string_type& format_str, + const special_values_parser& sv_parser) const + { + stringstream_type ss(value); + stream_itr_type sitr(ss); + stream_itr_type stream_end; + return parse_date(sitr, stream_end, format_str, sv_parser); + } + + date_type + parse_date(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + const special_values_parser& sv_parser) const + { + return parse_date(sitr, stream_end, m_format, sv_parser); + } + + /*! Of all the objects that the format_date_parser can parse, only a + * date can be a special value. Therefore, only parse_date checks + * for special_values. */ + date_type + parse_date(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + const special_values_parser& sv_parser) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + short year(0), month(0), day(0), day_of_year(0);// wkday(0); + /* Initialized the following to their minimum values. These intermediate + * objects are used so we get specific exceptions when part of the input + * is unparsable. + * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/ + year_type t_year(1400); + month_type t_month(1); + day_type t_day(1); + day_of_week_type wkday(0); + + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + if ( ++itr == format_str.end()) + break; + if (*itr != '%') { + switch(*itr) { + case 'a': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + match_results mr = m_weekday_short_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + wkday = mr.current_match; + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'A': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + match_results mr = m_weekday_long_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + wkday = mr.current_match; + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'b': + { + match_results mr = m_month_short_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_month = month_type(mr.current_match); + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'B': + { + match_results mr = m_month_long_names.match(sitr, stream_end); + if(mr.current_match == match_results::PARSE_ERROR) { + // check special_values + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_month = month_type(mr.current_match); + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'd': + { + match_results mr; + day = fixed_string_to_int(sitr, stream_end, mr, 2); + if(day == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_day = day_type(day); + break; + } + case 'e': + { + match_results mr; + day = fixed_string_to_int(sitr, stream_end, mr, 2, ' '); + if(day == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_day = day_type(day); + break; + } + case 'j': + { + match_results mr; + day_of_year = fixed_string_to_int(sitr, stream_end, mr, 3); + if(day_of_year == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + // these next two lines are so we get an exception with bad input + day_of_year_type t_day_of_year(1); + t_day_of_year = day_of_year_type(day_of_year); + break; + } + case 'm': + { + match_results mr; + month = fixed_string_to_int(sitr, stream_end, mr, 2); + if(month == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_month = month_type(month); + break; + } + case 'Y': + { + match_results mr; + year = fixed_string_to_int(sitr, stream_end, mr, 4); + if(year == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + t_year = year_type(year); + break; + } + case 'y': + { + match_results mr; + year = fixed_string_to_int(sitr, stream_end, mr, 2); + if(year == -1) { + if(sv_parser.match(sitr, stream_end, mr)) { + return date_type(static_cast(mr.current_match)); + } + } + year += 2000; //make 2 digit years in this century + t_year = year_type(year); + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + } + else { + sitr++; + } + } + } + + if (day_of_year > 0) { + date_type d(static_cast(year-1),12,31); //end of prior year + return d + duration_type(day_of_year); + } + + return date_type(t_year, t_month, t_day); // exceptions were thrown earlier + // if input was no good + } + + //! Throws bad_month if unable to parse + month_type + parse_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str) const + { + match_results mr; + return parse_month(sitr, stream_end, format_str, mr); + } + + //! Throws bad_month if unable to parse + month_type + parse_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + match_results& mr) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + short month(0); + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + if ( ++itr == format_str.end()) + break; + if (*itr != '%') { + switch(*itr) { + case 'b': + { + mr = m_month_short_names.match(sitr, stream_end); + month = mr.current_match; + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'B': + { + mr = m_month_long_names.match(sitr, stream_end); + month = mr.current_match; + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'm': + { + month = var_string_to_int(sitr, stream_end, 2); + // var_string_to_int returns -1 if parse failed. That will + // cause a bad_month exception to be thrown so we do nothing here + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + } + else { + sitr++; + } + } + } + + return month_type(month); // throws bad_month exception when values are zero + } + + //! Expects 1 or 2 digits 1-31. Throws bad_day_of_month if unable to parse + day_type + parse_var_day_of_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + return day_type(var_string_to_int(sitr, stream_end, 2)); + } + //! Expects 2 digits 01-31. Throws bad_day_of_month if unable to parse + day_type + parse_day_of_month(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + //return day_type(var_string_to_int(sitr, stream_end, 2)); + match_results mr; + return day_type(fixed_string_to_int(sitr, stream_end, mr, 2)); + } + + day_of_week_type + parse_weekday(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str) const + { + match_results mr; + return parse_weekday(sitr, stream_end, format_str, mr); + } + day_of_week_type + parse_weekday(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + match_results& mr) const + { + bool use_current_char = false; + + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + short wkday(0); + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + if ( ++itr == format_str.end()) + break; + if (*itr != '%') { + switch(*itr) { + case 'a': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + mr = m_weekday_short_names.match(sitr, stream_end); + wkday = mr.current_match; + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'A': + { + //this value is just throw away. It could be used for + //error checking potentially, but it isn't helpful in + //actually constructing the date - we just need to get it + //out of the stream + mr = m_weekday_long_names.match(sitr, stream_end); + wkday = mr.current_match; + if (mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'w': + { + // weekday as number 0-6, Sunday == 0 + wkday = var_string_to_int(sitr, stream_end, 2); + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + if (use_current_char) { + use_current_char = false; + } + else { + sitr++; + } + } + } + + return day_of_week_type(wkday); // throws bad_day_of_month exception + // when values are zero + } + + //! throws bad_year if unable to parse + year_type + parse_year(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str) const + { + match_results mr; + return parse_year(sitr, stream_end, format_str, mr); + } + + //! throws bad_year if unable to parse + year_type + parse_year(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + string_type format_str, + match_results& mr) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + unsigned short year(0); + + const_itr itr(format_str.begin()); + while (itr != format_str.end() && (sitr != stream_end)) { + if (*itr == '%') { + if ( ++itr == format_str.end()) + break; + if (*itr != '%') { + //match_results mr; + switch(*itr) { + case 'Y': + { + // year from 4 digit string + year = fixed_string_to_int(sitr, stream_end, mr, 4); + break; + } + case 'y': + { + // year from 2 digit string (no century) + year = fixed_string_to_int(sitr, stream_end, mr, 2); + year += 2000; //make 2 digit years in this century + break; + } + default: + {} //ignore those we don't understand + + }//switch + + } + else { // itr == '%', second consecutive + sitr++; + } + + itr++; //advance past format specifier + } + else { //skip past chars in format and in buffer + itr++; + sitr++; + } + } + + return year_type(year); // throws bad_year exception when values are zero + } + + + private: + string_type m_format; + parse_tree_type m_month_short_names; + parse_tree_type m_month_long_names; + parse_tree_type m_weekday_short_names; + parse_tree_type m_weekday_long_names; + +}; + +} } //namespace + +#endif + + + diff --git a/src/vendor/boost/date_time/gregorian/conversion.hpp b/src/vendor/boost/date_time/gregorian/conversion.hpp new file mode 100644 index 000000000..c844c4e34 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/conversion.hpp @@ -0,0 +1,68 @@ +#ifndef _GREGORIAN__CONVERSION_HPP___ +#define _GREGORIAN__CONVERSION_HPP___ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { + +namespace gregorian { + + //! Converts a date to a tm struct. Throws out_of_range exception if date is a special value + inline + std::tm to_tm(const date& d) + { + if (d.is_special()) + { + std::string s = "tm unable to handle "; + switch (d.as_special()) + { + case date_time::not_a_date_time: + s += "not-a-date-time value"; break; + case date_time::neg_infin: + s += "-infinity date value"; break; + case date_time::pos_infin: + s += "+infinity date value"; break; + default: + s += "a special date value"; break; + } + boost::throw_exception(std::out_of_range(s)); + } + + std::tm datetm; + std::memset(&datetm, 0, sizeof(datetm)); + boost::gregorian::date::ymd_type ymd = d.year_month_day(); + datetm.tm_year = ymd.year - 1900; + datetm.tm_mon = ymd.month - 1; + datetm.tm_mday = ymd.day; + datetm.tm_wday = d.day_of_week(); + datetm.tm_yday = d.day_of_year() - 1; + datetm.tm_isdst = -1; // negative because not enough info to set tm_isdst + return datetm; + } + + //! Converts a tm structure into a date dropping the any time values. + inline + date date_from_tm(const std::tm& datetm) + { + return date(static_cast(datetm.tm_year+1900), + static_cast(datetm.tm_mon+1), + static_cast(datetm.tm_mday)); + } + +} } //namespace boost::gregorian + +#endif diff --git a/src/vendor/boost/date_time/gregorian/formatters.hpp b/src/vendor/boost/date_time/gregorian/formatters.hpp new file mode 100644 index 000000000..d486ef0f4 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/formatters.hpp @@ -0,0 +1,162 @@ +#ifndef GREGORIAN_FORMATTERS_HPP___ +#define GREGORIAN_FORMATTERS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/gregorian/gregorian_types.hpp" +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/date_formatting_limited.hpp" +#else +#include "boost/date_time/date_formatting.hpp" +#endif +#include "boost/date_time/iso_format.hpp" +#include "boost/date_time/date_format_simple.hpp" + +/* NOTE: "to_*_string" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * formatters_limited.hpp + */ + +namespace boost { +namespace gregorian { + + // wrapper function for to_simple_(w)string(date) + template + inline + std::basic_string to_simple_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date& d) { + return to_simple_string_type(d); + } + + + // wrapper function for to_simple_(w)string(date_period) + template + inline std::basic_string to_simple_string_type(const date_period& d) { + typedef std::basic_string string_type; + charT b = '[', m = '/', e=']'; + + string_type d1(date_time::date_formatter,charT>::date_to_string(d.begin())); + string_type d2(date_time::date_formatter,charT>::date_to_string(d.last())); + return string_type(b + d1 + m + d2 + e); + } + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::string to_simple_string(const date_period& d) { + return to_simple_string_type(d); + } + + // wrapper function for to_iso_(w)string(date_period) + template + inline std::basic_string to_iso_string_type(const date_period& d) { + charT sep = '/'; + std::basic_string s(date_time::date_formatter,charT>::date_to_string(d.begin())); + return s + sep + date_time::date_formatter,charT>::date_to_string(d.last()); + } + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date_period& d) { + return to_iso_string_type(d); + } + + + // wrapper function for to_iso_extended_(w)string(date) + template + inline std::basic_string to_iso_extended_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::string to_iso_extended_string(const date& d) { + return to_iso_extended_string_type(d); + } + + // wrapper function for to_iso_(w)string(date) + template + inline std::basic_string to_iso_string_type(const date& d) { + return date_time::date_formatter,charT>::date_to_string(d); + } + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::string to_iso_string(const date& d) { + return to_iso_string_type(d); + } + + + + + // wrapper function for to_sql_(w)string(date) + template + inline std::basic_string to_sql_string_type(const date& d) + { + date::ymd_type ymd = d.year_month_day(); + std::basic_ostringstream ss; + ss << ymd.year << "-" + << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.month.as_number() //solves problem with gcc 3.1 hanging + << "-" + << std::setw(2) << std::setfill(ss.widen('0')) + << ymd.day; + return ss.str(); + } + inline std::string to_sql_string(const date& d) { + return to_sql_string_type(d); + } + + +#if !defined(BOOST_NO_STD_WSTRING) + //! Convert date period to simple string. Example: [2002-Jan-01/2002-Jan-02] + /*!\ingroup date_format + */ + inline std::wstring to_simple_wstring(const date_period& d) { + return to_simple_string_type(d); + } + //! To YYYY-mmm-DD string where mmm 3 char month name. Example: 2002-Jan-01 + /*!\ingroup date_format + */ + inline std::wstring to_simple_wstring(const date& d) { + return to_simple_string_type(d); + } + //! Date period to iso standard format CCYYMMDD/CCYYMMDD. Example: 20021225/20021231 + /*!\ingroup date_format + */ + inline std::wstring to_iso_wstring(const date_period& d) { + return to_iso_string_type(d); + } + //! Convert to iso extended format string CCYY-MM-DD. Example 2002-12-31 + /*!\ingroup date_format + */ + inline std::wstring to_iso_extended_wstring(const date& d) { + return to_iso_extended_string_type(d); + } + //! Convert to iso standard string YYYYMMDD. Example: 20021231 + /*!\ingroup date_format + */ + inline std::wstring to_iso_wstring(const date& d) { + return to_iso_string_type(d); + } + inline std::wstring to_sql_wstring(const date& d) { + return to_sql_string_type(d); + } +#endif // BOOST_NO_STD_WSTRING + +} } //namespace gregorian + + +#endif + diff --git a/src/vendor/boost/date_time/gregorian/greg_calendar.hpp b/src/vendor/boost/date_time/gregorian/greg_calendar.hpp new file mode 100644 index 000000000..16e47c1df --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_calendar.hpp @@ -0,0 +1,49 @@ +#ifndef GREGORIAN_GREGORIAN_CALENDAR_HPP__ +#define GREGORIAN_GREGORIAN_CALENDAR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //!An internal date representation that includes infinities, not a date + typedef date_time::int_adapter fancy_date_rep; + + //! Gregorian calendar for this implementation, hard work in the base + class BOOST_SYMBOL_VISIBLE gregorian_calendar : + public date_time::gregorian_calendar_base { + public: + //! Type to hold a weekday (eg: Sunday, Monday,...) + typedef greg_weekday day_of_week_type; + //! Counter type from 1 to 366 for gregorian dates. + typedef greg_day_of_year_rep day_of_year_type; + //! Internal date representation that handles infinity, not a date + typedef fancy_date_rep date_rep_type; + //! Date rep implements the traits stuff as well + typedef fancy_date_rep date_traits_type; + + + private: + }; + +} } //namespace gregorian + + + + +#endif + diff --git a/src/vendor/boost/date_time/gregorian/greg_date.hpp b/src/vendor/boost/date_time/gregorian/greg_date.hpp new file mode 100644 index 000000000..c7bcc964c --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_date.hpp @@ -0,0 +1,145 @@ +#ifndef GREG_DATE_HPP___ +#define GREG_DATE_HPP___ + +/* Copyright (c) 2002,2003, 2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + + //! A date type based on gregorian_calendar + /*! This class is the primary interface for programming with + greogorian dates. The is a lightweight type that can be + freely passed by value. All comparison operators are + supported. + \ingroup date_basics + */ + class BOOST_SYMBOL_VISIBLE date : public date_time::date + { + public: + typedef gregorian_calendar::year_type year_type; + typedef gregorian_calendar::month_type month_type; + typedef gregorian_calendar::day_type day_type; + typedef gregorian_calendar::day_of_year_type day_of_year_type; + typedef gregorian_calendar::ymd_type ymd_type; + typedef gregorian_calendar::date_rep_type date_rep_type; + typedef gregorian_calendar::date_int_type date_int_type; + typedef date_duration duration_type; +#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) + //! Default constructor constructs with not_a_date_time + BOOST_CXX14_CONSTEXPR date(): + date_time::date(date_rep_type::from_special(not_a_date_time)) + {} +#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR + //! Main constructor with year, month, day + BOOST_CXX14_CONSTEXPR date(year_type y, month_type m, day_type d) + : date_time::date(y, m, d) + { + if (gregorian_calendar::end_of_month_day(y, m) < d) { + boost::throw_exception(bad_day_of_month(std::string("Day of month is not valid for year"))); + } + } + //! Constructor from a ymd_type structure + BOOST_CXX14_CONSTEXPR explicit date(const ymd_type& ymd) + : date_time::date(ymd) + {} + //! Needed copy constructor + BOOST_CXX14_CONSTEXPR explicit date(const date_int_type& rhs): + date_time::date(rhs) + {} + //! Needed copy constructor + BOOST_CXX14_CONSTEXPR explicit date(date_rep_type rhs): + date_time::date(rhs) + {} + //! Constructor for infinities, not a date, max and min date + BOOST_CXX14_CONSTEXPR explicit date(special_values sv): + date_time::date(date_rep_type::from_special(sv)) + { + if (sv == min_date_time) + { + *this = date(1400, 1, 1); + } + if (sv == max_date_time) + { + *this = date(9999, 12, 31); + } + + } + //!Return the Julian Day number for the date. + BOOST_CXX14_CONSTEXPR date_int_type julian_day() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::julian_day_number(ymd); + } + //!Return the day of year 1..365 or 1..366 (for leap year) + BOOST_CXX14_CONSTEXPR day_of_year_type day_of_year() const + { + date start_of_year(year(), 1, 1); + unsigned short doy = static_cast((*this-start_of_year).days() + 1); + return day_of_year_type(doy); + } + //!Return the Modified Julian Day number for the date. + BOOST_CXX14_CONSTEXPR date_int_type modjulian_day() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::modjulian_day_number(ymd); + } + //!Return the iso 8601 week number 1..53 + BOOST_CXX14_CONSTEXPR int week_number() const + { + ymd_type ymd = year_month_day(); + return gregorian_calendar::week_number(ymd); + } + //! Return the day number from the calendar + BOOST_CXX14_CONSTEXPR date_int_type day_number() const + { + return days_; + } + //! Return the last day of the current month + BOOST_CXX14_CONSTEXPR date end_of_month() const + { + ymd_type ymd = year_month_day(); + unsigned short eom_day = gregorian_calendar::end_of_month_day(ymd.year, ymd.month); + return date(ymd.year, ymd.month, eom_day); + } + + friend BOOST_CXX14_CONSTEXPR + bool operator==(const date& lhs, const date& rhs); + + private: + + }; + + inline BOOST_CXX14_CONSTEXPR + bool operator==(const date& lhs, const date& rhs) + { + return lhs.days_ == rhs.days_; + } + + +} } //namespace gregorian + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_day.hpp b/src/vendor/boost/date_time/gregorian/greg_day.hpp new file mode 100644 index 000000000..a0780a96b --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_day.hpp @@ -0,0 +1,58 @@ +#ifndef GREG_DAY_HPP___ +#define GREG_DAY_HPP___ + +/* Copyright (c) 2002,2003,2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for gregorian day of month (1..31) + struct BOOST_SYMBOL_VISIBLE bad_day_of_month : public std::out_of_range + { + bad_day_of_month() : + std::out_of_range(std::string("Day of month value is out of range 1..31")) + {} + //! Allow other classes to throw with unique string for bad day like Feb 29 + bad_day_of_month(const std::string& s) : + std::out_of_range(s) + {} + }; + //! Policy class that declares error handling and day of month ranges + typedef CV::simple_exception_policy greg_day_policies; + + //! Generated represetation for gregorian day of month + typedef CV::constrained_value greg_day_rep; + + //! Represent a day of the month (range 1 - 31) + /*! This small class allows for simple conversion an integer value into + a day of the month for a standard gregorian calendar. The type + is automatically range checked so values outside of the range 1-31 + will cause a bad_day_of_month exception + */ + class BOOST_SYMBOL_VISIBLE greg_day : public greg_day_rep { + public: + BOOST_CXX14_CONSTEXPR greg_day(value_type day_of_month) : greg_day_rep(day_of_month) {} + BOOST_CXX14_CONSTEXPR value_type as_number() const {return value_;} + BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;} + private: + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_day_of_year.hpp b/src/vendor/boost/date_time/gregorian/greg_day_of_year.hpp new file mode 100644 index 000000000..3f753e1d6 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_day_of_year.hpp @@ -0,0 +1,39 @@ +#ifndef GREG_DAY_OF_YEAR_HPP___ +#define GREG_DAY_OF_YEAR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for day of year (1..366) + struct BOOST_SYMBOL_VISIBLE bad_day_of_year : public std::out_of_range + { + bad_day_of_year() : + std::out_of_range(std::string("Day of year value is out of range 1..366")) + {} + }; + + //! A day of the year range (1..366) + typedef CV::simple_exception_policy greg_day_of_year_policies; + + //! Define a range representation type for the day of the year 1..366 + typedef CV::constrained_value greg_day_of_year_rep; + + +} } //namespace gregorian + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_duration.hpp b/src/vendor/boost/date_time/gregorian/greg_duration.hpp new file mode 100644 index 000000000..6be6cdbdc --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_duration.hpp @@ -0,0 +1,147 @@ +#ifndef GREG_DURATION_HPP___ +#define GREG_DURATION_HPP___ + +/* Copyright (c) 2002,2003, 2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //!An internal date representation that includes infinities, not a date + typedef boost::date_time::duration_traits_adapted date_duration_rep; + + //! Durations in days for gregorian system + /*! \ingroup date_basics + */ + class BOOST_SYMBOL_VISIBLE date_duration : + public boost::date_time::date_duration< date_duration_rep > + { + typedef boost::date_time::date_duration< date_duration_rep > base_type; + + public: + typedef base_type::duration_rep duration_rep; + + //! Construct from a day count + BOOST_CXX14_CONSTEXPR explicit + date_duration(duration_rep day_count = 0) : base_type(day_count) {} + + //! construct from special_values + BOOST_CXX14_CONSTEXPR + date_duration(date_time::special_values sv) : base_type(sv) {} + + //! Construct from another date_duration + BOOST_CXX14_CONSTEXPR + date_duration(const base_type& other) : base_type(other) + {} + + // Relational operators + // NOTE: Because of date_time::date_duration< T > design choice we don't use Boost.Operators here, + // because we need the class to be a direct base. Either lose EBO, or define operators by hand. + // The latter is more effecient. + BOOST_CXX14_CONSTEXPR bool operator== (const date_duration& rhs) const + { + return base_type::operator== (rhs); + } + BOOST_CXX14_CONSTEXPR bool operator!= (const date_duration& rhs) const + { + return !operator== (rhs); + } + BOOST_CXX14_CONSTEXPR bool operator< (const date_duration& rhs) const + { + return base_type::operator< (rhs); + } + BOOST_CXX14_CONSTEXPR bool operator> (const date_duration& rhs) const + { + return !(base_type::operator< (rhs) || base_type::operator== (rhs)); + } + BOOST_CXX14_CONSTEXPR bool operator<= (const date_duration& rhs) const + { + return (base_type::operator< (rhs) || base_type::operator== (rhs)); + } + BOOST_CXX14_CONSTEXPR bool operator>= (const date_duration& rhs) const + { + return !base_type::operator< (rhs); + } + + //! Subtract another duration -- result is signed + BOOST_CXX14_CONSTEXPR date_duration& operator-= (const date_duration& rhs) + { + base_type::operator-= (rhs); + return *this; + } + + BOOST_CXX14_CONSTEXPR friend + date_duration operator- (date_duration rhs, date_duration const& lhs); + + //! Add a duration -- result is signed + BOOST_CXX14_CONSTEXPR date_duration& operator+= (const date_duration& rhs) + { + base_type::operator+= (rhs); + return *this; + } + + BOOST_CXX14_CONSTEXPR friend + date_duration operator+ (date_duration rhs, date_duration const& lhs); + + //! unary- Allows for dd = -date_duration(2); -> dd == -2 + BOOST_CXX14_CONSTEXPR date_duration operator- ()const + { + return date_duration(get_rep() * (-1)); + } + + //! Division operations on a duration with an integer. + BOOST_CXX14_CONSTEXPR date_duration& operator/= (int divisor) + { + base_type::operator/= (divisor); + return *this; + } + + BOOST_CXX14_CONSTEXPR friend date_duration operator/ (date_duration rhs, int lhs); + + //! Returns the smallest duration -- used by to calculate 'end' + static BOOST_CXX14_CONSTEXPR date_duration unit() + { + return date_duration(base_type::unit().get_rep()); + } + }; + + inline BOOST_CXX14_CONSTEXPR + date_duration operator- (date_duration rhs, date_duration const& lhs) + { + rhs -= lhs; + return rhs; + } + + inline BOOST_CXX14_CONSTEXPR + date_duration operator+ (date_duration rhs, date_duration const& lhs) + { + rhs += lhs; + return rhs; + } + + inline BOOST_CXX14_CONSTEXPR date_duration operator/ (date_duration rhs, int lhs) + { + rhs /= lhs; + return rhs; + } + + //! Shorthand for date_duration + typedef date_duration days; + +} } //namespace gregorian + +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include +#endif + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_duration_types.hpp b/src/vendor/boost/date_time/gregorian/greg_duration_types.hpp new file mode 100644 index 000000000..2fd33dd59 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_duration_types.hpp @@ -0,0 +1,44 @@ +#ifndef GREG_DURATION_TYPES_HPP___ +#define GREG_DURATION_TYPES_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! config struct for additional duration types (ie months_duration<> & years_duration<>) + struct BOOST_SYMBOL_VISIBLE greg_durations_config { + typedef date date_type; + typedef date_time::int_adapter int_rep; + typedef date_time::month_functor month_adjustor_type; + }; + + typedef date_time::months_duration months; + typedef date_time::years_duration years; + + class BOOST_SYMBOL_VISIBLE weeks_duration : public date_duration { + public: + BOOST_CXX14_CONSTEXPR weeks_duration(duration_rep w) + : date_duration(w * 7) {} + BOOST_CXX14_CONSTEXPR weeks_duration(date_time::special_values sv) + : date_duration(sv) {} + }; + + typedef weeks_duration weeks; + +}} // namespace boost::gregorian + +#endif // GREG_DURATION_TYPES_HPP___ diff --git a/src/vendor/boost/date_time/gregorian/greg_month.hpp b/src/vendor/boost/date_time/gregorian/greg_month.hpp new file mode 100644 index 000000000..535a29604 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_month.hpp @@ -0,0 +1,133 @@ +#ifndef GREG_MONTH_HPP___ +#define GREG_MONTH_HPP___ + +/* Copyright (c) 2002,2003, 2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + typedef date_time::months_of_year months_of_year; + + //bring enum values into the namespace + using date_time::Jan; + using date_time::Feb; + using date_time::Mar; + using date_time::Apr; + using date_time::May; + using date_time::Jun; + using date_time::Jul; + using date_time::Aug; + using date_time::Sep; + using date_time::Oct; + using date_time::Nov; + using date_time::Dec; + using date_time::NotAMonth; + using date_time::NumMonths; + + //! Exception thrown if a greg_month is constructed with a value out of range + struct BOOST_SYMBOL_VISIBLE bad_month : public std::out_of_range + { + bad_month() : std::out_of_range(std::string("Month number is out of range 1..12")) {} + }; + //! Build a policy class for the greg_month_rep + typedef CV::simple_exception_policy greg_month_policies; + //! A constrained range that implements the gregorian_month rules + typedef CV::constrained_value greg_month_rep; + + + //! Wrapper class to represent months in gregorian based calendar + class BOOST_SYMBOL_VISIBLE greg_month : public greg_month_rep { + public: + typedef date_time::months_of_year month_enum; + + //! Construct a month from the months_of_year enumeration + BOOST_CXX14_CONSTEXPR greg_month(month_enum theMonth) : + greg_month_rep(static_cast(theMonth)) {} + //! Construct from a short value + BOOST_CXX14_CONSTEXPR greg_month(value_type theMonth) : greg_month_rep(theMonth) {} + //! Convert the value back to a short + BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;} + //! Returns month as number from 1 to 12 + BOOST_CXX14_CONSTEXPR value_type as_number() const {return value_;} + BOOST_CXX14_CONSTEXPR month_enum as_enum() const {return static_cast(value_);} + + //! Returns 3 char english string for the month ex: Jan, Feb, Mar, Apr + const char* + as_short_string() const + { + static const char* const short_month_names[NumMonths] + = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", "NAM"}; + return short_month_names[value_-1]; + } + + //! Returns full name of month as string in english ex: January, February + const char* + as_long_string() const + { + static const char* const long_month_names[NumMonths] + = {"January","February","March","April","May","June","July","August", + "September","October","November","December","NotAMonth"}; + return long_month_names[value_-1]; + } + +#ifndef BOOST_NO_STD_WSTRING + + //! Returns 3 wchar_t english string for the month ex: Jan, Feb, Mar, Apr + const wchar_t* + as_short_wstring() const + { + static const wchar_t* const w_short_month_names[NumMonths] + = {L"Jan",L"Feb",L"Mar",L"Apr",L"May",L"Jun",L"Jul",L"Aug",L"Sep",L"Oct", + L"Nov",L"Dec",L"NAM"}; + return w_short_month_names[value_-1]; + } + + //! Returns full name of month as wchar_t string in english ex: January, February + const wchar_t* + as_long_wstring() const + { + static const wchar_t* const w_long_month_names[NumMonths] + = {L"January",L"February",L"March",L"April",L"May",L"June",L"July",L"August", + L"September",L"October",L"November",L"December",L"NotAMonth"}; + return w_long_month_names[value_-1]; + } + +#endif // BOOST_NO_STD_WSTRING + + /* parameterized as_*_string functions are intended to be called + * from a template function: "... as_short_string(charT c='\0');" */ + const char* as_short_string(char) const + { + return as_short_string(); + } + const char* as_long_string(char) const + { + return as_long_string(); + } +#ifndef BOOST_NO_STD_WSTRING + const wchar_t* as_short_string(wchar_t) const + { + return as_short_wstring(); + } + const wchar_t* as_long_string(wchar_t) const + { + return as_long_wstring(); + } +#endif // BOOST_NO_STD_WSTRING + }; + +} } //namespace gregorian + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_weekday.hpp b/src/vendor/boost/date_time/gregorian/greg_weekday.hpp new file mode 100644 index 000000000..46b70927b --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_weekday.hpp @@ -0,0 +1,100 @@ +#ifndef GREG_WEEKDAY_HPP___ +#define GREG_WEEKDAY_HPP___ + +/* Copyright (c) 2002,2003,2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //bring enum values into the namespace + using date_time::Sunday; + using date_time::Monday; + using date_time::Tuesday; + using date_time::Wednesday; + using date_time::Thursday; + using date_time::Friday; + using date_time::Saturday; + + + //! Exception that flags that a weekday number is incorrect + struct BOOST_SYMBOL_VISIBLE bad_weekday : public std::out_of_range + { + bad_weekday() : std::out_of_range(std::string("Weekday is out of range 0..6")) {} + }; + typedef CV::simple_exception_policy greg_weekday_policies; + typedef CV::constrained_value greg_weekday_rep; + + + //! Represent a day within a week (range 0==Sun to 6==Sat) + class BOOST_SYMBOL_VISIBLE greg_weekday : public greg_weekday_rep { + public: + typedef boost::date_time::weekdays weekday_enum; + BOOST_CXX14_CONSTEXPR greg_weekday(value_type day_of_week_num) : + greg_weekday_rep(day_of_week_num) + {} + + BOOST_CXX14_CONSTEXPR value_type as_number() const {return value_;} + BOOST_CXX14_CONSTEXPR weekday_enum as_enum() const {return static_cast(value_);} + + //! Return a 3 digit english string of the day of week (eg: Sun) + const char* as_short_string() const + { + static const char* const short_weekday_names[] + = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; + + return short_weekday_names[value_]; + } + + //! Return a point to a long english string representing day of week + const char* as_long_string() const + { + static const char* const long_weekday_names[] + = {"Sunday","Monday","Tuesday","Wednesday", "Thursday", "Friday", "Saturday"}; + + return long_weekday_names[value_]; + } + + +#ifndef BOOST_NO_STD_WSTRING + + //! Return a 3 digit english wchar_t string of the day of week (eg: Sun) + const wchar_t* as_short_wstring() const + { + static const wchar_t* const w_short_weekday_names[]={L"Sun", L"Mon", L"Tue", + L"Wed", L"Thu", L"Fri", L"Sat"}; + return w_short_weekday_names[value_]; + } + + //! Return a point to a long english wchar_t string representing day of week + const wchar_t* as_long_wstring() const + { + static const wchar_t* const w_long_weekday_names[]= {L"Sunday",L"Monday",L"Tuesday", + L"Wednesday", L"Thursday", + L"Friday", L"Saturday"}; + return w_long_weekday_names[value_]; + } + +#endif // BOOST_NO_STD_WSTRING + + + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_year.hpp b/src/vendor/boost/date_time/gregorian/greg_year.hpp new file mode 100644 index 000000000..b2d456a8c --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_year.hpp @@ -0,0 +1,52 @@ +#ifndef GREG_YEAR_HPP___ +#define GREG_YEAR_HPP___ + +/* Copyright (c) 2002,2003, 2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Exception type for gregorian year + struct BOOST_SYMBOL_VISIBLE bad_year : public std::out_of_range + { + bad_year() : + std::out_of_range(std::string("Year is out of valid range: 1400..9999")) + {} + }; + //! Policy class that declares error handling gregorian year type + typedef CV::simple_exception_policy greg_year_policies; + + //! Generated representation for gregorian year + typedef CV::constrained_value greg_year_rep; + + //! Represent a year (range 1400 - 9999) + /*! This small class allows for simple conversion an integer value into + a year for the gregorian calendar. This currently only allows a + range of 1400 to 9999. Both ends of the range are a bit arbitrary + at the moment, but they are the limits of current testing of the + library. As such they may be increased in the future. + */ + class BOOST_SYMBOL_VISIBLE greg_year : public greg_year_rep { + public: + BOOST_CXX14_CONSTEXPR greg_year(value_type year) : greg_year_rep(year) {} + BOOST_CXX14_CONSTEXPR operator value_type() const {return value_;} + }; + + + +} } //namespace gregorian + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/greg_ymd.hpp b/src/vendor/boost/date_time/gregorian/greg_ymd.hpp new file mode 100644 index 000000000..503666c31 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/greg_ymd.hpp @@ -0,0 +1,33 @@ +#ifndef DATE_TIME_GREG_YMD_HPP__ +#define DATE_TIME_GREG_YMD_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include "boost/date_time/year_month_day.hpp" +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/gregorian/greg_day.hpp" +#include "boost/date_time/gregorian/greg_year.hpp" +#include "boost/date_time/gregorian/greg_month.hpp" + +namespace boost { +namespace gregorian { + + typedef date_time::year_month_day_base greg_year_month_day; + + + +} } //namespace gregorian + + + + +#endif + diff --git a/src/vendor/boost/date_time/gregorian/gregorian.hpp b/src/vendor/boost/date_time/gregorian/gregorian.hpp new file mode 100644 index 000000000..47d545ecc --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/gregorian.hpp @@ -0,0 +1,38 @@ +#ifndef GREGORIAN_HPP__ +#define GREGORIAN_HPP__ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file gregorian.hpp + Single file header that provides overall include for all elements of + the gregorian date-time system. This includes the various types + defined, but also other functions for formatting and parsing. +*/ + + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/gregorian/gregorian_types.hpp" +#include "boost/date_time/gregorian/conversion.hpp" +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/gregorian/formatters_limited.hpp" +#else +#include "boost/date_time/gregorian/formatters.hpp" +#endif + +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +#include "boost/date_time/gregorian/greg_facet.hpp" +#else +#include "boost/date_time/gregorian/gregorian_io.hpp" +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + +#include "boost/date_time/gregorian/parsers.hpp" + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/gregorian_io.hpp b/src/vendor/boost/date_time/gregorian/gregorian_io.hpp new file mode 100644 index 000000000..49e5d41ed --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/gregorian_io.hpp @@ -0,0 +1,784 @@ +#ifndef DATE_TIME_GREGORIAN_IO_HPP__ +#define DATE_TIME_GREGORIAN_IO_HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include // i/ostreambuf_iterator +#include +#include +#include +#include +#include +#include +#include +#include // to_tm will be needed in the facets + +namespace boost { +namespace gregorian { + + + typedef boost::date_time::period_formatter wperiod_formatter; + typedef boost::date_time::period_formatter period_formatter; + + typedef boost::date_time::date_facet wdate_facet; + typedef boost::date_time::date_facet date_facet; + + typedef boost::date_time::period_parser period_parser; + typedef boost::date_time::period_parser wperiod_parser; + + typedef boost::date_time::special_values_formatter special_values_formatter; + typedef boost::date_time::special_values_formatter wspecial_values_formatter; + + typedef boost::date_time::special_values_parser special_values_parser; + typedef boost::date_time::special_values_parser wspecial_values_parser; + + typedef boost::date_time::date_input_facet date_input_facet; + typedef boost::date_time::date_input_facet wdate_input_facet; + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::date& d) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), d); + else { + //instantiate a custom facet for dealing with dates since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every date + //if the locale did not already exist. Of course this will be overridden + //if the user imbues at some later point. With the default settings + //for the facet the resulting format will be the same as the + //std::time_facet settings. + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), d); + } + return os; + } + + //! input operator for date + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, date& d) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, d); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, d); + } + } + catch(...) { + // mask tells us what exceptions are turned on + std::ios_base::iostate exception_mask = is.exceptions(); + // if the user wants exceptions on failbit, we'll rethrow our + // date_time exception & set the failbit + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} // ignore this one + throw; // rethrow original exception + } + else { + // if the user want's to fail quietly, we simply set the failbit + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::date_duration& dd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), dd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), dd); + + } + return os; + } + + //! input operator for date_duration + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, date_duration& dd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, dd); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, dd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::date_period& dp) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), dp); + else { + //instantiate a custom facet for dealing with date periods since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the local did not already exist. Of course this will be overridden + //if the user imbues at some later point. With the default settings + //for the facet the resulting format will be the same as the + //std::time_facet settings. + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), dp); + + } + return os; + } + + //! input operator for date_period + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, date_period& dp) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, dp); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, dp); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + /********** small gregorian types **********/ + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::greg_month& gm) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), gm); + else { + custom_date_facet* f = new custom_date_facet();//-> 10/1074199752/32 because year & day not initialized in put(...) + //custom_date_facet* f = new custom_date_facet("%B"); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), gm); + } + return os; + } + + //! input operator for greg_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_month& m) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, m); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, m); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::greg_weekday& gw) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), gw); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), gw); + } + return os; + } + + //! input operator for greg_weekday + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_weekday& wd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, wd); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, wd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + //NOTE: output operator for greg_day was not necessary + + //! input operator for greg_day + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_day& gd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, gd); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, gd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + //NOTE: output operator for greg_year was not necessary + + //! input operator for greg_year + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, greg_year& gy) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, gy); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, gy); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + /********** date generator types **********/ + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::partial_date& pd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), pd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), pd); + } + return os; + } + + //! input operator for partial_date + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, partial_date& pd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, pd); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, pd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::nth_day_of_the_week_in_month& nkd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), nkd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), nkd); + } + return os; + } + + //! input operator for nth_day_of_the_week_in_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + nth_day_of_the_week_in_month& nday) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, nday); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, nday); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::first_day_of_the_week_in_month& fkd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), fkd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), fkd); + } + return os; + } + + //! input operator for first_day_of_the_week_in_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + first_day_of_the_week_in_month& fkd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, fkd); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, fkd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::last_day_of_the_week_in_month& lkd) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), lkd); + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), lkd); + } + return os; + } + + //! input operator for last_day_of_the_week_in_month + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + last_day_of_the_week_in_month& lkd) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, lkd); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, lkd); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::first_day_of_the_week_after& fda) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), fda); + } + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), fda); + } + return os; + } + + //! input operator for first_day_of_the_week_after + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + first_day_of_the_week_after& fka) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, fka); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, fka); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + + template + inline std::basic_ostream& + operator<<(std::basic_ostream& os, const boost::gregorian::first_day_of_the_week_before& fdb) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::date_facet custom_date_facet; + std::ostreambuf_iterator output_itr(os); + if (std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(output_itr, os, os.fill(), fdb); + } + else { + custom_date_facet* f = new custom_date_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(output_itr, os, os.fill(), fdb); + } + return os; + } + + //! input operator for first_day_of_the_week_before + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, + first_day_of_the_week_before& fkb) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::date_input_facet date_input_facet_local; + + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, fkb); + } + else { + date_input_facet_local* f = new date_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, fkb); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + + } + } + return is; + } + + +} } // namespaces + +#endif // DATE_TIME_GREGORIAN_IO_HPP__ diff --git a/src/vendor/boost/date_time/gregorian/gregorian_types.hpp b/src/vendor/boost/date_time/gregorian/gregorian_types.hpp new file mode 100644 index 000000000..d50e9cc7d --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/gregorian_types.hpp @@ -0,0 +1,109 @@ +#ifndef _GREGORIAN_TYPES_HPP__ +#define _GREGORIAN_TYPES_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file gregorian_types.hpp + Single file header that defines most of the types for the gregorian + date-time system. +*/ + +#include "boost/date_time/date.hpp" +#include "boost/date_time/period.hpp" +#include "boost/date_time/gregorian/greg_calendar.hpp" +#include "boost/date_time/gregorian/greg_duration.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#endif +#include "boost/date_time/gregorian/greg_date.hpp" +#include "boost/date_time/date_generators.hpp" +#include "boost/date_time/date_clock_device.hpp" +#include "boost/date_time/date_iterator.hpp" +#include "boost/date_time/adjust_functors.hpp" + +namespace boost { + +//! Gregorian date system based on date_time components +/*! This date system defines a full complement of types including + * a date, date_duration, date_period, day_clock, and a + * day_iterator. + */ +namespace gregorian { + //! Date periods for the gregorian system + /*!\ingroup date_basics + */ + typedef date_time::period date_period; + + //! A unifying date_generator base type + /*! A unifying date_generator base type for: + * partial_date, nth_day_of_the_week_in_month, + * first_day_of_the_week_in_month, and last_day_of_the_week_in_month + */ + typedef date_time::year_based_generator year_based_generator; + + //! A date generation object type + typedef date_time::partial_date partial_date; + + typedef date_time::nth_kday_of_month nth_kday_of_month; + typedef nth_kday_of_month nth_day_of_the_week_in_month; + + typedef date_time::first_kday_of_month first_kday_of_month; + typedef first_kday_of_month first_day_of_the_week_in_month; + + typedef date_time::last_kday_of_month last_kday_of_month; + typedef last_kday_of_month last_day_of_the_week_in_month; + + typedef date_time::first_kday_after first_kday_after; + typedef first_kday_after first_day_of_the_week_after; + + typedef date_time::first_kday_before first_kday_before; + typedef first_kday_before first_day_of_the_week_before; + + //! A clock to get the current day from the local computer + /*!\ingroup date_basics + */ + typedef date_time::day_clock day_clock; + + //! Base date_iterator type for gregorian types. + /*!\ingroup date_basics + */ + typedef date_time::date_itr_base date_iterator; + + //! A day level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> day_iterator; + //! A week level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> week_iterator; + //! A month level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> month_iterator; + //! A year level iterator + /*!\ingroup date_basics + */ + typedef date_time::date_itr, + date> year_iterator; + + // bring in these date_generator functions from date_time namespace + using date_time::days_until_weekday; + using date_time::days_before_weekday; + using date_time::next_weekday; + using date_time::previous_weekday; + +} } //namespace gregorian + + + +#endif diff --git a/src/vendor/boost/date_time/gregorian/parsers.hpp b/src/vendor/boost/date_time/gregorian/parsers.hpp new file mode 100644 index 000000000..48274f649 --- /dev/null +++ b/src/vendor/boost/date_time/gregorian/parsers.hpp @@ -0,0 +1,110 @@ +#ifndef GREGORIAN_PARSERS_HPP___ +#define GREGORIAN_PARSERS_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace gregorian { + + //! Return special_value from string argument + /*! Return special_value from string argument. If argument is + * not one of the special value names (defined in names.hpp), + * return 'not_special' */ + inline + date_time::special_values + special_value_from_string(const std::string& s) { + static const char* const special_value_names[date_time::NumSpecialValues] + = {"not-a-date-time","-infinity","+infinity","min_date_time", + "max_date_time","not_special"}; + + short i = date_time::find_match(special_value_names, + special_value_names, + date_time::NumSpecialValues, + s); + if(i >= date_time::NumSpecialValues) { // match not found + return date_time::not_special; + } + else { + return static_cast(i); + } + } + + //! Deprecated: Use from_simple_string + inline date from_string(const std::string& s) { + return date_time::parse_date(s); + } + + //! From delimited date string where with order year-month-day eg: 2002-1-25 or 2003-Jan-25 (full month name is also accepted) + inline date from_simple_string(const std::string& s) { + return date_time::parse_date(s, date_time::ymd_order_iso); + } + + //! From delimited date string where with order year-month-day eg: 1-25-2003 or Jan-25-2003 (full month name is also accepted) + inline date from_us_string(const std::string& s) { + return date_time::parse_date(s, date_time::ymd_order_us); + } + + //! From delimited date string where with order day-month-year eg: 25-1-2002 or 25-Jan-2003 (full month name is also accepted) + inline date from_uk_string(const std::string& s) { + return date_time::parse_date(s, date_time::ymd_order_dmy); + } + + //! From iso type date string where with order year-month-day eg: 20020125 + inline date from_undelimited_string(const std::string& s) { + return date_time::parse_undelimited_date(s); + } + + //! From iso type date string where with order year-month-day eg: 20020125 + inline date date_from_iso_string(const std::string& s) { + return date_time::parse_undelimited_date(s); + } + +#if !(defined(BOOST_NO_STD_ITERATOR_TRAITS)) + //! Stream should hold a date in the form of: 2002-1-25. Month number, abbrev, or name are accepted + /* Arguments passed in by-value for convertability of char[] + * to iterator_type. Calls to from_stream_type are by-reference + * since conversion is already done */ + template + inline date from_stream(iterator_type beg, iterator_type end) { + if(beg == end) + { + return date(not_a_date_time); + } + typedef typename std::iterator_traits::value_type value_type; + return date_time::from_stream_type(beg, end, value_type()); + } +#endif //BOOST_NO_STD_ITERATOR_TRAITS + +#if (defined(_MSC_VER) && (_MSC_VER < 1300)) + // This function cannot be compiled with MSVC 6.0 due to internal compiler shorcomings +#else + //! Function to parse a date_period from a string (eg: [2003-Oct-31/2003-Dec-25]) + inline date_period date_period_from_string(const std::string& s){ + return date_time::from_simple_string_type(s); + } +# if !defined(BOOST_NO_STD_WSTRING) + //! Function to parse a date_period from a wstring (eg: [2003-Oct-31/2003-Dec-25]) + inline date_period date_period_from_wstring(const std::wstring& s){ + return date_time::from_simple_string_type(s); + } +# endif // BOOST_NO_STD_WSTRING +#endif + +} } //namespace gregorian + +#endif diff --git a/src/vendor/boost/date_time/gregorian_calendar.hpp b/src/vendor/boost/date_time/gregorian_calendar.hpp new file mode 100644 index 000000000..291dfc33a --- /dev/null +++ b/src/vendor/boost/date_time/gregorian_calendar.hpp @@ -0,0 +1,69 @@ +#ifndef DATE_TIME_GREGORIAN_CALENDAR_HPP__ +#define DATE_TIME_GREGORIAN_CALENDAR_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + + + //! An implementation of the Gregorian calendar + /*! This is a parameterized implementation of a proleptic Gregorian Calendar that + can be used in the creation of date systems or just to perform calculations. + All the methods of this class are static functions, so the intent is to + never create instances of this class. + @tparam ymd_type_ Struct type representing the year, month, day. The ymd_type must + define a of types for the year, month, and day. These types need to be + arithmetic types. + @tparam date_int_type_ Underlying type for the date count. Must be an arithmetic type. + */ + template + class BOOST_SYMBOL_VISIBLE gregorian_calendar_base { + public: + //! define a type a date split into components + typedef ymd_type_ ymd_type; + //! define a type for representing months + typedef typename ymd_type::month_type month_type; + //! define a type for representing days + typedef typename ymd_type::day_type day_type; + //! Type to hold a stand alone year value (eg: 2002) + typedef typename ymd_type::year_type year_type; + //! Define the integer type to use for internal calculations + typedef date_int_type_ date_int_type; + + + static BOOST_CXX14_CONSTEXPR unsigned short day_of_week(const ymd_type& ymd); + static BOOST_CXX14_CONSTEXPR int week_number(const ymd_type&ymd); + static BOOST_CXX14_CONSTEXPR date_int_type day_number(const ymd_type& ymd); + static BOOST_CXX14_CONSTEXPR date_int_type julian_day_number(const ymd_type& ymd); + static BOOST_CXX14_CONSTEXPR date_int_type modjulian_day_number(const ymd_type& ymd); + static BOOST_CXX14_CONSTEXPR ymd_type from_day_number(date_int_type); + static BOOST_CXX14_CONSTEXPR ymd_type from_julian_day_number(date_int_type); + static BOOST_CXX14_CONSTEXPR ymd_type from_modjulian_day_number(date_int_type); + static BOOST_CXX14_CONSTEXPR bool is_leap_year(year_type); + static BOOST_CXX14_CONSTEXPR unsigned short end_of_month_day(year_type y, month_type m); + static BOOST_CXX14_CONSTEXPR ymd_type epoch(); + static BOOST_CXX14_CONSTEXPR unsigned short days_in_week(); + + }; + + + +} } //namespace + +#include "boost/date_time/gregorian_calendar.ipp" + + + + +#endif + + diff --git a/src/vendor/boost/date_time/gregorian_calendar.ipp b/src/vendor/boost/date_time/gregorian_calendar.ipp new file mode 100644 index 000000000..f41c4993f --- /dev/null +++ b/src/vendor/boost/date_time/gregorian_calendar.ipp @@ -0,0 +1,224 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +namespace boost { +namespace date_time { + //! Return the day of the week (0==Sunday, 1==Monday, etc) + /*! Converts a year-month-day into a day of the week number + */ + template + BOOST_CXX14_CONSTEXPR + inline + unsigned short + gregorian_calendar_base::day_of_week(const ymd_type& ymd) { + unsigned short a = static_cast((14-ymd.month)/12); + unsigned short y = static_cast(ymd.year - a); + unsigned short m = static_cast(ymd.month + 12*a - 2); + unsigned short d = static_cast((ymd.day + y + (y/4) - (y/100) + (y/400) + (31*m)/12) % 7); + //std::cout << year << "-" << month << "-" << day << " is day: " << d << "\n"; + return d; + } + + //!Return the iso week number for the date + /*!Implements the rules associated with the iso 8601 week number. + Basically the rule is that Week 1 of the year is the week that contains + January 4th or the week that contains the first Thursday in January. + Reference for this algorithm is the Calendar FAQ by Claus Tondering, April 2000. + */ + template + BOOST_CXX14_CONSTEXPR + inline + int + gregorian_calendar_base::week_number(const ymd_type& ymd) { + unsigned long julianbegin = julian_day_number(ymd_type(ymd.year,1,1)); + unsigned long juliantoday = julian_day_number(ymd); + unsigned long day = (julianbegin + 3) % 7; + unsigned long week = (juliantoday + day - julianbegin + 4)/7; + + if ((week >= 1) && (week <= 52)) { + return static_cast(week); + } + + if (week == 53) { + if((day==6) ||(day == 5 && is_leap_year(ymd.year))) { + return static_cast(week); //under these circumstances week == 53. + } else { + return 1; //monday - wednesday is in week 1 of next year + } + } + //if the week is not in current year recalculate using the previous year as the beginning year + else if (week == 0) { + julianbegin = julian_day_number(ymd_type(static_cast(ymd.year-1),1,1)); + juliantoday = julian_day_number(ymd); + day = (julianbegin + 3) % 7; + week = (juliantoday + day - julianbegin + 4)/7; + return static_cast(week); + } + + return static_cast(week); //not reachable -- well except if day == 5 and is_leap_year != true + + } + + //! Convert a ymd_type into a day number + /*! The day number is an absolute number of days since the start of count + */ + template + BOOST_CXX14_CONSTEXPR + inline + date_int_type_ + gregorian_calendar_base::day_number(const ymd_type& ymd) + { + unsigned short a = static_cast((14-ymd.month)/12); + unsigned short y = static_cast(ymd.year + 4800 - a); + unsigned short m = static_cast(ymd.month + 12*a - 3); + unsigned long d = ymd.day + ((153*m + 2)/5) + 365*y + (y/4) - (y/100) + (y/400) - 32045; + return static_cast(d); + } + + //! Convert a year-month-day into the julian day number + /*! Since this implementation uses julian day internally, this is the same as the day_number. + */ + template + BOOST_CXX14_CONSTEXPR + inline + date_int_type_ + gregorian_calendar_base::julian_day_number(const ymd_type& ymd) + { + return day_number(ymd); + } + + //! Convert year-month-day into a modified julian day number + /*! The day number is an absolute number of days. + * MJD 0 thus started on 17 Nov 1858(Gregorian) at 00:00:00 UTC + */ + template + BOOST_CXX14_CONSTEXPR + inline + date_int_type_ + gregorian_calendar_base::modjulian_day_number(const ymd_type& ymd) + { + return julian_day_number(ymd)-2400001; //prerounded + } + + //! Change a day number into a year-month-day + template + BOOST_CXX14_CONSTEXPR + inline + ymd_type_ + gregorian_calendar_base::from_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a + 3)/146097; + date_int_type c = a-((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - (1461*d)/4; + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast(m + 3 - 12 * (m/10)); + year_type year = static_cast(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(static_cast(year),month,day); + } + + //! Change a day number into a year-month-day + template + BOOST_CXX14_CONSTEXPR + inline + ymd_type_ + gregorian_calendar_base::from_julian_day_number(date_int_type dayNumber) + { + date_int_type a = dayNumber + 32044; + date_int_type b = (4*a+3)/146097; + date_int_type c = a - ((146097*b)/4); + date_int_type d = (4*c + 3)/1461; + date_int_type e = c - ((1461*d)/4); + date_int_type m = (5*e + 2)/153; + unsigned short day = static_cast(e - ((153*m + 2)/5) + 1); + unsigned short month = static_cast(m + 3 - 12 * (m/10)); + year_type year = static_cast(100*b + d - 4800 + (m/10)); + //std::cout << year << "-" << month << "-" << day << "\n"; + + return ymd_type(year,month,day); + } + + //! Change a modified julian day number into a year-month-day + template + BOOST_CXX14_CONSTEXPR + inline + ymd_type_ + gregorian_calendar_base::from_modjulian_day_number(date_int_type dayNumber) { + date_int_type jd = dayNumber + 2400001; //is 2400000.5 prerounded + return from_julian_day_number(jd); + } + + //! Determine if the provided year is a leap year + /*! + *@return true if year is a leap year, false otherwise + */ + template + BOOST_CXX14_CONSTEXPR + inline + bool + gregorian_calendar_base::is_leap_year(year_type year) + { + //divisible by 4, not if divisible by 100, but true if divisible by 400 + return (!(year % 4)) && ((year % 100) || (!(year % 400))); + } + + //! Calculate the last day of the month + /*! Find the day which is the end of the month given year and month + * No error checking is performed. + */ + template + BOOST_CXX14_CONSTEXPR + inline + unsigned short + gregorian_calendar_base::end_of_month_day(year_type year, + month_type month) + { + switch (month) { + case 2: + if (is_leap_year(year)) { + return 29; + } else { + return 28; + } + case 4: + case 6: + case 9: + case 11: + return 30; + default: + return 31; + } + } + + //! Provide the ymd_type specification for the calendar start + template + BOOST_CXX14_CONSTEXPR + inline + ymd_type_ + gregorian_calendar_base::epoch() + { + return ymd_type(1400,1,1); + } + + //! Defines length of a week for week calculations + template + BOOST_CXX14_CONSTEXPR + inline + unsigned short + gregorian_calendar_base::days_in_week() + { + return 7; + } + + +} } //namespace gregorian diff --git a/src/vendor/boost/date_time/int_adapter.hpp b/src/vendor/boost/date_time/int_adapter.hpp new file mode 100644 index 000000000..79a8a8294 --- /dev/null +++ b/src/vendor/boost/date_time/int_adapter.hpp @@ -0,0 +1,516 @@ +#ifndef _DATE_TIME_INT_ADAPTER_HPP__ +#define _DATE_TIME_INT_ADAPTER_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include "boost/config.hpp" +#include "boost/limits.hpp" //work around compilers without limits +#include "boost/date_time/special_defs.hpp" +#include "boost/date_time/locale_config.hpp" +#ifndef BOOST_DATE_TIME_NO_LOCALE +# include +#endif + +#if defined(BOOST_MSVC) +#pragma warning(push) +// conditional expression is constant +#pragma warning(disable: 4127) +#endif + +namespace boost { +namespace date_time { + + +//! Adapter to create integer types with +-infinity, and not a value +/*! This class is used internally in counted date/time representations. + * It adds the floating point like features of infinities and + * not a number. It also provides mathmatical operations with + * consideration to special values following these rules: + *@code + * +infinity - infinity == Not A Number (NAN) + * infinity * non-zero == infinity + * infinity * zero == NAN + * +infinity * -integer == -infinity + * infinity / infinity == NAN + * infinity * infinity == infinity + *@endcode + */ +template +class int_adapter { +public: + typedef int_type_ int_type; + BOOST_CXX14_CONSTEXPR int_adapter(int_type v) : + value_(v) + {} + static BOOST_CONSTEXPR bool has_infinity() + { + return true; + } + static BOOST_CONSTEXPR int_adapter pos_infinity() + { + return (::std::numeric_limits::max)(); + } + static BOOST_CONSTEXPR int_adapter neg_infinity() + { + return (::std::numeric_limits::min)(); + } + static BOOST_CONSTEXPR int_adapter not_a_number() + { + return (::std::numeric_limits::max)()-1; + } + static BOOST_CONSTEXPR int_adapter max BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (::std::numeric_limits::max)()-2; + } + static BOOST_CONSTEXPR int_adapter min BOOST_PREVENT_MACRO_SUBSTITUTION () + { + return (::std::numeric_limits::min)()+1; + } + static BOOST_CXX14_CONSTEXPR int_adapter from_special(special_values sv) + { + switch (sv) { + case not_a_date_time: return not_a_number(); + case neg_infin: return neg_infinity(); + case pos_infin: return pos_infinity(); + case max_date_time: return (max)(); + case min_date_time: return (min)(); + default: return not_a_number(); + } + } + static BOOST_CONSTEXPR bool is_inf(int_type v) + { + return (v == neg_infinity().as_number() || + v == pos_infinity().as_number()); + } + static BOOST_CXX14_CONSTEXPR bool is_neg_inf(int_type v) + { + return (v == neg_infinity().as_number()); + } + static BOOST_CXX14_CONSTEXPR bool is_pos_inf(int_type v) + { + return (v == pos_infinity().as_number()); + } + static BOOST_CXX14_CONSTEXPR bool is_not_a_number(int_type v) + { + return (v == not_a_number().as_number()); + } + //! Returns either special value type or is_not_special + static BOOST_CXX14_CONSTEXPR special_values to_special(int_type v) + { + if (is_not_a_number(v)) return not_a_date_time; + if (is_neg_inf(v)) return neg_infin; + if (is_pos_inf(v)) return pos_infin; + return not_special; + } + + //-3 leaves room for representations of infinity and not a date + static BOOST_CONSTEXPR int_type maxcount() + { + return (::std::numeric_limits::max)()-3; + } + BOOST_CONSTEXPR bool is_infinity() const + { + return (value_ == neg_infinity().as_number() || + value_ == pos_infinity().as_number()); + } + BOOST_CONSTEXPR bool is_pos_infinity()const + { + return(value_ == pos_infinity().as_number()); + } + BOOST_CONSTEXPR bool is_neg_infinity()const + { + return(value_ == neg_infinity().as_number()); + } + BOOST_CONSTEXPR bool is_nan() const + { + return (value_ == not_a_number().as_number()); + } + BOOST_CONSTEXPR bool is_special() const + { + return(is_infinity() || is_nan()); + } + BOOST_CONSTEXPR bool operator==(const int_adapter& rhs) const + { + return (compare(rhs) == 0); + } + BOOST_CXX14_CONSTEXPR bool operator==(const int& rhs) const + { + if(!std::numeric_limits::is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return false; + } + } + return (compare(rhs) == 0); + } + BOOST_CONSTEXPR bool operator!=(const int_adapter& rhs) const + { + return (compare(rhs) != 0); + } + BOOST_CXX14_CONSTEXPR bool operator!=(const int& rhs) const + { + if(!std::numeric_limits::is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return true; + } + } + return (compare(rhs) != 0); + } + BOOST_CONSTEXPR bool operator<(const int_adapter& rhs) const + { + return (compare(rhs) == -1); + } + BOOST_CXX14_CONSTEXPR bool operator<(const int& rhs) const + { + // quiets compiler warnings + if(!std::numeric_limits::is_signed) + { + if(is_neg_inf(value_) && rhs == 0) + { + return true; + } + } + return (compare(rhs) == -1); + } + BOOST_CONSTEXPR bool operator>(const int_adapter& rhs) const + { + return (compare(rhs) == 1); + } + BOOST_CONSTEXPR int_type as_number() const + { + return value_; + } + //! Returns either special value type or is_not_special + BOOST_CONSTEXPR special_values as_special() const + { + return int_adapter::to_special(value_); + } + //creates nasty ambiguities +// operator int_type() const +// { +// return value_; +// } + + /*! Operator allows for adding dissimilar int_adapter types. + * The return type will match that of the the calling object's type */ + template + BOOST_CXX14_CONSTEXPR + int_adapter operator+(const int_adapter& rhs) const + { + if(is_special() || rhs.is_special()) + { + if (is_nan() || rhs.is_nan()) + { + return int_adapter::not_a_number(); + } + if((is_pos_inf(value_) && rhs.is_neg_inf(rhs.as_number())) || + (is_neg_inf(value_) && rhs.is_pos_inf(rhs.as_number())) ) + { + return int_adapter::not_a_number(); + } + if (is_infinity()) + { + return *this; + } + if (rhs.is_pos_inf(rhs.as_number())) + { + return int_adapter::pos_infinity(); + } + if (rhs.is_neg_inf(rhs.as_number())) + { + return int_adapter::neg_infinity(); + } + } + return int_adapter(value_ + static_cast(rhs.as_number())); + } + + BOOST_CXX14_CONSTEXPR + int_adapter operator+(const int_type rhs) const + { + if(is_special()) + { + if (is_nan()) + { + return int_adapter(not_a_number()); + } + if (is_infinity()) + { + return *this; + } + } + return int_adapter(value_ + rhs); + } + + /*! Operator allows for subtracting dissimilar int_adapter types. + * The return type will match that of the the calling object's type */ + template + BOOST_CXX14_CONSTEXPR + int_adapter operator-(const int_adapter& rhs)const + { + if(is_special() || rhs.is_special()) + { + if (is_nan() || rhs.is_nan()) + { + return int_adapter::not_a_number(); + } + if((is_pos_inf(value_) && rhs.is_pos_inf(rhs.as_number())) || + (is_neg_inf(value_) && rhs.is_neg_inf(rhs.as_number())) ) + { + return int_adapter::not_a_number(); + } + if (is_infinity()) + { + return *this; + } + if (rhs.is_pos_inf(rhs.as_number())) + { + return int_adapter::neg_infinity(); + } + if (rhs.is_neg_inf(rhs.as_number())) + { + return int_adapter::pos_infinity(); + } + } + return int_adapter(value_ - static_cast(rhs.as_number())); + } + + BOOST_CXX14_CONSTEXPR + int_adapter operator-(const int_type rhs) const + { + if(is_special()) + { + if (is_nan()) + { + return int_adapter(not_a_number()); + } + if (is_infinity()) + { + return *this; + } + } + return int_adapter(value_ - rhs); + } + + // should templatize this to be consistant with op +- + BOOST_CXX14_CONSTEXPR + int_adapter operator*(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ * rhs.value_); + } + + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + BOOST_CXX14_CONSTEXPR + int_adapter operator*(const int rhs) const + { + if(is_special()) + { + return mult_div_specials(rhs); + } + return int_adapter(value_ * rhs); + } + + // should templatize this to be consistant with op +- + BOOST_CXX14_CONSTEXPR + int_adapter operator/(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(is_infinity() && rhs.is_infinity()) + { + return int_adapter(not_a_number()); + } + if(rhs != 0) + { + return mult_div_specials(rhs); + } + else { // let divide by zero blow itself up + return int_adapter(value_ / rhs.value_); //NOLINT + } + } + return int_adapter(value_ / rhs.value_); + } + + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + BOOST_CXX14_CONSTEXPR + int_adapter operator/(const int rhs) const + { + if(is_special() && rhs != 0) + { + return mult_div_specials(rhs); + } + // let divide by zero blow itself up like int + return int_adapter(value_ / rhs); //NOLINT + } + + // should templatize this to be consistant with op +- + BOOST_CXX14_CONSTEXPR + int_adapter operator%(const int_adapter& rhs)const + { + if(this->is_special() || rhs.is_special()) + { + if(is_infinity() && rhs.is_infinity()) + { + return int_adapter(not_a_number()); + } + if(rhs != 0) + { + return mult_div_specials(rhs); + } + else { // let divide by zero blow itself up + return int_adapter(value_ % rhs.value_); //NOLINT + } + } + return int_adapter(value_ % rhs.value_); + } + + /*! Provided for cases when automatic conversion from + * 'int' to 'int_adapter' causes incorrect results. */ + BOOST_CXX14_CONSTEXPR + int_adapter operator%(const int rhs) const + { + if(is_special() && rhs != 0) + { + return mult_div_specials(rhs); + } + // let divide by zero blow itself up + return int_adapter(value_ % rhs); //NOLINT + } + +private: + int_type value_; + + //! returns -1, 0, 1, or 2 if 'this' is <, ==, >, or 'nan comparison' rhs + BOOST_CXX14_CONSTEXPR + int compare( const int_adapter& rhs ) const + { + if(this->is_special() || rhs.is_special()) + { + if(this->is_nan() || rhs.is_nan()) { + if(this->is_nan() && rhs.is_nan()) { + return 0; // equal + } + else { + return 2; // nan + } + } + if((is_neg_inf(value_) && !is_neg_inf(rhs.value_)) || + (is_pos_inf(rhs.value_) && !is_pos_inf(value_)) ) + { + return -1; // less than + } + if((is_pos_inf(value_) && !is_pos_inf(rhs.value_)) || + (is_neg_inf(rhs.value_) && !is_neg_inf(value_)) ) { + return 1; // greater than + } + } + if(value_ < rhs.value_) return -1; + if(value_ > rhs.value_) return 1; + // implied-> if(value_ == rhs.value_) + return 0; + } + + /* When multiplying and dividing with at least 1 special value + * very simmilar rules apply. In those cases where the rules + * are different, they are handled in the respective operator + * function. */ + //! Assumes at least 'this' or 'rhs' is a special value + BOOST_CXX14_CONSTEXPR + int_adapter mult_div_specials(const int_adapter& rhs) const + { + if(this->is_nan() || rhs.is_nan()) { + return int_adapter(not_a_number()); + } + BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits::is_signed ? 0 : 1; + if((*this > 0 && rhs > 0) || (*this < min_value && rhs < min_value)) { + return int_adapter(pos_infinity()); + } + if((*this > 0 && rhs < min_value) || (*this < min_value && rhs > 0)) { + return int_adapter(neg_infinity()); + } + //implied -> if(this->value_ == 0 || rhs.value_ == 0) + return int_adapter(not_a_number()); + } + + /* Overloaded function necessary because of special + * situation where int_adapter is instantiated with + * 'unsigned' and func is called with negative int. + * It would produce incorrect results since 'unsigned' + * wraps around when initialized with a negative value */ + //! Assumes 'this' is a special value + BOOST_CXX14_CONSTEXPR + int_adapter mult_div_specials(const int& rhs) const + { + if(this->is_nan()) { + return int_adapter(not_a_number()); + } + BOOST_CONSTEXPR_OR_CONST int min_value = std::numeric_limits::is_signed ? 0 : 1; + if((*this > 0 && rhs > 0) || (*this < min_value && rhs < 0)) { + return int_adapter(pos_infinity()); + } + if((*this > 0 && rhs < 0) || (*this < min_value && rhs > 0)) { + return int_adapter(neg_infinity()); + } + //implied -> if(this->value_ == 0 || rhs.value_ == 0) + return int_adapter(not_a_number()); + } + +}; + +#ifndef BOOST_DATE_TIME_NO_LOCALE + /*! Expected output is either a numeric representation + * or a special values representation.
    + * Ex. "12", "+infinity", "not-a-number", etc. */ + //template, typename int_type> + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const int_adapter& ia) + { + if(ia.is_special()) { + // switch copied from date_names_put.hpp + switch(ia.as_special()) + { + case not_a_date_time: + os << "not-a-number"; + break; + case pos_infin: + os << "+infinity"; + break; + case neg_infin: + os << "-infinity"; + break; + default: + os << ""; + } + } + else { + os << ia.as_number(); + } + return os; + } +#endif + + +} } //namespace date_time + +#if defined(BOOST_MSVC) +#pragma warning(pop) +#endif + +#endif diff --git a/src/vendor/boost/date_time/iso_format.hpp b/src/vendor/boost/date_time/iso_format.hpp new file mode 100644 index 000000000..2e7942d8b --- /dev/null +++ b/src/vendor/boost/date_time/iso_format.hpp @@ -0,0 +1,303 @@ +#ifndef ISO_FORMAT_HPP___ +#define ISO_FORMAT_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/parse_format_base.hpp" + +namespace boost { +namespace date_time { + +//! Class to provide common iso formatting spec +template +class iso_format_base { +public: + //! Describe month format -- its an integer in iso format + static month_format_spec month_format() + { + return month_as_integer; + } + + //! String used printed is date is invalid + static const charT* not_a_date() + { + return "not-a-date-time"; + } + //! String used to for positive infinity value + static const charT* pos_infinity() + { + return "+infinity"; + } + //! String used to for positive infinity value + static const charT* neg_infinity() + { + return "-infinity"; + } + + //! ISO char for a year -- used in durations + static charT year_sep_char() + { + return 'Y'; + } + //! ISO char for a month + static charT month_sep_char() + { + return '-'; + } + //! ISO char for a day + static charT day_sep_char() + { + return '-'; + } + //! char for minute + static charT hour_sep_char() + { + return ':'; + } + //! char for minute + static charT minute_sep_char() + { + return ':'; + } + //! char for second + static charT second_sep_char() + { + return ':'; + } + //! ISO char for a period + static charT period_start_char() + { + return 'P'; + } + //! Used in time in mixed strings to set start of time + static charT time_start_char() + { + return 'T'; + } + + //! Used in mixed strings to identify start of a week number + static charT week_start_char() + { + return 'W'; + } + + //! Separators for periods + static charT period_sep_char() + { + return '/'; + } + //! Separator for hh:mm:ss + static charT time_sep_char() + { + return ':'; + } + //! Preferred Separator for hh:mm:ss,decimal_fraction + static charT fractional_time_sep_char() + { + return ','; + } + + static bool is_component_sep(charT sep) + { + switch(sep) { + case 'H': + case 'M': + case 'S': + case 'W': + case 'T': + case 'Y': + case 'D':return true; + default: + return false; + } + } + + static bool is_fractional_time_sep(charT sep) + { + switch(sep) { + case ',': + case '.': return true; + default: return false; + } + } + static bool is_timezone_sep(charT sep) + { + switch(sep) { + case '+': + case '-': return true; + default: return false; + } + } + static charT element_sep_char() + { + return '-'; + } + +}; + +#ifndef BOOST_NO_STD_WSTRING + +//! Class to provide common iso formatting spec +template<> +class iso_format_base { +public: + //! Describe month format -- its an integer in iso format + static month_format_spec month_format() + { + return month_as_integer; + } + + //! String used printed is date is invalid + static const wchar_t* not_a_date() + { + return L"not-a-date-time"; + } + //! String used to for positive infinity value + static const wchar_t* pos_infinity() + { + return L"+infinity"; + } + //! String used to for positive infinity value + static const wchar_t* neg_infinity() + { + return L"-infinity"; + } + + //! ISO char for a year -- used in durations + static wchar_t year_sep_char() + { + return 'Y'; + } + //! ISO char for a month + static wchar_t month_sep_char() + { + return '-'; + } + //! ISO char for a day + static wchar_t day_sep_char() + { + return '-'; + } + //! char for minute + static wchar_t hour_sep_char() + { + return ':'; + } + //! char for minute + static wchar_t minute_sep_char() + { + return ':'; + } + //! char for second + static wchar_t second_sep_char() + { + return ':'; + } + //! ISO char for a period + static wchar_t period_start_char() + { + return 'P'; + } + //! Used in time in mixed strings to set start of time + static wchar_t time_start_char() + { + return 'T'; + } + + //! Used in mixed strings to identify start of a week number + static wchar_t week_start_char() + { + return 'W'; + } + + //! Separators for periods + static wchar_t period_sep_char() + { + return '/'; + } + //! Separator for hh:mm:ss + static wchar_t time_sep_char() + { + return ':'; + } + //! Preferred Separator for hh:mm:ss,decimal_fraction + static wchar_t fractional_time_sep_char() + { + return ','; + } + + static bool is_component_sep(wchar_t sep) + { + switch(sep) { + case 'H': + case 'M': + case 'S': + case 'W': + case 'T': + case 'Y': + case 'D':return true; + default: + return false; + } + } + + static bool is_fractional_time_sep(wchar_t sep) + { + switch(sep) { + case ',': + case '.': return true; + default: return false; + } + } + static bool is_timezone_sep(wchar_t sep) + { + switch(sep) { + case '+': + case '-': return true; + default: return false; + } + } + static wchar_t element_sep_char() + { + return '-'; + } + +}; + +#endif // BOOST_NO_STD_WSTRING + +//! Format description for iso normal YYYYMMDD +template +class iso_format : public iso_format_base { +public: + //! The ios standard format doesn't use char separators + static bool has_date_sep_chars() + { + return false; + } +}; + +//! Extended format uses seperators YYYY-MM-DD +template +class iso_extended_format : public iso_format_base { +public: + //! Extended format needs char separators + static bool has_date_sep_chars() + { + return true; + } + +}; + +} } //namespace date_time + + + + +#endif diff --git a/src/vendor/boost/date_time/locale_config.hpp b/src/vendor/boost/date_time/locale_config.hpp new file mode 100644 index 000000000..f1a349301 --- /dev/null +++ b/src/vendor/boost/date_time/locale_config.hpp @@ -0,0 +1,33 @@ +#ifndef DATE_TIME_LOCALE_CONFIG_HPP___ +#define DATE_TIME_LOCALE_CONFIG_HPP___ + +/* Copyright (c) 2002-2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +// This file configures whether the library will support locales and hence +// iostream based i/o. Even if a compiler has some support for locales, +// any failure to be compatible gets the compiler on the exclusion list. +// +// At the moment this is defined for MSVC 6 and any compiler that +// defines BOOST_NO_STD_LOCALE (gcc 2.95.x) + +#include "boost/config.hpp" //sets BOOST_NO_STD_LOCALE +#include "boost/config/workaround.hpp" + +//This file basically becomes a noop if locales are not properly supported +#if (defined(BOOST_NO_STD_LOCALE) \ + || (BOOST_WORKAROUND( BOOST_MSVC, < 1300)) \ + || (BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT( 0x581 )) ) \ + || (BOOST_WORKAROUND( BOOST_XLCPP_ZOS, BOOST_TESTED_AT( 0x42010000 )) ) /* "shadows" the locale enabled overloads from */ \ + ) +#define BOOST_DATE_TIME_NO_LOCALE +#endif + + +#endif + diff --git a/src/vendor/boost/date_time/microsec_time_clock.hpp b/src/vendor/boost/date_time/microsec_time_clock.hpp new file mode 100644 index 000000000..42a918b53 --- /dev/null +++ b/src/vendor/boost/date_time/microsec_time_clock.hpp @@ -0,0 +1,158 @@ +#ifndef DATE_TIME_HIGHRES_TIME_CLOCK_HPP___ +#define DATE_TIME_HIGHRES_TIME_CLOCK_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +/*! @file microsec_time_clock.hpp + This file contains a high resolution time clock implementation. +*/ + +#include +#include +#include +#include +#include +#include +#if defined(BOOST_HAS_FTIME) +#include +#endif + +#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + +namespace boost { +namespace date_time { + + //! A clock providing microsecond level resolution + /*! A high precision clock that measures the local time + * at a resolution up to microseconds and adjusts to the + * resolution of the time system. For example, for the + * a library configuration with nano second resolution, + * the last 3 places of the fractional seconds will always + * be 000 since there are 1000 nano-seconds in a micro second. + */ + template + class microsec_clock + { + private: + //! Type for the function used to convert time_t to tm + typedef std::tm* (*time_converter)(const std::time_t*, std::tm*); + + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_duration_type::rep_type resolution_traits_type; + + //! return a local time object for the given zone, based on computer clock + //JKG -- looks like we could rewrite this against universal_time + template + static time_type local_time(shared_ptr tz_ptr) + { + typedef typename time_type::utc_time_type utc_time_type; + typedef second_clock second_clock; + // we'll need to know the utc_offset this machine has + // in order to get a utc_time_type set to utc + utc_time_type utc_time = second_clock::universal_time(); + time_duration_type utc_offset = second_clock::local_time() - utc_time; + // use micro clock to get a local time with sub seconds + // and adjust it to get a true utc time reading with sub seconds + utc_time = microsec_clock::local_time() - utc_offset; + return time_type(utc_time, tz_ptr); + } + + //! Returns the local time based on computer clock settings + static time_type local_time() + { + return create_time(&c_time::localtime); + } + + //! Returns the UTC time based on computer settings + static time_type universal_time() + { + return create_time(&c_time::gmtime); + } + + private: + static time_type create_time(time_converter converter) + { +#ifdef BOOST_HAS_GETTIMEOFDAY + timeval tv; + gettimeofday(&tv, 0); //gettimeofday does not support TZ adjust on Linux. + std::time_t t = tv.tv_sec; + boost::uint32_t sub_sec = tv.tv_usec; +#elif defined(BOOST_HAS_FTIME) + boost::winapi::FILETIME_ ft; + boost::winapi::GetSystemTimeAsFileTime(&ft); +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) + // Some runtime library implementations expect local times as the norm for ctime functions. + { + boost::winapi::FILETIME_ local_ft; + boost::winapi::FileTimeToLocalFileTime(&ft, &local_ft); + ft = local_ft; + } +#endif + + boost::uint64_t micros = file_time_to_microseconds(ft); // it will not wrap, since ft is the current time + // and cannot be before 1970-Jan-01 + std::time_t t = static_cast(micros / 1000000UL); // seconds since epoch + // microseconds -- static casts suppress warnings + boost::uint32_t sub_sec = static_cast(micros % 1000000UL); +#else +#error Internal Boost.DateTime error: BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK is defined, however neither gettimeofday nor FILETIME support is detected. +#endif + + std::tm curr; + std::tm* curr_ptr = converter(&t, &curr); + date_type d(static_cast< typename date_type::year_type::value_type >(curr_ptr->tm_year + 1900), + static_cast< typename date_type::month_type::value_type >(curr_ptr->tm_mon + 1), + static_cast< typename date_type::day_type::value_type >(curr_ptr->tm_mday)); + + //The following line will adjust the fractional second tick in terms + //of the current time system. For example, if the time system + //doesn't support fractional seconds then res_adjust returns 0 + //and all the fractional seconds return 0. + int adjust = static_cast< int >(resolution_traits_type::res_adjust() / 1000000); + + time_duration_type td(static_cast< typename time_duration_type::hour_type >(curr_ptr->tm_hour), + static_cast< typename time_duration_type::min_type >(curr_ptr->tm_min), + static_cast< typename time_duration_type::sec_type >(curr_ptr->tm_sec), + sub_sec * adjust); + + return time_type(d,td); + } + +#if defined(BOOST_HAS_FTIME) + /*! + * The function converts file_time into number of microseconds elapsed since 1970-Jan-01 + * + * \note Only dates after 1970-Jan-01 are supported. Dates before will be wrapped. + */ + static boost::uint64_t file_time_to_microseconds(boost::winapi::FILETIME_ const& ft) + { + // shift is difference between 1970-Jan-01 & 1601-Jan-01 + // in 100-nanosecond units + const boost::uint64_t shift = 116444736000000000ULL; // (27111902 << 32) + 3577643008 + + // 100-nanos since 1601-Jan-01 + boost::uint64_t ft_as_integer = (static_cast< boost::uint64_t >(ft.dwHighDateTime) << 32) | static_cast< boost::uint64_t >(ft.dwLowDateTime); + + ft_as_integer -= shift; // filetime is now 100-nanos since 1970-Jan-01 + return (ft_as_integer / 10U); // truncate to microseconds + } +#endif + }; + + +} } //namespace date_time + +#endif //BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + + +#endif + diff --git a/src/vendor/boost/date_time/parse_format_base.hpp b/src/vendor/boost/date_time/parse_format_base.hpp new file mode 100644 index 000000000..d4b2f5975 --- /dev/null +++ b/src/vendor/boost/date_time/parse_format_base.hpp @@ -0,0 +1,29 @@ +#ifndef DATE_TIME_PARSE_FORMAT_BASE__ +#define DATE_TIME_PARSE_FORMAT_BASE__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +namespace boost { +namespace date_time { + + //! Enum for distinguishing parsing and formatting options + enum month_format_spec {month_as_integer, month_as_short_string, + month_as_long_string}; + + //! Enum for distinguishing the order of Month, Day, & Year. + /*! Enum for distinguishing the order in which Month, Day, & Year + * will appear in a date string */ + enum ymd_order_spec {ymd_order_iso, //order is year-month-day + ymd_order_dmy, //day-month-year + ymd_order_us}; //order is month-day-year + + +} }//namespace date_time + +#endif diff --git a/src/vendor/boost/date_time/period.hpp b/src/vendor/boost/date_time/period.hpp new file mode 100644 index 000000000..47cedc6b1 --- /dev/null +++ b/src/vendor/boost/date_time/period.hpp @@ -0,0 +1,375 @@ +#ifndef DATE_TIME_PERIOD_HPP___ +#define DATE_TIME_PERIOD_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! \file period.hpp + This file contain the implementation of the period abstraction. This is + basically the same idea as a range. Although this class is intended for + use in the time library, it is pretty close to general enough for other + numeric uses. + +*/ + +#include +#include + + +namespace boost { +namespace date_time { + //!Provides generalized period type useful in date-time systems + /*!This template uses a class to represent a time point within the period + and another class to represent a duration. As a result, this class is + not appropriate for use when the number and duration representation + are the same (eg: in the regular number domain). + + A period can be specified by providing either the begining point and + a duration or the begining point and the end point( end is NOT part + of the period but 1 unit past it. A period will be "invalid" if either + end_point <= begin_point or the given duration is <= 0. Any valid period + will return false for is_null(). + + Zero length periods are also considered invalid. Zero length periods are + periods where the begining and end points are the same, or, the given + duration is zero. For a zero length period, the last point will be one + unit less than the begining point. + + In the case that the begin and last are the same, the period has a + length of one unit. + + The best way to handle periods is usually to provide a begining point and + a duration. So, day1 + 7 days is a week period which includes all of the + first day and 6 more days (eg: Sun to Sat). + + */ + template + class BOOST_SYMBOL_VISIBLE period : private + boost::less_than_comparable + , boost::equality_comparable< period + > > + { + public: + typedef point_rep point_type; + typedef duration_rep duration_type; + + BOOST_CXX14_CONSTEXPR period(point_rep first_point, point_rep end_point); + BOOST_CXX14_CONSTEXPR period(point_rep first_point, duration_rep len); + BOOST_CXX14_CONSTEXPR point_rep begin() const; + BOOST_CXX14_CONSTEXPR point_rep end() const; + BOOST_CXX14_CONSTEXPR point_rep last() const; + BOOST_CXX14_CONSTEXPR duration_rep length() const; + BOOST_CXX14_CONSTEXPR bool is_null() const; + BOOST_CXX14_CONSTEXPR bool operator==(const period& rhs) const; + BOOST_CXX14_CONSTEXPR bool operator<(const period& rhs) const; + BOOST_CXX14_CONSTEXPR void shift(const duration_rep& d); + BOOST_CXX14_CONSTEXPR void expand(const duration_rep& d); + BOOST_CXX14_CONSTEXPR bool contains(const point_rep& point) const; + BOOST_CXX14_CONSTEXPR bool contains(const period& other) const; + BOOST_CXX14_CONSTEXPR bool intersects(const period& other) const; + BOOST_CXX14_CONSTEXPR bool is_adjacent(const period& other) const; + BOOST_CXX14_CONSTEXPR bool is_before(const point_rep& point) const; + BOOST_CXX14_CONSTEXPR bool is_after(const point_rep& point) const; + BOOST_CXX14_CONSTEXPR period intersection(const period& other) const; + BOOST_CXX14_CONSTEXPR period merge(const period& other) const; + BOOST_CXX14_CONSTEXPR period span(const period& other) const; + private: + point_rep begin_; + point_rep last_; + }; + + //! create a period from begin to last eg: [begin,end) + /*! If end <= begin then the period will be invalid + */ + template + inline BOOST_CXX14_CONSTEXPR + period::period(point_rep first_point, + point_rep end_point) : + begin_(first_point), + last_(end_point - duration_rep::unit()) + {} + + //! create a period as [begin, begin+len) + /*! If len is <= 0 then the period will be invalid + */ + template + inline BOOST_CXX14_CONSTEXPR + period::period(point_rep first_point, duration_rep len) : + begin_(first_point), + last_(first_point + len-duration_rep::unit()) + { } + + + //! Return the first element in the period + template + inline BOOST_CXX14_CONSTEXPR + point_rep period::begin() const + { + return begin_; + } + + //! Return one past the last element + template + inline BOOST_CXX14_CONSTEXPR + point_rep period::end() const + { + return last_ + duration_rep::unit(); + } + + //! Return the last item in the period + template + inline BOOST_CXX14_CONSTEXPR + point_rep period::last() const + { + return last_; + } + + //! True if period is ill formed (length is zero or less) + template + inline BOOST_CXX14_CONSTEXPR + bool period::is_null() const + { + return end() <= begin_; + } + + //! Return the length of the period + template + inline BOOST_CXX14_CONSTEXPR + duration_rep period::length() const + { + if(last_ < begin_){ // invalid period + return last_+duration_rep::unit() - begin_; + } + else{ + return end() - begin_; // normal case + } + } + + //! Equality operator + template + inline BOOST_CXX14_CONSTEXPR + bool period::operator==(const period& rhs) const + { + return ((begin_ == rhs.begin_) && + (last_ == rhs.last_)); + } + + //! Strict as defined by rhs.last <= lhs.last + template + inline BOOST_CXX14_CONSTEXPR + bool period::operator<(const period& rhs) const + { + return (last_ < rhs.begin_); + } + + + //! Shift the start and end by the specified amount + template + inline BOOST_CXX14_CONSTEXPR + void period::shift(const duration_rep& d) + { + begin_ = begin_ + d; + last_ = last_ + d; + } + + /** Expands the size of the period by the duration on both ends. + * + *So before expand + *@code + * + * [-------] + * ^ ^ ^ ^ ^ ^ ^ + * 1 2 3 4 5 6 7 + * + *@endcode + * After expand(2) + *@code + * + * [----------------------] + * ^ ^ ^ ^ ^ ^ ^ + * 1 2 3 4 5 6 7 + * + *@endcode + */ + template + inline BOOST_CXX14_CONSTEXPR + void period::expand(const duration_rep& d) + { + begin_ = begin_ - d; + last_ = last_ + d; + } + + //! True if the point is inside the period, zero length periods contain no points + template + inline BOOST_CXX14_CONSTEXPR + bool period::contains(const point_rep& point) const + { + return ((point >= begin_) && + (point <= last_)); + } + + + //! True if this period fully contains (or equals) the other period + template + inline BOOST_CXX14_CONSTEXPR + bool period::contains(const period& other) const + { + return ((begin_ <= other.begin_) && (last_ >= other.last_)); + } + + + //! True if periods are next to each other without a gap. + /* In the example below, p1 and p2 are adjacent, but p3 is not adjacent + * with either of p1 or p2. + *@code + * [-p1-) + * [-p2-) + * [-p3-) + *@endcode + */ + template + inline BOOST_CXX14_CONSTEXPR + bool period::is_adjacent(const period& other) const + { + return (other.begin() == end() || + begin_ == other.end()); + } + + + //! True if all of the period is prior or t < start + /* In the example below only point 1 would evaluate to true. + *@code + * [---------]) + * ^ ^ ^ ^ ^ + * 1 2 3 4 5 + * + *@endcode + */ + template + inline BOOST_CXX14_CONSTEXPR + bool period::is_after(const point_rep& t) const + { + if (is_null()) + { + return false; //null period isn't after + } + + return t < begin_; + } + + //! True if all of the period is prior to the passed point or end <= t + /* In the example below points 4 and 5 return true. + *@code + * [---------]) + * ^ ^ ^ ^ ^ + * 1 2 3 4 5 + * + *@endcode + */ + template + inline BOOST_CXX14_CONSTEXPR + bool period::is_before(const point_rep& t) const + { + if (is_null()) + { + return false; //null period isn't before anything + } + + return last_ < t; + } + + + //! True if the periods overlap in any way + /* In the example below p1 intersects with p2, p4, and p6. + *@code + * [---p1---) + * [---p2---) + * [---p3---) + * [---p4---) + * [-p5-) + * [-p6-) + *@endcode + */ + template + inline BOOST_CXX14_CONSTEXPR + bool period::intersects(const period& other) const + { + return ( contains(other.begin_) || + other.contains(begin_) || + ((other.begin_ < begin_) && (other.last_ >= begin_))); + } + + //! Returns the period of intersection or invalid range no intersection + template + inline BOOST_CXX14_CONSTEXPR + period + period::intersection(const period& other) const + { + if (begin_ > other.begin_) { + if (last_ <= other.last_) { //case2 + return *this; + } + //case 1 + return period(begin_, other.end()); + } + else { + if (last_ <= other.last_) { //case3 + return period(other.begin_, this->end()); + } + //case4 + return other; + } + //unreachable + } + + //! Returns the union of intersecting periods -- or null period + /*! + */ + template + inline BOOST_CXX14_CONSTEXPR + period + period::merge(const period& other) const + { + if (this->intersects(other)) { + if (begin_ < other.begin_) { + return period(begin_, last_ > other.last_ ? this->end() : other.end()); + } + + return period(other.begin_, last_ > other.last_ ? this->end() : other.end()); + + } + return period(begin_,begin_); // no intersect return null + } + + //! Combine two periods with earliest start and latest end. + /*! Combines two periods and any gap between them such that + * start = min(p1.start, p2.start) + * end = max(p1.end , p2.end) + *@code + * [---p1---) + * [---p2---) + * result: + * [-----------p3----------) + *@endcode + */ + template + inline BOOST_CXX14_CONSTEXPR + period + period::span(const period& other) const + { + point_rep start((begin_ < other.begin_) ? begin() : other.begin()); + point_rep newend((last_ < other.last_) ? other.end() : this->end()); + return period(start, newend); + } + + +} } //namespace date_time + + + +#endif diff --git a/src/vendor/boost/date_time/period_formatter.hpp b/src/vendor/boost/date_time/period_formatter.hpp new file mode 100644 index 000000000..2b46c3a01 --- /dev/null +++ b/src/vendor/boost/date_time/period_formatter.hpp @@ -0,0 +1,200 @@ + +#ifndef DATETIME_PERIOD_FORMATTER_HPP___ +#define DATETIME_PERIOD_FORMATTER_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include + +namespace boost { namespace date_time { + + + //! Not a facet, but a class used to specify and control period formats + /*! Provides settings for the following: + * - period_separator -- default '/' + * - period_open_start_delimeter -- default '[' + * - period_open_range_end_delimeter -- default ')' + * - period_closed_range_end_delimeter -- default ']' + * - display_as_open_range, display_as_closed_range -- default closed_range + * + * Thus the default formatting for a period is as follows: + *@code + * [period.start()/period.last()] + *@endcode + * So for a typical date_period this would be + *@code + * [2004-Jan-04/2004-Feb-01] + *@endcode + * where the date formatting is controlled by the date facet + */ + template > > + class period_formatter { + public: + typedef std::basic_string string_type; + typedef CharT char_type; + typedef typename std::basic_string::const_iterator const_itr_type; + typedef std::vector > collection_type; + + static const char_type default_period_separator[2]; + static const char_type default_period_start_delimeter[2]; + static const char_type default_period_open_range_end_delimeter[2]; + static const char_type default_period_closed_range_end_delimeter[2]; + + enum range_display_options { AS_OPEN_RANGE, AS_CLOSED_RANGE }; + + //! Constructor that sets up period formatter options -- default should suffice most cases. + period_formatter(range_display_options range_option_in = AS_CLOSED_RANGE, + const char_type* const period_separator = default_period_separator, + const char_type* const period_start_delimeter = default_period_start_delimeter, + const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter, + const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) : + m_range_option(range_option_in), + m_period_separator(period_separator), + m_period_start_delimeter(period_start_delimeter), + m_open_range_end_delimeter(period_open_range_end_delimeter), + m_closed_range_end_delimeter(period_closed_range_end_delimeter) + {} + + //! Puts the characters between period elements into stream -- default is / + OutItrT put_period_separator(OutItrT& oitr) const + { + const_itr_type ci = m_period_separator.begin(); + while (ci != m_period_separator.end()) { + *oitr = *ci; + ci++; + } + return oitr; + } + + //! Puts the period start characters into stream -- default is [ + OutItrT put_period_start_delimeter(OutItrT& oitr) const + { + const_itr_type ci = m_period_start_delimeter.begin(); + while (ci != m_period_start_delimeter.end()) { + *oitr = *ci; + ci++; + } + return oitr; + } + + //! Puts the period end characters into stream as controled by open/closed range setting. + OutItrT put_period_end_delimeter(OutItrT& oitr) const + { + + const_itr_type ci, end; + if (m_range_option == AS_OPEN_RANGE) { + ci = m_open_range_end_delimeter.begin(); + end = m_open_range_end_delimeter.end(); + } + else { + ci = m_closed_range_end_delimeter.begin(); + end = m_closed_range_end_delimeter.end(); + } + while (ci != end) { + *oitr = *ci; + ci++; + } + return oitr; + } + + range_display_options range_option() const + { + return m_range_option; + } + + //! Reset the range_option control + void + range_option(range_display_options option) const + { + m_range_option = option; + } + + //! Change the delimiter strings + void delimiter_strings(const string_type& separator, + const string_type& start_delim, + const string_type& open_end_delim, + const string_type& closed_end_delim) + { + m_period_separator = separator; + m_period_start_delimeter = start_delim; + m_open_range_end_delimeter = open_end_delim; + m_closed_range_end_delimeter = closed_end_delim; + } + + //! Generic code to output a period -- no matter the period type. + /*! This generic code will output any period using a facet to + * to output the 'elements'. For example, in the case of a date_period + * the elements will be instances of a date which will be formatted + * according the to setup in the passed facet parameter. + * + * The steps for formatting a period are always the same: + * - put the start delimiter + * - put start element + * - put the separator + * - put either last or end element depending on range settings + * - put end delimeter depending on range settings + * + * Thus for a typical date period the result might look like this: + *@code + * + * [March 01, 2004/June 07, 2004] <-- closed range + * [March 01, 2004/June 08, 2004) <-- open range + * + *@endcode + */ + template + OutItrT put_period(OutItrT next, + std::ios_base& a_ios, + char_type a_fill, + const period_type& p, + const facet_type& facet) const { + put_period_start_delimeter(next); + next = facet.put(next, a_ios, a_fill, p.begin()); + put_period_separator(next); + if (m_range_option == AS_CLOSED_RANGE) { + facet.put(next, a_ios, a_fill, p.last()); + } + else { + facet.put(next, a_ios, a_fill, p.end()); + } + put_period_end_delimeter(next); + return next; + } + + + private: + range_display_options m_range_option; + string_type m_period_separator; + string_type m_period_start_delimeter; + string_type m_open_range_end_delimeter; + string_type m_closed_range_end_delimeter; + }; + + template + const typename period_formatter::char_type + period_formatter::default_period_separator[2] = {'/'}; + + template + const typename period_formatter::char_type + period_formatter::default_period_start_delimeter[2] = {'['}; + + template + const typename period_formatter::char_type + period_formatter::default_period_open_range_end_delimeter[2] = {')'}; + + template + const typename period_formatter::char_type + period_formatter::default_period_closed_range_end_delimeter[2] = {']'}; + + } } //namespace boost::date_time + +#endif diff --git a/src/vendor/boost/date_time/period_parser.hpp b/src/vendor/boost/date_time/period_parser.hpp new file mode 100644 index 000000000..7e4cdc7d7 --- /dev/null +++ b/src/vendor/boost/date_time/period_parser.hpp @@ -0,0 +1,197 @@ + +#ifndef DATETIME_PERIOD_PARSER_HPP___ +#define DATETIME_PERIOD_PARSER_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace boost { namespace date_time { + + + //! Not a facet, but a class used to specify and control period parsing + /*! Provides settings for the following: + * - period_separator -- default '/' + * - period_open_start_delimeter -- default '[' + * - period_open_range_end_delimeter -- default ')' + * - period_closed_range_end_delimeter -- default ']' + * - display_as_open_range, display_as_closed_range -- default closed_range + * + * For a typical date_period, the contents of the input stream would be + *@code + * [2004-Jan-04/2004-Feb-01] + *@endcode + * where the date format is controlled by the date facet + */ + template + class period_parser { + public: + typedef std::basic_string string_type; + typedef CharT char_type; + //typedef typename std::basic_string::const_iterator const_itr_type; + typedef std::istreambuf_iterator stream_itr_type; + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > collection_type; + + static const char_type default_period_separator[2]; + static const char_type default_period_start_delimeter[2]; + static const char_type default_period_open_range_end_delimeter[2]; + static const char_type default_period_closed_range_end_delimeter[2]; + + enum period_range_option { AS_OPEN_RANGE, AS_CLOSED_RANGE }; + + //! Constructor that sets up period parser options + period_parser(period_range_option range_opt = AS_CLOSED_RANGE, + const char_type* const period_separator = default_period_separator, + const char_type* const period_start_delimeter = default_period_start_delimeter, + const char_type* const period_open_range_end_delimeter = default_period_open_range_end_delimeter, + const char_type* const period_closed_range_end_delimeter = default_period_closed_range_end_delimeter) + : m_range_option(range_opt) + { + delimiters.push_back(string_type(period_separator)); + delimiters.push_back(string_type(period_start_delimeter)); + delimiters.push_back(string_type(period_open_range_end_delimeter)); + delimiters.push_back(string_type(period_closed_range_end_delimeter)); + } + + period_range_option range_option() const + { + return m_range_option; + } + void range_option(period_range_option option) + { + m_range_option = option; + } + collection_type delimiter_strings() const + { + return delimiters; + } + void delimiter_strings(const string_type& separator, + const string_type& start_delim, + const string_type& open_end_delim, + const string_type& closed_end_delim) + { + delimiters.clear(); + delimiters.push_back(separator); + delimiters.push_back(start_delim); + delimiters.push_back(open_end_delim); + delimiters.push_back(closed_end_delim); + } + + //! Generic code to parse a period -- no matter the period type. + /*! This generic code will parse any period using a facet to + * to get the 'elements'. For example, in the case of a date_period + * the elements will be instances of a date which will be parsed + * according the to setup in the passed facet parameter. + * + * The steps for parsing a period are always the same: + * - consume the start delimiter + * - get start element + * - consume the separator + * - get either last or end element depending on range settings + * - consume the end delimeter depending on range settings + * + * Thus for a typical date period the contents of the input stream + * might look like this: + *@code + * + * [March 01, 2004/June 07, 2004] <-- closed range + * [March 01, 2004/June 08, 2004) <-- open range + * + *@endcode + */ + template + period_type get_period(stream_itr_type& sitr, + stream_itr_type& stream_end, + std::ios_base& a_ios, + const period_type& /* p */, + const duration_type& dur_unit, + const facet_type& facet) const + { + // skip leading whitespace + while(std::isspace(*sitr) && sitr != stream_end) { ++sitr; } + + typedef typename period_type::point_type point_type; + point_type p1(not_a_date_time), p2(not_a_date_time); + + + consume_delim(sitr, stream_end, delimiters[START]); // start delim + facet.get(sitr, stream_end, a_ios, p1); // first point + consume_delim(sitr, stream_end, delimiters[SEPARATOR]); // separator + facet.get(sitr, stream_end, a_ios, p2); // second point + + // period construction parameters are always open range [begin, end) + if (m_range_option == AS_CLOSED_RANGE) { + consume_delim(sitr, stream_end, delimiters[CLOSED_END]);// end delim + // add 1 duration unit to p2 to make range open + p2 += dur_unit; + } + else { + consume_delim(sitr, stream_end, delimiters[OPEN_END]); // end delim + } + + return period_type(p1, p2); + } + + private: + collection_type delimiters; + period_range_option m_range_option; + + enum delim_ids { SEPARATOR, START, OPEN_END, CLOSED_END }; + + //! throws ios_base::failure if delimiter and parsed data do not match + void consume_delim(stream_itr_type& sitr, + stream_itr_type& stream_end, + const string_type& delim) const + { + /* string_parse_tree will not parse a string of punctuation characters + * without knowing exactly how many characters to process + * Ex [2000. Will not parse out the '[' string without knowing + * to process only one character. By using length of the delimiter + * string we can safely iterate past it. */ + string_type s; + for(unsigned int i = 0; i < delim.length() && sitr != stream_end; ++i) { + s += *sitr; + ++sitr; + } + if(s != delim) { + boost::throw_exception(std::ios_base::failure("Parse failed. Expected '" + + convert_string_type(delim) + "' but found '" + convert_string_type(s) + "'")); + } + } + }; + + template + const typename period_parser::char_type + period_parser::default_period_separator[2] = {'/'}; + + template + const typename period_parser::char_type + period_parser::default_period_start_delimeter[2] = {'['}; + + template + const typename period_parser::char_type + period_parser::default_period_open_range_end_delimeter[2] = {')'}; + + template + const typename period_parser::char_type + period_parser::default_period_closed_range_end_delimeter[2] = {']'}; + + } } //namespace boost::date_time + +#endif // DATETIME_PERIOD_PARSER_HPP___ diff --git a/src/vendor/boost/date_time/posix_time/conversion.hpp b/src/vendor/boost/date_time/posix_time/conversion.hpp new file mode 100644 index 000000000..cdff4b76f --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/conversion.hpp @@ -0,0 +1,100 @@ +#ifndef POSIX_TIME_CONVERSION_HPP___ +#define POSIX_TIME_CONVERSION_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include // absolute_value +#include + +namespace boost { + +namespace posix_time { + + //! Function that converts a time_t into a ptime. + inline + ptime from_time_t(std::time_t t) + { + return ptime(gregorian::date(1970,1,1)) + seconds(static_cast(t)); + } + + //! Function that converts a ptime into a time_t + inline + std::time_t to_time_t(ptime pt) + { + return (pt - ptime(gregorian::date(1970,1,1))).total_seconds(); + } + + //! Convert a time to a tm structure truncating any fractional seconds + inline + std::tm to_tm(const boost::posix_time::ptime& t) { + std::tm timetm = boost::gregorian::to_tm(t.date()); + boost::posix_time::time_duration td = t.time_of_day(); + timetm.tm_hour = static_cast(td.hours()); + timetm.tm_min = static_cast(td.minutes()); + timetm.tm_sec = static_cast(td.seconds()); + timetm.tm_isdst = -1; // -1 used when dst info is unknown + return timetm; + } + //! Convert a time_duration to a tm structure truncating any fractional seconds and zeroing fields for date components + inline + std::tm to_tm(const boost::posix_time::time_duration& td) { + std::tm timetm; + std::memset(&timetm, 0, sizeof(timetm)); + timetm.tm_hour = static_cast(date_time::absolute_value(td.hours())); + timetm.tm_min = static_cast(date_time::absolute_value(td.minutes())); + timetm.tm_sec = static_cast(date_time::absolute_value(td.seconds())); + timetm.tm_isdst = -1; // -1 used when dst info is unknown + return timetm; + } + + //! Convert a tm struct to a ptime ignoring is_dst flag + inline + ptime ptime_from_tm(const std::tm& timetm) { + boost::gregorian::date d = boost::gregorian::date_from_tm(timetm); + return ptime(d, time_duration(timetm.tm_hour, timetm.tm_min, timetm.tm_sec)); + } + + +#if defined(BOOST_HAS_FTIME) + + //! Function to create a time object from an initialized FILETIME struct. + /*! Function to create a time object from an initialized FILETIME struct. + * A FILETIME struct holds 100-nanosecond units (0.0000001). When + * built with microsecond resolution the FILETIME's sub second value + * will be truncated. Nanosecond resolution has no truncation. + * + * \note FILETIME is part of the Win32 API, so it is not portable to non-windows + * platforms. + * + * \note The function is templated on the FILETIME type, so that + * it can be used with both native FILETIME and the ad-hoc + * boost::detail::winapi::FILETIME_ type. + */ + template< typename TimeT, typename FileTimeT > + inline + TimeT from_ftime(const FileTimeT& ft) + { + return boost::date_time::time_from_ftime(ft); + } + +#endif // BOOST_HAS_FTIME + +} } //namespace boost::posix_time + + + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/date_duration_operators.hpp b/src/vendor/boost/date_time/posix_time/date_duration_operators.hpp new file mode 100644 index 000000000..cd21fa53f --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/date_duration_operators.hpp @@ -0,0 +1,114 @@ +#ifndef DATE_DURATION_OPERATORS_HPP___ +#define DATE_DURATION_OPERATORS_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. + * (See accompanying file LICENSE_1_0.txt or + * http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/gregorian/greg_duration_types.hpp" +#include "boost/date_time/posix_time/ptime.hpp" + +namespace boost { +namespace posix_time { + + /*!@file date_duration_operators.hpp Operators for ptime and + * optional gregorian types. Operators use snap-to-end-of-month behavior. + * Further details on this behavior can be found in reference for + * date_time/date_duration_types.hpp and documentation for + * month and year iterators. + */ + + + /*! Adds a months object and a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator+(const ptime& t, const boost::gregorian::months& m) + { + return t + m.get_offset(t.date()); + } + + /*! Adds a months object to a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator+=(ptime& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t += m.get_offset(t.date()); + } + + /*! Subtracts a months object and a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator-(const ptime& t, const boost::gregorian::months& m) + { + // get_neg_offset returns a negative duration, so we add + return t + m.get_neg_offset(t.date()); + } + + /*! Subtracts a months object from a ptime. Result will be same + * day-of-month as ptime unless original day was the last day of month. + * see date_time::months_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator-=(ptime& t, const boost::gregorian::months& m) + { + return t += m.get_neg_offset(t.date()); + } + + // ptime & years + + /*! Adds a years object and a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator+(const ptime& t, const boost::gregorian::years& y) + { + return t + y.get_offset(t.date()); + } + + /*! Adds a years object to a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator+=(ptime& t, const boost::gregorian::years& y) + { + return t += y.get_offset(t.date()); + } + + /*! Subtracts a years object and a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator-(const ptime& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t + y.get_neg_offset(t.date()); + } + + /*! Subtracts a years object from a ptime. Result will be same + * month and day-of-month as ptime unless original day was the + * last day of month. see date_time::years_duration for more details */ + inline BOOST_CXX14_CONSTEXPR + ptime + operator-=(ptime& t, const boost::gregorian::years& y) + { + // get_neg_offset returns a negative duration, so we add + return t += y.get_neg_offset(t.date()); + } + +}} // namespaces + +#endif // DATE_DURATION_OPERATORS_HPP___ diff --git a/src/vendor/boost/date_time/posix_time/posix_time.hpp b/src/vendor/boost/date_time/posix_time/posix_time.hpp new file mode 100644 index 000000000..aecf8a818 --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/posix_time.hpp @@ -0,0 +1,39 @@ +#ifndef POSIX_TIME_HPP___ +#define POSIX_TIME_HPP___ + +/* Copyright (c) 2002-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ +/*!@file posix_time.hpp Global header file to get all of posix time types + */ + +#include "boost/date_time/compiler_config.hpp" +#include "boost/date_time/posix_time/ptime.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/posix_time/date_duration_operators.hpp" +#endif + +// output functions +#if defined(BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS) +#include "boost/date_time/posix_time/time_formatters_limited.hpp" +#else +#include "boost/date_time/posix_time/time_formatters.hpp" +#endif // BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS + +// streaming operators +#if defined(USE_DATE_TIME_PRE_1_33_FACET_IO) +#include "boost/date_time/posix_time/posix_time_legacy_io.hpp" +#else +#include "boost/date_time/posix_time/posix_time_io.hpp" +#endif // USE_DATE_TIME_PRE_1_33_FACET_IO + +#include "boost/date_time/posix_time/time_parsers.hpp" +#include "boost/date_time/posix_time/conversion.hpp" + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/posix_time_config.hpp b/src/vendor/boost/date_time/posix_time/posix_time_config.hpp new file mode 100644 index 000000000..f554a4949 --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/posix_time_config.hpp @@ -0,0 +1,165 @@ +#ifndef POSIX_TIME_CONFIG_HPP___ +#define POSIX_TIME_CONFIG_HPP___ + +/* Copyright (c) 2002,2003,2005,2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include //for MCW 7.2 std::abs(long long) +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace posix_time { + + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + // set up conditional test compilations +#define BOOST_DATE_TIME_HAS_NANOSECONDS + typedef date_time::time_resolution_traits time_res_traits; +#else + // set up conditional test compilations +#undef BOOST_DATE_TIME_HAS_NANOSECONDS + typedef date_time::time_resolution_traits< + boost::date_time::time_resolution_traits_adapted64_impl, boost::date_time::micro, + 1000000, 6 > time_res_traits; + +#endif + + + //! Base time duration type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE time_duration : + public date_time::time_duration + { + public: + typedef time_res_traits rep_type; + typedef time_res_traits::day_type day_type; + typedef time_res_traits::hour_type hour_type; + typedef time_res_traits::min_type min_type; + typedef time_res_traits::sec_type sec_type; + typedef time_res_traits::fractional_seconds_type fractional_seconds_type; + typedef time_res_traits::tick_type tick_type; + typedef time_res_traits::impl_type impl_type; + BOOST_CXX14_CONSTEXPR time_duration(hour_type hour, + min_type min, + sec_type sec, + fractional_seconds_type fs=0) : + date_time::time_duration(hour,min,sec,fs) + {} + BOOST_CXX14_CONSTEXPR time_duration() : + date_time::time_duration(0,0,0) + {} + //! Construct from special_values + BOOST_CXX14_CONSTEXPR time_duration(boost::date_time::special_values sv) : + date_time::time_duration(sv) + {} + //Give duration access to ticks constructor -- hide from users + friend class date_time::time_duration; + protected: + BOOST_CXX14_CONSTEXPR explicit time_duration(impl_type tick_count) : + date_time::time_duration(tick_count) + {} + }; + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + + //! Simple implementation for the time rep + struct simple_time_rep + { + typedef gregorian::date date_type; + typedef time_duration time_duration_type; + BOOST_CXX14_CONSTEXPR simple_time_rep(date_type d, time_duration_type tod) : + day(d), + time_of_day(tod) + { + // make sure we have sane values for date & time + if(!day.is_special() && !time_of_day.is_special()){ + if(time_of_day >= time_duration_type(24,0,0)) { + while(time_of_day >= time_duration_type(24,0,0)) { + day += date_type::duration_type(1); + time_of_day -= time_duration_type(24,0,0); + } + } + else if(time_of_day.is_negative()) { + while(time_of_day.is_negative()) { + day -= date_type::duration_type(1); + time_of_day += time_duration_type(24,0,0); + } + } + } + } + date_type day; + time_duration_type time_of_day; + BOOST_CXX14_CONSTEXPR bool is_special()const + { + return(is_pos_infinity() || is_neg_infinity() || is_not_a_date_time()); + } + BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const + { + return(day.is_pos_infinity() || time_of_day.is_pos_infinity()); + } + BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const + { + return(day.is_neg_infinity() || time_of_day.is_neg_infinity()); + } + BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const + { + return(day.is_not_a_date() || time_of_day.is_not_a_date_time()); + } + }; + + class BOOST_SYMBOL_VISIBLE posix_time_system_config + { + public: + typedef simple_time_rep time_rep_type; + typedef gregorian::date date_type; + typedef gregorian::date_duration date_duration_type; + typedef time_duration time_duration_type; + typedef time_res_traits::tick_type int_type; + typedef time_res_traits resolution_traits; +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers +#else + BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000000); +#endif + }; + +#else + + class millisec_posix_time_system_config + { + public: + typedef boost::int64_t time_rep_type; + //typedef time_res_traits::tick_type time_rep_type; + typedef gregorian::date date_type; + typedef gregorian::date_duration date_duration_type; + typedef time_duration time_duration_type; + typedef time_res_traits::tick_type int_type; + typedef time_res_traits::impl_type impl_type; + typedef time_res_traits resolution_traits; +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers +#else + BOOST_STATIC_CONSTANT(boost::int64_t, tick_per_second = 1000000); +#endif + }; + +#endif + +} }//namespace posix_time + + +#endif + + diff --git a/src/vendor/boost/date_time/posix_time/posix_time_duration.hpp b/src/vendor/boost/date_time/posix_time/posix_time_duration.hpp new file mode 100644 index 000000000..6dfd782aa --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/posix_time_duration.hpp @@ -0,0 +1,91 @@ +#ifndef POSIX_TIME_DURATION_HPP___ +#define POSIX_TIME_DURATION_HPP___ + +/* Copyright (c) 2002,2003, 2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace posix_time { + + //! Allows expression of durations as an hour count + //! The argument must be an integral type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE hours : public time_duration + { + public: + template + BOOST_CXX14_CONSTEXPR explicit hours(T const& h, + typename boost::enable_if, void>::type* = BOOST_DATE_TIME_NULLPTR) : + time_duration(numeric_cast(h), 0, 0) + {} + }; + + //! Allows expression of durations as a minute count + //! The argument must be an integral type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE minutes : public time_duration + { + public: + template + BOOST_CXX14_CONSTEXPR explicit minutes(T const& m, + typename boost::enable_if, void>::type* = BOOST_DATE_TIME_NULLPTR) : + time_duration(0, numeric_cast(m),0) + {} + }; + + //! Allows expression of durations as a seconds count + //! The argument must be an integral type + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE seconds : public time_duration + { + public: + template + BOOST_CXX14_CONSTEXPR explicit seconds(T const& s, + typename boost::enable_if, void>::type* = BOOST_DATE_TIME_NULLPTR) : + time_duration(0,0, numeric_cast(s)) + {} + }; + + + //! Allows expression of durations as milli seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration millisec; + typedef date_time::subsecond_duration milliseconds; + + //! Allows expression of durations as micro seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration microsec; + typedef date_time::subsecond_duration microseconds; + + //This is probably not needed anymore... +#if defined(BOOST_DATE_TIME_HAS_NANOSECONDS) + + //! Allows expression of durations as nano seconds + /*! \ingroup time_basics + */ + typedef date_time::subsecond_duration nanosec; + typedef date_time::subsecond_duration nanoseconds; + +#endif + +} }//namespace posix_time + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/posix_time_io.hpp b/src/vendor/boost/date_time/posix_time/posix_time_io.hpp new file mode 100644 index 000000000..90b02a691 --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/posix_time_io.hpp @@ -0,0 +1,236 @@ +#ifndef DATE_TIME_POSIX_TIME_IO_HPP__ +#define DATE_TIME_POSIX_TIME_IO_HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include // i/ostreambuf_iterator +#include +#include +#include +#include +#include +#include +#include // to_tm will be needed in the facets + +namespace boost { +namespace posix_time { + + + //! wptime_facet is depricated and will be phased out. use wtime_facet instead + //typedef boost::date_time::time_facet wptime_facet; + //! ptime_facet is depricated and will be phased out. use time_facet instead + //typedef boost::date_time::time_facet ptime_facet; + + //! wptime_input_facet is depricated and will be phased out. use wtime_input_facet instead + //typedef boost::date_time::time_input_facet wptime_input_facet; + //! ptime_input_facet is depricated and will be phased out. use time_input_facet instead + //typedef boost::date_time::time_input_facet ptime_input_facet; + + typedef boost::date_time::time_facet wtime_facet; + typedef boost::date_time::time_facet time_facet; + + typedef boost::date_time::time_input_facet wtime_input_facet; + typedef boost::date_time::time_input_facet time_input_facet; + + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const ptime& p) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::time_facet custom_ptime_facet; + std::ostreambuf_iterator oitr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(oitr, os, os.fill(), p); + else { + //instantiate a custom facet for dealing with times since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the locale did not already exist. Of course this will be overridden + //if the user imbues as some later point. + custom_ptime_facet* f = new custom_ptime_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), p); + } + return os; + } + + //! input operator for ptime + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, ptime& pt) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::time_input_facet time_input_facet_local; + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, pt); + } + else { + time_input_facet_local* f = new time_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, pt); + } + } + catch(...) { + // mask tells us what exceptions are turned on + std::ios_base::iostate exception_mask = is.exceptions(); + // if the user wants exceptions on failbit, we'll rethrow our + // date_time exception & set the failbit + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} // ignore this one + throw; // rethrow original exception + } + else { + // if the user want's to fail quietly, we simply set the failbit + is.setstate(std::ios_base::failbit); + } + } + } + return is; + } + + + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, + const boost::posix_time::time_period& p) { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::time_facet custom_ptime_facet; + std::ostreambuf_iterator oitr(os); + if (std::has_facet(os.getloc())) { + std::use_facet(os.getloc()).put(oitr, os, os.fill(), p); + } + else { + //instantiate a custom facet for dealing with periods since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the local did not already exist. Of course this will be overridden + //if the user imbues as some later point. + custom_ptime_facet* f = new custom_ptime_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), p); + } + return os; + } + + //! input operator for time_period + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, time_period& tp) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::time_input_facet time_input_facet_local; + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, tp); + } + else { + time_input_facet_local* f = new time_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, tp); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + } + } + return is; + } + + + //! ostream operator for posix_time::time_duration + // todo fix to use facet -- place holder for now... + template + inline + std::basic_ostream& + operator<<(std::basic_ostream& os, const time_duration& td) + { + boost::io::ios_flags_saver iflags(os); + typedef boost::date_time::time_facet custom_ptime_facet; + std::ostreambuf_iterator oitr(os); + if (std::has_facet(os.getloc())) + std::use_facet(os.getloc()).put(oitr, os, os.fill(), td); + else { + //instantiate a custom facet for dealing with times since the user + //has not put one in the stream so far. This is for efficiency + //since we would always need to reconstruct for every time period + //if the locale did not already exist. Of course this will be overridden + //if the user imbues as some later point. + custom_ptime_facet* f = new custom_ptime_facet(); + std::locale l = std::locale(os.getloc(), f); + os.imbue(l); + f->put(oitr, os, os.fill(), td); + } + return os; + } + + //! input operator for time_duration + template + inline + std::basic_istream& + operator>>(std::basic_istream& is, time_duration& td) + { + boost::io::ios_flags_saver iflags(is); + typename std::basic_istream::sentry strm_sentry(is, false); + if (strm_sentry) { + try { + typedef typename date_time::time_input_facet time_input_facet_local; + std::istreambuf_iterator sit(is), str_end; + if(std::has_facet(is.getloc())) { + std::use_facet(is.getloc()).get(sit, str_end, is, td); + } + else { + time_input_facet_local* f = new time_input_facet_local(); + std::locale l = std::locale(is.getloc(), f); + is.imbue(l); + f->get(sit, str_end, is, td); + } + } + catch(...) { + std::ios_base::iostate exception_mask = is.exceptions(); + if(std::ios_base::failbit & exception_mask) { + try { is.setstate(std::ios_base::failbit); } + catch(std::ios_base::failure&) {} + throw; // rethrow original exception + } + else { + is.setstate(std::ios_base::failbit); + } + } + } + return is; + } + +} } // namespaces +#endif // DATE_TIME_POSIX_TIME_IO_HPP__ diff --git a/src/vendor/boost/date_time/posix_time/posix_time_system.hpp b/src/vendor/boost/date_time/posix_time/posix_time_system.hpp new file mode 100644 index 000000000..84c21ca00 --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/posix_time_system.hpp @@ -0,0 +1,68 @@ +#ifndef POSIX_TIME_SYSTEM_HPP___ +#define POSIX_TIME_SYSTEM_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + + +#include "boost/date_time/posix_time/posix_time_config.hpp" +#include "boost/date_time/time_system_split.hpp" +#include "boost/date_time/time_system_counted.hpp" +#include "boost/date_time/compiler_config.hpp" + + +namespace boost { +namespace posix_time { + +#ifdef BOOST_DATE_TIME_POSIX_TIME_STD_CONFIG + +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) //help bad compilers + typedef date_time::split_timedate_system posix_time_system; +#else + typedef date_time::split_timedate_system posix_time_system; +#endif + +#else + + typedef date_time::counted_time_rep int64_time_rep; + typedef date_time::counted_time_system posix_time_system; + +#endif + +} }//namespace posix_time + + +#endif + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/vendor/boost/date_time/posix_time/posix_time_types.hpp b/src/vendor/boost/date_time/posix_time/posix_time_types.hpp new file mode 100644 index 000000000..f2488f8be --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/posix_time_types.hpp @@ -0,0 +1,55 @@ +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + */ +#ifndef POSIX_TIME_TYPES_HPP___ +#define POSIX_TIME_TYPES_HPP___ + +#include "boost/date_time/time_clock.hpp" +#include "boost/date_time/microsec_time_clock.hpp" +#include "boost/date_time/posix_time/ptime.hpp" +#if defined(BOOST_DATE_TIME_OPTIONAL_GREGORIAN_TYPES) +#include "boost/date_time/posix_time/date_duration_operators.hpp" +#endif +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/posix_time_system.hpp" +#include "boost/date_time/posix_time/time_period.hpp" +#include "boost/date_time/time_iterator.hpp" +#include "boost/date_time/dst_rules.hpp" + +namespace boost { + +//!Defines a non-adjusted time system with nano-second resolution and stable calculation properties +namespace posix_time { + + //! Iterator over a defined time duration + /*! \ingroup time_basics + */ + typedef date_time::time_itr time_iterator; + //! A time clock that has a resolution of one second + /*! \ingroup time_basics + */ + typedef date_time::second_clock second_clock; + +#ifdef BOOST_DATE_TIME_HAS_HIGH_PRECISION_CLOCK + //! A time clock that has a resolution of one microsecond + /*! \ingroup time_basics + */ + typedef date_time::microsec_clock microsec_clock; +#endif + + //! Define a dst null dst rule for the posix_time system + typedef date_time::null_dst_rules no_dst; + //! Define US dst rule calculator for the posix_time system + typedef date_time::us_dst_rules us_dst; + + +} } //namespace posix_time + + + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/ptime.hpp b/src/vendor/boost/date_time/posix_time/ptime.hpp new file mode 100644 index 000000000..60661f25b --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/ptime.hpp @@ -0,0 +1,84 @@ +#ifndef POSIX_PTIME_HPP___ +#define POSIX_PTIME_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include + +namespace boost { + +namespace posix_time { + + //bring special enum values into the namespace + using date_time::special_values; + using date_time::not_special; + using date_time::neg_infin; + using date_time::pos_infin; + using date_time::not_a_date_time; + using date_time::max_date_time; + using date_time::min_date_time; + + //! Time type with no timezone or other adjustments + /*! \ingroup time_basics + */ + class BOOST_SYMBOL_VISIBLE ptime : public date_time::base_time + { + public: + typedef posix_time_system time_system_type; + typedef time_system_type::time_rep_type time_rep_type; + typedef time_system_type::time_duration_type time_duration_type; + typedef ptime time_type; + //! Construct with date and offset in day + BOOST_CXX14_CONSTEXPR + ptime(gregorian::date d,time_duration_type td) : + date_time::base_time(d,td) + {} + //! Construct a time at start of the given day (midnight) + BOOST_CXX14_CONSTEXPR + explicit ptime(gregorian::date d) : + date_time::base_time(d,time_duration_type(0,0,0)) + {} + //! Copy from time_rep + BOOST_CXX14_CONSTEXPR + ptime(const time_rep_type& rhs): + date_time::base_time(rhs) + {} + //! Construct from special value + BOOST_CXX14_CONSTEXPR + ptime(const special_values sv) : + date_time::base_time(sv) + {} +#if !defined(DATE_TIME_NO_DEFAULT_CONSTRUCTOR) + // Default constructor constructs to not_a_date_time + BOOST_CXX14_CONSTEXPR + ptime() : + date_time::base_time(gregorian::date(not_a_date_time), + time_duration_type(not_a_date_time)) + {} +#endif // DATE_TIME_NO_DEFAULT_CONSTRUCTOR + + friend BOOST_CXX14_CONSTEXPR + bool operator==(const ptime& lhs, const ptime& rhs); + + }; + + inline BOOST_CXX14_CONSTEXPR + bool operator==(const ptime& lhs, const ptime& rhs) + { + return ptime::time_system_type::is_equal(lhs.time_,rhs.time_); + } + + +} }//namespace posix_time + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/time_formatters.hpp b/src/vendor/boost/date_time/posix_time/time_formatters.hpp new file mode 100644 index 000000000..ce1956822 --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/time_formatters.hpp @@ -0,0 +1,289 @@ +#ifndef POSIXTIME_FORMATTERS_HPP___ +#define POSIXTIME_FORMATTERS_HPP___ + +/* Copyright (c) 2002-2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include // absolute_value +#include + +/* NOTE: The "to_*_string" code for older compilers, ones that define + * BOOST_DATE_TIME_INCLUDE_LIMITED_HEADERS, is located in + * formatters_limited.hpp + */ + +namespace boost { + +namespace posix_time { + + // template function called by wrapper functions: + // to_*_string(time_duration) & to_*_wstring(time_duration) + template + inline std::basic_string to_simple_string_type(time_duration td) { + std::basic_ostringstream ss; + if(td.is_special()) { + /* simply using 'ss << td.get_rep()' won't work on compilers + * that don't support locales. This way does. */ + // switch copied from date_names_put.hpp + switch(td.get_rep().as_special()) + { + case not_a_date_time: + //ss << "not-a-number"; + ss << "not-a-date-time"; + break; + case pos_infin: + ss << "+infinity"; + break; + case neg_infin: + ss << "-infinity"; + break; + default: + ss << ""; + } + } + else { + charT fill_char = '0'; + if(td.is_negative()) { + ss << '-'; + } + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.hours()) << ":"; + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.minutes()) << ":"; + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.seconds()); + //TODO the following is totally non-generic, yelling FIXME +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + boost::int64_t frac_sec = + date_time::absolute_value(td.fractional_seconds()); + // JDG [7/6/02 VC++ compatibility] + charT buff[32]; + _i64toa(frac_sec, buff, 10); +#else + time_duration::fractional_seconds_type frac_sec = + date_time::absolute_value(td.fractional_seconds()); +#endif + if (frac_sec != 0) { + ss << "." << std::setw(time_duration::num_fractional_digits()) + << std::setfill(fill_char) + + // JDG [7/6/02 VC++ compatibility] +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + << buff; +#else + << frac_sec; +#endif + } + }// else + return ss.str(); + } + //! Time duration to string -hh::mm::ss.fffffff. Example: 10:09:03.0123456 + /*!\ingroup time_format + */ + inline std::string to_simple_string(time_duration td) { + return to_simple_string_type(td); + } + + + // template function called by wrapper functions: + // to_*_string(time_duration) & to_*_wstring(time_duration) + template + inline std::basic_string to_iso_string_type(time_duration td) + { + std::basic_ostringstream ss; + if(td.is_special()) { + /* simply using 'ss << td.get_rep()' won't work on compilers + * that don't support locales. This way does. */ + // switch copied from date_names_put.hpp + switch(td.get_rep().as_special()) { + case not_a_date_time: + //ss << "not-a-number"; + ss << "not-a-date-time"; + break; + case pos_infin: + ss << "+infinity"; + break; + case neg_infin: + ss << "-infinity"; + break; + default: + ss << ""; + } + } + else { + charT fill_char = '0'; + if(td.is_negative()) { + ss << '-'; + } + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.hours()); + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.minutes()); + ss << std::setw(2) << std::setfill(fill_char) + << date_time::absolute_value(td.seconds()); + //TODO the following is totally non-generic, yelling FIXME +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + boost::int64_t frac_sec = + date_time::absolute_value(td.fractional_seconds()); + // JDG [7/6/02 VC++ compatibility] + charT buff[32]; + _i64toa(frac_sec, buff, 10); +#else + time_duration::fractional_seconds_type frac_sec = + date_time::absolute_value(td.fractional_seconds()); +#endif + if (frac_sec != 0) { + ss << "." << std::setw(time_duration::num_fractional_digits()) + << std::setfill(fill_char) + + // JDG [7/6/02 VC++ compatibility] +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + << buff; +#else + << frac_sec; +#endif + } + }// else + return ss.str(); + } + //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456 + /*!\ingroup time_format + */ + inline std::string to_iso_string(time_duration td){ + return to_iso_string_type(td); + } + + //! Time to simple format CCYY-mmm-dd hh:mm:ss.fffffff + /*!\ingroup time_format + */ + template + inline std::basic_string to_simple_string_type(ptime t) + { + // can't use this w/gcc295, no to_simple_string_type<>(td) available + std::basic_string ts = gregorian::to_simple_string_type(t.date());// + " "; + if(!t.time_of_day().is_special()) { + charT space = ' '; + return ts + space + to_simple_string_type(t.time_of_day()); + } + else { + return ts; + } + } + inline std::string to_simple_string(ptime t){ + return to_simple_string_type(t); + } + + // function called by wrapper functions to_*_string(time_period) + // & to_*_wstring(time_period) + template + inline std::basic_string to_simple_string_type(time_period tp) + { + charT beg = '[', mid = '/', end = ']'; + std::basic_string d1(to_simple_string_type(tp.begin())); + std::basic_string d2(to_simple_string_type(tp.last())); + return std::basic_string(beg + d1 + mid + d2 + end); + } + //! Convert to string of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff] + /*!\ingroup time_format + */ + inline std::string to_simple_string(time_period tp){ + return to_simple_string_type(tp); + } + + // function called by wrapper functions to_*_string(time_period) + // & to_*_wstring(time_period) + template + inline std::basic_string to_iso_string_type(ptime t) + { + std::basic_string ts = gregorian::to_iso_string_type(t.date());// + "T"; + if(!t.time_of_day().is_special()) { + charT sep = 'T'; + return ts + sep + to_iso_string_type(t.time_of_day()); + } + else { + return ts; + } + } + //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::string to_iso_string(ptime t){ + return to_iso_string_type(t); + } + + + // function called by wrapper functions to_*_string(time_period) + // & to_*_wstring(time_period) + template + inline std::basic_string to_iso_extended_string_type(ptime t) + { + std::basic_string ts = gregorian::to_iso_extended_string_type(t.date());// + "T"; + if(!t.time_of_day().is_special()) { + charT sep = 'T'; + return ts + sep + to_simple_string_type(t.time_of_day()); + } + else { + return ts; + } + } + //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::string to_iso_extended_string(ptime t){ + return to_iso_extended_string_type(t); + } + +#if !defined(BOOST_NO_STD_WSTRING) + //! Time duration to wstring -hh::mm::ss.fffffff. Example: 10:09:03.0123456 + /*!\ingroup time_format + */ + inline std::wstring to_simple_wstring(time_duration td) { + return to_simple_string_type(td); + } + //! Time duration in iso format -hhmmss,fffffff Example: 10:09:03,0123456 + /*!\ingroup time_format + */ + inline std::wstring to_iso_wstring(time_duration td){ + return to_iso_string_type(td); + } + inline std::wstring to_simple_wstring(ptime t){ + return to_simple_string_type(t); + } + //! Convert to wstring of form [YYYY-mmm-DD HH:MM::SS.ffffff/YYYY-mmm-DD HH:MM::SS.fffffff] + /*!\ingroup time_format + */ + inline std::wstring to_simple_wstring(time_period tp){ + return to_simple_string_type(tp); + } + //! Convert iso short form YYYYMMDDTHHMMSS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::wstring to_iso_wstring(ptime t){ + return to_iso_string_type(t); + } + //! Convert to form YYYY-MM-DDTHH:MM:SS where T is the date-time separator + /*!\ingroup time_format + */ + inline std::wstring to_iso_extended_wstring(ptime t){ + return to_iso_extended_string_type(t); + } + +#endif // BOOST_NO_STD_WSTRING + + +} } //namespace posix_time + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/time_parsers.hpp b/src/vendor/boost/date_time/posix_time/time_parsers.hpp new file mode 100644 index 000000000..24f20704a --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/time_parsers.hpp @@ -0,0 +1,48 @@ +#ifndef POSIXTIME_PARSERS_HPP___ +#define POSIXTIME_PARSERS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include "boost/date_time/gregorian/gregorian.hpp" +#include "boost/date_time/time_parsing.hpp" +#include "boost/date_time/posix_time/posix_time_types.hpp" + + +namespace boost { + +namespace posix_time { + + //! Creates a time_duration object from a delimited string + /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]". + * A negative duration will be created if the first character in + * string is a '-', all other '-' will be treated as delimiters. + * Accepted delimiters are "-:,.". */ + inline time_duration duration_from_string(const std::string& s) { + return date_time::parse_delimited_time_duration(s); + } + + inline ptime time_from_string(const std::string& s) { + return date_time::parse_delimited_time(s, ' '); + } + + inline ptime from_iso_string(const std::string& s) { + return date_time::parse_iso_time(s, 'T'); + } + + inline ptime from_iso_extended_string(const std::string& s) { + return date_time::parse_delimited_time(s, 'T'); + } + + + +} } //namespace posix_time + + +#endif + diff --git a/src/vendor/boost/date_time/posix_time/time_period.hpp b/src/vendor/boost/date_time/posix_time/time_period.hpp new file mode 100644 index 000000000..7c6095b89 --- /dev/null +++ b/src/vendor/boost/date_time/posix_time/time_period.hpp @@ -0,0 +1,29 @@ +#ifndef POSIX_TIME_PERIOD_HPP___ +#define POSIX_TIME_PERIOD_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include "boost/date_time/period.hpp" +#include "boost/date_time/posix_time/posix_time_duration.hpp" +#include "boost/date_time/posix_time/ptime.hpp" + +namespace boost { +namespace posix_time { + + //! Time period type + /*! \ingroup time_basics + */ + typedef date_time::period time_period; + + +} }//namespace posix_time + + +#endif + diff --git a/src/vendor/boost/date_time/special_defs.hpp b/src/vendor/boost/date_time/special_defs.hpp new file mode 100644 index 000000000..5a757be10 --- /dev/null +++ b/src/vendor/boost/date_time/special_defs.hpp @@ -0,0 +1,25 @@ +#ifndef DATE_TIME_SPECIAL_DEFS_HPP__ +#define DATE_TIME_SPECIAL_DEFS_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +namespace boost { +namespace date_time { + + enum special_values {not_a_date_time, + neg_infin, pos_infin, + min_date_time, max_date_time, + not_special, NumSpecialValues}; + + +} } //namespace date_time + + +#endif + diff --git a/src/vendor/boost/date_time/special_values_formatter.hpp b/src/vendor/boost/date_time/special_values_formatter.hpp new file mode 100644 index 000000000..0eb3cae8e --- /dev/null +++ b/src/vendor/boost/date_time/special_values_formatter.hpp @@ -0,0 +1,97 @@ + +#ifndef DATETIME_SPECIAL_VALUE_FORMATTER_HPP___ +#define DATETIME_SPECIAL_VALUE_FORMATTER_HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include "boost/date_time/special_defs.hpp" + +namespace boost { namespace date_time { + + + //! Class that provides generic formmatting ostream formatting for special values + /*! This class provides for the formmating of special values to an output stream. + * In particular, it produces strings for the values of negative and positive + * infinity as well as not_a_date_time. + * + * While not a facet, this class is used by the date and time facets for formatting + * special value types. + * + */ + template > > + class special_values_formatter + { + public: + typedef std::basic_string string_type; + typedef CharT char_type; + typedef std::vector collection_type; + static const char_type default_special_value_names[3][17]; + + //! Construct special values formatter using default strings. + /*! Default strings are not-a-date-time -infinity +infinity + */ + special_values_formatter() + { + std::copy(&default_special_value_names[0], + &default_special_value_names[3], + std::back_inserter(m_special_value_names)); + } + + //! Construct special values formatter from array of strings + /*! This constructor will take pair of iterators from an array of strings + * that represent the special values and copy them for use in formatting + * special values. + *@code + * const char* const special_value_names[]={"nadt","-inf","+inf" }; + * + * special_value_formatter svf(&special_value_names[0], &special_value_names[3]); + *@endcode + */ + special_values_formatter(const char_type* const* begin, const char_type* const* end) + { + std::copy(begin, end, std::back_inserter(m_special_value_names)); + } + special_values_formatter(typename collection_type::iterator beg, typename collection_type::iterator end) + { + std::copy(beg, end, std::back_inserter(m_special_value_names)); + } + + OutItrT put_special(OutItrT next, + const boost::date_time::special_values& value) const + { + + unsigned int index = value; + if (index < m_special_value_names.size()) { + std::copy(m_special_value_names[index].begin(), + m_special_value_names[index].end(), + next); + } + return next; + } + protected: + collection_type m_special_value_names; + }; + + //! Storage for the strings used to indicate special values + /* using c_strings to initialize these worked fine in testing, however, + * a project that compiled its objects separately, then linked in a separate + * step wound up with redefinition errors for the values in this array. + * Initializing individual characters eliminated this problem */ + template + const typename special_values_formatter::char_type special_values_formatter::default_special_value_names[3][17] = { + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}, + {'-','i','n','f','i','n','i','t','y'}, + {'+','i','n','f','i','n','i','t','y'} }; + + } } //namespace boost::date_time + +#endif diff --git a/src/vendor/boost/date_time/special_values_parser.hpp b/src/vendor/boost/date_time/special_values_parser.hpp new file mode 100644 index 000000000..d436d924c --- /dev/null +++ b/src/vendor/boost/date_time/special_values_parser.hpp @@ -0,0 +1,163 @@ + +#ifndef DATE_TIME_SPECIAL_VALUES_PARSER_HPP__ +#define DATE_TIME_SPECIAL_VALUES_PARSER_HPP__ + +/* Copyright (c) 2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date: + */ + + +#include "boost/date_time/string_parse_tree.hpp" +#include "boost/date_time/special_defs.hpp" +#include +#include + +namespace boost { namespace date_time { + + //! Class for special_value parsing + /*! + * TODO: add doc-comments for which elements can be changed + * Parses input stream for strings representing special_values. + * Special values parsed are: + * - not_a_date_time + * - neg_infin + * - pod_infin + * - min_date_time + * - max_date_time + */ + template + class special_values_parser + { + public: + typedef std::basic_string string_type; + typedef std::basic_stringstream stringstream_type; + typedef std::istreambuf_iterator stream_itr_type; + typedef typename date_type::duration_type duration_type; + typedef string_parse_tree parse_tree_type; + typedef typename parse_tree_type::parse_match_result_type match_results; + typedef std::vector > collection_type; + + typedef charT char_type; + static const char_type nadt_string[16]; + static const char_type neg_inf_string[10]; + static const char_type pos_inf_string[10]; + static const char_type min_date_time_string[18]; + static const char_type max_date_time_string[18]; + + //! Creates a special_values_parser with the default set of "sv_strings" + special_values_parser() + { + sv_strings(string_type(nadt_string), + string_type(neg_inf_string), + string_type(pos_inf_string), + string_type(min_date_time_string), + string_type(max_date_time_string)); + } + + //! Creates a special_values_parser using a user defined set of element strings + special_values_parser(const string_type& nadt_str, + const string_type& neg_inf_str, + const string_type& pos_inf_str, + const string_type& min_dt_str, + const string_type& max_dt_str) + { + sv_strings(nadt_str, neg_inf_str, pos_inf_str, min_dt_str, max_dt_str); + } + + special_values_parser(typename collection_type::iterator beg, typename collection_type::iterator end) + { + collection_type phrases; + std::copy(beg, end, std::back_inserter(phrases)); + m_sv_strings = parse_tree_type(phrases, static_cast(not_a_date_time)); + } + + //! Replace special value strings + void sv_strings(const string_type& nadt_str, + const string_type& neg_inf_str, + const string_type& pos_inf_str, + const string_type& min_dt_str, + const string_type& max_dt_str) + { + collection_type phrases; + phrases.push_back(nadt_str); + phrases.push_back(neg_inf_str); + phrases.push_back(pos_inf_str); + phrases.push_back(min_dt_str); + phrases.push_back(max_dt_str); + m_sv_strings = parse_tree_type(phrases, static_cast(not_a_date_time)); + } + + //! The parser is expensive to create, and not thread-safe so it cannot be static + //! therefore given a string, determine if it is likely to be a special value. + //! A negative response is a definite no, whereas a positive is only likely and + //! match() should be called and return value checked. + //! \param[in] str the string to check + //! \returns false if it is definitely not a special value + static bool likely(const string_type& str) + { + if (!str.empty()) { + switch (str[0]) { + // See string definitions at the end of this class.. + case '+': + case '-': + case 'n': + case 'm': + return true; + + default: + break; + } + } + + return false; + } + + //! Given an input iterator, attempt to match it to a known special value + //! \param[in] sitr the start iterator + //! \param[in] str_end the end iterator + //! \param[out] mr the match result: + //! mr.current_match is set to the corresponding special_value or -1 + //! \returns whether something matched + bool match(stream_itr_type& sitr, + stream_itr_type& str_end, + match_results& mr) const + { + unsigned int level = 0; + m_sv_strings.match(sitr, str_end, mr, level); + return (mr.current_match != match_results::PARSE_ERROR); + } + + private: + parse_tree_type m_sv_strings; + + }; + + template + const typename special_values_parser::char_type + special_values_parser::nadt_string[16] = + {'n','o','t','-','a','-','d','a','t','e','-','t','i','m','e'}; + template + const typename special_values_parser::char_type + special_values_parser::neg_inf_string[10] = + {'-','i','n','f','i','n','i','t','y'}; + template + const typename special_values_parser::char_type + special_values_parser::pos_inf_string[10] = + {'+','i','n','f','i','n','i','t','y'}; + template + const typename special_values_parser::char_type + special_values_parser::min_date_time_string[18] = + {'m','i','n','i','m','u','m','-','d','a','t','e','-','t','i','m','e'}; + template + const typename special_values_parser::char_type + special_values_parser::max_date_time_string[18] = + {'m','a','x','i','m','u','m','-','d','a','t','e','-','t','i','m','e'}; + +} } //namespace + +#endif // DATE_TIME_SPECIAL_VALUES_PARSER_HPP__ + diff --git a/src/vendor/boost/date_time/string_convert.hpp b/src/vendor/boost/date_time/string_convert.hpp new file mode 100644 index 000000000..30be3567a --- /dev/null +++ b/src/vendor/boost/date_time/string_convert.hpp @@ -0,0 +1,32 @@ +#ifndef _STRING_CONVERT_HPP___ +#define _STRING_CONVERT_HPP___ + +/* Copyright (c) 2005 CrystalClear Software, Inc. + * Subject to the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/date_time/compiler_config.hpp" +#include + +namespace boost { +namespace date_time { + + //! Converts a string from one value_type to another + /*! Converts a wstring to a string (or a string to wstring). If both template parameters + * are of same type, a copy of the input string is returned. */ + template + inline + std::basic_string convert_string_type(const std::basic_string& inp_str) + { + typedef std::basic_string output_type; + output_type result; + result.insert(result.begin(), inp_str.begin(), inp_str.end()); + return result; + } + +}} // namespace boost::date_time + +#endif // _STRING_CONVERT_HPP___ diff --git a/src/vendor/boost/date_time/string_parse_tree.hpp b/src/vendor/boost/date_time/string_parse_tree.hpp new file mode 100644 index 000000000..ecac86312 --- /dev/null +++ b/src/vendor/boost/date_time/string_parse_tree.hpp @@ -0,0 +1,281 @@ +#ifndef BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__ +#define BOOST_DATE_TIME_STRING_PARSE_TREE___HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace date_time { + + +template +struct parse_match_result +{ + parse_match_result() : + match_depth(0), + current_match(PARSE_ERROR) + {} + typedef std::basic_string string_type; + string_type remaining() const + { + if (match_depth == cache.size()) { + return string_type(); + } + if (current_match == PARSE_ERROR) { + return cache; + } + //some of the cache was used return the rest + return string_type(cache, match_depth); + } + charT last_char() const + { + return cache[cache.size()-1]; + } + //! Returns true if more characters were parsed than was necessary + /*! Should be used in conjunction with last_char() + * to get the remaining character. + */ + bool has_remaining() const + { + return (cache.size() > match_depth); + } + + // cache will hold characters that have been read from the stream + string_type cache; + unsigned short match_depth; + short current_match; + enum PARSE_STATE { PARSE_ERROR = -1 }; +}; + + //for debug -- really only char streams... +template +std::basic_ostream& +operator<<(std::basic_ostream& os, parse_match_result& mr) +{ + os << "cm: " << mr.current_match + << " C: '" << mr.cache + << "' md: " << mr.match_depth + << " R: " << mr.remaining(); + return os; +} + + + +//! Recursive data structure to allow efficient parsing of various strings +/*! This class provides a quick lookup by building what amounts to a + * tree data structure. It also features a match function which can + * can handle nasty input interators by caching values as it recurses + * the tree so that it can backtrack as needed. + */ +template +struct string_parse_tree +{ +#if BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0x581) ) + typedef std::multimap > ptree_coll; +#else + typedef std::multimap ptree_coll; +#endif + typedef typename ptree_coll::value_type value_type; + typedef typename ptree_coll::iterator iterator; + typedef typename ptree_coll::const_iterator const_iterator; + typedef std::basic_string string_type; + typedef std::vector > collection_type; + typedef parse_match_result parse_match_result_type; + + /*! Parameter "starting_point" designates where the numbering begins. + * A starting_point of zero will start the numbering at zero + * (Sun=0, Mon=1, ...) were a starting_point of one starts the + * numbering at one (Jan=1, Feb=2, ...). The default is zero, + * negative vaules are not allowed */ + string_parse_tree(collection_type names, unsigned int starting_point=0) : + m_value(parse_match_result_type::PARSE_ERROR) + { + // iterate thru all the elements and build the tree + unsigned short index = 0; + while (index != names.size() ) { + string_type s = boost::algorithm::to_lower_copy(names[index]); + insert(s, static_cast(index + starting_point)); + index++; + } + //set the last tree node = index+1 indicating a value + index++; + } + + + string_parse_tree(short value = parse_match_result_type::PARSE_ERROR) : + m_value(value) + {} + ptree_coll m_next_chars; + short m_value; + + void insert(const string_type& s, unsigned short value) + { + unsigned int i = 0; + iterator ti; + while(i < s.size()) { + if (i==0) { + if (i == (s.size()-1)) { + ti = m_next_chars.insert(value_type(s[i], + string_parse_tree(value))); + } + else { + ti = m_next_chars.insert(value_type(s[i], + string_parse_tree())); + } + } + else { + if (i == (s.size()-1)) { + ti = ti->second.m_next_chars.insert(value_type(s[i], + string_parse_tree(value))); + } + + else { + ti = ti->second.m_next_chars.insert(value_type(s[i], + string_parse_tree())); + } + + } + i++; + } + } + + + //! Recursive function that finds a matching string in the tree. + /*! Must check match_results::has_remaining() after match() is + * called. This is required so the user can determine if + * stream iterator is already pointing to the expected + * character or not (match() might advance sitr to next char in stream). + * + * A parse_match_result that has been returned from a failed match + * attempt can be sent in to the match function of a different + * string_parse_tree to attempt a match there. Use the iterators + * for the partially consumed stream, the parse_match_result object, + * and '0' for the level parameter. */ + short + match(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end, + parse_match_result_type& result, + unsigned int& level) const + { + + level++; + charT c; + // if we conditionally advance sitr, we won't have + // to consume the next character past the input + bool adv_itr = true; + if (level > result.cache.size()) { + if (sitr == stream_end) return 0; //bail - input exhausted + c = static_cast(std::tolower(*sitr)); + //result.cache += c; + //sitr++; + } + else { + // if we're looking for characters from the cache, + // we don't want to increment sitr + adv_itr = false; + c = static_cast(std::tolower(result.cache[level-1])); + } + const_iterator litr = m_next_chars.lower_bound(c); + const_iterator uitr = m_next_chars.upper_bound(c); + while (litr != uitr) { // equal if not found + if(adv_itr) { + sitr++; + result.cache += c; + } + if (litr->second.m_value != -1) { // -1 is default value + if (result.match_depth < level) { + result.current_match = litr->second.m_value; + result.match_depth = static_cast(level); + } + litr->second.match(sitr, stream_end, + result, level); + level--; + } + else { + litr->second.match(sitr, stream_end, + result, level); + level--; + } + + if(level <= result.cache.size()) { + adv_itr = false; + } + + litr++; + } + return result.current_match; + + } + + /*! Must check match_results::has_remaining() after match() is + * called. This is required so the user can determine if + * stream iterator is already pointing to the expected + * character or not (match() might advance sitr to next char in stream). + */ + parse_match_result_type + match(std::istreambuf_iterator& sitr, + std::istreambuf_iterator& stream_end) const + { + // lookup to_lower of char in tree. + unsigned int level = 0; + // string_type cache; + parse_match_result_type result; + match(sitr, stream_end, result, level); + return result; + } + + void printme(std::ostream& os, int& level) + { + level++; + iterator itr = m_next_chars.begin(); + iterator end = m_next_chars.end(); + // os << "starting level: " << level << std::endl; + while (itr != end) { + os << "level: " << level + << " node: " << itr->first + << " value: " << itr->second.m_value + << std::endl; + itr->second.printme(os, level); + itr++; + } + level--; + } + + void print(std::ostream& os) + { + int level = 0; + printme(os, level); + } + + void printmatch(std::ostream& os, charT c) + { + iterator litr = m_next_chars.lower_bound(c); + iterator uitr = m_next_chars.upper_bound(c); + os << "matches for: " << c << std::endl; + while (litr != uitr) { + os << " node: " << litr->first + << " value: " << litr->second.m_value + << std::endl; + litr++; + } + } + +}; + + +} } //namespace +#endif diff --git a/src/vendor/boost/date_time/strings_from_facet.hpp b/src/vendor/boost/date_time/strings_from_facet.hpp new file mode 100644 index 000000000..cecd32faa --- /dev/null +++ b/src/vendor/boost/date_time/strings_from_facet.hpp @@ -0,0 +1,127 @@ +#ifndef DATE_TIME_STRINGS_FROM_FACET__HPP___ +#define DATE_TIME_STRINGS_FROM_FACET__HPP___ + +/* Copyright (c) 2004 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace date_time { + +//! This function gathers up all the month strings from a std::locale +/*! Using the time_put facet, this function creates a collection of + * all the month strings from a locale. This is handy when building + * custom date parsers or formatters that need to be localized. + * + *@param charT The type of char to use when gathering typically char + * or wchar_t. + *@param locale The locale to use when gathering the strings + *@param short_strings True(default) to gather short strings, + * false for long strings. + *@return A vector of strings containing the strings in order. eg: + * Jan, Feb, Mar, etc. + */ +template +std::vector > +gather_month_strings(const std::locale& locale, bool short_strings=true) +{ + typedef std::basic_string string_type; + typedef std::vector collection_type; + typedef std::ostreambuf_iterator ostream_iter_type; + typedef std::basic_ostringstream stringstream_type; + typedef std::time_put time_put_facet_type; + charT short_fmt[3] = { '%', 'b' }; + charT long_fmt[3] = { '%', 'B' }; + collection_type months; + string_type outfmt(short_fmt); + if (!short_strings) { + outfmt = long_fmt; + } + { + //grab the needed strings by using the locale to + //output each month + const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size(); + tm tm_value; + std::memset(&tm_value, 0, sizeof(tm_value)); + for (int m=0; m < 12; m++) { + tm_value.tm_mon = m; + stringstream_type ss; + ostream_iter_type oitr(ss); + std::use_facet(locale).put(oitr, ss, ss.fill(), + &tm_value, + p_outfmt, + p_outfmt_end); + months.push_back(ss.str()); + } + } + return months; +} + +//! This function gathers up all the weekday strings from a std::locale +/*! Using the time_put facet, this function creates a collection of + * all the weekday strings from a locale starting with the string for + * 'Sunday'. This is handy when building custom date parsers or + * formatters that need to be localized. + * + *@param charT The type of char to use when gathering typically char + * or wchar_t. + *@param locale The locale to use when gathering the strings + *@param short_strings True(default) to gather short strings, + * false for long strings. + *@return A vector of strings containing the weekdays in order. eg: + * Sun, Mon, Tue, Wed, Thu, Fri, Sat + */ +template +std::vector > +gather_weekday_strings(const std::locale& locale, bool short_strings=true) +{ + typedef std::basic_string string_type; + typedef std::vector collection_type; + typedef std::ostreambuf_iterator ostream_iter_type; + typedef std::basic_ostringstream stringstream_type; + typedef std::time_put time_put_facet_type; + charT short_fmt[3] = { '%', 'a' }; + charT long_fmt[3] = { '%', 'A' }; + + collection_type weekdays; + + + string_type outfmt(short_fmt); + if (!short_strings) { + outfmt = long_fmt; + } + { + //grab the needed strings by using the locale to + //output each month / weekday + const charT* p_outfmt = outfmt.c_str(), *p_outfmt_end = p_outfmt + outfmt.size(); + tm tm_value; + std::memset(&tm_value, 0, sizeof(tm_value)); + for (int i=0; i < 7; i++) { + tm_value.tm_wday = i; + stringstream_type ss; + ostream_iter_type oitr(ss); + std::use_facet(locale).put(oitr, ss, ss.fill(), + &tm_value, + p_outfmt, + p_outfmt_end); + + weekdays.push_back(ss.str()); + } + } + return weekdays; +} + +} } //namespace + + +#endif diff --git a/src/vendor/boost/date_time/time.hpp b/src/vendor/boost/date_time/time.hpp new file mode 100644 index 000000000..1705b9e7d --- /dev/null +++ b/src/vendor/boost/date_time/time.hpp @@ -0,0 +1,214 @@ +#ifndef DATE_TIME_TIME_HPP___ +#define DATE_TIME_TIME_HPP___ + +/* Copyright (c) 2002,2003,2005,2020 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +/*! @file time.hpp + This file contains the interface for the time associated classes. +*/ +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! Representation of a precise moment in time, including the date. + /*! + This class is a skeleton for the interface of a temporal type + with a resolution that is higher than a day. It is intended that + this class be the base class and that the actual time + class be derived using the BN pattern. In this way, the derived + class can make decisions such as 'should there be a default constructor' + and what should it set its value to, should there be optional constructors + say allowing only an time_durations that generate a time from a clock,etc. + So, in fact multiple time types can be created for a time_system with + different construction policies, and all of them can perform basic + operations by only writing a copy constructor. Finally, compiler + errors are also shorter. + + The real behavior of the time class is provided by the time_system + template parameter. This class must provide all the logic + for addition, subtraction, as well as define all the interface + types. + + */ + + template + class base_time : private + boost::less_than_comparable > + { + public: + // A tag for type categorization. Can be used to detect Boost.DateTime time points in generic code. + typedef void _is_boost_date_time_time_point; + typedef T time_type; + typedef typename time_system::time_rep_type time_rep_type; + typedef typename time_system::date_type date_type; + typedef typename time_system::date_duration_type date_duration_type; + typedef typename time_system::time_duration_type time_duration_type; + //typedef typename time_system::hms_type hms_type; + + BOOST_CXX14_CONSTEXPR + base_time(const date_type& day, + const time_duration_type& td, + dst_flags dst=not_dst) : + time_(time_system::get_time_rep(day, td, dst)) + {} + BOOST_CXX14_CONSTEXPR + base_time(special_values sv) : + time_(time_system::get_time_rep(sv)) + {} + BOOST_CXX14_CONSTEXPR + base_time(const time_rep_type& rhs) : + time_(rhs) + {} + BOOST_CXX14_CONSTEXPR + date_type date() const + { + return time_system::get_date(time_); + } + BOOST_CXX14_CONSTEXPR + time_duration_type time_of_day() const + { + return time_system::get_time_of_day(time_); + } + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00"). Empty string is returned for classes that do + * not use a time_zone */ + std::string zone_name(bool /*as_offset*/=false) const + { + return time_system::zone_name(time_); + } + /*! Optional bool parameter will return time zone as an offset + * (ie "+07:00"). Empty string is returned for classes that do + * not use a time_zone */ + std::string zone_abbrev(bool /*as_offset*/=false) const + { + return time_system::zone_name(time_); + } + //! An empty string is returned for classes that do not use a time_zone + std::string zone_as_posix_string() const + { + return std::string(); + } + + //! check to see if date is not a value + BOOST_CXX14_CONSTEXPR + bool is_not_a_date_time() const + { + return time_.is_not_a_date_time(); + } + //! check to see if date is one of the infinity values + BOOST_CXX14_CONSTEXPR + bool is_infinity() const + { + return (is_pos_infinity() || is_neg_infinity()); + } + //! check to see if date is greater than all possible dates + BOOST_CXX14_CONSTEXPR + bool is_pos_infinity() const + { + return time_.is_pos_infinity(); + } + //! check to see if date is greater than all possible dates + BOOST_CXX14_CONSTEXPR + bool is_neg_infinity() const + { + return time_.is_neg_infinity(); + } + //! check to see if time is a special value + BOOST_CXX14_CONSTEXPR + bool is_special() const + { + return(is_not_a_date_time() || is_infinity()); + } + //!Equality operator -- others generated by boost::equality_comparable + BOOST_CXX14_CONSTEXPR + bool operator==(const time_type& rhs) const + { + return time_system::is_equal(time_,rhs.time_); + } + //!Equality operator -- others generated by boost::less_than_comparable + BOOST_CXX14_CONSTEXPR + bool operator<(const time_type& rhs) const + { + return time_system::is_less(time_,rhs.time_); + } + //! difference between two times + BOOST_CXX14_CONSTEXPR + time_duration_type operator-(const time_type& rhs) const + { + return time_system::subtract_times(time_, rhs.time_); + } + //! add date durations + BOOST_CXX14_CONSTEXPR + time_type operator+(const date_duration_type& dd) const + { + return time_system::add_days(time_, dd); + } + BOOST_CXX14_CONSTEXPR + time_type operator+=(const date_duration_type& dd) + { + time_ = (time_system::get_time_rep(date() + dd, time_of_day())); + return time_type(time_); + } + //! subtract date durations + BOOST_CXX14_CONSTEXPR + time_type operator-(const date_duration_type& dd) const + { + return time_system::subtract_days(time_, dd); + } + BOOST_CXX14_CONSTEXPR + time_type operator-=(const date_duration_type& dd) + { + time_ = (time_system::get_time_rep(date() - dd, time_of_day())); + return time_type(time_); + } + //! add time durations + BOOST_CXX14_CONSTEXPR + time_type operator+(const time_duration_type& td) const + { + return time_type(time_system::add_time_duration(time_, td)); + } + BOOST_CXX14_CONSTEXPR + time_type operator+=(const time_duration_type& td) + { + time_ = time_system::add_time_duration(time_,td); + return time_type(time_); + } + //! subtract time durations + BOOST_CXX14_CONSTEXPR + time_type operator-(const time_duration_type& rhs) const + { + return time_system::subtract_time_duration(time_, rhs); + } + BOOST_CXX14_CONSTEXPR + time_type operator-=(const time_duration_type& td) + { + time_ = time_system::subtract_time_duration(time_, td); + return time_type(time_); + } + + protected: + time_rep_type time_; + }; + + + + + +} } //namespace date_time::boost + + +#endif + diff --git a/src/vendor/boost/date_time/time_clock.hpp b/src/vendor/boost/date_time/time_clock.hpp new file mode 100644 index 000000000..a64a5b81b --- /dev/null +++ b/src/vendor/boost/date_time/time_clock.hpp @@ -0,0 +1,83 @@ +#ifndef DATE_TIME_TIME_CLOCK_HPP___ +#define DATE_TIME_TIME_CLOCK_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +/*! @file time_clock.hpp + This file contains the interface for clock devices. +*/ + +#include "boost/date_time/c_time.hpp" +#include "boost/shared_ptr.hpp" + +namespace boost { +namespace date_time { + + + //! A clock providing time level services based on C time_t capabilities + /*! This clock provides resolution to the 1 second level + */ + template + class second_clock + { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + + static time_type local_time() + { + ::std::time_t t; + ::std::time(&t); + ::std::tm curr, *curr_ptr; + //curr_ptr = ::std::localtime(&t); + curr_ptr = c_time::localtime(&t, &curr); + return create_time(curr_ptr); + } + + + //! Get the current day in universal date as a ymd_type + static time_type universal_time() + { + + ::std::time_t t; + ::std::time(&t); + ::std::tm curr, *curr_ptr; + //curr_ptr = ::std::gmtime(&t); + curr_ptr = c_time::gmtime(&t, &curr); + return create_time(curr_ptr); + } + + template + static time_type local_time(boost::shared_ptr tz_ptr) + { + typedef typename time_type::utc_time_type utc_time_type; + utc_time_type utc_time = second_clock::universal_time(); + return time_type(utc_time, tz_ptr); + } + + + private: + static time_type create_time(::std::tm* current) + { + date_type d(static_cast(current->tm_year + 1900), + static_cast(current->tm_mon + 1), + static_cast(current->tm_mday)); + time_duration_type td(current->tm_hour, + current->tm_min, + current->tm_sec); + return time_type(d,td); + } + + }; + + +} } //namespace date_time + + +#endif diff --git a/src/vendor/boost/date_time/time_defs.hpp b/src/vendor/boost/date_time/time_defs.hpp new file mode 100644 index 000000000..852207e68 --- /dev/null +++ b/src/vendor/boost/date_time/time_defs.hpp @@ -0,0 +1,43 @@ +#ifndef DATE_TIME_TIME_PRECISION_LIMITS_HPP +#define DATE_TIME_TIME_PRECISION_LIMITS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + + + +/*! \file time_defs.hpp + This file contains nice definitions for handling the resoluion of various time + reprsentations. +*/ + +namespace boost { +namespace date_time { + + //!Defines some nice types for handling time level resolutions + enum time_resolutions { + sec, + tenth, + hundreth, // deprecated misspelled version of hundredth + hundredth = hundreth, + milli, + ten_thousandth, + micro, + nano, + NumResolutions + }; + + //! Flags for daylight savings or summer time + enum dst_flags {not_dst, is_dst, calculate}; + + +} } //namespace date_time + + + +#endif diff --git a/src/vendor/boost/date_time/time_duration.hpp b/src/vendor/boost/date_time/time_duration.hpp new file mode 100644 index 000000000..0696eede3 --- /dev/null +++ b/src/vendor/boost/date_time/time_duration.hpp @@ -0,0 +1,310 @@ +#ifndef DATE_TIME_TIME_DURATION_HPP___ +#define DATE_TIME_TIME_DURATION_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Represents some amount of elapsed time measure to a given resolution + /*! This class represents a standard set of capabilities for all + counted time durations. Time duration implementations should derive + from this class passing their type as the first template parameter. + This design allows the subclass duration types to provide custom + construction policies or other custom features not provided here. + + @tparam T The subclass type + @tparam rep_type The time resolution traits for this duration type. + */ + template + class BOOST_SYMBOL_VISIBLE time_duration : private + boost::less_than_comparable > + /* dividable, addable, and subtractable operator templates + * won't work with this class (MSVC++ 6.0). return type + * from '+=' is different than expected return type + * from '+'. multipliable probably wont work + * either (haven't tried) */ + { + public: + // A tag for type categorization. Can be used to detect Boost.DateTime duration types in generic code. + typedef void _is_boost_date_time_duration; + typedef T duration_type; //the subclass + typedef rep_type traits_type; + typedef typename rep_type::day_type day_type; + typedef typename rep_type::hour_type hour_type; + typedef typename rep_type::min_type min_type; + typedef typename rep_type::sec_type sec_type; + typedef typename rep_type::fractional_seconds_type fractional_seconds_type; + typedef typename rep_type::tick_type tick_type; + typedef typename rep_type::impl_type impl_type; + + BOOST_CXX14_CONSTEXPR time_duration() : ticks_(0) {} + BOOST_CXX14_CONSTEXPR time_duration(hour_type hours_in, + min_type minutes_in, + sec_type seconds_in=0, + fractional_seconds_type frac_sec_in = 0) : + ticks_(rep_type::to_tick_count(hours_in,minutes_in,seconds_in,frac_sec_in)) + {} + //! Construct from special_values + BOOST_CXX14_CONSTEXPR time_duration(special_values sv) : ticks_(impl_type::from_special(sv)) + {} + //! Returns smallest representable duration + static BOOST_CXX14_CONSTEXPR duration_type unit() + { + return duration_type(0,0,0,1); + } + //! Return the number of ticks in a second + static BOOST_CXX14_CONSTEXPR tick_type ticks_per_second() + { + return rep_type::res_adjust(); + } + //! Provide the resolution of this duration type + static BOOST_CXX14_CONSTEXPR time_resolutions resolution() + { + return rep_type::resolution(); + } + //! Returns number of hours in the duration + BOOST_CXX14_CONSTEXPR hour_type hours() const + { + return static_cast(ticks() / (3600*ticks_per_second())); + } + //! Returns normalized number of minutes + BOOST_CXX14_CONSTEXPR min_type minutes() const + { + return static_cast((ticks() / (60*ticks_per_second())) % 60); + } + //! Returns normalized number of seconds (0..60) + BOOST_CXX14_CONSTEXPR sec_type seconds() const + { + return static_cast((ticks()/ticks_per_second()) % 60); + } + //! Returns total number of seconds truncating any fractional seconds + BOOST_CXX14_CONSTEXPR sec_type total_seconds() const + { + return static_cast(ticks() / ticks_per_second()); + } + //! Returns total number of milliseconds truncating any fractional seconds + BOOST_CXX14_CONSTEXPR tick_type total_milliseconds() const + { + if (ticks_per_second() < 1000) { + return ticks() * (static_cast(1000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000)) ; + } + //! Returns total number of nanoseconds truncating any sub millisecond values + BOOST_CXX14_CONSTEXPR tick_type total_nanoseconds() const + { + if (ticks_per_second() < 1000000000) { + return ticks() * (static_cast(1000000000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000000000)) ; + } + //! Returns total number of microseconds truncating any sub microsecond values + BOOST_CXX14_CONSTEXPR tick_type total_microseconds() const + { + if (ticks_per_second() < 1000000) { + return ticks() * (static_cast(1000000) / ticks_per_second()); + } + return ticks() / (ticks_per_second() / static_cast(1000000)) ; + } + //! Returns count of fractional seconds at given resolution + BOOST_CXX14_CONSTEXPR fractional_seconds_type fractional_seconds() const + { + return (ticks() % ticks_per_second()); + } + //! Returns number of possible digits in fractional seconds + static BOOST_CXX14_CONSTEXPR unsigned short num_fractional_digits() + { + return rep_type::num_fractional_digits(); + } + BOOST_CXX14_CONSTEXPR duration_type invert_sign() const + { + return duration_type(ticks_ * (-1)); + } + BOOST_CXX14_CONSTEXPR duration_type abs() const + { + if ( is_negative() ) + { + return invert_sign(); + } + return duration_type(ticks_); + } + BOOST_CONSTEXPR bool is_negative() const + { + return ticks_ < 0; + } + BOOST_CONSTEXPR bool is_zero() const + { + return ticks_ == 0; + } + BOOST_CONSTEXPR bool is_positive() const + { + return ticks_ > 0; + } + BOOST_CONSTEXPR bool operator<(const time_duration& rhs) const + { + return ticks_ < rhs.ticks_; + } + BOOST_CONSTEXPR bool operator==(const time_duration& rhs) const + { + return ticks_ == rhs.ticks_; + } + //! unary- Allows for time_duration td = -td1 + BOOST_CONSTEXPR duration_type operator-()const + { + return duration_type(ticks_ * (-1)); + } + BOOST_CONSTEXPR duration_type operator-(const duration_type& d) const + { + return duration_type(ticks_ - d.ticks_); + } + BOOST_CONSTEXPR duration_type operator+(const duration_type& d) const + { + return duration_type(ticks_ + d.ticks_); + } + BOOST_CONSTEXPR duration_type operator/(int divisor) const + { + return duration_type(ticks_ / divisor); + } + BOOST_CXX14_CONSTEXPR duration_type operator-=(const duration_type& d) + { + ticks_ = ticks_ - d.ticks_; + return duration_type(ticks_); + } + BOOST_CXX14_CONSTEXPR duration_type operator+=(const duration_type& d) + { + ticks_ = ticks_ + d.ticks_; + return duration_type(ticks_); + } + //! Division operations on a duration with an integer. + BOOST_CXX14_CONSTEXPR duration_type operator/=(int divisor) + { + ticks_ = ticks_ / divisor; + return duration_type(ticks_); + } + //! Multiplication operations an a duration with an integer + BOOST_CXX14_CONSTEXPR duration_type operator*(int rhs) const + { + return duration_type(ticks_ * rhs); + } + BOOST_CXX14_CONSTEXPR duration_type operator*=(int divisor) + { + ticks_ = ticks_ * divisor; + return duration_type(ticks_); + } + BOOST_CXX14_CONSTEXPR tick_type ticks() const + { + return traits_type::as_number(ticks_); + } + + //! Is ticks_ a special value? + BOOST_CXX14_CONSTEXPR bool is_special()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_special(); + } + else{ + return false; + } + } + //! Is duration pos-infinity + BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_pos_infinity(); + } + else{ + return false; + } + } + //! Is duration neg-infinity + BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_neg_infinity(); + } + else{ + return false; + } + } + //! Is duration not-a-date-time + BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const + { + if(traits_type::is_adapted()) + { + return ticks_.is_nan(); + } + else{ + return false; + } + } + + //! Used for special_values output + BOOST_CONSTEXPR impl_type get_rep()const + { + return ticks_; + } + + protected: + BOOST_CXX14_CONSTEXPR explicit time_duration(impl_type in) : ticks_(in) {} + impl_type ticks_; + }; + + + + //! Template for instantiating derived adjusting durations + /* These templates are designed to work with multiples of + * 10 for frac_of_second and resolution adjustment + */ + template + class BOOST_SYMBOL_VISIBLE subsecond_duration : public base_duration + { + public: + typedef typename base_duration::impl_type impl_type; + typedef typename base_duration::traits_type traits_type; + + private: + // To avoid integer overflow we precompute the duration resolution conversion coefficient (ticket #3471) + BOOST_STATIC_ASSERT_MSG((traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second % frac_of_second : frac_of_second % traits_type::ticks_per_second) == 0,\ + "The base duration resolution must be a multiple of the subsecond duration resolution"); + BOOST_STATIC_CONSTANT(boost::int64_t, adjustment_ratio = (traits_type::ticks_per_second >= frac_of_second ? traits_type::ticks_per_second / frac_of_second : frac_of_second / traits_type::ticks_per_second)); + + public: + // The argument (ss) must be an integral type + template + BOOST_CXX14_CONSTEXPR explicit subsecond_duration(T const& ss, + typename boost::enable_if, + void>::type* = BOOST_DATE_TIME_NULLPTR) : + base_duration(impl_type(traits_type::ticks_per_second >= frac_of_second ? ss * adjustment_ratio : ss / adjustment_ratio)) + { + } + }; + +} } //namespace date_time + + + + +#endif + diff --git a/src/vendor/boost/date_time/time_facet.hpp b/src/vendor/boost/date_time/time_facet.hpp new file mode 100644 index 000000000..eaa365913 --- /dev/null +++ b/src/vendor/boost/date_time/time_facet.hpp @@ -0,0 +1,1370 @@ + +#ifndef _DATE_TIME_FACET__HPP__ +#define _DATE_TIME_FACET__HPP__ + +/* Copyright (c) 2004-2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Martin Andrian, Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include // i/ostreambuf_iterator +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // absolute_value + +namespace boost { +namespace date_time { + + template + struct time_formats { + public: + typedef CharT char_type; + static const char_type fractional_seconds_format[3]; // f + static const char_type fractional_seconds_or_none_format[3]; // F + static const char_type seconds_with_fractional_seconds_format[3]; // s + static const char_type seconds_format[3]; // S + static const char_type hours_format[3]; // H + static const char_type unrestricted_hours_format[3]; // O + static const char_type full_24_hour_time_format[3]; // T + static const char_type full_24_hour_time_expanded_format[9]; // HH:MM:SS + static const char_type short_24_hour_time_format[3]; // R + static const char_type short_24_hour_time_expanded_format[6]; // HH:MM + static const char_type standard_format[9]; // x X + static const char_type zone_abbrev_format[3]; // z + static const char_type zone_name_format[3]; // Z + static const char_type zone_iso_format[3]; // q + static const char_type zone_iso_extended_format[3]; // Q + static const char_type posix_zone_string_format[4]; // ZP + static const char_type duration_sign_negative_only[3]; // - + static const char_type duration_sign_always[3]; // + + static const char_type duration_seperator[2]; + static const char_type negative_sign[2]; //- + static const char_type positive_sign[2]; //+ + static const char_type iso_time_format_specifier[18]; + static const char_type iso_time_format_extended_specifier[22]; + //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] + static const char_type default_time_format[23]; + // default_time_input_format uses a posix_time_zone_string instead of a time zone abbrev + static const char_type default_time_input_format[24]; + //default time_duration format is HH:MM:SS[.fff...] + static const char_type default_time_duration_format[11]; + }; + + template + const typename time_formats::char_type + time_formats::fractional_seconds_format[3] = {'%','f'}; + + template + const typename time_formats::char_type + time_formats::fractional_seconds_or_none_format[3] = {'%','F'}; + + template + const typename time_formats::char_type + time_formats::seconds_with_fractional_seconds_format[3] = {'%','s'}; + + template + const typename time_formats::char_type + time_formats::seconds_format[3] = {'%','S'}; + + template + const typename time_formats::char_type + time_formats::hours_format[3] = {'%','H'}; + + template + const typename time_formats::char_type + time_formats::unrestricted_hours_format[3] = {'%','O'}; + + template + const typename time_formats::char_type + time_formats::full_24_hour_time_format[3] = {'%','T'}; + + template + const typename time_formats::char_type + time_formats::full_24_hour_time_expanded_format[9] = + {'%','H',':','%','M',':','%','S'}; + + template + const typename time_formats::char_type + time_formats::short_24_hour_time_format[3] = {'%','R'}; + + template + const typename time_formats::char_type + time_formats::short_24_hour_time_expanded_format[6] = + {'%','H',':','%','M'}; + + template + const typename time_formats::char_type + //time_formats::standard_format[5] = {'%','c',' ','%','z'}; + time_formats::standard_format[9] = {'%','x',' ','%','X',' ','%','z'}; + + template + const typename time_formats::char_type + time_formats::zone_abbrev_format[3] = {'%','z'}; + + template + const typename time_formats::char_type + time_formats::zone_name_format[3] = {'%','Z'}; + + template + const typename time_formats::char_type + time_formats::zone_iso_format[3] = {'%','q'}; + + template + const typename time_formats::char_type + time_formats::zone_iso_extended_format[3] ={'%','Q'}; + + template + const typename time_formats::char_type + time_formats::posix_zone_string_format[4] ={'%','Z','P'}; + + template + const typename time_formats::char_type + time_formats::duration_seperator[2] = {':'}; + + template + const typename time_formats::char_type + time_formats::negative_sign[2] = {'-'}; + + template + const typename time_formats::char_type + time_formats::positive_sign[2] = {'+'}; + + template + const typename time_formats::char_type + time_formats::duration_sign_negative_only[3] ={'%','-'}; + + template + const typename time_formats::char_type + time_formats::duration_sign_always[3] ={'%','+'}; + + template + const typename time_formats::char_type + time_formats::iso_time_format_specifier[18] = + {'%', 'Y', '%', 'm', '%', 'd', 'T', + '%', 'H', '%', 'M', '%', 'S', '%', 'F', '%','q' }; + + template + const typename time_formats::char_type + time_formats::iso_time_format_extended_specifier[22] = + {'%', 'Y', '-', '%', 'm', '-', '%', 'd', ' ', + '%', 'H', ':', '%', 'M', ':', '%', 'S', '%', 'F','%','Q'}; + + template + const typename time_formats::char_type + time_formats::default_time_format[23] = + {'%','Y','-','%','b','-','%','d',' ', + '%','H',':','%','M',':','%','S','%','F',' ','%','z'}; + + template + const typename time_formats::char_type + time_formats::default_time_input_format[24] = + {'%','Y','-','%','b','-','%','d',' ', + '%','H',':','%','M',':','%','S','%','F',' ','%','Z','P'}; + + template + const typename time_formats::char_type + time_formats::default_time_duration_format[11] = + {'%','O',':','%','M',':','%','S','%','F'}; + + + + /*! Facet used for format-based output of time types + * This class provides for the use of format strings to output times. In addition + * to the flags for formatting date elements, the following are the allowed format flags: + * - %x %X => default format - enables addition of more flags to default (ie. "%x %X %z") + * - %f => fractional seconds ".123456" + * - %F => fractional seconds or none: like frac sec but empty if frac sec == 0 + * - %s => seconds w/ fractional sec "02.123" (this is the same as "%S%f) + * - %S => seconds "02" + * - %z => abbreviated time zone "EDT" + * - %Z => full time zone name "Eastern Daylight Time" + */ + template > > + class BOOST_SYMBOL_VISIBLE time_facet : + public boost::date_time::date_facet { + typedef time_formats< CharT > formats_type; + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef boost::date_time::period period_type; + typedef boost::date_time::date_facet base_type; + typedef typename base_type::string_type string_type; + typedef typename base_type::char_type char_type; + typedef typename base_type::period_formatter_type period_formatter_type; + typedef typename base_type::special_values_formatter_type special_values_formatter_type; + typedef typename base_type::date_gen_formatter_type date_gen_formatter_type; + static const char_type* fractional_seconds_format; // %f + static const char_type* fractional_seconds_or_none_format; // %F + static const char_type* seconds_with_fractional_seconds_format; // %s + static const char_type* seconds_format; // %S + static const char_type* hours_format; // %H + static const char_type* unrestricted_hours_format; // %O + static const char_type* standard_format; // %x X + static const char_type* zone_abbrev_format; // %z + static const char_type* zone_name_format; // %Z + static const char_type* zone_iso_format; // %q + static const char_type* zone_iso_extended_format; // %Q + static const char_type* posix_zone_string_format; // %ZP + static const char_type* duration_seperator; + static const char_type* duration_sign_always; // %+ + static const char_type* duration_sign_negative_only; // %- + static const char_type* negative_sign; //- + static const char_type* positive_sign; //+ + static const char_type* iso_time_format_specifier; + static const char_type* iso_time_format_extended_specifier; + + //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] + static const char_type* default_time_format; + //default time_duration format is HH:MM:SS[.fff...] + static const char_type* default_time_duration_format; + static std::locale::id id; + +#if defined (__SUNPRO_CC) && defined (_RWSTD_VER) + std::locale::id& __get_id (void) const { return id; } +#endif + + //! sets default formats for ptime, local_date_time, and time_duration + explicit time_facet(::size_t ref_arg = 0) + : base_type(default_time_format, period_formatter_type(), special_values_formatter_type(), date_gen_formatter_type(), ref_arg), + m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) + {} + + //! Construct the facet with an explicitly specified format + explicit time_facet(const char_type* format_arg, + period_formatter_type period_formatter_arg = period_formatter_type(), + const special_values_formatter_type& special_value_formatter = special_values_formatter_type(), + date_gen_formatter_type dg_formatter = date_gen_formatter_type(), + ::size_t ref_arg = 0) + : base_type(format_arg, + period_formatter_arg, + special_value_formatter, + dg_formatter, + ref_arg), + m_time_duration_format(string_type(duration_sign_negative_only) + default_time_duration_format) + {} + + //! Changes format for time_duration + void time_duration_format(const char_type* const format) + { + m_time_duration_format = format; + } + + void set_iso_format() BOOST_OVERRIDE + { + this->m_format = iso_time_format_specifier; + } + void set_iso_extended_format() BOOST_OVERRIDE + { + this->m_format = iso_time_format_extended_specifier; + } + + OutItrT put(OutItrT next_arg, + std::ios_base& ios_arg, + char_type fill_arg, + const time_type& time_arg) const + { + if (time_arg.is_special()) { + return this->do_put_special(next_arg, ios_arg, fill_arg, + time_arg.date().as_special()); + } + string_type local_format(this->m_format); + + // %T and %R have to be replaced here since they are not standard + boost::algorithm::replace_all(local_format, + boost::as_literal(formats_type::full_24_hour_time_format), + boost::as_literal(formats_type::full_24_hour_time_expanded_format)); + boost::algorithm::replace_all(local_format, + boost::as_literal(formats_type::short_24_hour_time_format), + boost::as_literal(formats_type::short_24_hour_time_expanded_format)); + + string_type frac_str; + if (local_format.find(seconds_with_fractional_seconds_format) != string_type::npos) { + // replace %s with %S.nnn + frac_str = + fractional_seconds_as_string(time_arg.time_of_day(), false); + char_type sep = std::use_facet >(ios_arg.getloc()).decimal_point(); + + string_type replace_string(seconds_format); + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(local_format, + seconds_with_fractional_seconds_format, + replace_string); + } + /* NOTE: replacing posix_zone_string_format must be done BEFORE + * zone_name_format: "%ZP" & "%Z", if Z is checked first it will + * incorrectly replace a zone_name where a posix_string should go */ + if (local_format.find(posix_zone_string_format) != string_type::npos) { + if(time_arg.zone_abbrev().empty()) { + // if zone_abbrev() returns an empty string, we want to + // erase posix_zone_string_format from format + boost::algorithm::erase_all(local_format, posix_zone_string_format); + } + else{ + boost::algorithm::replace_all(local_format, + posix_zone_string_format, + time_arg.zone_as_posix_string()); + } + } + if (local_format.find(zone_name_format) != string_type::npos) { + if(time_arg.zone_name().empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_name() returns an empty string, we want to + // erase zone_name_format & one preceeding space + std::basic_ostringstream ss; + ss << ' ' << zone_name_format; + boost::algorithm::erase_all(local_format, ss.str()); + } + else{ + boost::algorithm::replace_all(local_format, + zone_name_format, + time_arg.zone_name()); + } + } + if (local_format.find(zone_abbrev_format) != string_type::npos) { + if(time_arg.zone_abbrev(false).empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_abbrev() returns an empty string, we want to + // erase zone_abbrev_format & one preceeding space + std::basic_ostringstream ss; + ss << ' ' << zone_abbrev_format; + boost::algorithm::erase_all(local_format, ss.str()); + } + else{ + boost::algorithm::replace_all(local_format, + zone_abbrev_format, + time_arg.zone_abbrev(false)); + } + } + if (local_format.find(zone_iso_extended_format) != string_type::npos) { + if(time_arg.zone_name(true).empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_name() returns an empty string, we want to + // erase zone_iso_extended_format from format + boost::algorithm::erase_all(local_format, zone_iso_extended_format); + } + else{ + boost::algorithm::replace_all(local_format, + zone_iso_extended_format, + time_arg.zone_name(true)); + } + } + + if (local_format.find(zone_iso_format) != string_type::npos) { + if(time_arg.zone_abbrev(true).empty()) { + /* TODO: this'll probably create problems if a user places + * the zone_*_format flag in the format with a ptime. This + * code removes the flag from the default formats */ + + // if zone_abbrev() returns an empty string, we want to + // erase zone_iso_format from format + boost::algorithm::erase_all(local_format, zone_iso_format); + } + else{ + boost::algorithm::replace_all(local_format, + zone_iso_format, + time_arg.zone_abbrev(true)); + } + } + if (local_format.find(fractional_seconds_format) != string_type::npos) { + // replace %f with nnnnnnn + if (frac_str.empty()) { + frac_str = fractional_seconds_as_string(time_arg.time_of_day(), false); + } + boost::algorithm::replace_all(local_format, + fractional_seconds_format, + frac_str); + } + + if (local_format.find(fractional_seconds_or_none_format) != string_type::npos) { + // replace %F with nnnnnnn or nothing if fs == 0 + frac_str = + fractional_seconds_as_string(time_arg.time_of_day(), true); + if (!frac_str.empty()) { + char_type sep = std::use_facet >(ios_arg.getloc()).decimal_point(); + string_type replace_string; + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(local_format, + fractional_seconds_or_none_format, + replace_string); + } + else { + boost::algorithm::erase_all(local_format, + fractional_seconds_or_none_format); + } + } + + return this->do_put_tm(next_arg, ios_arg, fill_arg, + to_tm(time_arg), local_format); + } + + //! put function for time_duration + OutItrT put(OutItrT next_arg, + std::ios_base& ios_arg, + char_type fill_arg, + const time_duration_type& time_dur_arg) const + { + if (time_dur_arg.is_special()) { + return this->do_put_special(next_arg, ios_arg, fill_arg, + time_dur_arg.get_rep().as_special()); + } + + string_type format(m_time_duration_format); + if (time_dur_arg.is_negative()) { + // replace %- with minus sign. Should we use the numpunct facet? + boost::algorithm::replace_all(format, + duration_sign_negative_only, + negative_sign); + // remove all the %+ in the string with '-' + boost::algorithm::replace_all(format, + duration_sign_always, + negative_sign); + } + else { //duration is positive + // remove all the %- combos from the string + boost::algorithm::erase_all(format, duration_sign_negative_only); + // remove all the %+ in the string with '+' + boost::algorithm::replace_all(format, + duration_sign_always, + positive_sign); + } + + // %T and %R have to be replaced here since they are not standard + boost::algorithm::replace_all(format, + boost::as_literal(formats_type::full_24_hour_time_format), + boost::as_literal(formats_type::full_24_hour_time_expanded_format)); + boost::algorithm::replace_all(format, + boost::as_literal(formats_type::short_24_hour_time_format), + boost::as_literal(formats_type::short_24_hour_time_expanded_format)); + + /* + * It is possible for a time duration to span more then 24 hours. + * Standard time_put::put is obliged to behave the same as strftime + * (See ISO 14882-2003 22.2.5.3.1 par. 1) and strftime's behavior is + * unspecified for the case when tm_hour field is outside 0-23 range + * (See ISO 9899-1999 7.23.3.5 par. 3). So we must output %H and %O + * here ourself. + */ + string_type hours_str; + if (format.find(unrestricted_hours_format) != string_type::npos) { + hours_str = hours_as_string(time_dur_arg); + boost::algorithm::replace_all(format, unrestricted_hours_format, hours_str); + } + // We still have to process restricted hours format specifier. In order to + // support parseability of durations in ISO format (%H%M%S), we'll have to + // restrict the stringified hours length to 2 characters. + if (format.find(hours_format) != string_type::npos) { + if (hours_str.empty()) + hours_str = hours_as_string(time_dur_arg); + BOOST_ASSERT(hours_str.length() <= 2); + boost::algorithm::replace_all(format, hours_format, hours_str); + } + + string_type frac_str; + if (format.find(seconds_with_fractional_seconds_format) != string_type::npos) { + // replace %s with %S.nnn + frac_str = + fractional_seconds_as_string(time_dur_arg, false); + char_type sep = std::use_facet >(ios_arg.getloc()).decimal_point(); + + string_type replace_string(seconds_format); + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(format, + seconds_with_fractional_seconds_format, + replace_string); + } + if (format.find(fractional_seconds_format) != string_type::npos) { + // replace %f with nnnnnnn + if (!frac_str.size()) { + frac_str = fractional_seconds_as_string(time_dur_arg, false); + } + boost::algorithm::replace_all(format, + fractional_seconds_format, + frac_str); + } + + if (format.find(fractional_seconds_or_none_format) != string_type::npos) { + // replace %F with nnnnnnn or nothing if fs == 0 + frac_str = + fractional_seconds_as_string(time_dur_arg, true); + if (frac_str.size()) { + char_type sep = std::use_facet >(ios_arg.getloc()).decimal_point(); + string_type replace_string; + replace_string += sep; + replace_string += frac_str; + boost::algorithm::replace_all(format, + fractional_seconds_or_none_format, + replace_string); + } + else { + boost::algorithm::erase_all(format, + fractional_seconds_or_none_format); + } + } + + return this->do_put_tm(next_arg, ios_arg, fill_arg, + to_tm(time_dur_arg), format); + } + + OutItrT put(OutItrT next, std::ios_base& ios_arg, + char_type fill, const period_type& p) const + { + return this->m_period_formatter.put_period(next, ios_arg, fill,p,*this); + } + + + protected: + + static + string_type + fractional_seconds_as_string(const time_duration_type& time_arg, + bool null_when_zero) + { + typename time_duration_type::fractional_seconds_type frac_sec = + time_arg.fractional_seconds(); + + if (null_when_zero && (frac_sec == 0)) { + return string_type(); + } + + //make sure there is no sign + return integral_as_string( + date_time::absolute_value(frac_sec), + time_duration_type::num_fractional_digits()); + } + + static + string_type + hours_as_string(const time_duration_type& time_arg, int width = 2) + { + return integral_as_string(date_time::absolute_value(time_arg.hours()), width); + } + + template< typename IntT > + static + string_type + integral_as_string(IntT val, int width = 2) + { + std::basic_ostringstream ss; + ss.imbue(std::locale::classic()); // don't want any formatting + ss << std::setw(width) + << std::setfill(static_cast('0')); +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // JDG [7/6/02 VC++ compatibility] + char_type buff[34]; + ss << _i64toa(static_cast(val), buff, 10); +#else + ss << val; +#endif + return ss.str(); + } + + private: + string_type m_time_duration_format; + + }; + + template + std::locale::id time_facet::id; + + template + const typename time_facet::char_type* + time_facet::fractional_seconds_format = time_formats::fractional_seconds_format; + + template + const typename time_facet::char_type* + time_facet::fractional_seconds_or_none_format = time_formats::fractional_seconds_or_none_format; + + template + const typename time_facet::char_type* + time_facet::seconds_with_fractional_seconds_format = + time_formats::seconds_with_fractional_seconds_format; + + + template + const typename time_facet::char_type* + time_facet::zone_name_format = time_formats::zone_name_format; + + template + const typename time_facet::char_type* + time_facet::zone_abbrev_format = time_formats::zone_abbrev_format; + + template + const typename time_facet::char_type* + time_facet::zone_iso_extended_format =time_formats::zone_iso_extended_format; + + template + const typename time_facet::char_type* + time_facet::posix_zone_string_format =time_formats::posix_zone_string_format; + + template + const typename time_facet::char_type* + time_facet::zone_iso_format = time_formats::zone_iso_format; + + template + const typename time_facet::char_type* + time_facet::seconds_format = time_formats::seconds_format; + + template + const typename time_facet::char_type* + time_facet::hours_format = time_formats::hours_format; + + template + const typename time_facet::char_type* + time_facet::unrestricted_hours_format = time_formats::unrestricted_hours_format; + + template + const typename time_facet::char_type* + time_facet::standard_format = time_formats::standard_format; + + template + const typename time_facet::char_type* + time_facet::duration_seperator = time_formats::duration_seperator; + + template + const typename time_facet::char_type* + time_facet::negative_sign = time_formats::negative_sign; + + template + const typename time_facet::char_type* + time_facet::positive_sign = time_formats::positive_sign; + + template + const typename time_facet::char_type* + time_facet::duration_sign_negative_only = time_formats::duration_sign_negative_only; + + template + const typename time_facet::char_type* + time_facet::duration_sign_always = time_formats::duration_sign_always; + + template + const typename time_facet::char_type* + time_facet::iso_time_format_specifier = time_formats::iso_time_format_specifier; + + template + const typename time_facet::char_type* + time_facet::iso_time_format_extended_specifier = time_formats::iso_time_format_extended_specifier; + + template + const typename time_facet::char_type* + time_facet::default_time_format = + time_formats::default_time_format; + + template + const typename time_facet::char_type* + time_facet::default_time_duration_format = + time_formats::default_time_duration_format; + + + //! Facet for format-based input. + /*! + */ + template > > + class BOOST_SYMBOL_VISIBLE time_input_facet : + public boost::date_time::date_input_facet { + public: + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef typename time_duration_type::fractional_seconds_type fracional_seconds_type; + typedef boost::date_time::period period_type; + typedef boost::date_time::date_input_facet base_type; + typedef typename base_type::duration_type date_duration_type; + typedef typename base_type::year_type year_type; + typedef typename base_type::month_type month_type; + typedef typename base_type::day_type day_type; + typedef typename base_type::string_type string_type; + typedef typename string_type::const_iterator const_itr; + typedef typename base_type::char_type char_type; + typedef typename base_type::format_date_parser_type format_date_parser_type; + typedef typename base_type::period_parser_type period_parser_type; + typedef typename base_type::special_values_parser_type special_values_parser_type; + typedef typename base_type::date_gen_parser_type date_gen_parser_type; + typedef typename base_type::special_values_parser_type::match_results match_results; + + static const char_type* fractional_seconds_format; // f + static const char_type* fractional_seconds_or_none_format; // F + static const char_type* seconds_with_fractional_seconds_format; // s + static const char_type* seconds_format; // S + static const char_type* standard_format; // x X + static const char_type* zone_abbrev_format; // z + static const char_type* zone_name_format; // Z + static const char_type* zone_iso_format; // q + static const char_type* zone_iso_extended_format; // Q + static const char_type* duration_seperator; + static const char_type* iso_time_format_specifier; + static const char_type* iso_time_format_extended_specifier; + static const char_type* default_time_input_format; + static const char_type* default_time_duration_format; + static std::locale::id id; + + //! Constructor that takes a format string for a ptime + explicit time_input_facet(const string_type& format, ::size_t ref_arg = 0) + : base_type(format, ref_arg), + m_time_duration_format(default_time_duration_format) + { } + + explicit time_input_facet(const string_type& format, + const format_date_parser_type& date_parser, + const special_values_parser_type& sv_parser, + const period_parser_type& per_parser, + const date_gen_parser_type& date_gen_parser, + ::size_t ref_arg = 0) + : base_type(format, + date_parser, + sv_parser, + per_parser, + date_gen_parser, + ref_arg), + m_time_duration_format(default_time_duration_format) + {} + + //! sets default formats for ptime, local_date_time, and time_duration + explicit time_input_facet(::size_t ref_arg = 0) + : base_type(default_time_input_format, ref_arg), + m_time_duration_format(default_time_duration_format) + { } + + //! Set the format for time_duration + void time_duration_format(const char_type* const format) { + m_time_duration_format = format; + } + virtual void set_iso_format() + { + this->m_format = iso_time_format_specifier; + } + virtual void set_iso_extended_format() + { + this->m_format = iso_time_format_extended_specifier; + } + + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& ios_arg, + period_type& p) const + { + p = this->m_period_parser.get_period(sitr, + stream_end, + ios_arg, + p, + time_duration_type::unit(), + *this); + return sitr; + } + + //default ptime format is YYYY-Mon-DD HH:MM:SS[.fff...][ zzz] + //default time_duration format is %H:%M:%S%F HH:MM:SS[.fff...] + + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& ios_arg, + time_duration_type& td) const + { + // skip leading whitespace + while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } + + bool use_current_char = false; + + // num_get will consume the +/-, we may need a copy if special_value + char_type c = '\0'; + if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) { + c = *sitr; + } + + typedef typename time_duration_type::hour_type hour_type; + typedef typename time_duration_type::min_type min_type; + typedef typename time_duration_type::sec_type sec_type; + + hour_type hour = 0; + min_type min = 0; + sec_type sec = 0; + typename time_duration_type::fractional_seconds_type frac(0); + + typedef std::num_get num_get; + if(!std::has_facet(ios_arg.getloc())) { + num_get* ng = new num_get(); + std::locale loc = std::locale(ios_arg.getloc(), ng); + ios_arg.imbue(loc); + } + + const_itr itr(m_time_duration_format.begin()); + while (itr != m_time_duration_format.end() && (sitr != stream_end)) { + if (*itr == '%') { + if (++itr == m_time_duration_format.end()) break; + if (*itr != '%') { + switch(*itr) { + case 'O': + { + // A period may span more than 24 hours. In that case the format + // string should be composed with the unrestricted hours specifier. + hour = var_string_to_int(sitr, stream_end, + std::numeric_limits::digits10 + 1); + if(hour == -1){ + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 'H': + { + match_results mr; + hour = fixed_string_to_int(sitr, stream_end, mr, 2); + if(hour == -1){ + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 'M': + { + match_results mr; + min = fixed_string_to_int(sitr, stream_end, mr, 2); + if(min == -1){ + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 's': + case 'S': + { + match_results mr; + sec = fixed_string_to_int(sitr, stream_end, mr, 2); + if(sec == -1){ + return check_special_value(sitr, stream_end, td, c); + } + if (*itr == 'S') + break; + // %s is the same as %S%f so we drop through into %f + } + /* Falls through. */ + case 'f': + { + // check for decimal, check special_values if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + return check_special_value(sitr, stream_end, td, c); + } + break; + } + case 'F': + { + // check for decimal, skip if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + // nothing was parsed so we don't want to advance sitr + use_current_char = true; + } + break; + } + default: + {} // ignore what we don't understand? + }// switch + } + else { // itr == '%', second consecutive + ++sitr; + } + + ++itr; //advance past format specifier + } + else { //skip past chars in format and in buffer + ++itr; + // set use_current_char when sitr is already + // pointing at the next character to process + if (use_current_char) { + use_current_char = false; + } + else { + ++sitr; + } + } + } + + td = time_duration_type(hour, min, sec, frac); + return sitr; + } + + + //! Parses a time object from the input stream + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& ios_arg, + time_type& t) const + { + string_type tz_str; + return get(sitr, stream_end, ios_arg, t, tz_str, false); + } + //! Expects a time_zone in the input stream + InItrT get_local_time(InItrT& sitr, + InItrT& stream_end, + std::ios_base& ios_arg, + time_type& t, + string_type& tz_str) const + { + return get(sitr, stream_end, ios_arg, t, tz_str, true); + } + + protected: + + InItrT get(InItrT& sitr, + InItrT& stream_end, + std::ios_base& ios_arg, + time_type& t, + string_type& tz_str, + bool time_is_local) const + { + // skip leading whitespace + while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } + + bool use_current_char = false; + bool use_current_format_char = false; // used with two character flags + + // num_get will consume the +/-, we may need a copy if special_value + char_type c = '\0'; + if((sitr != stream_end) && (*sitr == '-' || *sitr == '+')) { + c = *sitr; + } + + typedef typename time_duration_type::hour_type hour_type; + typedef typename time_duration_type::min_type min_type; + typedef typename time_duration_type::sec_type sec_type; + + // time elements + hour_type hour = 0; + min_type min = 0; + sec_type sec = 0; + typename time_duration_type::fractional_seconds_type frac(0); + // date elements + short day_of_year(0); + /* Initialized the following to their minimum values. These intermediate + * objects are used so we get specific exceptions when part of the input + * is unparsable. + * Ex: "205-Jan-15" will throw a bad_year, "2005-Jsn-15"- bad_month, etc.*/ + year_type t_year(1400); + month_type t_month(1); + day_type t_day(1); + + typedef std::num_get num_get; + if(!std::has_facet(ios_arg.getloc())) { + num_get* ng = new num_get(); + std::locale loc = std::locale(ios_arg.getloc(), ng); + ios_arg.imbue(loc); + } + + const_itr itr(this->m_format.begin()); + while (itr != this->m_format.end() && (sitr != stream_end)) { + if (*itr == '%') { + if (++itr == this->m_format.end()) break; + if (*itr != '%') { + // the cases are grouped by date & time flags - not alphabetical order + switch(*itr) { + // date flags + case 'Y': + case 'y': + { + char_type cs[3] = { '%', *itr }; + string_type s(cs); + match_results mr; + try { + t_year = this->m_parser.parse_year(sitr, stream_end, s, mr); + } + catch(std::out_of_range&) { // base class for bad_year exception + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_year + } + } + break; + } + case 'B': + case 'b': + case 'm': + { + char_type cs[3] = { '%', *itr }; + string_type s(cs); + match_results mr; + try { + t_month = this->m_parser.parse_month(sitr, stream_end, s, mr); + } + catch(std::out_of_range&) { // base class for bad_month exception + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_month + } + } + // did m_parser already advance sitr to next char? + if(mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'a': + case 'A': + case 'w': + { + // weekday is not used in construction but we need to get it out of the stream + char_type cs[3] = { '%', *itr }; + string_type s(cs); + match_results mr; + typename date_type::day_of_week_type wd(0); + try { + wd = this->m_parser.parse_weekday(sitr, stream_end, s, mr); + } + catch(std::out_of_range&) { // base class for bad_weekday exception + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_weekday + } + } + // did m_parser already advance sitr to next char? + if(mr.has_remaining()) { + use_current_char = true; + } + break; + } + case 'j': + { + // code that gets julian day (from format_date_parser) + match_results mr; + day_of_year = fixed_string_to_int(sitr, stream_end, mr, 3); + if(day_of_year == -1) { + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + } + // these next two lines are so we get an exception with bad input + typedef typename time_type::date_type::day_of_year_type day_of_year_type; + day_of_year_type t_day_of_year(day_of_year); + break; + } + case 'd': + case 'e': + { + try { + t_day = (*itr == 'd') ? + this->m_parser.parse_day_of_month(sitr, stream_end) : + this->m_parser.parse_var_day_of_month(sitr, stream_end); + } + catch(std::out_of_range&) { // base class for exception bad_day_of_month + match_results mr; + if(this->m_sv_parser.match(sitr, stream_end, mr)) { + t = time_type(static_cast(mr.current_match)); + return sitr; + } + else { + throw; // rethrow bad_day_of_month + } + } + break; + } + // time flags + case 'H': + { + match_results mr; + hour = fixed_string_to_int(sitr, stream_end, mr, 2); + if(hour == -1){ + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 'M': + { + match_results mr; + min = fixed_string_to_int(sitr, stream_end, mr, 2); + if(min == -1){ + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 's': + case 'S': + { + match_results mr; + sec = fixed_string_to_int(sitr, stream_end, mr, 2); + if(sec == -1){ + return check_special_value(sitr, stream_end, t, c); + } + if (*itr == 'S' || sitr == stream_end) + break; + // %s is the same as %S%f so we drop through into %f if we are + // not at the end of the stream + } + /* Falls through. */ + case 'f': + { + // check for decimal, check SV if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + return check_special_value(sitr, stream_end, t, c); + } + break; + } + case 'F': + { + // check for decimal, skip if missing + if(*sitr == '.') { + ++sitr; + parse_frac_type(sitr, stream_end, frac); + // sitr will point to next expected char after this parsing + // is complete so no need to advance it + use_current_char = true; + } + else { + // nothing was parsed so we don't want to advance sitr + use_current_char = true; + } + break; + } + // time_zone flags + //case 'q': + //case 'Q': + //case 'z': + case 'Z': + { + if(time_is_local) { // skip if 't' is a ptime + ++itr; + if(*itr == 'P') { + // skip leading whitespace + while((sitr != stream_end) && std::isspace(*sitr)) { ++sitr; } + // parse zone + while((sitr != stream_end) && (!std::isspace(*sitr))) { + tz_str += *sitr; + ++sitr; + } + } + else { + use_current_format_char = true; + } + + } + else { + // nothing was parsed so we don't want to advance sitr + use_current_char = true; + } + + break; + } + default: + {} // ignore what we don't understand? + }// switch + } + else { // itr == '%', second consecutive + ++sitr; + } + + if(use_current_format_char) { + use_current_format_char = false; + } + else { + ++itr; //advance past format specifier + } + + } + else { //skip past chars in format and in buffer + ++itr; + // set use_current_char when sitr is already + // pointing at the next character to process + if (use_current_char) { + use_current_char = false; + } + else { + ++sitr; + } + } + } + + date_type d(not_a_date_time); + if (day_of_year > 0) { + d = date_type(static_cast(t_year),1,1) + date_duration_type(day_of_year-1); + } + else { + d = date_type(t_year, t_month, t_day); + } + + time_duration_type td(hour, min, sec, frac); + t = time_type(d, td); + return sitr; + } + + //! Helper function to check for special_value + /*! First character may have been consumed during original parse + * attempt. Parameter 'c' should be a copy of that character. + * Throws ios_base::failure if parse fails. */ + template + inline + InItrT check_special_value(InItrT& sitr,InItrT& stream_end, temporal_type& tt, char_type c='\0') const + { + match_results mr; + if((c == '-' || c == '+') && (*sitr != c)) { // was the first character consumed? + mr.cache += c; + } + (void)this->m_sv_parser.match(sitr, stream_end, mr); + if(mr.current_match == match_results::PARSE_ERROR) { + std::string tmp = convert_string_type(mr.cache); + boost::throw_exception(std::ios_base::failure("Parse failed. No match found for '" + tmp + "'")); + BOOST_DATE_TIME_UNREACHABLE_EXPRESSION(return sitr); // should never reach + } + tt = temporal_type(static_cast(mr.current_match)); + return sitr; + } + + //! Helper function for parsing a fractional second type from the stream + void parse_frac_type(InItrT& sitr, + InItrT& stream_end, + fracional_seconds_type& frac) const + { + string_type cache; + while((sitr != stream_end) && std::isdigit(*sitr)) { + cache += *sitr; + ++sitr; + } + if(cache.size() > 0) { + unsigned short precision = time_duration_type::num_fractional_digits(); + // input may be only the first few decimal places + if(cache.size() < precision) { + frac = lexical_cast(cache); + frac = decimal_adjust(frac, static_cast(precision - cache.size())); + } + else { + // if input has too many decimal places, drop excess digits + frac = lexical_cast(cache.substr(0, precision)); + } + } + } + + private: + string_type m_time_duration_format; + + //! Helper function to adjust trailing zeros when parsing fractional digits + template + inline + int_type decimal_adjust(int_type val, const unsigned short places) const + { + unsigned long factor = 1; + for(int i = 0; i < places; ++i){ + factor *= 10; // shift decimal to the right + } + return val * factor; + } + + }; + +template + std::locale::id time_input_facet::id; + +template + const typename time_input_facet::char_type* + time_input_facet::fractional_seconds_format = time_formats::fractional_seconds_format; + + template + const typename time_input_facet::char_type* + time_input_facet::fractional_seconds_or_none_format = time_formats::fractional_seconds_or_none_format; + + template + const typename time_input_facet::char_type* + time_input_facet::seconds_with_fractional_seconds_format = time_formats::seconds_with_fractional_seconds_format; + + template + const typename time_input_facet::char_type* + time_input_facet::seconds_format = time_formats::seconds_format; + + template + const typename time_input_facet::char_type* + time_input_facet::standard_format = time_formats::standard_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_abbrev_format = time_formats::zone_abbrev_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_name_format = time_formats::zone_name_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_iso_format = time_formats::zone_iso_format; + + template + const typename time_input_facet::char_type* + time_input_facet::zone_iso_extended_format = time_formats::zone_iso_extended_format; + + template + const typename time_input_facet::char_type* + time_input_facet::duration_seperator = time_formats::duration_seperator; + + template + const typename time_input_facet::char_type* + time_input_facet::iso_time_format_specifier = time_formats::iso_time_format_specifier; + + template + const typename time_input_facet::char_type* + time_input_facet::iso_time_format_extended_specifier = time_formats::iso_time_format_extended_specifier; + + template + const typename time_input_facet::char_type* + time_input_facet::default_time_input_format = time_formats::default_time_input_format; + + template + const typename time_input_facet::char_type* + time_input_facet::default_time_duration_format = time_formats::default_time_duration_format; + +} } // namespaces + +#endif diff --git a/src/vendor/boost/date_time/time_formatting_streams.hpp b/src/vendor/boost/date_time/time_formatting_streams.hpp new file mode 100644 index 000000000..f69f87a34 --- /dev/null +++ b/src/vendor/boost/date_time/time_formatting_streams.hpp @@ -0,0 +1,122 @@ +#ifndef DATE_TIME_TIME_FORMATTING_STREAMS_HPP___ +#define DATE_TIME_TIME_FORMATTING_STREAMS_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include + +#ifndef BOOST_DATE_TIME_NO_LOCALE + +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + + //! Put a time type into a stream using appropriate facets + template + class ostream_time_duration_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type; + + //! Put time into an ostream + static void duration_put(const time_duration_type& td, + ostream_type& os) + { + if(td.is_special()) { + os << td.get_rep(); + } + else { + charT fill_char = '0'; + if(td.is_negative()) { + os << '-'; + } + os << std::setw(2) << std::setfill(fill_char) + << absolute_value(td.hours()) << ":"; + os << std::setw(2) << std::setfill(fill_char) + << absolute_value(td.minutes()) << ":"; + os << std::setw(2) << std::setfill(fill_char) + << absolute_value(td.seconds()); + fractional_seconds_type frac_sec = + absolute_value(td.fractional_seconds()); + if (frac_sec != 0) { + os << "." + << std::setw(time_duration_type::num_fractional_digits()) + << std::setfill(fill_char) + << frac_sec; + } + } // else + } // duration_put + }; //class ostream_time_duration_formatter + + //! Put a time type into a stream using appropriate facets + template + class ostream_time_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename time_type::date_type date_type; + typedef typename time_type::time_duration_type time_duration_type; + typedef ostream_time_duration_formatter duration_formatter; + + //! Put time into an ostream + static void time_put(const time_type& t, + ostream_type& os) + { + date_type d = t.date(); + os << d; + if(!d.is_infinity() && !d.is_not_a_date()) + { + os << " "; //TODO: fix the separator here. + duration_formatter::duration_put(t.time_of_day(), os); + } + + } // time_to_ostream + }; //class ostream_time_formatter + + + //! Put a time period into a stream using appropriate facets + template + class ostream_time_period_formatter + { + public: + typedef std::basic_ostream ostream_type; + typedef typename time_period_type::point_type time_type; + typedef ostream_time_formatter time_formatter; + + //! Put time into an ostream + static void period_put(const time_period_type& tp, + ostream_type& os) + { + os << '['; //TODO: facet or manipulator for periods? + time_formatter::time_put(tp.begin(), os); + os << '/'; //TODO: facet or manipulator for periods? + time_formatter::time_put(tp.last(), os); + os << ']'; + + } // period_put + + }; //class ostream_time_period_formatter + + + +} } //namespace date_time + +#endif //BOOST_DATE_TIME_NO_LOCALE + +#endif diff --git a/src/vendor/boost/date_time/time_iterator.hpp b/src/vendor/boost/date_time/time_iterator.hpp new file mode 100644 index 000000000..64439363d --- /dev/null +++ b/src/vendor/boost/date_time/time_iterator.hpp @@ -0,0 +1,52 @@ +#ifndef DATE_TIME_TIME_ITERATOR_HPP___ +#define DATE_TIME_TIME_ITERATOR_HPP___ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +namespace boost { +namespace date_time { + + + //! Simple time iterator skeleton class + template + class time_itr { + public: + typedef typename time_type::time_duration_type time_duration_type; + time_itr(time_type t, time_duration_type d) : current_(t), offset_(d) {} + time_itr& operator++() + { + current_ = current_ + offset_; + return *this; + } + time_itr& operator--() + { + current_ = current_ - offset_; + return *this; + } + time_type operator*() {return current_;} + time_type* operator->() {return ¤t_;} + bool operator< (const time_type& t) {return current_ < t;} + bool operator<= (const time_type& t) {return current_ <= t;} + bool operator!= (const time_type& t) {return current_ != t;} + bool operator== (const time_type& t) {return current_ == t;} + bool operator> (const time_type& t) {return current_ > t;} + bool operator>= (const time_type& t) {return current_ >= t;} + + private: + time_type current_; + time_duration_type offset_; + }; + + + +} }//namespace date_time + + +#endif diff --git a/src/vendor/boost/date_time/time_parsing.hpp b/src/vendor/boost/date_time/time_parsing.hpp new file mode 100644 index 000000000..04482736c --- /dev/null +++ b/src/vendor/boost/date_time/time_parsing.hpp @@ -0,0 +1,339 @@ +#ifndef _DATE_TIME_TIME_PARSING_HPP___ +#define _DATE_TIME_TIME_PARSING_HPP___ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/tokenizer.hpp" +#include "boost/lexical_cast.hpp" +#include "boost/date_time/date_parsing.hpp" +#include "boost/date_time/special_values_parser.hpp" +#include "boost/cstdint.hpp" +#include + +namespace boost { +namespace date_time { + + //! computes exponential math like 2^8 => 256, only works with positive integers + //Not general purpose, but needed b/c std::pow is not available + //everywhere. Hasn't been tested with negatives and zeros + template + inline + int_type power(int_type base, int_type exponent) + { + int_type result = 1; + for(int i = 0; i < exponent; ++i){ + result *= base; + } + return result; + } + + //! Creates a time_duration object from a delimited string + /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]". + * If the number of fractional digits provided is greater than the + * precision of the time duration type then the extra digits are + * truncated. + * + * A negative duration will be created if the first character in + * string is a '-', all other '-' will be treated as delimiters. + * Accepted delimiters are "-:,.". + */ + template + inline + time_duration + str_from_delimited_time_duration(const std::basic_string& s) + { + unsigned short min=0, sec =0; + int hour =0; + bool is_neg = (s.at(0) == '-'); + boost::int64_t fs=0; + int pos = 0; + + typedef typename std::basic_string::traits_type traits_type; + typedef boost::char_separator char_separator_type; + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef typename boost::tokenizer::const_iterator, + typename std::basic_string >::iterator tokenizer_iterator; + + char_type sep_chars[5] = {'-',':',',','.'}; + char_separator_type sep(sep_chars); + tokenizer tok(s,sep); + for(tokenizer_iterator beg=tok.begin(); beg!=tok.end();++beg){ + switch(pos) { + case 0: { + hour = boost::lexical_cast(*beg); + break; + } + case 1: { + min = boost::lexical_cast(*beg); + break; + } + case 2: { + sec = boost::lexical_cast(*beg); + break; + } + case 3: { + int digits = static_cast(beg->length()); + //Works around a bug in MSVC 6 library that does not support + //operator>> thus meaning lexical_cast will fail to compile. +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + // msvc wouldn't compile 'time_duration::num_fractional_digits()' + // (required template argument list) as a workaround a temp + // time_duration object was used + time_duration td(hour,min,sec,fs); + int precision = td.num_fractional_digits(); + // _atoi64 is an MS specific function + if(digits >= precision) { + // drop excess digits + fs = _atoi64(beg->substr(0, precision).c_str()); + } + else { + fs = _atoi64(beg->c_str()); + } +#else + int precision = time_duration::num_fractional_digits(); + if(digits >= precision) { + // drop excess digits + fs = boost::lexical_cast(beg->substr(0, precision)); + } + else { + fs = boost::lexical_cast(*beg); + } +#endif + if(digits < precision){ + // trailing zeros get dropped from the string, + // "1:01:01.1" would yield .000001 instead of .100000 + // the power() compensates for the missing decimal places + fs *= power(10, precision - digits); + } + + break; + } + default: break; + }//switch + pos++; + } + if(is_neg) { + return -time_duration(hour, min, sec, fs); + } + else { + return time_duration(hour, min, sec, fs); + } + } + + //! Creates a time_duration object from a delimited string + /*! Expected format for string is "[-]h[h][:mm][:ss][.fff]". + * If the number of fractional digits provided is greater than the + * precision of the time duration type then the extra digits are + * truncated. + * + * A negative duration will be created if the first character in + * string is a '-', all other '-' will be treated as delimiters. + * Accepted delimiters are "-:,.". + */ + template + inline + time_duration + parse_delimited_time_duration(const std::string& s) + { + return str_from_delimited_time_duration(s); + } + + //! Utility function to split appart string + inline + bool + split(const std::string& s, + char sep, + std::string& first, + std::string& second) + { + std::string::size_type sep_pos = s.find(sep); + first = s.substr(0,sep_pos); + if (sep_pos!=std::string::npos) + second = s.substr(sep_pos+1); + return true; + } + + + template + inline + time_type + parse_delimited_time(const std::string& s, char sep) + { + typedef typename time_type::time_duration_type time_duration; + typedef typename time_type::date_type date_type; + + //split date/time on a unique delimiter char such as ' ' or 'T' + std::string date_string, tod_string; + split(s, sep, date_string, tod_string); + //call parse_date with first string + date_type d = parse_date(date_string); + //call parse_time_duration with remaining string + time_duration td = parse_delimited_time_duration(tod_string); + //construct a time + return time_type(d, td); + + } + + //! Parse time duration part of an iso time of form: [-]hhmmss[.fff...] (eg: 120259.123 is 12 hours, 2 min, 59 seconds, 123000 microseconds) + template + inline + time_duration + parse_undelimited_time_duration(const std::string& s) + { + int precision = 0; + { + // msvc wouldn't compile 'time_duration::num_fractional_digits()' + // (required template argument list) as a workaround, a temp + // time_duration object was used + time_duration tmp(0,0,0,1); + precision = tmp.num_fractional_digits(); + } + // 'precision+1' is so we grab all digits, plus the decimal + int offsets[] = {2,2,2, precision+1}; + int pos = 0, sign = 0; + int hours = 0; + short min=0, sec=0; + boost::int64_t fs=0; + // increment one position if the string was "signed" + if(s.at(sign) == '-') + { + ++sign; + } + // stlport choked when passing s.substr() to tokenizer + // using a new string fixed the error + std::string remain = s.substr(sign); + /* We do not want the offset_separator to wrap the offsets, we + * will never want to process more than: + * 2 char, 2 char, 2 char, frac_sec length. + * We *do* want the offset_separator to give us a partial for the + * last characters if there were not enough provided in the input string. */ + bool wrap_off = false; + bool ret_part = true; + boost::offset_separator osf(offsets, offsets+4, wrap_off, ret_part); + typedef boost::tokenizer::const_iterator, + std::basic_string > tokenizer; + typedef boost::tokenizer::const_iterator, + std::basic_string >::iterator tokenizer_iterator; + tokenizer tok(remain, osf); + for(tokenizer_iterator ti=tok.begin(); ti!=tok.end();++ti){ + switch(pos) { + case 0: + { + hours = boost::lexical_cast(*ti); + break; + } + case 1: + { + min = boost::lexical_cast(*ti); + break; + } + case 2: + { + sec = boost::lexical_cast(*ti); + break; + } + case 3: + { + std::string char_digits(ti->substr(1)); // digits w/no decimal + int digits = static_cast(char_digits.length()); + + //Works around a bug in MSVC 6 library that does not support + //operator>> thus meaning lexical_cast will fail to compile. +#if (defined(BOOST_MSVC) && (_MSC_VER <= 1200)) // 1200 == VC++ 6.0 + // _atoi64 is an MS specific function + if(digits >= precision) { + // drop excess digits + fs = _atoi64(char_digits.substr(0, precision).c_str()); + } + else if(digits == 0) { + fs = 0; // just in case _atoi64 doesn't like an empty string + } + else { + fs = _atoi64(char_digits.c_str()); + } +#else + if(digits >= precision) { + // drop excess digits + fs = boost::lexical_cast(char_digits.substr(0, precision)); + } + else if(digits == 0) { + fs = 0; // lexical_cast doesn't like empty strings + } + else { + fs = boost::lexical_cast(char_digits); + } +#endif + if(digits < precision){ + // trailing zeros get dropped from the string, + // "1:01:01.1" would yield .000001 instead of .100000 + // the power() compensates for the missing decimal places + fs *= power(10, precision - digits); + } + + break; + } + default: break; + } + pos++; + } + if(sign) { + return -time_duration(hours, min, sec, fs); + } + else { + return time_duration(hours, min, sec, fs); + } + } + + //! Parse time string of form YYYYMMDDThhmmss where T is delimeter between date and time + template + inline + time_type + parse_iso_time(const std::string& s, char sep) + { + typedef typename time_type::time_duration_type time_duration; + typedef typename time_type::date_type date_type; + typedef special_values_parser svp_type; + + // given to_iso_string can produce a special value string + // then from_iso_string should be able to read a special value string + // the special_values_parser is expensive to set up and not thread-safe + // so it cannot be static, so we need to be careful about when we use it + if (svp_type::likely(s)) { + typedef typename svp_type::stringstream_type ss_type; + typedef typename svp_type::stream_itr_type itr_type; + typedef typename svp_type::match_results mr_type; + svp_type p; // expensive + mr_type mr; + ss_type ss(s); + itr_type itr(ss); + itr_type end; + if (p.match(itr, end, mr)) { + return time_type(static_cast(mr.current_match)); + } + } + + //split date/time on a unique delimiter char such as ' ' or 'T' + std::string date_string, tod_string; + split(s, sep, date_string, tod_string); + //call parse_date with first string + date_type d = parse_undelimited_date(date_string); + //call parse_time_duration with remaining string + time_duration td = parse_undelimited_time_duration(tod_string); + //construct a time + return time_type(d, td); + } + +} }//namespace date_time + +#endif diff --git a/src/vendor/boost/date_time/time_resolution_traits.hpp b/src/vendor/boost/date_time/time_resolution_traits.hpp new file mode 100644 index 000000000..6b4718022 --- /dev/null +++ b/src/vendor/boost/date_time/time_resolution_traits.hpp @@ -0,0 +1,167 @@ +#ifndef DATE_TIME_TIME_RESOLUTION_TRAITS_HPP +#define DATE_TIME_TIME_RESOLUTION_TRAITS_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! Simple function to calculate absolute value of a numeric type + template + // JDG [7/6/02 made a template], + // moved here from time_duration.hpp 2003-Sept-4. + inline BOOST_CXX14_CONSTEXPR T absolute_value(T x) + { + return x < 0 ? -x : x; + } + + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_bi32_impl { + typedef boost::int32_t int_type; + typedef boost::int32_t impl_type; + static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i;} + //! Used to determine if implemented type is int_adapter or int + static BOOST_CXX14_CONSTEXPR bool is_adapted() { return false;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_adapted32_impl { + typedef boost::int32_t int_type; + typedef boost::date_time::int_adapter impl_type; + static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i.as_number();} + //! Used to determine if implemented type is int_adapter or int + static BOOST_CXX14_CONSTEXPR bool is_adapted() { return true;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_bi64_impl { + typedef boost::int64_t int_type; + typedef boost::int64_t impl_type; + static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i;} + //! Used to determine if implemented type is int_adapter or int + static BOOST_CXX14_CONSTEXPR bool is_adapted() { return false;} + }; + //! traits struct for time_resolution_traits implementation type + struct time_resolution_traits_adapted64_impl { + typedef boost::int64_t int_type; + typedef boost::date_time::int_adapter impl_type; + static BOOST_CXX14_CONSTEXPR int_type as_number(impl_type i){ return i.as_number();} + //! Used to determine if implemented type is int_adapter or int + static BOOST_CXX14_CONSTEXPR bool is_adapted() { return true;} + }; + + // + // Note about var_type, which is used to define the variable that + // stores hours, minutes, and seconds values: + // + // In Boost 1.65.1 and earlier var_type was boost::int32_t which suffers + // the year 2038 problem. Binary serialization of posix_time uses + // 32-bit values, and uses serialization version 0. + // + // In Boost 1.66.0 the var_type changed to std::time_t, however + // binary serialization was not properly versioned, so on platforms + // where std::time_t is 32-bits, it remains compatible, however on + // platforms where std::time_t is 64-bits, binary serialization ingest + // will be incompatible with previous versions. Furthermore, binary + // serialized output from 1.66.0 will not be compatible with future + // versions. Yes, it's a mess. Static assertions were not present + // in the serialization code to protect against this possibility. + // + // In Boost 1.67.0 the var_type was changed to boost::int64_t, + // ensuring the output size is 64 bits, and the serialization version + // was bumped. Static assertions were added as well, protecting + // future changes in this area. + // + + template // see note above + class time_resolution_traits { + public: + typedef typename frac_sec_type::int_type fractional_seconds_type; + typedef typename frac_sec_type::int_type tick_type; + typedef typename frac_sec_type::impl_type impl_type; + typedef var_type day_type; + typedef var_type hour_type; + typedef var_type min_type; + typedef var_type sec_type; + + // bring in function from frac_sec_type traits structs + static BOOST_CXX14_CONSTEXPR fractional_seconds_type as_number(impl_type i) + { + return frac_sec_type::as_number(i); + } + static BOOST_CXX14_CONSTEXPR bool is_adapted() + { + return frac_sec_type::is_adapted(); + } + + //Would like this to be frac_sec_type, but some compilers complain +#if (defined(BOOST_MSVC) && (_MSC_VER < 1300)) + BOOST_STATIC_CONSTANT(boost::int64_t, ticks_per_second = resolution_adjust); +#else + BOOST_STATIC_CONSTANT(fractional_seconds_type, ticks_per_second = resolution_adjust); +#endif + + static BOOST_CXX14_CONSTEXPR time_resolutions resolution() + { + return res; + } + static BOOST_CXX14_CONSTEXPR unsigned short num_fractional_digits() + { + return frac_digits; + } + static BOOST_CXX14_CONSTEXPR fractional_seconds_type res_adjust() + { + return resolution_adjust; + } + //! Any negative argument results in a negative tick_count + static BOOST_CXX14_CONSTEXPR tick_type to_tick_count(hour_type hours, + min_type minutes, + sec_type seconds, + fractional_seconds_type fs) + { + if(hours < 0 || minutes < 0 || seconds < 0 || fs < 0) + { + hours = absolute_value(hours); + minutes = absolute_value(minutes); + seconds = absolute_value(seconds); + fs = absolute_value(fs); + return static_cast(((((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs) * -1); + } + + return static_cast((((fractional_seconds_type(hours)*3600) + + (fractional_seconds_type(minutes)*60) + + seconds)*res_adjust()) + fs); + } + + }; + + typedef time_resolution_traits milli_res; + typedef time_resolution_traits micro_res; + typedef time_resolution_traits nano_res; + + +} } //namespace date_time + + + +#endif diff --git a/src/vendor/boost/date_time/time_system_counted.hpp b/src/vendor/boost/date_time/time_system_counted.hpp new file mode 100644 index 000000000..6c27aded7 --- /dev/null +++ b/src/vendor/boost/date_time/time_system_counted.hpp @@ -0,0 +1,269 @@ +#ifndef DATE_TIME_TIME_SYSTEM_COUNTED_HPP +#define DATE_TIME_TIME_SYSTEM_COUNTED_HPP + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include +#include + + +namespace boost { +namespace date_time { + + //! Time representation that uses a single integer count + template + struct counted_time_rep + { + typedef typename config::int_type int_type; + typedef typename config::date_type date_type; + typedef typename config::impl_type impl_type; + typedef typename date_type::duration_type date_duration_type; + typedef typename date_type::calendar_type calendar_type; + typedef typename date_type::ymd_type ymd_type; + typedef typename config::time_duration_type time_duration_type; + typedef typename config::resolution_traits resolution_traits; + + BOOST_CXX14_CONSTEXPR + counted_time_rep(const date_type& d, const time_duration_type& time_of_day) + : time_count_(1) + { + if(d.is_infinity() || d.is_not_a_date() || time_of_day.is_special()) { + time_count_ = time_of_day.get_rep() + d.day_count(); + //std::cout << time_count_ << std::endl; + } + else { + time_count_ = (d.day_number() * frac_sec_per_day()) + time_of_day.ticks(); + } + } + BOOST_CXX14_CONSTEXPR + explicit counted_time_rep(int_type count) : + time_count_(count) + {} + BOOST_CXX14_CONSTEXPR + explicit counted_time_rep(impl_type count) : + time_count_(count) + {} + BOOST_CXX14_CONSTEXPR + date_type date() const + { + if(time_count_.is_special()) { + return date_type(time_count_.as_special()); + } + else { + typename calendar_type::date_int_type dc = static_cast(day_count()); + //std::cout << "time_rep here:" << dc << std::endl; + ymd_type ymd = calendar_type::from_day_number(dc); + return date_type(ymd); + } + } + //int_type day_count() const + BOOST_CXX14_CONSTEXPR + unsigned long day_count() const + { + /* resolution_traits::as_number returns a boost::int64_t & + * frac_sec_per_day is also a boost::int64_t so, naturally, + * the division operation returns a boost::int64_t. + * The static_cast to an unsigned long is ok (results in no data loss) + * because frac_sec_per_day is either the number of + * microseconds per day, or the number of nanoseconds per day. + * Worst case scenario: resolution_traits::as_number returns the + * maximum value an int64_t can hold and frac_sec_per_day + * is microseconds per day (lowest possible value). + * The division operation will then return a value of 106751991 - + * easily fitting in an unsigned long. + */ + return static_cast(resolution_traits::as_number(time_count_) / frac_sec_per_day()); + } + BOOST_CXX14_CONSTEXPR int_type time_count() const + { + return resolution_traits::as_number(time_count_); + } + BOOST_CXX14_CONSTEXPR int_type tod() const + { + return resolution_traits::as_number(time_count_) % frac_sec_per_day(); + } + static BOOST_CXX14_CONSTEXPR int_type frac_sec_per_day() + { + int_type seconds_per_day = 60*60*24; + int_type fractional_sec_per_sec(resolution_traits::res_adjust()); + return seconds_per_day*fractional_sec_per_sec; + } + BOOST_CXX14_CONSTEXPR bool is_pos_infinity()const + { + return impl_type::is_pos_inf(time_count_.as_number()); + } + BOOST_CXX14_CONSTEXPR bool is_neg_infinity()const + { + return impl_type::is_neg_inf(time_count_.as_number()); + } + BOOST_CXX14_CONSTEXPR bool is_not_a_date_time()const + { + return impl_type::is_not_a_number(time_count_.as_number()); + } + BOOST_CXX14_CONSTEXPR bool is_special()const + { + return time_count_.is_special(); + } + BOOST_CXX14_CONSTEXPR impl_type get_rep()const + { + return time_count_; + } + private: + impl_type time_count_; + }; + + //! An unadjusted time system implementation. + template + class counted_time_system + { + public: + typedef time_rep time_rep_type; + typedef typename time_rep_type::impl_type impl_type; + typedef typename time_rep_type::time_duration_type time_duration_type; + typedef typename time_duration_type::fractional_seconds_type fractional_seconds_type; + typedef typename time_rep_type::date_type date_type; + typedef typename time_rep_type::date_duration_type date_duration_type; + + + template static BOOST_CXX14_CONSTEXPR void unused_var(const T&) {} + + static BOOST_CXX14_CONSTEXPR + time_rep_type get_time_rep(const date_type& day, + const time_duration_type& tod, + date_time::dst_flags dst=not_dst) + { + unused_var(dst); + return time_rep_type(day, tod); + } + + static BOOST_CXX14_CONSTEXPR time_rep_type get_time_rep(special_values sv) + { + switch (sv) { + case not_a_date_time: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + case pos_infin: + return time_rep_type(date_type(pos_infin), + time_duration_type(pos_infin)); + case neg_infin: + return time_rep_type(date_type(neg_infin), + time_duration_type(neg_infin)); + case max_date_time: { + time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); + return time_rep_type(date_type(max_date_time), td); + } + case min_date_time: + return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); + + default: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + + } + + } + + static BOOST_CXX14_CONSTEXPR date_type + get_date(const time_rep_type& val) + { + return val.date(); + } + static BOOST_CXX14_CONSTEXPR + time_duration_type get_time_of_day(const time_rep_type& val) + { + if(val.is_special()) { + return time_duration_type(val.get_rep().as_special()); + } + else{ + return time_duration_type(0,0,0,val.tod()); + } + } + static std::string zone_name(const time_rep_type&) + { + return ""; + } + static BOOST_CXX14_CONSTEXPR bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) + { + return (lhs.time_count() == rhs.time_count()); + } + static BOOST_CXX14_CONSTEXPR + bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) + { + return (lhs.time_count() < rhs.time_count()); + } + static BOOST_CXX14_CONSTEXPR + time_rep_type add_days(const time_rep_type& base, + const date_duration_type& dd) + { + if(base.is_special() || dd.is_special()) { + return(time_rep_type(base.get_rep() + dd.get_rep())); + } + else { + return time_rep_type(base.time_count() + (dd.days() * time_rep_type::frac_sec_per_day())); + } + } + static BOOST_CXX14_CONSTEXPR + time_rep_type subtract_days(const time_rep_type& base, + const date_duration_type& dd) + { + if(base.is_special() || dd.is_special()) { + return(time_rep_type(base.get_rep() - dd.get_rep())); + } + else{ + return time_rep_type(base.time_count() - (dd.days() * time_rep_type::frac_sec_per_day())); + } + } + static BOOST_CXX14_CONSTEXPR + time_rep_type subtract_time_duration(const time_rep_type& base, + const time_duration_type& td) + { + if(base.is_special() || td.is_special()) { + return(time_rep_type(base.get_rep() - td.get_rep())); + } + else { + return time_rep_type(base.time_count() - td.ticks()); + } + } + static BOOST_CXX14_CONSTEXPR + time_rep_type add_time_duration(const time_rep_type& base, + time_duration_type td) + { + if(base.is_special() || td.is_special()) { + return(time_rep_type(base.get_rep() + td.get_rep())); + } + else { + return time_rep_type(base.time_count() + td.ticks()); + } + } + static BOOST_CXX14_CONSTEXPR + time_duration_type subtract_times(const time_rep_type& lhs, + const time_rep_type& rhs) + { + if(lhs.is_special() || rhs.is_special()) { + return(time_duration_type( + impl_type::to_special((lhs.get_rep() - rhs.get_rep()).as_number()))); + } + else { + fractional_seconds_type fs = lhs.time_count() - rhs.time_count(); + return time_duration_type(0,0,0,fs); + } + } + + }; + + +} } //namespace date_time + + + +#endif + diff --git a/src/vendor/boost/date_time/time_system_split.hpp b/src/vendor/boost/date_time/time_system_split.hpp new file mode 100644 index 000000000..4da165379 --- /dev/null +++ b/src/vendor/boost/date_time/time_system_split.hpp @@ -0,0 +1,226 @@ +#ifndef DATE_TIME_TIME_SYSTEM_SPLIT_HPP +#define DATE_TIME_TIME_SYSTEM_SPLIT_HPP + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + + +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace date_time { + + //! An unadjusted time system implementation. +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) + template +#else + template +#endif + class split_timedate_system + { + public: + typedef typename config::time_rep_type time_rep_type; + typedef typename config::date_type date_type; + typedef typename config::time_duration_type time_duration_type; + typedef typename config::date_duration_type date_duration_type; + typedef typename config::int_type int_type; + typedef typename config::resolution_traits resolution_traits; + + //86400 is number of seconds in a day... +#if (defined(BOOST_DATE_TIME_NO_MEMBER_INIT)) + typedef date_time::wrapping_int wrap_int_type; +#else + private: + BOOST_STATIC_CONSTANT(int_type, ticks_per_day = INT64_C(86400) * config::tick_per_second); + public: +# if BOOST_WORKAROUND( BOOST_BORLANDC, BOOST_TESTED_AT(0X581) ) + typedef date_time::wrapping_int< split_timedate_system::int_type, split_timedate_system::ticks_per_day> wrap_int_type; +# else + typedef date_time::wrapping_int wrap_int_type; +#endif +#endif + + static + BOOST_CXX14_CONSTEXPR + time_rep_type get_time_rep(special_values sv) + { + switch (sv) { + case not_a_date_time: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + case pos_infin: + return time_rep_type(date_type(pos_infin), + time_duration_type(pos_infin)); + case neg_infin: + return time_rep_type(date_type(neg_infin), + time_duration_type(neg_infin)); + case max_date_time: { + time_duration_type td = time_duration_type(24,0,0,0) - time_duration_type(0,0,0,1); + return time_rep_type(date_type(max_date_time), td); + } + case min_date_time: + return time_rep_type(date_type(min_date_time), time_duration_type(0,0,0,0)); + + default: + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + + } + + } + + static + BOOST_CXX14_CONSTEXPR + time_rep_type get_time_rep(const date_type& day, + const time_duration_type& tod, + date_time::dst_flags /* dst */ = not_dst) + { + if(day.is_special() || tod.is_special()) { + if(day.is_not_a_date() || tod.is_not_a_date_time()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else if(day.is_pos_infinity()) { + if(tod.is_neg_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(day, time_duration_type(pos_infin)); + } + } + else if(day.is_neg_infinity()) { + if(tod.is_pos_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(day, time_duration_type(neg_infin)); + } + } + else if(tod.is_pos_infinity()) { + if(day.is_neg_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(date_type(pos_infin), tod); + } + } + else if(tod.is_neg_infinity()) { + if(day.is_pos_infinity()) { + return time_rep_type(date_type(not_a_date_time), + time_duration_type(not_a_date_time)); + } + else { + return time_rep_type(date_type(neg_infin), tod); + } + } + } + return time_rep_type(day, tod); + } + static BOOST_CONSTEXPR date_type get_date(const time_rep_type& val) + { + return date_type(val.day); + } + static BOOST_CONSTEXPR time_duration_type get_time_of_day(const time_rep_type& val) + { + return time_duration_type(val.time_of_day); + } + static std::string zone_name(const time_rep_type&) + { + return std::string(); + } + static BOOST_CONSTEXPR + bool is_equal(const time_rep_type& lhs, const time_rep_type& rhs) + { + return ((lhs.day == rhs.day) && (lhs.time_of_day == rhs.time_of_day)); + } + static BOOST_CXX14_CONSTEXPR + bool is_less(const time_rep_type& lhs, const time_rep_type& rhs) + { + if (lhs.day < rhs.day) return true; + if (lhs.day > rhs.day) return false; + return (lhs.time_of_day < rhs.time_of_day); + } + static BOOST_CXX14_CONSTEXPR + time_rep_type add_days(const time_rep_type& base, + const date_duration_type& dd) + { + return time_rep_type(base.day+dd, base.time_of_day); + } + static BOOST_CXX14_CONSTEXPR + time_rep_type subtract_days(const time_rep_type& base, + const date_duration_type& dd) + { + return split_timedate_system::get_time_rep(base.day-dd, base.time_of_day); + } + static BOOST_CXX14_CONSTEXPR + time_rep_type subtract_time_duration(const time_rep_type& base, + const time_duration_type& td) + { + if(base.day.is_special() || td.is_special()) + { + return split_timedate_system::get_time_rep(base.day, -td); + } + if (td.is_negative()) { + time_duration_type td1 = td.invert_sign(); + return add_time_duration(base,td1); + } + + wrap_int_type day_offset(base.time_of_day.ticks()); + date_duration_type day_overflow(static_cast(day_offset.subtract(td.ticks()))); + + return time_rep_type(base.day-day_overflow, + time_duration_type(0,0,0,day_offset.as_int())); + } + static BOOST_CXX14_CONSTEXPR + time_rep_type add_time_duration(const time_rep_type& base, + time_duration_type td) + { + if(base.day.is_special() || td.is_special()) { + return split_timedate_system::get_time_rep(base.day, td); + } + if (td.is_negative()) { + time_duration_type td1 = td.invert_sign(); + return subtract_time_duration(base,td1); + } + + wrap_int_type day_offset(base.time_of_day.ticks()); + date_duration_type day_overflow(static_cast< typename date_duration_type::duration_rep_type >(day_offset.add(td.ticks()))); + + return time_rep_type(base.day+day_overflow, + time_duration_type(0,0,0,day_offset.as_int())); + } + static BOOST_CXX14_CONSTEXPR + time_duration_type subtract_times(const time_rep_type& lhs, + const time_rep_type& rhs) + { + date_duration_type dd = lhs.day - rhs.day; + if (BOOST_LIKELY(!dd.is_special())) { + time_duration_type td(dd.days()*24,0,0); // days * 24 hours + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + } else { + time_duration_type td(dd.as_special()); + time_duration_type td2 = lhs.time_of_day - rhs.time_of_day; + return td+td2; + } + } + + }; + +} } //namespace date_time + + +#endif diff --git a/src/vendor/boost/date_time/wrapping_int.hpp b/src/vendor/boost/date_time/wrapping_int.hpp new file mode 100644 index 000000000..a3df21a21 --- /dev/null +++ b/src/vendor/boost/date_time/wrapping_int.hpp @@ -0,0 +1,170 @@ +#ifndef _DATE_TIME_WRAPPING_INT_HPP__ +#define _DATE_TIME_WRAPPING_INT_HPP__ + +/* Copyright (c) 2002,2003,2005 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland, Bart Garst + * $Date$ + */ + +#include "boost/config.hpp" + +namespace boost { +namespace date_time { + +//! A wrapping integer used to support time durations (WARNING: only instantiate with a signed type) +/*! In composite date and time types this type is used to + * wrap at the day boundary. + * Ex: + * A wrapping_int will roll over after nine, and + * roll under below zero. This gives a range of [0,9] + * + * NOTE: it is strongly recommended that wrapping_int2 be used + * instead of wrapping_int as wrapping_int is to be depricated + * at some point soon. + * + * Also Note that warnings will occur if instantiated with an + * unsigned type. Only a signed type should be used! + */ +template +class wrapping_int { +public: + typedef int_type_ int_type; + //typedef overflow_type_ overflow_type; + static BOOST_CONSTEXPR int_type wrap_value() {return wrap_val;} + //!Add, return true if wrapped + BOOST_CXX14_CONSTEXPR wrapping_int(int_type v) : value_(v) {} + //! Explicit converion method + BOOST_CONSTEXPR int_type as_int() const {return value_;} + BOOST_CONSTEXPR operator int_type() const {return value_;} + //!Add, return number of wraps performed + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: add a negative number and wrapping under could occur, + * this would be indicated by a negative return value. If wrapping over + * took place, a positive value would be returned */ + template< typename IntT > + BOOST_CXX14_CONSTEXPR IntT add(IntT v) + { + int_type remainder = static_cast(v % (wrap_val)); + IntT overflow = static_cast(v / (wrap_val)); + value_ = static_cast(value_ + remainder); + return calculate_wrap(overflow); + } + //! Subtract will return '+d' if wrapping under took place ('d' is the number of wraps) + /*! The sign of the returned value will indicate which direction the + * wraps went (positive indicates wrap under, negative indicates wrap over). + * Ex: subtract a negative number and wrapping over could + * occur, this would be indicated by a negative return value. If + * wrapping under took place, a positive value would be returned. */ + template< typename IntT > + BOOST_CXX14_CONSTEXPR IntT subtract(IntT v) + { + int_type remainder = static_cast(v % (wrap_val)); + IntT underflow = static_cast(-(v / (wrap_val))); + value_ = static_cast(value_ - remainder); + return calculate_wrap(underflow) * -1; + } +private: + int_type value_; + + template< typename IntT > + BOOST_CXX14_CONSTEXPR IntT calculate_wrap(IntT wrap) + { + if ((value_) >= wrap_val) + { + ++wrap; + value_ -= (wrap_val); + } + else if(value_ < 0) + { + --wrap; + value_ += (wrap_val); + } + return wrap; + } + +}; + + +//! A wrapping integer used to wrap around at the top (WARNING: only instantiate with a signed type) +/*! Bad name, quick impl to fix a bug -- fix later!! + * This allows the wrap to restart at a value other than 0. + */ +template +class wrapping_int2 { +public: + typedef int_type_ int_type; + static BOOST_CONSTEXPR int_type wrap_value() {return wrap_max;} + static BOOST_CONSTEXPR int_type min_value() {return wrap_min;} + /*! If initializing value is out of range of [wrap_min, wrap_max], + * value will be initialized to closest of min or max */ + BOOST_CXX14_CONSTEXPR wrapping_int2(int_type v) : value_(v) { + if(value_ < wrap_min) + { + value_ = wrap_min; + } + if(value_ > wrap_max) + { + value_ = wrap_max; + } + } + //! Explicit converion method + BOOST_CONSTEXPR int_type as_int() const {return value_;} + BOOST_CONSTEXPR operator int_type() const {return value_;} + //!Add, return number of wraps performed + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: add a negative number and wrapping under could occur, + * this would be indicated by a negative return value. If wrapping over + * took place, a positive value would be returned */ + template< typename IntT > + BOOST_CXX14_CONSTEXPR IntT add(IntT v) + { + int_type remainder = static_cast(v % (wrap_max - wrap_min + 1)); + IntT overflow = static_cast(v / (wrap_max - wrap_min + 1)); + value_ = static_cast(value_ + remainder); + return calculate_wrap(overflow); + } + //! Subtract will return '-d' if wrapping under took place ('d' is the number of wraps) + /*! The sign of the returned value will indicate which direction the + * wraps went. Ex: subtract a negative number and wrapping over could + * occur, this would be indicated by a positive return value. If + * wrapping under took place, a negative value would be returned */ + template< typename IntT > + BOOST_CXX14_CONSTEXPR IntT subtract(IntT v) + { + int_type remainder = static_cast(v % (wrap_max - wrap_min + 1)); + IntT underflow = static_cast(-(v / (wrap_max - wrap_min + 1))); + value_ = static_cast(value_ - remainder); + return calculate_wrap(underflow); + } + +private: + int_type value_; + + template< typename IntT > + BOOST_CXX14_CONSTEXPR IntT calculate_wrap(IntT wrap) + { + if ((value_) > wrap_max) + { + ++wrap; + value_ -= (wrap_max - wrap_min + 1); + } + else if((value_) < wrap_min) + { + --wrap; + value_ += (wrap_max - wrap_min + 1); + } + return wrap; + } +}; + + + +} } //namespace date_time + + + +#endif + diff --git a/src/vendor/boost/date_time/year_month_day.hpp b/src/vendor/boost/date_time/year_month_day.hpp new file mode 100644 index 000000000..be473b8a9 --- /dev/null +++ b/src/vendor/boost/date_time/year_month_day.hpp @@ -0,0 +1,49 @@ +#ifndef YearMonthDayBase_HPP__ +#define YearMonthDayBase_HPP__ + +/* Copyright (c) 2002,2003 CrystalClear Software, Inc. + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + * Author: Jeff Garland + * $Date$ + */ + +#include + +namespace boost { +namespace date_time { + + //! Allow rapid creation of ymd triples of different types + template + struct BOOST_SYMBOL_VISIBLE year_month_day_base { + BOOST_CXX14_CONSTEXPR + year_month_day_base(YearType year, + MonthType month, + DayType day); + + YearType year; + MonthType month; + DayType day; + typedef YearType year_type; + typedef MonthType month_type; + typedef DayType day_type; + }; + + + //! A basic constructor + template + inline BOOST_CXX14_CONSTEXPR + year_month_day_base::year_month_day_base(YearType y, + MonthType m, + DayType d) : + year(y), + month(m), + day(d) + {} + +} }//namespace date_time + + +#endif + diff --git a/src/vendor/boost/detail/basic_pointerbuf.hpp b/src/vendor/boost/detail/basic_pointerbuf.hpp new file mode 100644 index 000000000..a92a489fc --- /dev/null +++ b/src/vendor/boost/detail/basic_pointerbuf.hpp @@ -0,0 +1,138 @@ +//----------------------------------------------------------------------------- +// boost detail/templated_streams.hpp header file +// See http://www.boost.org for updates, documentation, and revision history. +//----------------------------------------------------------------------------- +// +// Copyright (c) 2013 John Maddock, Antony Polukhin +// +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_BASIC_POINTERBUF_HPP +#define BOOST_DETAIL_BASIC_POINTERBUF_HPP + +// MS compatible compilers support #pragma once +#if defined(_MSC_VER) +# pragma once +#endif + +#include "boost/config.hpp" +#include + +namespace boost { namespace detail { + +// +// class basic_pointerbuf: +// acts as a stream buffer which wraps around a pair of pointers: +// +template +class basic_pointerbuf : public BufferT { +protected: + typedef BufferT base_type; + typedef basic_pointerbuf this_type; + typedef typename base_type::int_type int_type; + typedef typename base_type::char_type char_type; + typedef typename base_type::pos_type pos_type; + typedef ::std::streamsize streamsize; + typedef typename base_type::off_type off_type; + +public: + basic_pointerbuf() : base_type() { this_type::setbuf(0, 0); } + const charT* getnext() { return this->gptr(); } + +#ifndef BOOST_NO_USING_TEMPLATE + using base_type::pptr; + using base_type::pbase; +#else + charT* pptr() const { return base_type::pptr(); } + charT* pbase() const { return base_type::pbase(); } +#endif + +protected: + // VC mistakenly assumes that `setbuf` and other functions are not referenced. + // Marking those functions with `inline` suppresses the warnings. + // There must be no harm from marking virtual functions as inline: inline virtual + // call can be inlined ONLY when the compiler knows the "exact class". + inline base_type* setbuf(char_type* s, streamsize n) BOOST_OVERRIDE; + inline typename this_type::pos_type seekpos(pos_type sp, ::std::ios_base::openmode which) BOOST_OVERRIDE; + inline typename this_type::pos_type seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) BOOST_OVERRIDE; + +private: + basic_pointerbuf& operator=(const basic_pointerbuf&); + basic_pointerbuf(const basic_pointerbuf&); +}; + +template +BufferT* +basic_pointerbuf::setbuf(char_type* s, streamsize n) +{ + this->setg(s, s, s + n); + return this; +} + +template +typename basic_pointerbuf::pos_type +basic_pointerbuf::seekoff(off_type off, ::std::ios_base::seekdir way, ::std::ios_base::openmode which) +{ + typedef typename boost::int_t::least cast_type; + + if(which & ::std::ios_base::out) + return pos_type(off_type(-1)); + std::ptrdiff_t size = this->egptr() - this->eback(); + std::ptrdiff_t pos = this->gptr() - this->eback(); + charT* g = this->eback(); + switch(static_cast(way)) + { + case ::std::ios_base::beg: + if((off < 0) || (off > size)) + return pos_type(off_type(-1)); + else + this->setg(g, g + off, g + size); + break; + case ::std::ios_base::end: + if((off < 0) || (off > size)) + return pos_type(off_type(-1)); + else + this->setg(g, g + size - off, g + size); + break; + case ::std::ios_base::cur: + { + std::ptrdiff_t newpos = static_cast(pos + off); + if((newpos < 0) || (newpos > size)) + return pos_type(off_type(-1)); + else + this->setg(g, g + newpos, g + size); + break; + } + default: ; + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + return static_cast(this->gptr() - this->eback()); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +} + +template +typename basic_pointerbuf::pos_type +basic_pointerbuf::seekpos(pos_type sp, ::std::ios_base::openmode which) +{ + if(which & ::std::ios_base::out) + return pos_type(off_type(-1)); + off_type size = static_cast(this->egptr() - this->eback()); + charT* g = this->eback(); + if(off_type(sp) <= size) + { + this->setg(g, g + off_type(sp), g + size); + } + return pos_type(off_type(-1)); +} + +}} // namespace boost::detail + +#endif // BOOST_DETAIL_BASIC_POINTERBUF_HPP diff --git a/src/vendor/boost/detail/call_traits.hpp b/src/vendor/boost/detail/call_traits.hpp new file mode 100644 index 000000000..feca93da3 --- /dev/null +++ b/src/vendor/boost/detail/call_traits.hpp @@ -0,0 +1,172 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// call_traits: defines typedefs for function usage +// (see libs/utility/call_traits.htm) + +/* Release notes: + 23rd July 2000: + Fixed array specialization. (JM) + Added Borland specific fixes for reference types + (issue raised by Steve Cleary). +*/ + +#ifndef BOOST_DETAIL_CALL_TRAITS_HPP +#define BOOST_DETAIL_CALL_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +#include +#endif +#include + +#include +#include +#include +#include + +namespace boost{ + +namespace detail{ + +template +struct ct_imp2 +{ + typedef const T& param_type; +}; + +template +struct ct_imp2 +{ + typedef const T param_type; +}; + +template +struct ct_imp +{ + typedef const T& param_type; +}; + +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp +{ + typedef typename ct_imp2::param_type param_type; +}; + +template +struct ct_imp +{ + typedef const T param_type; +}; + +} + +template +struct call_traits +{ +public: + typedef T value_type; + typedef T& reference; + typedef const T& const_reference; + // + // C++ Builder workaround: we should be able to define a compile time + // constant and pass that as a single template parameter to ct_imp, + // however compiler bugs prevent this - instead pass three bool's to + // ct_imp and add an extra partial specialisation + // of ct_imp to handle the logic. (JM) + typedef typename boost::detail::ct_imp< + T, + ::boost::is_pointer::value, + ::boost::is_arithmetic::value, + ::boost::is_enum::value + >::param_type param_type; +}; + +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +#if BOOST_WORKAROUND( BOOST_BORLANDC, < 0x5A0 ) +// these are illegal specialisations; cv-qualifies applied to +// references have no effect according to [8.3.2p1], +// C++ Builder requires them though as it treats cv-qualified +// references as distinct types... +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; +template +struct call_traits +{ + typedef T& value_type; + typedef T& reference; + typedef const T& const_reference; + typedef T& param_type; // hh removed const +}; + +template +struct call_traits< T * > +{ + typedef T * value_type; + typedef T * & reference; + typedef T * const & const_reference; + typedef T * const param_type; // hh removed const +}; +#endif +#if !defined(BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS) +template +struct call_traits +{ +private: + typedef T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; + +template +struct call_traits +{ +private: + typedef const T array_type[N]; +public: + // degrades array to pointer: + typedef const T* value_type; + typedef array_type& reference; + typedef const array_type& const_reference; + typedef const T* const param_type; +}; +#endif + +} + +#endif // BOOST_DETAIL_CALL_TRAITS_HPP diff --git a/src/vendor/boost/detail/compressed_pair.hpp b/src/vendor/boost/detail/compressed_pair.hpp new file mode 100644 index 000000000..b090a727d --- /dev/null +++ b/src/vendor/boost/detail/compressed_pair.hpp @@ -0,0 +1,452 @@ +// (C) Copyright Steve Cleary, Beman Dawes, Howard Hinnant & John Maddock 2000. +// Use, modification and distribution are subject to the Boost Software License, +// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt). +// +// See http://www.boost.org/libs/utility for most recent version including documentation. + +// compressed_pair: pair that "compresses" empty members +// (see libs/utility/doc/html/compressed_pair.html) +// +// JM changes 25 Jan 2004: +// For the case where T1 == T2 and both are empty, then first() and second() +// should return different objects. +// JM changes 25 Jan 2000: +// Removed default arguments from compressed_pair_switch to get +// C++ Builder 4 to accept them +// rewriten swap to get gcc and C++ builder to compile. +// added partial specialisations for case T1 == T2 to avoid duplicate constructor defs. + +#ifndef BOOST_DETAIL_COMPRESSED_PAIR_HPP +#define BOOST_DETAIL_COMPRESSED_PAIR_HPP + +#include + +#include +#include +#include +#include +#include + +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4512) +#endif +namespace boost +{ + +template +class compressed_pair; + + +// compressed_pair + +namespace details +{ + template::value> + struct compressed_pair_empty + : ::boost::false_type { }; + + template + struct compressed_pair_empty + : ::boost::is_empty { }; + + // JM altered 26 Jan 2000: + template + struct compressed_pair_switch; + + template + struct compressed_pair_switch + {static const int value = 0;}; + + template + struct compressed_pair_switch + {static const int value = 3;}; + + template + struct compressed_pair_switch + {static const int value = 1;}; + + template + struct compressed_pair_switch + {static const int value = 2;}; + + template + struct compressed_pair_switch + {static const int value = 4;}; + + template + struct compressed_pair_switch + {static const int value = 5;}; + + template class compressed_pair_imp; + +#ifdef __GNUC__ + // workaround for GCC (JM): + using std::swap; +#endif + // + // can't call unqualified swap from within classname::swap + // as Koenig lookup rules will find only the classname::swap + // member function not the global declaration, so use cp_swap + // as a forwarding function (JM): + template + inline void cp_swap(T& t1, T& t2) + { +#ifndef __GNUC__ + using std::swap; +#endif + swap(t1, t2); + } + + // 0 derive from neither + + template + class compressed_pair_imp + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_(x) {} + + compressed_pair_imp(second_param_type y) + : second_(y) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + cp_swap(first_, y.first()); + cp_swap(second_, y.second()); + } + private: + first_type first_; + second_type second_; + }; + + // 1 derive from T1 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x) {} + + compressed_pair_imp(second_param_type y) + : second_(y) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + // no need to swap empty base class: + cp_swap(second_, y.second()); + } + private: + second_type second_; + }; + + // 2 derive from T2 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : second_type(y), first_(x) {} + + compressed_pair_imp(first_param_type x) + : first_(x) {} + + compressed_pair_imp(second_param_type y) + : second_type(y) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return *this;} + second_const_reference second() const {return *this;} + + void swap(::boost::compressed_pair& y) + { + // no need to swap empty base class: + cp_swap(first_, y.first()); + } + + private: + first_type first_; + }; + + // 3 derive from T1 and T2 + + template + class compressed_pair_imp + : protected ::boost::remove_cv::type, + protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), second_type(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x) {} + + compressed_pair_imp(second_param_type y) + : second_type(y) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return *this;} + second_const_reference second() const {return *this;} + // + // no need to swap empty bases: + void swap(::boost::compressed_pair&) {} + }; + + // JM + // 4 T1 == T2, T1 and T2 both empty + // Originally this did not store an instance of T2 at all + // but that led to problems beause it meant &x.first() == &x.second() + // which is not true for any other kind of pair, so now we store an instance + // of T2 just in case the user is relying on first() and second() returning + // different objects (albeit both empty). + template + class compressed_pair_imp + : protected ::boost::remove_cv::type + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_type(x), m_second(y) {} + + compressed_pair_imp(first_param_type x) + : first_type(x), m_second(x) {} + + first_reference first() {return *this;} + first_const_reference first() const {return *this;} + + second_reference second() {return m_second;} + second_const_reference second() const {return m_second;} + + void swap(::boost::compressed_pair&) {} + private: + T2 m_second; + }; + + // 5 T1 == T2 and are not empty: //JM + + template + class compressed_pair_imp + { + public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair_imp() {} + + compressed_pair_imp(first_param_type x, second_param_type y) + : first_(x), second_(y) {} + + compressed_pair_imp(first_param_type x) + : first_(x), second_(x) {} + + first_reference first() {return first_;} + first_const_reference first() const {return first_;} + + second_reference second() {return second_;} + second_const_reference second() const {return second_;} + + void swap(::boost::compressed_pair& y) + { + cp_swap(first_, y.first()); + cp_swap(second_, y.second()); + } + private: + first_type first_; + second_type second_; + }; + +} // details + +template +class compressed_pair + : private ::boost::details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::details::compressed_pair_empty::value, + ::boost::details::compressed_pair_empty::value>::value> +{ +private: + typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::details::compressed_pair_empty::value, + ::boost::details::compressed_pair_empty::value>::value> base; +public: + typedef T1 first_type; + typedef T2 second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base() {} + compressed_pair(first_param_type x, second_param_type y) : base(x, y) {} + explicit compressed_pair(first_param_type x) : base(x) {} + explicit compressed_pair(second_param_type y) : base(y) {} + + first_reference first() {return base::first();} + first_const_reference first() const {return base::first();} + + second_reference second() {return base::second();} + second_const_reference second() const {return base::second();} + + void swap(compressed_pair& y) { base::swap(y); } +}; + +// JM +// Partial specialisation for case where T1 == T2: +// +template +class compressed_pair + : private details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::details::compressed_pair_empty::value, + ::boost::details::compressed_pair_empty::value>::value> +{ +private: + typedef details::compressed_pair_imp::type, typename remove_cv::type>::value, + ::boost::details::compressed_pair_empty::value, + ::boost::details::compressed_pair_empty::value>::value> base; +public: + typedef T first_type; + typedef T second_type; + typedef typename call_traits::param_type first_param_type; + typedef typename call_traits::param_type second_param_type; + typedef typename call_traits::reference first_reference; + typedef typename call_traits::reference second_reference; + typedef typename call_traits::const_reference first_const_reference; + typedef typename call_traits::const_reference second_const_reference; + + compressed_pair() : base() {} + compressed_pair(first_param_type x, second_param_type y) : base(x, y) {} +#if !(defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)) + explicit +#endif + compressed_pair(first_param_type x) : base(x) {} + + first_reference first() {return base::first();} + first_const_reference first() const {return base::first();} + + second_reference second() {return base::second();} + second_const_reference second() const {return base::second();} + + void swap(::boost::compressed_pair& y) { base::swap(y); } +}; + +template +inline +void +swap(compressed_pair& x, compressed_pair& y) +{ + x.swap(y); +} + +} // boost + +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // BOOST_DETAIL_COMPRESSED_PAIR_HPP + diff --git a/src/vendor/boost/detail/indirect_traits.hpp b/src/vendor/boost/detail/indirect_traits.hpp new file mode 100644 index 000000000..94e9b34dc --- /dev/null +++ b/src/vendor/boost/detail/indirect_traits.hpp @@ -0,0 +1,195 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef INDIRECT_TRAITS_DWA2002131_HPP +# define INDIRECT_TRAITS_DWA2002131_HPP +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include + + +namespace boost { namespace detail { + +namespace indirect_traits { + +template +struct is_reference_to_const : boost::false_type +{ +}; + +template +struct is_reference_to_const : boost::true_type +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_const : boost::true_type +{ +}; +# endif + +template +struct is_reference_to_function : boost::false_type +{ +}; + +template +struct is_reference_to_function : is_function +{ +}; + +template +struct is_pointer_to_function : boost::false_type +{ +}; + +// There's no such thing as a pointer-to-cv-function, so we don't need +// specializations for those +template +struct is_pointer_to_function : is_function +{ +}; + +template +struct is_reference_to_member_function_pointer_impl : boost::false_type +{ +}; + +template +struct is_reference_to_member_function_pointer_impl + : is_member_function_pointer::type> +{ +}; + + +template +struct is_reference_to_member_function_pointer + : is_reference_to_member_function_pointer_impl +{ +}; + +template +struct is_reference_to_function_pointer_aux + : boost::integral_constant::value && + is_pointer_to_function< + typename remove_cv< + typename remove_reference::type + >::type + >::value + > +{ + // There's no such thing as a pointer-to-cv-function, so we don't need specializations for those +}; + +template +struct is_reference_to_function_pointer + : boost::detail::if_true< + is_reference_to_function::value + >::template then< + boost::false_type + , is_reference_to_function_pointer_aux + >::type +{ +}; + +template +struct is_reference_to_non_const + : boost::integral_constant::value && + !is_reference_to_const::value + > +{ +}; + +template +struct is_reference_to_volatile : boost::false_type +{ +}; + +template +struct is_reference_to_volatile : boost::true_type +{ +}; + +# if defined(BOOST_MSVC) && _MSC_FULL_VER <= 13102140 // vc7.01 alpha workaround +template +struct is_reference_to_volatile : boost::true_type +{ +}; +# endif + + +template +struct is_reference_to_pointer : boost::false_type +{ +}; + +template +struct is_reference_to_pointer : boost::true_type +{ +}; + +template +struct is_reference_to_pointer : boost::true_type +{ +}; + +template +struct is_reference_to_pointer : boost::true_type +{ +}; + +template +struct is_reference_to_pointer : boost::true_type +{ +}; + +template +struct is_reference_to_class + : boost::integral_constant::value && + is_class< + typename remove_cv< + typename remove_reference::type + >::type + >::value + > +{ +}; + +template +struct is_pointer_to_class + : boost::integral_constant::value && + is_class< + typename remove_cv< + typename remove_pointer::type + >::type + >::value + > +{ +}; + + +} + +using namespace indirect_traits; + +}} // namespace boost::python::detail + +#endif // INDIRECT_TRAITS_DWA2002131_HPP diff --git a/src/vendor/boost/detail/is_incrementable.hpp b/src/vendor/boost/detail/is_incrementable.hpp new file mode 100644 index 000000000..fa70cf2ed --- /dev/null +++ b/src/vendor/boost/detail/is_incrementable.hpp @@ -0,0 +1,121 @@ +// Copyright David Abrahams 2004. Use, modification and distribution is +// subject to the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +#ifndef IS_INCREMENTABLE_DWA200415_HPP +# define IS_INCREMENTABLE_DWA200415_HPP + +# include +# include +# include + +namespace boost { namespace detail { + +// is_incrementable metafunction +// +// Requires: Given x of type T&, if the expression ++x is well-formed +// it must have complete type; otherwise, it must neither be ambiguous +// nor violate access. + +// This namespace ensures that ADL doesn't mess things up. +namespace is_incrementable_ +{ + // a type returned from operator++ when no increment is found in the + // type's own namespace + struct tag {}; + + // any soaks up implicit conversions and makes the following + // operator++ less-preferred than any other such operator that + // might be found via ADL. + struct any { template any(T const&); }; + + // This is a last-resort operator++ for when none other is found +# if BOOST_WORKAROUND(__GNUC__, == 4) && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 2 + +} + +namespace is_incrementable_2 +{ + is_incrementable_::tag operator++(is_incrementable_::any const&); + is_incrementable_::tag operator++(is_incrementable_::any const&,int); +} +using namespace is_incrementable_2; + +namespace is_incrementable_ +{ + +# else + + tag operator++(any const&); + tag operator++(any const&,int); + +# endif + +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) +# define BOOST_comma(a,b) (a) +# else + // In case an operator++ is found that returns void, we'll use ++x,0 + tag operator,(tag,int); +# define BOOST_comma(a,b) (a,b) +# endif + +# if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4913) // Warning about operator, +# endif + + // two check overloads help us identify which operator++ was picked + char (& check_(tag) )[2]; + + template + char check_(T const&); + + + template + struct impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check_(BOOST_comma(++x,0))) == 1 + ); + }; + + template + struct postfix_impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_incrementable_::check_(BOOST_comma(x++,0))) == 1 + ); + }; + +# if defined(BOOST_MSVC) +# pragma warning(pop) +# endif + +} + +# undef BOOST_comma + +template +struct is_incrementable : + public boost::integral_constant::value> +{ +}; + +template +struct is_postfix_incrementable : + public boost::integral_constant::value> +{ +}; + +} // namespace detail + +} // namespace boost + +# include + +#endif // IS_INCREMENTABLE_DWA200415_HPP diff --git a/src/vendor/boost/detail/lcast_precision.hpp b/src/vendor/boost/detail/lcast_precision.hpp new file mode 100644 index 000000000..84bf1222b --- /dev/null +++ b/src/vendor/boost/detail/lcast_precision.hpp @@ -0,0 +1,185 @@ +// Copyright Alexander Nasonov & Paul A. Bristow 2006. + +// Use, modification and distribution are subject to the +// Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt +// or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED +#define BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + +#include +#include +#include + +#include +#include + +#ifndef BOOST_NO_IS_ABSTRACT +// Fix for SF:1358600 - lexical_cast & pure virtual functions & VC 8 STL +#include +#include +#endif + +#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || \ + (defined(BOOST_MSVC) && (BOOST_MSVC<1310)) + +#define BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#endif + +#ifdef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +#include +#else +#include +#endif + +namespace boost { namespace detail { + +class lcast_abstract_stub {}; + +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION +// Calculate an argument to pass to std::ios_base::precision from +// lexical_cast. See alternative implementation for broken standard +// libraries in lcast_get_precision below. Keep them in sync, please. +template +struct lcast_precision +{ +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::conditional< + boost::is_abstract::value + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + BOOST_STATIC_CONSTANT(bool, use_default_precision = + !limits::is_specialized || limits::is_exact + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_bin = + !use_default_precision && + limits::radix == 2 && limits::digits > 0 + ); + + BOOST_STATIC_CONSTANT(bool, is_specialized_dec = + !use_default_precision && + limits::radix == 10 && limits::digits10 > 0 + ); + + BOOST_STATIC_CONSTANT(std::streamsize, streamsize_max = + boost::integer_traits::const_max + ); + + BOOST_STATIC_CONSTANT(unsigned int, precision_dec = limits::digits10 + 1U); + + BOOST_STATIC_ASSERT(!is_specialized_dec || + precision_dec <= streamsize_max + 0UL + ); + + BOOST_STATIC_CONSTANT(unsigned long, precision_bin = + 2UL + limits::digits * 30103UL / 100000UL + ); + + BOOST_STATIC_ASSERT(!is_specialized_bin || + (limits::digits + 0UL < ULONG_MAX / 30103UL && + precision_bin > limits::digits10 + 0UL && + precision_bin <= streamsize_max + 0UL) + ); + + BOOST_STATIC_CONSTANT(std::streamsize, value = + is_specialized_bin ? precision_bin + : is_specialized_dec ? precision_dec : 6 + ); +}; +#endif + +template +inline std::streamsize lcast_get_precision(T* = 0) +{ +#ifndef BOOST_LCAST_NO_COMPILE_TIME_PRECISION + return lcast_precision::value; +#else // Follow lcast_precision algorithm at run-time: + +#ifdef BOOST_NO_IS_ABSTRACT + typedef std::numeric_limits limits; // No fix for SF:1358600. +#else + typedef BOOST_DEDUCED_TYPENAME boost::conditional< + boost::is_abstract::value + , std::numeric_limits + , std::numeric_limits + >::type limits; +#endif + + bool const use_default_precision = + !limits::is_specialized || limits::is_exact; + + if(!use_default_precision) + { // Includes all built-in floating-point types, float, double ... + // and UDT types for which digits (significand bits) is defined (not zero) + + bool const is_specialized_bin = + limits::radix == 2 && limits::digits > 0; + bool const is_specialized_dec = + limits::radix == 10 && limits::digits10 > 0; + std::streamsize const streamsize_max = + (boost::integer_traits::max)(); + (void)streamsize_max; + + if(is_specialized_bin) + { // Floating-point types with + // limits::digits defined by the specialization. + + unsigned long const digits = limits::digits; + unsigned long const precision = 2UL + digits * 30103UL / 100000UL; + // unsigned long is selected because it is at least 32-bits + // and thus ULONG_MAX / 30103UL is big enough for all types. + BOOST_ASSERT( + digits < ULONG_MAX / 30103UL && + precision > limits::digits10 + 0UL && + precision <= streamsize_max + 0UL + ); + return precision; + } + else if(is_specialized_dec) + { // Decimal Floating-point type, most likely a User Defined Type + // rather than a real floating-point hardware type. + unsigned int const precision = limits::digits10 + 1U; + BOOST_ASSERT(precision <= streamsize_max + 0UL); + return precision; + } + } + + // Integral type (for which precision has no effect) + // or type T for which limits is NOT specialized, + // so assume stream precision remains the default 6 decimal digits. + // Warning: if your User-defined Floating-point type T is NOT specialized, + // then you may lose accuracy by only using 6 decimal digits. + // To avoid this, you need to specialize T with either + // radix == 2 and digits == the number of significand bits, + // OR + // radix = 10 and digits10 == the number of decimal digits. + + return 6; +#endif +} + +template +inline void lcast_set_precision(std::ios_base& stream, T*) +{ + stream.precision(lcast_get_precision()); +} + +template +inline void lcast_set_precision(std::ios_base& stream, Source*, Target*) +{ + std::streamsize const s = lcast_get_precision(static_cast(0)); + std::streamsize const t = lcast_get_precision(static_cast(0)); + stream.precision(s > t ? s : t); +} + +}} + +#endif // BOOST_DETAIL_LCAST_PRECISION_HPP_INCLUDED + diff --git a/src/vendor/boost/detail/select_type.hpp b/src/vendor/boost/detail/select_type.hpp new file mode 100644 index 000000000..c13946f33 --- /dev/null +++ b/src/vendor/boost/detail/select_type.hpp @@ -0,0 +1,36 @@ +// (C) Copyright David Abrahams 2001. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org for most recent version including documentation. + +// Revision History +// 09 Feb 01 Applied John Maddock's Borland patch Moving +// specialization to unspecialized template (David Abrahams) +// 06 Feb 01 Created (David Abrahams) + +#ifndef SELECT_TYPE_DWA20010206_HPP +# define SELECT_TYPE_DWA20010206_HPP + +namespace boost { namespace detail { + + // Template class if_true -- select among 2 types based on a bool constant expression + // Usage: + // typename if_true<(bool_const_expression)>::template then::type + + // HP aCC cannot deal with missing names for template value parameters + template struct if_true + { + template + struct then { typedef T type; }; + }; + + template <> + struct if_true + { + template + struct then { typedef F type; }; + }; +}} +#endif // SELECT_TYPE_DWA20010206_HPP diff --git a/src/vendor/boost/detail/workaround.hpp b/src/vendor/boost/detail/workaround.hpp new file mode 100644 index 000000000..fb9611588 --- /dev/null +++ b/src/vendor/boost/detail/workaround.hpp @@ -0,0 +1,10 @@ +// Copyright David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef WORKAROUND_DWA2002126_HPP +#define WORKAROUND_DWA2002126_HPP + +#include + +#endif // WORKAROUND_DWA2002126_HPP diff --git a/src/vendor/boost/exception/exception.hpp b/src/vendor/boost/exception/exception.hpp new file mode 100644 index 000000000..37a582c2e --- /dev/null +++ b/src/vendor/boost/exception/exception.hpp @@ -0,0 +1,487 @@ +//Copyright (c) 2006-2009 Emil Dotchevski and Reverge Studios, Inc. + +//Distributed under the Boost Software License, Version 1.0. (See accompanying +//file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +#ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 +#define BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 + +#include + +#ifdef BOOST_EXCEPTION_MINI_BOOST +#include +namespace boost { namespace exception_detail { using std::shared_ptr; } } +#else +namespace boost { template class shared_ptr; } +namespace boost { namespace exception_detail { using boost::shared_ptr; } } +#endif + +#if !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#if __GNUC__*100+__GNUC_MINOR__>301 +#pragma GCC system_header +#endif +#ifdef __clang__ +#pragma clang system_header +#endif +#ifdef _MSC_VER +#pragma warning(push,1) +#pragma warning(disable: 4265) +#endif +#endif + +namespace +boost + { + namespace + exception_detail + { + template + class + refcount_ptr + { + public: + + refcount_ptr(): + px_(0) + { + } + + ~refcount_ptr() + { + release(); + } + + refcount_ptr( refcount_ptr const & x ): + px_(x.px_) + { + add_ref(); + } + + refcount_ptr & + operator=( refcount_ptr const & x ) + { + adopt(x.px_); + return *this; + } + + void + adopt( T * px ) + { + release(); + px_=px; + add_ref(); + } + + T * + get() const + { + return px_; + } + + private: + + T * px_; + + void + add_ref() + { + if( px_ ) + px_->add_ref(); + } + + void + release() + { + if( px_ && px_->release() ) + px_=0; + } + }; + } + + //////////////////////////////////////////////////////////////////////// + + template + class error_info; + + typedef error_info throw_function; + typedef error_info throw_file; + typedef error_info throw_line; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef char const * value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + template <> + class + error_info + { + public: + typedef int value_type; + value_type v_; + explicit + error_info( value_type v ): + v_(v) + { + } + }; + + class + BOOST_SYMBOL_VISIBLE + exception; + + namespace + exception_detail + { + class error_info_base; + struct type_info_; + + struct + error_info_container + { + virtual char const * diagnostic_information( char const * ) const = 0; + virtual shared_ptr get( type_info_ const & ) const = 0; + virtual void set( shared_ptr const &, type_info_ const & ) = 0; + virtual void add_ref() const = 0; + virtual bool release() const = 0; + virtual refcount_ptr clone() const = 0; + + protected: + + ~error_info_container() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + + template + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template <> + struct get_info; + + template + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + template <> + struct set_info_rv; + + char const * get_diagnostic_information( exception const &, char const * ); + + void copy_boost_exception( exception *, exception const * ); + + template + E const & set_info( E const &, error_info const & ); + + template + E const & set_info( E const &, throw_function const & ); + + template + E const & set_info( E const &, throw_file const & ); + + template + E const & set_info( E const &, throw_line const & ); + } + + class + BOOST_SYMBOL_VISIBLE + exception + { + // + public: + template void set( typename Tag::type const & ); + template typename Tag::type const * get() const; + // + + protected: + + exception(): + throw_function_(0), + throw_file_(0), + throw_line_(-1) + { + } + +#ifdef __HP_aCC + //On HP aCC, this protected copy constructor prevents throwing boost::exception. + //On all other platforms, the same effect is achieved by the pure virtual destructor. + exception( exception const & x ) BOOST_NOEXCEPT_OR_NOTHROW: + data_(x.data_), + throw_function_(x.throw_function_), + throw_file_(x.throw_file_), + throw_line_(x.throw_line_) + { + } +#endif + + virtual ~exception() BOOST_NOEXCEPT_OR_NOTHROW +#ifndef __HP_aCC + = 0 //Workaround for HP aCC, =0 incorrectly leads to link errors. +#endif + ; + +#if (defined(__MWERKS__) && __MWERKS__<=0x3207) || (defined(_MSC_VER) && _MSC_VER<=1310) + public: +#else + private: + + template + friend E const & exception_detail::set_info( E const &, throw_function const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_file const & ); + + template + friend E const & exception_detail::set_info( E const &, throw_line const & ); + + template + friend E const & exception_detail::set_info( E const &, error_info const & ); + + friend char const * exception_detail::get_diagnostic_information( exception const &, char const * ); + + template + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + friend struct exception_detail::get_info; + template + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend struct exception_detail::set_info_rv; + friend void exception_detail::copy_boost_exception( exception *, exception const * ); +#endif + mutable exception_detail::refcount_ptr data_; + mutable char const * throw_function_; + mutable char const * throw_file_; + mutable int throw_line_; + }; + + inline + exception:: + ~exception() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + namespace + exception_detail + { + template + E const & + set_info( E const & x, throw_function const & y ) + { + x.throw_function_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_file const & y ) + { + x.throw_file_=y.v_; + return x; + } + + template + E const & + set_info( E const & x, throw_line const & y ) + { + x.throw_line_=y.v_; + return x; + } + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + template + struct + BOOST_SYMBOL_VISIBLE + error_info_injector: + public T, + public exception + { + explicit + error_info_injector( T const & x ): + T(x) + { + } + + ~error_info_injector() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + + struct large_size { char c[256]; }; + large_size dispatch_boost_exception( exception const * ); + + struct small_size { }; + small_size dispatch_boost_exception( void const * ); + + template + struct enable_error_info_helper; + + template + struct + enable_error_info_helper + { + typedef T type; + }; + + template + struct + enable_error_info_helper + { + typedef error_info_injector type; + }; + + template + struct + enable_error_info_return_type + { + typedef typename enable_error_info_helper(0)))>::type type; + }; + } + + template + inline + typename + exception_detail::enable_error_info_return_type::type + enable_error_info( T const & x ) + { + typedef typename exception_detail::enable_error_info_return_type::type rt; + return rt(x); + } + + //////////////////////////////////////////////////////////////////////// + + namespace + exception_detail + { + class + BOOST_SYMBOL_VISIBLE + clone_base + { + public: + + virtual clone_base const * clone() const = 0; + virtual void rethrow() const = 0; + + virtual + ~clone_base() BOOST_NOEXCEPT_OR_NOTHROW + { + } + }; + + inline + void + copy_boost_exception( exception * a, exception const * b ) + { + refcount_ptr data; + if( error_info_container * d=b->data_.get() ) + data = d->clone(); + a->throw_file_ = b->throw_file_; + a->throw_line_ = b->throw_line_; + a->throw_function_ = b->throw_function_; + a->data_ = data; + } + + inline + void + copy_boost_exception( void *, void const * ) + { + } + + template + class + BOOST_SYMBOL_VISIBLE + clone_impl: + public T, + public virtual clone_base + { + struct clone_tag { }; + clone_impl( clone_impl const & x, clone_tag ): + T(x) + { + copy_boost_exception(this,&x); + } + + public: + + explicit + clone_impl( T const & x ): + T(x) + { + copy_boost_exception(this,&x); + } + + ~clone_impl() BOOST_NOEXCEPT_OR_NOTHROW + { + } + + private: + + clone_base const * + clone() const + { + return new clone_impl(*this,clone_tag()); + } + + void + rethrow() const + { + throw*this; + } + }; + } + + template + inline + exception_detail::clone_impl + enable_current_exception( T const & x ) + { + return exception_detail::clone_impl(x); + } + } + +#if defined(_MSC_VER) && !defined(BOOST_EXCEPTION_ENABLE_WARNINGS) +#pragma warning(pop) +#endif + +#endif // #ifndef BOOST_EXCEPTION_274DA366004E11DCB1DDFE2E56D89593 diff --git a/src/vendor/boost/function.hpp b/src/vendor/boost/function.hpp new file mode 100644 index 000000000..ef907e0ff --- /dev/null +++ b/src/vendor/boost/function.hpp @@ -0,0 +1,74 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org/libs/function + +// William Kempf, Jesse Jones and Karl Nelson were all very helpful in the +// design of this library. + +#ifndef BOOST_FUNCTION_MAX_ARGS +# define BOOST_FUNCTION_MAX_ARGS 10 +#endif // BOOST_FUNCTION_MAX_ARGS + +#if !defined(BOOST_FUNCTION_MAX_ARGS_DEFINED) || (BOOST_FUNCTION_MAX_ARGS_DEFINED != BOOST_FUNCTION_MAX_ARGS) + +#if !defined(BOOST_FUNCTION_MAX_ARGS_DEFINED) +#define BOOST_FUNCTION_MAX_ARGS_DEFINED 0 +#endif + +#include // unary_function, binary_function + +#include +#include + +// Include the prologue here so that the use of file-level iteration +// in anything that may be included by function_template.hpp doesn't break +#include + +// Older Visual Age C++ version do not handle the file iteration well +#if BOOST_WORKAROUND(__IBMCPP__, >= 500) && BOOST_WORKAROUND(__IBMCPP__, < 800) +# if BOOST_FUNCTION_MAX_ARGS >= 0 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 1 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 2 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 3 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 4 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 5 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 6 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 7 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 8 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 9 +# include +# endif +# if BOOST_FUNCTION_MAX_ARGS >= 10 +# include +# endif +#else +// What is the '3' for? +# define BOOST_PP_ITERATION_PARAMS_1 (3,(0,BOOST_FUNCTION_MAX_ARGS,)) +# include BOOST_PP_ITERATE() +# undef BOOST_PP_ITERATION_PARAMS_1 +#endif + +#endif // !defined(BOOST_FUNCTION_MAX_ARGS_DEFINED) || (BOOST_FUNCTION_MAX_ARGS_DEFINED != BOOST_FUNCTION_MAX_ARGS) diff --git a/src/vendor/boost/function/detail/function_iterate.hpp b/src/vendor/boost/function/detail/function_iterate.hpp new file mode 100644 index 000000000..5370b36aa --- /dev/null +++ b/src/vendor/boost/function/detail/function_iterate.hpp @@ -0,0 +1,16 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org +#if !defined(BOOST_PP_IS_ITERATING) +# error Boost.Function - do not include this file! +#endif + +#define BOOST_FUNCTION_NUM_ARGS BOOST_PP_ITERATION() +#include +#undef BOOST_FUNCTION_NUM_ARGS + diff --git a/src/vendor/boost/function/detail/maybe_include.hpp b/src/vendor/boost/function/detail/maybe_include.hpp new file mode 100644 index 000000000..ec88905dc --- /dev/null +++ b/src/vendor/boost/function/detail/maybe_include.hpp @@ -0,0 +1,369 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#if BOOST_FUNCTION_NUM_ARGS == 0 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 0 +# ifndef BOOST_FUNCTION_0 +# define BOOST_FUNCTION_0 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 1 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 1 +# ifndef BOOST_FUNCTION_1 +# define BOOST_FUNCTION_1 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 2 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 2 +# ifndef BOOST_FUNCTION_2 +# define BOOST_FUNCTION_2 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 3 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 3 +# ifndef BOOST_FUNCTION_3 +# define BOOST_FUNCTION_3 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 4 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 4 +# ifndef BOOST_FUNCTION_4 +# define BOOST_FUNCTION_4 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 5 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 5 +# ifndef BOOST_FUNCTION_5 +# define BOOST_FUNCTION_5 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 6 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 6 +# ifndef BOOST_FUNCTION_6 +# define BOOST_FUNCTION_6 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 7 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 7 +# ifndef BOOST_FUNCTION_7 +# define BOOST_FUNCTION_7 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 8 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 8 +# ifndef BOOST_FUNCTION_8 +# define BOOST_FUNCTION_8 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 9 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 9 +# ifndef BOOST_FUNCTION_9 +# define BOOST_FUNCTION_9 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 10 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 10 +# ifndef BOOST_FUNCTION_10 +# define BOOST_FUNCTION_10 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 11 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 11 +# ifndef BOOST_FUNCTION_11 +# define BOOST_FUNCTION_11 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 12 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 12 +# ifndef BOOST_FUNCTION_12 +# define BOOST_FUNCTION_12 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 13 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 13 +# ifndef BOOST_FUNCTION_13 +# define BOOST_FUNCTION_13 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 14 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 14 +# ifndef BOOST_FUNCTION_14 +# define BOOST_FUNCTION_14 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 15 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 15 +# ifndef BOOST_FUNCTION_15 +# define BOOST_FUNCTION_15 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 16 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 16 +# ifndef BOOST_FUNCTION_16 +# define BOOST_FUNCTION_16 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 17 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 17 +# ifndef BOOST_FUNCTION_17 +# define BOOST_FUNCTION_17 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 18 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 18 +# ifndef BOOST_FUNCTION_18 +# define BOOST_FUNCTION_18 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 19 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 19 +# ifndef BOOST_FUNCTION_19 +# define BOOST_FUNCTION_19 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 20 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 20 +# ifndef BOOST_FUNCTION_20 +# define BOOST_FUNCTION_20 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 21 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 21 +# ifndef BOOST_FUNCTION_21 +# define BOOST_FUNCTION_21 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 22 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 22 +# ifndef BOOST_FUNCTION_22 +# define BOOST_FUNCTION_22 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 23 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 23 +# ifndef BOOST_FUNCTION_23 +# define BOOST_FUNCTION_23 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 24 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 24 +# ifndef BOOST_FUNCTION_24 +# define BOOST_FUNCTION_24 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 25 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 25 +# ifndef BOOST_FUNCTION_25 +# define BOOST_FUNCTION_25 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 26 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 26 +# ifndef BOOST_FUNCTION_26 +# define BOOST_FUNCTION_26 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 27 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 27 +# ifndef BOOST_FUNCTION_27 +# define BOOST_FUNCTION_27 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 28 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 28 +# ifndef BOOST_FUNCTION_28 +# define BOOST_FUNCTION_28 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 29 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 29 +# ifndef BOOST_FUNCTION_29 +# define BOOST_FUNCTION_29 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 30 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 30 +# ifndef BOOST_FUNCTION_30 +# define BOOST_FUNCTION_30 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 31 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 31 +# ifndef BOOST_FUNCTION_31 +# define BOOST_FUNCTION_31 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 32 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 32 +# ifndef BOOST_FUNCTION_32 +# define BOOST_FUNCTION_32 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 33 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 33 +# ifndef BOOST_FUNCTION_33 +# define BOOST_FUNCTION_33 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 34 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 34 +# ifndef BOOST_FUNCTION_34 +# define BOOST_FUNCTION_34 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 35 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 35 +# ifndef BOOST_FUNCTION_35 +# define BOOST_FUNCTION_35 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 36 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 36 +# ifndef BOOST_FUNCTION_36 +# define BOOST_FUNCTION_36 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 37 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 37 +# ifndef BOOST_FUNCTION_37 +# define BOOST_FUNCTION_37 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 38 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 38 +# ifndef BOOST_FUNCTION_38 +# define BOOST_FUNCTION_38 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 39 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 39 +# ifndef BOOST_FUNCTION_39 +# define BOOST_FUNCTION_39 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 40 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 40 +# ifndef BOOST_FUNCTION_40 +# define BOOST_FUNCTION_40 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 41 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 41 +# ifndef BOOST_FUNCTION_41 +# define BOOST_FUNCTION_41 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 42 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 42 +# ifndef BOOST_FUNCTION_42 +# define BOOST_FUNCTION_42 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 43 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 43 +# ifndef BOOST_FUNCTION_43 +# define BOOST_FUNCTION_43 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 44 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 44 +# ifndef BOOST_FUNCTION_44 +# define BOOST_FUNCTION_44 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 45 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 45 +# ifndef BOOST_FUNCTION_45 +# define BOOST_FUNCTION_45 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 46 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 46 +# ifndef BOOST_FUNCTION_46 +# define BOOST_FUNCTION_46 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 47 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 47 +# ifndef BOOST_FUNCTION_47 +# define BOOST_FUNCTION_47 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 48 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 48 +# ifndef BOOST_FUNCTION_48 +# define BOOST_FUNCTION_48 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 49 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 49 +# ifndef BOOST_FUNCTION_49 +# define BOOST_FUNCTION_49 +# include +# endif +#elif BOOST_FUNCTION_NUM_ARGS == 50 +# undef BOOST_FUNCTION_MAX_ARGS_DEFINED +# define BOOST_FUNCTION_MAX_ARGS_DEFINED 50 +# ifndef BOOST_FUNCTION_50 +# define BOOST_FUNCTION_50 +# include +# endif +#else +# error Cannot handle Boost.Function objects that accept more than 50 arguments! +#endif diff --git a/src/vendor/boost/function/detail/prologue.hpp b/src/vendor/boost/function/detail/prologue.hpp new file mode 100644 index 000000000..53d0f05cd --- /dev/null +++ b/src/vendor/boost/function/detail/prologue.hpp @@ -0,0 +1,26 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2002-2003. Use, modification and +// distribution is subject to the Boost Software License, Version +// 1.0. (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#ifndef BOOST_FUNCTION_PROLOGUE_HPP +#define BOOST_FUNCTION_PROLOGUE_HPP +# include +# include +# include // unary_function, binary_function +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif // BOOST_FUNCTION_PROLOGUE_HPP diff --git a/src/vendor/boost/function/function_base.hpp b/src/vendor/boost/function/function_base.hpp new file mode 100644 index 000000000..d63c848e5 --- /dev/null +++ b/src/vendor/boost/function/function_base.hpp @@ -0,0 +1,878 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2006 +// Copyright Emil Dotchevski 2007 +// Use, modification and distribution is subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +#ifndef BOOST_FUNCTION_BASE_HEADER +#define BOOST_FUNCTION_BASE_HEADER + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef BOOST_NO_SFINAE +#include +#else +#include +#endif +#include +#include + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable : 4793 ) // complaint about native code generation +# pragma warning( disable : 4127 ) // "conditional expression is constant" +#endif + +#if defined(__ICL) && __ICL <= 600 || defined(__MWERKS__) && __MWERKS__ < 0x2406 && !defined(BOOST_STRICT_CONFIG) +# define BOOST_FUNCTION_TARGET_FIX(x) x +#else +# define BOOST_FUNCTION_TARGET_FIX(x) +#endif // __ICL etc + +# define BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor,Type) \ + typename ::boost::enable_if_< \ + !(::boost::is_integral::value), \ + Type>::type + +namespace boost { + namespace detail { + namespace function { + class X; + + /** + * A buffer used to store small function objects in + * boost::function. It is a union containing function pointers, + * object pointers, and a structure that resembles a bound + * member function pointer. + */ + union function_buffer_members + { + // For pointers to function objects + typedef void* obj_ptr_t; + mutable obj_ptr_t obj_ptr; + + // For pointers to std::type_info objects + struct type_t { + // (get_functor_type_tag, check_functor_type_tag). + const boost::typeindex::type_info* type; + + // Whether the type is const-qualified. + bool const_qualified; + // Whether the type is volatile-qualified. + bool volatile_qualified; + } type; + + // For function pointers of all kinds + typedef void (*func_ptr_t)(); + mutable func_ptr_t func_ptr; + + // For bound member pointers + struct bound_memfunc_ptr_t { + void (X::*memfunc_ptr)(int); + void* obj_ptr; + } bound_memfunc_ptr; + + // For references to function objects. We explicitly keep + // track of the cv-qualifiers on the object referenced. + struct obj_ref_t { + mutable void* obj_ptr; + bool is_const_qualified; + bool is_volatile_qualified; + } obj_ref; + }; + + union BOOST_SYMBOL_VISIBLE function_buffer + { + // Type-specific union members + mutable function_buffer_members members; + + // To relax aliasing constraints + mutable char data[sizeof(function_buffer_members)]; + }; + + /** + * The unusable class is a placeholder for unused function arguments + * It is also completely unusable except that it constructable from + * anything. This helps compilers without partial specialization to + * handle Boost.Function objects returning void. + */ + struct unusable + { + unusable() {} + template unusable(const T&) {} + }; + + /* Determine the return type. This supports compilers that do not support + * void returns or partial specialization by silently changing the return + * type to "unusable". + */ + template struct function_return_type { typedef T type; }; + + template<> + struct function_return_type + { + typedef unusable type; + }; + + // The operation type to perform on the given functor/function pointer + enum functor_manager_operation_type { + clone_functor_tag, + move_functor_tag, + destroy_functor_tag, + check_functor_type_tag, + get_functor_type_tag + }; + + // Tags used to decide between different types of functions + struct function_ptr_tag {}; + struct function_obj_tag {}; + struct member_ptr_tag {}; + struct function_obj_ref_tag {}; + + template + class get_function_tag + { + typedef typename conditional<(is_pointer::value), + function_ptr_tag, + function_obj_tag>::type ptr_or_obj_tag; + + typedef typename conditional<(is_member_pointer::value), + member_ptr_tag, + ptr_or_obj_tag>::type ptr_or_obj_or_mem_tag; + + typedef typename conditional<(is_reference_wrapper::value), + function_obj_ref_tag, + ptr_or_obj_or_mem_tag>::type or_ref_tag; + + public: + typedef or_ref_tag type; + }; + + // The trivial manager does nothing but return the same pointer (if we + // are cloning) or return the null pointer (if we are deleting). + template + struct reference_manager + { + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + switch (op) { + case clone_functor_tag: + out_buffer.members.obj_ref = in_buffer.members.obj_ref; + return; + + case move_functor_tag: + out_buffer.members.obj_ref = in_buffer.members.obj_ref; + in_buffer.members.obj_ref.obj_ptr = 0; + return; + + case destroy_functor_tag: + out_buffer.members.obj_ref.obj_ptr = 0; + return; + + case check_functor_type_tag: + { + // Check whether we have the same type. We can add + // cv-qualifiers, but we can't take them away. + if (*out_buffer.members.type.type == boost::typeindex::type_id() + && (!in_buffer.members.obj_ref.is_const_qualified + || out_buffer.members.type.const_qualified) + && (!in_buffer.members.obj_ref.is_volatile_qualified + || out_buffer.members.type.volatile_qualified)) + out_buffer.members.obj_ptr = in_buffer.members.obj_ref.obj_ptr; + else + out_buffer.members.obj_ptr = 0; + } + return; + + case get_functor_type_tag: + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = in_buffer.members.obj_ref.is_const_qualified; + out_buffer.members.type.volatile_qualified = in_buffer.members.obj_ref.is_volatile_qualified; + return; + } + } + }; + + /** + * Determine if boost::function can use the small-object + * optimization with the function object type F. + */ + template + struct function_allows_small_object_optimization + { + BOOST_STATIC_CONSTANT + (bool, + value = ((sizeof(F) <= sizeof(function_buffer) && + (alignment_of::value + % alignment_of::value == 0)))); + }; + + template + struct functor_wrapper: public F, public A + { + functor_wrapper( F f, A a ): + F(f), + A(a) + { + } + + functor_wrapper(const functor_wrapper& f) : + F(static_cast(f)), + A(static_cast(f)) + { + } + }; + + /** + * The functor_manager class contains a static function "manage" which + * can clone or destroy the given function/function object pointer. + */ + template + struct functor_manager_common + { + typedef Functor functor_type; + + // Function pointers + static inline void + manage_ptr(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + if (op == clone_functor_tag) + out_buffer.members.func_ptr = in_buffer.members.func_ptr; + else if (op == move_functor_tag) { + out_buffer.members.func_ptr = in_buffer.members.func_ptr; + in_buffer.members.func_ptr = 0; + } else if (op == destroy_functor_tag) + out_buffer.members.func_ptr = 0; + else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = &in_buffer.members.func_ptr; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + + // Function objects that fit in the small-object buffer. + static inline void + manage_small(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + if (op == clone_functor_tag || op == move_functor_tag) { + const functor_type* in_functor = + reinterpret_cast(in_buffer.data); + new (reinterpret_cast(out_buffer.data)) functor_type(*in_functor); + + if (op == move_functor_tag) { + functor_type* f = reinterpret_cast(in_buffer.data); + (void)f; // suppress warning about the value of f not being used (MSVC) + f->~Functor(); + } + } else if (op == destroy_functor_tag) { + // Some compilers (Borland, vc6, ...) are unhappy with ~functor_type. + functor_type* f = reinterpret_cast(out_buffer.data); + (void)f; // suppress warning about the value of f not being used (MSVC) + f->~Functor(); + } else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.data; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + }; + + template + struct functor_manager + { + private: + typedef Functor functor_type; + + // Function pointers + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_ptr_tag) + { + functor_manager_common::manage_ptr(in_buffer,out_buffer,op); + } + + // Function objects that fit in the small-object buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, true_type) + { + functor_manager_common::manage_small(in_buffer,out_buffer,op); + } + + // Function objects that require heap allocation + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, false_type) + { + if (op == clone_functor_tag) { + // Clone the functor + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + // jewillco: Changing this to static_cast because GCC 2.95.3 is + // obsolete. + const functor_type* f = + static_cast(in_buffer.members.obj_ptr); + functor_type* new_f = new functor_type(*f); + out_buffer.members.obj_ptr = new_f; + } else if (op == move_functor_tag) { + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + in_buffer.members.obj_ptr = 0; + } else if (op == destroy_functor_tag) { + /* Cast from the void pointer to the functor pointer type */ + functor_type* f = + static_cast(out_buffer.members.obj_ptr); + delete f; + out_buffer.members.obj_ptr = 0; + } else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + + // For function objects, we determine whether the function + // object can use the small-object optimization buffer or + // whether we need to allocate it on the heap. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_obj_tag) + { + manager(in_buffer, out_buffer, op, + integral_constant::value)>()); + } + + // For member pointers, we use the small-object optimization buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, member_ptr_tag) + { + manager(in_buffer, out_buffer, op, true_type()); + } + + public: + /* Dispatch to an appropriate manager based on whether we have a + function pointer or a function object pointer. */ + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + typedef typename get_function_tag::type tag_type; + if (op == get_functor_type_tag) { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } else { + manager(in_buffer, out_buffer, op, tag_type()); + } + } + }; + + template + struct functor_manager_a + { + private: + typedef Functor functor_type; + + // Function pointers + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_ptr_tag) + { + functor_manager_common::manage_ptr(in_buffer,out_buffer,op); + } + + // Function objects that fit in the small-object buffer. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, true_type) + { + functor_manager_common::manage_small(in_buffer,out_buffer,op); + } + + // Function objects that require heap allocation + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, false_type) + { + typedef functor_wrapper functor_wrapper_type; +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Allocator::template rebind::other + wrapper_allocator_type; + typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; +#else + using wrapper_allocator_type = typename std::allocator_traits::template rebind_alloc; + using wrapper_allocator_pointer_type = typename std::allocator_traits::pointer; +#endif + + if (op == clone_functor_tag) { + // Clone the functor + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + const functor_wrapper_type* f = + static_cast(in_buffer.members.obj_ptr); + wrapper_allocator_type wrapper_allocator(static_cast(*f)); + wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); +#if defined(BOOST_NO_CXX11_ALLOCATOR) + wrapper_allocator.construct(copy, *f); +#else + std::allocator_traits::construct(wrapper_allocator, copy, *f); +#endif + + // Get back to the original pointer type + functor_wrapper_type* new_f = static_cast(copy); + out_buffer.members.obj_ptr = new_f; + } else if (op == move_functor_tag) { + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + in_buffer.members.obj_ptr = 0; + } else if (op == destroy_functor_tag) { + /* Cast from the void pointer to the functor_wrapper_type */ + functor_wrapper_type* victim = + static_cast(in_buffer.members.obj_ptr); + wrapper_allocator_type wrapper_allocator(static_cast(*victim)); +#if defined(BOOST_NO_CXX11_ALLOCATOR) + wrapper_allocator.destroy(victim); +#else + std::allocator_traits::destroy(wrapper_allocator, victim); +#endif + wrapper_allocator.deallocate(victim,1); + out_buffer.members.obj_ptr = 0; + } else if (op == check_functor_type_tag) { + if (*out_buffer.members.type.type == boost::typeindex::type_id()) + out_buffer.members.obj_ptr = in_buffer.members.obj_ptr; + else + out_buffer.members.obj_ptr = 0; + } else /* op == get_functor_type_tag */ { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } + } + + // For function objects, we determine whether the function + // object can use the small-object optimization buffer or + // whether we need to allocate it on the heap. + static inline void + manager(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op, function_obj_tag) + { + manager(in_buffer, out_buffer, op, + integral_constant::value)>()); + } + + public: + /* Dispatch to an appropriate manager based on whether we have a + function pointer or a function object pointer. */ + static inline void + manage(const function_buffer& in_buffer, function_buffer& out_buffer, + functor_manager_operation_type op) + { + typedef typename get_function_tag::type tag_type; + if (op == get_functor_type_tag) { + out_buffer.members.type.type = &boost::typeindex::type_id().type_info(); + out_buffer.members.type.const_qualified = false; + out_buffer.members.type.volatile_qualified = false; + } else { + manager(in_buffer, out_buffer, op, tag_type()); + } + } + }; + + // A type that is only used for comparisons against zero + struct useless_clear_type {}; + +#ifdef BOOST_NO_SFINAE + // These routines perform comparisons between a Boost.Function + // object and an arbitrary function object (when the last + // parameter is false_type) or against zero (when the + // last parameter is true_type). They are only necessary + // for compilers that don't support SFINAE. + template + bool + compare_equal(const Function& f, const Functor&, int, true_type) + { return f.empty(); } + + template + bool + compare_not_equal(const Function& f, const Functor&, int, + true_type) + { return !f.empty(); } + + template + bool + compare_equal(const Function& f, const Functor& g, long, + false_type) + { + if (const Functor* fp = f.template target()) + return function_equal(*fp, g); + else return false; + } + + template + bool + compare_equal(const Function& f, const reference_wrapper& g, + int, false_type) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + + template + bool + compare_not_equal(const Function& f, const Functor& g, long, + false_type) + { + if (const Functor* fp = f.template target()) + return !function_equal(*fp, g); + else return true; + } + + template + bool + compare_not_equal(const Function& f, + const reference_wrapper& g, int, + false_type) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } +#endif // BOOST_NO_SFINAE + + /** + * Stores the "manager" portion of the vtable for a + * boost::function object. + */ + struct vtable_base + { + void (*manager)(const function_buffer& in_buffer, + function_buffer& out_buffer, + functor_manager_operation_type op); + }; + } // end namespace function + } // end namespace detail + +/** + * The function_base class contains the basic elements needed for the + * function1, function2, function3, etc. classes. It is common to all + * functions (and as such can be used to tell if we have one of the + * functionN objects). + */ +class function_base +{ +public: + function_base() : vtable(0) { } + + /** Determine if the function is empty (i.e., has no target). */ + bool empty() const { return !vtable; } + + /** Retrieve the type of the stored function object, or type_id() + if this is empty. */ + const boost::typeindex::type_info& target_type() const + { + if (!vtable) return boost::typeindex::type_id().type_info(); + + detail::function::function_buffer type; + get_vtable()->manager(functor, type, detail::function::get_functor_type_tag); + return *type.members.type.type; + } + + template + Functor* target() + { + if (!vtable) return 0; + + detail::function::function_buffer type_result; + type_result.members.type.type = &boost::typeindex::type_id().type_info(); + type_result.members.type.const_qualified = is_const::value; + type_result.members.type.volatile_qualified = is_volatile::value; + get_vtable()->manager(functor, type_result, + detail::function::check_functor_type_tag); + return static_cast(type_result.members.obj_ptr); + } + + template + const Functor* target() const + { + if (!vtable) return 0; + + detail::function::function_buffer type_result; + type_result.members.type.type = &boost::typeindex::type_id().type_info(); + type_result.members.type.const_qualified = true; + type_result.members.type.volatile_qualified = is_volatile::value; + get_vtable()->manager(functor, type_result, + detail::function::check_functor_type_tag); + // GCC 2.95.3 gets the CV qualifiers wrong here, so we + // can't do the static_cast that we should do. + return static_cast(type_result.members.obj_ptr); + } + + template + bool contains(const F& f) const + { + if (const F* fp = this->template target()) + { + return function_equal(*fp, f); + } else { + return false; + } + } + +#if defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3 + // GCC 3.3 and newer cannot copy with the global operator==, due to + // problems with instantiation of function return types before it + // has been verified that the argument types match up. + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g) const + { + if (const Functor* fp = target()) + return function_equal(*fp, g); + else return false; + } + + template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g) const + { + if (const Functor* fp = target()) + return !function_equal(*fp, g); + else return true; + } +#endif + +public: // should be protected, but GCC 2.95.3 will fail to allow access + detail::function::vtable_base* get_vtable() const { + return reinterpret_cast( + reinterpret_cast(vtable) & ~static_cast(0x01)); + } + + bool has_trivial_copy_and_destroy() const { + return reinterpret_cast(vtable) & 0x01; + } + + detail::function::vtable_base* vtable; + mutable detail::function::function_buffer functor; +}; + +#if defined(BOOST_CLANG) +# pragma clang diagnostic push + //# pragma clang diagnostic ignored "-Wweak-vtables" +#endif +/** + * The bad_function_call exception class is thrown when a boost::function + * object is invoked + */ +class BOOST_SYMBOL_VISIBLE bad_function_call : public std::runtime_error +{ +public: + bad_function_call() : std::runtime_error("call to empty boost::function") {} +}; +#if defined(BOOST_CLANG) +# pragma clang diagnostic pop +#endif + +#ifndef BOOST_NO_SFINAE +inline bool operator==(const function_base& f, + detail::function::useless_clear_type*) +{ + return f.empty(); +} + +inline bool operator!=(const function_base& f, + detail::function::useless_clear_type*) +{ + return !f.empty(); +} + +inline bool operator==(detail::function::useless_clear_type*, + const function_base& f) +{ + return f.empty(); +} + +inline bool operator!=(detail::function::useless_clear_type*, + const function_base& f) +{ + return !f.empty(); +} +#endif + +#ifdef BOOST_NO_SFINAE +// Comparisons between boost::function objects and arbitrary function objects +template + inline bool operator==(const function_base& f, Functor g) + { + typedef integral_constant::value)> integral; + return detail::function::compare_equal(f, g, 0, integral()); + } + +template + inline bool operator==(Functor g, const function_base& f) + { + typedef integral_constant::value)> integral; + return detail::function::compare_equal(f, g, 0, integral()); + } + +template + inline bool operator!=(const function_base& f, Functor g) + { + typedef integral_constant::value)> integral; + return detail::function::compare_not_equal(f, g, 0, integral()); + } + +template + inline bool operator!=(Functor g, const function_base& f) + { + typedef integral_constant::value)> integral; + return detail::function::compare_not_equal(f, g, 0, integral()); + } +#else + +# if !(defined(__GNUC__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 3) +// Comparisons between boost::function objects and arbitrary function +// objects. GCC 3.3 and before has an obnoxious bug that prevents this +// from working. +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const function_base& f, Functor g) + { + if (const Functor* fp = f.template target()) + return function_equal(*fp, g); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(Functor g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return function_equal(g, *fp); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const function_base& f, Functor g) + { + if (const Functor* fp = f.template target()) + return !function_equal(*fp, g); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(Functor g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return !function_equal(g, *fp); + else return true; + } +# endif + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(const function_base& f, reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp == g.get_pointer(); + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator==(reference_wrapper g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() == fp; + else return false; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(const function_base& f, reference_wrapper g) + { + if (const Functor* fp = f.template target()) + return fp != g.get_pointer(); + else return true; + } + +template + BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL(Functor, bool) + operator!=(reference_wrapper g, const function_base& f) + { + if (const Functor* fp = f.template target()) + return g.get_pointer() != fp; + else return true; + } + +#endif // Compiler supporting SFINAE + +namespace detail { + namespace function { + inline bool has_empty_target(const function_base* f) + { + return f->empty(); + } + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) + inline bool has_empty_target(const void*) + { + return false; + } +#else + inline bool has_empty_target(...) + { + return false; + } +#endif + } // end namespace function +} // end namespace detail +} // end namespace boost + +#undef BOOST_FUNCTION_ENABLE_IF_NOT_INTEGRAL + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif + +#endif // BOOST_FUNCTION_BASE_HEADER diff --git a/src/vendor/boost/function/function_fwd.hpp b/src/vendor/boost/function/function_fwd.hpp new file mode 100644 index 000000000..e79b50489 --- /dev/null +++ b/src/vendor/boost/function/function_fwd.hpp @@ -0,0 +1,69 @@ +// Boost.Function library +// Copyright (C) Douglas Gregor 2008 +// +// Use, modification and distribution is subject to the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// For more information, see http://www.boost.org +#ifndef BOOST_FUNCTION_FWD_HPP +#define BOOST_FUNCTION_FWD_HPP +#include + +#if defined(__sgi) && defined(_COMPILER_VERSION) && _COMPILER_VERSION <= 730 && !defined(BOOST_STRICT_CONFIG) +// Work around a compiler bug. +// boost::python::objects::function has to be seen by the compiler before the +// boost::function class template. +namespace boost { namespace python { namespace objects { + class function; +}}} +#endif + +#if defined(BOOST_BCB_PARTIAL_SPECIALIZATION_BUG) \ + || !(defined(BOOST_STRICT_CONFIG) || !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x540) +# define BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX +#endif + +namespace boost { + class bad_function_call; + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + // Preferred syntax + template class function; + + template + inline void swap(function& f1, function& f2) + { + f1.swap(f2); + } +#endif // have partial specialization + + // Portable syntax + template class function0; + template class function1; + template class function2; + template class function3; + template + class function4; + template + class function5; + template + class function6; + template + class function7; + template + class function8; + template + class function9; + template + class function10; +} + +#endif diff --git a/src/vendor/boost/function/function_template.hpp b/src/vendor/boost/function/function_template.hpp new file mode 100644 index 000000000..26f1d67d0 --- /dev/null +++ b/src/vendor/boost/function/function_template.hpp @@ -0,0 +1,1203 @@ +// Boost.Function library + +// Copyright Douglas Gregor 2001-2006 +// Copyright Emil Dotchevski 2007 +// Use, modification and distribution is subject to the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org + +// Note: this header is a header template and must NOT have multiple-inclusion +// protection. +#include +#include + +#if defined(BOOST_MSVC) +# pragma warning( push ) +# pragma warning( disable : 4127 ) // "conditional expression is constant" +#endif + +#define BOOST_FUNCTION_TEMPLATE_PARMS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, typename T) + +#define BOOST_FUNCTION_TEMPLATE_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, T) + +#define BOOST_FUNCTION_PARM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I) + +#define BOOST_FUNCTION_PARMS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_PARM,BOOST_PP_EMPTY) + +#ifdef BOOST_NO_CXX11_RVALUE_REFERENCES +# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM_PARAMS(BOOST_FUNCTION_NUM_ARGS, a) +#else +# define BOOST_FUNCTION_ARG(J,I,D) static_cast(BOOST_PP_CAT(a,I)) +# define BOOST_FUNCTION_ARGS BOOST_PP_ENUM(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG,BOOST_PP_EMPTY) +#endif + +#define BOOST_FUNCTION_ARG_TYPE(J,I,D) \ + typedef BOOST_PP_CAT(T,I) BOOST_PP_CAT(BOOST_PP_CAT(arg, BOOST_PP_INC(I)),_type); + +#define BOOST_FUNCTION_ARG_TYPES BOOST_PP_REPEAT(BOOST_FUNCTION_NUM_ARGS,BOOST_FUNCTION_ARG_TYPE,BOOST_PP_EMPTY) + +// Comma if nonzero number of arguments +#if BOOST_FUNCTION_NUM_ARGS == 0 +# define BOOST_FUNCTION_COMMA +#else +# define BOOST_FUNCTION_COMMA , +#endif // BOOST_FUNCTION_NUM_ARGS > 0 + +// Class names used in this version of the code +#define BOOST_FUNCTION_FUNCTION BOOST_JOIN(function,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_INVOKER \ + BOOST_JOIN(function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_INVOKER \ + BOOST_JOIN(void_function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(void_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_FUNCTION_REF_INVOKER \ + BOOST_JOIN(function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER \ + BOOST_JOIN(void_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_MEMBER_INVOKER \ + BOOST_JOIN(function_mem_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VOID_MEMBER_INVOKER \ + BOOST_JOIN(function_void_mem_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_INVOKER \ + BOOST_JOIN(get_function_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER \ + BOOST_JOIN(get_function_obj_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER \ + BOOST_JOIN(get_function_ref_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_MEMBER_INVOKER \ + BOOST_JOIN(get_member_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_GET_INVOKER \ + BOOST_JOIN(get_invoker,BOOST_FUNCTION_NUM_ARGS) +#define BOOST_FUNCTION_VTABLE BOOST_JOIN(basic_vtable,BOOST_FUNCTION_NUM_ARGS) + +#ifndef BOOST_NO_VOID_RETURNS +# define BOOST_FUNCTION_VOID_RETURN_TYPE void +# define BOOST_FUNCTION_RETURN(X) X +#else +# define BOOST_FUNCTION_VOID_RETURN_TYPE boost::detail::function::unusable +# define BOOST_FUNCTION_RETURN(X) X; return BOOST_FUNCTION_VOID_RETURN_TYPE () +#endif + +namespace boost { + namespace detail { + namespace function { + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_INVOKER + { + static R invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + { + FunctionPtr f = reinterpret_cast(function_ptr.members.func_ptr); + return f(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionPtr f = reinterpret_cast(function_ptr.members.func_ptr); + BOOST_FUNCTION_RETURN(f(BOOST_FUNCTION_ARGS)); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_OBJ_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f; + if (function_allows_small_object_optimization::value) + f = reinterpret_cast(function_obj_ptr.data); + else + f = reinterpret_cast(function_obj_ptr.members.obj_ptr); + return (*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f; + if (function_allows_small_object_optimization::value) + f = reinterpret_cast(function_obj_ptr.data); + else + f = reinterpret_cast(function_obj_ptr.members.obj_ptr); + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_FUNCTION_REF_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f = + reinterpret_cast(function_obj_ptr.members.obj_ptr); + return (*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + FunctionObj* f = + reinterpret_cast(function_obj_ptr.members.obj_ptr); + BOOST_FUNCTION_RETURN((*f)(BOOST_FUNCTION_ARGS)); + } + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Handle invocation of member pointers. */ + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_MEMBER_INVOKER + { + static R invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + MemberPtr* f = + reinterpret_cast(function_obj_ptr.data); + return boost::mem_fn(*f)(BOOST_FUNCTION_ARGS); + } + }; + + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_VOID_MEMBER_INVOKER + { + static BOOST_FUNCTION_VOID_RETURN_TYPE + invoke(function_buffer& function_obj_ptr BOOST_FUNCTION_COMMA + BOOST_FUNCTION_PARMS) + + { + MemberPtr* f = + reinterpret_cast(function_obj_ptr.data); + BOOST_FUNCTION_RETURN(boost::mem_fn(*f)(BOOST_FUNCTION_ARGS)); + } + }; +#endif + + template< + typename FunctionPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_INVOKER + { + typedef typename conditional<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER + { + typedef typename conditional<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + + template< + typename FunctionObj, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER + { + typedef typename conditional<(is_void::value), + BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_FUNCTION_REF_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Retrieve the appropriate invoker for a member pointer. */ + template< + typename MemberPtr, + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + struct BOOST_FUNCTION_GET_MEMBER_INVOKER + { + typedef typename conditional<(is_void::value), + BOOST_FUNCTION_VOID_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >, + BOOST_FUNCTION_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + > + >::type type; + }; +#endif + + /* Given the tag returned by get_function_tag, retrieve the + actual invoker that will be used for the given function + object. + + Each specialization contains an "apply" nested class template + that accepts the function object, return type, function + argument types, and allocator. The resulting "apply" class + contains two typedefs, "invoker_type" and "manager_type", + which correspond to the invoker and manager types. */ + template + struct BOOST_FUNCTION_GET_INVOKER { }; + + /* Retrieve the invoker for a function pointer. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_INVOKER< + FunctionPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; + +#if BOOST_FUNCTION_NUM_ARGS > 0 + /* Retrieve the invoker for a member pointer. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_MEMBER_INVOKER< + MemberPtr, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + }; +#endif + + /* Retrieve the invoker for a function object. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER< + FunctionObj, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef functor_manager_a manager_type; + }; + }; + + /* Retrieve the invoker for a reference to a function object. */ + template<> + struct BOOST_FUNCTION_GET_INVOKER + { + template + struct apply + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< + typename RefWrapper::type, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef reference_manager manager_type; + }; + + template + struct apply_a + { + typedef typename BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER< + typename RefWrapper::type, + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >::type + invoker_type; + + typedef reference_manager manager_type; + }; + }; + + + /** + * vtable for a specific boost::function instance. This + * structure must be an aggregate so that we can use static + * initialization in boost::function's assign_to and assign_to_a + * members. It therefore cannot have any constructors, + * destructors, base classes, etc. + */ + template + struct BOOST_FUNCTION_VTABLE + { +#ifndef BOOST_NO_VOID_RETURNS + typedef R result_type; +#else + typedef typename function_return_type::type result_type; +#endif // BOOST_NO_VOID_RETURNS + + typedef result_type (*invoker_type)(function_buffer& + BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS); + + template + bool assign_to(F f, function_buffer& functor) const + { + typedef typename get_function_tag::type tag; + return assign_to(f, functor, tag()); + } + template + bool assign_to_a(F f, function_buffer& functor, Allocator a) const + { + typedef typename get_function_tag::type tag; + return assign_to_a(f, functor, a, tag()); + } + + void clear(function_buffer& functor) const + { + if (base.manager) + base.manager(functor, functor, destroy_functor_tag); + } + + private: + // Function pointers + template + bool + assign_to(FunctionPtr f, function_buffer& functor, function_ptr_tag) const + { + this->clear(functor); + if (f) { + // should be a reinterpret cast, but some compilers insist + // on giving cv-qualifiers to free functions + functor.members.func_ptr = reinterpret_cast(f); + return true; + } else { + return false; + } + } + template + bool + assign_to_a(FunctionPtr f, function_buffer& functor, Allocator, function_ptr_tag) const + { + return assign_to(f,functor,function_ptr_tag()); + } + + // Member pointers +#if BOOST_FUNCTION_NUM_ARGS > 0 + template + bool assign_to(MemberPtr f, function_buffer& functor, member_ptr_tag) const + { + // DPG TBD: Add explicit support for member function + // objects, so we invoke through mem_fn() but we retain the + // right target_type() values. + if (f) { + this->assign_to(boost::mem_fn(f), functor); + return true; + } else { + return false; + } + } + template + bool assign_to_a(MemberPtr f, function_buffer& functor, Allocator a, member_ptr_tag) const + { + // DPG TBD: Add explicit support for member function + // objects, so we invoke through mem_fn() but we retain the + // right target_type() values. + if (f) { + this->assign_to_a(boost::mem_fn(f), functor, a); + return true; + } else { + return false; + } + } +#endif // BOOST_FUNCTION_NUM_ARGS > 0 + + // Function objects + // Assign to a function object using the small object optimization + template + void + assign_functor(FunctionObj f, function_buffer& functor, true_type) const + { + new (reinterpret_cast(functor.data)) FunctionObj(f); + } + template + void + assign_functor_a(FunctionObj f, function_buffer& functor, Allocator, true_type) const + { + assign_functor(f,functor,true_type()); + } + + // Assign to a function object allocated on the heap. + template + void + assign_functor(FunctionObj f, function_buffer& functor, false_type) const + { + functor.members.obj_ptr = new FunctionObj(f); + } + template + void + assign_functor_a(FunctionObj f, function_buffer& functor, Allocator a, false_type) const + { + typedef functor_wrapper functor_wrapper_type; +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Allocator::template rebind::other + wrapper_allocator_type; + typedef typename wrapper_allocator_type::pointer wrapper_allocator_pointer_type; +#else + using wrapper_allocator_type = typename std::allocator_traits::template rebind_alloc; + using wrapper_allocator_pointer_type = typename std::allocator_traits::pointer; +#endif + wrapper_allocator_type wrapper_allocator(a); + wrapper_allocator_pointer_type copy = wrapper_allocator.allocate(1); +#if defined(BOOST_NO_CXX11_ALLOCATOR) + wrapper_allocator.construct(copy, functor_wrapper_type(f,a)); +#else + std::allocator_traits::construct(wrapper_allocator, copy, functor_wrapper_type(f,a)); +#endif + functor_wrapper_type* new_f = static_cast(copy); + functor.members.obj_ptr = new_f; + } + + template + bool + assign_to(FunctionObj f, function_buffer& functor, function_obj_tag) const + { + if (!boost::detail::function::has_empty_target(boost::addressof(f))) { + assign_functor(f, functor, + integral_constant::value)>()); + return true; + } else { + return false; + } + } + template + bool + assign_to_a(FunctionObj f, function_buffer& functor, Allocator a, function_obj_tag) const + { + if (!boost::detail::function::has_empty_target(boost::addressof(f))) { + assign_functor_a(f, functor, a, + integral_constant::value)>()); + return true; + } else { + return false; + } + } + + // Reference to a function object + template + bool + assign_to(const reference_wrapper& f, + function_buffer& functor, function_obj_ref_tag) const + { + functor.members.obj_ref.obj_ptr = (void *)(f.get_pointer()); + functor.members.obj_ref.is_const_qualified = is_const::value; + functor.members.obj_ref.is_volatile_qualified = is_volatile::value; + return true; + } + template + bool + assign_to_a(const reference_wrapper& f, + function_buffer& functor, Allocator, function_obj_ref_tag) const + { + return assign_to(f,functor,function_obj_ref_tag()); + } + + public: + vtable_base base; + invoker_type invoker; + }; + } // end namespace function + } // end namespace detail + + template< + typename R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_PARMS + > + class BOOST_FUNCTION_FUNCTION : public function_base + { + public: +#ifndef BOOST_NO_VOID_RETURNS + typedef R result_type; +#else + typedef typename boost::detail::function::function_return_type::type + result_type; +#endif // BOOST_NO_VOID_RETURNS + + private: + typedef boost::detail::function::BOOST_FUNCTION_VTABLE< + R BOOST_FUNCTION_COMMA BOOST_FUNCTION_TEMPLATE_ARGS> + vtable_type; + + vtable_type* get_vtable() const { + return reinterpret_cast( + reinterpret_cast(vtable) & ~static_cast(0x01)); + } + + struct clear_type {}; + + public: + BOOST_STATIC_CONSTANT(int, args = BOOST_FUNCTION_NUM_ARGS); + + // add signature for boost::lambda + template + struct sig + { + typedef result_type type; + }; + +#if BOOST_FUNCTION_NUM_ARGS == 1 + typedef T0 argument_type; +#elif BOOST_FUNCTION_NUM_ARGS == 2 + typedef T0 first_argument_type; + typedef T1 second_argument_type; +#endif + + BOOST_STATIC_CONSTANT(int, arity = BOOST_FUNCTION_NUM_ARGS); + BOOST_FUNCTION_ARG_TYPES + + typedef BOOST_FUNCTION_FUNCTION self_type; + + BOOST_DEFAULTED_FUNCTION(BOOST_FUNCTION_FUNCTION(), : function_base() {}) + + // MSVC chokes if the following two constructors are collapsed into + // one with a default parameter. + template + BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_< + !(is_integral::value), + int>::type = 0 +#endif // BOOST_NO_SFINAE + ) : + function_base() + { + this->assign_to(f); + } + template + BOOST_FUNCTION_FUNCTION(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_< + !(is_integral::value), + int>::type = 0 +#endif // BOOST_NO_SFINAE + ) : + function_base() + { + this->assign_to_a(f,a); + } + +#ifndef BOOST_NO_SFINAE + BOOST_FUNCTION_FUNCTION(clear_type*) : function_base() { } +#else + BOOST_FUNCTION_FUNCTION(int zero) : function_base() + { + BOOST_ASSERT(zero == 0); + } +#endif + + BOOST_FUNCTION_FUNCTION(const BOOST_FUNCTION_FUNCTION& f) : function_base() + { + this->assign_to_own(f); + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + BOOST_FUNCTION_FUNCTION(BOOST_FUNCTION_FUNCTION&& f) : function_base() + { + this->move_assign(f); + } +#endif + + ~BOOST_FUNCTION_FUNCTION() { clear(); } + + result_type operator()(BOOST_FUNCTION_PARMS) const + { + if (this->empty()) + boost::throw_exception(bad_function_call()); + + return get_vtable()->invoker + (this->functor BOOST_FUNCTION_COMMA BOOST_FUNCTION_ARGS); + } + + // The distinction between when to use BOOST_FUNCTION_FUNCTION and + // when to use self_type is obnoxious. MSVC cannot handle self_type as + // the return type of these assignment operators, but Borland C++ cannot + // handle BOOST_FUNCTION_FUNCTION as the type of the temporary to + // construct. + template +#ifndef BOOST_NO_SFINAE + typename boost::enable_if_< + !(is_integral::value), + BOOST_FUNCTION_FUNCTION&>::type +#else + BOOST_FUNCTION_FUNCTION& +#endif + operator=(Functor BOOST_FUNCTION_TARGET_FIX(const &) f) + { + this->clear(); + BOOST_TRY { + this->assign_to(f); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + return *this; + } + template + void assign(Functor BOOST_FUNCTION_TARGET_FIX(const &) f, Allocator a) + { + this->clear(); + BOOST_TRY{ + this->assign_to_a(f,a); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + } + +#ifndef BOOST_NO_SFINAE + BOOST_FUNCTION_FUNCTION& operator=(clear_type*) + { + this->clear(); + return *this; + } +#else + BOOST_FUNCTION_FUNCTION& operator=(int zero) + { + BOOST_ASSERT(zero == 0); + this->clear(); + return *this; + } +#endif + + // Assignment from another BOOST_FUNCTION_FUNCTION + BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f) + { + if (&f == this) + return *this; + + this->clear(); + BOOST_TRY { + this->assign_to_own(f); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Move assignment from another BOOST_FUNCTION_FUNCTION + BOOST_FUNCTION_FUNCTION& operator=(BOOST_FUNCTION_FUNCTION&& f) + { + if (&f == this) + return *this; + + this->clear(); + BOOST_TRY { + this->move_assign(f); + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + return *this; + } +#endif + + void swap(BOOST_FUNCTION_FUNCTION& other) + { + if (&other == this) + return; + + BOOST_FUNCTION_FUNCTION tmp; + tmp.move_assign(*this); + this->move_assign(other); + other.move_assign(tmp); + } + + // Clear out a target, if there is one + void clear() + { + if (vtable) { + if (!this->has_trivial_copy_and_destroy()) + get_vtable()->clear(this->functor); + vtable = 0; + } + } + +#if (defined __SUNPRO_CC) && (__SUNPRO_CC <= 0x530) && !(defined BOOST_NO_COMPILER_CONFIG) + // Sun C++ 5.3 can't handle the safe_bool idiom, so don't use it + operator bool () const { return !this->empty(); } +#else + private: + struct dummy { + void nonnull() {} + }; + + typedef void (dummy::*safe_bool)(); + + public: + operator safe_bool () const + { return (this->empty())? 0 : &dummy::nonnull; } + + bool operator!() const + { return this->empty(); } +#endif + + private: + void assign_to_own(const BOOST_FUNCTION_FUNCTION& f) + { + if (!f.empty()) { + this->vtable = f.vtable; + if (this->has_trivial_copy_and_destroy()) { + // Don't operate on storage directly since union type doesn't relax + // strict aliasing rules, despite of having member char type. +# if defined(BOOST_GCC) && (BOOST_GCC >= 40700) +# pragma GCC diagnostic push + // This warning is technically correct, but we don't want to pay the price for initializing + // just to silence a warning: https://github.com/boostorg/function/issues/27 +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +# endif + std::memcpy(this->functor.data, f.functor.data, sizeof(boost::detail::function::function_buffer)); +# if defined(BOOST_GCC) && (BOOST_GCC >= 40700) +# pragma GCC diagnostic pop +# endif + } else + get_vtable()->base.manager(f.functor, this->functor, + boost::detail::function::clone_functor_tag); + } + } + + template + void assign_to(Functor f) + { + using boost::detail::function::vtable_base; + + typedef typename boost::detail::function::get_function_tag::type tag; + typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; + typedef typename get_invoker:: + template apply + handler_type; + + typedef typename handler_type::invoker_type invoker_type; + typedef typename handler_type::manager_type manager_type; + + // Note: it is extremely important that this initialization use + // static initialization. Otherwise, we will have a race + // condition here in multi-threaded code. See + // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. + static const vtable_type stored_vtable = + { { &manager_type::manage }, &invoker_type::invoke }; + + if (stored_vtable.assign_to(f, functor)) { + std::size_t value = reinterpret_cast(&stored_vtable.base); + // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). + if (boost::has_trivial_copy_constructor::value && + boost::has_trivial_destructor::value && + boost::detail::function::function_allows_small_object_optimization::value) + value |= static_cast(0x01); + vtable = reinterpret_cast(value); + } else + vtable = 0; + } + + template + void assign_to_a(Functor f,Allocator a) + { + using boost::detail::function::vtable_base; + + typedef typename boost::detail::function::get_function_tag::type tag; + typedef boost::detail::function::BOOST_FUNCTION_GET_INVOKER get_invoker; + typedef typename get_invoker:: + template apply_a + handler_type; + + typedef typename handler_type::invoker_type invoker_type; + typedef typename handler_type::manager_type manager_type; + + // Note: it is extremely important that this initialization use + // static initialization. Otherwise, we will have a race + // condition here in multi-threaded code. See + // http://thread.gmane.org/gmane.comp.lib.boost.devel/164902/. + static const vtable_type stored_vtable = + { { &manager_type::manage }, &invoker_type::invoke }; + + if (stored_vtable.assign_to_a(f, functor, a)) { + std::size_t value = reinterpret_cast(&stored_vtable.base); + // coverity[pointless_expression]: suppress coverity warnings on apparant if(const). + if (boost::has_trivial_copy_constructor::value && + boost::has_trivial_destructor::value && + boost::detail::function::function_allows_small_object_optimization::value) + value |= static_cast(0x01); + vtable = reinterpret_cast(value); + } else + vtable = 0; + } + + // Moves the value from the specified argument to *this. If the argument + // has its function object allocated on the heap, move_assign will pass + // its buffer to *this, and set the argument's buffer pointer to NULL. + void move_assign(BOOST_FUNCTION_FUNCTION& f) + { + if (&f == this) + return; + + BOOST_TRY { + if (!f.empty()) { + this->vtable = f.vtable; + if (this->has_trivial_copy_and_destroy()) { + // Don't operate on storage directly since union type doesn't relax + // strict aliasing rules, despite of having member char type. +# if defined(BOOST_GCC) && (BOOST_GCC >= 40700) +# pragma GCC diagnostic push + // This warning is technically correct, but we don't want to pay the price for initializing + // just to silence a warning: https://github.com/boostorg/function/issues/27 +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +# endif + std::memcpy(this->functor.data, f.functor.data, sizeof(this->functor.data)); +# if defined(BOOST_GCC) && (BOOST_GCC >= 40700) +# pragma GCC diagnostic pop +# endif + } else + get_vtable()->base.manager(f.functor, this->functor, + boost::detail::function::move_functor_tag); + f.vtable = 0; + } else { + clear(); + } + } BOOST_CATCH (...) { + vtable = 0; + BOOST_RETHROW; + } + BOOST_CATCH_END + } + }; + + template + inline void swap(BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >& f1, + BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS + >& f2) + { + f1.swap(f2); + } + +// Poison comparisons between boost::function objects of the same type. +template + void operator==(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>&, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>&); +template + void operator!=(const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>&, + const BOOST_FUNCTION_FUNCTION< + R BOOST_FUNCTION_COMMA + BOOST_FUNCTION_TEMPLATE_ARGS>& ); + +#if !defined(BOOST_FUNCTION_NO_FUNCTION_TYPE_SYNTAX) + +#if BOOST_FUNCTION_NUM_ARGS == 0 +#define BOOST_FUNCTION_PARTIAL_SPEC R (void) +#else +#define BOOST_FUNCTION_PARTIAL_SPEC R (BOOST_FUNCTION_TEMPLATE_ARGS) +#endif + +template +class function + : public BOOST_FUNCTION_FUNCTION +{ + typedef BOOST_FUNCTION_FUNCTION base_type; + typedef function self_type; + + struct clear_type {}; + +public: + + BOOST_DEFAULTED_FUNCTION(function(), : base_type() {}) + + template + function(Functor f +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_< + !(is_integral::value), + int>::type = 0 +#endif + ) : + base_type(f) + { + } + template + function(Functor f, Allocator a +#ifndef BOOST_NO_SFINAE + ,typename boost::enable_if_< + !(is_integral::value), + int>::type = 0 +#endif + ) : + base_type(f,a) + { + } + +#ifndef BOOST_NO_SFINAE + function(clear_type*) : base_type() {} +#endif + + function(const self_type& f) : base_type(static_cast(f)){} + + function(const base_type& f) : base_type(static_cast(f)){} + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Move constructors + function(self_type&& f): base_type(static_cast(f)){} + function(base_type&& f): base_type(static_cast(f)){} +#endif + + self_type& operator=(const self_type& f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + self_type& operator=(self_type&& f) + { + self_type(static_cast(f)).swap(*this); + return *this; + } +#endif + + template +#ifndef BOOST_NO_SFINAE + typename boost::enable_if_< + !(is_integral::value), + self_type&>::type +#else + self_type& +#endif + operator=(Functor f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_SFINAE + self_type& operator=(clear_type*) + { + this->clear(); + return *this; + } +#endif + + self_type& operator=(const base_type& f) + { + self_type(f).swap(*this); + return *this; + } + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + self_type& operator=(base_type&& f) + { + self_type(static_cast(f)).swap(*this); + return *this; + } +#endif +}; + +#undef BOOST_FUNCTION_PARTIAL_SPEC +#endif // have partial specialization + +} // end namespace boost + +// Cleanup after ourselves... +#undef BOOST_FUNCTION_VTABLE +#undef BOOST_FUNCTION_COMMA +#undef BOOST_FUNCTION_FUNCTION +#undef BOOST_FUNCTION_FUNCTION_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_INVOKER +#undef BOOST_FUNCTION_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_VOID_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_MEMBER_INVOKER +#undef BOOST_FUNCTION_VOID_MEMBER_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_OBJ_INVOKER +#undef BOOST_FUNCTION_GET_FUNCTION_REF_INVOKER +#undef BOOST_FUNCTION_GET_MEM_FUNCTION_INVOKER +#undef BOOST_FUNCTION_GET_INVOKER +#undef BOOST_FUNCTION_TEMPLATE_PARMS +#undef BOOST_FUNCTION_TEMPLATE_ARGS +#undef BOOST_FUNCTION_PARMS +#undef BOOST_FUNCTION_PARM +#ifdef BOOST_FUNCTION_ARG +# undef BOOST_FUNCTION_ARG +#endif +#undef BOOST_FUNCTION_ARGS +#undef BOOST_FUNCTION_ARG_TYPE +#undef BOOST_FUNCTION_ARG_TYPES +#undef BOOST_FUNCTION_VOID_RETURN_TYPE +#undef BOOST_FUNCTION_RETURN + +#if defined(BOOST_MSVC) +# pragma warning( pop ) +#endif diff --git a/src/vendor/boost/function_equal.hpp b/src/vendor/boost/function_equal.hpp new file mode 100644 index 000000000..2d76c75bc --- /dev/null +++ b/src/vendor/boost/function_equal.hpp @@ -0,0 +1,28 @@ +// Copyright Douglas Gregor 2004. +// Copyright 2005 Peter Dimov + +// Use, modification and distribution is subject to +// the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// For more information, see http://www.boost.org +#ifndef BOOST_FUNCTION_EQUAL_HPP +#define BOOST_FUNCTION_EQUAL_HPP + +namespace boost { + +template + bool function_equal_impl(const F& f, const G& g, long) + { return f == g; } + +// function_equal_impl needs to be unqualified to pick +// user overloads on two-phase compilers + +template + bool function_equal(const F& f, const G& g) + { return function_equal_impl(f, g, 0); } + +} // end namespace boost + +#endif // BOOST_FUNCTION_EQUAL_HPP diff --git a/src/vendor/boost/get_pointer.hpp b/src/vendor/boost/get_pointer.hpp new file mode 100644 index 000000000..b8d82f075 --- /dev/null +++ b/src/vendor/boost/get_pointer.hpp @@ -0,0 +1,76 @@ +// Copyright Peter Dimov and David Abrahams 2002. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +#ifndef GET_POINTER_DWA20021219_HPP +#define GET_POINTER_DWA20021219_HPP + +#include + +// In order to avoid circular dependencies with Boost.TR1 +// we make sure that our include of doesn't try to +// pull in the TR1 headers: that's why we use this header +// rather than including directly: +#include // std::auto_ptr + +namespace boost { + +// get_pointer(p) extracts a ->* capable pointer from p + +template T * get_pointer(T * p) +{ + return p; +} + +// get_pointer(shared_ptr const & p) has been moved to shared_ptr.hpp + +#if !defined( BOOST_NO_AUTO_PTR ) + +#if defined( __GNUC__ ) && (defined( __GXX_EXPERIMENTAL_CXX0X__ ) || (__cplusplus >= 201103L)) +#if defined( BOOST_GCC ) +#if BOOST_GCC >= 40600 +#define BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS +#endif // BOOST_GCC >= 40600 +#elif defined( __clang__ ) && defined( __has_warning ) +#if __has_warning("-Wdeprecated-declarations") +#define BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS +#endif // __has_warning("-Wdeprecated-declarations") +#endif +#endif // defined( __GNUC__ ) && (defined( __GXX_EXPERIMENTAL_CXX0X__ ) || (__cplusplus >= 201103L)) + +#if defined( BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS ) +// Disable libstdc++ warnings about std::auto_ptr being deprecated in C++11 mode +#pragma GCC diagnostic push + //#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#define BOOST_CORE_DETAIL_DISABLED_DEPRECATED_WARNINGS +#endif + +template T * get_pointer(std::auto_ptr const& p) +{ + return p.get(); +} + +#if defined( BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS ) +#pragma GCC diagnostic pop +#undef BOOST_CORE_DETAIL_DISABLE_LIBSTDCXX_DEPRECATED_WARNINGS +#endif + +#endif // !defined( BOOST_NO_AUTO_PTR ) + +#if !defined( BOOST_NO_CXX11_SMART_PTR ) + +template T * get_pointer( std::unique_ptr const& p ) +{ + return p.get(); +} + +template T * get_pointer( std::shared_ptr const& p ) +{ + return p.get(); +} + +#endif + +} // namespace boost + +#endif // GET_POINTER_DWA20021219_HPP diff --git a/src/vendor/boost/integer.hpp b/src/vendor/boost/integer.hpp new file mode 100644 index 000000000..6db0f7641 --- /dev/null +++ b/src/vendor/boost/integer.hpp @@ -0,0 +1,262 @@ +// boost integer.hpp header file -------------------------------------------// + +// Copyright Beman Dawes and Daryle Walker 1999. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +// Revision History +// 22 Sep 01 Added value-based integer templates. (Daryle Walker) +// 01 Apr 01 Modified to use new header. (John Maddock) +// 30 Jul 00 Add typename syntax fix (Jens Maurer) +// 28 Aug 99 Initial version + +#ifndef BOOST_INTEGER_HPP +#define BOOST_INTEGER_HPP + +#include // self include + +#include // for boost::::boost::integer_traits +#include // for ::std::numeric_limits +#include // for boost::int64_t and BOOST_NO_INTEGRAL_INT64_T +#include + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +// boost/integer.hpp:77:30: warning: use of C99 long long integer constant +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +namespace boost +{ + + // Helper templates ------------------------------------------------------// + + // fast integers from least integers + // int_fast_t<> works correctly for unsigned too, in spite of the name. + template< typename LeastInt > + struct int_fast_t + { + typedef LeastInt fast; + typedef fast type; + }; // imps may specialize + + namespace detail{ + + // convert category to type + template< int Category > struct int_least_helper {}; // default is empty + template< int Category > struct uint_least_helper {}; // default is empty + + // specializatons: 1=long, 2=int, 3=short, 4=signed char, + // 6=unsigned long, 7=unsigned int, 8=unsigned short, 9=unsigned char + // no specializations for 0 and 5: requests for a type > long are in error +#ifdef BOOST_HAS_LONG_LONG + template<> struct int_least_helper<1> { typedef boost::long_long_type least; }; +#elif defined(BOOST_HAS_MS_INT64) + template<> struct int_least_helper<1> { typedef __int64 least; }; +#endif + template<> struct int_least_helper<2> { typedef long least; }; + template<> struct int_least_helper<3> { typedef int least; }; + template<> struct int_least_helper<4> { typedef short least; }; + template<> struct int_least_helper<5> { typedef signed char least; }; +#ifdef BOOST_HAS_LONG_LONG + template<> struct uint_least_helper<1> { typedef boost::ulong_long_type least; }; +#elif defined(BOOST_HAS_MS_INT64) + template<> struct uint_least_helper<1> { typedef unsigned __int64 least; }; +#endif + template<> struct uint_least_helper<2> { typedef unsigned long least; }; + template<> struct uint_least_helper<3> { typedef unsigned int least; }; + template<> struct uint_least_helper<4> { typedef unsigned short least; }; + template<> struct uint_least_helper<5> { typedef unsigned char least; }; + + template + struct exact_signed_base_helper{}; + template + struct exact_unsigned_base_helper{}; + + template <> struct exact_signed_base_helper { typedef signed char exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned char exact; }; +#if USHRT_MAX != UCHAR_MAX + template <> struct exact_signed_base_helper { typedef short exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned short exact; }; +#endif +#if UINT_MAX != USHRT_MAX + template <> struct exact_signed_base_helper { typedef int exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned int exact; }; +#endif +#if ULONG_MAX != UINT_MAX && ( !defined __TI_COMPILER_VERSION__ || \ + ( __TI_COMPILER_VERSION__ >= 7000000 && !defined __TI_40BIT_LONG__ ) ) + template <> struct exact_signed_base_helper { typedef long exact; }; + template <> struct exact_unsigned_base_helper { typedef unsigned long exact; }; +#endif +#if defined(BOOST_HAS_LONG_LONG) &&\ + ((defined(ULLONG_MAX) && (ULLONG_MAX != ULONG_MAX)) ||\ + (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX != ULONG_MAX)) ||\ + (defined(ULONGLONG_MAX) && (ULONGLONG_MAX != ULONG_MAX)) ||\ + (defined(_ULLONG_MAX) && (_ULLONG_MAX != ULONG_MAX))) + template <> struct exact_signed_base_helper { typedef boost::long_long_type exact; }; + template <> struct exact_unsigned_base_helper { typedef boost::ulong_long_type exact; }; +#endif + + + } // namespace detail + + // integer templates specifying number of bits ---------------------------// + + // signed + template< int Bits > // bits (including sign) required + struct int_t : public boost::detail::exact_signed_base_helper + { + BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::intmax_t) * CHAR_BIT), + "No suitable signed integer type with the requested number of bits is available."); + typedef typename boost::detail::int_least_helper + < +#ifdef BOOST_HAS_LONG_LONG + (Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) + +#else + 1 + +#endif + (Bits-1 <= ::std::numeric_limits::digits) + + (Bits-1 <= ::std::numeric_limits::digits) + + (Bits-1 <= ::std::numeric_limits::digits) + + (Bits-1 <= ::std::numeric_limits::digits) + >::least least; + typedef typename int_fast_t::type fast; + }; + + // unsigned + template< int Bits > // bits required + struct uint_t : public boost::detail::exact_unsigned_base_helper + { + BOOST_STATIC_ASSERT_MSG(Bits <= (int)(sizeof(boost::uintmax_t) * CHAR_BIT), + "No suitable unsigned integer type with the requested number of bits is available."); +#if (defined(BOOST_BORLANDC) || defined(__CODEGEAR__)) && defined(BOOST_NO_INTEGRAL_INT64_T) + // It's really not clear why this workaround should be needed... shrug I guess! JM + BOOST_STATIC_CONSTANT(int, s = + 6 + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits)); + typedef typename detail::int_least_helper< ::boost::uint_t::s>::least least; +#else + typedef typename boost::detail::uint_least_helper + < +#ifdef BOOST_HAS_LONG_LONG + (Bits <= (int)(sizeof(boost::long_long_type) * CHAR_BIT)) + +#else + 1 + +#endif + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + + (Bits <= ::std::numeric_limits::digits) + >::least least; +#endif + typedef typename int_fast_t::type fast; + // int_fast_t<> works correctly for unsigned too, in spite of the name. + }; + + // integer templates specifying extreme value ----------------------------// + + // signed +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MaxValue > // maximum value to require support +#else + template< long MaxValue > // maximum value to require support +#endif + struct int_max_value_t + { + typedef typename boost::detail::int_least_helper + < +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + (MaxValue <= ::boost::integer_traits::const_max) + +#else + 1 + +#endif + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + >::least least; + typedef typename int_fast_t::type fast; + }; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MinValue > // minimum value to require support +#else + template< long MinValue > // minimum value to require support +#endif + struct int_min_value_t + { + typedef typename boost::detail::int_least_helper + < +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) + (MinValue >= ::boost::integer_traits::const_min) + +#else + 1 + +#endif + (MinValue >= ::boost::integer_traits::const_min) + + (MinValue >= ::boost::integer_traits::const_min) + + (MinValue >= ::boost::integer_traits::const_min) + + (MinValue >= ::boost::integer_traits::const_min) + >::least least; + typedef typename int_fast_t::type fast; + }; + + // unsigned +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::ulong_long_type MaxValue > // minimum value to require support +#else + template< unsigned long MaxValue > // minimum value to require support +#endif + struct uint_value_t + { +#if (defined(BOOST_BORLANDC) || defined(__CODEGEAR__)) + // It's really not clear why this workaround should be needed... shrug I guess! JM +#if defined(BOOST_NO_INTEGRAL_INT64_T) + BOOST_STATIC_CONSTANT(unsigned, which = + 1 + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max)); + typedef typename detail::int_least_helper< ::boost::uint_value_t::which>::least least; +#else // BOOST_NO_INTEGRAL_INT64_T + BOOST_STATIC_CONSTANT(unsigned, which = + 1 + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max)); + typedef typename detail::uint_least_helper< ::boost::uint_value_t::which>::least least; +#endif // BOOST_NO_INTEGRAL_INT64_T +#else + typedef typename boost::detail::uint_least_helper + < +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + (MaxValue <= ::boost::integer_traits::const_max) + +#else + 1 + +#endif + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + + (MaxValue <= ::boost::integer_traits::const_max) + >::least least; +#endif + typedef typename int_fast_t::type fast; + }; + + +} // namespace boost + +#endif // BOOST_INTEGER_HPP diff --git a/src/vendor/boost/integer_fwd.hpp b/src/vendor/boost/integer_fwd.hpp new file mode 100644 index 000000000..18519dd69 --- /dev/null +++ b/src/vendor/boost/integer_fwd.hpp @@ -0,0 +1,190 @@ +// Boost integer_fwd.hpp header file ---------------------------------------// + +// (C) Copyright Dave Abrahams and Daryle Walker 2001. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +// See http://www.boost.org/libs/integer for documentation. + +#ifndef BOOST_INTEGER_FWD_HPP +#define BOOST_INTEGER_FWD_HPP + +#include // for UCHAR_MAX, etc. +#include // for std::size_t + +#include // for BOOST_NO_INTRINSIC_WCHAR_T +#include // for std::numeric_limits +#include // For intmax_t + + +namespace boost +{ + +#ifdef BOOST_NO_INTEGRAL_INT64_T + typedef unsigned long static_log2_argument_type; + typedef int static_log2_result_type; + typedef long static_min_max_signed_type; + typedef unsigned long static_min_max_unsigned_type; +#else + typedef boost::uintmax_t static_min_max_unsigned_type; + typedef boost::intmax_t static_min_max_signed_type; + typedef boost::uintmax_t static_log2_argument_type; + typedef int static_log2_result_type; +#endif + +// From ------------------------------------------------// + +// Only has typedefs or using statements, with #conditionals + + +// From -----------------------------------------// + +template < class T > + class integer_traits; + +template < > + class integer_traits< bool >; + +template < > + class integer_traits< char >; + +template < > + class integer_traits< signed char >; + +template < > + class integer_traits< unsigned char >; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template < > + class integer_traits< wchar_t >; +#endif + +template < > + class integer_traits< short >; + +template < > + class integer_traits< unsigned short >; + +template < > + class integer_traits< int >; + +template < > + class integer_traits< unsigned int >; + +template < > + class integer_traits< long >; + +template < > + class integer_traits< unsigned long >; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_LONG_LONG) +template < > +class integer_traits< ::boost::long_long_type>; + +template < > +class integer_traits< ::boost::ulong_long_type >; +#elif !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) && defined(BOOST_HAS_MS_INT64) +template < > +class integer_traits<__int64>; + +template < > +class integer_traits; +#endif + + +// From ------------------------------------------------// + +template < typename LeastInt > + struct int_fast_t; + +template< int Bits > + struct int_t; + +template< int Bits > + struct uint_t; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MaxValue > // maximum value to require support +#else + template< long MaxValue > // maximum value to require support +#endif + struct int_max_value_t; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::long_long_type MinValue > // minimum value to require support +#else + template< long MinValue > // minimum value to require support +#endif + struct int_min_value_t; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && defined(BOOST_HAS_LONG_LONG) + template< boost::ulong_long_type MaxValue > // maximum value to require support +#else + template< unsigned long MaxValue > // maximum value to require support +#endif + struct uint_value_t; + + +// From -----------------------------------// + +template < std::size_t Bit > + struct high_bit_mask_t; + +template < std::size_t Bits > + struct low_bits_mask_t; + +template < > + struct low_bits_mask_t< ::std::numeric_limits::digits >; + +// From ------------------------------------// + +template + struct static_log2; + +template <> struct static_log2<0u>; + + +// From ---------------------------------// + +template + struct static_signed_min; + +template + struct static_signed_max; + +template + struct static_unsigned_min; + +template + struct static_unsigned_max; + + +namespace integer +{ +// From + +#ifdef BOOST_NO_INTEGRAL_INT64_T + typedef unsigned long static_gcd_type; +#else + typedef boost::uintmax_t static_gcd_type; +#endif + +template < static_gcd_type Value1, static_gcd_type Value2 > + struct static_gcd; +template < static_gcd_type Value1, static_gcd_type Value2 > + struct static_lcm; + + +// From + +template < typename IntegerType > + class gcd_evaluator; +template < typename IntegerType > + class lcm_evaluator; + +} // namespace integer + +} // namespace boost + + +#endif // BOOST_INTEGER_FWD_HPP diff --git a/src/vendor/boost/integer_traits.hpp b/src/vendor/boost/integer_traits.hpp new file mode 100644 index 000000000..aaaeed6ba --- /dev/null +++ b/src/vendor/boost/integer_traits.hpp @@ -0,0 +1,256 @@ +/* boost integer_traits.hpp header file + * + * Copyright Jens Maurer 2000 + * Distributed under the Boost Software License, Version 1.0. (See + * accompanying file LICENSE_1_0.txt or copy at + * http://www.boost.org/LICENSE_1_0.txt) + * + * $Id$ + * + * Idea by Beman Dawes, Ed Brey, Steve Cleary, and Nathan Myers + */ + +// See http://www.boost.org/libs/integer for documentation. + + +#ifndef BOOST_INTEGER_TRAITS_HPP +#define BOOST_INTEGER_TRAITS_HPP + +#include +#include + +// These are an implementation detail and not part of the interface +#include +// we need wchar.h for WCHAR_MAX/MIN but not all platforms provide it, +// and some may have but not ... +#if !defined(BOOST_NO_INTRINSIC_WCHAR_T) && (!defined(BOOST_NO_CWCHAR) || defined(sun) || defined(__sun) || defined(__QNX__)) +#include +#endif + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +// ../../../boost/integer_traits.hpp:164:66: warning: use of C99 long long integer constant +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +namespace boost { +template +class integer_traits : public std::numeric_limits +{ +public: + BOOST_STATIC_CONSTANT(bool, is_integral = false); +}; + +namespace detail { +template +class integer_traits_base +{ +public: + BOOST_STATIC_CONSTANT(bool, is_integral = true); + BOOST_STATIC_CONSTANT(T, const_min = min_val); + BOOST_STATIC_CONSTANT(T, const_max = max_val); +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template +const bool integer_traits_base::is_integral; + +template +const T integer_traits_base::const_min; + +template +const T integer_traits_base::const_max; +#endif + +} // namespace detail + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +#ifndef BOOST_NO_INTRINSIC_WCHAR_T +template<> +class integer_traits + : public std::numeric_limits, + // Don't trust WCHAR_MIN and WCHAR_MAX with Mac OS X's native + // library: they are wrong! +#if defined(WCHAR_MIN) && defined(WCHAR_MAX) && !defined(__APPLE__) + public detail::integer_traits_base +#elif defined(BOOST_BORLANDC) || defined(__CYGWIN__) || defined(__MINGW32__) || (defined(__BEOS__) && defined(__GNUC__)) + // No WCHAR_MIN and WCHAR_MAX, whar_t is short and unsigned: + public detail::integer_traits_base +#elif (defined(__sgi) && (!defined(__SGI_STL_PORT) || __SGI_STL_PORT < 0x400))\ + || (defined __APPLE__)\ + || (defined(__OpenBSD__) && defined(__GNUC__))\ + || (defined(__NetBSD__) && defined(__GNUC__))\ + || (defined(__FreeBSD__) && defined(__GNUC__))\ + || (defined(__DragonFly__) && defined(__GNUC__))\ + || (defined(__hpux) && defined(__GNUC__) && (__GNUC__ == 3) && !defined(__SGI_STL_PORT)) + // No WCHAR_MIN and WCHAR_MAX, wchar_t has the same range as int. + // - SGI MIPSpro with native library + // - gcc 3.x on HP-UX + // - Mac OS X with native library + // - gcc on FreeBSD, OpenBSD and NetBSD + public detail::integer_traits_base +#else +#error No WCHAR_MIN and WCHAR_MAX present, please adjust integer_traits<> for your compiler. +#endif +{ }; +#endif // BOOST_NO_INTRINSIC_WCHAR_T + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +template<> +class integer_traits + : public std::numeric_limits, + public detail::integer_traits_base +{ }; + +#if !defined(BOOST_NO_INTEGRAL_INT64_T) && !defined(BOOST_NO_INT64_T) +#if defined(ULLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LLONG_MIN, LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULLONG_MAX> +{ }; + +#elif defined(ULONG_LONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> : public std::numeric_limits< ::boost::long_long_type>, public detail::integer_traits_base< ::boost::long_long_type, LONG_LONG_MIN, LONG_LONG_MAX>{ }; +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONG_LONG_MAX> +{ }; + +#elif defined(ULONGLONG_MAX) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, LONGLONG_MIN, LONGLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ULONGLONG_MAX> +{ }; + +#elif defined(_LLONG_MAX) && defined(_C2) && defined(BOOST_HAS_LONG_LONG) + +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, -_LLONG_MAX - _C2, _LLONG_MAX> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, _ULLONG_MAX> +{ }; + +#elif defined(BOOST_HAS_LONG_LONG) +// +// we have long long but no constants, this happens for example with gcc in -ansi mode, +// we'll just have to work out the values for ourselves (assumes 2's compliment representation): +// +template<> +class integer_traits< ::boost::long_long_type> + : public std::numeric_limits< ::boost::long_long_type>, + public detail::integer_traits_base< ::boost::long_long_type, (1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1)), ~(1LL << (sizeof(::boost::long_long_type) * CHAR_BIT - 1))> +{ }; + +template<> +class integer_traits< ::boost::ulong_long_type> + : public std::numeric_limits< ::boost::ulong_long_type>, + public detail::integer_traits_base< ::boost::ulong_long_type, 0, ~0uLL> +{ }; + +#elif defined(BOOST_HAS_MS_INT64) + +template<> +class integer_traits< __int64> + : public std::numeric_limits< __int64>, + public detail::integer_traits_base< __int64, _I64_MIN, _I64_MAX> +{ }; + +template<> +class integer_traits< unsigned __int64> + : public std::numeric_limits< unsigned __int64>, + public detail::integer_traits_base< unsigned __int64, 0, _UI64_MAX> +{ }; + +#endif +#endif + +} // namespace boost + +#endif /* BOOST_INTEGER_TRAITS_HPP */ + + + diff --git a/src/vendor/boost/intrusive/circular_slist_algorithms.hpp b/src/vendor/boost/intrusive/circular_slist_algorithms.hpp new file mode 100644 index 000000000..bc5b48178 --- /dev/null +++ b/src/vendor/boost/intrusive/circular_slist_algorithms.hpp @@ -0,0 +1,406 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! circular_slist_algorithms provides basic algorithms to manipulate nodes +//! forming a circular singly linked list. An empty circular list is formed by a node +//! whose pointer to the next node points to itself. +//! +//! circular_slist_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the circular list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class circular_slist_algorithms + /// @cond + : public detail::common_slist_algorithms + /// @endcond +{ + /// @cond + typedef detail::common_slist_algorithms base_t; + /// @endcond + public: + typedef typename NodeTraits::node node; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Constructs an non-used list element, putting the next + //! pointer to null: + //! NodeTraits::get_next(this_node) == node_ptr() + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(node_ptr this_node); + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! or it's a not inserted node: + //! return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool unique(const_node_ptr this_node); + + //! Effects: Returns true is "this_node" has the same state as + //! if it was inited using "init(node_ptr)" + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool inited(const_node_ptr this_node); + + //! Requires: prev_node must be in a circular list or be an empty circular list. + //! + //! Effects: Unlinks the next node of prev_node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(node_ptr prev_node); + + //! Requires: prev_node and last_node must be in a circular list + //! or be an empty circular list. + //! + //! Effects: Unlinks the range (prev_node, last_node) from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(node_ptr prev_node, node_ptr last_node); + + //! Requires: prev_node must be a node of a circular list. + //! + //! Effects: Links this_node after prev_node in the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void link_after(node_ptr prev_node, node_ptr this_node); + + //! Requires: b and e must be nodes of the same circular list or an empty range. + //! and p must be a node of a different circular list. + //! + //! Effects: Removes the nodes from (b, e] range from their circular list and inserts + //! them after p in p's circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer_after(node_ptr p, node_ptr b, node_ptr e); + + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void init_header(node_ptr this_node) + { NodeTraits::set_next(this_node, this_node); } + + //! Requires: this_node and prev_init_node must be in the same circular list. + //! + //! Effects: Returns the previous node of this_node in the circular list starting. + //! the search from prev_init_node. The first node checked for equality + //! is NodeTraits::get_next(prev_init_node). + //! + //! Complexity: Linear to the number of elements between prev_init_node and this_node. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr &prev_init_node, const node_ptr &this_node) + { return base_t::get_previous_node(prev_init_node, this_node); } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the previous node of this_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & this_node) + { return base_t::get_previous_node(this_node, this_node); } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the previous node of the previous node of this_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_previous_node(const node_ptr & this_node) + { return get_previous_previous_node(this_node, this_node); } + + //! Requires: this_node and p must be in the same circular list. + //! + //! Effects: Returns the previous node of the previous node of this_node in the + //! circular list starting. the search from p. The first node checked + //! for equality is NodeTraits::get_next((NodeTraits::get_next(p)). + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + static node_ptr get_previous_previous_node(node_ptr p, const node_ptr & this_node) + { + node_ptr p_next = NodeTraits::get_next(p); + node_ptr p_next_next = NodeTraits::get_next(p_next); + while (this_node != p_next_next){ + p = p_next; + p_next = p_next_next; + p_next_next = NodeTraits::get_next(p_next); + } + return p; + } + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns the number of nodes in a circular list. If the circular list + //! is empty, returns 1. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t count(const const_node_ptr & this_node) + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + } while (p != this_node); + return result; + } + + //! Requires: this_node must be in a circular list, be an empty circular list or be inited. + //! + //! Effects: Unlinks the node from the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void unlink(node_ptr this_node) + { + if(NodeTraits::get_next(this_node)) + base_t::unlink_after(get_previous_node(this_node)); + } + + //! Requires: nxt_node must be a node of a circular list. + //! + //! Effects: Links this_node before nxt_node in the circular list. + //! + //! Complexity: Linear to the number of elements in the circular list. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void link_before (node_ptr nxt_node, node_ptr this_node) + { base_t::link_after(get_previous_node(nxt_node), this_node); } + + //! Requires: this_node and other_node must be nodes inserted + //! in circular lists or be empty circular lists. + //! + //! Effects: Swaps the position of the nodes: this_node is inserted in + //! other_nodes position in the second circular list and the other_node is inserted + //! in this_node's position in the first circular list. + //! + //! Complexity: Linear to number of elements of both lists + //! + //! Throws: Nothing. + static void swap_nodes(node_ptr this_node, node_ptr other_node) + { + if (other_node == this_node) + return; + const node_ptr this_next = NodeTraits::get_next(this_node); + const node_ptr other_next = NodeTraits::get_next(other_node); + const bool this_null = !this_next; + const bool other_null = !other_next; + const bool this_empty = this_next == this_node; + const bool other_empty = other_next == other_node; + + if(!(other_null || other_empty)){ + NodeTraits::set_next(this_next == other_node ? other_node : get_previous_node(other_node), this_node ); + } + if(!(this_null | this_empty)){ + NodeTraits::set_next(other_next == this_node ? this_node : get_previous_node(this_node), other_node ); + } + NodeTraits::set_next(this_node, other_empty ? this_node : (other_next == this_node ? other_node : other_next) ); + NodeTraits::set_next(other_node, this_empty ? other_node : (this_next == other_node ? this_node : this_next ) ); + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + static void reverse(node_ptr p) + { + node_ptr i = NodeTraits::get_next(p), e(p); + for (;;) { + node_ptr nxt(NodeTraits::get_next(i)); + if (nxt == e) + break; + base_t::transfer_after(e, i, nxt); + } + } + + //! Effects: Moves the node p n positions towards the end of the list. + //! + //! Returns: The previous node of p after the function if there has been any movement, + //! Null if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static node_ptr move_backwards(node_ptr p, std::size_t n) + { + //Null shift, nothing to do + if(!n) return node_ptr(); + node_ptr first = NodeTraits::get_next(p); + + //count() == 1 or 2, nothing to do + if(NodeTraits::get_next(first) == p) + return node_ptr(); + + bool end_found = false; + node_ptr new_last = node_ptr(); + + //Now find the new last node according to the shift count. + //If we find p before finding the new last node + //unlink p, shortcut the search now that we know the size of the list + //and continue. + for(std::size_t i = 1; i <= n; ++i){ + new_last = first; + first = NodeTraits::get_next(first); + if(first == p){ + //Shortcut the shift with the modulo of the size of the list + n %= i; + if(!n) + return node_ptr(); + i = 0; + //Unlink p and continue the new first node search + first = NodeTraits::get_next(p); + base_t::unlink_after(new_last); + end_found = true; + } + } + + //If the p has not been found in the previous loop, find it + //starting in the new first node and unlink it + if(!end_found){ + base_t::unlink_after(base_t::get_previous_node(first, p)); + } + + //Now link p after the new last node + base_t::link_after(new_last, p); + return new_last; + } + + //! Effects: Moves the node p n positions towards the beginning of the list. + //! + //! Returns: The previous node of p after the function if there has been any movement, + //! Null if n leads equals to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static node_ptr move_forward(node_ptr p, std::size_t n) + { + //Null shift, nothing to do + if(!n) return node_ptr(); + node_ptr first = node_traits::get_next(p); + + //count() == 1 or 2, nothing to do + if(node_traits::get_next(first) == p) return node_ptr(); + + //Iterate until p is found to know where the current last node is. + //If the shift count is less than the size of the list, we can also obtain + //the position of the new last node after the shift. + node_ptr old_last(first), next_to_it, new_last(p); + std::size_t distance = 1; + while(p != (next_to_it = node_traits::get_next(old_last))){ + if(++distance > n) + new_last = node_traits::get_next(new_last); + old_last = next_to_it; + } + //If the shift was bigger or equal than the size, obtain the equivalent + //forward shifts and find the new last node. + if(distance <= n){ + //Now find the equivalent forward shifts. + //Shortcut the shift with the modulo of the size of the list + std::size_t new_before_last_pos = (distance - (n % distance))% distance; + //If the shift is a multiple of the size there is nothing to do + if(!new_before_last_pos) return node_ptr(); + + for( new_last = p + ; new_before_last_pos-- + ; new_last = node_traits::get_next(new_last)){ + //empty + } + } + + //Now unlink p and link it after the new last node + base_t::unlink_after(old_last); + base_t::link_after(new_last, p); + return new_last; + } +}; + +/// @cond + +template +struct get_algo +{ + typedef circular_slist_algorithms type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_CIRCULAR_SLIST_ALGORITHMS_HPP diff --git a/src/vendor/boost/intrusive/detail/algo_type.hpp b/src/vendor/boost/intrusive/detail/algo_type.hpp new file mode 100644 index 000000000..70ec63f57 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/algo_type.hpp @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP +#define BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +enum algo_types +{ + CircularListAlgorithms, + CircularSListAlgorithms, + LinearSListAlgorithms, + CommonSListAlgorithms, + BsTreeAlgorithms, + RbTreeAlgorithms, + AvlTreeAlgorithms, + SgTreeAlgorithms, + SplayTreeAlgorithms, + TreapAlgorithms, + UnorderedAlgorithms, + UnorderedCircularSlistAlgorithms, + AnyAlgorithm +}; + +template +struct get_algo; + +template +struct get_node_checker; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_ALGO_TYPE_HPP diff --git a/src/vendor/boost/intrusive/detail/algorithm.hpp b/src/vendor/boost/intrusive/detail/algorithm.hpp new file mode 100644 index 000000000..d2421ffaa --- /dev/null +++ b/src/vendor/boost/intrusive/detail/algorithm.hpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP +#define BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +struct algo_pred_equal +{ + template + bool operator()(const T &x, const T &y) const + { return x == y; } +}; + +struct algo_pred_less +{ + template + bool operator()(const T &x, const T &y) const + { return x < y; } +}; + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p) +{ + for (; first1 != last1; ++first1, ++first2) { + if (!p(*first1, *first2)) { + return false; + } + } + return true; +} + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) +{ return (algo_equal)(first1, last1, first2, algo_pred_equal()); } + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate pred) +{ + for (; first1 != last1 && first2 != last2; ++first1, ++first2) + if (!pred(*first1, *first2)) + return false; + return first1 == last1 && first2 == last2; +} + +template +bool algo_equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2) +{ return (algo_equal)(first1, last1, first2, last2, algo_pred_equal()); } + +template + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2, + BinaryPredicate pred) +{ + while (first1 != last1){ + if (first2 == last2 || *first2 < *first1) return false; + else if (pred(*first1, *first2)) return true; + ++first1; ++first2; + } + return (first2 != last2); +} + +template + bool algo_lexicographical_compare (InputIterator1 first1, InputIterator1 last1, + InputIterator2 first2, InputIterator2 last2) +{ return (algo_lexicographical_compare)(first1, last1, first2, last2, algo_pred_less()); } + +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_ALGORITHM_HPP diff --git a/src/vendor/boost/intrusive/detail/array_initializer.hpp b/src/vendor/boost/intrusive/detail/array_initializer.hpp new file mode 100644 index 000000000..d9ed5bd97 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/array_initializer.hpp @@ -0,0 +1,96 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP +#define BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +//This is not standard, but should work with all compilers +union max_align +{ + char char_; + short short_; + int int_; + long long_; + #ifdef BOOST_HAS_LONG_LONG + ::boost::long_long_type long_long_; + #endif + float float_; + double double_; + long double long_double_; + void * void_ptr_; +}; + +template +class array_initializer +{ + public: + template + array_initializer(const CommonInitializer &init) + { + char *init_buf = (char*)rawbuf; + std::size_t i = 0; + BOOST_TRY{ + for(; i != N; ++i){ + ::new(init_buf, boost_move_new_t()) T(init); + init_buf += sizeof(T); + } + } + BOOST_CATCH(...){ + while(i--){ + init_buf -= sizeof(T); + ((T*)init_buf)->~T(); + } + BOOST_RETHROW; + } + BOOST_CATCH_END + } + + operator T* () + { return (T*)(rawbuf); } + + operator const T*() const + { return (const T*)(rawbuf); } + + ~array_initializer() + { + char *init_buf = (char*)rawbuf + N*sizeof(T); + for(std::size_t i = 0; i != N; ++i){ + init_buf -= sizeof(T); + ((T*)init_buf)->~T(); + } + } + + private: + detail::max_align rawbuf[(N*sizeof(T)-1)/sizeof(detail::max_align)+1]; +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_ARRAY_INITIALIZER_HPP diff --git a/src/vendor/boost/intrusive/detail/assert.hpp b/src/vendor/boost/intrusive/detail/assert.hpp new file mode 100644 index 000000000..7199eb240 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/assert.hpp @@ -0,0 +1,45 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ASSERT_HPP +#define BOOST_INTRUSIVE_DETAIL_ASSERT_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +#pragma once +#endif + +#if !defined(BOOST_INTRUSIVE_INVARIANT_ASSERT) + #include + #define BOOST_INTRUSIVE_INVARIANT_ASSERT BOOST_ASSERT +#elif defined(BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE) + #include BOOST_INTRUSIVE_INVARIANT_ASSERT_INCLUDE +#endif + +#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT) + #include + #define BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT BOOST_ASSERT +#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE) + #include BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE +#endif + +#if !defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT) + #include + #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT BOOST_ASSERT +#elif defined(BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE) + #include BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE +#endif + +#endif //BOOST_INTRUSIVE_DETAIL_ASSERT_HPP diff --git a/src/vendor/boost/intrusive/detail/common_slist_algorithms.hpp b/src/vendor/boost/intrusive/detail/common_slist_algorithms.hpp new file mode 100644 index 000000000..88f3fedac --- /dev/null +++ b/src/vendor/boost/intrusive/detail/common_slist_algorithms.hpp @@ -0,0 +1,198 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class common_slist_algorithms +{ + public: + typedef typename NodeTraits::node node; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + static node_ptr get_previous_node(node_ptr p, const node_ptr & this_node) + { + for( node_ptr p_next + ; this_node != (p_next = NodeTraits::get_next(p)) + ; p = p_next){ + //Logic error: possible use of linear lists with + //operations only permitted with circular lists + BOOST_INTRUSIVE_INVARIANT_ASSERT(p); + } + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static void init(node_ptr this_node) + { NodeTraits::set_next(this_node, node_ptr()); } + + BOOST_INTRUSIVE_FORCEINLINE static bool unique(const const_node_ptr & this_node) + { + node_ptr next = NodeTraits::get_next(this_node); + return !next || next == this_node; + } + + BOOST_INTRUSIVE_FORCEINLINE static bool inited(const const_node_ptr & this_node) + { return !NodeTraits::get_next(this_node); } + + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node) + { + const_node_ptr this_node(NodeTraits::get_next(prev_node)); + NodeTraits::set_next(prev_node, NodeTraits::get_next(this_node)); + } + + BOOST_INTRUSIVE_FORCEINLINE static void unlink_after(node_ptr prev_node, node_ptr last_node) + { NodeTraits::set_next(prev_node, last_node); } + + BOOST_INTRUSIVE_FORCEINLINE static void link_after(node_ptr prev_node, node_ptr this_node) + { + NodeTraits::set_next(this_node, NodeTraits::get_next(prev_node)); + NodeTraits::set_next(prev_node, this_node); + } + + BOOST_INTRUSIVE_FORCEINLINE static void incorporate_after(node_ptr bp, node_ptr b, node_ptr be) + { + node_ptr p(NodeTraits::get_next(bp)); + NodeTraits::set_next(bp, b); + NodeTraits::set_next(be, p); + } + + static void transfer_after(node_ptr bp, node_ptr bb, node_ptr be) + { + if (bp != bb && bp != be && bb != be) { + node_ptr next_b = NodeTraits::get_next(bb); + node_ptr next_e = NodeTraits::get_next(be); + node_ptr next_p = NodeTraits::get_next(bp); + NodeTraits::set_next(bb, next_e); + NodeTraits::set_next(be, next_p); + NodeTraits::set_next(bp, next_b); + } + } + + struct stable_partition_info + { + std::size_t num_1st_partition; + std::size_t num_2nd_partition; + node_ptr beg_2st_partition; + node_ptr new_last_node; + }; + + template + static void stable_partition(node_ptr before_beg, node_ptr end, Pred pred, stable_partition_info &info) + { + node_ptr bcur = before_beg; + node_ptr cur = node_traits::get_next(bcur); + node_ptr new_f = end; + + std::size_t num1 = 0, num2 = 0; + while(cur != end){ + if(pred(cur)){ + ++num1; + bcur = cur; + cur = node_traits::get_next(cur); + } + else{ + ++num2; + node_ptr last_to_remove = bcur; + new_f = cur; + bcur = cur; + cur = node_traits::get_next(cur); + BOOST_TRY{ + //Main loop + while(cur != end){ + if(pred(cur)){ //Might throw + ++num1; + //Process current node + node_traits::set_next(last_to_remove, cur); + last_to_remove = cur; + node_ptr nxt = node_traits::get_next(cur); + node_traits::set_next(bcur, nxt); + cur = nxt; + } + else{ + ++num2; + bcur = cur; + cur = node_traits::get_next(cur); + } + } + } + BOOST_CATCH(...){ + node_traits::set_next(last_to_remove, new_f); + BOOST_RETHROW; + } + BOOST_CATCH_END + node_traits::set_next(last_to_remove, new_f); + break; + } + } + info.num_1st_partition = num1; + info.num_2nd_partition = num2; + info.beg_2st_partition = new_f; + info.new_last_node = bcur; + } + + //! Requires: f and l must be in a circular list. + //! + //! Effects: Returns the number of nodes in the range [f, l). + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t distance(const const_node_ptr &f, const const_node_ptr &l) + { + const_node_ptr i(f); + std::size_t result = 0; + while(i != l){ + i = NodeTraits::get_next(i); + ++result; + } + return result; + } +}; + +/// @endcond + +} //namespace detail + +/// @cond + +template +struct get_algo +{ + typedef detail::common_slist_algorithms type; +}; + + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_COMMON_SLIST_ALGORITHMS_HPP diff --git a/src/vendor/boost/intrusive/detail/config_begin.hpp b/src/vendor/boost/intrusive/detail/config_begin.hpp new file mode 100644 index 000000000..8bd57a3b5 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/config_begin.hpp @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +#ifdef BOOST_MSVC + + #pragma warning (push) + #pragma warning (disable : 4275) // non DLL-interface classkey "identifier" used as base for DLL-interface classkey "identifier" + #pragma warning (disable : 4251) // "identifier" : class "type" needs to have dll-interface to be used by clients of class "type2" + #pragma warning (disable : 4675) // "method" should be declared "static" and have exactly one parameter + #pragma warning (disable : 4996) // "function": was declared deprecated + #pragma warning (disable : 4503) // "identifier" : decorated name length exceeded, name was truncated + #pragma warning (disable : 4284) // odd return type for operator-> + #pragma warning (disable : 4244) // possible loss of data + #pragma warning (disable : 4521) ////Disable "multiple copy constructors specified" + #pragma warning (disable : 4127) //conditional expression is constant + #pragma warning (disable : 4146) // unary minus operator applied to unsigned type, result still unsigned + #pragma warning (disable : 4267) //conversion from 'X' to 'Y', possible loss of data + #pragma warning (disable : 4541) //'typeid' used on polymorphic type 'boost::exception' with /GR- + #pragma warning (disable : 4512) //'typeid' used on polymorphic type 'boost::exception' with /GR- + #pragma warning (disable : 4522) // "class" : multiple assignment operators specified + #pragma warning (disable : 4706) //assignment within conditional expression + #pragma warning (disable : 4710) // function not inlined + #pragma warning (disable : 4714) // "function": marked as __forceinline not inlined + #pragma warning (disable : 4711) // function selected for automatic inline expansion + #pragma warning (disable : 4786) // identifier truncated in debug info + #pragma warning (disable : 4996) // "function": was declared deprecated +#endif + +//#define BOOST_INTRUSIVE_USE_ITERATOR_FACADE +//#define BOOST_INTRUSIVE_USE_ITERATOR_ENABLE_IF_CONVERTIBLE diff --git a/src/vendor/boost/intrusive/detail/config_end.hpp b/src/vendor/boost/intrusive/detail/config_end.hpp new file mode 100644 index 000000000..a081443e6 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/config_end.hpp @@ -0,0 +1,15 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#if defined BOOST_MSVC + #pragma warning (pop) +#endif diff --git a/src/vendor/boost/intrusive/detail/default_header_holder.hpp b/src/vendor/boost/intrusive/detail/default_header_holder.hpp new file mode 100644 index 000000000..ba561b5f5 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/default_header_holder.hpp @@ -0,0 +1,70 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +// trivial header node holder +template < typename NodeTraits > +struct default_header_holder : public NodeTraits::node +{ + typedef NodeTraits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + + default_header_holder() : node() {} + + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr get_node() const + { return pointer_traits< const_node_ptr >::pointer_to(*static_cast< const node* >(this)); } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr get_node() + { return pointer_traits< node_ptr >::pointer_to(*static_cast< node* >(this)); } + + // (unsafe) downcast used to implement container-from-iterator + BOOST_INTRUSIVE_FORCEINLINE static default_header_holder* get_holder(const node_ptr &p) + { return static_cast< default_header_holder* >(boost::movelib::to_raw_pointer(p)); } +}; + +// type function producing the header node holder +template < typename ValueTraits, typename HeaderHolder > +struct get_header_holder_type +{ + typedef HeaderHolder type; +}; +template < typename ValueTraits > +struct get_header_holder_type< ValueTraits, void > +{ + typedef default_header_holder< typename ValueTraits::node_traits > type; +}; + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_DEFAULT_HEADER_HOLDER_HPP diff --git a/src/vendor/boost/intrusive/detail/ebo_functor_holder.hpp b/src/vendor/boost/intrusive/detail/ebo_functor_holder.hpp new file mode 100644 index 000000000..888316678 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/ebo_functor_holder.hpp @@ -0,0 +1,292 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Joaquin M Lopez Munoz 2006-2013 +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +#if defined(BOOST_MSVC) || defined(__BORLANDC_) +#define BOOST_INTRUSIVE_TT_DECL __cdecl +#else +#define BOOST_INTRUSIVE_TT_DECL +#endif + +#if defined(_MSC_EXTENSIONS) && !defined(__BORLAND__) && !defined(_WIN64) && !defined(_M_ARM) && !defined(_M_ARM64) && !defined(UNDER_CE) +#define BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = false; }; + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#ifndef _MANAGED + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#ifndef _MANAGED + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +// see boost ticket #4094 +// avoid duplicate definitions of is_unary_or_binary_function_impl +#ifndef BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#else // BOOST_INTRUSIVE_TT_TEST_MSC_FUNC_SIGS + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#ifndef _MANAGED + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; + +template +struct is_unary_or_binary_function_impl +{ static const bool value = true; }; +#endif + +template +struct is_unary_or_binary_function_impl +{ static const bool value = false; }; + +template +struct is_unary_or_binary_function : is_unary_or_binary_function_impl +{}; + +template::value> +class ebo_functor_holder +{ + BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) + + public: + typedef T functor_type; + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder() + : t_() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t) + : t_(t) + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t) + : t_(::boost::move(t)) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) + : t_(::boost::forward(arg1), ::boost::forward(arg2)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x) + : t_(x.t_) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x) + : t_(x.t_) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x) + { + this->get() = x.get(); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x) + { + this->get() = ::boost::move(x.get()); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x) + { + this->get() = x; + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x) + { + this->get() = ::boost::move(x); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE T& get(){return t_;} + BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return t_;} + + private: + T t_; +}; + +template +class ebo_functor_holder + : public T +{ + BOOST_COPYABLE_AND_MOVABLE(ebo_functor_holder) + + public: + typedef T functor_type; + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder() + : T() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(const T &t) + : T(t) + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit ebo_functor_holder(BOOST_RV_REF(T) t) + : T(::boost::move(t)) + {} + + template + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_FWD_REF(Arg1) arg1, BOOST_FWD_REF(Arg2) arg2) + : T(::boost::forward(arg1), ::boost::forward(arg2)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(const ebo_functor_holder &x) + : T(static_cast(x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder(BOOST_RV_REF(ebo_functor_holder) x) + : T(BOOST_MOVE_BASE(T, x)) + {} + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_COPY_ASSIGN_REF(ebo_functor_holder) x) + { + const ebo_functor_holder&r = x; + this->get() = r; + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(ebo_functor_holder) x) + { + this->get() = ::boost::move(x.get()); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(const T &x) + { + this->get() = x; + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE ebo_functor_holder& operator=(BOOST_RV_REF(T) x) + { + this->get() = ::boost::move(x); + return *this; + } + + BOOST_INTRUSIVE_FORCEINLINE T& get(){return *this;} + BOOST_INTRUSIVE_FORCEINLINE const T& get()const{return *this;} +}; + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_EBO_HOLDER_HPP diff --git a/src/vendor/boost/intrusive/detail/equal_to_value.hpp b/src/vendor/boost/intrusive/detail/equal_to_value.hpp new file mode 100644 index 000000000..c5d9e5305 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/equal_to_value.hpp @@ -0,0 +1,50 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP +#define BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +//This functor compares a stored value +//and the one passed as an argument +template +class equal_to_value +{ + ConstReference t_; + + public: + equal_to_value(ConstReference t) + : t_(t) + {} + + BOOST_INTRUSIVE_FORCEINLINE bool operator()(ConstReference t)const + { return t_ == t; } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_EQUAL_TO_VALUE_HPP diff --git a/src/vendor/boost/intrusive/detail/exception_disposer.hpp b/src/vendor/boost/intrusive/detail/exception_disposer.hpp new file mode 100644 index 000000000..91c5bf3b6 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/exception_disposer.hpp @@ -0,0 +1,90 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP +#define BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +class exception_disposer +{ + Container *cont_; + Disposer &disp_; + + exception_disposer(const exception_disposer&); + exception_disposer &operator=(const exception_disposer&); + + public: + exception_disposer(Container &cont, Disposer &disp) + : cont_(&cont), disp_(disp) + {} + + BOOST_INTRUSIVE_FORCEINLINE void release() + { cont_ = 0; } + + ~exception_disposer() + { + if(cont_){ + cont_->clear_and_dispose(disp_); + } + } +}; + +template +class exception_array_disposer +{ + Container *cont_; + Disposer &disp_; + SizeType &constructed_; + + exception_array_disposer(const exception_array_disposer&); + exception_array_disposer &operator=(const exception_array_disposer&); + + public: + + exception_array_disposer + (Container &cont, Disposer &disp, SizeType &constructed) + : cont_(&cont), disp_(disp), constructed_(constructed) + {} + + BOOST_INTRUSIVE_FORCEINLINE void release() + { cont_ = 0; } + + ~exception_array_disposer() + { + SizeType n = constructed_; + if(cont_){ + while(n--){ + cont_[n].clear_and_dispose(disp_); + } + } + } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_EXCEPTION_DISPOSER_HPP diff --git a/src/vendor/boost/intrusive/detail/function_detector.hpp b/src/vendor/boost/intrusive/detail/function_detector.hpp new file mode 100644 index 000000000..5ecaeaf07 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/function_detector.hpp @@ -0,0 +1,92 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009-2013. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +// This code was modified from the code posted by Alexandre Courpron in his +// article "Interface Detection" in The Code Project: +// http://www.codeproject.com/KB/architecture/Detector.aspx +/////////////////////////////////////////////////////////////////////////////// +// Copyright 2007 Alexandre Courpron +// +// Permission to use, copy, modify, redistribute and sell this software, +// provided that this copyright notice appears on all copies of the software. +/////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP +#define BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { +namespace function_detector { + + typedef char NotFoundType; + struct StaticFunctionType { NotFoundType x [2]; }; + struct NonStaticFunctionType { NotFoundType x [3]; }; + + enum + { NotFound = 0, + StaticFunction = sizeof( StaticFunctionType ) - sizeof( NotFoundType ), + NonStaticFunction = sizeof( NonStaticFunctionType ) - sizeof( NotFoundType ) + }; + +} //namespace boost { +} //namespace intrusive { +} //namespace function_detector { + +#define BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(Identifier, InstantiationKey) \ + namespace boost { \ + namespace intrusive { \ + namespace function_detector { \ + template < class T, \ + class NonStaticType, \ + class NonStaticConstType, \ + class StaticType > \ + class DetectMember_##InstantiationKey_##Identifier { \ + template < NonStaticType > \ + struct TestNonStaticNonConst ; \ + \ + template < NonStaticConstType > \ + struct TestNonStaticConst ; \ + \ + template < StaticType > \ + struct TestStatic ; \ + \ + template \ + static NonStaticFunctionType Test( TestNonStaticNonConst<&U::Identifier>*, int ); \ + \ + template \ + static NonStaticFunctionType Test( TestNonStaticConst<&U::Identifier>*, int ); \ + \ + template \ + static StaticFunctionType Test( TestStatic<&U::Identifier>*, int ); \ + \ + template \ + static NotFoundType Test( ... ); \ + public : \ + static const int check = NotFound + (sizeof(Test(0, 0)) - sizeof(NotFoundType));\ + };\ +}}} //namespace boost::intrusive::function_detector { + +#define BOOST_INTRUSIVE_DETECT_FUNCTION(Class, InstantiationKey, ReturnType, Identifier, Params) \ + ::boost::intrusive::function_detector::DetectMember_##InstantiationKey_##Identifier< Class,\ + ReturnType (Class::*)Params,\ + ReturnType (Class::*)Params const,\ + ReturnType (*)Params \ + >::check + +#endif //@ifndef BOOST_INTRUSIVE_DETAIL_FUNCTION_DETECTOR_HPP diff --git a/src/vendor/boost/intrusive/detail/generic_hook.hpp b/src/vendor/boost/intrusive/detail/generic_hook.hpp new file mode 100644 index 000000000..a4921dec8 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/generic_hook.hpp @@ -0,0 +1,223 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_GENERIC_HOOK_HPP +#define BOOST_INTRUSIVE_GENERIC_HOOK_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +/// @cond + +namespace detail { + +template +struct link_dispatch +{}; + +template +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch) +{ //If this assertion raises, you might have destroyed an object + //while it was still inserted in a container that is alive. + //If so, remove the object from the container before destroying it. + (void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked()); +} + +template +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &hook, detail::link_dispatch) +{ hook.unlink(); } + +template +BOOST_INTRUSIVE_FORCEINLINE void destructor_impl(Hook &, detail::link_dispatch) +{} + +} //namespace detail { + +enum base_hook_type +{ NoBaseHookId +, ListBaseHookId +, SlistBaseHookId +, RbTreeBaseHookId +, HashBaseHookId +, AvlTreeBaseHookId +, BsTreeBaseHookId +, TreapTreeBaseHookId +, AnyBaseHookId +}; + + +template +struct hook_tags_definer{}; + +template +struct hook_tags_definer +{ typedef HookTags default_list_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_slist_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_rbtree_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_hashtable_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_avltree_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_bstree_hook; }; + +template +struct hook_tags_definer +{ typedef HookTags default_any_hook; }; + +template + < class NodeTraits + , class Tag + , link_mode_type LinkMode + , base_hook_type BaseHookType + > +struct hooktags_impl +{ + static const link_mode_type link_mode = LinkMode; + typedef Tag tag; + typedef NodeTraits node_traits; + static const bool is_base_hook = !detail::is_same::value; + static const bool safemode_or_autounlink = is_safe_autounlink::value; + static const unsigned int type = BaseHookType; +}; + +/// @endcond + +template + < boost::intrusive::algo_types Algo + , class NodeTraits + , class Tag + , link_mode_type LinkMode + , base_hook_type BaseHookType + > +class generic_hook + /// @cond + //If the hook is a base hook, derive generic hook from node_holder + //so that a unique base class is created to convert from the node + //to the type. This mechanism will be used by bhtraits. + // + //If the hook is a member hook, generic hook will directly derive + //from the hook. + : public detail::if_c + < detail::is_same::value + , typename NodeTraits::node + , node_holder + >::type + //If this is the a default-tagged base hook derive from a class that + //will define an special internal typedef. Containers will be able to detect this + //special typedef and obtain generic_hook's internal types in order to deduce + //value_traits for this hook. + , public hook_tags_definer + < generic_hook + , detail::is_same::value ? BaseHookType : NoBaseHookId> + /// @endcond +{ + /// @cond + typedef typename get_algo::type node_algorithms; + typedef typename node_algorithms::node node; + typedef typename node_algorithms::node_ptr node_ptr; + typedef typename node_algorithms::const_node_ptr const_node_ptr; + + public: + + typedef hooktags_impl + < NodeTraits + , Tag, LinkMode, BaseHookType> hooktags; + + BOOST_INTRUSIVE_FORCEINLINE node_ptr this_ptr() + { return pointer_traits::pointer_to(static_cast(*this)); } + + BOOST_INTRUSIVE_FORCEINLINE const_node_ptr this_ptr() const + { return pointer_traits::pointer_to(static_cast(*this)); } + + public: + /// @endcond + + BOOST_INTRUSIVE_FORCEINLINE generic_hook() + { + if(hooktags::safemode_or_autounlink){ + node_algorithms::init(this->this_ptr()); + } + } + + BOOST_INTRUSIVE_FORCEINLINE generic_hook(const generic_hook& ) + { + if(hooktags::safemode_or_autounlink){ + node_algorithms::init(this->this_ptr()); + } + } + + BOOST_INTRUSIVE_FORCEINLINE generic_hook& operator=(const generic_hook& ) + { return *this; } + + BOOST_INTRUSIVE_FORCEINLINE ~generic_hook() + { + destructor_impl + (*this, detail::link_dispatch()); + } + + BOOST_INTRUSIVE_FORCEINLINE void swap_nodes(generic_hook &other) + { + node_algorithms::swap_nodes + (this->this_ptr(), other.this_ptr()); + } + + BOOST_INTRUSIVE_FORCEINLINE bool is_linked() const + { + //is_linked() can be only used in safe-mode or auto-unlink + BOOST_STATIC_ASSERT(( hooktags::safemode_or_autounlink )); + return !node_algorithms::unique(this->this_ptr()); + } + + BOOST_INTRUSIVE_FORCEINLINE void unlink() + { + BOOST_STATIC_ASSERT(( (int)hooktags::link_mode == (int)auto_unlink )); + node_ptr n(this->this_ptr()); + if(!node_algorithms::inited(n)){ + node_algorithms::unlink(n); + node_algorithms::init(n); + } + } +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_GENERIC_HOOK_HPP diff --git a/src/vendor/boost/intrusive/detail/get_value_traits.hpp b/src/vendor/boost/intrusive/detail/get_value_traits.hpp new file mode 100644 index 000000000..222f8078a --- /dev/null +++ b/src/vendor/boost/intrusive/detail/get_value_traits.hpp @@ -0,0 +1,222 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +template +struct is_default_hook_tag +{ static const bool value = false; }; + +namespace detail{ + +template +struct concrete_hook_base_value_traits +{ + typedef typename BaseHook::hooktags tags; + typedef bhtraits + < T + , typename tags::node_traits + , tags::link_mode + , typename tags::tag + , tags::type> type; +}; + +template +struct concrete_hook_base_value_traits +{ + typedef typename BaseHook::hooktags type; +}; + +template +struct any_hook_base_value_traits +{ + //AnyToSomeHook value_traits derive from a generic_hook + //The generic_hook is configured with any_node_traits + //and AnyToSomeHook::value_traits with the correct + //node traits for the container, so use node_traits + //from AnyToSomeHook_ProtoValueTraits and the rest of + //elements from the hooktags member of the generic_hook + + typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t; + typedef typename pointer_rebind + < typename basic_hook_t::hooktags::node_traits::node_ptr + , void>::type void_pointer; + typedef typename AnyToSomeHook_ProtoValueTraits::template + node_traits_from_voidptr::type node_traits; + + typedef bhtraits + < T + , node_traits + , basic_hook_t::hooktags::link_mode + , typename basic_hook_t::hooktags::tag + , basic_hook_t::hooktags::type + > type; +}; + +template +struct any_hook_base_value_traits +{ + typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t; + typedef typename pointer_rebind + < typename basic_hook_t::hooktags::node_traits::node_ptr + , void>::type void_pointer; + + struct type + { + typedef typename AnyToSomeHook_ProtoValueTraits::template + node_traits_from_voidptr::type node_traits; + }; +}; + +template +struct get_member_value_traits +{ + typedef typename MemberHook::member_value_traits type; +}; + +BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_any_hook, is_any_hook) +BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(internal_base_hook, hooktags::is_base_hook) + +template +struct internal_member_value_traits +{ + template static yes_type test(...); + template static no_type test(typename U::member_value_traits* = 0); + static const bool value = sizeof(test(0)) == sizeof(no_type); +}; + +template::value> +struct supposed_value_traits; + +template::value> +struct get_base_value_traits; + +template::value> +struct supposed_base_value_traits; + +template::value> +struct supposed_member_value_traits; + +template::value> +struct any_or_concrete_value_traits; + +//Base any hook +template +struct get_base_value_traits + : any_hook_base_value_traits +{}; + +//Non-any base hook +template +struct get_base_value_traits + : concrete_hook_base_value_traits +{}; + +//...It's a default hook +template +struct supposed_value_traits +{ typedef typename SupposedValueTraits::template apply::type type; }; + +//...Not a default hook +template +struct supposed_value_traits +{ typedef SupposedValueTraits type; }; + +//...It's a base hook +template +struct supposed_base_value_traits + : get_base_value_traits +{}; + +//...Not a base hook, try if it's a member or value_traits +template +struct supposed_base_value_traits + : supposed_member_value_traits +{}; + +//...It's a member hook +template +struct supposed_member_value_traits + : get_member_value_traits +{}; + +//...Not a member hook +template +struct supposed_member_value_traits + : any_or_concrete_value_traits +{}; + +template +struct any_or_concrete_value_traits +{ + //A hook node (non-base, e.g.: member or other value traits + typedef typename AnyToSomeHook_ProtoValueTraits::basic_hook_t basic_hook_t; + typedef typename pointer_rebind + ::type void_pointer; + typedef typename AnyToSomeHook_ProtoValueTraits::template + node_traits_from_voidptr::type any_node_traits; + + struct type : basic_hook_t + { + typedef any_node_traits node_traits; + }; +}; + +template +struct any_or_concrete_value_traits +{ + typedef SupposedValueTraits type; +}; + +//////////////////////////////////////// +// get_value_traits / get_node_traits +//////////////////////////////////////// + +template +struct get_value_traits + : supposed_base_value_traits::type, T> +{}; + +template +struct get_node_traits +{ + typedef typename get_value_traits::type::node_traits type; +}; + +} //namespace detail{ + +#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_GET_VALUE_TRAITS_HPP diff --git a/src/vendor/boost/intrusive/detail/has_member_function_callable_with.hpp b/src/vendor/boost/intrusive/detail/has_member_function_callable_with.hpp new file mode 100644 index 000000000..92ef60ee6 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/has_member_function_callable_with.hpp @@ -0,0 +1,366 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +//In case no decltype and no variadics, mark that we don't support 0 arg calls due to +//compiler ICE in GCC 3.4/4.0/4.1 and, wrong SFINAE for GCC 4.2/4.3/MSVC10/MSVC11 +#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +# if defined(BOOST_GCC) && (BOOST_GCC < 40400) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_INTEL) && (BOOST_INTEL < 1200) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800) +# define BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED +# endif +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) && defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +#include +#include +#include + +namespace boost_intrusive_hmfcw { + +typedef char yes_type; +struct no_type{ char dummy[2]; }; + +struct dont_care +{ + dont_care(...); +}; + +#if defined(BOOST_NO_CXX11_DECLTYPE) + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template +struct make_dontcare +{ + typedef dont_care type; +}; + +#endif + +struct private_type +{ + static private_type p; + private_type const &operator,(int) const; +}; + +template +no_type is_private_type(T const &); +yes_type is_private_type(private_type const &); + +#endif //#if defined(BOOST_NO_CXX11_DECLTYPE) + +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; +template struct remove_cv { typedef T type; }; + +#endif + +} //namespace boost_intrusive_hmfcw { + +#endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_CALLABLE_WITH_HPP + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN before including this header!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX + #error "You MUST define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX before including this header!" +#endif + +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX < BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX value MUST be greater or equal than BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN!" +#endif + +#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF +#else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF , +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG not defined!" +#endif + +#ifndef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + #error "BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END not defined!" +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) + //With decltype and variadic templaes, things are pretty easy + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template + static decltype(boost::move_detail::declval(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...) + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + template + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + +#else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) || defined(BOOST_NO_CXX11_DECLTYPE) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX + // declaration, special case and 0 arg specializaton + // + ///////////////////////////////////////////////////////// + + template + class BOOST_MOVE_CAT(has_member_function_named_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + struct BaseMixin + { + void BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + {} //Some compilers require the definition or linker errors happen + }; + + struct Base + : public boost_intrusive_hmfcw::remove_cv::type, public BaseMixin + { //Declare the unneeded default constructor as some old compilers wrongly require it with is_convertible + Base(){} + }; + template class Helper{}; + + template + static boost_intrusive_hmfcw::no_type deduce + (U*, Helper* = 0); + static boost_intrusive_hmfcw::yes_type deduce(...); + + public: + static const bool value = sizeof(boost_intrusive_hmfcw::yes_type) == sizeof(deduce((Base*)0)); + }; + + #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX for 1 to N arguments + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //defined(BOOST_NO_CXX11_DECLTYPE) must be true + template + struct FunWrapTmpl : Fun + { + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME; + FunWrapTmpl(); + template + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(DontCares...) const; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); + + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type + ( (::boost::move_detail::declval + < FunWrapTmpl >(). + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(::boost::move_detail::declval()...), 0) ) + ) + ); + }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + , Args...> + {}; + #else //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_impl_XXX specializations + // + ///////////////////////////////////////////////////////// + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME); + + //No BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME member specialization + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + + { + static const bool value = false; + }; + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + //0 arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + #if !defined(BOOST_NO_CXX11_DECLTYPE) + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template + static decltype(boost::move_detail::declval().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME() + , boost_intrusive_hmfcw::yes_type()) Test(U* f); + + template + static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + + #else //defined(BOOST_NO_CXX11_DECLTYPE) + + #if !defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + + template().BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(), 0)> + struct BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { boost_intrusive_hmfcw::yes_type dummy[N ? 1 : 2]; }; + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { + template static BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + Test(BOOST_MOVE_CAT(zeroarg_checker_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)*); + template static boost_intrusive_hmfcw::no_type Test(...); + static const bool value = sizeof(Test< Fun >(0)) == sizeof(boost_intrusive_hmfcw::yes_type); + }; + + #else //defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + { //Some compilers gives ICE when instantiating the 0 arg version so it is not supported. + static const bool value = true; + }; + + #endif//!defined(BOOST_INTRUSIVE_DETAIL_HAS_MEMBER_FUNCTION_CALLABLE_WITH_0_ARGS_UNSUPPORTED) + #endif //!defined(BOOST_NO_CXX11_DECLTYPE) + #endif //#if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + //1 to N arg specialization when BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME is present + //Declare some unneeded default constructor as some old compilers wrongly require it with is_convertible + #if defined(BOOST_NO_CXX11_DECLTYPE) + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + \ + template\ + struct BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + : Fun\ + {\ + using Fun::BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME;\ + BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)();\ + boost_intrusive_hmfcw::private_type BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME\ + (BOOST_MOVE_REPEAT##N(boost_intrusive_hmfcw::dont_care)) const;\ + };\ + \ + template\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + {\ + static bool const value = (sizeof(boost_intrusive_hmfcw::no_type) == sizeof(boost_intrusive_hmfcw::is_private_type\ + ( (::boost::move_detail::declval\ + < BOOST_MOVE_CAT(FunWrap##N, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) >().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N), 0) )\ + )\ + );\ + };\ + // + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION(N)\ + template\ + struct BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME)\ + \ + {\ + template\ + static decltype(boost::move_detail::declval().\ + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME(BOOST_MOVE_DECLVAL##N)\ + , boost_intrusive_hmfcw::yes_type()) Test(U* f);\ + template\ + static boost_intrusive_hmfcw::no_type Test(...);\ + static const bool value = sizeof(Test((Fun*)0)) == sizeof(boost_intrusive_hmfcw::yes_type);\ + };\ + // + #endif + //////////////////////////////////// + // Build and invoke BOOST_MOVE_ITERATE_NTOM macrofunction, note that N has to be at least 1 + //////////////////////////////////// + #if BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN == 0 + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN 1 + #else + #define BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN + #endif + BOOST_MOVE_CAT + (BOOST_MOVE_CAT(BOOST_MOVE_CAT(BOOST_MOVE_ITERATE_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN), TO) + ,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX) + (BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION) + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATION + #undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_ITERATE_MIN + //////////////////////////////////// + // End of BOOST_MOVE_ITERATE_NTOM + //////////////////////////////////// + #endif //BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX > 0 + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + // + // has_member_function_callable_with_FUNC + // + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + //Otherwise use the preprocessor + template + struct BOOST_MOVE_CAT(has_member_function_callable_with_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + : public BOOST_MOVE_CAT(has_member_function_callable_with_impl_, BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME) + ::value + BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF BOOST_MOVE_CAT(BOOST_MOVE_TARG,BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX)> + {}; + #endif //defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) +#endif + +BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END + +//Undef local macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_COMMA_IF + +//Undef user defined macros +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_FUNCNAME +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MIN +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_MAX +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_BEG +#undef BOOST_INTRUSIVE_HAS_MEMBER_FUNCTION_CALLABLE_WITH_NS_END diff --git a/src/vendor/boost/intrusive/detail/hook_traits.hpp b/src/vendor/boost/intrusive/detail/hook_traits.hpp new file mode 100644 index 000000000..7f7dc27e0 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/hook_traits.hpp @@ -0,0 +1,195 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP +#define BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct bhtraits_base +{ + public: + typedef NodePtr node_ptr; + typedef typename pointer_traits::element_type node; + typedef node_holder node_holder_type; + typedef T value_type; + typedef typename pointer_traits:: + template rebind_pointer::type const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + //typedef typename pointer_traits::reference reference; + //typedef typename pointer_traits::reference const_reference; + typedef T & reference; + typedef const T & const_reference; + typedef node_holder_type & node_holder_reference; + typedef const node_holder_type & const_node_holder_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n) + { + pointer p = pointer_traits::pointer_to + (static_cast(static_cast(*n))); + BOOST_ASSERT(!!p); + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n) + { + const_pointer p = pointer_traits::pointer_to + (static_cast(static_cast(*n))); + BOOST_ASSERT(!!p); + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) + { + node_ptr p = pointer_traits::pointer_to + (static_cast(static_cast(value))); + BOOST_ASSERT(!!p); + return p; + } + + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) + { + const_node_ptr p = pointer_traits::pointer_to + (static_cast(static_cast(value))); + BOOST_ASSERT(!!p); + return p; + } +}; + +template +struct bhtraits + : public bhtraits_base +{ + static const link_mode_type link_mode = LinkMode; + typedef NodeTraits node_traits; +}; + + +template +struct mhtraits +{ + public: + typedef Hook hook_type; + typedef typename hook_type::hooktags::node_traits node_traits; + typedef typename node_traits::node node; + typedef T value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef node& node_reference; + typedef const node & const_node_reference; + typedef hook_type& hook_reference; + typedef const hook_type & const_hook_reference; + + static const link_mode_type link_mode = Hook::hooktags::link_mode; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr to_node_ptr(reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value.*P))); + } + + BOOST_INTRUSIVE_FORCEINLINE static const_node_ptr to_node_ptr(const_reference value) + { + return pointer_traits::pointer_to + (static_cast(static_cast(value.*P))); + } + + BOOST_INTRUSIVE_FORCEINLINE static pointer to_value_ptr(const node_ptr & n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::movelib::to_raw_pointer(n)), P)); + } + + BOOST_INTRUSIVE_FORCEINLINE static const_pointer to_value_ptr(const const_node_ptr & n) + { + return pointer_traits::pointer_to + (*detail::parent_from_member + (static_cast(boost::movelib::to_raw_pointer(n)), P)); + } +}; + + +template +struct fhtraits +{ + public: + typedef typename Functor::hook_type hook_type; + typedef typename Functor::hook_ptr hook_ptr; + typedef typename Functor::const_hook_ptr const_hook_ptr; + typedef typename hook_type::hooktags::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename Functor::value_type value_type; + typedef typename node_traits::node_ptr node_ptr; + typedef typename node_traits::const_node_ptr const_node_ptr; + typedef typename pointer_traits:: + template rebind_pointer::type pointer; + typedef typename pointer_traits:: + template rebind_pointer::type const_pointer; + typedef value_type & reference; + typedef const value_type & const_reference; + static const link_mode_type link_mode = hook_type::hooktags::link_mode; + + static node_ptr to_node_ptr(reference value) + { return static_cast(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); } + + static const_node_ptr to_node_ptr(const_reference value) + { return static_cast(boost::movelib::to_raw_pointer(Functor::to_hook_ptr(value))); } + + static pointer to_value_ptr(const node_ptr & n) + { return Functor::to_value_ptr(to_hook_ptr(n)); } + + static const_pointer to_value_ptr(const const_node_ptr & n) + { return Functor::to_value_ptr(to_hook_ptr(n)); } + + private: + static hook_ptr to_hook_ptr(const node_ptr & n) + { return hook_ptr(&*static_cast(&*n)); } + + static const_hook_ptr to_hook_ptr(const const_node_ptr & n) + { return const_hook_ptr(&*static_cast(&*n)); } +}; + + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_HOOK_TRAITS_HPP diff --git a/src/vendor/boost/intrusive/detail/iiterator.hpp b/src/vendor/boost/intrusive/detail/iiterator.hpp new file mode 100644 index 000000000..5ab1de2bb --- /dev/null +++ b/src/vendor/boost/intrusive/detail/iiterator.hpp @@ -0,0 +1,122 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct value_traits_pointers +{ + typedef BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT + (boost::intrusive::detail:: + , ValueTraits, value_traits_ptr + , typename boost::intrusive::pointer_traits::template + rebind_pointer::type) value_traits_ptr; + + typedef typename boost::intrusive::pointer_traits::template + rebind_pointer::type const_value_traits_ptr; +}; + +template +struct iiterator +{ + typedef ValueTraits value_traits; + typedef typename value_traits::node_traits node_traits; + typedef typename node_traits::node node; + typedef typename node_traits::node_ptr node_ptr; + typedef ::boost::intrusive::pointer_traits nodepointer_traits_t; + typedef typename nodepointer_traits_t::template + rebind_pointer::type void_pointer; + typedef typename ValueTraits::value_type value_type; + typedef typename ValueTraits::pointer nonconst_pointer; + typedef typename ValueTraits::const_pointer yesconst_pointer; + typedef typename ::boost::intrusive::pointer_traits + ::reference nonconst_reference; + typedef typename ::boost::intrusive::pointer_traits + ::reference yesconst_reference; + typedef typename nodepointer_traits_t::difference_type difference_type; + typedef typename detail::if_c + ::type pointer; + typedef typename detail::if_c + ::type reference; + typedef iterator + < Category + , value_type + , difference_type + , pointer + , reference + > iterator_type; + typedef typename value_traits_pointers + ::value_traits_ptr value_traits_ptr; + typedef typename value_traits_pointers + ::const_value_traits_ptr const_value_traits_ptr; + static const bool stateful_value_traits = + detail::is_stateful_value_traits::value; +}; + +template +struct iiterator_members +{ + + BOOST_INTRUSIVE_FORCEINLINE iiterator_members() + : nodeptr_()//Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_INTRUSIVE_FORCEINLINE iiterator_members(const NodePtr &n_ptr, const StoredPointer &data) + : nodeptr_(n_ptr), ptr_(data) + {} + + BOOST_INTRUSIVE_FORCEINLINE StoredPointer get_ptr() const + { return ptr_; } + + NodePtr nodeptr_; + StoredPointer ptr_; +}; + +template +struct iiterator_members +{ + BOOST_INTRUSIVE_FORCEINLINE iiterator_members() + : nodeptr_()//Value initialization to achieve "null iterators" (N3644) + {} + + BOOST_INTRUSIVE_FORCEINLINE iiterator_members(const NodePtr &n_ptr, const StoredPointer &) + : nodeptr_(n_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE StoredPointer get_ptr() const + { return StoredPointer(); } + + NodePtr nodeptr_; +}; + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_IITERATOR_HPP diff --git a/src/vendor/boost/intrusive/detail/is_stateful_value_traits.hpp b/src/vendor/boost/intrusive/detail/is_stateful_value_traits.hpp new file mode 100644 index 000000000..e43f6d340 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/is_stateful_value_traits.hpp @@ -0,0 +1,81 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2009-2013. +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP +#define BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#if defined(_MSC_VER) && (_MSC_VER <= 1310) + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct is_stateful_value_traits +{ + static const bool value = !detail::is_empty::value; +}; + +}}} + +#else + +#include + +BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_node_ptr, boost_intrusive) +BOOST_INTRUSIVE_CREATE_FUNCTION_DETECTOR(to_value_ptr, boost_intrusive) + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct is_stateful_value_traits +{ + typedef typename ValueTraits::node_ptr node_ptr; + typedef typename ValueTraits::pointer pointer; + typedef typename ValueTraits::value_type value_type; + typedef typename ValueTraits::const_node_ptr const_node_ptr; + typedef typename ValueTraits::const_pointer const_pointer; + + typedef ValueTraits value_traits; + + static const bool value = + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, node_ptr, to_node_ptr, (value_type&) ))) + || + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, pointer, to_value_ptr, (node_ptr) ))) + || + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_node_ptr, to_node_ptr, (const value_type&) ))) + || + (boost::intrusive::function_detector::NonStaticFunction == + (BOOST_INTRUSIVE_DETECT_FUNCTION(ValueTraits, boost_intrusive, const_pointer, to_value_ptr, (const_node_ptr) ))) + ; +}; + +}}} + +#endif + +#endif //@ifndef BOOST_INTRUSIVE_DETAIL_IS_STATEFUL_VALUE_TRAITS_HPP diff --git a/src/vendor/boost/intrusive/detail/iterator.hpp b/src/vendor/boost/intrusive/detail/iterator.hpp new file mode 100644 index 000000000..41ffca125 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/iterator.hpp @@ -0,0 +1,262 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost{ +namespace iterators{ + +struct incrementable_traversal_tag; +struct single_pass_traversal_tag; +struct forward_traversal_tag; +struct bidirectional_traversal_tag; +struct random_access_traversal_tag; + +namespace detail{ + +template +struct iterator_category_with_traversal; + +} //namespace boost{ +} //namespace iterators{ +} //namespace detail{ + +namespace boost { +namespace intrusive { + +using boost::movelib::iterator_traits; + +//////////////////// +// iterator +//////////////////// +template +struct iterator +{ + typedef Category iterator_category; + typedef T value_type; + typedef Difference difference_type; + typedef Pointer pointer; + typedef Reference reference; +}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_boost_iterator +//////////////////////////////////////// +template +struct is_boost_iterator +{ + static const bool value = false; +}; + +template +struct is_boost_iterator< boost::iterators::detail::iterator_category_with_traversal > +{ + static const bool value = true; +}; + +template +struct iterator_enable_if_boost_iterator + : ::boost::move_detail::enable_if_c + < is_boost_iterator::iterator_category >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value + , R> +{}; + +template +struct iterator_disable_if_tag + : ::boost::move_detail::enable_if_c + < !::boost::move_detail::is_same + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag +//////////////////////////////////////// +template +struct iterator_enable_if_convertible_tag + : ::boost::move_detail::enable_if_c + < ::boost::move_detail::is_same_or_convertible + < typename boost::intrusive::iterator_traits::iterator_category + , Tag + >::value && + !::boost::move_detail::is_same_or_convertible + < typename boost::intrusive::iterator_traits::iterator_category + , Tag2 + >::value + , R> +{}; + +//////////////////////////////////////// +// iterator_[dis|en]able_if_tag_difference_type +//////////////////////////////////////// +template +struct iterator_enable_if_tag_difference_type + : iterator_enable_if_tag::difference_type> +{}; + +template +struct iterator_disable_if_tag_difference_type + : iterator_disable_if_tag::difference_type> +{}; + +//////////////////// +// advance +//////////////////// + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + while(n--) + ++it; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + for (; 0 < n; --n) + ++it; + for (; n < 0; ++n) + --it; +} + +class fake{}; + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_convertible_tag + ::type + iterator_advance(InputIt& it, Distance n) +{ + it += n; +} + +//////////////////// +// distance +//////////////////// +template inline +typename iterator_disable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) +{ + typename iterator_traits::difference_type off = 0; + while(first != last){ + ++off; + ++first; + } + return off; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_enable_if_tag_difference_type + ::type + iterator_distance(InputIt first, InputIt last) +{ + typename iterator_traits::difference_type off = last - first; + return off; +} + +template +BOOST_INTRUSIVE_FORCEINLINE typename iterator_traits::pointer iterator_arrow_result(const I &i) +{ return i.operator->(); } + +template +BOOST_INTRUSIVE_FORCEINLINE T * iterator_arrow_result(T *p) +{ return p; } + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_DETAIL_ITERATOR_HPP diff --git a/src/vendor/boost/intrusive/detail/key_nodeptr_comp.hpp b/src/vendor/boost/intrusive/detail/key_nodeptr_comp.hpp new file mode 100644 index 000000000..1029a3404 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/key_nodeptr_comp.hpp @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP +#define BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + + +namespace boost { +namespace intrusive { +namespace detail { + +template < class KeyTypeKeyCompare + , class ValueTraits + , class KeyOfValue + > +struct key_nodeptr_comp_types +{ + typedef ValueTraits value_traits; + typedef typename value_traits::value_type value_type; + typedef typename value_traits::node_ptr node_ptr; + typedef typename value_traits::const_node_ptr const_node_ptr; + typedef typename detail::if_c + < detail::is_same::value + , detail::identity + , KeyOfValue + >::type key_of_value; + typedef tree_value_compare + base_t; +}; + +//This function object transforms a key comparison type to +//a function that can compare nodes or nodes with nodes or keys. +template < class KeyTypeKeyCompare + , class ValueTraits + , class KeyOfValue = void + > +struct key_nodeptr_comp + //Use public inheritance to avoid MSVC bugs with closures + : public key_nodeptr_comp_types::base_t +{ +private: + struct sfinae_type; + +public: + typedef key_nodeptr_comp_types types_t; + typedef typename types_t::value_traits value_traits; + typedef typename types_t::value_type value_type; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::const_node_ptr const_node_ptr; + typedef typename types_t::base_t base_t; + typedef typename types_t::key_of_value key_of_value; + + template + struct is_same_or_nodeptr_convertible + { + static const bool same_type = is_same::value || is_same::value; + static const bool value = same_type || is_convertible::value; + }; + + BOOST_INTRUSIVE_FORCEINLINE base_t base() const + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE key_nodeptr_comp(KeyTypeKeyCompare kcomp, const ValueTraits *traits) + : base_t(kcomp), traits_(traits) + {} + + //pred(pnode) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator()(const T1 &t1, typename enable_if_c< is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base().get()(key_of_value()(*traits_->to_value_ptr(t1))); } + + //operator() 2 arg + //pred(pnode, pnode) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(*traits_->to_value_ptr(t1), *traits_->to_value_ptr(t2)); } + + //pred(pnode, key) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(*traits_->to_value_ptr(t1), t2); } + + //pred(key, pnode) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(t1, *traits_->to_value_ptr(t2)); } + + //pred(key, key) + template + BOOST_INTRUSIVE_FORCEINLINE bool operator() + (const T1 &t1, const T2 &t2, typename enable_if_c< !is_same_or_nodeptr_convertible::value && !is_same_or_nodeptr_convertible::value, sfinae_type* >::type = 0) const + { return base()(t1, t2); } + + const ValueTraits *const traits_; +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_KEY_NODEPTR_COMP_HPP diff --git a/src/vendor/boost/intrusive/detail/minimal_less_equal_header.hpp b/src/vendor/boost/intrusive/detail/minimal_less_equal_header.hpp new file mode 100644 index 000000000..5e8a19deb --- /dev/null +++ b/src/vendor/boost/intrusive/detail/minimal_less_equal_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP +# +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#//Try to avoid including , as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include +#else +# include //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_LESS_EQUAL_HEADER_HPP diff --git a/src/vendor/boost/intrusive/detail/minimal_pair_header.hpp b/src/vendor/boost/intrusive/detail/minimal_pair_header.hpp new file mode 100644 index 000000000..1358a0858 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/minimal_pair_header.hpp @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2015 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +#define BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif +# +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#//Try to avoid including , as it's quite big in C++11 +#if defined(BOOST_GNU_STDLIB) +# include +#else +# include //Fallback +#endif +# +#endif //BOOST_INTRUSIVE_DETAIL_MINIMAL_PAIR_HEADER_HPP diff --git a/src/vendor/boost/intrusive/detail/mpl.hpp b/src/vendor/boost/intrusive/detail/mpl.hpp new file mode 100644 index 000000000..935c04c28 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/mpl.hpp @@ -0,0 +1,217 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// (C) Copyright Microsoft Corporation 2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP +#define BOOST_INTRUSIVE_DETAIL_MPL_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +using boost::move_detail::is_same; +using boost::move_detail::add_const; +using boost::move_detail::remove_const; +using boost::move_detail::remove_cv; +using boost::move_detail::remove_reference; +using boost::move_detail::add_reference; +using boost::move_detail::remove_pointer; +using boost::move_detail::add_pointer; +using boost::move_detail::true_type; +using boost::move_detail::false_type; +using boost::move_detail::voider; +using boost::move_detail::enable_if_c; +using boost::move_detail::enable_if; +using boost::move_detail::disable_if_c; +using boost::move_detail::disable_if; +using boost::move_detail::is_convertible; +using boost::move_detail::if_c; +using boost::move_detail::if_; +using boost::move_detail::is_const; +using boost::move_detail::identity; +using boost::move_detail::alignment_of; +using boost::move_detail::is_empty; +using boost::move_detail::addressof; +using boost::move_detail::integral_constant; +using boost::move_detail::enable_if_convertible; +using boost::move_detail::disable_if_convertible; +using boost::move_detail::bool_; +using boost::move_detail::true_; +using boost::move_detail::false_; +using boost::move_detail::yes_type; +using boost::move_detail::no_type; +using boost::move_detail::apply; +using boost::move_detail::eval_if_c; +using boost::move_detail::eval_if; +using boost::move_detail::unvoid_ref; +using boost::move_detail::add_const_if_c; + +template +struct ls_zeros +{ + static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value); +}; + +template<> +struct ls_zeros<0> +{ + static const std::size_t value = 0; +}; + +template<> +struct ls_zeros<1> +{ + static const std::size_t value = 0; +}; + +// Infrastructure for providing a default type for T::TNAME if absent. +#define BOOST_INTRUSIVE_INSTANTIATE_DEFAULT_TYPE_TMPLT(TNAME) \ + template \ + struct boost_intrusive_has_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(...); \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + }; \ + \ + template \ + struct boost_intrusive_default_type_ ## TNAME \ + { \ + struct DefaultWrap { typedef DefaultType TNAME; }; \ + \ + typedef typename \ + ::boost::intrusive::detail::if_c \ + < boost_intrusive_has_type_ ## TNAME::value \ + , T, DefaultWrap>::type::TNAME type; \ + }; \ + // + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_HAS_TYPE(INSTANTIATION_NS_PREFIX, T, TNAME) \ + INSTANTIATION_NS_PREFIX \ + boost_intrusive_has_type_ ## TNAME< T >::value \ +// + +#define BOOST_INTRUSIVE_INSTANTIATE_EVAL_DEFAULT_TYPE_TMPLT(TNAME)\ + template \ + struct boost_intrusive_eval_default_type_ ## TNAME \ + { \ + template \ + static char test(int, typename X::TNAME*); \ + \ + template \ + static int test(...); \ + \ + struct DefaultWrap \ + { typedef typename DefaultType::type TNAME; }; \ + \ + static const bool value = (1 == sizeof(test(0, 0))); \ + \ + typedef typename \ + ::boost::intrusive::detail::eval_if_c \ + < value \ + , ::boost::intrusive::detail::identity \ + , ::boost::intrusive::detail::identity \ + >::type::TNAME type; \ + }; \ +// + +#define BOOST_INTRUSIVE_OBTAIN_TYPE_WITH_EVAL_DEFAULT(INSTANTIATION_NS_PREFIX, T, TNAME, TIMPL) \ + typename INSTANTIATION_NS_PREFIX \ + boost_intrusive_eval_default_type_ ## TNAME< T, TIMPL >::type \ +// + +#define BOOST_INTRUSIVE_INTERNAL_STATIC_BOOL_IS_TRUE(TRAITS_PREFIX, TYPEDEF_TO_FIND) \ +template \ +struct TRAITS_PREFIX##_bool\ +{\ + template\ + struct two_or_three {yes_type _[2 + Add];};\ + template static yes_type test(...);\ + template static two_or_three test (int);\ + static const std::size_t value = sizeof(test(0));\ +};\ +\ +template \ +struct TRAITS_PREFIX##_bool_is_true\ +{\ + static const bool value = TRAITS_PREFIX##_bool::value > sizeof(yes_type)*2;\ +};\ +// + +#define BOOST_INTRUSIVE_HAS_STATIC_MEMBER_FUNC_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ + template \ + class TRAITS_NAME \ + { \ + private: \ + template struct helper;\ + template \ + static ::boost::intrusive::detail::yes_type test(helper<&T::FUNC_NAME>*); \ + template static ::boost::intrusive::detail::no_type test(...); \ + public: \ + static const bool value = sizeof(test(0)) == sizeof(::boost::intrusive::detail::yes_type); \ + }; \ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME, FUNC_NAME) \ +template \ +struct TRAITS_NAME \ +{ \ + struct BaseMixin \ + { \ + void FUNC_NAME(); \ + }; \ + struct Base : public Type, public BaseMixin { Base(); }; \ + template class Helper{}; \ + template \ + static ::boost::intrusive::detail::no_type test(U*, Helper* = 0); \ + static ::boost::intrusive::detail::yes_type test(...); \ + static const bool value = sizeof(::boost::intrusive::detail::yes_type) == sizeof(test((Base*)(0))); \ +};\ +// + +#define BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED_IGNORE_SIGNATURE(TRAITS_NAME, FUNC_NAME) \ +BOOST_INTRUSIVE_HAS_MEMBER_FUNC_CALLED(TRAITS_NAME##_ignore_signature, FUNC_NAME) \ +\ +template \ +struct TRAITS_NAME \ + : public TRAITS_NAME##_ignore_signature \ +{};\ +// + +} //namespace detail +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_MPL_HPP diff --git a/src/vendor/boost/intrusive/detail/node_holder.hpp b/src/vendor/boost/intrusive/detail/node_holder.hpp new file mode 100644 index 000000000..b8dabef2d --- /dev/null +++ b/src/vendor/boost/intrusive/detail/node_holder.hpp @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +template +struct node_holder + : public Node +{}; + +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_NODE_HOLDER_HPP diff --git a/src/vendor/boost/intrusive/detail/parent_from_member.hpp b/src/vendor/boost/intrusive/detail/parent_from_member.hpp new file mode 100644 index 000000000..275229ab4 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/parent_from_member.hpp @@ -0,0 +1,121 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP +#define BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +#if defined(_MSC_VER) + #define BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER + #include +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +template +BOOST_INTRUSIVE_FORCEINLINE std::ptrdiff_t offset_from_pointer_to_member(const Member Parent::* ptr_to_member) +{ + //The implementation of a pointer to member is compiler dependent. + #if defined(BOOST_INTRUSIVE_MSVC_ABI_PTR_TO_MEMBER) + + //MSVC compliant compilers use their the first 32 bits as offset (even in 64 bit mode) + union caster_union + { + const Member Parent::* ptr_to_member; + int offset; + } caster; + + //MSVC ABI can use up to 3 int32 to represent pointer to member data + //with virtual base classes, in those cases there is no simple to + //obtain the address of the parent. So static assert to avoid runtime errors + BOOST_STATIC_ASSERT( sizeof(caster) == sizeof(int) ); + + caster.ptr_to_member = ptr_to_member; + return std::ptrdiff_t(caster.offset); + //Additional info on MSVC behaviour for the future. For 2/3 int ptr-to-member + //types dereference seems to be: + // + // vboffset = [compile_time_offset if 2-int ptr2memb] / + // [ptr2memb.i32[2] if 3-int ptr2memb]. + // vbtable = *(this + vboffset); + // adj = vbtable[ptr2memb.i32[1]]; + // var = adj + (this + vboffset) + ptr2memb.i32[0]; + // + //To reverse the operation we need to + // - obtain vboffset (in 2-int ptr2memb implementation only) + // - Go to Parent's vbtable and obtain adjustment at index ptr2memb.i32[1] + // - parent = member - adj - vboffset - ptr2memb.i32[0] + // + //Even accessing to RTTI we might not be able to obtain this information + //so anyone who thinks it's possible, please send a patch. + + //This works with gcc, msvc, ac++, ibmcpp + #elif defined(__GNUC__) || defined(__HP_aCC) || defined(BOOST_INTEL) || \ + defined(__IBMCPP__) || defined(__DECCXX) + const Parent * const parent = 0; + const char *const member = static_cast(static_cast(&(parent->*ptr_to_member))); + return std::ptrdiff_t(member - static_cast(static_cast(parent))); + #else + //This is the traditional C-front approach: __MWERKS__, __DMC__, __SUNPRO_CC + union caster_union + { + const Member Parent::* ptr_to_member; + std::ptrdiff_t offset; + } caster; + caster.ptr_to_member = ptr_to_member; + return caster.offset - 1; + #endif +} + +template +BOOST_INTRUSIVE_FORCEINLINE Parent *parent_from_member(Member *member, const Member Parent::* ptr_to_member) +{ + return static_cast + ( + static_cast + ( + static_cast(static_cast(member)) - offset_from_pointer_to_member(ptr_to_member) + ) + ); +} + +template +BOOST_INTRUSIVE_FORCEINLINE const Parent *parent_from_member(const Member *member, const Member Parent::* ptr_to_member) +{ + return static_cast + ( + static_cast + ( + static_cast(static_cast(member)) - offset_from_pointer_to_member(ptr_to_member) + ) + ); +} + +} //namespace detail { +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_PARENT_FROM_MEMBER_HPP diff --git a/src/vendor/boost/intrusive/detail/reverse_iterator.hpp b/src/vendor/boost/intrusive/detail/reverse_iterator.hpp new file mode 100644 index 000000000..57631feb5 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/reverse_iterator.hpp @@ -0,0 +1,165 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP +#define BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +class reverse_iterator +{ + public: + typedef typename boost::intrusive::iterator_traits::pointer pointer; + typedef typename boost::intrusive::iterator_traits::reference reference; + typedef typename boost::intrusive::iterator_traits::difference_type difference_type; + typedef typename boost::intrusive::iterator_traits::iterator_category iterator_category; + typedef typename boost::intrusive::iterator_traits::value_type value_type; + + + typedef It iterator_type; + + reverse_iterator() + : m_current() //Value initialization to achieve "null iterators" (N3644) + {} + + explicit reverse_iterator(It r) + : m_current(r) + {} + + reverse_iterator(const reverse_iterator& r) + : m_current(r.base()) + {} + + template + reverse_iterator( const reverse_iterator& r + , typename boost::intrusive::detail::enable_if_convertible::type* =0 + ) + : m_current(r.base()) + {} + + reverse_iterator & operator=( const reverse_iterator& r) + { m_current = r.base(); return *this; } + + template + typename boost::intrusive::detail::enable_if_convertible::type + operator=( const reverse_iterator& r) + { m_current = r.base(); return *this; } + + It base() const + { return m_current; } + + reference operator*() const + { + It temp(m_current); + --temp; + reference r = *temp; + return r; + } + + pointer operator->() const + { + It temp(m_current); + --temp; + return iterator_arrow_result(temp); + } + + reference operator[](difference_type off) const + { + return this->m_current[-off - 1]; + } + + reverse_iterator& operator++() + { + --m_current; + return *this; + } + + reverse_iterator operator++(int) + { + reverse_iterator temp((*this)); + --m_current; + return temp; + } + + reverse_iterator& operator--() + { + ++m_current; + return *this; + } + + reverse_iterator operator--(int) + { + reverse_iterator temp((*this)); + ++m_current; + return temp; + } + + friend bool operator==(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current == r.m_current; } + + friend bool operator!=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current != r.m_current; } + + friend bool operator<(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current > r.m_current; } + + friend bool operator<=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current >= r.m_current; } + + friend bool operator>(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current < r.m_current; } + + friend bool operator>=(const reverse_iterator& l, const reverse_iterator& r) + { return l.m_current <= r.m_current; } + + reverse_iterator& operator+=(difference_type off) + { m_current -= off; return *this; } + + reverse_iterator& operator-=(difference_type off) + { m_current += off; return *this; } + + friend reverse_iterator operator+(reverse_iterator l, difference_type off) + { return (l += off); } + + friend reverse_iterator operator+(difference_type off, reverse_iterator r) + { return (r += off); } + + friend reverse_iterator operator-(reverse_iterator l, difference_type off) + { return (l-= off); } + + friend difference_type operator-(const reverse_iterator& l, const reverse_iterator& r) + { return r.m_current - l.m_current; } + + private: + It m_current; // the wrapped iterator +}; + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_REVERSE_ITERATOR_HPP diff --git a/src/vendor/boost/intrusive/detail/simple_disposers.hpp b/src/vendor/boost/intrusive/detail/simple_disposers.hpp new file mode 100644 index 000000000..17fa1e46b --- /dev/null +++ b/src/vendor/boost/intrusive/detail/simple_disposers.hpp @@ -0,0 +1,52 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP +#define BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP + +#include + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { +namespace detail { + +class null_disposer +{ + public: + template + void operator()(Pointer) + {} +}; + +template +class init_disposer +{ + typedef typename NodeAlgorithms::node_ptr node_ptr; + + public: + BOOST_INTRUSIVE_FORCEINLINE void operator()(const node_ptr & p) + { NodeAlgorithms::init(p); } +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_SIMPLE_DISPOSERS_HPP diff --git a/src/vendor/boost/intrusive/detail/size_holder.hpp b/src/vendor/boost/intrusive/detail/size_holder.hpp new file mode 100644 index 000000000..bd14dc504 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/size_holder.hpp @@ -0,0 +1,91 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP +#define BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct size_holder +{ + static const bool constant_time_size = ConstantSize; + typedef SizeType size_type; + + BOOST_INTRUSIVE_FORCEINLINE SizeType get_size() const + { return size_; } + + BOOST_INTRUSIVE_FORCEINLINE void set_size(SizeType size) + { size_ = size; } + + BOOST_INTRUSIVE_FORCEINLINE void decrement() + { --size_; } + + BOOST_INTRUSIVE_FORCEINLINE void increment() + { ++size_; } + + BOOST_INTRUSIVE_FORCEINLINE void increase(SizeType n) + { size_ += n; } + + BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType n) + { size_ -= n; } + + BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder &other) + { SizeType tmp(size_); size_ = other.size_; other.size_ = tmp; } + + SizeType size_; +}; + +template +struct size_holder +{ + static const bool constant_time_size = false; + typedef SizeType size_type; + + BOOST_INTRUSIVE_FORCEINLINE size_type get_size() const + { return 0; } + + BOOST_INTRUSIVE_FORCEINLINE void set_size(size_type) + {} + + BOOST_INTRUSIVE_FORCEINLINE void decrement() + {} + + BOOST_INTRUSIVE_FORCEINLINE void increment() + {} + + BOOST_INTRUSIVE_FORCEINLINE void increase(SizeType) + {} + + BOOST_INTRUSIVE_FORCEINLINE void decrease(SizeType) + {} + + BOOST_INTRUSIVE_FORCEINLINE void swap(size_holder){} +}; + +} //namespace detail{ +} //namespace intrusive{ +} //namespace boost{ + +#endif //BOOST_INTRUSIVE_DETAIL_SIZE_HOLDER_HPP diff --git a/src/vendor/boost/intrusive/detail/slist_iterator.hpp b/src/vendor/boost/intrusive/detail/slist_iterator.hpp new file mode 100644 index 000000000..9e72af9f3 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/slist_iterator.hpp @@ -0,0 +1,137 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SLIST_ITERATOR_HPP +#define BOOST_INTRUSIVE_SLIST_ITERATOR_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { +namespace intrusive { + + +// slist_iterator provides some basic functions for a +// node oriented bidirectional iterator: +template +class slist_iterator +{ + private: + typedef iiterator + types_t; + + static const bool stateful_value_traits = types_t::stateful_value_traits; + + typedef ValueTraits value_traits; + typedef typename types_t::node_traits node_traits; + + typedef typename types_t::node node; + typedef typename types_t::node_ptr node_ptr; + typedef typename types_t::const_value_traits_ptr const_value_traits_ptr; + class nat; + typedef typename + detail::if_c< IsConst + , slist_iterator + , nat>::type nonconst_iterator; + + public: + typedef typename types_t::iterator_type::difference_type difference_type; + typedef typename types_t::iterator_type::value_type value_type; + typedef typename types_t::iterator_type::pointer pointer; + typedef typename types_t::iterator_type::reference reference; + typedef typename types_t::iterator_type::iterator_category iterator_category; + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit slist_iterator(const node_ptr & nodeptr, const const_value_traits_ptr &traits_ptr) + : members_(nodeptr, traits_ptr) + {} + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const slist_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator(const nonconst_iterator &other) + : members_(other.pointed_node(), other.get_value_traits()) + {} + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const slist_iterator &other) + { members_.nodeptr_ = other.members_.nodeptr_; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE node_ptr pointed_node() const + { return members_.nodeptr_; } + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator &operator=(const node_ptr &node) + { members_.nodeptr_ = node; return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE const_value_traits_ptr get_value_traits() const + { return members_.get_ptr(); } + + public: + BOOST_INTRUSIVE_FORCEINLINE slist_iterator& operator++() + { + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return static_cast (*this); + } + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator operator++(int) + { + slist_iterator result (*this); + members_.nodeptr_ = node_traits::get_next(members_.nodeptr_); + return result; + } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator== (const slist_iterator& l, const slist_iterator& r) + { return l.pointed_node() == r.pointed_node(); } + + BOOST_INTRUSIVE_FORCEINLINE friend bool operator!= (const slist_iterator& l, const slist_iterator& r) + { return !(l == r); } + + BOOST_INTRUSIVE_FORCEINLINE reference operator*() const + { return *operator->(); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator->() const + { return this->operator_arrow(detail::bool_()); } + + BOOST_INTRUSIVE_FORCEINLINE slist_iterator unconst() const + { return slist_iterator(this->pointed_node(), this->get_value_traits()); } + + private: + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::false_) const + { return ValueTraits::to_value_ptr(members_.nodeptr_); } + + BOOST_INTRUSIVE_FORCEINLINE pointer operator_arrow(detail::true_) const + { return this->get_value_traits()->to_value_ptr(members_.nodeptr_); } + + iiterator_members members_; +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_ITERATOR_HPP diff --git a/src/vendor/boost/intrusive/detail/slist_node.hpp b/src/vendor/boost/intrusive/detail/slist_node.hpp new file mode 100644 index 000000000..ee8ab40a3 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/slist_node.hpp @@ -0,0 +1,64 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_SLIST_NODE_HPP +#define BOOST_INTRUSIVE_SLIST_NODE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { + +template +struct slist_node +{ + typedef typename pointer_rebind::type node_ptr; + node_ptr next_; +}; + +// slist_node_traits can be used with circular_slist_algorithms and supplies +// a slist_node holding the pointers needed for a singly-linked list +// it is used by slist_base_hook and slist_member_hook +template +struct slist_node_traits +{ + typedef slist_node node; + typedef typename node::node_ptr node_ptr; + typedef typename pointer_rebind::type const_node_ptr; + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const const_node_ptr & n) + { return n->next_; } + + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_next(const node_ptr & n) + { return n->next_; } + + BOOST_INTRUSIVE_FORCEINLINE static void set_next(node_ptr n, node_ptr next) + { n->next_ = next; } +}; + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_SLIST_NODE_HPP diff --git a/src/vendor/boost/intrusive/detail/std_fwd.hpp b/src/vendor/boost/intrusive/detail/std_fwd.hpp new file mode 100644 index 000000000..8193ea8ed --- /dev/null +++ b/src/vendor/boost/intrusive/detail/std_fwd.hpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP +#define BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +////////////////////////////////////////////////////////////////////////////// +// Standard predeclarations +////////////////////////////////////////////////////////////////////////////// + +#include +BOOST_MOVE_STD_NS_BEG + +template +struct less; + +template +struct equal_to; + +struct input_iterator_tag; +struct forward_iterator_tag; +struct bidirectional_iterator_tag; +struct random_access_iterator_tag; + +BOOST_MOVE_STD_NS_END +#include + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_STD_FWD_HPP diff --git a/src/vendor/boost/intrusive/detail/tree_value_compare.hpp b/src/vendor/boost/intrusive/detail/tree_value_compare.hpp new file mode 100644 index 000000000..c78da0acd --- /dev/null +++ b/src/vendor/boost/intrusive/detail/tree_value_compare.hpp @@ -0,0 +1,186 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/container for documentation. +// +////////////////////////////////////////////////////////////////////////////// +#ifndef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP +#define BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost{ +namespace intrusive{ + +//Needed to support smart references to value types +template +struct disable_if_smartref_to + : detail::disable_if_c + < detail::is_same + + ::reference>::value + || detail::is_same + ::type>::type> + ::reference>::value + > +{}; + +//This function object takes a KeyCompare function object +//and compares values that contains keys using KeyOfValue +template< class ValuePtr, class KeyCompare, class KeyOfValue, class Ret = bool + , bool = boost::intrusive::detail::is_same + ::type, typename KeyOfValue::type>::value > +struct tree_value_compare + : public boost::intrusive::detail::ebo_functor_holder +{ + typedef typename + boost::movelib::pointer_element::type value_type; + typedef KeyCompare key_compare; + typedef KeyOfValue key_of_value; + typedef typename KeyOfValue::type key_type; + + typedef boost::intrusive::detail::ebo_functor_holder base_t; + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare() + : base_t() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp) + : base_t(kcomp) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x) + : base_t(x.base_t::get()) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x) + { this->base_t::get() = x.base_t::get(); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x) + { this->base_t::get() = x; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_comp()(key); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value) const + { return this->key_comp()(KeyOfValue()(value)); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const + { return this->key_comp()(key1, key2); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const value_type &value2) const + { return this->key_comp()(KeyOfValue()(value1), KeyOfValue()(value2)); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const value_type &value2) const + { return this->key_comp()(key1, KeyOfValue()(value2)); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const value_type &value1, const key_type &key2) const + { return this->key_comp()(KeyOfValue()(value1), key2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(key1, nonkey2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey1, const key_type &key2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey1, key2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const value_type &value1, const U &nonvalue2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(KeyOfValue()(value1), nonvalue2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonvalue1, const value_type &value2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonvalue1, KeyOfValue()(value2)); } +}; + +template +struct tree_value_compare + : public boost::intrusive::detail::ebo_functor_holder +{ + typedef typename + boost::movelib::pointer_element::type value_type; + typedef KeyCompare key_compare; + typedef KeyOfValue key_of_value; + typedef typename KeyOfValue::type key_type; + + typedef boost::intrusive::detail::ebo_functor_holder base_t; + + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare() + : base_t() + {} + + BOOST_INTRUSIVE_FORCEINLINE explicit tree_value_compare(const key_compare &kcomp) + : base_t(kcomp) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare (const tree_value_compare &x) + : base_t(x.base_t::get()) + {} + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const tree_value_compare &x) + { this->base_t::get() = x.base_t::get(); return *this; } + + BOOST_INTRUSIVE_FORCEINLINE tree_value_compare &operator=(const key_compare &x) + { this->base_t::get() = x; return *this; } + + BOOST_INTRUSIVE_FORCEINLINE const key_compare &key_comp() const + { return static_cast(*this); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key) const + { return this->key_comp()(key); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const U &nonkey + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey); } + + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const key_type &key1, const key_type &key2) const + { return this->key_comp()(key1, key2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()( const key_type &key1, const U &nonkey2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(key1, nonkey2); } + + template + BOOST_INTRUSIVE_FORCEINLINE Ret operator()(const U &nonkey1, const key_type &key2 + , typename disable_if_smartref_to::type* = 0) const + { return this->key_comp()(nonkey1, key2); } +}; + +} //namespace intrusive{ +} //namespace boost{ + +#endif //#ifdef BOOST_INTRUSIVE_DETAIL_TREE_VALUE_COMPARE_HPP diff --git a/src/vendor/boost/intrusive/detail/uncast.hpp b/src/vendor/boost/intrusive/detail/uncast.hpp new file mode 100644 index 000000000..7db97b745 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/uncast.hpp @@ -0,0 +1,55 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_UNCAST_HPP +#define BOOST_INTRUSIVE_DETAIL_UNCAST_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#include +#include +#include + +namespace boost { +namespace intrusive { +namespace detail { + +template +struct uncast_types +{ + typedef typename pointer_traits::element_type element_type; + typedef typename remove_const::type non_const_type; + typedef typename pointer_traits:: + template rebind_pointer::type non_const_pointer; + typedef pointer_traits non_const_traits; +}; + +template +static typename uncast_types::non_const_pointer + uncast(const ConstNodePtr & ptr) +{ + return uncast_types::non_const_traits::const_cast_from(ptr); +} + +} //namespace detail { +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_DETAIL_UTILITIES_HPP diff --git a/src/vendor/boost/intrusive/detail/workaround.hpp b/src/vendor/boost/intrusive/detail/workaround.hpp new file mode 100644 index 000000000..f0cfaf2b2 --- /dev/null +++ b/src/vendor/boost/intrusive/detail/workaround.hpp @@ -0,0 +1,58 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2005-2013. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/interprocess for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#define BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +#ifndef BOOST_CONFIG_HPP +#include +#endif + +// MSVC-12 ICEs when variadic templates are enabled. +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && (!defined(BOOST_MSVC) || BOOST_MSVC >= 1900) + #define BOOST_INTRUSIVE_VARIADIC_TEMPLATES +#endif + +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + #define BOOST_INTRUSIVE_PERFECT_FORWARDING +#endif + +//Macros for documentation purposes. For code, expands to the argument +#define BOOST_INTRUSIVE_IMPDEF(TYPE) TYPE +#define BOOST_INTRUSIVE_SEEDOC(TYPE) TYPE +#define BOOST_INTRUSIVE_DOC1ST(TYPE1, TYPE2) TYPE2 +#define BOOST_INTRUSIVE_I , +#define BOOST_INTRUSIVE_DOCIGN(T1) T1 + +//#define BOOST_INTRUSIVE_DISABLE_FORCEINLINE + +#if defined(BOOST_INTRUSIVE_DISABLE_FORCEINLINE) + #define BOOST_INTRUSIVE_FORCEINLINE inline +#elif defined(BOOST_INTRUSIVE_FORCEINLINE_IS_BOOST_FORCELINE) + #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE +#elif defined(BOOST_MSVC) && defined(_DEBUG) + //"__forceinline" and MSVC seems to have some bugs in debug mode + #define BOOST_INTRUSIVE_FORCEINLINE inline +#elif defined(__GNUC__) && ((__GNUC__ < 4) || (__GNUC__ == 4 && (__GNUC_MINOR__ < 5))) + //Older GCCs have problems with forceinline + #define BOOST_INTRUSIVE_FORCEINLINE inline +#else + #define BOOST_INTRUSIVE_FORCEINLINE BOOST_FORCEINLINE +#endif + +#endif //#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP diff --git a/src/vendor/boost/intrusive/intrusive_fwd.hpp b/src/vendor/boost/intrusive/intrusive_fwd.hpp new file mode 100644 index 000000000..37cdb6613 --- /dev/null +++ b/src/vendor/boost/intrusive/intrusive_fwd.hpp @@ -0,0 +1,766 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_FWD_HPP +#define BOOST_INTRUSIVE_FWD_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif +# +#ifndef BOOST_CSTDINT_HPP +# include +#endif +# +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +//! \file +//! This header file forward declares most Intrusive classes. +//! +//! It forward declares the following containers and hooks: +//! - boost::intrusive::slist / boost::intrusive::slist_base_hook / boost::intrusive::slist_member_hook +//! - boost::intrusive::list / boost::intrusive::list_base_hook / boost::intrusive::list_member_hook +//! - boost::intrusive::bstree / boost::intrusive::bs_set / boost::intrusive::bs_multiset / +//! boost::intrusive::bs_set_base_hook / boost::intrusive::bs_set_member_hook +//! - boost::intrusive::rbtree / boost::intrusive::set / boost::intrusive::multiset / +//! boost::intrusive::set_base_hook / boost::intrusive::set_member_hook +//! - boost::intrusive::avltree / boost::intrusive::avl_set / boost::intrusive::avl_multiset / +//! boost::intrusive::avl_set_base_hook / boost::intrusive::avl_set_member_hook +//! - boost::intrusive::splaytree / boost::intrusive::splay_set / boost::intrusive::splay_multiset +//! - boost::intrusive::sgtree / boost::intrusive::sg_set / boost::intrusive::sg_multiset +//! - boost::intrusive::treap / boost::intrusive::treap_set / boost::intrusive::treap_multiset +//! - boost::intrusive::hashtable / boost::intrusive::unordered_set / boost::intrusive::unordered_multiset / +//! boost::intrusive::unordered_set_base_hook / boost::intrusive::unordered_set_member_hook / +//! - boost::intrusive::any_base_hook / boost::intrusive::any_member_hook +//! +//! It forward declares the following container or hook options: +//! - boost::intrusive::constant_time_size / boost::intrusive::size_type / boost::intrusive::compare / boost::intrusive::equal +//! - boost::intrusive::floating_point / boost::intrusive::priority / boost::intrusive::hash +//! - boost::intrusive::value_traits / boost::intrusive::member_hook / boost::intrusive::function_hook / boost::intrusive::base_hook +//! - boost::intrusive::void_pointer / boost::intrusive::tag / boost::intrusive::link_mode +//! - boost::intrusive::optimize_size / boost::intrusive::linear / boost::intrusive::cache_last +//! - boost::intrusive::bucket_traits / boost::intrusive::store_hash / boost::intrusive::optimize_multikey +//! - boost::intrusive::power_2_buckets / boost::intrusive::cache_begin / boost::intrusive::compare_hash / boost::intrusive::incremental +//! +//! It forward declares the following value traits utilities: +//! - boost::intrusive::value_traits / boost::intrusive::derivation_value_traits / +//! boost::intrusive::trivial_value_traits +//! +//! Finally it forward declares the following general purpose utilities: +//! - boost::intrusive::pointer_plus_bits / boost::intrusive::priority_compare. + +#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +#include +#include +#include + +namespace boost { +namespace intrusive { + +#if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) +# ifdef BOOST_HAS_INTPTR_T + using ::boost::uintptr_t; +# else + typedef std::size_t uintptr_t; +# endif +#endif + +//////////////////////////// +// Node algorithms +//////////////////////////// + +//Algorithms predeclarations +template +class circular_list_algorithms; + +template +class circular_slist_algorithms; + +template +class linear_slist_algorithms; + +template +class bstree_algorithms; + +template +class rbtree_algorithms; + +template +class avltree_algorithms; + +template +class sgtree_algorithms; + +template +class splaytree_algorithms; + +template +class treap_algorithms; + +//////////////////////////// +// Containers +//////////////////////////// + +//slist +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class slist; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class slist_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class slist_member_hook; + +//list +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class list; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class list_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class list_member_hook; + +//rbtree/set/multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class rbtree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class set_member_hook; + +//splaytree/splay_set/splay_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class splaytree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class splay_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class splay_multiset; + +//avltree/avl_set/avl_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class avltree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class avl_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class avl_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class avl_set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class avl_set_member_hook; + + +//treap/treap_set/treap_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + > +#else +template +#endif +class treap; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + > +#else +template +#endif +class treap_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + > +#else +template +#endif +class treap_multiset; + +//sgtree/sg_set/sg_multiset +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class sgtree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class sg_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class sg_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class bstree; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class bs_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + > +#else +template +#endif +class bs_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class bs_set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class bs_set_member_hook; + +//hashtable/unordered_set/unordered_multiset + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + > +#else +template +#endif +class hashtable; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + > +#else +template +#endif +class unordered_set; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class T + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + > +#else +template +#endif +class unordered_multiset; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class unordered_set_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + > +#else +template +#endif +class unordered_set_member_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class any_base_hook; + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) +template + < class O1 = void + , class O2 = void + , class O3 = void + > +#else +template +#endif +class any_member_hook; + +//Options + +template +struct constant_time_size; + +template +struct size_type; + +template +struct compare; + +template +struct floating_point; + +template +struct equal; + +template +struct priority; + +template +struct hash; + +template struct value_traits; + +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook; + +template +struct function_hook; + +template +struct base_hook; + +template +struct void_pointer; + +template +struct tag; + +template +struct link_mode; + +template struct +optimize_size; + +template +struct linear; + +template +struct cache_last; + +template +struct bucket_traits; + +template +struct store_hash; + +template +struct optimize_multikey; + +template +struct power_2_buckets; + +template +struct cache_begin; + +template +struct compare_hash; + +template +struct incremental; + +//Value traits + +template +struct value_traits; + +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook; + +template< typename Functor> +struct function_hook; + +template +struct base_hook; + +template +struct derivation_value_traits; + +template +struct trivial_value_traits; + +//Additional utilities + +template +struct max_pointer_plus_bits; + +template +struct max_pointer_plus_bits; + +template +struct pointer_plus_bits; + +template +struct pointer_plus_bits; + +template +struct pointer_traits; + +template +struct pointer_traits; + +} //namespace intrusive { +} //namespace boost { + +#endif //#if !defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + +#endif //#ifndef BOOST_INTRUSIVE_FWD_HPP diff --git a/src/vendor/boost/intrusive/linear_slist_algorithms.hpp b/src/vendor/boost/intrusive/linear_slist_algorithms.hpp new file mode 100644 index 000000000..6aeb036ab --- /dev/null +++ b/src/vendor/boost/intrusive/linear_slist_algorithms.hpp @@ -0,0 +1,342 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Olaf Krzikalla 2004-2006. +// (C) Copyright Ion Gaztanaga 2006-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP +#define BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP + +#include +#include +#include +#include +#include +#include //std::pair + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//! linear_slist_algorithms provides basic algorithms to manipulate nodes +//! forming a linear singly linked list. +//! +//! linear_slist_algorithms is configured with a NodeTraits class, which encapsulates the +//! information about the node to be manipulated. NodeTraits must support the +//! following interface: +//! +//! Typedefs: +//! +//! node: The type of the node that forms the linear list +//! +//! node_ptr: A pointer to a node +//! +//! const_node_ptr: A pointer to a const node +//! +//! Static functions: +//! +//! static node_ptr get_next(const_node_ptr n); +//! +//! static void set_next(node_ptr n, node_ptr next); +template +class linear_slist_algorithms + /// @cond + : public detail::common_slist_algorithms + /// @endcond +{ + /// @cond + typedef detail::common_slist_algorithms base_t; + /// @endcond + public: + typedef typename NodeTraits::node node; + typedef typename NodeTraits::node_ptr node_ptr; + typedef typename NodeTraits::const_node_ptr const_node_ptr; + typedef NodeTraits node_traits; + + #if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Constructs an non-used list element, putting the next + //! pointer to null: + //! NodeTraits::get_next(this_node) == node_ptr() + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void init(const node_ptr & this_node); + + //! Requires: this_node must be in a circular list or be an empty circular list. + //! + //! Effects: Returns true is "this_node" is the only node of a circular list: + //! or it's a not inserted node: + //! return node_ptr() == NodeTraits::get_next(this_node) || NodeTraits::get_next(this_node) == this_node + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool unique(const_node_ptr this_node); + + //! Effects: Returns true is "this_node" has the same state as if + //! it was inited using "init(node_ptr)" + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static bool inited(const_node_ptr this_node); + + //! Requires: prev_node must be in a circular list or be an empty circular list. + //! + //! Effects: Unlinks the next node of prev_node from the circular list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(const node_ptr & prev_node); + + //! Requires: prev_node and last_node must be in a circular list + //! or be an empty circular list. + //! + //! Effects: Unlinks the range (prev_node, last_node) from the linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void unlink_after(const node_ptr & prev_node, const node_ptr & last_node); + + //! Requires: prev_node must be a node of a linear list. + //! + //! Effects: Links this_node after prev_node in the linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void link_after(const node_ptr & prev_node, const node_ptr & this_node); + + //! Requires: b and e must be nodes of the same linear list or an empty range. + //! and p must be a node of a different linear list. + //! + //! Effects: Removes the nodes from (b, e] range from their linear list and inserts + //! them after p in p's linear list. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void transfer_after(const node_ptr & p, const node_ptr & b, const node_ptr & e); + + #endif //#if defined(BOOST_INTRUSIVE_DOXYGEN_INVOKED) + + //! Effects: Constructs an empty list, making this_node the only + //! node of the circular list: + //! NodeTraits::get_next(this_node) == this_node. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static void init_header(const node_ptr & this_node) + { NodeTraits::set_next(this_node, node_ptr ()); } + + //! Requires: this_node and prev_init_node must be in the same linear list. + //! + //! Effects: Returns the previous node of this_node in the linear list starting. + //! the search from prev_init_node. The first node checked for equality + //! is NodeTraits::get_next(prev_init_node). + //! + //! Complexity: Linear to the number of elements between prev_init_node and this_node. + //! + //! Throws: Nothing. + BOOST_INTRUSIVE_FORCEINLINE static node_ptr get_previous_node(const node_ptr & prev_init_node, const node_ptr & this_node) + { return base_t::get_previous_node(prev_init_node, this_node); } + + //! Requires: this_node must be in a linear list or be an empty linear list. + //! + //! Effects: Returns the number of nodes in a linear list. If the linear list + //! is empty, returns 1. + //! + //! Complexity: Linear + //! + //! Throws: Nothing. + static std::size_t count(const const_node_ptr & this_node) + { + std::size_t result = 0; + const_node_ptr p = this_node; + do{ + p = NodeTraits::get_next(p); + ++result; + } while (p); + return result; + } + + //! Requires: this_node and other_node must be nodes inserted + //! in linear lists or be empty linear lists. + //! + //! Effects: Moves all the nodes previously chained after this_node after other_node + //! and vice-versa. + //! + //! Complexity: Constant + //! + //! Throws: Nothing. + static void swap_trailing_nodes(node_ptr this_node, node_ptr other_node) + { + node_ptr this_nxt = NodeTraits::get_next(this_node); + node_ptr other_nxt = NodeTraits::get_next(other_node); + NodeTraits::set_next(this_node, other_nxt); + NodeTraits::set_next(other_node, this_nxt); + } + + //! Effects: Reverses the order of elements in the list. + //! + //! Returns: The new first node of the list. + //! + //! Throws: Nothing. + //! + //! Complexity: This function is linear to the contained elements. + static node_ptr reverse(node_ptr p) + { + if(!p) return node_ptr(); + node_ptr i = NodeTraits::get_next(p); + node_ptr first(p); + while(i){ + node_ptr nxti(NodeTraits::get_next(i)); + base_t::unlink_after(p); + NodeTraits::set_next(i, first); + first = i; + i = nxti; + } + return first; + } + + //! Effects: Moves the first n nodes starting at p to the end of the list. + //! + //! Returns: A pair containing the new first and last node of the list or + //! if there has been any movement, a null pair if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static std::pair move_first_n_backwards(node_ptr p, std::size_t n) + { + std::pair ret; + //Null shift, or count() == 0 or 1, nothing to do + if(!n || !p || !NodeTraits::get_next(p)){ + return ret; + } + + node_ptr first = p; + bool end_found = false; + node_ptr new_last = node_ptr(); + node_ptr old_last = node_ptr(); + + //Now find the new last node according to the shift count. + //If we find 0 before finding the new last node + //unlink p, shortcut the search now that we know the size of the list + //and continue. + for(std::size_t i = 1; i <= n; ++i){ + new_last = first; + first = NodeTraits::get_next(first); + if(first == node_ptr()){ + //Shortcut the shift with the modulo of the size of the list + n %= i; + if(!n) return ret; + old_last = new_last; + i = 0; + //Unlink p and continue the new first node search + first = p; + //unlink_after(new_last); + end_found = true; + } + } + + //If the p has not been found in the previous loop, find it + //starting in the new first node and unlink it + if(!end_found){ + old_last = base_t::get_previous_node(first, node_ptr()); + } + + //Now link p after the new last node + NodeTraits::set_next(old_last, p); + NodeTraits::set_next(new_last, node_ptr()); + ret.first = first; + ret.second = new_last; + return ret; + } + + //! Effects: Moves the first n nodes starting at p to the beginning of the list. + //! + //! Returns: A pair containing the new first and last node of the list or + //! if there has been any movement, a null pair if n leads to no movement. + //! + //! Throws: Nothing. + //! + //! Complexity: Linear to the number of elements plus the number moved positions. + static std::pair move_first_n_forward(node_ptr p, std::size_t n) + { + std::pair ret; + //Null shift, or count() == 0 or 1, nothing to do + if(!n || !p || !NodeTraits::get_next(p)) + return ret; + + node_ptr first = p; + + //Iterate until p is found to know where the current last node is. + //If the shift count is less than the size of the list, we can also obtain + //the position of the new last node after the shift. + node_ptr old_last(first), next_to_it, new_last(p); + std::size_t distance = 1; + while(!!(next_to_it = node_traits::get_next(old_last))){ + if(distance++ > n) + new_last = node_traits::get_next(new_last); + old_last = next_to_it; + } + //If the shift was bigger or equal than the size, obtain the equivalent + //forward shifts and find the new last node. + if(distance <= n){ + //Now find the equivalent forward shifts. + //Shortcut the shift with the modulo of the size of the list + std::size_t new_before_last_pos = (distance - (n % distance))% distance; + //If the shift is a multiple of the size there is nothing to do + if(!new_before_last_pos) + return ret; + + for( new_last = p + ; --new_before_last_pos + ; new_last = node_traits::get_next(new_last)){ + //empty + } + } + + //Get the first new node + node_ptr new_first(node_traits::get_next(new_last)); + //Now put the old beginning after the old end + NodeTraits::set_next(old_last, p); + NodeTraits::set_next(new_last, node_ptr()); + ret.first = new_first; + ret.second = new_last; + return ret; + } +}; + +/// @cond + +template +struct get_algo +{ + typedef linear_slist_algorithms type; +}; + +/// @endcond + +} //namespace intrusive +} //namespace boost + +#include + +#endif //BOOST_INTRUSIVE_LINEAR_SLIST_ALGORITHMS_HPP diff --git a/src/vendor/boost/intrusive/link_mode.hpp b/src/vendor/boost/intrusive/link_mode.hpp new file mode 100644 index 000000000..4ba4daff7 --- /dev/null +++ b/src/vendor/boost/intrusive/link_mode.hpp @@ -0,0 +1,63 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2006-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_LINK_MODE_HPP +#define BOOST_INTRUSIVE_LINK_MODE_HPP + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +//!This enumeration defines the type of value_traits that can be defined +//!for Boost.Intrusive containers +enum link_mode_type{ + //!If this linking policy is specified in a value_traits class + //!as the link_mode, containers + //!configured with such value_traits won't set the hooks + //!of the erased values to a default state. Containers also won't + //!check that the hooks of the new values are default initialized. + normal_link, + + //!If this linking policy is specified in a value_traits class + //!as the link_mode, containers + //!configured with such value_traits will set the hooks + //!of the erased values to a default state. Containers also will + //!check that the hooks of the new values are default initialized. + safe_link, + + //!Same as "safe_link" but the user type is an auto-unlink + //!type, so the containers with constant-time size features won't be + //!compatible with value_traits configured with this policy. + //!Containers also know that the a value can be silently erased from + //!the container without using any function provided by the containers. + auto_unlink +}; + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +template +struct is_safe_autounlink +{ + static const bool value = + (int)link_mode == (int)auto_unlink || + (int)link_mode == (int)safe_link; +}; + +#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED + +} //namespace intrusive +} //namespace boost + +#endif //BOOST_INTRUSIVE_LINK_MODE_HPP diff --git a/src/vendor/boost/intrusive/options.hpp b/src/vendor/boost/intrusive/options.hpp new file mode 100644 index 000000000..8bf9ca8a8 --- /dev/null +++ b/src/vendor/boost/intrusive/options.hpp @@ -0,0 +1,264 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2007-2014 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_OPTIONS_HPP +#define BOOST_INTRUSIVE_OPTIONS_HPP + +#include +#include +#include +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +struct empty +{}; + +template +struct fhtraits; + +template +struct mhtraits; + +struct dft_tag; +struct member_tag; + +template +struct is_default_hook_tag; + +#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +//!This option setter specifies if the intrusive +//!container stores its size as a member to +//!obtain constant-time size() member. +BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size) + +//!This option setter specifies a container header holder type +BOOST_INTRUSIVE_OPTION_TYPE(header_holder_type, HeaderHolder, HeaderHolder, header_holder_type) + +//!This option setter specifies the type that +//!the container will use to store its size. +BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type) + +//!This option setter specifies the strict weak ordering +//!comparison functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare) + +//!This option setter specifies a function object +//!that specifies the type of the key of an associative +//!container and an operator to obtain it from a value type. +//! +//!This function object must the define a `type` member typedef and +//!a member with signature `type [const&] operator()(const value_type &) const` +//!that will return the key from a value_type of an associative container +BOOST_INTRUSIVE_OPTION_TYPE(key_of_value, KeyOfValue, KeyOfValue, key_of_value) + +//!This option setter specifies a function object +//!that specifies the type of the priority of a treap +//!container and an operator to obtain it from a value type. +//! +//!This function object must the define a `type` member typedef and +//!a member with signature `type [const&] operator()(const value_type &) const` +//!that will return the priority from a value_type of a treap container +BOOST_INTRUSIVE_OPTION_TYPE(priority_of_value, PrioOfValue, PrioOfValue, priority_of_value) + +//!This option setter for scapegoat containers specifies if +//!the intrusive scapegoat container should use a non-variable +//!alpha value that does not need floating-point operations. +//! +//!If activated, the fixed alpha value is 1/sqrt(2). This +//!option also saves some space in the container since +//!the alpha value and some additional data does not need +//!to be stored in the container. +//! +//!If the user only needs an alpha value near 1/sqrt(2), this +//!option also improves performance since avoids logarithm +//!and division operations when rebalancing the tree. +BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point) + +//!This option setter specifies the equality +//!functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal) + +//!This option setter specifies the priority comparison +//!functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority) + +//!This option setter specifies the hash +//!functor for the value type +BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash) + +//!This option setter specifies the relationship between the type +//!to be managed by the container (the value type) and the node to be +//!used in the node algorithms. It also specifies the linking policy. +BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits) + +//#define BOOST_INTRUSIVE_COMMA , +//#define BOOST_INTRUSIVE_LESS < +//#define BOOST_INTRUSIVE_MORE > +//BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits) +//template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember> +//struct member_hook { +// template struct pack : Base { +// typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits; +// }; +//}; +// +//#undef BOOST_INTRUSIVE_COMMA +//#undef BOOST_INTRUSIVE_LESS +//#undef BOOST_INTRUSIVE_MORE + +//!This option setter specifies the member hook the +//!container must use. +template< typename Parent + , typename MemberHook + , MemberHook Parent::* PtrToMember> +struct member_hook +{ +// @cond +// typedef typename MemberHook::hooktags::node_traits node_traits; +// typedef typename node_traits::node node_type; +// typedef node_type Parent::* Ptr2MemNode; +// typedef mhtraits +// < Parent +// , node_traits +// //This cast is really ugly but necessary to reduce template bloat. +// //Since we control the layout between the hook and the node, and there is +// //always single inheritance, the offset of the node is exactly the offset of +// //the hook. Since the node type is shared between all member hooks, this saves +// //quite a lot of symbol stuff. +// , (Ptr2MemNode)PtrToMember +// , MemberHook::hooktags::link_mode> member_value_traits; + typedef mhtraits member_value_traits; + template + struct pack : Base + { + typedef member_value_traits proto_value_traits; + }; +/// @endcond +}; + +//!This option setter specifies the function object that will +//!be used to convert between values to be inserted in a container +//!and the hook to be used for that purpose. +BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits, proto_value_traits) + +//!This option setter specifies that the container +//!must use the specified base hook +BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits) + +//!This option setter specifies the type of +//!a void pointer. This will instruct the hook +//!to use this type of pointer instead of the +//!default one +BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer) + +//!This option setter specifies the type of +//!the tag of a base hook. A type cannot have two +//!base hooks of the same type, so a tag can be used +//!to differentiate two base hooks with otherwise same type +BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag) + +//!This option setter specifies the link mode +//!(normal_link, safe_link or auto_unlink) +BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode) + +//!This option setter specifies if the hook +//!should be optimized for size instead of for speed. +BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size) + +//!This option setter specifies if the slist container should +//!use a linear implementation instead of a circular one. +BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear) + +//!If true, slist also stores a pointer to the last element of the singly linked list. +//!This allows O(1) swap and splice_after(iterator, slist &) for circular slists and makes +//!possible new functions like push_back(reference) and back(). +BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last) + +//!This option setter specifies the bucket traits +//!class for unordered associative containers. When this option is specified, +//!instead of using the default bucket traits, a user defined holder will be defined +BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits) + +//!This option setter specifies if the unordered hook +//!should offer room to store the hash value. +//!Storing the hash in the hook will speed up rehashing +//!processes in applications where rehashing is frequent, +//!rehashing might throw or the value is heavy to hash. +BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash) + +//!This option setter specifies if the unordered hook +//!should offer room to store another link to another node +//!with the same key. +//!Storing this link will speed up lookups and insertions on +//!unordered_multiset containers with a great number of elements +//!with the same key. +BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey) + +//!This option setter specifies if the bucket array will be always power of two. +//!This allows using masks instead of the default modulo operation to determine +//!the bucket number from the hash value, leading to better performance. +//!In debug mode, if power of two buckets mode is activated, the bucket length +//!will be checked with assertions. +BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets) + +//!This option setter specifies if the container will cache a pointer to the first +//!non-empty bucket so that begin() is always constant-time. +//!This is specially helpful when we can have containers with a few elements +//!but with big bucket arrays (that is, hashtables with low load factors). +BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin) + +//!This option setter specifies if the container will compare the hash value +//!before comparing objects. This option can't be specified if store_hash<> +//!is not true. +//!This is specially helpful when we have containers with a high load factor. +//!and the comparison function is much more expensive that comparing already +//!stored hash values. +BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash) + +//!This option setter specifies if the hash container will use incremental +//!hashing. With incremental hashing the cost of hash table expansion is spread +//!out across each hash table insertion operation, as opposed to be incurred all at once. +//!Therefore linear hashing is well suited for interactive applications or real-time +//!appplications where the worst-case insertion time of non-incremental hash containers +//!(rehashing the whole bucket array) is not admisible. +BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental) + +/// @cond + +struct hook_defaults +{ + typedef void* void_pointer; + static const link_mode_type link_mode = safe_link; + typedef dft_tag tag; + static const bool optimize_size = false; + static const bool store_hash = false; + static const bool linear = false; + static const bool optimize_multikey = false; +}; + +/// @endcond + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_OPTIONS_HPP diff --git a/src/vendor/boost/intrusive/pack_options.hpp b/src/vendor/boost/intrusive/pack_options.hpp new file mode 100644 index 000000000..ff07678ff --- /dev/null +++ b/src/vendor/boost/intrusive/pack_options.hpp @@ -0,0 +1,380 @@ +///////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2013-2013 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +///////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP +#define BOOST_INTRUSIVE_PACK_OPTIONS_HPP + +#include + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + +template +struct do_pack +{ + //Use "pack" member template to pack options + typedef typename Next::template pack type; +}; + +template +struct do_pack +{ + //Avoid packing "void" to shorten template names + typedef Prev type; +}; + +template + < class DefaultOptions + , class O1 = void + , class O2 = void + , class O3 = void + , class O4 = void + , class O5 = void + , class O6 = void + , class O7 = void + , class O8 = void + , class O9 = void + , class O10 = void + , class O11 = void + > +struct pack_options +{ + // join options + typedef + typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < typename do_pack + < DefaultOptions + , O1 + >::type + , O2 + >::type + , O3 + >::type + , O4 + >::type + , O5 + >::type + , O6 + >::type + , O7 + >::type + , O8 + >::type + , O9 + >::type + , O10 + >::type + , O11 + >::type + type; +}; +#else + +//index_tuple +template +struct index_tuple{}; + +//build_number_seq +template > +struct build_number_seq; + +template +struct build_number_seq > + : build_number_seq > +{}; + +template +struct build_number_seq<0, index_tuple > +{ typedef index_tuple type; }; + +template +struct typelist +{}; + +//invert_typelist +template +struct invert_typelist; + +template +struct typelist_element; + +template +struct typelist_element > +{ + typedef typename typelist_element >::type type; +}; + +template +struct typelist_element<0, typelist > +{ + typedef Head type; +}; + +template +typelist >::type...> + inverted_typelist(index_tuple, typelist) +{ + return typelist >::type...>(); +} + +//sizeof_typelist +template +struct sizeof_typelist; + +template +struct sizeof_typelist< typelist > +{ + static const std::size_t value = sizeof...(Types); +}; + +//invert_typelist_impl +template +struct invert_typelist_impl; + + +template +struct invert_typelist_impl< Typelist, index_tuple > +{ + static const std::size_t last_idx = sizeof_typelist::value - 1; + typedef typelist + ::type...> type; +}; + +template +struct invert_typelist_impl< Typelist, index_tuple > +{ + typedef Typelist type; +}; + +template +struct invert_typelist_impl< Typelist, index_tuple<> > +{ + typedef Typelist type; +}; + +//invert_typelist +template +struct invert_typelist; + +template +struct invert_typelist< typelist > +{ + typedef typelist typelist_t; + typedef typename build_number_seq::type indexes_t; + typedef typename invert_typelist_impl::type type; +}; + +//Do pack +template +struct do_pack; + +template<> +struct do_pack >; + +template +struct do_pack > +{ + typedef Prev type; +}; + +template +struct do_pack > +{ + typedef typename Prev::template pack type; +}; + +template +struct do_pack > +{ + typedef typename do_pack >::type type; +}; + +template +struct do_pack > +{ + typedef typename Prev::template pack + >::type> type; +}; + + +template +struct pack_options +{ + typedef typelist typelist_t; + typedef typename invert_typelist::type inverted_typelist; + typedef typename do_pack::type type; +}; + +#endif //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES) + +#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \ +template< class TYPE> \ +struct OPTION_NAME \ +{ \ + template \ + struct pack : Base \ + { \ + typedef TYPEDEF_EXPR TYPEDEF_NAME; \ + }; \ +}; \ +// + +#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \ +template< TYPE VALUE> \ +struct OPTION_NAME \ +{ \ + template \ + struct pack : Base \ + { \ + static const TYPE CONSTANT_NAME = VALUE; \ + }; \ +}; \ +// + +#else //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + +//! This class is a utility that takes: +//! - a default options class defining initial static constant +//! and typedefs +//! - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and +//! BOOST_INTRUSIVE_OPTION_TYPE +//! +//! and packs them together in a new type that defines all options as +//! member typedefs or static constant values. Given options of form: +//! +//! \code +//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type) +//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) +//! \endcode +//! +//! the following expression +//! +//! \code +//! +//! struct default_options +//! { +//! typedef long int_type; +//! static const int int_constant = -1; +//! }; +//! +//! pack_options< default_options, my_pointer, incremental >::type +//! \endcode +//! +//! will create a type that will contain the following typedefs/constants +//! +//! \code +//! struct unspecified_type +//! { +//! //Default options +//! typedef long int_type; +//! static const int int_constant = -1; +//! +//! //Packed options (will ovewrite any default option) +//! typedef void* my_pointer_type; +//! static const bool is_incremental = true; +//! }; +//! \endcode +//! +//! If an option is specified in the default options argument and later +//! redefined as an option, the last definition will prevail. +template +struct pack_options +{ + typedef unspecified_type type; +}; + +//! Defines an option class of name OPTION_NAME that can be used to specify a type +//! of type TYPE... +//! +//! \code +//! struct OPTION_NAME +//! { unspecified_content }; +//! \endcode +//! +//! ...that after being combined with +//! boost::intrusive::pack_options, +//! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example: +//! +//! \code +//! //[includes and namespaces omitted for brevity] +//! +//! //This macro will create the following class: +//! // template +//! // struct my_pointer +//! // { unspecified_content }; +//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer::type, my_pointer_type) +//! +//! struct empty_default{}; +//! +//! typedef pack_options< empty_default, typename my_pointer >::type::my_pointer_type type; +//! +//! BOOST_STATIC_ASSERT(( boost::is_same::value )); +//! +//! \endcode +#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) + +//! Defines an option class of name OPTION_NAME that can be used to specify a constant +//! of type TYPE with value VALUE... +//! +//! \code +//! struct OPTION_NAME +//! { unspecified_content }; +//! \endcode +//! +//! ...that after being combined with +//! boost::intrusive::pack_options, +//! will contain a CONSTANT_NAME static constant of value VALUE. Example: +//! +//! \code +//! //[includes and namespaces omitted for brevity] +//! +//! //This macro will create the following class: +//! // template +//! // struct incremental +//! // { unspecified_content }; +//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental) +//! +//! struct empty_default{}; +//! +//! const bool is_incremental = pack_options< empty_default, incremental >::type::is_incremental; +//! +//! BOOST_STATIC_ASSERT(( is_incremental == true )); +//! +//! \endcode +#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) + +#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED + + +} //namespace intrusive { +} //namespace boost { + +#include + +#endif //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP diff --git a/src/vendor/boost/intrusive/pointer_rebind.hpp b/src/vendor/boost/intrusive/pointer_rebind.hpp new file mode 100644 index 000000000..9592e06e1 --- /dev/null +++ b/src/vendor/boost/intrusive/pointer_rebind.hpp @@ -0,0 +1,188 @@ +////////////////////////////////////////////////////////////////////////////// +// +// (C) Copyright Ion Gaztanaga 2014-2014. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See http://www.boost.org/libs/intrusive for documentation. +// +////////////////////////////////////////////////////////////////////////////// + +#ifndef BOOST_INTRUSIVE_POINTER_REBIND_HPP +#define BOOST_INTRUSIVE_POINTER_REBIND_HPP + +#ifndef BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP +#include +#endif //BOOST_INTRUSIVE_DETAIL_WORKAROUND_HPP + +#ifndef BOOST_CONFIG_HPP +# include +#endif + +#if defined(BOOST_HAS_PRAGMA_ONCE) +# pragma once +#endif + +namespace boost { +namespace intrusive { + +/////////////////////////// +//struct pointer_rebind_mode +/////////////////////////// +template +struct pointer_has_rebind +{ + template struct any + { any(const V&) { } }; + + template + static char test(int, typename X::template rebind*); + + template + static int test(any, void*); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + +template +struct pointer_has_rebind_other +{ + template struct any + { any(const V&) { } }; + + template + static char test(int, typename X::template rebind::other*); + + template + static int test(any, void*); + + static const bool value = (1 == sizeof(test(0, 0))); +}; + +template +struct pointer_rebind_mode +{ + static const unsigned int rebind = (unsigned int)pointer_has_rebind::value; + static const unsigned int rebind_other = (unsigned int)pointer_has_rebind_other::value; + static const unsigned int mode = rebind + rebind*rebind_other; +}; + +//////////////////////// +//struct pointer_rebinder +//////////////////////// +template +struct pointer_rebinder; + +// Implementation of pointer_rebinder::type if Ptr has +// its own rebind::other type (C++03) +template +struct pointer_rebinder< Ptr, U, 2u > +{ + typedef typename Ptr::template rebind::other type; +}; + +// Implementation of pointer_rebinder::type if Ptr has +// its own rebind template. +template +struct pointer_rebinder< Ptr, U, 1u > +{ + typedef typename Ptr::template rebind type; +}; + +// Specialization of pointer_rebinder if Ptr does not +// have its own rebind template but has a the form Ptr, +// where An... comprises zero or more type parameters. +// Many types fit this form, hence many pointers will get a +// reasonable default for rebind. +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) + +template