├── .Rbuildignore ├── .clang-format ├── .github ├── .gitignore ├── CODE_OF_CONDUCT.md └── workflows │ ├── R-CMD-check.yaml │ ├── pkgdown.yaml │ ├── pr-commands.yaml │ └── test-coverage.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE ├── LICENSE.md ├── LICENSE.note ├── NAMESPACE ├── NEWS.md ├── R ├── aaa.R ├── altrep-lazy-character.R ├── altrep.R ├── arith.R ├── assert.R ├── bind.R ├── c.R ├── cast.R ├── compare.R ├── complete.R ├── conditions.R ├── dictionary.R ├── dim.R ├── empty.R ├── equal.R ├── expand.R ├── faq-developer.R ├── faq-internal.R ├── faq.R ├── fields.R ├── fill.R ├── group.R ├── hash.R ├── import-standalone-linked-version.R ├── import-standalone-obj-type.R ├── import-standalone-purrr.R ├── import-standalone-types-check.R ├── interval.R ├── match.R ├── missing.R ├── names.R ├── numeric.R ├── order.R ├── partial-factor.R ├── partial-frame.R ├── partial.R ├── print-str.R ├── proxy.R ├── ptype-abbr-full.R ├── rank.R ├── recycle.R ├── register-s3.R ├── rep.R ├── runs.R ├── set.R ├── shape.R ├── size.R ├── slice-chop.R ├── slice-interleave.R ├── slice.R ├── split.R ├── subscript-loc.R ├── subscript.R ├── translate.R ├── type-asis.R ├── type-bare.R ├── type-data-frame.R ├── type-data-table.R ├── type-date-time.R ├── type-dplyr.R ├── type-explore.R ├── type-factor.R ├── type-integer64.R ├── type-list-of.R ├── type-misc.R ├── type-rcrd.R ├── type-sclr.R ├── type-sf.R ├── type-table.R ├── type-tibble.R ├── type-unspecified.R ├── type-vctr.R ├── type.R ├── type2.R ├── utils-cli.R ├── utils.R ├── vctrs-deprecated.R ├── vctrs-package.R └── zzz.R ├── README.Rmd ├── README.md ├── _pkgdown.yml ├── bench ├── order.Rmd ├── order.md ├── order_files │ └── figure-gfm │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-13-1.png │ │ ├── unnamed-chunk-15-1.png │ │ ├── unnamed-chunk-17-1.png │ │ ├── unnamed-chunk-18-1.png │ │ ├── unnamed-chunk-20-1.png │ │ ├── unnamed-chunk-23-1.png │ │ ├── unnamed-chunk-24-1.png │ │ ├── unnamed-chunk-27-1.png │ │ ├── unnamed-chunk-28-1.png │ │ └── unnamed-chunk-8-1.png ├── rbind.Rmd ├── rbind.md ├── sorting-vs-hashing.Rmd ├── sorting-vs-hashing.md ├── sorting-vs-hashing_files │ └── figure-gfm │ │ ├── unnamed-chunk-10-1.png │ │ ├── unnamed-chunk-11-1.png │ │ ├── unnamed-chunk-12-1.png │ │ ├── unnamed-chunk-14-1.png │ │ ├── unnamed-chunk-16-1.png │ │ ├── unnamed-chunk-6-1.png │ │ ├── unnamed-chunk-7-1.png │ │ └── unnamed-chunk-9-1.png ├── unique.Rmd ├── unique.md └── unique_files │ └── figure-gfm │ ├── unnamed-chunk-3-1.png │ ├── unnamed-chunk-5-1.png │ ├── unnamed-chunk-6-1.png │ ├── unnamed-chunk-7-1.png │ └── unnamed-chunk-8-1.png ├── codecov.yml ├── cran-comments.md ├── inst ├── WORDLIST └── include │ ├── vctrs.c │ └── vctrs.h ├── man ├── as-is.Rd ├── data_frame.Rd ├── df_list.Rd ├── df_ptype2.Rd ├── faq-compatibility-types.Rd ├── faq-error-incompatible-attributes.Rd ├── faq-error-scalar-type.Rd ├── faq │ ├── developer │ │ ├── howto-coercion-data-frame.Rmd │ │ ├── howto-coercion.Rmd │ │ ├── howto-faq-fix-scalar-type-error.Rmd │ │ ├── links-coercion.Rmd │ │ ├── reference-compatibility.Rmd │ │ ├── snippet-roxy-workflow.Rmd │ │ ├── theory-coercion.Rmd │ │ └── theory-recycling.Rmd │ ├── internal │ │ ├── matches-algorithm.Rmd │ │ └── ptype2-identity.Rmd │ ├── setup.Rmd │ └── user │ │ ├── faq-compatibility-types.Rmd │ │ └── faq-error-scalar-type.Rmd ├── fields.Rd ├── figures │ ├── cast.png │ ├── coerce.png │ ├── combined.png │ ├── lifecycle-archived.svg │ ├── lifecycle-defunct.svg │ ├── lifecycle-deprecated.svg │ ├── lifecycle-experimental.svg │ ├── lifecycle-maturing.svg │ ├── lifecycle-questioning.svg │ ├── lifecycle-soft-deprecated.svg │ ├── lifecycle-stable.svg │ ├── lifecycle-superseded.svg │ ├── logo.png │ ├── sizes-recycling.png │ ├── sizes.graffle │ ├── types.graffle │ ├── vec-count-deps.graffle │ ├── vec-count-deps.png │ └── vec-count-deps.svg ├── howto-faq-coercion-data-frame.Rd ├── howto-faq-coercion.Rd ├── howto-faq-fix-scalar-type-error.Rd ├── int64.Rd ├── internal-faq-matches-algorithm.Rd ├── internal-faq-ptype2-identity.Rd ├── list_drop_empty.Rd ├── list_of.Rd ├── maybe_lossy_cast.Rd ├── missing.Rd ├── name_spec.Rd ├── new_data_frame.Rd ├── new_date.Rd ├── new_factor.Rd ├── new_list_of.Rd ├── new_partial.Rd ├── new_rcrd.Rd ├── new_vctr.Rd ├── obj_is_list.Rd ├── obj_print.Rd ├── op-empty-default.Rd ├── order-radix.Rd ├── partial_factor.Rd ├── partial_frame.Rd ├── reference-faq-compatibility.Rd ├── runs.Rd ├── s3_register.Rd ├── table.Rd ├── theory-faq-coercion.Rd ├── theory-faq-recycling.Rd ├── unspecified.Rd ├── vctrs-conditions.Rd ├── vctrs-data-frame.Rd ├── vctrs-package.Rd ├── vec-rep.Rd ├── vec-set.Rd ├── vec_arith.Rd ├── vec_as_index.Rd ├── vec_as_location.Rd ├── vec_as_names.Rd ├── vec_as_names_legacy.Rd ├── vec_as_subscript.Rd ├── vec_assert.Rd ├── vec_bind.Rd ├── vec_c.Rd ├── vec_cast.Rd ├── vec_cbind_frame_ptype.Rd ├── vec_chop.Rd ├── vec_compare.Rd ├── vec_count.Rd ├── vec_data.Rd ├── vec_default_ptype2.Rd ├── vec_detect_complete.Rd ├── vec_duplicate.Rd ├── vec_empty.Rd ├── vec_equal.Rd ├── vec_equal_na.Rd ├── vec_expand_grid.Rd ├── vec_fill_missing.Rd ├── vec_group.Rd ├── vec_init.Rd ├── vec_interleave.Rd ├── vec_is_list.Rd ├── vec_locate_matches.Rd ├── vec_locate_sorted_groups.Rd ├── vec_match.Rd ├── vec_math.Rd ├── vec_names.Rd ├── vec_order.Rd ├── vec_proxy.Rd ├── vec_proxy_compare.Rd ├── vec_proxy_equal.Rd ├── vec_ptype.Rd ├── vec_ptype2.Rd ├── vec_ptype_full.Rd ├── vec_rank.Rd ├── vec_recycle.Rd ├── vec_repeat.Rd ├── vec_seq_along.Rd ├── vec_size.Rd ├── vec_slice.Rd ├── vec_split.Rd ├── vec_type.Rd ├── vec_unchop.Rd ├── vec_unique.Rd └── vector-checks.Rd ├── pkgdown └── favicon │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ ├── apple-touch-icon-76x76.png │ ├── apple-touch-icon.png │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ └── favicon.ico ├── revdep ├── .gitignore ├── README.md ├── cran.md ├── email.yml ├── failures.md └── problems.md ├── src ├── .gitignore ├── Makevars ├── altrep-lazy-character.c ├── altrep-rle.c ├── altrep-rle.h ├── altrep.c ├── altrep.h ├── arg-counter.c ├── arg-counter.h ├── arg.c ├── arg.h ├── assert.c ├── assert.h ├── bind.c ├── c-unchop.c ├── c-unchop.h ├── c.c ├── c.h ├── callables.c ├── cast-bare.c ├── cast-bare.h ├── cast-dispatch.c ├── cast-dispatch.h ├── cast.c ├── cast.h ├── compare.c ├── compare.h ├── complete.c ├── complete.h ├── conditions.c ├── conditions.h ├── decl │ ├── arg-counter-decl.h │ ├── arg-decl.h │ ├── assert-decl.h │ ├── bind-decl.h │ ├── c-decl.h │ ├── c-unchop-decl.h │ ├── cast-decl.h │ ├── compare-decl.h │ ├── dictionary-decl.h │ ├── empty-decl.h │ ├── expand-decl.h │ ├── interval-decl.h │ ├── match-decl.h │ ├── match-joint-decl.h │ ├── missing-decl.h │ ├── names-decl.h │ ├── poly-op-decl.h │ ├── proxy-decl.h │ ├── proxy-restore-decl.h │ ├── ptype-common-decl.h │ ├── ptype-decl.h │ ├── ptype2-decl.h │ ├── ptype2-dispatch-decl.h │ ├── rank-decl.h │ ├── rep-decl.h │ ├── rlang-dev-decl.h │ ├── runs-decl.h │ ├── set-decl.h │ ├── shape-decl.h │ ├── size-common-decl.h │ ├── size-decl.h │ ├── slice-assign-decl.h │ ├── slice-chop-decl.h │ ├── slice-interleave-decl.h │ ├── subscript-decl.h │ ├── subscript-loc-decl.h │ ├── type-data-frame-decl.h │ ├── type-info-decl.h │ ├── type-integer64-decl.h │ ├── typeof2-s3-decl.h │ └── utils-dispatch-decl.h ├── dictionary.c ├── dictionary.h ├── dim.c ├── dim.h ├── empty.c ├── equal.c ├── equal.h ├── expand.c ├── expand.h ├── fields.c ├── fill.c ├── globals.c ├── globals.h ├── group.c ├── growable.c ├── hash.c ├── hash.h ├── init.c ├── interval.c ├── lazy.h ├── match-compare.h ├── match-joint.c ├── match-joint.h ├── match.c ├── missing.c ├── missing.h ├── names.c ├── names.h ├── order-collate.c ├── order-collate.h ├── order-groups.c ├── order-groups.h ├── order-sortedness.c ├── order-sortedness.h ├── order-truelength.c ├── order-truelength.h ├── order.c ├── order.h ├── owned.h ├── poly-op.c ├── poly-op.h ├── proxy-restore.c ├── proxy-restore.h ├── proxy.c ├── proxy.h ├── ptype-common.c ├── ptype-common.h ├── ptype.c ├── ptype.h ├── ptype2-dispatch.c ├── ptype2-dispatch.h ├── ptype2.c ├── ptype2.h ├── rank.c ├── rep.c ├── rep.h ├── rlang-dev.c ├── rlang-dev.h ├── rlang.c ├── rlang │ ├── altrep.h │ ├── arg.c │ ├── arg.h │ ├── attrib.c │ ├── attrib.h │ ├── c-utils.c │ ├── c-utils.h │ ├── call.c │ ├── call.h │ ├── cnd.c │ ├── cnd.h │ ├── cpp │ │ ├── rlang.cpp │ │ └── vec.cpp │ ├── debug.c │ ├── debug.h │ ├── decl │ │ ├── cnd-decl.h │ │ ├── df-decl.h │ │ ├── dict-decl.h │ │ ├── dyn-list-of-decl.h │ │ ├── env-decl.h │ │ ├── obj-decl.h │ │ ├── stack-decl.h │ │ └── walk-decl.h │ ├── df.c │ ├── df.h │ ├── dict.c │ ├── dict.h │ ├── dyn-array.c │ ├── dyn-array.h │ ├── dyn-list-of.c │ ├── dyn-list-of.h │ ├── env-binding.c │ ├── env-binding.h │ ├── env.c │ ├── env.h │ ├── eval.c │ ├── eval.h │ ├── export.c │ ├── export.h │ ├── fn.c │ ├── fn.h │ ├── formula.c │ ├── formula.h │ ├── globals.c │ ├── globals.h │ ├── node.c │ ├── node.h │ ├── obj.c │ ├── obj.h │ ├── parse.c │ ├── parse.h │ ├── quo.c │ ├── quo.h │ ├── rlang-types.h │ ├── rlang.c │ ├── rlang.h │ ├── rlang.hpp │ ├── session.c │ ├── session.h │ ├── stack.c │ ├── stack.h │ ├── state.h │ ├── sym.c │ ├── sym.h │ ├── vec-chr.c │ ├── vec-chr.h │ ├── vec-lgl.c │ ├── vec-lgl.h │ ├── vec.c │ ├── vec.h │ ├── vendor.c │ ├── vendor.h │ ├── walk.c │ └── walk.h ├── runs.c ├── runs.h ├── set.c ├── set.h ├── shape.c ├── shape.h ├── size-common.c ├── size-common.h ├── size.c ├── size.h ├── slice-array.c ├── slice-assign-array.c ├── slice-assign.c ├── slice-assign.h ├── slice-chop.c ├── slice-chop.h ├── slice-interleave.c ├── slice.c ├── slice.h ├── split.c ├── strides.h ├── subscript-loc.c ├── subscript-loc.h ├── subscript.c ├── subscript.h ├── translate.c ├── translate.h ├── type-complex.h ├── type-data-frame.c ├── type-data-frame.h ├── type-date-time.c ├── type-factor.c ├── type-factor.h ├── type-info.c ├── type-info.h ├── type-integer64.c ├── type-tibble.c ├── type-tibble.h ├── typeof2-s3.c ├── typeof2-s3.h ├── typeof2.c ├── typeof2.h ├── unspecified.c ├── utils-dispatch.c ├── utils-dispatch.h ├── utils.c ├── utils.h ├── vctrs-core.c ├── vctrs-core.h ├── vctrs.h ├── vec-bool.h └── version.c ├── tests ├── testthat.R └── testthat │ ├── _snaps │ ├── assert.md │ ├── bind.md │ ├── c.md │ ├── cast.md │ ├── compare.md │ ├── complete.md │ ├── conditions.md │ ├── dictionary.md │ ├── equal.md │ ├── error-call.md │ ├── expand.md │ ├── group.md │ ├── hash.md │ ├── interval.md │ ├── lifecycle-deprecated.md │ ├── match.md │ ├── names.md │ ├── order.md │ ├── partial-factor.md │ ├── partial-frame.md │ ├── print-str.md │ ├── ptype-abbr-full.md │ ├── rank.md │ ├── recycle.md │ ├── rep.md │ ├── runs.md │ ├── set.md │ ├── shape.md │ ├── size.md │ ├── slice-assign.md │ ├── slice-chop.md │ ├── slice-interleave.md │ ├── slice.md │ ├── subscript-loc.md │ ├── subscript.md │ ├── type-asis.md │ ├── type-data-frame.md │ ├── type-data-table.md │ ├── type-date-time.md │ ├── type-factor.md │ ├── type-list-of.md │ ├── type-misc.md │ ├── type-rcrd.md │ ├── type-sf.md │ ├── type-table.md │ ├── type-tibble.md │ ├── type-unspecified.md │ ├── type-vctr.md │ ├── type.md │ └── type2.md │ ├── helper-c.R │ ├── helper-cast.R │ ├── helper-conditions.R │ ├── helper-encoding.R │ ├── helper-expectations.R │ ├── helper-memory.R │ ├── helper-names.R │ ├── helper-order.R │ ├── helper-performance.R │ ├── helper-rational.R │ ├── helper-restart.R │ ├── helper-s3.R │ ├── helper-s4.R │ ├── helper-shape.R │ ├── helper-size.R │ ├── helper-type-dplyr.R │ ├── helper-types.R │ ├── helper-vctrs.R │ ├── test-arith.R │ ├── test-assert.R │ ├── test-bind.R │ ├── test-c.R │ ├── test-cast.R │ ├── test-compare.R │ ├── test-complete.R │ ├── test-conditions.R │ ├── test-dictionary.R │ ├── test-dim.R │ ├── test-empty.R │ ├── test-equal.R │ ├── test-error-call.R │ ├── test-expand.R │ ├── test-fields.R │ ├── test-fill.R │ ├── test-group.R │ ├── test-hash.R │ ├── test-interval.R │ ├── test-lifecycle-deprecated.R │ ├── test-match.R │ ├── test-missing.R │ ├── test-names.R │ ├── test-order.R │ ├── test-partial-factor.R │ ├── test-partial-frame.R │ ├── test-print-str.R │ ├── test-proxy-restore.R │ ├── test-proxy.R │ ├── test-ptype-abbr-full.R │ ├── test-rank.R │ ├── test-recycle.R │ ├── test-rep.R │ ├── test-runs.R │ ├── test-s4.R │ ├── test-set.R │ ├── test-shape.R │ ├── test-size.R │ ├── test-slice-assign.R │ ├── test-slice-chop.R │ ├── test-slice-interleave.R │ ├── test-slice.R │ ├── test-split.R │ ├── test-subscript-loc.R │ ├── test-subscript.R │ ├── test-translate.R │ ├── test-type-asis.R │ ├── test-type-bare.R │ ├── test-type-data-frame.R │ ├── test-type-data-table.R │ ├── test-type-date-time.R │ ├── test-type-dplyr.R │ ├── test-type-factor.R │ ├── test-type-integer64.R │ ├── test-type-list-of.R │ ├── test-type-misc.R │ ├── test-type-rational.R │ ├── test-type-rcrd.R │ ├── test-type-sclr.R │ ├── test-type-sf.R │ ├── test-type-table.R │ ├── test-type-tibble.R │ ├── test-type-unspecified.R │ ├── test-type-vctr.R │ ├── test-type.R │ ├── test-type2.R │ ├── test-utils.R │ └── test-vctrs.R ├── vctrs.Rproj └── vignettes ├── .gitignore ├── pillar.Rmd ├── s3-vector.Rmd ├── stability.Rmd └── type-size.Rmd /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^CRAN-RELEASE$ 2 | ^cran-comments\.md$ 3 | ^bench$ 4 | ^docs$ 5 | ^_pkgdown\.yml$ 6 | ^codecov\.yml$ 7 | ^\.travis\.yml$ 8 | ^README\.Rmd$ 9 | ^man/figures/*\.graffle$ 10 | ^.*\.Rproj$ 11 | ^\.Rproj\.user$ 12 | ^TAGS$ 13 | ^revdep$ 14 | ^revdep-all$ 15 | ^\.github$ 16 | ^man/faq/.*\.html 17 | ^man/faq/.*/.*\.html 18 | ^LICENSE\.md$ 19 | ^\.projectile$ 20 | ^src/\.clang_complete$ 21 | ^\.clang-format$ 22 | \.clangd$ 23 | ^compile_commands\.json$ 24 | ^compile_flags\.txt$ 25 | ^\.dir-locals\.el$ 26 | ^\.cache$ 27 | ^launch\.json$ 28 | ^\.vscode$ 29 | ^CRAN-SUBMISSION$ 30 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | IndentWidth: 2 3 | AllowAllArgumentsOnNextLine: false 4 | BinPackParameters: false 5 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v3 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@v4.4.1 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs 47 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: | 31 | covr::codecov( 32 | quiet = FALSE, 33 | clean = FALSE, 34 | install_path = file.path(Sys.getenv("RUNNER_TEMP"), "package") 35 | ) 36 | shell: Rscript {0} 37 | 38 | - name: Show testthat output 39 | if: always() 40 | run: | 41 | ## -------------------------------------------------------------------- 42 | find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true 43 | shell: bash 44 | 45 | - name: Upload test results 46 | if: failure() 47 | uses: actions/upload-artifact@v3 48 | with: 49 | name: coverage-test-failures 50 | path: ${{ runner.temp }}/package 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | inst/doc 2 | man/faq/**/*.html 3 | .Rproj.user 4 | .Rhistory 5 | .RData 6 | docs 7 | .clangd 8 | launch.json 9 | .vscode/ 10 | .cache/ 11 | compile_commands.json 12 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: vctrs 2 | Title: Vector Helpers 3 | Version: 0.6.5.9000 4 | Authors@R: c( 5 | person("Hadley", "Wickham", , "hadley@posit.co", role = "aut"), 6 | person("Lionel", "Henry", , "lionel@posit.co", role = "aut"), 7 | person("Davis", "Vaughan", , "davis@posit.co", role = c("aut", "cre")), 8 | person("data.table team", role = "cph", 9 | comment = "Radix sort based on data.table's forder() and their contribution to R's order()"), 10 | person("Posit Software, PBC", role = c("cph", "fnd")) 11 | ) 12 | Description: Defines new notions of prototype and size that are used to 13 | provide tools for consistent and well-founded type-coercion and 14 | size-recycling, and are in turn connected to ideas of type- and 15 | size-stability useful for analysing function interfaces. 16 | License: MIT + file LICENSE 17 | URL: https://vctrs.r-lib.org/, https://github.com/r-lib/vctrs 18 | BugReports: https://github.com/r-lib/vctrs/issues 19 | Depends: 20 | R (>= 3.5.0) 21 | Imports: 22 | cli (>= 3.4.0), 23 | glue, 24 | lifecycle (>= 1.0.3), 25 | rlang (>= 1.1.0) 26 | Suggests: 27 | bit64, 28 | covr, 29 | crayon, 30 | dplyr (>= 0.8.5), 31 | generics, 32 | knitr, 33 | pillar (>= 1.4.4), 34 | pkgdown (>= 2.0.1), 35 | rmarkdown, 36 | testthat (>= 3.0.0), 37 | tibble (>= 3.1.3), 38 | waldo (>= 0.2.0), 39 | withr, 40 | xml2, 41 | zeallot 42 | VignetteBuilder: 43 | knitr 44 | Config/Needs/website: tidyverse/tidytemplate 45 | Config/testthat/edition: 3 46 | Config/testthat/parallel: true 47 | Encoding: UTF-8 48 | Language: en-GB 49 | Roxygen: list(markdown = TRUE) 50 | RoxygenNote: 7.3.2 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2023 2 | COPYRIGHT HOLDER: vctrs authors 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2023 vctrs authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /R/aaa.R: -------------------------------------------------------------------------------- 1 | replace_from <- function(what, pkg, to = topenv(caller_env())) { 2 | if (what %in% getNamespaceExports(pkg)) { 3 | env <- ns_env(pkg) 4 | } else { 5 | env <- to 6 | } 7 | env_get(env, what, inherit = TRUE) 8 | } 9 | 10 | # nocov start 11 | 12 | # Useful for micro-optimising default arguments requiring evaluation, 13 | # such as `param = c("foo", "bar")`. Buys about 0.6us on my desktop. 14 | fn_inline_formals <- function(fn, names) { 15 | stopifnot(typeof(fn) == "closure") 16 | 17 | fmls <- formals(fn) 18 | fmls[names] <- lapply(fmls[names], eval) 19 | 20 | formals(fn) <- fmls 21 | fn 22 | } 23 | 24 | # nocov end 25 | -------------------------------------------------------------------------------- /R/altrep-lazy-character.R: -------------------------------------------------------------------------------- 1 | #' Lazy character vector 2 | #' 3 | #' `new_lazy_character()` takes a function with no arguments which must return 4 | #' a character vector of arbitrary length. The function will be evaluated 5 | #' exactly once whenever any properties of the character vector are required 6 | #' (including the length or any vector elements). 7 | #' 8 | #' A "real" production level implementation might work more like 9 | #' `carrier::crate()`, where the function is isolated and users must explicitly 10 | #' provide any data required to evaluate the function, since the time of 11 | #' evaluation is unknown. 12 | #' 13 | #' As of June 2023, running `x <- new_lazy_character(~ c("x", "y"))` in the 14 | #' RStudio console will call the ALTREP length method, which materializes the 15 | #' object. Doing this in a terminal session running R does not, so it is an 16 | #' RStudio issue. This doesn't affect tests run within a `test_that()` block. 17 | #' 18 | #' @param fn A function with no arguments returning a character vector. 19 | #' 20 | #' @noRd 21 | new_lazy_character <- function(fn) { 22 | fn <- as_function(fn) 23 | .Call(ffi_altrep_new_lazy_character, fn) 24 | } 25 | 26 | lazy_character_is_materialized <- function(x) { 27 | .Call(ffi_altrep_lazy_character_is_materialized, x) 28 | } 29 | -------------------------------------------------------------------------------- /R/altrep.R: -------------------------------------------------------------------------------- 1 | is_altrep <- function(x) { 2 | .Call(vctrs_is_altrep, x) 3 | } 4 | -------------------------------------------------------------------------------- /R/empty.R: -------------------------------------------------------------------------------- 1 | #' Drop empty elements from a list 2 | #' 3 | #' `list_drop_empty()` removes empty elements from a list. This includes `NULL` 4 | #' elements along with empty vectors, like `integer(0)`. This is equivalent to, 5 | #' but faster than, `vec_slice(x, list_sizes(x) != 0L)`. 6 | #' 7 | #' @section Dependencies: 8 | #' - [vec_slice()] 9 | #' 10 | #' @param x A list. 11 | #' 12 | #' @export 13 | #' @examples 14 | #' x <- list(1, NULL, integer(), 2) 15 | #' list_drop_empty(x) 16 | list_drop_empty <- function(x) { 17 | .Call(vctrs_list_drop_empty, x) 18 | } 19 | -------------------------------------------------------------------------------- /R/faq-developer.R: -------------------------------------------------------------------------------- 1 | #' FAQ - Is my class compatible with vctrs? 2 | #' 3 | #' @includeRmd man/faq/developer/reference-compatibility.Rmd description 4 | #' 5 | #' @name reference-faq-compatibility 6 | NULL 7 | 8 | #' FAQ - How does coercion work in vctrs? 9 | #' 10 | #' @includeRmd man/faq/developer/theory-coercion.Rmd description 11 | #' 12 | #' @name theory-faq-coercion 13 | NULL 14 | 15 | # Also see the `redirects:` section in `_pkgdown.yml` 16 | # for `vector_recycling_rules.html` 17 | 18 | #' FAQ - How does recycling work in vctrs and the tidyverse? 19 | #' 20 | #' @includeRmd man/faq/developer/theory-recycling.Rmd description 21 | #' 22 | #' @name theory-faq-recycling 23 | #' @aliases vector_recycling_rules 24 | NULL 25 | 26 | #' FAQ - How to implement ptype2 and cast methods? 27 | #' 28 | #' @includeRmd man/faq/developer/howto-coercion.Rmd description 29 | #' 30 | #' @name howto-faq-coercion 31 | NULL 32 | 33 | #' FAQ - How to implement ptype2 and cast methods? (Data frames) 34 | #' 35 | #' @includeRmd man/faq/developer/howto-coercion-data-frame.Rmd description 36 | #' 37 | #' @name howto-faq-coercion-data-frame 38 | NULL 39 | 40 | #' FAQ - Why isn't my class treated as a vector? 41 | #' 42 | #' @includeRmd man/faq/developer/howto-faq-fix-scalar-type-error.Rmd description 43 | #' 44 | #' @name howto-faq-fix-scalar-type-error 45 | NULL 46 | -------------------------------------------------------------------------------- /R/faq-internal.R: -------------------------------------------------------------------------------- 1 | #' Internal FAQ - `vec_ptype2()`, `NULL`, and unspecified vectors 2 | #' 3 | #' @includeRmd man/faq/internal/ptype2-identity.Rmd description 4 | #' 5 | #' @name internal-faq-ptype2-identity 6 | NULL 7 | -------------------------------------------------------------------------------- /R/faq.R: -------------------------------------------------------------------------------- 1 | #' FAQ - How is the compatibility of vector types decided? 2 | #' 3 | #' @includeRmd man/faq/user/faq-compatibility-types.Rmd description 4 | #' 5 | #' @name faq-compatibility-types 6 | NULL 7 | 8 | 9 | #' FAQ - Error/Warning: Some attributes are incompatible 10 | #' 11 | #' @description 12 | #' 13 | #' This error occurs when [vec_ptype2()] or [vec_cast()] are supplied 14 | #' vectors of the same classes with different attributes. In this 15 | #' case, vctrs doesn't know how to combine the inputs. 16 | #' 17 | #' To fix this error, the maintainer of the class should implement 18 | #' self-to-self coercion methods for [vec_ptype2()] and [vec_cast()]. 19 | #' 20 | #' @includeRmd man/faq/developer/links-coercion.Rmd 21 | #' 22 | #' @name faq-error-incompatible-attributes 23 | NULL 24 | 25 | 26 | #' FAQ - Error: Input must be a vector 27 | #' 28 | #' @includeRmd man/faq/user/faq-error-scalar-type.Rmd description 29 | #' 30 | #' @name faq-error-scalar-type 31 | NULL 32 | -------------------------------------------------------------------------------- /R/fields.R: -------------------------------------------------------------------------------- 1 | #' Tools for accessing the fields of a record. 2 | #' 3 | #' A [rcrd] behaves like a vector, so `length()`, `names()`, and `$` can 4 | #' not provide access to the fields of the underlying list. These helpers do: 5 | #' `fields()` is equivalent to `names()`; `n_fields()` is equivalent to 6 | #' `length()`; `field()` is equivalent to `$`. 7 | #' 8 | #' @param x A [rcrd], i.e. a list of equal length vectors with unique names. 9 | #' @keywords internal 10 | #' @export 11 | #' @examples 12 | #' x <- new_rcrd(list(x = 1:3, y = 3:1, z = letters[1:3])) 13 | #' n_fields(x) 14 | #' fields(x) 15 | #' 16 | #' field(x, "y") 17 | #' field(x, "y") <- runif(3) 18 | #' field(x, "y") 19 | fields <- function(x) { 20 | .Call(vctrs_fields, x) 21 | } 22 | 23 | #' @export 24 | #' @rdname fields 25 | n_fields <- function(x) { 26 | .Call(vctrs_n_fields, x) 27 | } 28 | 29 | #' @export 30 | #' @rdname fields 31 | field <- function(x, i) { 32 | .Call(vctrs_field_get, x, i) 33 | } 34 | 35 | #' @export 36 | #' @rdname fields 37 | `field<-` <- function(x, i, value) { 38 | .Call(vctrs_field_set, x, i, value) 39 | } 40 | -------------------------------------------------------------------------------- /R/fill.R: -------------------------------------------------------------------------------- 1 | #' Fill in missing values with the previous or following value 2 | #' 3 | #' @description 4 | #' `r lifecycle::badge("experimental")` 5 | #' 6 | #' `vec_fill_missing()` fills gaps of missing values with the previous or 7 | #' following non-missing value. 8 | #' 9 | #' @param x A vector 10 | #' @param direction Direction in which to fill missing values. Must be either 11 | #' `"down"`, `"up"`, `"downup"`, or `"updown"`. 12 | #' @param max_fill A single positive integer specifying the maximum number of 13 | #' sequential missing values that will be filled. If `NULL`, there is 14 | #' no limit. 15 | #' 16 | #' @export 17 | #' @examples 18 | #' x <- c(NA, NA, 1, NA, NA, NA, 3, NA, NA) 19 | #' 20 | #' # Filling down replaces missing values with the previous non-missing value 21 | #' vec_fill_missing(x, direction = "down") 22 | #' 23 | #' # To also fill leading missing values, use `"downup"` 24 | #' vec_fill_missing(x, direction = "downup") 25 | #' 26 | #' # Limit the number of sequential missing values to fill with `max_fill` 27 | #' vec_fill_missing(x, max_fill = 1) 28 | #' 29 | #' # Data frames are filled rowwise. Rows are only considered missing 30 | #' # if all elements of that row are missing. 31 | #' y <- c(1, NA, 2, NA, NA, 3, 4, NA, 5) 32 | #' df <- data_frame(x = x, y = y) 33 | #' df 34 | #' 35 | #' vec_fill_missing(df) 36 | vec_fill_missing <- function(x, 37 | direction = c("down", "up", "downup", "updown"), 38 | max_fill = NULL) { 39 | .Call(vctrs_fill_missing, x, direction, max_fill) 40 | } 41 | -------------------------------------------------------------------------------- /R/hash.R: -------------------------------------------------------------------------------- 1 | 2 | # These return raw vectors of hashes. Vector elements are coded with 3 | # 32 bit hashes. Thus, the size of the raw vector of hashes is 4 times 4 | # the size of the input. 5 | 6 | vec_hash <- function(x) { 7 | .Call(vctrs_hash, x) 8 | } 9 | 10 | obj_hash <- function(x) { 11 | .Call(vctrs_hash_object, x) 12 | } 13 | -------------------------------------------------------------------------------- /R/split.R: -------------------------------------------------------------------------------- 1 | #' Split a vector into groups 2 | #' 3 | #' This is a generalisation of [split()] that can split by any type of vector, 4 | #' not just factors. Instead of returning the keys in the character names, 5 | #' the are returned in a separate parallel vector. 6 | #' 7 | #' @param x Vector to divide into groups. 8 | #' @param by Vector whose unique values defines the groups. 9 | #' @return A data frame with two columns and size equal to 10 | #' `vec_size(vec_unique(by))`. The `key` column has the same type as 11 | #' `by`, and the `val` column is a list containing elements of type 12 | #' `vec_ptype(x)`. 13 | #' 14 | #' Note for complex types, the default `data.frame` print method will be 15 | #' suboptimal, and you will want to coerce into a tibble to better 16 | #' understand the output. 17 | #' @export 18 | #' 19 | #' @section Dependencies: 20 | #' - [vec_group_loc()] 21 | #' - [vec_chop()] 22 | #' 23 | #' @examples 24 | #' vec_split(mtcars$cyl, mtcars$vs) 25 | #' vec_split(mtcars$cyl, mtcars[c("vs", "am")]) 26 | #' 27 | #' if (require("tibble")) { 28 | #' as_tibble(vec_split(mtcars$cyl, mtcars[c("vs", "am")])) 29 | #' as_tibble(vec_split(mtcars, mtcars[c("vs", "am")])) 30 | #' } 31 | vec_split <- function(x, by) { 32 | .Call(vctrs_split, x, by) 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /R/translate.R: -------------------------------------------------------------------------------- 1 | vec_normalize_encoding <- function(x) { 2 | .Call(vctrs_normalize_encoding, x) 3 | } 4 | -------------------------------------------------------------------------------- /R/type-data-table.R: -------------------------------------------------------------------------------- 1 | delayedAssign("as.data.table", { 2 | if (is_installed("data.table")) { 3 | env_get(ns_env("data.table"), "as.data.table") 4 | } else { 5 | function(...) abort("`data.table` must be installed.") 6 | } 7 | }) 8 | 9 | dt_ptype2 <- function(x, y, ...) { 10 | as.data.table(df_ptype2(x, y, ...)) 11 | } 12 | dt_cast <- function(x, to, ...) { 13 | as.data.table(df_cast(x, to, ...)) 14 | } 15 | 16 | #' @export 17 | vec_ptype2.data.table.data.table <- function(x, y, ...) { 18 | dt_ptype2(x, y, ...) 19 | } 20 | #' @export 21 | vec_ptype2.data.table.data.frame <- function(x, y, ...) { 22 | dt_ptype2(x, y, ...) 23 | } 24 | #' @export 25 | vec_ptype2.data.frame.data.table <- function(x, y, ...) { 26 | dt_ptype2(x, y, ...) 27 | } 28 | 29 | #' @export 30 | vec_cast.data.table.data.table <- function(x, to, ...) { 31 | dt_cast(x, to, ...) 32 | } 33 | #' @export 34 | vec_cast.data.table.data.frame <- function(x, to, ...) { 35 | dt_cast(x, to, ...) 36 | } 37 | #' @export 38 | vec_cast.data.frame.data.table <- function(x, to, ...) { 39 | df_cast(x, to, ...) 40 | } 41 | 42 | #' @export 43 | vec_ptype_abbr.data.table <- function(x, ...) { 44 | "dt" 45 | } 46 | -------------------------------------------------------------------------------- /R/type-explore.R: -------------------------------------------------------------------------------- 1 | coerces_to <- function(x, y, using = "strict") { 2 | type_max <- switch(using, 3 | strict = vec_ptype2, 4 | base_c = c, 5 | base_unlist = function(x, y) unlist(list(x, y)), 6 | base_modify = function(x, y) `[<-`(x, 2, value = y) 7 | ) 8 | 9 | tryCatch({ 10 | type <- suppressWarnings(type_max(x, y)) 11 | vec_ptype_full(type) 12 | }, error = function(e) { 13 | NA_character_ 14 | }) 15 | } 16 | 17 | maxtype_mat <- function(types, using = "strict") { 18 | names(types) <- map_chr(types, function(x) vec_ptype_full(vec_ptype(x))) 19 | 20 | grid <- expand.grid(x = types, y = types) 21 | grid$max <- map2_chr(grid$x, grid$y, coerces_to, using = using) 22 | 23 | matrix( 24 | grid$max, 25 | nrow = length(types), 26 | dimnames = list(names(types), names(types)) 27 | ) 28 | } 29 | -------------------------------------------------------------------------------- /R/type-tibble.R: -------------------------------------------------------------------------------- 1 | #' @rdname df_ptype2 2 | #' @export 3 | tib_ptype2 <- function(x, 4 | y, 5 | ..., 6 | x_arg = "", 7 | y_arg = "", 8 | call = caller_env()) { 9 | .Call( 10 | ffi_tib_ptype2, 11 | x = x, 12 | y = y, 13 | x_arg = x_arg, 14 | y_arg = y_arg, 15 | frame = environment() 16 | ) 17 | } 18 | #' @rdname df_ptype2 19 | #' @export 20 | tib_cast <- function(x, 21 | to, 22 | ..., 23 | x_arg = "", 24 | to_arg = "", 25 | call = caller_env()) { 26 | .Call( 27 | ffi_tib_cast, 28 | x = x, 29 | to = to, 30 | x_arg = x_arg, 31 | to_arg = to_arg, 32 | frame = environment() 33 | ) 34 | } 35 | 36 | df_as_tibble <- function(df) { 37 | class(df) <- c("tbl_df", "tbl", "data.frame") 38 | df 39 | } 40 | 41 | # Conditionally registered in .onLoad() 42 | 43 | vec_ptype2_tbl_df_tbl_df <- function(x, y, ...) { 44 | vec_ptype2_dispatch_native(x, y, ...) 45 | } 46 | vec_ptype2_tbl_df_data.frame <- function(x, y, ...) { 47 | vec_ptype2_dispatch_native(x, y, ...) 48 | } 49 | vec_ptype2_data.frame_tbl_df <- function(x, y, ...) { 50 | vec_ptype2_dispatch_native(x, y, ...) 51 | } 52 | 53 | vec_cast_tbl_df_tbl_df <- function(x, to, ...) { 54 | vec_cast_dispatch_native(x, to, ...) 55 | } 56 | vec_cast_data.frame_tbl_df <- function(x, to, ...) { 57 | vec_cast_dispatch_native(x, to, ...) 58 | } 59 | vec_cast_tbl_df_data.frame <- function(x, to, ...) { 60 | vec_cast_dispatch_native(x, to, ...) 61 | } 62 | -------------------------------------------------------------------------------- /R/type-unspecified.R: -------------------------------------------------------------------------------- 1 | #' A 1d vector of unspecified type 2 | #' 3 | #' This is a [partial type][new_partial] used to represent logical vectors 4 | #' that only contain `NA`. These require special handling because we want to 5 | #' allow `NA` to specify missingness without requiring a type. 6 | #' 7 | #' @keywords internal 8 | #' @param n Length of vector 9 | #' @export 10 | #' @examples 11 | #' vec_ptype_show() 12 | #' vec_ptype_show(NA) 13 | #' 14 | #' vec_c(NA, factor("x")) 15 | #' vec_c(NA, Sys.Date()) 16 | #' vec_c(NA, Sys.time()) 17 | #' vec_c(NA, list(1:3, 4:5)) 18 | unspecified <- function(n = 0) { 19 | .Call(vctrs_unspecified, n) 20 | } 21 | 22 | #' @export 23 | `[.vctrs_unspecified` <- function(x, i, ...) { 24 | unspecified(length(NextMethod())) 25 | } 26 | 27 | #' @export 28 | print.vctrs_unspecified <- function(x, ...) { 29 | cat(" [", length(x), "]\n", sep = "") 30 | } 31 | 32 | #' @export 33 | vec_ptype_abbr.vctrs_unspecified <- function(x, ...) { 34 | "???" 35 | } 36 | 37 | is_unspecified <- function(x) { 38 | .Call(vctrs_is_unspecified, x) 39 | } 40 | 41 | ununspecify <- function(x) { 42 | if (is_unspecified(x)) { 43 | new_logical(length(x)) 44 | } else { 45 | x 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /R/utils-cli.R: -------------------------------------------------------------------------------- 1 | 2 | parens <- function(x, left = TRUE) { 3 | x_lines <- strsplit(x, "\n") 4 | x_lines <- map(x_lines, paren, left = left) 5 | map_chr(x_lines, paste0, collapse = "\n") 6 | } 7 | 8 | paren <- function(x, left = TRUE) { 9 | if (length(x) <= 1) { 10 | if (left) { 11 | paste0("( ", x) 12 | } else { 13 | paste0(x, " )") 14 | } 15 | } else { 16 | if (left) { 17 | paste0(c("\u250c ", rep("\u2502 ", length(x) - 2), "\u2514 "), x) 18 | } else { 19 | paste0(format(x), c(" \u2510", rep(" \u2502", length(x) - 2), " \u2518")) 20 | } 21 | } 22 | } 23 | 24 | pad_height <- function(x) { 25 | pad <- function(x, n) c(x, rep("", n - length(x))) 26 | 27 | lines <- strsplit(x, "\n") 28 | height <- max(map_int(lines, length)) 29 | lines <- map(lines, pad, height) 30 | map_chr(lines, paste0, "\n", collapse = "") 31 | } 32 | 33 | pad_width <- function(x) { 34 | lines <- strsplit(x, "\n", fixed = TRUE) 35 | 36 | # fix up strsplit bug 37 | n <- map_int(lines, length) 38 | lines[n == 0] <- "" 39 | 40 | width <- max(unlist(map(lines, nchar))) 41 | lines <- map(lines, format, width = width) 42 | map_chr(lines, paste, collapse = "\n") 43 | } 44 | 45 | str_backtick <- function(x) { 46 | paste0("`", x, "`") 47 | } 48 | str_is_multiline <- function(x) { 49 | grepl("\n", x) 50 | } 51 | -------------------------------------------------------------------------------- /R/vctrs-package.R: -------------------------------------------------------------------------------- 1 | #' @description 2 | #' `r lifecycle::badge("maturing")` 3 | #' 4 | #' Defines new notions of prototype and size that are 5 | #' used to provide tools for consistent and well-founded type-coercion 6 | #' and size-recycling, and are in turn connected to ideas of type- and 7 | #' size-stability useful for analysing function interfaces. 8 | #' 9 | #' @keywords internal 10 | #' @import rlang 11 | #' @useDynLib vctrs, .registration = TRUE 12 | "_PACKAGE" 13 | 14 | release_extra_revdeps <- function() { 15 | # Extra revdeps to run before release. 16 | # Recognized by `usethis::use_release_issue()`. 17 | c("dplyr", "tidyr", "purrr") 18 | } 19 | -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-13-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-13-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-15-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-15-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-17-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-17-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-18-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-18-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-20-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-20-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-23-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-23-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-24-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-24-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-27-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-27-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-28-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-28-1.png -------------------------------------------------------------------------------- /bench/order_files/figure-gfm/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/order_files/figure-gfm/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /bench/rbind.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Row-binding" 3 | output: github_document 4 | --- 5 | 6 | ```{r, include = FALSE} 7 | knitr::opts_chunk$set(collapse = TRUE, comment = "#> ") 8 | ``` 9 | 10 | ```{r setup, message = FALSE} 11 | library(tidyverse) 12 | library(vctrs) 13 | 14 | df <- data.frame(x = 1:10, y = letters[1:10], stringsAsFactors = FALSE) 15 | dfs <- map(1:100, ~ df) 16 | ``` 17 | 18 | Currently, `vec_rbind()` is _much_ slower than the alternatives: 19 | 20 | ```{r} 21 | bench::mark( 22 | do.call(rbind, dfs), 23 | vec_rbind(!!!dfs), 24 | dplyr::bind_rows(dfs) 25 | ) 26 | ``` 27 | 28 | I've removed the biggest bottlenecks coercing data frames to lists with `vec_data()`, operating on them, and then restoring with `vec_restore()`. This avoids the expensive data frame methods. I think further improvement (to get on par with base/dplyr) will require a systematic rewrite in C. 29 | 30 | ```{r, eval = FALSE} 31 | profvis::profvis(vec_rbind(!!!dfs)) 32 | ``` 33 | -------------------------------------------------------------------------------- /bench/rbind.md: -------------------------------------------------------------------------------- 1 | Row-binding 2 | ================ 3 | 4 | ``` r 5 | library(tidyverse) 6 | library(vctrs) 7 | 8 | df <- data.frame(x = 1:10, y = letters[1:10], stringsAsFactors = FALSE) 9 | dfs <- map(1:100, ~ df) 10 | ``` 11 | 12 | Currently, `vec_rbind()` is *much* slower than the alternatives: 13 | 14 | ``` r 15 | bench::mark( 16 | do.call(rbind, dfs), 17 | vec_rbind(!!!dfs), 18 | dplyr::bind_rows(dfs) 19 | ) 20 | #> Warning: Some expressions had a GC in every iteration; so filtering is 21 | #> disabled. 22 | #> # A tibble: 3 x 10 23 | #> expression min mean median max `itr/sec` mem_alloc n_gc 24 | #> 25 | #> 1 do.call(r… 3.01ms 4.19ms 3.4ms 32.52ms 239. 200.7KB 16 26 | #> 2 vec_rbind… 42.18ms 46.06ms 46.2ms 49.17ms 21.7 566.9KB 19 27 | #> 3 dplyr::bi… 97.02µs 130.19µs 109.3µs 4.51ms 7681. 43.1KB 16 28 | #> # … with 2 more variables: n_itr , total_time 29 | ``` 30 | 31 | I’ve removed the biggest bottlenecks coercing data frames to lists with 32 | `vec_data()`, operating on them, and then restoring with `vec_recast()`. 33 | This avoids the expensive data frame methods. I think further 34 | improvement (to get on par with base/dplyr) will require a systematic 35 | rewrite in C. 36 | 37 | ``` r 38 | profvis::profvis(vec_rbind(!!!dfs)) 39 | ``` 40 | -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-10-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-10-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-11-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-11-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-12-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-12-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-14-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-14-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-16-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-16-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-9-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/sorting-vs-hashing_files/figure-gfm/unnamed-chunk-9-1.png -------------------------------------------------------------------------------- /bench/unique_files/figure-gfm/unnamed-chunk-3-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/unique_files/figure-gfm/unnamed-chunk-3-1.png -------------------------------------------------------------------------------- /bench/unique_files/figure-gfm/unnamed-chunk-5-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/unique_files/figure-gfm/unnamed-chunk-5-1.png -------------------------------------------------------------------------------- /bench/unique_files/figure-gfm/unnamed-chunk-6-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/unique_files/figure-gfm/unnamed-chunk-6-1.png -------------------------------------------------------------------------------- /bench/unique_files/figure-gfm/unnamed-chunk-7-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/unique_files/figure-gfm/unnamed-chunk-7-1.png -------------------------------------------------------------------------------- /bench/unique_files/figure-gfm/unnamed-chunk-8-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/bench/unique_files/figure-gfm/unnamed-chunk-8-1.png -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | This is a patch release with no expected breakage of any reverse dependencies. 2 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | vectorised 2 | -------------------------------------------------------------------------------- /inst/include/vctrs.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | 3 | // Maturing 4 | bool (*obj_is_vector)(SEXP) = NULL; 5 | R_len_t (*short_vec_size)(SEXP) = NULL; 6 | SEXP (*short_vec_recycle)(SEXP, R_len_t) = NULL; 7 | 8 | // Deprecated 9 | bool (*vec_is_vector)(SEXP) = NULL; 10 | 11 | void vctrs_init_api(void) { 12 | obj_is_vector = (bool (*)(SEXP)) R_GetCCallable("vctrs", "obj_is_vector"); 13 | short_vec_size = (R_len_t (*)(SEXP)) R_GetCCallable("vctrs", "short_vec_size"); 14 | short_vec_recycle = (SEXP (*)(SEXP, R_len_t)) R_GetCCallable("vctrs", "short_vec_recycle"); 15 | 16 | vec_is_vector = (bool (*)(SEXP)) R_GetCCallable("vctrs", "vec_is_vector"); 17 | } 18 | -------------------------------------------------------------------------------- /inst/include/vctrs.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_H 2 | #define VCTRS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | // Maturing 9 | extern bool (*obj_is_vector)(SEXP); 10 | extern R_len_t (*short_vec_size)(SEXP); 11 | extern SEXP (*short_vec_recycle)(SEXP, R_len_t); 12 | 13 | // Deprecated in favor of `obj_is_vector()` 14 | // version: 0.5.3 15 | // date: 2023-02-15 16 | extern bool (*vec_is_vector)(SEXP); 17 | 18 | void vctrs_init_api(void); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /man/as-is.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-asis.R 3 | \name{as-is} 4 | \alias{as-is} 5 | \alias{vec_ptype2.AsIs} 6 | \title{AsIs S3 class} 7 | \usage{ 8 | \method{vec_ptype2}{AsIs}(x, y, ..., x_arg = "", y_arg = "") 9 | } 10 | \description{ 11 | These functions help the base AsIs class fit into the vctrs type system 12 | by providing coercion and casting functions. 13 | } 14 | \keyword{internal} 15 | -------------------------------------------------------------------------------- /man/faq-error-incompatible-attributes.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/faq.R 3 | \name{faq-error-incompatible-attributes} 4 | \alias{faq-error-incompatible-attributes} 5 | \title{FAQ - Error/Warning: Some attributes are incompatible} 6 | \description{ 7 | This error occurs when \code{\link[=vec_ptype2]{vec_ptype2()}} or \code{\link[=vec_cast]{vec_cast()}} are supplied 8 | vectors of the same classes with different attributes. In this 9 | case, vctrs doesn't know how to combine the inputs. 10 | 11 | To fix this error, the maintainer of the class should implement 12 | self-to-self coercion methods for \code{\link[=vec_ptype2]{vec_ptype2()}} and \code{\link[=vec_cast]{vec_cast()}}. 13 | } 14 | \section{Implementing coercion methods}{ 15 | \itemize{ 16 | \item For an overview of how these generics work and their roles in vctrs, 17 | see \code{\link[=theory-faq-coercion]{?theory-faq-coercion}}. 18 | \item For an example of implementing coercion methods for simple vectors, 19 | see \code{\link[=howto-faq-coercion]{?howto-faq-coercion}}. 20 | \item For an example of implementing coercion methods for data frame 21 | subclasses, see 22 | \code{\link[=howto-faq-coercion-data-frame]{?howto-faq-coercion-data-frame}}. 23 | \item For a tutorial about implementing vctrs classes from scratch, see 24 | \code{vignette("s3-vector")}. 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /man/faq/developer/links-coercion.Rmd: -------------------------------------------------------------------------------- 1 | 2 | # Implementing coercion methods 3 | 4 | - For an overview of how these generics work and their roles in vctrs, see [`?theory-faq-coercion`][theory-faq-coercion]. 5 | 6 | - For an example of implementing coercion methods for simple vectors, see [`?howto-faq-coercion`][howto-faq-coercion]. 7 | 8 | - For an example of implementing coercion methods for data frame subclasses, see [`?howto-faq-coercion-data-frame`][howto-faq-coercion-data-frame]. 9 | 10 | - For a tutorial about implementing vctrs classes from scratch, see `vignette("s3-vector")`. 11 | -------------------------------------------------------------------------------- /man/faq/developer/snippet-roxy-workflow.Rmd: -------------------------------------------------------------------------------- 1 | 2 | To implement methods for generics, first import the generics in your namespace and redocument: 3 | 4 | ```{r, eval = FALSE} 5 | #' @importFrom vctrs vec_ptype2 vec_cast 6 | NULL 7 | ``` 8 | 9 | Note that for each batches of methods that you add to your package, you need to export the methods and redocument immediately, even during development. Otherwise they won't be in scope when you run unit tests e.g. with testthat. 10 | 11 | Implementing double dispatch methods is very similar to implementing regular S3 methods. In these examples we are using roxygen2 tags to register the methods, but you can also register the methods manually in your NAMESPACE file or lazily with `s3_register()`. 12 | -------------------------------------------------------------------------------- /man/faq/setup.Rmd: -------------------------------------------------------------------------------- 1 | 2 | ```{r, include = FALSE} 3 | knitr::opts_chunk$set( 4 | collapse = TRUE, 5 | comment = "#>" 6 | ) 7 | 8 | options( 9 | cli.unicode = FALSE, 10 | rlang_call_format_srcrefs = FALSE 11 | ) 12 | 13 | library(vctrs) 14 | ``` 15 | -------------------------------------------------------------------------------- /man/fields.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/fields.R 3 | \name{fields} 4 | \alias{fields} 5 | \alias{n_fields} 6 | \alias{field} 7 | \alias{field<-} 8 | \title{Tools for accessing the fields of a record.} 9 | \usage{ 10 | fields(x) 11 | 12 | n_fields(x) 13 | 14 | field(x, i) 15 | 16 | field(x, i) <- value 17 | } 18 | \arguments{ 19 | \item{x}{A \link{rcrd}, i.e. a list of equal length vectors with unique names.} 20 | } 21 | \description{ 22 | A \link{rcrd} behaves like a vector, so \code{length()}, \code{names()}, and \code{$} can 23 | not provide access to the fields of the underlying list. These helpers do: 24 | \code{fields()} is equivalent to \code{names()}; \code{n_fields()} is equivalent to 25 | \code{length()}; \code{field()} is equivalent to \code{$}. 26 | } 27 | \examples{ 28 | x <- new_rcrd(list(x = 1:3, y = 3:1, z = letters[1:3])) 29 | n_fields(x) 30 | fields(x) 31 | 32 | field(x, "y") 33 | field(x, "y") <- runif(3) 34 | field(x, "y") 35 | } 36 | \keyword{internal} 37 | -------------------------------------------------------------------------------- /man/figures/cast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/cast.png -------------------------------------------------------------------------------- /man/figures/coerce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/coerce.png -------------------------------------------------------------------------------- /man/figures/combined.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/combined.png -------------------------------------------------------------------------------- /man/figures/lifecycle-archived.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclearchivedarchived -------------------------------------------------------------------------------- /man/figures/lifecycle-defunct.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycledefunctdefunct -------------------------------------------------------------------------------- /man/figures/lifecycle-deprecated.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycledeprecateddeprecated -------------------------------------------------------------------------------- /man/figures/lifecycle-experimental.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycleexperimentalexperimental -------------------------------------------------------------------------------- /man/figures/lifecycle-maturing.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclematuringmaturing -------------------------------------------------------------------------------- /man/figures/lifecycle-questioning.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclequestioningquestioning -------------------------------------------------------------------------------- /man/figures/lifecycle-soft-deprecated.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclesoft-deprecatedsoft-deprecated -------------------------------------------------------------------------------- /man/figures/lifecycle-stable.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclestablestable -------------------------------------------------------------------------------- /man/figures/lifecycle-superseded.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclesupersededsuperseded -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/logo.png -------------------------------------------------------------------------------- /man/figures/sizes-recycling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/sizes-recycling.png -------------------------------------------------------------------------------- /man/figures/sizes.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/sizes.graffle -------------------------------------------------------------------------------- /man/figures/types.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/types.graffle -------------------------------------------------------------------------------- /man/figures/vec-count-deps.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/vec-count-deps.graffle -------------------------------------------------------------------------------- /man/figures/vec-count-deps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/man/figures/vec-count-deps.png -------------------------------------------------------------------------------- /man/int64.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-integer64.R 3 | \name{vec_ptype_full.integer64} 4 | \alias{vec_ptype_full.integer64} 5 | \alias{vec_ptype_abbr.integer64} 6 | \alias{vec_ptype2.integer64} 7 | \alias{vec_cast.integer64} 8 | \title{64 bit integers} 9 | \usage{ 10 | \method{vec_ptype_full}{integer64}(x, ...) 11 | 12 | \method{vec_ptype_abbr}{integer64}(x, ...) 13 | 14 | \method{vec_ptype2}{integer64}(x, y, ...) 15 | 16 | \method{vec_cast}{integer64}(x, to, ...) 17 | } 18 | \description{ 19 | A \code{integer64} is a 64 bits integer vector, implemented in the \code{bit64} package. 20 | } 21 | \details{ 22 | These functions help the \code{integer64} class from \code{bit64} in to 23 | the vctrs type system by providing coercion functions 24 | and casting functions. 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /man/list_drop_empty.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/empty.R 3 | \name{list_drop_empty} 4 | \alias{list_drop_empty} 5 | \title{Drop empty elements from a list} 6 | \usage{ 7 | list_drop_empty(x) 8 | } 9 | \arguments{ 10 | \item{x}{A list.} 11 | } 12 | \description{ 13 | \code{list_drop_empty()} removes empty elements from a list. This includes \code{NULL} 14 | elements along with empty vectors, like \code{integer(0)}. This is equivalent to, 15 | but faster than, \code{vec_slice(x, list_sizes(x) != 0L)}. 16 | } 17 | \section{Dependencies}{ 18 | 19 | \itemize{ 20 | \item \code{\link[=vec_slice]{vec_slice()}} 21 | } 22 | } 23 | 24 | \examples{ 25 | x <- list(1, NULL, integer(), 2) 26 | list_drop_empty(x) 27 | } 28 | -------------------------------------------------------------------------------- /man/new_data_frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-data-frame.R 3 | \name{new_data_frame} 4 | \alias{new_data_frame} 5 | \title{Assemble attributes for data frame construction} 6 | \usage{ 7 | new_data_frame(x = list(), n = NULL, ..., class = NULL) 8 | } 9 | \arguments{ 10 | \item{x}{A named list of equal-length vectors. The lengths are not 11 | checked; it is responsibility of the caller to make sure they are 12 | equal.} 13 | 14 | \item{n}{Number of rows. If \code{NULL}, will be computed from the length of 15 | the first element of \code{x}.} 16 | 17 | \item{..., class}{Additional arguments for creating subclasses. 18 | 19 | The following attributes have special behavior: 20 | \itemize{ 21 | \item \code{"names"} is preferred if provided, overriding existing names in \code{x}. 22 | \item \code{"row.names"} is preferred if provided, overriding both \code{n} and the size 23 | implied by \code{x}. 24 | }} 25 | } 26 | \description{ 27 | \code{new_data_frame()} constructs a new data frame from an existing list. It is 28 | meant to be performant, and does not check the inputs for correctness in any 29 | way. It is only safe to use after a call to \code{\link[=df_list]{df_list()}}, which collects and 30 | validates the columns used to construct the data frame. 31 | } 32 | \examples{ 33 | new_data_frame(list(x = 1:10, y = 10:1)) 34 | } 35 | \seealso{ 36 | \code{\link[=df_list]{df_list()}} for a way to safely construct a data frame's underlying 37 | data structure from individual columns. This can be used to create a 38 | named list for further use by \code{new_data_frame()}. 39 | } 40 | -------------------------------------------------------------------------------- /man/new_factor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-factor.R 3 | \name{new_factor} 4 | \alias{new_factor} 5 | \alias{new_ordered} 6 | \alias{vec_ptype2.factor} 7 | \alias{vec_ptype2.ordered} 8 | \alias{vec_cast.factor} 9 | \alias{vec_cast.ordered} 10 | \title{Factor/ordered factor S3 class} 11 | \usage{ 12 | new_factor(x = integer(), levels = character(), ..., class = character()) 13 | 14 | new_ordered(x = integer(), levels = character()) 15 | 16 | \method{vec_ptype2}{factor}(x, y, ...) 17 | 18 | \method{vec_ptype2}{ordered}(x, y, ...) 19 | 20 | \method{vec_cast}{factor}(x, to, ...) 21 | 22 | \method{vec_cast}{ordered}(x, to, ...) 23 | } 24 | \arguments{ 25 | \item{x}{Integer values which index in to \code{levels}.} 26 | 27 | \item{levels}{Character vector of labels.} 28 | 29 | \item{..., class}{Used to for subclasses.} 30 | } 31 | \description{ 32 | A \link{factor} is an integer with attribute \code{levels}, a character vector. There 33 | should be one level for each integer between 1 and \code{max(x)}. 34 | An \link{ordered} factor has the same properties as a factor, but possesses 35 | an extra class that marks levels as having a total ordering. 36 | } 37 | \details{ 38 | These functions help the base factor and ordered factor classes fit in to 39 | the vctrs type system by providing constructors, coercion functions, 40 | and casting functions. \code{new_factor()} and \code{new_ordered()} are low-level 41 | constructors - they only check that types, but not values, are valid, so 42 | are for expert use only. 43 | } 44 | \keyword{internal} 45 | -------------------------------------------------------------------------------- /man/new_list_of.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-list-of.R 3 | \name{new_list_of} 4 | \alias{new_list_of} 5 | \title{Create list_of subclass} 6 | \usage{ 7 | new_list_of(x = list(), ptype = logical(), ..., class = character()) 8 | } 9 | \arguments{ 10 | \item{x}{A list} 11 | 12 | \item{ptype}{The prototype which every element of \code{x} belongs to} 13 | 14 | \item{...}{Additional attributes used by subclass} 15 | 16 | \item{class}{Optional subclass name} 17 | } 18 | \description{ 19 | Create list_of subclass 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/new_partial.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/partial.R 3 | \name{new_partial} 4 | \alias{new_partial} 5 | \alias{is_partial} 6 | \alias{vec_ptype_finalise} 7 | \title{Partial type} 8 | \usage{ 9 | new_partial(..., class = character()) 10 | 11 | is_partial(x) 12 | 13 | vec_ptype_finalise(x, ...) 14 | } 15 | \arguments{ 16 | \item{...}{Attributes of the partial type} 17 | 18 | \item{class}{Name of subclass.} 19 | } 20 | \description{ 21 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} 22 | 23 | Use \code{new_partial()} when constructing a new partial type subclass; 24 | and use \code{is_partial()} to test if a type is partial. All subclasses 25 | need to provide a \code{vec_ptype_finalise()} method. 26 | } 27 | \details{ 28 | As the name suggests, a partial type \emph{partially} specifies a type, and 29 | it must be combined with data to yield a full type. A useful example 30 | of a partial type is \code{\link[=partial_frame]{partial_frame()}}, which makes it possible to 31 | specify the type of just a few columns in a data frame. Use this constructor 32 | if you're making your own partial type. 33 | } 34 | \keyword{internal} 35 | -------------------------------------------------------------------------------- /man/new_rcrd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-rcrd.R 3 | \name{new_rcrd} 4 | \alias{new_rcrd} 5 | \alias{ses} 6 | \alias{rcrd} 7 | \title{rcrd (record) S3 class} 8 | \usage{ 9 | new_rcrd(fields, ..., class = character()) 10 | } 11 | \arguments{ 12 | \item{fields}{A list or a data frame. Lists must be rectangular 13 | (same sizes), and contain uniquely named vectors (at least 14 | one). \code{fields} is validated with \code{\link[=df_list]{df_list()}} to ensure uniquely 15 | named vectors.} 16 | 17 | \item{...}{Additional attributes} 18 | 19 | \item{class}{Name of subclass.} 20 | } 21 | \description{ 22 | The rcrd class extends \link{vctr}. A rcrd is composed of 1 or more \link{field}s, 23 | which must be vectors of the same length. Is designed specifically for 24 | classes that can naturally be decomposed into multiple vectors of the same 25 | length, like \link{POSIXlt}, but where the organisation should be considered 26 | an implementation detail invisible to the user (unlike a \link{data.frame}). 27 | } 28 | \details{ 29 | Record-style objects created with \code{\link[=new_rcrd]{new_rcrd()}} do not do much on their own. 30 | For instance they do not have a default \code{\link[=format]{format()}} method, which means printing 31 | the object causes an error. See \link{Record-style objects}(https://vctrs.r-lib.org/articles/s3-vector.html?q=record#record-style-objects 32 | for details on implementing methods for record vectors. 33 | } 34 | \keyword{internal} 35 | -------------------------------------------------------------------------------- /man/obj_print.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/print-str.R 3 | \name{obj_print} 4 | \alias{obj_print} 5 | \alias{obj_print_header} 6 | \alias{obj_print_data} 7 | \alias{obj_print_footer} 8 | \alias{obj_str} 9 | \alias{obj_str_header} 10 | \alias{obj_str_data} 11 | \alias{obj_str_footer} 12 | \title{\code{print()} and \code{str()} generics.} 13 | \usage{ 14 | obj_print(x, ...) 15 | 16 | obj_print_header(x, ...) 17 | 18 | obj_print_data(x, ...) 19 | 20 | obj_print_footer(x, ...) 21 | 22 | obj_str(x, ...) 23 | 24 | obj_str_header(x, ...) 25 | 26 | obj_str_data(x, ...) 27 | 28 | obj_str_footer(x, ...) 29 | } 30 | \arguments{ 31 | \item{x}{A vector} 32 | 33 | \item{...}{Additional arguments passed on to methods. See \code{\link[=print]{print()}} and 34 | \code{\link[=str]{str()}} for commonly used options} 35 | } 36 | \description{ 37 | These are constructed to be more easily extensible since you can override 38 | the \verb{_header()}, \verb{_data()} or \verb{_footer()} components individually. The 39 | default methods are built on top of \code{format()}. 40 | } 41 | \keyword{internal} 42 | -------------------------------------------------------------------------------- /man/op-empty-default.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/size.R 3 | \name{\%0\%} 4 | \alias{\%0\%} 5 | \title{Default value for empty vectors} 6 | \usage{ 7 | x \%0\% y 8 | } 9 | \arguments{ 10 | \item{x}{A vector} 11 | 12 | \item{y}{Value to use if \code{x} is empty. To preserve type-stability, should 13 | be the same type as \code{x}.} 14 | } 15 | \description{ 16 | Use this inline operator when you need to provide a default value for 17 | empty (as defined by \code{\link[=vec_is_empty]{vec_is_empty()}}) vectors. 18 | } 19 | \examples{ 20 | 1:10 \%0\% 5 21 | integer() \%0\% 5 22 | } 23 | -------------------------------------------------------------------------------- /man/partial_factor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/partial-factor.R 3 | \name{partial_factor} 4 | \alias{partial_factor} 5 | \title{Partially specify a factor} 6 | \usage{ 7 | partial_factor(levels = character()) 8 | } 9 | \arguments{ 10 | \item{levels}{Character vector of labels.} 11 | } 12 | \description{ 13 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} 14 | 15 | This special class can be passed as a \code{ptype} in order to specify that the 16 | result should be a factor that contains at least the specified levels. 17 | } 18 | \examples{ 19 | pf <- partial_factor(levels = c("x", "y")) 20 | pf 21 | 22 | vec_ptype_common(factor("v"), factor("w"), .ptype = pf) 23 | 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /man/partial_frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/partial-frame.R 3 | \name{partial_frame} 4 | \alias{partial_frame} 5 | \title{Partially specify columns of a data frame} 6 | \usage{ 7 | partial_frame(...) 8 | } 9 | \arguments{ 10 | \item{...}{Attributes of subclass} 11 | } 12 | \description{ 13 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} 14 | 15 | This special class can be passed to \code{.ptype} in order to specify the 16 | types of only some of the columns in a data frame. 17 | } 18 | \examples{ 19 | pf <- partial_frame(x = double()) 20 | pf 21 | 22 | vec_rbind( 23 | data.frame(x = 1L, y = "a"), 24 | data.frame(x = FALSE, z = 10), 25 | .ptype = partial_frame(x = double(), a = character()) 26 | ) 27 | } 28 | \keyword{internal} 29 | -------------------------------------------------------------------------------- /man/table.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-table.R 3 | \name{table} 4 | \alias{table} 5 | \title{Table S3 class} 6 | \description{ 7 | These functions help the base table class fit into the vctrs type system 8 | by providing coercion and casting functions. 9 | } 10 | \keyword{internal} 11 | -------------------------------------------------------------------------------- /man/unspecified.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-unspecified.R 3 | \name{unspecified} 4 | \alias{unspecified} 5 | \title{A 1d vector of unspecified type} 6 | \usage{ 7 | unspecified(n = 0) 8 | } 9 | \arguments{ 10 | \item{n}{Length of vector} 11 | } 12 | \description{ 13 | This is a \link[=new_partial]{partial type} used to represent logical vectors 14 | that only contain \code{NA}. These require special handling because we want to 15 | allow \code{NA} to specify missingness without requiring a type. 16 | } 17 | \examples{ 18 | vec_ptype_show() 19 | vec_ptype_show(NA) 20 | 21 | vec_c(NA, factor("x")) 22 | vec_c(NA, Sys.Date()) 23 | vec_c(NA, Sys.time()) 24 | vec_c(NA, list(1:3, 4:5)) 25 | } 26 | \keyword{internal} 27 | -------------------------------------------------------------------------------- /man/vctrs-data-frame.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/type-data-frame.R 3 | \name{vctrs-data-frame} 4 | \alias{vctrs-data-frame} 5 | \alias{vec_ptype2.data.frame} 6 | \alias{vec_cast.data.frame} 7 | \title{vctrs methods for data frames} 8 | \usage{ 9 | \method{vec_ptype2}{data.frame}(x, y, ...) 10 | 11 | \method{vec_cast}{data.frame}(x, to, ...) 12 | } 13 | \description{ 14 | These functions help the base data.frame class fit into the vctrs type system 15 | by providing coercion and casting functions. 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/vctrs-package.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-package.R 3 | \docType{package} 4 | \name{vctrs-package} 5 | \alias{vctrs} 6 | \alias{vctrs-package} 7 | \title{vctrs: Vector Helpers} 8 | \description{ 9 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#maturing}{\figure{lifecycle-maturing.svg}{options: alt='[Maturing]'}}}{\strong{[Maturing]}} 10 | 11 | Defines new notions of prototype and size that are 12 | used to provide tools for consistent and well-founded type-coercion 13 | and size-recycling, and are in turn connected to ideas of type- and 14 | size-stability useful for analysing function interfaces. 15 | } 16 | \seealso{ 17 | Useful links: 18 | \itemize{ 19 | \item \url{https://vctrs.r-lib.org/} 20 | \item \url{https://github.com/r-lib/vctrs} 21 | \item Report bugs at \url{https://github.com/r-lib/vctrs/issues} 22 | } 23 | 24 | } 25 | \author{ 26 | \strong{Maintainer}: Davis Vaughan \email{davis@posit.co} 27 | 28 | Authors: 29 | \itemize{ 30 | \item Hadley Wickham \email{hadley@posit.co} 31 | \item Lionel Henry \email{lionel@posit.co} 32 | } 33 | 34 | Other contributors: 35 | \itemize{ 36 | \item data.table team (Radix sort based on data.table's forder() and their contribution to R's order()) [copyright holder] 37 | \item Posit Software, PBC [copyright holder, funder] 38 | } 39 | 40 | } 41 | \keyword{internal} 42 | -------------------------------------------------------------------------------- /man/vec_as_index.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-deprecated.R 3 | \name{vec_as_index} 4 | \alias{vec_as_index} 5 | \title{Convert to an index vector} 6 | \usage{ 7 | vec_as_index(i, n, names = NULL) 8 | } 9 | \arguments{ 10 | \item{i}{An integer, character or logical vector specifying the 11 | locations or names of the observations to get/set. Specify 12 | \code{TRUE} to index all elements (as in \code{x[]}), or \code{NULL}, \code{FALSE} or 13 | \code{integer()} to index none (as in \code{x[NULL]}).} 14 | 15 | \item{n}{A single integer representing the total size of the 16 | object that \code{i} is meant to index into.} 17 | 18 | \item{names}{If \code{i} is a character vector, \code{names} should be a character 19 | vector that \code{i} will be matched against to construct the index. Otherwise, 20 | not used. The default value of \code{NULL} will result in an error 21 | if \code{i} is a character vector.} 22 | } 23 | \description{ 24 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 25 | 26 | \code{vec_as_index()} has been renamed to \code{\link[=vec_as_location]{vec_as_location()}} and is 27 | deprecated as of vctrs 0.2.2. 28 | } 29 | \keyword{internal} 30 | -------------------------------------------------------------------------------- /man/vec_as_names_legacy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/names.R 3 | \name{vec_as_names_legacy} 4 | \alias{vec_as_names_legacy} 5 | \title{Repair names with legacy method} 6 | \usage{ 7 | vec_as_names_legacy(names, prefix = "V", sep = "") 8 | } 9 | \arguments{ 10 | \item{names}{A character vector.} 11 | 12 | \item{prefix, sep}{Prefix and separator for repaired names.} 13 | } 14 | \description{ 15 | This standardises names with the legacy approach that was used in 16 | tidyverse packages (such as tibble, tidyr, and readxl) before 17 | \code{\link[=vec_as_names]{vec_as_names()}} was implemented. This tool is meant to help 18 | transitioning to the new name repairing standard and will be 19 | deprecated and removed from the package some time in the future. 20 | } 21 | \examples{ 22 | if (rlang::is_installed("tibble")) { 23 | 24 | library(tibble) 25 | 26 | # Names repair is turned off by default in tibble: 27 | try(tibble(a = 1, a = 2)) 28 | 29 | # You can turn it on by supplying a repair method: 30 | tibble(a = 1, a = 2, .name_repair = "universal") 31 | 32 | # If you prefer the legacy method, use `vec_as_names_legacy()`: 33 | tibble(a = 1, a = 2, .name_repair = vec_as_names_legacy) 34 | 35 | } 36 | } 37 | \keyword{internal} 38 | -------------------------------------------------------------------------------- /man/vec_cbind_frame_ptype.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/bind.R 3 | \name{vec_cbind_frame_ptype} 4 | \alias{vec_cbind_frame_ptype} 5 | \title{Frame prototype} 6 | \usage{ 7 | vec_cbind_frame_ptype(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{A data frame.} 11 | 12 | \item{...}{These dots are for future extensions and must be empty.} 13 | } 14 | \description{ 15 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} 16 | 17 | This is an experimental generic that returns zero-columns variants 18 | of a data frame. It is needed for \code{\link[=vec_cbind]{vec_cbind()}}, to work around the 19 | lack of colwise primitives in vctrs. Expect changes. 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/vec_compare.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/compare.R 3 | \name{vec_compare} 4 | \alias{vec_compare} 5 | \title{Compare two vectors} 6 | \usage{ 7 | vec_compare(x, y, na_equal = FALSE, .ptype = NULL) 8 | } 9 | \arguments{ 10 | \item{x, y}{Vectors with compatible types and lengths.} 11 | 12 | \item{na_equal}{Should \code{NA} values be considered equal?} 13 | 14 | \item{.ptype}{Override to optionally specify common type} 15 | } 16 | \value{ 17 | An integer vector with values -1 for \code{x < y}, 0 if \code{x == y}, 18 | and 1 if \code{x > y}. If \code{na_equal} is \code{FALSE}, the result will be \code{NA} 19 | if either \code{x} or \code{y} is \code{NA}. 20 | } 21 | \description{ 22 | Compare two vectors 23 | } 24 | \section{S3 dispatch}{ 25 | 26 | \code{vec_compare()} is not generic for performance; instead it uses 27 | \code{\link[=vec_proxy_compare]{vec_proxy_compare()}} to create a proxy that is used in the comparison. 28 | } 29 | 30 | \section{Dependencies}{ 31 | 32 | \itemize{ 33 | \item \code{\link[=vec_cast_common]{vec_cast_common()}} with fallback 34 | \item \code{\link[=vec_recycle_common]{vec_recycle_common()}} 35 | \item \code{\link[=vec_proxy_compare]{vec_proxy_compare()}} 36 | } 37 | } 38 | 39 | \examples{ 40 | vec_compare(c(TRUE, FALSE, NA), FALSE) 41 | vec_compare(c(TRUE, FALSE, NA), FALSE, na_equal = TRUE) 42 | 43 | vec_compare(1:10, 5) 44 | vec_compare(runif(10), 0.5) 45 | vec_compare(letters[1:10], "d") 46 | 47 | df <- data.frame(x = c(1, 1, 1, 2), y = c(0, 1, 2, 1)) 48 | vec_compare(df, data.frame(x = 1, y = 1)) 49 | } 50 | -------------------------------------------------------------------------------- /man/vec_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/proxy.R 3 | \name{vec_data} 4 | \alias{vec_data} 5 | \title{Extract underlying data} 6 | \usage{ 7 | vec_data(x) 8 | } 9 | \arguments{ 10 | \item{x}{A vector or object implementing \code{vec_proxy()}.} 11 | } 12 | \value{ 13 | The data underlying \code{x}, free from any attributes except the names. 14 | } 15 | \description{ 16 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} 17 | 18 | Extract the data underlying an S3 vector object, i.e. the underlying 19 | (named) atomic vector, data frame, or list. 20 | } 21 | \section{Difference with \code{vec_proxy()}}{ 22 | 23 | \itemize{ 24 | \item \code{vec_data()} returns unstructured data. The only attributes 25 | preserved are names, dims, and dimnames. 26 | 27 | Currently, due to the underlying memory architecture of R, this 28 | creates a full copy of the data for atomic vectors. 29 | \item \code{vec_proxy()} may return structured data. This generic is the 30 | main customisation point for accessing memory values in vctrs, 31 | along with \code{\link[=vec_restore]{vec_restore()}}. 32 | 33 | Methods must return a vector type. Records and data frames will 34 | be processed rowwise. 35 | } 36 | } 37 | 38 | \keyword{internal} 39 | -------------------------------------------------------------------------------- /man/vec_detect_complete.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/complete.R 3 | \name{vec_detect_complete} 4 | \alias{vec_detect_complete} 5 | \title{Complete} 6 | \usage{ 7 | vec_detect_complete(x) 8 | } 9 | \arguments{ 10 | \item{x}{A vector} 11 | } 12 | \value{ 13 | A logical vector with the same size as \code{x}. 14 | } 15 | \description{ 16 | \code{vec_detect_complete()} detects "complete" observations. An observation is 17 | considered complete if it is non-missing. For most vectors, this implies that 18 | \code{vec_detect_complete(x) == !vec_detect_missing(x)}. 19 | 20 | For data frames and matrices, a row is only considered complete if all 21 | elements of that row are non-missing. To compare, \code{!vec_detect_missing(x)} 22 | detects rows that are partially complete (they have at least one non-missing 23 | value). 24 | } 25 | \details{ 26 | A \link[=new_rcrd]{record} type vector is similar to a data frame, and is only 27 | considered complete if all fields are non-missing. 28 | } 29 | \examples{ 30 | x <- c(1, 2, NA, 4, NA) 31 | 32 | # For most vectors, this is identical to `!vec_detect_missing(x)` 33 | vec_detect_complete(x) 34 | !vec_detect_missing(x) 35 | 36 | df <- data_frame( 37 | x = x, 38 | y = c("a", "b", NA, "d", "e") 39 | ) 40 | 41 | # This returns `TRUE` where all elements of the row are non-missing. 42 | # Compare that with `!vec_detect_missing()`, which detects rows that have at 43 | # least one non-missing value. 44 | df2 <- df 45 | df2$all_non_missing <- vec_detect_complete(df) 46 | df2$any_non_missing <- !vec_detect_missing(df) 47 | df2 48 | } 49 | \seealso{ 50 | \code{\link[stats:complete.cases]{stats::complete.cases()}} 51 | } 52 | -------------------------------------------------------------------------------- /man/vec_empty.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-deprecated.R 3 | \name{vec_empty} 4 | \alias{vec_empty} 5 | \title{Is a vector empty} 6 | \usage{ 7 | vec_empty(x) 8 | } 9 | \arguments{ 10 | \item{x}{An object.} 11 | } 12 | \description{ 13 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#defunct}{\figure{lifecycle-defunct.svg}{options: alt='[Defunct]'}}}{\strong{[Defunct]}} 14 | 15 | This function is defunct, please use \code{\link[=vec_is_empty]{vec_is_empty()}}. 16 | } 17 | \keyword{internal} 18 | -------------------------------------------------------------------------------- /man/vec_equal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/equal.R 3 | \name{vec_equal} 4 | \alias{vec_equal} 5 | \title{Equality} 6 | \usage{ 7 | vec_equal(x, y, na_equal = FALSE, .ptype = NULL) 8 | } 9 | \arguments{ 10 | \item{x, y}{Vectors with compatible types and lengths.} 11 | 12 | \item{na_equal}{Should \code{NA} values be considered equal?} 13 | 14 | \item{.ptype}{Override to optionally specify common type} 15 | } 16 | \value{ 17 | A logical vector the same size as the common size of \code{x} and \code{y}. 18 | Will only contain \code{NA}s if \code{na_equal} is \code{FALSE}. 19 | } 20 | \description{ 21 | \code{vec_equal()} tests if two vectors are equal. 22 | } 23 | \section{Dependencies}{ 24 | 25 | \itemize{ 26 | \item \code{\link[=vec_cast_common]{vec_cast_common()}} with fallback 27 | \item \code{\link[=vec_recycle_common]{vec_recycle_common()}} 28 | \item \code{\link[=vec_proxy_equal]{vec_proxy_equal()}} 29 | } 30 | } 31 | 32 | \examples{ 33 | vec_equal(c(TRUE, FALSE, NA), FALSE) 34 | vec_equal(c(TRUE, FALSE, NA), FALSE, na_equal = TRUE) 35 | 36 | vec_equal(5, 1:10) 37 | vec_equal("d", letters[1:10]) 38 | 39 | df <- data.frame(x = c(1, 1, 2, 1), y = c(1, 2, 1, NA)) 40 | vec_equal(df, data.frame(x = 1, y = 2)) 41 | } 42 | \seealso{ 43 | \code{\link[=vec_detect_missing]{vec_detect_missing()}} 44 | } 45 | -------------------------------------------------------------------------------- /man/vec_equal_na.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-deprecated.R 3 | \name{vec_equal_na} 4 | \alias{vec_equal_na} 5 | \title{Missing values} 6 | \usage{ 7 | vec_equal_na(x) 8 | } 9 | \arguments{ 10 | \item{x}{A vector} 11 | } 12 | \value{ 13 | A logical vector the same size as \code{x}. 14 | } 15 | \description{ 16 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 17 | 18 | \code{vec_equal_na()} has been renamed to \code{\link[=vec_detect_missing]{vec_detect_missing()}} and is deprecated 19 | as of vctrs 0.5.0. 20 | } 21 | \keyword{internal} 22 | -------------------------------------------------------------------------------- /man/vec_init.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/slice.R 3 | \name{vec_init} 4 | \alias{vec_init} 5 | \title{Initialize a vector} 6 | \usage{ 7 | vec_init(x, n = 1L) 8 | } 9 | \arguments{ 10 | \item{x}{Template of vector to initialize.} 11 | 12 | \item{n}{Desired size of result.} 13 | } 14 | \description{ 15 | Initialize a vector 16 | } 17 | \section{Dependencies}{ 18 | 19 | \itemize{ 20 | \item vec_slice() 21 | } 22 | } 23 | 24 | \examples{ 25 | vec_init(1:10, 3) 26 | vec_init(Sys.Date(), 5) 27 | 28 | # The "missing" value for a data frame is a row that is entirely missing 29 | vec_init(mtcars, 2) 30 | 31 | # The "missing" value for a list is `NULL` 32 | vec_init(list(), 3) 33 | } 34 | -------------------------------------------------------------------------------- /man/vec_is_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-deprecated.R 3 | \name{vec_is_list} 4 | \alias{vec_is_list} 5 | \alias{vec_check_list} 6 | \title{List checks} 7 | \usage{ 8 | vec_is_list(x) 9 | 10 | vec_check_list(x, ..., arg = caller_arg(x), call = caller_env()) 11 | } 12 | \arguments{ 13 | \item{x}{For \verb{vec_*()} functions, an object. For \verb{list_*()} functions, a 14 | list.} 15 | 16 | \item{...}{These dots are for future extensions and must be empty.} 17 | 18 | \item{arg}{An argument name as a string. This argument 19 | will be mentioned in error messages as the input that is at the 20 | origin of a problem.} 21 | 22 | \item{call}{The execution environment of a currently 23 | running function, e.g. \code{caller_env()}. The function will be 24 | mentioned in error messages as the source of the error. See the 25 | \code{call} argument of \code{\link[rlang:abort]{abort()}} for more information.} 26 | } 27 | \description{ 28 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 29 | 30 | These functions have been deprecated as of vctrs 0.6.0. 31 | \itemize{ 32 | \item \code{vec_is_list()} has been renamed to \code{\link[=obj_is_list]{obj_is_list()}}. 33 | \item \code{vec_check_list()} has been renamed to \code{\link[=obj_check_list]{obj_check_list()}}. 34 | } 35 | } 36 | \keyword{internal} 37 | -------------------------------------------------------------------------------- /man/vec_ptype_full.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/ptype-abbr-full.R 3 | \name{vec_ptype_full} 4 | \alias{vec_ptype_full} 5 | \alias{vec_ptype_abbr} 6 | \title{Vector type as a string} 7 | \usage{ 8 | vec_ptype_full(x, ...) 9 | 10 | vec_ptype_abbr(x, ..., prefix_named = FALSE, suffix_shape = TRUE) 11 | } 12 | \arguments{ 13 | \item{x}{A vector.} 14 | 15 | \item{...}{These dots are for future extensions and must be empty.} 16 | 17 | \item{prefix_named}{If \code{TRUE}, add a prefix for named vectors.} 18 | 19 | \item{suffix_shape}{If \code{TRUE} (the default), append the shape of 20 | the vector.} 21 | } 22 | \value{ 23 | A string. 24 | } 25 | \description{ 26 | \code{vec_ptype_full()} displays the full type of the vector. \code{vec_ptype_abbr()} 27 | provides an abbreviated summary suitable for use in a column heading. 28 | } 29 | \section{S3 dispatch}{ 30 | 31 | The default method for \code{vec_ptype_full()} uses the first element of the 32 | class vector. Override this method if your class has parameters that should 33 | be prominently displayed. 34 | 35 | The default method for \code{vec_ptype_abbr()} \code{\link[=abbreviate]{abbreviate()}}s \code{vec_ptype_full()} 36 | to 8 characters. You should almost always override, aiming for 4-6 37 | characters where possible. 38 | 39 | These arguments are handled by the generic and not passed to methods: 40 | \itemize{ 41 | \item \code{prefix_named} 42 | \item \code{suffix_shape} 43 | } 44 | } 45 | 46 | \examples{ 47 | cat(vec_ptype_full(1:10)) 48 | cat(vec_ptype_full(iris)) 49 | 50 | cat(vec_ptype_abbr(1:10)) 51 | } 52 | \keyword{internal} 53 | -------------------------------------------------------------------------------- /man/vec_repeat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-deprecated.R 3 | \name{vec_repeat} 4 | \alias{vec_repeat} 5 | \title{Expand the length of a vector} 6 | \usage{ 7 | vec_repeat(x, each = 1L, times = 1L) 8 | } 9 | \arguments{ 10 | \item{x}{A vector.} 11 | 12 | \item{each}{Number of times to repeat each element of \code{x}.} 13 | 14 | \item{times}{Number of times to repeat the whole vector of \code{x}.} 15 | } 16 | \value{ 17 | A vector the same type as \code{x} with size \code{vec_size(x) * times * each}. 18 | } 19 | \description{ 20 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 21 | 22 | \code{vec_repeat()} has been replaced with \code{\link[=vec_rep]{vec_rep()}} and \code{\link[=vec_rep_each]{vec_rep_each()}} and is 23 | deprecated as of vctrs 0.3.0. 24 | } 25 | \keyword{internal} 26 | -------------------------------------------------------------------------------- /man/vec_seq_along.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/size.R 3 | \name{vec_seq_along} 4 | \alias{vec_seq_along} 5 | \alias{vec_init_along} 6 | \title{Useful sequences} 7 | \usage{ 8 | vec_seq_along(x) 9 | 10 | vec_init_along(x, y = x) 11 | } 12 | \arguments{ 13 | \item{x, y}{Vectors} 14 | } 15 | \value{ 16 | \itemize{ 17 | \item \code{vec_seq_along()} an integer vector with the same size as \code{x}. 18 | \item \code{vec_init_along()} a vector with the same type as \code{x} and the same size 19 | as \code{y}. 20 | } 21 | } 22 | \description{ 23 | \code{vec_seq_along()} is equivalent to \code{\link[=seq_along]{seq_along()}} but uses size, not length. 24 | \code{vec_init_along()} creates a vector of missing values with size matching 25 | an existing object. 26 | } 27 | \examples{ 28 | vec_seq_along(mtcars) 29 | vec_init_along(head(mtcars)) 30 | } 31 | -------------------------------------------------------------------------------- /man/vec_split.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/split.R 3 | \name{vec_split} 4 | \alias{vec_split} 5 | \title{Split a vector into groups} 6 | \usage{ 7 | vec_split(x, by) 8 | } 9 | \arguments{ 10 | \item{x}{Vector to divide into groups.} 11 | 12 | \item{by}{Vector whose unique values defines the groups.} 13 | } 14 | \value{ 15 | A data frame with two columns and size equal to 16 | \code{vec_size(vec_unique(by))}. The \code{key} column has the same type as 17 | \code{by}, and the \code{val} column is a list containing elements of type 18 | \code{vec_ptype(x)}. 19 | 20 | Note for complex types, the default \code{data.frame} print method will be 21 | suboptimal, and you will want to coerce into a tibble to better 22 | understand the output. 23 | } 24 | \description{ 25 | This is a generalisation of \code{\link[=split]{split()}} that can split by any type of vector, 26 | not just factors. Instead of returning the keys in the character names, 27 | the are returned in a separate parallel vector. 28 | } 29 | \section{Dependencies}{ 30 | 31 | \itemize{ 32 | \item \code{\link[=vec_group_loc]{vec_group_loc()}} 33 | \item \code{\link[=vec_chop]{vec_chop()}} 34 | } 35 | } 36 | 37 | \examples{ 38 | vec_split(mtcars$cyl, mtcars$vs) 39 | vec_split(mtcars$cyl, mtcars[c("vs", "am")]) 40 | 41 | if (require("tibble")) { 42 | as_tibble(vec_split(mtcars$cyl, mtcars[c("vs", "am")])) 43 | as_tibble(vec_split(mtcars, mtcars[c("vs", "am")])) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /man/vec_type.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/vctrs-deprecated.R 3 | \name{vec_type} 4 | \alias{vec_type} 5 | \alias{vec_type_common} 6 | \alias{vec_type2} 7 | \title{Deprecated type functions} 8 | \usage{ 9 | vec_type(x) 10 | 11 | vec_type_common(..., .ptype = NULL) 12 | 13 | vec_type2(x, y, ...) 14 | } 15 | \arguments{ 16 | \item{x, y, ..., .ptype}{Arguments for deprecated functions.} 17 | } 18 | \description{ 19 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} 20 | 21 | These functions have been renamed: 22 | \itemize{ 23 | \item \code{vec_type()} => \code{\link[=vec_ptype]{vec_ptype()}} 24 | \item \code{vec_type2()} => \code{\link[=vec_ptype2]{vec_ptype2()}} 25 | \item \code{vec_type_common()} => \code{\link[=vec_ptype_common]{vec_ptype_common()}} 26 | } 27 | } 28 | \keyword{internal} 29 | -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /revdep/.gitignore: -------------------------------------------------------------------------------- 1 | checks 2 | library 3 | checks.noindex 4 | library.noindex 5 | cloud.noindex 6 | data.sqlite 7 | *.html 8 | -------------------------------------------------------------------------------- /revdep/cran.md: -------------------------------------------------------------------------------- 1 | ## revdepcheck results 2 | 3 | We checked 4392 reverse dependencies (4359 from CRAN + 33 from Bioconductor), comparing R CMD check results across CRAN and dev versions of this package. 4 | 5 | * We saw 2 new problems 6 | * We failed to check 7 packages 7 | 8 | Issues with CRAN packages are summarised below. 9 | 10 | ### New problems 11 | (This reports the first line of each new failure) 12 | 13 | * covidcast 14 | checking re-building of vignette outputs ... ERROR 15 | 16 | * scGOclust 17 | checking re-building of vignette outputs ... ERROR 18 | 19 | ### Failed to check 20 | 21 | * ImputeRobust (NA) 22 | * loon.ggplot (NA) 23 | * loon.shiny (NA) 24 | * MarketMatching (NA) 25 | * Platypus (NA) 26 | * tidyfit (NA) 27 | * vivid (NA) 28 | -------------------------------------------------------------------------------- /revdep/email.yml: -------------------------------------------------------------------------------- 1 | release_date: ??? 2 | rel_release_date: ??? 3 | my_news_url: ??? 4 | release_version: ??? 5 | release_details: ??? 6 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.dll 4 | -------------------------------------------------------------------------------- /src/Makevars: -------------------------------------------------------------------------------- 1 | PKG_CPPFLAGS = -I./rlang 2 | PKG_CFLAGS = $(C_VISIBILITY) 3 | -------------------------------------------------------------------------------- /src/altrep-rle.h: -------------------------------------------------------------------------------- 1 | #ifndef ALTREP_RLE_H 2 | #define ALTREP_RLE_H 3 | 4 | #include "altrep.h" 5 | 6 | #if (HAS_ALTREP) 7 | 8 | SEXP altrep_rle_Make(SEXP input); 9 | R_xlen_t altrep_rle_Length(SEXP vec); 10 | Rboolean altrep_rle_Inspect( 11 | SEXP x, 12 | int pre, 13 | int deep, 14 | int pvec, 15 | void (*inspect_subtree)(SEXP, int, int, int)); 16 | SEXP altrep_rle_string_Elt(SEXP vec, R_xlen_t i); 17 | SEXP altrep_rle_Extract_subset(SEXP x, SEXP indx, SEXP call); 18 | SEXP altrep_rle_string_Materialize(SEXP vec); 19 | void* altrep_rle_Dataptr(SEXP vec, Rboolean writeable); 20 | const void* altrep_rle_Dataptr_or_null(SEXP vec); 21 | void vctrs_init_altrep_rle(DllInfo* dll); 22 | 23 | extern R_altrep_class_t altrep_rle_class; 24 | 25 | #endif 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/altrep.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "altrep.h" 3 | 4 | // [[ register() ]] 5 | r_obj* vctrs_is_altrep(r_obj* x) { 6 | return r_lgl(ALTREP(x)); 7 | } 8 | -------------------------------------------------------------------------------- /src/arg.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_ARG_H 2 | #define VCTRS_ARG_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | 7 | // Materialise an argument tag as a CHARSXP. 8 | r_obj* vctrs_arg(struct vctrs_arg* arg); 9 | 10 | // Materialise an argument tag as a vmax-protected C string. 11 | const char* vec_arg_format(struct vctrs_arg* p_arg); 12 | 13 | 14 | // Simple wrapper around a string 15 | struct vctrs_arg new_wrapper_arg(struct vctrs_arg* parent, 16 | const char* arg); 17 | 18 | 19 | struct vctrs_arg new_lazy_arg(struct r_lazy* data); 20 | 21 | 22 | // Wrapper around a counter representing the current position of the 23 | // argument 24 | struct arg_data_counter { 25 | struct vctrs_arg* p_parent; 26 | r_ssize* i; 27 | r_obj** names; 28 | r_ssize* names_i; 29 | }; 30 | 31 | struct vctrs_arg new_counter_arg(struct vctrs_arg* parent, 32 | struct arg_data_counter* data); 33 | 34 | struct arg_data_counter new_counter_arg_data(struct vctrs_arg* p_parent, 35 | r_ssize* i, 36 | r_obj** names, 37 | r_ssize* names_i); 38 | 39 | 40 | struct vctrs_arg* new_subscript_arg_vec(struct vctrs_arg* parent, 41 | r_obj* x, 42 | r_ssize* p_i); 43 | 44 | struct vctrs_arg* new_subscript_arg(struct vctrs_arg* parent, 45 | r_obj* names, 46 | r_ssize n, 47 | r_ssize* p_i); 48 | 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/assert.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_ASSERT_H 2 | #define VCTRS_ASSERT_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | void obj_check_vector(r_obj* x, 7 | struct vctrs_arg* arg, 8 | struct r_lazy call); 9 | 10 | void vec_check_size(r_obj* x, 11 | r_ssize size, 12 | struct vctrs_arg* arg, 13 | struct r_lazy call); 14 | 15 | void obj_check_list(r_obj* x, 16 | struct vctrs_arg* arg, 17 | struct r_lazy call); 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /src/c-unchop.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_C_UNCHOP_H 2 | #define VCTRS_C_UNCHOP_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | 7 | 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/c.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_C_H 2 | #define VCTRS_C_H 3 | 4 | #include "vctrs-core.h" 5 | #include "names.h" 6 | #include "ptype2.h" 7 | 8 | 9 | r_obj* vec_c(r_obj* xs, 10 | r_obj* ptype, 11 | r_obj* name_spec, 12 | const struct name_repair_opts* name_repair, 13 | struct vctrs_arg* p_error_arg, 14 | struct r_lazy error_call); 15 | 16 | r_obj* vec_c_opts(r_obj* xs, 17 | r_obj* ptype, 18 | r_obj* name_spec, 19 | const struct name_repair_opts* name_repair, 20 | const struct fallback_opts* fallback_opts, 21 | struct vctrs_arg* p_error_arg, 22 | struct r_lazy error_call); 23 | 24 | r_obj* vec_c_fallback_invoke(r_obj* xs, 25 | r_obj* name_spec, 26 | struct r_lazy error_call); 27 | r_obj* vec_c_fallback(r_obj* ptype, 28 | r_obj* xs, 29 | r_obj* name_spec, 30 | const struct name_repair_opts* name_repair, 31 | struct vctrs_arg* p_error_arg, 32 | struct r_lazy error_call); 33 | 34 | bool needs_vec_c_fallback(r_obj* ptype); 35 | bool needs_vec_c_homogeneous_fallback(r_obj* xs, r_obj* ptype); 36 | 37 | void df_c_fallback(r_obj* out, 38 | r_obj* ptype, 39 | r_obj* xs, 40 | r_ssize n_rows, 41 | r_obj* name_spec, 42 | const struct name_repair_opts* name_repair, 43 | struct r_lazy error_call); 44 | 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/callables.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | 3 | // ----------------------------------------------------------------------------- 4 | // Maturing 5 | 6 | R_len_t short_vec_size(SEXP x) { 7 | return vec_size(x); 8 | } 9 | 10 | SEXP short_vec_recycle(SEXP x, R_len_t size) { 11 | return vec_recycle(x, size); 12 | } 13 | 14 | // ----------------------------------------------------------------------------- 15 | // Experimental 16 | 17 | SEXP exp_vec_cast(SEXP x, SEXP to) { 18 | return vec_cast(x, to, vec_args.empty, vec_args.empty, r_lazy_null); 19 | } 20 | 21 | SEXP exp_vec_chop(SEXP x, SEXP indices) { 22 | return vec_chop_unsafe(x, indices, r_null); 23 | } 24 | 25 | SEXP exp_vec_slice_impl(SEXP x, SEXP subscript) { 26 | return vec_slice_unsafe(x, subscript); 27 | } 28 | 29 | SEXP exp_vec_names(SEXP x) { 30 | return vec_names(x); 31 | } 32 | 33 | SEXP exp_vec_set_names(SEXP x, SEXP names) { 34 | return vec_set_names(x, names); 35 | } 36 | 37 | SEXP exp_short_compact_seq(R_len_t start, R_len_t size, bool increasing) { 38 | return compact_seq(start, size, increasing); 39 | } 40 | 41 | void exp_short_init_compact_seq(int* p, R_len_t start, R_len_t size, bool increasing) { 42 | init_compact_seq(p, start, size, increasing); 43 | } 44 | -------------------------------------------------------------------------------- /src/cast-bare.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_CAST_BARE_H 2 | #define VCTRS_CAST_BARE_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* int_as_double(r_obj* x, bool* lossy); 7 | r_obj* lgl_as_double(r_obj* x, bool* lossy); 8 | r_obj* dbl_as_integer(r_obj* x, bool* lossy); 9 | r_obj* lgl_as_integer(r_obj* x, bool* lossy); 10 | r_obj* chr_as_logical(r_obj* x, bool* lossy); 11 | r_obj* dbl_as_logical(r_obj* x, bool* lossy); 12 | r_obj* int_as_logical(r_obj* x, bool* lossy); 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/cast-dispatch.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_CAST_DISPATCH_H 2 | #define VCTRS_CAST_DISPATCH_H 3 | 4 | #include "vctrs-core.h" 5 | #include "cast.h" 6 | 7 | r_obj* vec_cast_dispatch_native(const struct cast_opts* opts, 8 | enum vctrs_type x_type, 9 | enum vctrs_type to_type, 10 | bool* lossy); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/complete.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_COMPLETE_H 2 | #define VCTRS_COMPLETE_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_detect_complete(r_obj* x); 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/conditions.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_CONDITIONS_H 2 | #define VCTRS_CONDITIONS_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_no_return 7 | void stop_incompatible_size(r_obj* x, 8 | r_obj* y, 9 | r_ssize x_size, 10 | r_ssize y_size, 11 | struct vctrs_arg* x_arg, 12 | struct vctrs_arg* y_arg, 13 | struct r_lazy call); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/decl/arg-counter-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* reduce_impl(r_obj* current, 3 | r_obj* rest, 4 | struct vctrs_arg* p_parent_arg, 5 | struct counters* counters, 6 | bool spliced, 7 | r_obj* (*impl)(r_obj* current, 8 | r_obj* next, 9 | struct counters* counters, 10 | void* data), 11 | void* data); 12 | 13 | static 14 | r_obj* reduce_splice_box(r_obj* current, 15 | r_obj* rest, 16 | struct vctrs_arg* p_parent_arg, 17 | struct counters* counters, 18 | r_obj* (*impl)(r_obj* current, 19 | r_obj* rest, 20 | struct counters* counters, 21 | void* data), 22 | void* data); 23 | -------------------------------------------------------------------------------- /src/decl/arg-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | int fill_arg_buffer(struct vctrs_arg* arg, 3 | char* buf, 4 | r_ssize cur_size, 5 | r_ssize tot_size); 6 | 7 | static 8 | r_ssize counter_arg_fill(void* data, char* buf, r_ssize remaining); 9 | 10 | static 11 | r_ssize wrapper_arg_fill(void* data, char* buf, r_ssize remaining); 12 | 13 | static 14 | r_ssize lazy_arg_fill(void* data, char* buf, r_ssize remaining); 15 | 16 | static 17 | r_ssize subscript_arg_fill(void* p_data, char* buf, r_ssize remaining); 18 | 19 | static 20 | bool is_empty_arg(struct vctrs_arg* arg); 21 | -------------------------------------------------------------------------------- /src/decl/assert-decl.h: -------------------------------------------------------------------------------- 1 | static r_no_return 2 | void stop_non_list_type(r_obj* x, 3 | struct vctrs_arg* arg, 4 | struct r_lazy call); 5 | 6 | static 7 | void list_check_all_size(r_obj* xs, 8 | r_ssize size, 9 | struct vctrs_arg* p_arg, 10 | struct r_lazy call); 11 | -------------------------------------------------------------------------------- /src/decl/bind-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* vec_rbind(r_obj* xs, 3 | r_obj* ptype, 4 | r_obj* id, 5 | struct name_repair_opts* name_repair, 6 | r_obj* name_spec, 7 | struct r_lazy error_call); 8 | 9 | static 10 | r_obj* as_df_row(r_obj* x, 11 | struct name_repair_opts* name_repair, 12 | struct r_lazy error_call); 13 | 14 | static 15 | r_obj* as_df_row_impl(r_obj* x, 16 | struct name_repair_opts* name_repair, 17 | struct r_lazy error_call); 18 | 19 | static 20 | struct name_repair_opts validate_bind_name_repair(r_obj* name_repair, bool allow_minimal); 21 | 22 | static 23 | r_obj* vec_cbind(r_obj* xs, 24 | r_obj* ptype, 25 | r_obj* size, 26 | struct name_repair_opts* name_repair, 27 | struct r_lazy error_call); 28 | 29 | static 30 | r_obj* cbind_names_to(bool has_names, 31 | r_obj* names_to, 32 | r_obj* ptype, 33 | struct r_lazy error_call); 34 | 35 | static 36 | r_obj* as_df_col(r_obj* x, 37 | r_obj* outer, 38 | bool* allow_pack, 39 | struct r_lazy error_call); 40 | 41 | static 42 | r_obj* cbind_container_type(r_obj* x, void* data); 43 | 44 | static r_obj* syms_vec_cbind_frame_ptype; 45 | static r_obj* fns_vec_cbind_frame_ptype; 46 | 47 | static 48 | r_obj* shaped_as_df_col(r_obj* x, r_obj* outer); 49 | 50 | static 51 | r_obj* vec_as_df_col(r_obj* x, r_obj* outer); 52 | -------------------------------------------------------------------------------- /src/decl/c-decl.h: -------------------------------------------------------------------------------- 1 | static inline 2 | bool vec_implements_base_c(r_obj* x); 3 | 4 | static inline 5 | int vec_c_fallback_validate_args(r_obj* x, r_obj* name_spec); 6 | 7 | static 8 | void stop_vec_c_fallback(r_obj* xs, int err_type, struct r_lazy call); 9 | 10 | static 11 | bool df_needs_fallback(r_obj* x); 12 | -------------------------------------------------------------------------------- /src/decl/c-unchop-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* list_unchop(r_obj* xs, 3 | r_obj* indices, 4 | r_obj* ptype, 5 | r_obj* name_spec, 6 | const struct name_repair_opts* name_repair, 7 | struct vctrs_arg* p_error_arg, 8 | struct r_lazy error_call); 9 | 10 | static 11 | r_obj* list_unchop_fallback(r_obj* ptype, 12 | r_obj* xs, 13 | r_obj* indices, 14 | r_obj* name_spec, 15 | const struct name_repair_opts* name_repair, 16 | enum fallback_homogeneous homogenous, 17 | struct vctrs_arg* p_error_arg, 18 | struct r_lazy error_call); 19 | -------------------------------------------------------------------------------- /src/decl/cast-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* vec_cast_switch_native(const struct cast_opts* opts, 3 | enum vctrs_type x_type, 4 | enum vctrs_type to_type, 5 | bool* lossy); 6 | 7 | static 8 | r_obj* vec_cast_dispatch_s3(const struct cast_opts* opts); 9 | -------------------------------------------------------------------------------- /src/decl/compare-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* df_compare(r_obj* x, r_obj* y, bool na_equal, r_ssize size); 3 | 4 | static 5 | void df_compare_impl(int* v_out, 6 | struct df_short_circuit_info* p_info, 7 | r_obj* x, 8 | r_obj* y, 9 | bool na_equal); 10 | 11 | static 12 | void vec_compare_col(int* v_out, 13 | struct df_short_circuit_info* p_info, 14 | r_obj* x, 15 | r_obj* y, 16 | bool na_equal); 17 | -------------------------------------------------------------------------------- /src/decl/dictionary-decl.h: -------------------------------------------------------------------------------- 1 | static inline uint32_t dict_key_size(SEXP x); 2 | -------------------------------------------------------------------------------- /src/decl/empty-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* list_drop_empty(r_obj* x); 2 | -------------------------------------------------------------------------------- /src/decl/expand-decl.h: -------------------------------------------------------------------------------- 1 | static inline 2 | enum vctrs_expand_vary parse_vary(r_obj* vary); 3 | -------------------------------------------------------------------------------- /src/decl/interval-decl.h: -------------------------------------------------------------------------------- 1 | // Initialized at load time 2 | struct vctrs_arg args_start_; 3 | static struct vctrs_arg* const args_start = &args_start_; 4 | 5 | struct vctrs_arg args_end_; 6 | static struct vctrs_arg* const args_end = &args_end_; 7 | 8 | struct vctrs_arg args_lower_; 9 | static struct vctrs_arg* const args_lower = &args_lower_; 10 | 11 | struct vctrs_arg args_upper_; 12 | static struct vctrs_arg* const args_upper = &args_upper_; 13 | 14 | static r_obj* vec_interval_group_info(r_obj* start, 15 | r_obj* end, 16 | bool abutting, 17 | enum vctrs_interval_missing missing, 18 | bool locations); 19 | 20 | static 21 | r_obj* vec_interval_complement(r_obj* start, 22 | r_obj* end, 23 | r_obj* lower, 24 | r_obj* upper); 25 | 26 | static 27 | r_obj* vec_interval_locate_containers(r_obj* start, r_obj* end); 28 | 29 | static inline 30 | r_obj* interval_order(r_obj* start, 31 | r_obj* end, 32 | r_obj* direction, 33 | r_obj* na_value, 34 | r_ssize size); 35 | 36 | static inline 37 | enum vctrs_interval_missing parse_missing(r_obj* missing); 38 | -------------------------------------------------------------------------------- /src/decl/match-joint-decl.h: -------------------------------------------------------------------------------- 1 | static inline r_obj* vec_joint_proxy_order(r_obj* x, r_obj* y); 2 | static inline r_obj* vec_joint_proxy_order_independent(r_obj* x, r_obj* y); 3 | static inline r_obj* vec_joint_proxy_order_dependent(r_obj* x, r_obj* y); 4 | static inline r_obj* vec_joint_proxy_order_s3(r_obj* x, r_obj* y); 5 | static inline r_obj* df_joint_proxy_order(r_obj* x, r_obj* y); 6 | -------------------------------------------------------------------------------- /src/decl/names-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* syms_as_universal_names; 2 | static r_obj* syms_check_unique_names; 3 | static r_obj* fns_as_universal_names; 4 | static r_obj* fns_check_unique_names; 5 | static r_obj* syms_glue_as_name_spec; 6 | static r_obj* fns_glue_as_name_spec; 7 | static r_obj* syms_internal_spec; 8 | static r_obj* syms_set_rownames_dispatch; 9 | static r_obj* fns_set_rownames_dispatch; 10 | static r_obj* syms_set_names_dispatch; 11 | static r_obj* fns_set_names_dispatch; 12 | 13 | static 14 | void describe_repair(r_obj* old_names, r_obj* new_names); 15 | 16 | static 17 | r_obj* check_unique_names(r_obj* names, 18 | const struct name_repair_opts* opts); 19 | 20 | static 21 | void vec_validate_minimal_names(r_obj* names, r_ssize n, struct r_lazy call); 22 | 23 | r_obj* ffi_as_minimal_names(r_obj* names); 24 | 25 | static 26 | bool any_has_suffix(r_obj* names); 27 | 28 | static 29 | r_obj* as_unique_names_impl(r_obj* names, bool quiet); 30 | 31 | static 32 | void stop_large_name(void); 33 | 34 | static 35 | bool is_dotdotint(const char* name); 36 | 37 | static 38 | ptrdiff_t suffix_pos(const char* name); 39 | 40 | static 41 | bool needs_suffix(r_obj* str); 42 | 43 | static 44 | r_obj* names_iota(r_ssize n); 45 | 46 | static 47 | r_obj* vec_unique_names_impl(r_obj* names, r_ssize n, bool quiet); 48 | 49 | static 50 | r_obj* glue_as_name_spec(r_obj* spec); 51 | -------------------------------------------------------------------------------- /src/decl/poly-op-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | int p_df_equal_na_equal(const void* x, r_ssize i, const void* y, r_ssize j); 3 | 4 | static 5 | int p_df_compare_na_equal(const void* x, r_ssize i, const void* y, r_ssize j); 6 | 7 | static 8 | bool p_df_is_missing(const void* x, r_ssize i); 9 | 10 | static 11 | bool p_df_is_incomplete(const void* x, r_ssize i); 12 | 13 | static void init_nil_poly_vec(struct poly_vec* p_poly_vec); 14 | static void init_lgl_poly_vec(struct poly_vec* p_poly_vec); 15 | static void init_int_poly_vec(struct poly_vec* p_poly_vec); 16 | static void init_dbl_poly_vec(struct poly_vec* p_poly_vec); 17 | static void init_cpl_poly_vec(struct poly_vec* p_poly_vec); 18 | static void init_chr_poly_vec(struct poly_vec* p_poly_vec); 19 | static void init_raw_poly_vec(struct poly_vec* p_poly_vec); 20 | static void init_list_poly_vec(struct poly_vec* p_poly_vec); 21 | static void init_df_poly_vec(struct poly_vec* p_poly_vec); 22 | -------------------------------------------------------------------------------- /src/decl/proxy-decl.h: -------------------------------------------------------------------------------- 1 | r_obj* syms_vec_proxy; 2 | r_obj* syms_vec_proxy_equal; 3 | r_obj* syms_vec_proxy_equal_array; 4 | r_obj* syms_vec_proxy_compare; 5 | r_obj* syms_vec_proxy_compare_array; 6 | r_obj* syms_vec_proxy_order; 7 | r_obj* syms_vec_proxy_order_array; 8 | 9 | r_obj* fns_vec_proxy_equal_array; 10 | r_obj* fns_vec_proxy_compare_array; 11 | r_obj* fns_vec_proxy_order_array; 12 | 13 | static 14 | r_obj* vec_proxy_2(r_obj* x, enum vctrs_recurse recurse); 15 | 16 | static inline 17 | r_obj* vec_proxy_equal_impl(r_obj* x); 18 | static inline 19 | r_obj* vec_proxy_compare_impl(r_obj* x); 20 | static inline 21 | r_obj* vec_proxy_order_impl(r_obj* x); 22 | 23 | static inline 24 | r_obj* vec_proxy_equal_method(r_obj* x); 25 | 26 | static inline 27 | r_obj* vec_proxy_equal_invoke(r_obj* x, r_obj* method); 28 | 29 | static inline 30 | r_obj* vec_proxy_compare_method(r_obj* x); 31 | 32 | static inline 33 | r_obj* vec_proxy_compare_invoke(r_obj* x, r_obj* method); 34 | 35 | static inline 36 | r_obj* vec_proxy_order_method(r_obj* x); 37 | 38 | static inline 39 | r_obj* vec_proxy_order_invoke(r_obj* x, r_obj* method); 40 | 41 | static inline 42 | r_obj* df_proxy(r_obj* x, enum vctrs_proxy_kind kind); 43 | 44 | static inline 45 | r_obj* df_proxy_recurse(r_obj* x); 46 | -------------------------------------------------------------------------------- /src/decl/proxy-restore-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* syms_vec_restore_dispatch; 2 | static r_obj* fns_vec_restore_dispatch; 3 | 4 | static 5 | r_obj* vec_restore_4(r_obj* x, 6 | r_obj* to, 7 | enum vctrs_owned owned, 8 | enum vctrs_recurse recurse); 9 | 10 | static 11 | r_obj* vec_restore_dispatch(r_obj* x, r_obj* to); 12 | -------------------------------------------------------------------------------- /src/decl/ptype-common-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* ptype2_common(r_obj* current, 3 | r_obj* next, 4 | struct counters* counters, 5 | void* data); 6 | -------------------------------------------------------------------------------- /src/decl/ptype-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | SEXP syms_vec_ptype; 3 | 4 | static 5 | SEXP syms_vec_ptype_finalise_dispatch; 6 | 7 | static 8 | SEXP fns_vec_ptype_finalise_dispatch; 9 | 10 | static inline 11 | r_obj* vec_ptype_slice(r_obj* x, r_obj* empty); 12 | 13 | static 14 | r_obj* df_ptype(r_obj* x, bool bare); 15 | 16 | static 17 | r_obj* col_ptype(r_obj* x); 18 | 19 | static 20 | r_obj* s3_ptype(r_obj* x, 21 | struct vctrs_arg* x_arg, 22 | struct r_lazy call); 23 | 24 | static inline 25 | r_obj* vec_ptype_method(r_obj* x); 26 | 27 | static inline 28 | r_obj* vec_ptype_invoke(r_obj* x, r_obj* method); 29 | 30 | static 31 | r_obj* vec_ptype_finalise_unspecified(r_obj* x); 32 | 33 | static 34 | r_obj* vec_ptype_finalise_dispatch(r_obj* x); 35 | 36 | static 37 | r_obj* vec_ptype_final_call; 38 | 39 | static 40 | struct r_lazy vec_ptype_final_lazy_call; 41 | -------------------------------------------------------------------------------- /src/decl/ptype2-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* vec_ptype2_switch_native(const struct ptype2_opts* opts, 3 | enum vctrs_type x_type, 4 | enum vctrs_type y_type, 5 | int* left); 6 | -------------------------------------------------------------------------------- /src/decl/ptype2-dispatch-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* syms_vec_ptype2_default; 3 | -------------------------------------------------------------------------------- /src/decl/rank-decl.h: -------------------------------------------------------------------------------- 1 | static inline enum ties parse_ties(r_obj* ties); 2 | static inline enum incomplete parse_incomplete(r_obj* incomplete); 3 | 4 | static inline bool r_lgl_all(r_obj* x); 5 | 6 | static r_obj* vec_rank(r_obj* x, 7 | enum ties ties_type, 8 | enum incomplete incomplete_type, 9 | r_obj* direction, 10 | r_obj* na_value, 11 | bool nan_distinct, 12 | r_obj* chr_proxy_collate); 13 | 14 | static void vec_rank_min(const int* v_order, 15 | const int* v_group_sizes, 16 | r_ssize n_groups, 17 | int* v_rank); 18 | 19 | static void vec_rank_max(const int* v_order, 20 | const int* v_group_sizes, 21 | r_ssize n_groups, 22 | int* v_rank); 23 | 24 | static void vec_rank_sequential(const int* v_order, 25 | const int* v_group_sizes, 26 | r_ssize n_groups, 27 | int* v_rank); 28 | 29 | static void vec_rank_dense(const int* v_order, 30 | const int* v_group_sizes, 31 | r_ssize n_groups, 32 | int* v_rank); 33 | -------------------------------------------------------------------------------- /src/decl/rlang-dev-decl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/src/decl/rlang-dev-decl.h -------------------------------------------------------------------------------- /src/decl/set-decl.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/r-lib/vctrs/78d9f2b0b24131b5ce2230eb3c2c9f93620b10d9/src/decl/set-decl.h -------------------------------------------------------------------------------- /src/decl/shape-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* vec_shape2(r_obj* x, r_obj* y, struct vctrs_arg* p_x_arg, struct vctrs_arg* p_y_arg); 3 | 4 | static 5 | r_obj* vec_shape2_impl(r_obj* x_dimensions, 6 | r_obj* y_dimensions, 7 | r_obj* x, 8 | r_obj* y, 9 | struct vctrs_arg* p_x_arg, 10 | struct vctrs_arg* p_y_arg); 11 | 12 | static 13 | r_obj* vec_shape(r_obj* dimensions); 14 | 15 | static inline 16 | int vec_dimension2(int x_dimension, int y_dimension, 17 | int axis, 18 | r_obj* x, r_obj* y, 19 | struct vctrs_arg* p_x_arg, struct vctrs_arg* p_y_arg); 20 | -------------------------------------------------------------------------------- /src/decl/size-common-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* vctrs_size2_common(r_obj* x, 3 | r_obj* y, 4 | struct counters* counters, 5 | void* data); 6 | -------------------------------------------------------------------------------- /src/decl/size-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_ssize vec_size_opts(r_obj* x, const struct vec_error_opts* opts); 3 | 4 | static 5 | r_ssize vec_raw_size(r_obj* x); 6 | 7 | static 8 | bool list_all_size(r_obj* xs, r_ssize size); 9 | -------------------------------------------------------------------------------- /src/decl/slice-assign-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* syms_vec_assign_fallback; 2 | static r_obj* fns_vec_assign_fallback; 3 | 4 | static 5 | r_obj* vec_assign_fallback(r_obj* x, r_obj* index, r_obj* value); 6 | 7 | static 8 | r_obj* vec_proxy_assign_names(r_obj* proxy, r_obj* index, r_obj* value, const enum vctrs_owned owned); 9 | 10 | static 11 | r_obj* lgl_assign(r_obj* x, r_obj* index, r_obj* value, const enum vctrs_owned owned); 12 | 13 | static 14 | r_obj* int_assign(r_obj* x, r_obj* index, r_obj* value, const enum vctrs_owned owned); 15 | 16 | static 17 | r_obj* dbl_assign(r_obj* x, r_obj* index, r_obj* value, const enum vctrs_owned owned); 18 | 19 | static 20 | r_obj* cpl_assign(r_obj* x, r_obj* index, r_obj* value, const enum vctrs_owned owned); 21 | 22 | static 23 | r_obj* raw_assign(r_obj* x, r_obj* index, r_obj* value, const enum vctrs_owned owned); 24 | -------------------------------------------------------------------------------- /src/decl/slice-chop-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* vec_chop_base(r_obj* x, 3 | struct vctrs_proxy_info info, 4 | struct vctrs_chop_indices* p_indices); 5 | 6 | static 7 | r_obj* chop(r_obj* x, 8 | struct vctrs_proxy_info info, 9 | struct vctrs_chop_indices* p_indices); 10 | static 11 | r_obj* chop_shaped(r_obj* x, 12 | struct vctrs_proxy_info info, 13 | struct vctrs_chop_indices* p_indices); 14 | static 15 | r_obj* chop_df(r_obj* x, 16 | struct vctrs_proxy_info info, 17 | struct vctrs_chop_indices* p_indices); 18 | 19 | static 20 | r_obj* chop_fallback(r_obj* x, struct vctrs_chop_indices* p_indices); 21 | static 22 | r_obj* chop_fallback_shaped(r_obj* x, struct vctrs_chop_indices* p_indices); 23 | 24 | static 25 | r_obj* vec_as_chop_sizes(r_obj* sizes, r_ssize size); 26 | -------------------------------------------------------------------------------- /src/decl/slice-interleave-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* vec_interleave_indices(r_ssize n, r_ssize size); 2 | -------------------------------------------------------------------------------- /src/decl/subscript-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* fns_cnd_body_subscript_dim; 3 | 4 | static 5 | r_obj* new_error_subscript_type(r_obj* subscript, 6 | const struct subscript_opts* opts, 7 | r_obj* body); 8 | 9 | static 10 | enum subscript_type_action parse_subscript_arg_type(r_obj* x, 11 | const char* kind); 12 | 13 | static 14 | r_obj* obj_cast_subscript(r_obj* subscript, 15 | const struct subscript_opts* opts, 16 | ERR* err); 17 | 18 | static 19 | r_obj* dbl_cast_subscript(r_obj* subscript, 20 | const struct subscript_opts* opts, 21 | ERR* err); 22 | 23 | static 24 | r_obj* dbl_cast_subscript_fallback(r_obj* subscript, 25 | const struct subscript_opts* opts, 26 | ERR* err); 27 | 28 | static 29 | r_obj* syms_new_dbl_cast_subscript_body; 30 | 31 | static 32 | r_obj* syms_lossy_err; 33 | 34 | static 35 | r_obj* syms_new_error_subscript_type; 36 | -------------------------------------------------------------------------------- /src/decl/type-data-frame-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* syms_df_lossy_cast; 2 | static r_obj* fns_df_lossy_cast; 3 | 4 | static 5 | r_obj* new_compact_rownames(r_ssize n); 6 | 7 | static 8 | r_ssize df_size_from_n(r_obj* n); 9 | 10 | static 11 | r_obj* c_data_frame_class(r_obj* cls); 12 | 13 | static 14 | r_obj* data_frame(r_obj* x, 15 | r_ssize size, 16 | const struct name_repair_opts* p_name_repair_opts, 17 | struct r_lazy error_call); 18 | 19 | static 20 | r_obj* df_list(r_obj* x, 21 | r_ssize size, 22 | bool unpack, 23 | const struct name_repair_opts* p_name_repair_opts, 24 | struct r_lazy error_call); 25 | 26 | static 27 | r_obj* df_list_drop_null(r_obj* x); 28 | 29 | static 30 | r_obj* df_list_unpack(r_obj* x); 31 | 32 | static 33 | void init_bare_data_frame(r_obj* x, r_ssize n); 34 | 35 | static 36 | r_obj* df_ptype2_match(const struct ptype2_opts* opts, 37 | r_obj* x_names, 38 | r_obj* y_names); 39 | 40 | static 41 | r_obj* df_ptype2_loop(const struct ptype2_opts* opts, 42 | r_obj* y_names); 43 | 44 | static 45 | r_obj* df_cast_match(const struct cast_opts* opts, 46 | r_obj* x_names, 47 | r_obj* to_names); 48 | 49 | static 50 | r_obj* df_cast_loop(const struct cast_opts* opts, r_obj* names); 51 | 52 | static 53 | r_ssize df_flatten_loop(r_obj* x, 54 | r_obj* out, 55 | r_obj* out_names, 56 | r_ssize counter); 57 | -------------------------------------------------------------------------------- /src/decl/type-info-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | enum vctrs_type vec_base_typeof(r_obj* x, bool proxied); 3 | -------------------------------------------------------------------------------- /src/decl/type-integer64-decl.h: -------------------------------------------------------------------------------- 1 | static inline 2 | void int64_unpack(int64_t x, r_ssize i, double* v_left, double* v_right); 3 | 4 | static inline 5 | int64_t int64_pack(double left, double right); 6 | -------------------------------------------------------------------------------- /src/decl/typeof2-s3-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | enum vctrs_type2_s3 vec_typeof2_s3_impl2(SEXP x, 3 | SEXP y, 4 | enum vctrs_type type_y, 5 | int* left); 6 | -------------------------------------------------------------------------------- /src/decl/utils-dispatch-decl.h: -------------------------------------------------------------------------------- 1 | enum vctrs_class_type class_type(r_obj* x); 2 | 3 | static 4 | enum vctrs_class_type class_type_impl(r_obj* cls); 5 | 6 | static 7 | const char* class_type_as_str(enum vctrs_class_type type); 8 | -------------------------------------------------------------------------------- /src/dim.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | 3 | // [[ register() ]] 4 | SEXP vctrs_dim(SEXP x) { 5 | return vec_dim(x); 6 | } 7 | 8 | // [[ register() ]] 9 | SEXP vctrs_dim_n(SEXP x) { 10 | return r_int(vec_dim_n(x)); 11 | } 12 | 13 | // [[ register() ]] 14 | SEXP vctrs_has_dim(SEXP x) { 15 | return r_lgl(has_dim(x)); 16 | } 17 | -------------------------------------------------------------------------------- /src/dim.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_DIM_H 2 | #define VCTRS_DIM_H 3 | 4 | #include "vctrs-core.h" 5 | #include "utils.h" 6 | 7 | // These versions return NULL and 0 for bare vectors. 8 | // This is useful to distinguish them from 1D arrays. 9 | static inline SEXP vec_bare_dim(SEXP x) { 10 | return r_dim(x); 11 | } 12 | static inline R_len_t vec_bare_dim_n(SEXP x) { 13 | return Rf_length(vec_bare_dim(x)); 14 | } 15 | 16 | 17 | static inline SEXP vec_dim(SEXP x) { 18 | SEXP dim = vec_bare_dim(x); 19 | 20 | if (dim == R_NilValue) { 21 | dim = r_int(Rf_length(x)); 22 | } 23 | 24 | return dim; 25 | } 26 | 27 | static inline R_len_t vec_dim_n(SEXP x) { 28 | SEXP dim = vec_bare_dim(x); 29 | 30 | if (dim == R_NilValue) { 31 | return 1; 32 | } 33 | 34 | return Rf_length(dim); 35 | } 36 | 37 | 38 | static inline bool has_dim(SEXP x) { 39 | return ATTRIB(x) != R_NilValue && r_dim(x) != R_NilValue; 40 | } 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/empty.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | #include "decl/empty-decl.h" 3 | 4 | // [[ register() ]] 5 | r_obj* vctrs_list_drop_empty(r_obj* x) { 6 | return list_drop_empty(x); 7 | } 8 | 9 | static 10 | r_obj* list_drop_empty(r_obj* x) { 11 | if (!obj_is_list(x)) { 12 | r_abort("`x` must be a list."); 13 | } 14 | 15 | r_ssize i = 0; 16 | const r_ssize size = vec_size(x); 17 | 18 | r_obj* const* v_x = r_list_cbegin(x); 19 | 20 | // Locate first element to drop 21 | for (; i < size; ++i) { 22 | if (vec_size(v_x[i]) == 0) { 23 | break; 24 | } 25 | } 26 | 27 | if (i == size) { 28 | // Nothing to drop 29 | return x; 30 | } 31 | 32 | r_obj* keep = KEEP(r_alloc_logical(size)); 33 | int* v_keep = r_lgl_begin(keep); 34 | 35 | for (r_ssize j = 0; j < i; ++j) { 36 | // Keep everything before first element to drop 37 | v_keep[j] = true; 38 | } 39 | 40 | // `i` should be dropped so handle that here 41 | v_keep[i] = false; 42 | ++i; 43 | 44 | for (; i < size; ++i) { 45 | v_keep[i] = vec_size(v_x[i]) != 0; 46 | } 47 | 48 | r_obj* out = vec_slice(x, keep); 49 | 50 | FREE(1); 51 | return out; 52 | } 53 | -------------------------------------------------------------------------------- /src/expand.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_EXPAND_H 2 | #define VCTRS_EXPAND_H 3 | 4 | #include "vctrs-core.h" 5 | #include "names.h" 6 | 7 | enum vctrs_expand_vary { 8 | VCTRS_EXPAND_VARY_slowest = 0, 9 | VCTRS_EXPAND_VARY_fastest = 1 10 | }; 11 | 12 | r_obj* vec_expand_grid(r_obj* xs, 13 | enum vctrs_expand_vary vary, 14 | const struct name_repair_opts* p_name_repair_opts, 15 | struct r_lazy error_call); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/growable.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | 3 | struct growable new_growable(SEXPTYPE type, int capacity) { 4 | struct growable g; 5 | 6 | g.x = Rf_allocVector(type, capacity); 7 | g.type = type; 8 | g.array = r_vec_unwrap(type, g.x); 9 | g.n = 0; 10 | g.capacity = capacity; 11 | 12 | return g; 13 | } 14 | 15 | SEXP growable_values(struct growable* g) { 16 | return Rf_lengthgets(g->x, g->n); 17 | } 18 | -------------------------------------------------------------------------------- /src/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_HASH_H 2 | #define VCTRS_HASH_H 3 | 4 | #define HASH_MISSING 1 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/match-joint.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_MATCH_JOINT_H 2 | #define VCTRS_MATCH_JOINT_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_joint_xtfrm(r_obj* x, 7 | r_obj* y, 8 | r_ssize x_size, 9 | r_ssize y_size, 10 | bool nan_distinct, 11 | r_obj* chr_proxy_collate); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/order-collate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * The implementation of vec_order() is based on data.table’s forder() and their 3 | * earlier contribution to R’s order(). See LICENSE.note for more information. 4 | * 5 | * This Source Code Form is subject to the terms of the Mozilla Public 6 | * License, v. 2.0. If a copy of the MPL was not distributed with this file, 7 | * You can obtain one at https://mozilla.org/MPL/2.0/. 8 | * 9 | * Copyright (c) 2020, RStudio 10 | * Copyright (c) 2020, Data table team 11 | */ 12 | 13 | #ifndef VCTRS_ORDER_COLLATE_H 14 | #define VCTRS_ORDER_COLLATE_H 15 | 16 | #include "vctrs-core.h" 17 | 18 | // ----------------------------------------------------------------------------- 19 | 20 | /* 21 | * `proxy_apply_chr_proxy_collate()` iterates over `proxy`, applying 22 | * `chr_proxy_collate` on any character vectors that it detects. 23 | * 24 | * It expects that: 25 | * - If `proxy` is a data frame, it has been flattened by its corresponding 26 | * `vec_proxy_*()` function. 27 | * - All character vectors in `proxy` have already been normalized to UTF-8 28 | * by `vec_normalize_encoding()`. 29 | */ 30 | SEXP proxy_apply_chr_proxy_collate(SEXP proxy, SEXP chr_proxy_collate); 31 | 32 | // ----------------------------------------------------------------------------- 33 | #endif 34 | -------------------------------------------------------------------------------- /src/owned.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_OWNED_H 2 | #define VCTRS_OWNED_H 3 | 4 | #include "vctrs-core.h" 5 | #include "altrep.h" 6 | #include "utils.h" 7 | 8 | 9 | static inline enum vctrs_owned vec_owned(SEXP x) { 10 | return NO_REFERENCES(x) ? VCTRS_OWNED_true : VCTRS_OWNED_false; 11 | } 12 | 13 | // Wrapper around `r_clone_referenced()` that only attempts to clone if 14 | // we indicate that we don't own `x` 15 | static inline SEXP vec_clone_referenced(SEXP x, const enum vctrs_owned owned) { 16 | if (owned == VCTRS_OWNED_false) { 17 | return r_clone_referenced(x); 18 | } else { 19 | return x; 20 | } 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/poly-op.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_POLY_OP 2 | #define VCTRS_POLY_OP 3 | 4 | #include "vctrs-core.h" 5 | 6 | 7 | struct poly_vec { 8 | r_obj* shelter; 9 | r_obj* vec; 10 | const void* p_vec; 11 | }; 12 | 13 | struct poly_vec* new_poly_vec(r_obj* proxy, enum vctrs_type type); 14 | 15 | 16 | struct poly_df_data { 17 | enum vctrs_type* v_col_type; 18 | const void** v_col_ptr; 19 | r_ssize n_col; 20 | }; 21 | 22 | 23 | typedef int (poly_binary_int_fn)(const void* x, r_ssize i, const void* y, r_ssize j); 24 | poly_binary_int_fn* poly_p_equal_na_equal(enum vctrs_type type); 25 | poly_binary_int_fn* poly_p_compare_na_equal(enum vctrs_type type); 26 | 27 | typedef bool (poly_unary_bool_fn)(const void* x, r_ssize i); 28 | poly_unary_bool_fn* poly_p_is_missing(enum vctrs_type type); 29 | poly_unary_bool_fn* poly_p_is_incomplete(enum vctrs_type type); 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/proxy-restore.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_PROXY_RESTORE_H 2 | #define VCTRS_PROXY_RESTORE_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | 7 | r_obj* vec_restore(r_obj* x, r_obj* to, enum vctrs_owned owned); 8 | r_obj* vec_restore_default(r_obj* x, r_obj* to, enum vctrs_owned owned); 9 | 10 | r_obj* vec_restore_recurse(r_obj* x, r_obj* to, enum vctrs_owned owned); 11 | 12 | r_obj* vec_df_restore(r_obj* x, 13 | r_obj* to, 14 | enum vctrs_owned owned, 15 | enum vctrs_recurse recurse); 16 | 17 | r_obj* vec_bare_df_restore(r_obj* x, 18 | r_obj* to, 19 | enum vctrs_owned owned, 20 | enum vctrs_recurse recurse); 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/proxy.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_PROXY_H 2 | #define VCTRS_PROXY_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_proxy(r_obj* x); 7 | r_obj* vec_proxy_equal(r_obj* x); 8 | r_obj* vec_proxy_compare(r_obj* x); 9 | r_obj* vec_proxy_order(r_obj* x); 10 | r_obj* vec_proxy_recurse(r_obj* x); 11 | 12 | r_obj* vec_proxy_method(r_obj* x); 13 | r_obj* vec_proxy_invoke(r_obj* x, r_obj* method); 14 | r_obj* vec_proxy_unwrap(r_obj* x); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/ptype-common.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_PTYPE_COMMON_H 2 | #define VCTRS_PTYPE_COMMON_H 3 | 4 | #include "vctrs-core.h" 5 | #include "ptype2.h" 6 | #include "utils.h" 7 | 8 | struct ptype_common_opts { 9 | struct r_lazy call; 10 | struct vctrs_arg* p_arg; 11 | struct fallback_opts fallback; 12 | }; 13 | 14 | static inline 15 | bool vec_is_common_class_fallback(r_obj* ptype) { 16 | return r_inherits(ptype, c_strs_vctrs_common_class_fallback); 17 | } 18 | 19 | r_obj* vec_ptype_common_params(r_obj* dots, 20 | r_obj* ptype, 21 | enum s3_fallback s3_fallback, 22 | struct vctrs_arg* p_arg, 23 | struct r_lazy call); 24 | 25 | r_obj* vec_ptype_common_opts(r_obj* dots, 26 | r_obj* ptype, 27 | const struct ptype_common_opts* opts); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/ptype.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_PTYPE_H 2 | #define VCTRS_PTYPE_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_ptype(r_obj* x, struct vctrs_arg* x_arg, struct r_lazy call); 7 | r_obj* vec_ptype_final(r_obj* x); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/ptype2-dispatch.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_PTYPE2_DISPATCH_H 2 | #define VCTRS_PTYPE2_DISPATCH_H 3 | 4 | #include "vctrs-core.h" 5 | #include "ptype2.h" 6 | 7 | r_obj* vec_ptype2_dispatch_native(const struct ptype2_opts* opts, 8 | enum vctrs_type x_type, 9 | enum vctrs_type y_type, 10 | int* left); 11 | 12 | r_obj* vec_ptype2_dispatch_s3(const struct ptype2_opts* opts); 13 | 14 | r_obj* vec_invoke_coerce_method(r_obj* method_sym, r_obj* method, 15 | r_obj* x_sym, r_obj* x, 16 | r_obj* y_sym, r_obj* y, 17 | r_obj* x_arg_sym, r_obj* x_arg, 18 | r_obj* y_arg_sym, r_obj* y_arg, 19 | struct r_lazy call, 20 | const struct fallback_opts* opts); 21 | 22 | r_obj* vec_ptype2_default(r_obj* x, 23 | r_obj* y, 24 | struct vctrs_arg* x_arg, 25 | struct vctrs_arg* y_arg, 26 | struct r_lazy call, 27 | const struct fallback_opts* p_opts); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/rep.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_REP_H 2 | #define VCTRS_REP_H 3 | 4 | r_obj* vec_rep(r_obj* x, 5 | int times, 6 | struct r_lazy error_call, 7 | struct vctrs_arg* p_x_arg, 8 | struct vctrs_arg* p_times_arg); 9 | 10 | r_obj* vec_rep_each(r_obj* x, 11 | r_obj* times, 12 | struct r_lazy error_call, 13 | struct vctrs_arg* p_x_arg, 14 | struct vctrs_arg* p_times_arg); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/rlang-dev.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | #include "decl/rlang-dev-decl.h" 3 | 4 | const char* r_obj_type_friendly_length(r_obj* x) { 5 | return r_obj_type_friendly_full(x, true, true); 6 | } 7 | -------------------------------------------------------------------------------- /src/rlang-dev.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_RLANG_DEV_H 2 | #define VCTRS_RLANG_DEV_H 3 | 4 | #include 5 | 6 | static inline 7 | const char* r_c_str_format_error_arg(const char* x) { 8 | r_obj* ffi_x = KEEP(r_chr(x)); 9 | const char* out = r_format_error_arg(ffi_x); 10 | FREE(1); 11 | return out; 12 | } 13 | 14 | // vmax-protected result 15 | const char* r_obj_type_friendly_length(r_obj* x); 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/rlang.c: -------------------------------------------------------------------------------- 1 | // This is an include point for the implementations of the rlang 2 | // library. It should be included in a single and separate compilation 3 | // unit. 4 | 5 | #include "rlang/rlang.c" 6 | -------------------------------------------------------------------------------- /src/rlang/altrep.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_ALTREP_H 2 | #define RLANG_ALTREP_H 3 | 4 | 5 | #if (R_VERSION < R_Version(3, 5, 0)) || \ 6 | (defined(_WIN32) && R_VERSION == R_Version(3, 5, 0)) 7 | # define R_HAS_ALTREP 0 8 | #else 9 | # define R_HAS_ALTREP 1 10 | #endif 11 | 12 | #if !R_HAS_ALTREP 13 | # define ALTREP(x) false 14 | #endif 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/rlang/arg.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | 3 | int (*r_arg_match)(r_obj* arg, 4 | r_obj* values, 5 | struct r_lazy error_arg, 6 | struct r_lazy error_call); 7 | 8 | void r_init_library_arg(void) { 9 | r_arg_match = (int (*)(r_obj*, r_obj*, struct r_lazy, struct r_lazy)) 10 | r_peek_c_callable("rlang", "rlang_arg_match_2"); 11 | } 12 | -------------------------------------------------------------------------------- /src/rlang/arg.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_ARG_H 2 | #define RLANG_ARG_H 3 | 4 | 5 | extern int (*r_arg_match)(r_obj* arg, 6 | r_obj* values, 7 | struct r_lazy error_arg, 8 | struct r_lazy error_call); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/rlang/c-utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void* r_shelter_deref(r_obj* x) { 4 | enum r_type type = r_typeof(x); 5 | 6 | switch (type) { 7 | case R_TYPE_list: 8 | if (r_length(x) < 1) { 9 | r_abort("Shelter must have at least one element"); 10 | } 11 | x = r_list_get(x, 0); 12 | type = r_typeof(x); 13 | break; 14 | case R_TYPE_pairlist: 15 | x = r_node_car(x); 16 | type = r_typeof(x); 17 | break; 18 | case R_TYPE_raw: 19 | break; 20 | default: 21 | r_stop_unimplemented_type(type); 22 | } 23 | 24 | if (type != R_TYPE_raw) { 25 | r_stop_unexpected_type(type); 26 | } 27 | 28 | return r_raw_begin(x); 29 | } 30 | -------------------------------------------------------------------------------- /src/rlang/call.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | 3 | static r_obj* quote_prim = NULL; 4 | 5 | 6 | bool r_is_call(r_obj* x, const char* name) { 7 | if (r_typeof(x) != LANGSXP) { 8 | return false; 9 | } else { 10 | return name == NULL || r_is_symbol(r_node_car(x), name); 11 | } 12 | } 13 | 14 | bool r_is_call_any(r_obj* x, const char** names, int n) { 15 | if (r_typeof(x) != LANGSXP) { 16 | return false; 17 | } else { 18 | return r_is_symbol_any(r_node_car(x), names, n); 19 | } 20 | } 21 | 22 | r_obj* r_expr_protect(r_obj* x) { 23 | switch (r_typeof(x)) { 24 | case R_TYPE_symbol: 25 | case R_TYPE_call: 26 | case R_TYPE_promise: 27 | return r_call2(quote_prim, x); 28 | default: 29 | return x; 30 | } 31 | } 32 | 33 | static inline 34 | bool is_node(r_obj* x) { 35 | switch (r_typeof(x)) { 36 | case R_TYPE_call: 37 | case R_TYPE_pairlist: 38 | return true; 39 | default: 40 | return false; 41 | } 42 | } 43 | 44 | r_obj* r_call_clone(r_obj* x) { 45 | if (!is_node(x)) { 46 | r_abort("Input must be a call."); 47 | } 48 | 49 | x = KEEP(r_clone(x)); 50 | 51 | r_obj* rest = x; 52 | while (rest != r_null) { 53 | r_obj* head = r_node_car(rest); 54 | if (is_node(head)) { 55 | r_node_poke_car(rest, r_call_clone(head)); 56 | } 57 | rest = r_node_cdr(rest); 58 | } 59 | 60 | FREE(1); 61 | return x; 62 | } 63 | 64 | 65 | void r_init_library_call(void) { 66 | quote_prim = r_base_ns_get("quote"); 67 | } 68 | -------------------------------------------------------------------------------- /src/rlang/call.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_LANG_H 2 | #define RLANG_LANG_H 3 | 4 | #include "node.h" 5 | 6 | 7 | #define r_new_call Rf_lcons 8 | #define r_call Rf_lang1 9 | #define r_call2 Rf_lang2 10 | #define r_call3 Rf_lang3 11 | #define r_call4 Rf_lang4 12 | #define r_call5 Rf_lang5 13 | 14 | bool r_is_call(r_obj* x, const char* name); 15 | bool r_is_call_any(r_obj* x, const char** names, int n); 16 | 17 | r_obj* r_expr_protect(r_obj* x); 18 | r_obj* r_call_clone(r_obj* x); 19 | 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /src/rlang/cpp/rlang.cpp: -------------------------------------------------------------------------------- 1 | #include "vec.cpp" 2 | -------------------------------------------------------------------------------- /src/rlang/cpp/vec.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | extern "C" { 5 | 6 | int* r_int_unique0(int* v_data, r_ssize size) { 7 | try { 8 | return std::unique(v_data, v_data + size); 9 | } catch (...) { 10 | rcc_abort("r_int_unique0"); 11 | } 12 | } 13 | 14 | bool r_list_all_of0(r_obj* const * v_first, 15 | r_ssize size, 16 | bool (*predicate)(r_obj* x)) { 17 | try { 18 | return std::all_of(v_first, v_first + size, predicate); 19 | } catch (...) { 20 | rcc_abort("r_list_all_of"); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/rlang/debug.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | 3 | 4 | void r_sexp_inspect(r_obj* x) { 5 | r_obj* call = KEEP(r_parse(".Internal(inspect(x))")); 6 | r_eval_with_x(call, x, r_envs.base); 7 | FREE(1); 8 | } 9 | 10 | void r_browse(r_obj* x) { 11 | r_env_poke(r_envs.global, r_sym(".debug"), x); 12 | 13 | r_printf("Object saved in `.debug`:\n"); 14 | r_obj_print(x); 15 | 16 | r_obj* frame = KEEP(r_peek_frame()); 17 | r_browse_at(frame); 18 | FREE(1); 19 | } 20 | void r_browse_at(r_obj* env) { 21 | // The NULL expression is needed because of a limitation in ESS 22 | r_parse_eval("{ browser(); NULL }", env); 23 | } 24 | 25 | void r_dbg_str(r_obj* x) { 26 | r_obj* call = KEEP(r_parse("str(x)")); 27 | r_eval_with_x(call, x, r_ns_env("utils")); 28 | FREE(1); 29 | } 30 | -------------------------------------------------------------------------------- /src/rlang/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_DEBUG_H 2 | #define RLANG_DEBUG_H 3 | 4 | 5 | #define r_printf Rprintf 6 | void r_sexp_inspect(r_obj* x); 7 | void r_browse(r_obj* x); 8 | void r_browse_at(r_obj* env); 9 | void r_dbg_str(r_obj* x); 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/rlang/decl/cnd-decl.h: -------------------------------------------------------------------------------- 1 | static r_obj* cnd_signal_call; 2 | -------------------------------------------------------------------------------- /src/rlang/decl/df-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | void init_compact_rownames(r_obj* x, r_ssize n_rows); 3 | 4 | static 5 | r_obj* new_compact_rownames(r_ssize n_rows); 6 | -------------------------------------------------------------------------------- /src/rlang/decl/dict-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* dict_find_node_info(struct r_dict* dict, 3 | r_obj* key, 4 | r_ssize* hash, 5 | r_obj** parent); 6 | 7 | static 8 | r_obj* dict_find_node(struct r_dict* dict, r_obj* key); 9 | 10 | static 11 | void dict_push(struct r_dict* p_dict, 12 | r_ssize hash, 13 | r_obj* parent, 14 | r_obj* key, 15 | r_obj* value); 16 | -------------------------------------------------------------------------------- /src/rlang/decl/dyn-list-of-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | bool reserve_push_back(struct r_dyn_list_of* p_lof, r_ssize i, void* p_elt); 3 | 4 | static 5 | void reserve_move(struct r_dyn_list_of* p_lof, r_ssize i, void* p_elt); 6 | -------------------------------------------------------------------------------- /src/rlang/decl/env-decl.h: -------------------------------------------------------------------------------- 1 | r_obj* eval_with_x(r_obj* call, r_obj* x); 2 | r_obj* eval_with_xy(r_obj* call, r_obj* x, r_obj* y); 3 | r_obj* eval_with_xyz(r_obj* call, r_obj* x, r_obj* y, r_obj* z); 4 | 5 | #if R_VERSION < R_Version(4, 1, 0) 6 | static 7 | r_obj* new_env_call; 8 | 9 | static 10 | r_obj* new_env__parent_node; 11 | 12 | static 13 | r_obj* new_env__size_node; 14 | #endif 15 | 16 | static 17 | r_obj* exists_call; 18 | 19 | static 20 | r_obj* remove_call; 21 | 22 | static 23 | r_obj* poke_lazy_call; 24 | 25 | static 26 | r_obj* poke_lazy_value_node; 27 | 28 | 29 | static 30 | r_obj* env2list_call; 31 | 32 | static 33 | r_obj* list2env_call; 34 | 35 | #if R_VERSION < R_Version(4, 0, 0) 36 | static 37 | r_obj* env_as_list_compat(r_obj* env, r_obj* out); 38 | #endif 39 | 40 | static 41 | void env_coalesce_plain(r_obj* env, r_obj* from, r_obj* nms); 42 | -------------------------------------------------------------------------------- /src/rlang/decl/obj-decl.h: -------------------------------------------------------------------------------- 1 | static 2 | r_obj* new_precious_stack(r_obj* x); 3 | 4 | static 5 | int push_precious(r_obj* stack); 6 | 7 | static 8 | int pop_precious(r_obj* stack); 9 | 10 | static 11 | r_obj* as_label_call; 12 | -------------------------------------------------------------------------------- /src/rlang/decl/stack-decl.h: -------------------------------------------------------------------------------- 1 | // From env.c 2 | r_obj* rlang_ns_get(const char* name); 3 | 4 | static r_obj* peek_frame_call; 5 | static r_obj* caller_env_call; 6 | -------------------------------------------------------------------------------- /src/rlang/decl/walk-decl.h: -------------------------------------------------------------------------------- 1 | static inline 2 | enum sexp_iterator_type sexp_iterator_type(enum r_type type, 3 | r_obj* x); 4 | 5 | static inline 6 | r_obj* sexp_node_attrib(enum r_type type, r_obj* x); 7 | 8 | static inline 9 | r_obj* sexp_node_car(enum r_type type, 10 | r_obj* x, 11 | enum r_sexp_it_relation* p_rel); 12 | 13 | static inline 14 | r_obj* sexp_node_cdr(enum r_type type, 15 | r_obj* x, 16 | enum r_sexp_it_relation* p_rel); 17 | 18 | static inline 19 | r_obj* sexp_node_tag(enum r_type type, 20 | r_obj* x, 21 | enum r_sexp_it_relation* p_rel); 22 | 23 | static inline 24 | void init_incoming_stack_info(struct sexp_stack_info* p_info, 25 | enum sexp_iterator_type it_type, 26 | bool has_attrib); 27 | 28 | static 29 | bool sexp_next_incoming(struct r_sexp_iterator* p_it, 30 | struct sexp_stack_info* p_info); 31 | -------------------------------------------------------------------------------- /src/rlang/df.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_DF_H 2 | #define RLANG_DF_H 3 | 4 | 5 | r_obj* r_alloc_df_list(r_ssize n_rows, 6 | r_obj* names, 7 | const enum r_type* v_types, 8 | r_ssize types_size); 9 | 10 | void r_init_data_frame(r_obj* x, r_ssize n_nows); 11 | void r_init_tibble(r_obj* x, r_ssize n_rows); 12 | 13 | 14 | #endif 15 | -------------------------------------------------------------------------------- /src/rlang/dict.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_DICT_H 2 | #define RLANG_DICT_H 3 | 4 | /** 5 | * This is a simple hash table of `r_obj*`. It is structured like R 6 | * environments and uses xxhash for hashing. 7 | */ 8 | 9 | 10 | struct r_dict { 11 | r_obj* shelter; 12 | 13 | /* private: */ 14 | r_obj* buckets; 15 | r_obj* const * p_buckets; 16 | 17 | r_ssize n_buckets; 18 | r_ssize n_entries; 19 | 20 | // For testing collisions 21 | bool prevent_resize; 22 | }; 23 | 24 | struct r_dict* r_new_dict(r_ssize size); 25 | 26 | r_obj* r_dict_poke(struct r_dict* p_dict, r_obj* key, r_obj* value); 27 | bool r_dict_put(struct r_dict* p_dict, r_obj* key, r_obj* value); 28 | bool r_dict_del(struct r_dict* p_dict, r_obj* key); 29 | bool r_dict_has(struct r_dict* p_dict, r_obj* key); 30 | r_obj* r_dict_get(struct r_dict* p_dict, r_obj* key); 31 | r_obj* r_dict_get0(struct r_dict* p_dict, r_obj* key); 32 | 33 | // Pass a negative size to resize by the default growth factor 34 | void r_dict_resize(struct r_dict* p_dict, r_ssize size); 35 | 36 | r_obj* r_dict_as_df_list(struct r_dict* p_dict); 37 | r_obj* r_dict_as_list(struct r_dict* p_dict); 38 | 39 | 40 | struct r_dict_iterator { 41 | r_obj* shelter; 42 | r_obj* key; 43 | r_obj* value; 44 | 45 | /* private: */ 46 | r_ssize i; 47 | r_ssize n; 48 | r_obj* const * v_buckets; 49 | r_obj* node; 50 | }; 51 | 52 | struct r_dict_iterator* r_new_dict_iterator(struct r_dict* p_dict); 53 | bool r_dict_next(struct r_dict_iterator* p_it); 54 | 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/rlang/env-binding.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_ENV_BINDING_H 2 | #define RLANG_ENV_BINDING_H 3 | 4 | 5 | enum r_env_binding_type { 6 | R_ENV_BINDING_TYPE_value = 0, 7 | R_ENV_BINDING_TYPE_promise, 8 | R_ENV_BINDING_TYPE_active 9 | }; 10 | 11 | bool r_env_binding_is_promise(r_obj* env, r_obj* sym); 12 | bool r_env_binding_is_active(r_obj* env, r_obj* sym); 13 | r_obj* r_env_binding_types(r_obj* env, r_obj* bindings); 14 | 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /src/rlang/export.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | #include "export.h" 3 | #include 4 | 5 | #if (defined(R_VERSION) && R_VERSION < R_Version(3, 4, 0)) 6 | r_obj* R_MakeExternalPtrFn(DL_FUNC p, r_obj* tag, r_obj* prot) { 7 | fn_ptr ptr; 8 | ptr.fn = p; 9 | return R_MakeExternalPtr(ptr.p, tag, prot); 10 | } 11 | DL_FUNC R_ExternalPtrAddrFn(r_obj* s) { 12 | fn_ptr ptr; 13 | ptr.p = EXTPTR_PTR(s); 14 | return ptr.fn; 15 | } 16 | #endif 17 | 18 | r_obj* rlang_namespace(const char* ns) { 19 | r_obj* ns_string = KEEP(Rf_mkString(ns)); 20 | r_obj* call = KEEP(r_sym("getNamespace")); 21 | call = KEEP(Rf_lang2(call, ns_string)); 22 | r_obj* ns_env = r_eval(call, R_BaseEnv); 23 | FREE(3); 24 | return ns_env; 25 | } 26 | -------------------------------------------------------------------------------- /src/rlang/export.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_EXPORT_H 2 | #define RLANG_EXPORT_H 3 | 4 | #include 5 | #include 6 | 7 | 8 | #if (defined(R_VERSION) && R_VERSION < R_Version(3, 4, 0)) 9 | typedef union {void* p; DL_FUNC fn;} fn_ptr; 10 | r_obj* R_MakeExternalPtrFn(DL_FUNC p, r_obj* tag, r_obj* prot); 11 | DL_FUNC R_ExternalPtrAddrFn(r_obj* s); 12 | #endif 13 | 14 | typedef DL_FUNC r_void_fn; 15 | 16 | static inline 17 | r_void_fn r_peek_c_callable(const char* pkg, const char* callable) { 18 | return R_GetCCallable(pkg, callable); 19 | } 20 | 21 | static inline 22 | r_obj* r_new_fn_ptr(r_void_fn p) { 23 | return R_MakeExternalPtrFn(p, r_null, r_null); 24 | } 25 | 26 | static inline 27 | r_void_fn r_fn_ptr_addr(r_obj* p) { 28 | return R_ExternalPtrAddrFn(p); 29 | } 30 | 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/rlang/fn.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | 3 | 4 | r_obj* rlang_formula_formals = NULL; 5 | 6 | r_obj* r_as_function(r_obj* x, const char* arg) { 7 | switch (r_typeof(x)) { 8 | case R_TYPE_closure: 9 | case R_TYPE_builtin: 10 | case R_TYPE_special: 11 | return x; 12 | 13 | case R_TYPE_call: 14 | if (r_node_car(x) == r_syms.tilde && r_node_cddr(x) == r_null) { 15 | r_obj* env = r_attrib_get(x, r_syms.dot_environment); 16 | if (env == r_null) { 17 | r_abort("Can't transform formula to function because it doesn't have an environment."); 18 | } 19 | 20 | return r_new_function(rlang_formula_formals, r_node_cadr(x), env); 21 | } 22 | // else fallthrough; 23 | default: 24 | r_abort("Can't convert `%s` to a function", arg); 25 | } 26 | } 27 | 28 | void r_init_library_fn(void) { 29 | const char* formals_code = "formals(function(..., .x = ..1, .y = ..2, . = ..1) NULL)"; 30 | rlang_formula_formals = r_parse_eval(formals_code, r_envs.base); 31 | r_preserve_global(rlang_formula_formals); 32 | } 33 | -------------------------------------------------------------------------------- /src/rlang/fn.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_FN_H 2 | #define RLANG_FN_H 3 | 4 | 5 | static inline 6 | r_obj* r_fn_body(r_obj* fn) { 7 | return BODY_EXPR(fn); 8 | } 9 | static inline 10 | void r_fn_poke_body(r_obj* fn, r_obj* body) { 11 | SET_BODY(fn, body); 12 | } 13 | 14 | static inline 15 | r_obj* r_fn_env(r_obj* fn) { 16 | return CLOENV(fn); 17 | } 18 | static inline 19 | void r_fn_poke_env(r_obj* fn, r_obj* env) { 20 | SET_CLOENV(fn, env); 21 | } 22 | 23 | static inline 24 | r_obj* r_new_function(r_obj* formals, r_obj* body, r_obj* env) { 25 | SEXP fn = Rf_allocSExp(R_TYPE_closure); 26 | SET_FORMALS(fn, formals); 27 | SET_BODY(fn, body); 28 | SET_CLOENV(fn, env); 29 | return fn; 30 | } 31 | 32 | r_obj* r_as_function(r_obj* x, const char* arg); 33 | 34 | static inline 35 | bool r_is_function(r_obj* x) { 36 | switch (r_typeof(x)) { 37 | case R_TYPE_closure: 38 | case R_TYPE_builtin: 39 | case R_TYPE_special: 40 | return true; 41 | default: 42 | return false; 43 | } 44 | } 45 | 46 | static inline 47 | bool r_is_primitive(r_obj* x) { 48 | switch (r_typeof(x)) { 49 | case R_TYPE_builtin: 50 | case R_TYPE_special: 51 | return true; 52 | default: 53 | return false; 54 | } 55 | } 56 | 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/rlang/formula.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_FORMULA_H 2 | #define RLANG_FORMULA_H 3 | 4 | 5 | bool r_is_formula(r_obj* x, int scoped, int lhs); 6 | 7 | r_obj* r_f_rhs(r_obj* f); 8 | r_obj* r_f_lhs(r_obj* f); 9 | r_obj* r_f_env(r_obj* f); 10 | bool r_f_has_env(r_obj* f); 11 | 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /src/rlang/parse.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | #include 3 | 4 | 5 | static void abort_parse(r_obj* code, const char* why) { 6 | if (r_peek_option("rlang__verbose_errors") != r_null) { 7 | r_obj_print(code); 8 | } 9 | r_abort("Internal error: %s", why); 10 | } 11 | 12 | r_obj* r_parse(const char* str) { 13 | r_obj* str_ = KEEP(r_chr(str)); 14 | 15 | ParseStatus status; 16 | r_obj* out = KEEP(R_ParseVector(str_, -1, &status, r_null)); 17 | if (status != PARSE_OK) { 18 | abort_parse(str_, "Parsing failed"); 19 | } 20 | if (r_length(out) != 1) { 21 | abort_parse(str_, "Expected a single expression"); 22 | } 23 | 24 | out = r_list_get(out, 0); 25 | 26 | FREE(2); 27 | return out; 28 | } 29 | r_obj* r_parse_eval(const char* str, r_obj* env) { 30 | r_obj* out = r_eval(KEEP(r_parse(str)), env); 31 | FREE(1); 32 | return out; 33 | } 34 | -------------------------------------------------------------------------------- /src/rlang/parse.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_PARSE_H 2 | #define RLANG_PARSE_H 3 | 4 | 5 | r_obj* r_parse(const char* str); 6 | r_obj* r_parse_eval(const char* str, r_obj* env); 7 | 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/rlang/quo.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | 3 | r_obj* (*r_quo_get_expr)(r_obj* quo); 4 | r_obj* (*r_quo_set_expr)(r_obj* quo, r_obj* expr); 5 | r_obj* (*r_quo_get_env)(r_obj* quo); 6 | r_obj* (*r_quo_set_env)(r_obj* quo, r_obj* env); 7 | 8 | void r_init_library_quo(void) { 9 | r_quo_get_expr = (r_obj* (*)(r_obj*)) r_peek_c_callable("rlang", "rlang_quo_get_expr"); 10 | r_quo_set_expr = (r_obj* (*)(r_obj*, r_obj*)) r_peek_c_callable("rlang", "rlang_quo_set_expr"); 11 | r_quo_get_env = (r_obj* (*)(r_obj*)) r_peek_c_callable("rlang", "rlang_quo_get_env"); 12 | r_quo_set_env = (r_obj* (*)(r_obj*, r_obj*)) r_peek_c_callable("rlang", "rlang_quo_set_env"); 13 | } 14 | -------------------------------------------------------------------------------- /src/rlang/quo.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_QUO_H 2 | #define RLANG_QUO_H 3 | 4 | 5 | extern r_obj* (*r_quo_get_expr)(r_obj* quo); 6 | extern r_obj* (*r_quo_set_expr)(r_obj* quo, r_obj* expr); 7 | extern r_obj* (*r_quo_get_env)(r_obj* quo); 8 | extern r_obj* (*r_quo_set_env)(r_obj* quo, r_obj* env); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/rlang/rlang.hpp: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_RLANG_HPP 2 | #define RLANG_RLANG_HPP 3 | 4 | #include 5 | 6 | #define R_NO_REMAP 7 | #include 8 | 9 | extern "C" { 10 | #include 11 | } 12 | 13 | static inline 14 | r_no_return 15 | void rcc_abort(const char* fn) { 16 | try { 17 | throw; 18 | } catch (const std::exception& err) { 19 | r_abort(err.what()); 20 | } catch (...) { 21 | r_obj* call = KEEP(r_call(r_sym(fn))); 22 | (r_stop_internal)("", -1, call, "Caught unknown C++ exception."); 23 | } 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/rlang/session.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_SESSION_H 2 | #define RLANG_SESSION_H 3 | 4 | 5 | bool r_is_installed(const char* pkg); 6 | bool r_has_colour(void); 7 | r_obj* r_getppid(void); 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/rlang/stack.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_STACK_H 2 | #define RLANG_STACK_H 3 | 4 | 5 | void r_on_exit(r_obj* expr, r_obj* frame); 6 | 7 | r_obj* r_peek_frame(void); 8 | r_obj* r_caller_env(r_obj* n); 9 | r_obj* r_sys_frame(int n, r_obj* frame); 10 | r_obj* r_sys_call(int n, r_obj* frame); 11 | 12 | static inline 13 | void r_yield_interrupt(void) { 14 | R_CheckUserInterrupt(); 15 | } 16 | 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /src/rlang/state.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_STATE_H 2 | #define RLANG_STATE_H 3 | 4 | 5 | static inline 6 | r_obj* r_peek_option(const char* name) { 7 | return Rf_GetOption1(Rf_install(name)); 8 | } 9 | 10 | static inline 11 | void r_poke_option(const char* name, r_obj* value) { 12 | r_obj* args = KEEP(r_new_node(value, r_null)); 13 | r_node_poke_tag(args, r_sym(name)); 14 | 15 | r_obj* call = KEEP(r_new_call(r_syms.options, args)); 16 | r_eval(call, r_envs.base); 17 | 18 | FREE(2); 19 | } 20 | 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /src/rlang/sym.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rlang.h" 4 | 5 | 6 | // In old R versions `as.name()` does not translate to native which 7 | // loses the encoding. This symbol constructor always translates. 8 | r_obj* r_new_symbol(r_obj* x, int* err) { 9 | switch (r_typeof(x)) { 10 | case SYMSXP: 11 | return x; 12 | case R_TYPE_character: 13 | if (r_length(x) == 1) { 14 | const char* string = Rf_translateChar(r_chr_get(x, 0)); 15 | return r_sym(string); 16 | } // else fallthrough 17 | default: { 18 | if (err) { 19 | *err = -1; 20 | return r_null; 21 | } else { 22 | const char* type = r_type_as_c_string(r_typeof(x)); 23 | r_abort("Can't create a symbol with a %s", type); 24 | } 25 | }} 26 | } 27 | 28 | bool r_is_symbol(r_obj* x, const char* string) { 29 | if (r_typeof(x) != SYMSXP) { 30 | return false; 31 | } else { 32 | return strcmp(CHAR(PRINTNAME(x)), string) == 0; 33 | } 34 | } 35 | 36 | bool r_is_symbol_any(r_obj* x, const char** strings, int n) { 37 | if (r_typeof(x) != SYMSXP) { 38 | return false; 39 | } 40 | 41 | const char* name = CHAR(PRINTNAME(x)); 42 | 43 | for (int i = 0; i < n; ++i) { 44 | if (strcmp(name, strings[i]) == 0) { 45 | return true; 46 | } 47 | } 48 | 49 | return false; 50 | } 51 | 52 | 53 | r_obj* (*r_sym_as_utf8_character)(r_obj* x) = NULL; 54 | r_obj* (*r_sym_as_utf8_string)(r_obj* x) = NULL; 55 | 56 | void r_init_library_sym(void) { 57 | r_sym_as_utf8_character = (r_obj* (*)(r_obj*)) r_peek_c_callable("rlang", "rlang_sym_as_character"); 58 | r_sym_as_utf8_string = (r_obj* (*)(r_obj*)) r_peek_c_callable("rlang", "rlang_sym_as_string"); 59 | } 60 | -------------------------------------------------------------------------------- /src/rlang/sym.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_SYM_H 2 | #define RLANG_SYM_H 3 | 4 | 5 | // The results of `r_sym_as_` functions must be protected 6 | 7 | extern r_obj* (*r_sym_as_utf8_character)(r_obj* x); 8 | extern r_obj* (*r_sym_as_utf8_string)(r_obj* x); 9 | 10 | r_obj* r_new_symbol(r_obj* x, int* err); 11 | 12 | static inline 13 | r_obj* r_sym(const char* c_string) { 14 | return Rf_install(c_string); 15 | } 16 | 17 | static inline 18 | r_obj* r_sym_string(r_obj* sym) { 19 | return PRINTNAME(sym); 20 | } 21 | static inline 22 | const char* r_sym_c_string(r_obj* sym) { 23 | return CHAR(PRINTNAME(sym)); 24 | } 25 | 26 | bool r_is_symbol(r_obj* sym, const char* string); 27 | bool r_is_symbol_any(r_obj* x, const char** strings, int n); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/rlang/vec-lgl.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_VECTOR_LGL_H 2 | #define RLANG_VECTOR_LGL_H 3 | 4 | 5 | r_ssize r_lgl_sum(r_obj* x, bool na_true); 6 | r_obj* r_lgl_which(r_obj* x, bool na_propagate); 7 | 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/rlang/vendor.c: -------------------------------------------------------------------------------- 1 | #include "rlang.h" 2 | 3 | uint64_t (*r_xxh3_64bits)(const void*, size_t); 4 | 5 | void r_init_library_vendor(void) { 6 | r_xxh3_64bits = (uint64_t (*)(const void*, size_t)) r_peek_c_callable("rlang", "rlang_xxh3_64bits"); 7 | } 8 | -------------------------------------------------------------------------------- /src/rlang/vendor.h: -------------------------------------------------------------------------------- 1 | #ifndef RLANG_VENDOR_H 2 | #define RLANG_VENDOR_H 3 | 4 | 5 | extern uint64_t (*r_xxh3_64bits)(const void*, size_t); 6 | 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /src/runs.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_RUNS_H 2 | #define VCTRS_RUNS_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_identify_runs(r_obj* x, struct r_lazy error_call); 7 | r_obj* vec_run_sizes(r_obj* x, struct r_lazy error_call); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /src/set.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_SET_H 2 | #define VCTRS_SET_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_set_intersect(r_obj* x, 7 | r_obj* y, 8 | r_obj* ptype, 9 | struct vctrs_arg* x_arg, 10 | struct vctrs_arg* y_arg, 11 | struct r_lazy call); 12 | 13 | r_obj* vec_set_difference(r_obj* x, 14 | r_obj* y, 15 | r_obj* ptype, 16 | struct vctrs_arg* x_arg, 17 | struct vctrs_arg* y_arg, 18 | struct r_lazy call); 19 | 20 | r_obj* vec_set_union(r_obj* x, 21 | r_obj* y, 22 | r_obj* ptype, 23 | struct vctrs_arg* x_arg, 24 | struct vctrs_arg* y_arg, 25 | struct r_lazy call); 26 | 27 | r_obj* vec_set_symmetric_difference(r_obj* x, 28 | r_obj* y, 29 | r_obj* ptype, 30 | struct vctrs_arg* x_arg, 31 | struct vctrs_arg* y_arg, 32 | struct r_lazy call); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/shape.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_SHAPE_H 2 | #define VCTRS_SHAPE_H 3 | 4 | #include "vctrs-core.h" 5 | #include "cast.h" 6 | 7 | 8 | SEXP vec_shaped_ptype(SEXP ptype, 9 | SEXP x, SEXP y, 10 | struct vctrs_arg* p_x_arg, struct vctrs_arg* p_y_arg); 11 | 12 | r_obj* vec_shape_broadcast(r_obj* out, const struct cast_opts* p_opts); 13 | 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /src/size.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_SIZE_H 2 | #define VCTRS_SIZE_H 3 | 4 | #include "vctrs-core.h" 5 | #include "globals.h" 6 | 7 | r_ssize vec_size(r_obj* x); 8 | r_ssize vec_size_3(r_obj* x, struct vctrs_arg* p_arg, struct r_lazy call); 9 | 10 | r_obj* vec_check_recycle(r_obj* x, 11 | r_ssize size, 12 | struct vctrs_arg* x_arg, 13 | struct r_lazy call); 14 | 15 | static inline 16 | r_obj* vec_recycle(r_obj* x, 17 | r_ssize size) { 18 | return vec_check_recycle(x, size, vec_args.x, lazy_calls.vec_recycle); 19 | } 20 | 21 | r_obj* vec_recycle_fallback(r_obj* x, 22 | r_ssize size, 23 | struct vctrs_arg* x_arg, 24 | struct r_lazy call); 25 | 26 | r_obj* list_sizes(r_obj* x, const struct vec_error_opts* opts); 27 | 28 | r_ssize df_size(r_obj* x); 29 | r_ssize df_raw_size(r_obj* x); 30 | r_ssize df_rownames_size(r_obj* x); 31 | r_ssize df_raw_size_from_list(r_obj* x); 32 | 33 | r_ssize vec_as_short_length(r_obj* size, 34 | struct vctrs_arg* p_arg, 35 | struct r_lazy call); 36 | 37 | r_ssize vec_as_ssize(r_obj* n, 38 | struct vctrs_arg* arg, 39 | struct r_lazy call); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/slice-chop.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_SLICE_CHOP_H 2 | #define VCTRS_SLICE_CHOP_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | r_obj* vec_chop(r_obj* x, r_obj* indices, r_obj* sizes); 7 | r_obj* vec_chop_unsafe(r_obj*, r_obj* indices, r_obj* sizes); 8 | 9 | r_obj* list_as_locations(r_obj* indices, r_ssize n, r_obj* names); 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/slice-interleave.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | #include "decl/slice-interleave-decl.h" 3 | 4 | // [[ register() ]] 5 | r_obj* ffi_interleave_indices(r_obj* n, r_obj* size) { 6 | r_ssize c_n = r_arg_as_ssize(n, "n"); 7 | r_ssize c_size = r_arg_as_ssize(size, "size"); 8 | return vec_interleave_indices(c_n, c_size); 9 | } 10 | 11 | static 12 | r_obj* vec_interleave_indices(r_ssize n, r_ssize size) { 13 | if (n < 0) { 14 | r_stop_internal( 15 | "`n` must be greater than or equal to 0." 16 | ); 17 | } 18 | 19 | if (size < 0) { 20 | r_stop_internal( 21 | "`size` must be greater than or equal to 0." 22 | ); 23 | } 24 | 25 | const r_ssize total_size = r_ssize_mult(n, size); 26 | 27 | if (total_size > R_LEN_T_MAX) { 28 | r_abort( 29 | "Long vectors are not yet supported in `vec_interleave()`. " 30 | "Result from interleaving would have size %td, which is larger " 31 | "than the maximum supported size of 2^31 - 1.", 32 | total_size 33 | ); 34 | } 35 | 36 | r_obj* out = KEEP(r_alloc_list(n)); 37 | 38 | for (r_ssize i = 0; i < n; ++i) { 39 | const r_ssize start = i + 1; 40 | 41 | r_obj* elt = r_alloc_integer(size); 42 | r_list_poke(out, i, elt); 43 | int* v_elt = r_int_begin(elt); 44 | 45 | for (r_ssize j = 0; j < size; ++j) { 46 | v_elt[j] = start + n * j; 47 | } 48 | } 49 | 50 | FREE(1); 51 | return out; 52 | } 53 | -------------------------------------------------------------------------------- /src/slice.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_SLICE_H 2 | #define VCTRS_SLICE_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | struct vec_slice_opts { 7 | struct vctrs_arg* x_arg; 8 | struct vctrs_arg* i_arg; 9 | struct r_lazy call; 10 | }; 11 | 12 | enum vctrs_materialize { 13 | VCTRS_MATERIALIZE_false = 0, 14 | VCTRS_MATERIALIZE_true 15 | }; 16 | 17 | r_obj* vec_slice_opts(r_obj* x, 18 | r_obj* i, 19 | const struct vec_slice_opts* opts); 20 | 21 | static inline 22 | r_obj* vec_slice(r_obj* x, r_obj* i) { 23 | const struct vec_slice_opts opts = { 0 }; 24 | return vec_slice_opts(x, i, &opts); 25 | } 26 | 27 | r_obj* vec_init(r_obj* x, r_ssize n); 28 | 29 | r_obj* vec_slice_unsafe(r_obj* x, r_obj* i); 30 | 31 | r_obj* vec_slice_base(enum vctrs_type type, 32 | r_obj* x, 33 | r_obj* subscript, 34 | enum vctrs_materialize materialize); 35 | 36 | r_obj* slice_names(r_obj* names, r_obj* subscript); 37 | r_obj* slice_rownames(r_obj* names, r_obj* subscript); 38 | r_obj* vec_slice_fallback(r_obj* x, r_obj* subscript); 39 | 40 | bool vec_is_restored(r_obj* x, r_obj* to); 41 | 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/split.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | 3 | // [[ register() ]] 4 | SEXP vec_split(SEXP x, SEXP by) { 5 | if (vec_size(x) != vec_size(by)) { 6 | Rf_errorcall(R_NilValue, "`x` and `by` must have the same size."); 7 | } 8 | 9 | SEXP out = PROTECT(vec_group_loc(by)); 10 | 11 | SEXP indices = VECTOR_ELT(out, 1); 12 | 13 | SEXP val = vec_chop_unsafe(x, indices, r_null); 14 | SET_VECTOR_ELT(out, 1, val); 15 | 16 | SEXP names = PROTECT(Rf_getAttrib(out, R_NamesSymbol)); 17 | SET_STRING_ELT(names, 1, strings_val); 18 | Rf_setAttrib(out, R_NamesSymbol, names); 19 | 20 | UNPROTECT(2); 21 | return out; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/subscript-loc.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_SUBSCRIPT_LOC_H 2 | #define VCTRS_SUBSCRIPT_LOC_H 3 | 4 | #include "vctrs-core.h" 5 | #include "utils.h" 6 | #include "subscript.h" 7 | 8 | 9 | enum subscript_missing { 10 | SUBSCRIPT_MISSING_PROPAGATE = 0, 11 | SUBSCRIPT_MISSING_REMOVE, 12 | SUBSCRIPT_MISSING_ERROR 13 | }; 14 | enum num_loc_negative { 15 | LOC_NEGATIVE_INVERT = 0, 16 | LOC_NEGATIVE_ERROR, 17 | LOC_NEGATIVE_IGNORE 18 | }; 19 | enum num_loc_oob { 20 | LOC_OOB_ERROR = 0, 21 | LOC_OOB_REMOVE, 22 | LOC_OOB_EXTEND 23 | }; 24 | enum num_loc_zero { 25 | LOC_ZERO_REMOVE = 0, 26 | LOC_ZERO_ERROR, 27 | LOC_ZERO_IGNORE 28 | }; 29 | 30 | struct location_opts { 31 | struct subscript_opts subscript_opts; 32 | enum num_loc_negative loc_negative; 33 | enum num_loc_oob loc_oob; 34 | enum num_loc_zero loc_zero; 35 | enum subscript_missing missing; 36 | }; 37 | 38 | static inline 39 | struct location_opts new_location_opts_assign(void) { 40 | return (struct location_opts) { 41 | .subscript_opts = new_subscript_opts_assign() 42 | }; 43 | } 44 | 45 | 46 | r_obj* vec_as_location(r_obj* i, 47 | r_ssize n, 48 | r_obj* names); 49 | 50 | r_obj* vec_as_location_ctxt(r_obj* subscript, 51 | r_ssize n, 52 | r_obj* names, 53 | struct vctrs_arg* arg, 54 | struct r_lazy call); 55 | 56 | r_obj* vec_as_location_opts(r_obj* subscript, 57 | r_ssize n, 58 | r_obj* names, 59 | const struct location_opts* location_opts); 60 | 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/translate.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_TRANSLATE_H 2 | #define VCTRS_TRANSLATE_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | // ----------------------------------------------------------------------------- 7 | // Vector translation 8 | 9 | SEXP vec_normalize_encoding(SEXP x); 10 | 11 | // ----------------------------------------------------------------------------- 12 | // Low-level string translation 13 | 14 | #define MASK_ASCII 8 15 | #define MASK_UTF8 64 16 | 17 | // The first 128 values are ASCII, and are the same regardless of the encoding. 18 | // Otherwise we enforce UTF-8. 19 | static inline bool string_is_ascii_or_utf8(SEXP x) { 20 | const int levels = LEVELS(x); 21 | return (levels & MASK_ASCII) || (levels & MASK_UTF8); 22 | } 23 | 24 | #undef MASK_ASCII 25 | #undef MASK_UTF8 26 | 27 | static inline SEXP string_normalize(SEXP x) { 28 | return Rf_mkCharCE(Rf_translateCharUTF8(x), CE_UTF8); 29 | } 30 | 31 | static inline bool string_is_normalized(SEXP x) { 32 | return string_is_ascii_or_utf8(x) || (x == NA_STRING); 33 | } 34 | 35 | // ----------------------------------------------------------------------------- 36 | #endif 37 | -------------------------------------------------------------------------------- /src/type-complex.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_TYPE_COMPLEX_H 2 | #define VCTRS_TYPE_COMPLEX_H 3 | 4 | #include "vctrs.h" 5 | 6 | /* 7 | * Normalises a complex value so that if one side is missing, both are. This 8 | * ensures that all missing complex values are grouped together, no matter 9 | * what type of missingness it is. NA and NaN can still be separated by 10 | * `nan_distinct`, resulting in 4 different combinations of missingness. These 11 | * 4 groups of missingness will still all be grouped together, either before 12 | * or after any non-missing values have appeared. 13 | * See issue #1403 for more information. 14 | */ 15 | static inline 16 | r_complex cpl_normalise_missing(r_complex x) { 17 | const double na = r_globals.na_dbl; 18 | const double nan = R_NaN; 19 | 20 | const enum vctrs_dbl r_type = dbl_classify(x.r); 21 | const enum vctrs_dbl i_type = dbl_classify(x.i); 22 | 23 | switch (r_type) { 24 | case VCTRS_DBL_number: 25 | switch (i_type) { 26 | case VCTRS_DBL_number: return x; 27 | case VCTRS_DBL_missing: return (r_complex) { .r = na, .i = na}; 28 | case VCTRS_DBL_nan: return (r_complex) { .r = nan, .i = nan}; 29 | } 30 | case VCTRS_DBL_missing: 31 | switch (i_type) { 32 | case VCTRS_DBL_number: return (r_complex) { .r = na, .i = na}; 33 | case VCTRS_DBL_missing: return x; 34 | case VCTRS_DBL_nan: return x; 35 | } 36 | case VCTRS_DBL_nan: 37 | switch (i_type) { 38 | case VCTRS_DBL_number: return (r_complex) { .r = nan, .i = nan}; 39 | case VCTRS_DBL_missing: return x; 40 | case VCTRS_DBL_nan: return x; 41 | } 42 | } 43 | 44 | never_reached("cpl_normalise_missing"); 45 | } 46 | 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/type-factor.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_TYPE_FACTOR_H 2 | #define VCTRS_TYPE_FACTOR_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | SEXP fct_ptype2(const struct ptype2_opts* opts); 7 | SEXP ord_ptype2(const struct ptype2_opts* opts); 8 | SEXP ord_as_ordered(const struct cast_opts* opts); 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/type-tibble.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | #include "type-data-frame.h" 3 | 4 | // [[ include("vctrs.h") ]] 5 | SEXP tib_ptype2(const struct ptype2_opts* opts) { 6 | SEXP out = PROTECT(df_ptype2(opts)); 7 | 8 | Rf_setAttrib(out, R_ClassSymbol, classes_tibble); 9 | 10 | UNPROTECT(1); 11 | return out; 12 | } 13 | 14 | // [[ register() ]] 15 | r_obj* ffi_tib_ptype2(r_obj* x, 16 | r_obj* y, 17 | r_obj* ffi_x_arg_, 18 | r_obj* ffi_y_arg_, 19 | r_obj* frame) { 20 | struct vctrs_arg x_arg = vec_as_arg(ffi_x_arg_); 21 | struct vctrs_arg y_arg = vec_as_arg(ffi_y_arg_); 22 | 23 | const struct ptype2_opts opts = { 24 | .x = x, 25 | .y = y, 26 | .p_x_arg = &x_arg, 27 | .p_y_arg = &y_arg, 28 | .call = { .x = r_syms.call, .env = frame } 29 | }; 30 | 31 | return tib_ptype2(&opts); 32 | } 33 | 34 | // [[ include("type-tibble.h") ]] 35 | SEXP tib_cast(const struct cast_opts* opts) { 36 | SEXP out = PROTECT(df_cast_opts(opts)); 37 | 38 | Rf_setAttrib(out, R_ClassSymbol, classes_tibble); 39 | 40 | UNPROTECT(1); 41 | return out; 42 | } 43 | 44 | // [[ register() ]] 45 | r_obj* ffi_tib_cast(r_obj* x, 46 | r_obj* to, 47 | r_obj* ffi_x_arg, 48 | r_obj* ffi_to_arg, 49 | r_obj* frame) { 50 | struct vctrs_arg x_arg = vec_as_arg(ffi_x_arg); 51 | struct vctrs_arg to_arg = vec_as_arg(ffi_to_arg); 52 | 53 | const struct cast_opts opts = { 54 | .x = x, 55 | .to = to, 56 | .p_x_arg = &x_arg, 57 | .p_to_arg = &to_arg, 58 | .call = { .x = r_syms.call, .env = frame } 59 | }; 60 | 61 | return tib_cast(&opts); 62 | } 63 | -------------------------------------------------------------------------------- /src/type-tibble.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_TYPE_TIBBLE_H 2 | #define VCTRS_TYPE_TIBBLE_H 3 | 4 | #include "vctrs-core.h" 5 | #include "ptype2.h" 6 | 7 | 8 | SEXP tib_ptype2(const struct ptype2_opts* opts); 9 | SEXP tib_cast(const struct cast_opts* opts); 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /src/utils-dispatch.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_UTILS_DISPATCH_H 2 | #define VCTRS_UTILS_DISPATCH_H 3 | 4 | #include "vctrs-core.h" 5 | 6 | enum vctrs_class_type { 7 | VCTRS_CLASS_list, 8 | VCTRS_CLASS_data_frame, 9 | VCTRS_CLASS_bare_asis, 10 | VCTRS_CLASS_bare_data_frame, 11 | VCTRS_CLASS_bare_tibble, 12 | VCTRS_CLASS_bare_factor, 13 | VCTRS_CLASS_bare_ordered, 14 | VCTRS_CLASS_bare_date, 15 | VCTRS_CLASS_bare_posixct, 16 | VCTRS_CLASS_bare_posixlt, 17 | VCTRS_CLASS_unknown, 18 | VCTRS_CLASS_none 19 | }; 20 | 21 | enum vctrs_class_type class_type(r_obj* x); 22 | 23 | static inline 24 | bool class_type_is_data_frame(enum vctrs_class_type type) { 25 | switch (type) { 26 | case VCTRS_CLASS_data_frame: 27 | case VCTRS_CLASS_bare_data_frame: 28 | case VCTRS_CLASS_bare_tibble: 29 | return true; 30 | default: 31 | return false; 32 | } 33 | } 34 | 35 | bool vec_is_partial(r_obj* x); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/vctrs-core.c: -------------------------------------------------------------------------------- 1 | #include "vctrs.h" 2 | 3 | enum vctrs_dbl dbl_classify(double x) { 4 | if (!isnan(x)) { 5 | return VCTRS_DBL_number; 6 | } 7 | 8 | union vctrs_dbl_indicator indicator; 9 | indicator.value = x; 10 | 11 | if (indicator.key[vctrs_indicator_pos] == 1954) { 12 | return VCTRS_DBL_missing; 13 | } else { 14 | return VCTRS_DBL_nan; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/vec-bool.h: -------------------------------------------------------------------------------- 1 | #ifndef VCTRS_VEC_BOOL_H 2 | #define VCTRS_VEC_BOOL_H 3 | 4 | #include 5 | 6 | struct r_vector_bool { 7 | r_obj* shelter; 8 | 9 | r_obj* data; 10 | bool* v_data; 11 | 12 | r_ssize n; 13 | }; 14 | 15 | static inline 16 | struct r_vector_bool* r_new_vector_bool(r_ssize n) { 17 | r_obj* shelter = KEEP(r_alloc_list(2)); 18 | 19 | r_obj* vec = r_alloc_raw(sizeof(struct r_vector_bool)); 20 | r_list_poke(shelter, 0, vec); 21 | 22 | r_obj* data = r_alloc_raw(n * sizeof(bool)); 23 | r_list_poke(shelter, 1, data); 24 | 25 | struct r_vector_bool* p_vec = r_raw_begin(vec); 26 | p_vec->shelter = shelter; 27 | p_vec->data = data; 28 | p_vec->v_data = r_raw_begin(data); 29 | p_vec->n = n; 30 | 31 | FREE(1); 32 | return p_vec; 33 | } 34 | 35 | static inline 36 | bool* r_vector_bool_begin(struct r_vector_bool* p_vec) { 37 | return p_vec->v_data; 38 | } 39 | static inline 40 | const bool* r_vector_bool_cbegin(struct r_vector_bool* p_vec) { 41 | return (const bool*) p_vec->v_data; 42 | } 43 | 44 | static inline 45 | r_ssize r_vector_bool_length(struct r_vector_bool* p_vec) { 46 | return p_vec->n; 47 | } 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/version.c: -------------------------------------------------------------------------------- 1 | #define R_NO_REMAP 2 | #include 3 | 4 | const char* vctrs_version = "0.6.5.9000"; 5 | 6 | /** 7 | * This file records the expected package version in the shared 8 | * library (or DLL) of the package. This is useful to check that users 9 | * have properly installed your package. Installation issues where the 10 | * package is updated but the DLL isn't are common on Windows in 11 | * particular. To automatically check that the native library of the 12 | * package was properly installed: 13 | * 14 | * - Register the function below as a C callable under the name 15 | * "vctrs_linked_version". 16 | * 17 | * - Call `rlang::check_linked_version(pkg_name)` from your 18 | * `.onLoad()` hook. If you don't depend on rlang copy the 19 | * compat-linked-version.R file from the rlang repository to your R 20 | * folder. Find it at 21 | * 22 | */ 23 | 24 | // [[ register() ]] 25 | SEXP vctrs_linked_version(void) { 26 | return Rf_mkString(vctrs_version); 27 | } 28 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(vctrs) 3 | 4 | test_check("vctrs") 5 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/compare.md: -------------------------------------------------------------------------------- 1 | # error is thrown when comparing complexes (#1655) 2 | 3 | Code 4 | (expect_error(vec_compare(complex(), complex()))) 5 | Output 6 | 7 | Error in `vec_compare()`: 8 | ! Can't compare complexes. 9 | 10 | # `na_equal` is validated 11 | 12 | Code 13 | (expect_error(vec_compare(1, 1, na_equal = 1))) 14 | Output 15 | 16 | Error in `vec_compare()`: 17 | ! `na_equal` must be `TRUE` or `FALSE`, not the number 1. 18 | Code 19 | (expect_error(vec_compare(1, 1, na_equal = c(TRUE, FALSE)))) 20 | Output 21 | 22 | Error in `vec_compare()`: 23 | ! `na_equal` must be `TRUE` or `FALSE`, not a logical vector. 24 | 25 | # can't supply NA as `na_equal` 26 | 27 | Code 28 | vec_compare(NA, NA, na_equal = NA) 29 | Condition 30 | Error in `vec_compare()`: 31 | ! `na_equal` must be `TRUE` or `FALSE`, not `NA`. 32 | 33 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/complete.md: -------------------------------------------------------------------------------- 1 | # catches `NULL` data frame columns 2 | 3 | Code 4 | vec_detect_complete(df) 5 | Condition 6 | Error in `vec_detect_complete()`: 7 | ! Unexpected `NULL` column found in a data frame. 8 | 9 | # catches scalar objects 10 | 11 | Code 12 | vec_detect_complete(lm(1 ~ 1)) 13 | Condition 14 | Error in `vec_size()`: 15 | ! `x` must be a vector, not a object. 16 | 17 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/dictionary.md: -------------------------------------------------------------------------------- 1 | # vec_match() and vec_in() check types 2 | 3 | Code 4 | df1 <- data_frame(x = data_frame(foo = 1)) 5 | df2 <- data_frame(x = data_frame(foo = "")) 6 | (expect_error(vec_match(df1, df2), class = "vctrs_error_incompatible_type")) 7 | Output 8 | 9 | Error in `vec_match()`: 10 | ! Can't combine `x$foo` and `x$foo` . 11 | Code 12 | (expect_error(vec_match(df1, df2, needles_arg = "n", haystack_arg = "h"), 13 | class = "vctrs_error_incompatible_type")) 14 | Output 15 | 16 | Error in `vec_match()`: 17 | ! Can't combine `n$x$foo` and `h$x$foo` . 18 | Code 19 | (expect_error(vec_in(df1, df2), class = "vctrs_error_incompatible_type")) 20 | Output 21 | 22 | Error in `vec_in()`: 23 | ! Can't combine `x$foo` and `x$foo` . 24 | Code 25 | (expect_error(vec_in(df1, df2, needles_arg = "n", haystack_arg = "h"), class = "vctrs_error_incompatible_type") 26 | ) 27 | Output 28 | 29 | Error in `vec_in()`: 30 | ! Can't combine `n$x$foo` and `h$x$foo` . 31 | 32 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/equal.md: -------------------------------------------------------------------------------- 1 | # `na_equal` is validated 2 | 3 | Code 4 | vec_equal(1, 1, na_equal = 1) 5 | Condition 6 | Error in `vec_equal()`: 7 | ! `na_equal` must be `TRUE` or `FALSE`, not the number 1. 8 | 9 | --- 10 | 11 | Code 12 | vec_equal(1, 1, na_equal = c(TRUE, FALSE)) 13 | Condition 14 | Error in `vec_equal()`: 15 | ! `na_equal` must be `TRUE` or `FALSE`, not a logical vector. 16 | 17 | # can't supply NA as `na_equal` 18 | 19 | Code 20 | vec_equal(NA, NA, na_equal = NA) 21 | Condition 22 | Error in `vec_equal()`: 23 | ! `na_equal` must be `TRUE` or `FALSE`, not `NA`. 24 | 25 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/group.md: -------------------------------------------------------------------------------- 1 | # print method is useful 2 | 3 | Code 4 | x 5 | Output 6 | 7 | [1] 1x3 2x2 1x1 8 | 9 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/lifecycle-deprecated.md: -------------------------------------------------------------------------------- 1 | # vec_unchop() is soft-deprecated 2 | 3 | Code 4 | vec_unchop(list(1), indices = list(1)) 5 | Condition 6 | Warning: 7 | `vec_unchop()` was deprecated in vctrs 0.5.0. 8 | i Please use `list_unchop()` instead. 9 | Output 10 | [1] 1 11 | 12 | # vec_equal_na() is soft-deprecated 13 | 14 | Code 15 | vec_equal_na(c(1, NA)) 16 | Condition 17 | Warning: 18 | `vec_equal_na()` was deprecated in vctrs 0.5.0. 19 | i Please use `vec_detect_missing()` instead. 20 | Output 21 | [1] FALSE TRUE 22 | 23 | # vec_check_list() still works 24 | 25 | Code 26 | vec_check_list(1) 27 | Condition 28 | Error: 29 | ! `1` must be a list, not the number 1. 30 | 31 | --- 32 | 33 | Code 34 | my_check(1) 35 | Condition 36 | Error in `my_check()`: 37 | ! `x` must be a list, not the number 1. 38 | 39 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/order.md: -------------------------------------------------------------------------------- 1 | # `direction` is recycled right with array columns (#1753) 2 | 3 | Code 4 | vec_order_radix(df, direction = c("asc", "desc", "desc")) 5 | Condition 6 | Error: 7 | ! `direction` should have length 1 or length equal to the number of columns of `x` when `x` is a data frame. 8 | 9 | # `na_value` is recycled right with array columns (#1753) 10 | 11 | Code 12 | vec_order_radix(df, direction = c("smallest", "largest", "largest")) 13 | Condition 14 | Error: 15 | ! `direction` must contain only "asc" or "desc". 16 | 17 | # dots must be empty (#1647) 18 | 19 | Code 20 | vec_order(1, 2) 21 | Condition 22 | Error in `vec_order()`: 23 | ! `...` must be empty. 24 | x Problematic argument: 25 | * ..1 = 2 26 | i Did you forget to name an argument? 27 | 28 | --- 29 | 30 | Code 31 | vec_sort(1, 2) 32 | Condition 33 | Error in `vec_sort()`: 34 | ! `...` must be empty. 35 | x Problematic argument: 36 | * ..1 = 2 37 | i Did you forget to name an argument? 38 | 39 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/partial-factor.md: -------------------------------------------------------------------------------- 1 | # has ok print method 2 | 3 | Code 4 | partial 5 | Output 6 | partial_factor< 7 | bf275 {partial} 8 | > 9 | 10 | --- 11 | 12 | Code 13 | both 14 | Output 15 | partial_factor< 16 | bf275 {partial} 17 | fd1ad 18 | > 19 | 20 | --- 21 | 22 | Code 23 | empty 24 | Output 25 | partial_factor< 26 | 27 | > 28 | 29 | --- 30 | 31 | Code 32 | learned 33 | Output 34 | partial_factor< 35 | fd1ad 36 | > 37 | 38 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/partial-frame.md: -------------------------------------------------------------------------------- 1 | # has ok print method 2 | 3 | Code 4 | pf 5 | Output 6 | partial_frame< 7 | x: integer {partial} 8 | y: double 9 | > 10 | 11 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/print-str.md: -------------------------------------------------------------------------------- 1 | # show attributes 2 | 3 | Code 4 | obj_str(x) 5 | Output 6 | int [1:100] 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16... 7 | @ x: chr "a string" 8 | @ y: int [1:20] 1 2 3 4 5 6 7 8 9 10 ... 9 | @ z:'data.frame': 3 obs. of 1 variable: 10 | ..$ x: int [1:3] 1 2 3 11 | 12 | --- 13 | 14 | Code 15 | obj_str(mtcars) 16 | Output 17 | df[,11] [1:32] 18 | 'data.frame': 32 obs. of 11 variables: 19 | $ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ... 20 | $ cyl : num 6 6 4 6 8 6 8 4 4 6 ... 21 | $ disp: num 160 160 108 258 360 ... 22 | $ hp : num 110 110 93 110 175 105 245 62 95 123 ... 23 | $ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ... 24 | $ wt : num 2.62 2.88 2.32 3.21 3.44 ... 25 | $ qsec: num 16.5 17 18.6 19.4 17 ... 26 | $ vs : num 0 0 1 1 0 1 0 1 1 1 ... 27 | $ am : num 1 1 1 0 0 0 0 0 0 0 ... 28 | $ gear: num 4 4 4 3 3 3 3 4 4 4 ... 29 | $ carb: num 4 4 1 1 2 1 4 2 2 4 ... 30 | @ row.names: chr [1:32] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ... 31 | 32 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/ptype-abbr-full.md: -------------------------------------------------------------------------------- 1 | # data.frames have good default abbr and full methods 2 | 3 | Code 4 | df <- foobar(data.frame(x = 1, y = "", z = TRUE)) 5 | vec_ptype_abbr(df) 6 | Output 7 | [1] "vctrs_fb[,3]" 8 | Code 9 | vec_ptype_full(df) 10 | Output 11 | [1] "vctrs_foobar<\n x: double\n y: character\n z: logical\n>" 12 | 13 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/rank.md: -------------------------------------------------------------------------------- 1 | # `x` must not be `NULL` (#1823) 2 | 3 | Code 4 | vec_rank(NULL) 5 | Condition 6 | Error: 7 | ! This type is not supported by `vec_order()`. 8 | 9 | --- 10 | 11 | Code 12 | vec_rank(NULL, incomplete = "na") 13 | Condition 14 | Error: 15 | ! This type is not supported by `vec_order()`. 16 | 17 | # `ties` is validated 18 | 19 | Code 20 | vec_rank(1, ties = "foo") 21 | Condition 22 | Error in `vec_rank()`: 23 | ! `ties` must be one of "min", "max", "sequential", or "dense", not "foo". 24 | 25 | --- 26 | 27 | Code 28 | vec_rank(1, ties = 1) 29 | Condition 30 | Error in `vec_rank()`: 31 | ! `ties` must be a string or character vector. 32 | 33 | # `incomplete` is validated 34 | 35 | Code 36 | vec_rank(1, incomplete = NA) 37 | Condition 38 | Error in `vec_rank()`: 39 | ! `incomplete` must be a string or character vector. 40 | 41 | --- 42 | 43 | Code 44 | vec_rank(1, incomplete = c(TRUE, FALSE)) 45 | Condition 46 | Error in `vec_rank()`: 47 | ! `incomplete` must be a string or character vector. 48 | 49 | --- 50 | 51 | Code 52 | vec_rank(1, incomplete = "foo") 53 | Condition 54 | Error in `vec_rank()`: 55 | ! `incomplete` must be one of "rank" or "na", not "foo". 56 | 57 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/shape.md: -------------------------------------------------------------------------------- 1 | # incompatible shapes throw errors 2 | 3 | Code 4 | (expect_error(vec_shape2(shaped_int(1, 0, 5), shaped_int(1, 5, 1)), class = "vctrs_error_incompatible_type") 5 | ) 6 | Output 7 | 8 | Error: 9 | ! Can't combine and . 10 | x Incompatible sizes 0 and 5 along axis 2. 11 | Code 12 | (expect_error(vec_shape2(shaped_int(1, 5, 0), shaped_int(1, 1, 5)), class = "vctrs_error_incompatible_type") 13 | ) 14 | Output 15 | 16 | Error: 17 | ! Can't combine and . 18 | x Incompatible sizes 0 and 5 along axis 3. 19 | 20 | # can override error args 21 | 22 | Code 23 | (expect_error(vec_shape2(shaped_int(1, 0, 5), shaped_int(1, 5, 1), x_arg = "foo", 24 | y_arg = "bar"), class = "vctrs_error_incompatible_type")) 25 | Output 26 | 27 | Error: 28 | ! Can't combine `foo` and `bar` . 29 | x Incompatible sizes 0 and 5 along axis 2. 30 | 31 | # can combine shaped native classes (#1290, #1329) 32 | 33 | Code 34 | vec_c(x, y) 35 | Condition 36 | Error: 37 | ! Can't combine `..1` > and `..2` >. 38 | x Incompatible sizes 2 and 3 along axis 2. 39 | 40 | # factor casts support shape 41 | 42 | Code 43 | vec_cast(x, y) 44 | Condition 45 | Error: 46 | ! Can't convert `x` [,1]> to >. 47 | Can't decrease dimensionality from 2 to 1. 48 | 49 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/slice-interleave.md: -------------------------------------------------------------------------------- 1 | # allows for name repair 2 | 3 | Code 4 | vec_interleave(x, x, .name_repair = "unique") 5 | Message 6 | New names: 7 | * `x` -> `x...1` 8 | * `x` -> `x...2` 9 | Output 10 | x...1 x...2 11 | 1 1 12 | 13 | # can repair names quietly 14 | 15 | Code 16 | res_unique <- vec_interleave(c(x = 1), c(x = 2), .name_repair = "unique_quiet") 17 | res_universal <- vec_interleave(c(`if` = 1), c(`in` = 2), .name_repair = "universal_quiet") 18 | 19 | # uses recycling errors 20 | 21 | Code 22 | vec_interleave(1:2, 1:3) 23 | Condition 24 | Error in `vec_interleave()`: 25 | ! Can't recycle `..1` (size 2) to match `..2` (size 3). 26 | 27 | # errors if the result would be a long vector 28 | 29 | Code 30 | vec_interleave_indices(3L, 1000000000L) 31 | Condition 32 | Error in `vec_interleave_indices()`: 33 | ! Long vectors are not yet supported in `vec_interleave()`. Result from interleaving would have size 3000000000, which is larger than the maximum supported size of 2^31 - 1. 34 | 35 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-asis.md: -------------------------------------------------------------------------------- 1 | # AsIs objects throw ptype2 errors with their underlying types 2 | 3 | Code 4 | (expect_error(vec_ptype2(I(1), I("x")), class = "vctrs_error_incompatible_type") 5 | ) 6 | Output 7 | 8 | Error: 9 | ! Can't combine `I(1)` and `I("x")` . 10 | 11 | # AsIs objects throw cast errors with their underlying types 12 | 13 | Code 14 | (expect_error(vec_cast(I(1), I(factor("x"))), class = "vctrs_error_incompatible_type") 15 | ) 16 | Output 17 | 18 | Error: 19 | ! Can't convert `I(1)` to >. 20 | 21 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-data-table.md: -------------------------------------------------------------------------------- 1 | # data table has formatting methods 2 | 3 | Code 4 | dt <- data.table(x = 1, y = 2, z = 3) 5 | vec_ptype_abbr(dt) 6 | Output 7 | [1] "dt[,3]" 8 | Code 9 | vec_ptype_full(dt) 10 | Output 11 | [1] "data.table<\n x: double\n y: double\n z: double\n>" 12 | 13 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-date-time.md: -------------------------------------------------------------------------------- 1 | # datetime coercions are symmetric and unchanging 2 | 3 | Code 4 | print(mat) 5 | Output 6 | date datetime datetime POSIXlt duration duration 7 | date "date" "datetime" "datetime" "datetime" NA NA 8 | datetime "datetime" "datetime" "datetime" "datetime" NA NA 9 | datetime "datetime" "datetime" "datetime" "datetime" NA NA 10 | POSIXlt "datetime" "datetime" "datetime" "datetime" NA NA 11 | duration NA NA NA NA "duration" "duration" 12 | duration NA NA NA NA "duration" "duration" 13 | 14 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-factor.md: -------------------------------------------------------------------------------- 1 | # factor/character coercions are symmetric and unchanging 2 | 3 | Code 4 | print(mat) 5 | Output 6 | ordered<> factor<> character 7 | ordered<> "ordered<>" NA "character" 8 | factor<> NA "factor<>" "character" 9 | character "character" "character" "character" 10 | 11 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-misc.md: -------------------------------------------------------------------------------- 1 | # `numeric_version` proxy can handle at most 8 components 2 | 3 | Code 4 | vec_proxy_equal(x) 5 | Condition 6 | Error in `vec_proxy_equal()`: 7 | ! `x` can't contain more than 8 version components. 8 | 9 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-sf.md: -------------------------------------------------------------------------------- 1 | # `crs` attributes of `sfc` vectors must be the same 2 | 3 | Code 4 | vctrs::vec_c(x, y) 5 | Condition 6 | Error: 7 | ! arguments have different crs 8 | 9 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-table.md: -------------------------------------------------------------------------------- 1 | # cannot decrease dimensionality 2 | 3 | Code 4 | (expect_error(vec_cast(x, y), class = "vctrs_error_incompatible_type")) 5 | Output 6 | 7 | Error: 8 | ! Can't convert `x` to . 9 | Can't decrease dimensionality from 3 to 2. 10 | 11 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-unspecified.md: -------------------------------------------------------------------------------- 1 | # has useful print method 2 | 3 | Code 4 | unspecified() 5 | Output 6 | [0] 7 | 8 | -------------------------------------------------------------------------------- /tests/testthat/_snaps/type-vctr.md: -------------------------------------------------------------------------------- 1 | # na.fail() works 2 | 3 | Code 4 | na.fail(x) 5 | Condition 6 | Error in `na.fail()`: 7 | ! missing values in object 8 | 9 | # default print and str methods are useful 10 | 11 | Code 12 | h 13 | Output 14 | 15 | [1] xxx xxx xxx xxx 16 | 17 | --- 18 | 19 | Code 20 | h[0] 21 | Output 22 | 23 | 24 | --- 25 | 26 | Code 27 | str(h) 28 | Output 29 | hidden [1:4] xxx, xxx, xxx, xxx 30 | 31 | # default print method shows names 32 | 33 | Code 34 | h 35 | Output 36 | 37 | A B C 38 | xxx xxx xxx 39 | 40 | -------------------------------------------------------------------------------- /tests/testthat/helper-c.R: -------------------------------------------------------------------------------- 1 | class_type <- function(x) { 2 | .Call(ffi_class_type, x) 3 | } 4 | -------------------------------------------------------------------------------- /tests/testthat/helper-cast.R: -------------------------------------------------------------------------------- 1 | 2 | expect_lossy_cast <- function(expr) { 3 | cnd <- NULL 4 | 5 | out <- with_handlers( 6 | warning = calling(function(x) { 7 | cnd <<- x 8 | cnd_muffle(x) 9 | }), 10 | expr 11 | ) 12 | expect_s3_class(cnd, "vctrs_warning_cast_lossy") 13 | 14 | out 15 | } 16 | -------------------------------------------------------------------------------- /tests/testthat/helper-encoding.R: -------------------------------------------------------------------------------- 1 | encodings <- function(bytes = FALSE) { 2 | string <- "\u00B0C" 3 | 4 | utf8 <- iconv(string, from = Encoding(string), to = "UTF-8") 5 | unknown <- iconv(string, from = Encoding(string), to = "", mark = FALSE) 6 | latin1 <- iconv(string, from = Encoding(string), to = "latin1") 7 | 8 | out <- list(utf8 = utf8, unknown = unknown, latin1 = latin1) 9 | 10 | if (bytes) { 11 | out <- list2(!!! out, bytes = encoding_bytes()) 12 | } 13 | 14 | out 15 | } 16 | 17 | encoding_bytes <- function() { 18 | string <- "\u00B0C" 19 | 20 | unknown <- iconv(string, from = Encoding(string), to = "", mark = FALSE) 21 | 22 | bytes <- unknown 23 | Encoding(bytes) <- "bytes" 24 | 25 | bytes 26 | } 27 | 28 | expect_equal_encoding <- function(object, expected) { 29 | args <- vec_recycle_common(object, expected) 30 | expect_equal(Encoding(args[[1L]]), Encoding(args[[2L]])) 31 | } 32 | -------------------------------------------------------------------------------- /tests/testthat/helper-memory.R: -------------------------------------------------------------------------------- 1 | maybe_shared_col <- function(x, i) { 2 | .Call(vctrs_maybe_shared_col, x, i) 3 | } 4 | 5 | new_df_unshared_col <- function() { 6 | .Call(vctrs_new_df_unshared_col) 7 | } 8 | -------------------------------------------------------------------------------- /tests/testthat/helper-names.R: -------------------------------------------------------------------------------- 1 | local_name_repair_quiet <- function(frame = caller_env()) { 2 | local_options(rlib_name_repair_verbosity = "quiet", .frame = frame) 3 | } 4 | local_name_repair_verbose <- function(frame = caller_env()) { 5 | local_options(rlib_name_repair_verbosity = "verbose", .frame = frame) 6 | } 7 | -------------------------------------------------------------------------------- /tests/testthat/helper-order.R: -------------------------------------------------------------------------------- 1 | # Keep in sync with macros in `order.c` 2 | GROUP_DATA_SIZE_DEFAULT <- 100000L 3 | ORDER_INSERTION_BOUNDARY <- 128L 4 | INT_ORDER_COUNTING_RANGE_BOUNDARY <- 100000L 5 | 6 | # Force radix method for character comparisons 7 | base_order <- function(x, na.last = TRUE, decreasing = FALSE) { 8 | if (is.data.frame(x)) { 9 | x <- unname(x) 10 | } else { 11 | x <- list(x) 12 | } 13 | 14 | args <- list(na.last = na.last, decreasing = decreasing) 15 | 16 | # `method` didn't exist on R < 3.3. 17 | # It would sometimes use radix sorting automatically. 18 | if (getRversion() < "3.3.0") { 19 | method <- list() 20 | } else { 21 | method <- list(method = "radix") 22 | } 23 | 24 | args <- c(x, args, method) 25 | 26 | 27 | rlang::exec("order", !!!args) 28 | } 29 | -------------------------------------------------------------------------------- /tests/testthat/helper-performance.R: -------------------------------------------------------------------------------- 1 | skip_if_not_testing_performance <- function(x) { 2 | opt <- Sys.getenv("VCTRS_TEST_PERFORMANCE", unset = "false") 3 | testing <- identical(opt, "true") 4 | 5 | if (testing) { 6 | return() 7 | } 8 | 9 | skip("Not testing performance") 10 | } 11 | 12 | expect_time_lt <- function(expr, expect) { 13 | time <- time_of({{ expr }}) 14 | expect_lt(time, expect) 15 | } 16 | 17 | time_of <- function(expr) { 18 | expr <- enquo(expr) 19 | time <- system.time(eval_tidy(expr)) 20 | unclass(time)[["elapsed"]] 21 | } 22 | 23 | # From r-lib/bench 24 | with_memory_prof <- function(expr) { 25 | f <- tempfile() 26 | on.exit(unlink(f)) 27 | 28 | tryCatch( 29 | utils::Rprofmem(f, threshold = 1), 30 | error = function(...) skip("Can't profile memory on this system.") 31 | ) 32 | on.exit(utils::Rprofmem(NULL), add = TRUE) 33 | 34 | res <- force(expr) 35 | utils::Rprofmem(NULL) 36 | 37 | bytes <- parse_allocations(f)$bytes 38 | bytes <- sum(bytes, na.rm = TRUE) 39 | new_vctrs_bytes(bytes) 40 | } 41 | parse_allocations <- function(filename) { 42 | if (!is_installed("profmem")) { 43 | testthat::skip("profmem must be installed.") 44 | } 45 | readRprofmem <- env_get(ns_env("profmem"), "readRprofmem") 46 | 47 | tryCatch( 48 | readRprofmem(filename), 49 | error = function(cnd) { 50 | testthat::skip(sprintf( 51 | "Memory profiling failed: %s", 52 | conditionMessage(cnd) 53 | )) 54 | } 55 | ) 56 | } 57 | -------------------------------------------------------------------------------- /tests/testthat/helper-shape.R: -------------------------------------------------------------------------------- 1 | 2 | shape_broadcast_ <- function(x, to, x_arg = "x", to_arg = "to") { 3 | shape_broadcast(x, to, x_arg = x_arg, to_arg = to_arg) 4 | } 5 | -------------------------------------------------------------------------------- /tests/testthat/helper-size.R: -------------------------------------------------------------------------------- 1 | 2 | expect_size <- function(object, n) { 3 | expect_identical(vec_size(object), vec_cast(n, int())) 4 | } 5 | -------------------------------------------------------------------------------- /tests/testthat/helper-type-dplyr.R: -------------------------------------------------------------------------------- 1 | 2 | expect_drop <- function(x, value) { 3 | drop <- dplyr::group_by_drop_default(x) 4 | if (value) { 5 | expect_true(drop) 6 | } else { 7 | expect_false(drop) 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /tests/testthat/test-arith.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("logical/integer/numeric works", { 3 | expect_equal(vec_arith("+", TRUE, TRUE), 2L) 4 | expect_equal(vec_arith("+", TRUE, 1L), 2L) 5 | expect_equal(vec_arith("+", TRUE, 1), 2) 6 | expect_equal(vec_arith("+", 1L, TRUE), 2L) 7 | expect_equal(vec_arith("+", 1L, 1L), 2L) 8 | expect_equal(vec_arith("+", 1L, 1), 2) 9 | expect_equal(vec_arith("+", 1, TRUE), 2L) 10 | expect_equal(vec_arith("+", 1, 1L), 2L) 11 | expect_equal(vec_arith("+", 1, 1), 2) 12 | }) 13 | 14 | test_that("default is error", { 15 | f <- new_vctr(1:10, class = "foo") 16 | 17 | expect_error(vec_arith("+", f, 1), class = "vctrs_error_incompatible_op") 18 | 19 | expect_error(vec_arith("+", TRUE, f), class = "vctrs_error_incompatible_op") 20 | expect_error(vec_arith("+", 1L, f), class = "vctrs_error_incompatible_op") 21 | expect_error(vec_arith("+", 1, f), class = "vctrs_error_incompatible_op") 22 | }) 23 | -------------------------------------------------------------------------------- /tests/testthat/test-dim.R: -------------------------------------------------------------------------------- 1 | 2 | # vec_dim ----------------------------------------------------------------- 3 | 4 | test_that("dim is dimensions", { 5 | expect_equal(vec_dim(array(dim = c(1))), c(1)) 6 | expect_equal(vec_dim(array(dim = c(1, 1))), c(1, 1)) 7 | expect_equal(vec_dim(array(dim = c(1, 1, 1))), c(1, 1, 1)) 8 | }) 9 | 10 | 11 | test_that("dim_n is number of dimensions", { 12 | expect_equal(vec_dim_n(array(dim = c(1))), 1) 13 | expect_equal(vec_dim_n(array(dim = c(1, 1))), 2) 14 | expect_equal(vec_dim_n(array(dim = c(1, 1, 1))), 3) 15 | }) 16 | 17 | test_that("vector and 1-d array are equivalent", { 18 | x1 <- 1:5 19 | x2 <- array(x1) 20 | 21 | expect_equal(vec_dim(x1), 5) 22 | expect_equal(vec_dim(x2), 5) 23 | 24 | expect_equal(vec_size(x1), 5) 25 | expect_equal(vec_size(x2), 5) 26 | }) 27 | -------------------------------------------------------------------------------- /tests/testthat/test-empty.R: -------------------------------------------------------------------------------- 1 | test_that("can compact missing elements", { 2 | x <- list(NULL, 1, NULL) 3 | expect_identical(list_drop_empty(x), list(1)) 4 | }) 5 | 6 | test_that("can compact empty elements", { 7 | x <- list(1, NULL, integer(), NULL) 8 | expect_identical(list_drop_empty(x), list(1)) 9 | }) 10 | 11 | test_that("emptyness works with data frames", { 12 | x <- data_frame() 13 | y <- data_frame(.size = 2L) 14 | 15 | lst <- list(x, y) 16 | 17 | expect_identical(list_drop_empty(lst), list(y)) 18 | }) 19 | 20 | test_that("emptyness works with rcrd types", { 21 | x <- new_rcrd(list(foo = integer(), bar = numeric())) 22 | y <- new_rcrd(list(foo = 1L, bar = 1)) 23 | 24 | lst <- list(x, y) 25 | 26 | expect_identical(list_drop_empty(lst), list(y)) 27 | }) 28 | 29 | test_that("works with empty lists", { 30 | expect_identical(list_drop_empty(list()), list()) 31 | }) 32 | 33 | test_that("retains list type", { 34 | x <- list_of(NULL, integer()) 35 | expect_identical(list_drop_empty(x), list_of(.ptype = integer())) 36 | }) 37 | 38 | test_that("validates `x`", { 39 | expect_error(list_drop_empty(1), "must be a list") 40 | expect_error(list_drop_empty(data_frame()), "must be a list") 41 | }) 42 | -------------------------------------------------------------------------------- /tests/testthat/test-partial-factor.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("has ok print method", { 3 | partial <- partial_factor("x") 4 | expect_snapshot(partial) 5 | 6 | both <- vec_ptype2(partial, factor("y")) 7 | expect_snapshot(both) 8 | 9 | empty <- partial_factor() 10 | expect_snapshot(empty) 11 | 12 | learned <- vec_ptype2(empty, factor("y")) 13 | expect_snapshot(learned) 14 | 15 | expect_equal(vec_ptype_abbr(partial), "prtl_fctr") 16 | }) 17 | 18 | test_that("order of levels comes from data", { 19 | pfctr <- partial_factor(c("y", "x")) 20 | fctr <- factor(levels = c("x", "y")) 21 | 22 | expect_equal(levels(vec_ptype_common(pfctr, fctr)), c("x", "y")) 23 | expect_equal(levels(vec_ptype_common(fctr, pfctr)), c("x", "y")) 24 | }) 25 | 26 | test_that("partial levels added to end if not in data", { 27 | pfctr <- partial_factor("y") 28 | fctr <- factor(levels = "x") 29 | 30 | expect_equal(levels(vec_ptype_common(pfctr, fctr)), c("x", "y")) 31 | expect_equal(levels(vec_ptype_common(fctr, pfctr)), c("x", "y")) 32 | }) 33 | 34 | test_that("can assert partial factors based on level presence", { 35 | pfctr <- partial_factor("y") 36 | 37 | expect_true(vec_is(factor("y"), pfctr)) 38 | expect_false(vec_is(factor("x"), pfctr)) 39 | 40 | expect_true(vec_is(factor(c("x", "y")), pfctr)) 41 | 42 | pfctr <- partial_factor(c("y", "z")) 43 | 44 | expect_false(vec_is(factor("y"), pfctr)) 45 | expect_true(vec_is(factor(c("y", "z")), pfctr)) 46 | expect_true(vec_is(factor(c("x", "y", "z")), pfctr)) 47 | }) 48 | 49 | # TODO - why is this not working? 50 | # test_that("can assert partial factor based on factor type", { 51 | # pfctr <- partial_factor() 52 | # expect_false(vec_is(1, pfctr)) 53 | # }) 54 | -------------------------------------------------------------------------------- /tests/testthat/test-print-str.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("show attributes", { 3 | x <- structure(1:100, x = "a string", y = 1:20, z = data.frame(x = 1:3)) 4 | expect_snapshot(obj_str(x)) 5 | 6 | expect_snapshot(obj_str(mtcars)) 7 | }) 8 | -------------------------------------------------------------------------------- /tests/testthat/test-split.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("can split empty vector", { 3 | out <- vec_split(integer(), character()) 4 | 5 | expect_s3_class(out, "data.frame") 6 | expect_equal(out$key, character()) 7 | expect_equal(out$val, list()) 8 | }) 9 | 10 | test_that("split data frame with data frame", { 11 | df <- data.frame(x = c(1, 1, 2), y = c(1, 1, 1)) 12 | out <- vec_split(df, df) 13 | 14 | expect_s3_class(out, "data.frame") 15 | expect_equal(out$key, data.frame(x = c(1, 2), y = c(1, 1))) 16 | expect_equal(out$val, list( 17 | data.frame(x = c(1, 1), y = c(1, 1)), 18 | data.frame(x = 2, y = 1) 19 | )) 20 | }) 21 | 22 | test_that("x and by must be same size", { 23 | expect_error( 24 | vec_split(1:3, 1:2), 25 | "same size" 26 | ) 27 | }) 28 | 29 | test_that("split takes the equality proxy (#375)", { 30 | local_comparable_tuple() 31 | x <- tuple(c(1, 2, 1), 1:3) 32 | expect_identical(nrow(vec_split(1:3, x)), 2L) 33 | }) 34 | 35 | test_that("split works with different encodings", { 36 | encs <- encodings() 37 | expect_identical(nrow(vec_split(1:3, encs)), 1L) 38 | }) 39 | 40 | test_that("`key` and `value` retain names", { 41 | x <- c(a = 1, b = 2, c = 1, a = 1) 42 | split <- vec_split(x, x) 43 | expect_identical(split$key, c(a = 1, b = 2)) 44 | expect_identical(split$val[[1]], c(a = 1, c = 1, a = 1)) 45 | expect_identical(split$val[[2]], c(b = 2)) 46 | }) 47 | 48 | -------------------------------------------------------------------------------- /tests/testthat/test-type-rational.R: -------------------------------------------------------------------------------- 1 | 2 | # These tests check the rational type from the S3 vignette 3 | 4 | test_that("equality proxy is taken (#375)", { 5 | local_rational_class() 6 | x <- rational(c(1, 2, 1, 2, 6), c(1, 1, 2, 2, 2)) 7 | 8 | expect_identical(x == rational(3, 1), c(FALSE, FALSE, FALSE, FALSE, TRUE)) 9 | 10 | expect_identical(unique(x), rational(c(1, 2, 1, 6), c(1, 1, 2, 2))) 11 | }) 12 | 13 | test_that("order proxy is taken", { 14 | local_rational_class() 15 | x <- rational(c(1, 2, 1, 2, 6), c(1, 1, 2, 2, 2)) 16 | expect_identical(sort(x), rational(c(1, 1, 2, 2, 6), c(2, 1, 2, 1, 2))) 17 | }) 18 | 19 | test_that("can find common type and cast to rational", { 20 | local_rational_class() 21 | x <- rational(1:2, 2:1) 22 | expect_identical(vec_cast_common(x, x), list(x, x)) 23 | }) 24 | -------------------------------------------------------------------------------- /tests/testthat/test-vctrs.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("generics are extensible", { 3 | expect_error(vec_cast(NA, NA, NA), class = "rlib_error_dots_nonempty") 4 | expect_error(vec_restore(NA, NA, NA), class = "rlib_error_dots_nonempty") 5 | expect_error(vec_proxy(NA, NA), class = "rlib_error_dots_nonempty") 6 | expect_error(vec_proxy_equal(NA, NA), class = "rlib_error_dots_nonempty") 7 | expect_error(vec_proxy_compare(NA, NA), class = "rlib_error_dots_nonempty") 8 | expect_error(vec_ptype2(NA, NA, NA), class = "rlib_error_dots_nonempty") 9 | expect_error(vec_ptype_abbr(NA, NA), class = "rlib_error_dots_nonempty") 10 | expect_error(vec_ptype_full(NA, NA), class = "rlib_error_dots_nonempty") 11 | expect_error(vec_arith(NA, NA, NA, NA), class = "rlib_error_dots_nonempty") 12 | expect_error(vec_ptype_finalise(NA, NA), class = "rlib_error_dots_nonempty") 13 | expect_error(vec_assign(NA, NA, NA, NA), class = "rlib_error_dots_nonempty") 14 | }) 15 | -------------------------------------------------------------------------------- /vctrs.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: knitr 13 | LaTeX: XeLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | PackageRoxygenize: rd,collate,namespace 22 | -------------------------------------------------------------------------------- /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | --------------------------------------------------------------------------------