This is an automated email from the ASF dual-hosted git repository.

westonpace pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-cookbook.git


The following commit(s) were added to refs/heads/main by this push:
     new d15e75c  Initial C++ cookbook (#22)
d15e75c is described below

commit d15e75c1d15b22b27d634a4254ef9ee8c41a9737
Author: Weston Pace <[email protected]>
AuthorDate: Mon Aug 23 09:44:26 2021 -1000

    Initial C++ cookbook (#22)
    
    * Initial C++ cookbook
    
    * Addressing PR feedback.  Converted contributing doc from RST to MD (since 
the extension was MD).
    
    * Update cpp/CONTRIBUTING.md
    
    Co-authored-by: David Li <[email protected]>
    
    * Creating standalone section for code of conduct
    
    * Update cpp/CONTRIBUTING.md
    
    Co-authored-by: David Li <[email protected]>
    
    * Addressing PR comments
    
    Co-authored-by: David Li <[email protected]>
---
 .github/workflows/deploy_cookbooks.yml |  44 ++++++++-
 .gitignore                             |   6 ++
 Makefile                               |  19 +++-
 build/index.html                       |   1 +
 cpp/CONTRIBUTING.md                    | 170 +++++++++++++++++++++++++++++++++
 cpp/Makefile                           |  20 ++++
 cpp/code/.clang-format                 |  20 ++++
 cpp/code/.gitignore                    |   1 +
 cpp/code/CMakeLists.txt                |  47 +++++++++
 cpp/code/basic_arrow.cc                |  59 ++++++++++++
 cpp/code/common.cc                     | 161 +++++++++++++++++++++++++++++++
 cpp/code/common.h                      |  52 ++++++++++
 cpp/code/creating_arrow_objects.cc     |  55 +++++++++++
 cpp/code/main.cc                       |  42 ++++++++
 cpp/environment.yml                    | 115 ++++++++++++++++++++++
 cpp/ext/recipeext.py                   | 102 ++++++++++++++++++++
 cpp/make.bat                           |  35 +++++++
 cpp/requirements.txt                   |   2 +
 cpp/source/basic.rst                   |  49 ++++++++++
 cpp/source/conf.py                     |  72 ++++++++++++++
 cpp/source/create.rst                  |  49 ++++++++++
 cpp/source/index.rst                   |  37 +++++++
 22 files changed, 1155 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/deploy_cookbooks.yml 
b/.github/workflows/deploy_cookbooks.yml
index f12ded9..07ca317 100644
--- a/.github/workflows/deploy_cookbooks.yml
+++ b/.github/workflows/deploy_cookbooks.yml
@@ -29,10 +29,47 @@ jobs:
           name: build_book
           path: build/
 
+  make_cpp:
+    name: build c++
+    runs-on: ubuntu-latest
+    defaults:
+      run:
+        shell: bash -l {0}
+    steps:
+      - uses: actions/checkout@v1
+      - name: Cache conda
+        uses: actions/cache@v2
+        env:
+          # Increase this value to reset cache if cpp/environment.yml has not 
changed
+          CACHE_NUMBER: 0
+        with:
+          path: ~/conda_pkgs_dir
+          key:
+            ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ 
hashFiles('cpp/environment.yml') }}
+      - name: Setup environment
+        uses: conda-incubator/setup-miniconda@v2
+        with:
+          auto-update-conda: true
+          python-version: 3.9
+          activate-environment: cookbook-cpp
+          environment-file: cpp/environment.yml
+          auto-activate-base: false
+      - name: Test
+        run:
+          echo ${CONDA_PREFIX}
+      - name: Build cookbook
+        run:
+          make cpp
+      - name: Upload cpp book
+        uses: actions/upload-artifact@v1
+        with:
+          name: cpp_book
+          path: build/cpp
+
   deploy_cookbooks:
     name: deploy
     runs-on: ubuntu-latest
-    needs: make_cookbooks
+    needs: [make_cookbooks, make_cpp]
     steps:
       - name: Checkout repo
         uses: actions/checkout@v2
@@ -47,6 +84,11 @@ jobs:
         with:
           name: build_book
           path: .
+      - name: Download cpp book
+        uses: actions/[email protected]
+        with:
+          name: cpp_book
+          path: ./cpp
       - name: Push changes to gh-pages/asf-site branch
         run: |
           git config --global user.name 'GitHub Actions'
diff --git a/.gitignore b/.gitignore
index 3e6a548..040bc4c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,12 @@
 r/content/_book/**
+r/content/_main.Rmd
 r/*.Rproj
 *.Rproj
 .Rproj.user
 
+*.idea/
+*.vscode/
+
 *build/
 
 *.parquet
@@ -10,3 +14,5 @@ r/*.Rproj
 *.arrows
 *.csv
 *.feather
+
+*.pyc
diff --git a/Makefile b/Makefile
index ad2b473..2acc8df 100644
--- a/Makefile
+++ b/Makefile
@@ -2,10 +2,10 @@ all: html
 
 
 html: py r
-       @echo "\n\n>>> Cookbooks Available in ./build <<<"
+       @echo "\n\n>>> Cookbooks (except C++) Available in ./build <<<"
 
 
-test:   pytest rtest
+test: pytest rtest
 
 
 help:
@@ -48,8 +48,23 @@ r: rdeps
        mkdir -p build/r
        cp -r r/content/_book/* build/r
 
+
 rtest: rdeps
        @echo ">>> Testing R Cookbook <<<\n"
        cd ./r && Rscript ./scripts/test.R
 
 
+cpptest:
+       @echo ">>> Running C++ Tests/Snippets <<<\n"
+       rm -rf cpp/recipe-test-build
+       mkdir cpp/recipe-test-build
+       cd cpp/recipe-test-build && cmake ../code -DCMAKE_BUILD_TYPE=Debug && 
cmake --build . && ctest -j 1
+       mkdir -p cpp/build
+       cp cpp/recipe-test-build/recipes_out.arrow cpp/build
+
+
+cpp: cpptest
+       @echo ">>> Building C++ Cookbook <<<\n"
+       cd cpp && make html
+       mkdir -p build/cpp
+       cp -r cpp/build/html/* build/cpp
diff --git a/build/index.html b/build/index.html
index d5ee952..a1a2a93 100644
--- a/build/index.html
+++ b/build/index.html
@@ -38,6 +38,7 @@
                   but some are specific to the language and environment in use.
                </p>
                <ul>
+                       <li><a href="cpp/index.html">C++ Cookbook</a></li>
                        <li><a href="py/index.html">Python Cookbook</a></li>
                        <li><a href="r/index.html">R Cookbook</a></li>
                </ul>
diff --git a/cpp/CONTRIBUTING.md b/cpp/CONTRIBUTING.md
new file mode 100644
index 0000000..153192e
--- /dev/null
+++ b/cpp/CONTRIBUTING.md
@@ -0,0 +1,170 @@
+# Bulding the C++ Cookbook
+
+The C++ cookbook combines output from a set of C++ test programs with
+an reStructuredText (RST) document tree rendered with Sphinx.
+
+Running `make py` from the cookbook root directory (the one where
+the `README.rst` exists) will install all necessary dependencies,
+run the tests to generate the output, and will compile the cookbook
+to HTML.
+
+You will see the compiled result inside the `build/cpp` directory.
+
+The above process requires conda to be installed and is primarily
+intended for build systems. See below for more information on setting
+up a development environment for developing recipes.
+
+# Developing C++ Recipes
+
+Every recipe is a combination of prose written in RST
+format using the [Sphinx](https://www.sphinx-doc.org/) documentation
+system and a snippet of a googletest test.
+
+New recipes can be added to one of the existing `.rst` files if
+they suit that section or you can create new sections by adding
+additional `.rst` files in the `source` directory. You just
+need to remember to add them to the `index.rst` file in the
+`toctree` for them to become visible.
+
+## Referencing a C++ Snippet
+
+Most recipes will reference a snippet of C++ code. For simplicity
+a custom `recipe` directive that can be used like so:
+
+```
+.. recipe:: ../code/creating_arrow_objects.cc CreatingArrays
+  :caption: Creating an array from C++ primitives
+  :dedent: 4
+```
+
+Each `recipe` directive has two requried arguments. The first is
+a path to the file containing the source file containing the snippet
+and the second is the name of the snippet and must correspond to a
+set of CreateRecipe/EndRecipe calls in the source file.
+
+The directive will generate two code blocks in the cookbook. The first
+code block will contain the source code itself and will be annotated
+with any (optional) caption specified on the recipe directive. The
+second block will contain the test output.
+
+The optional `dedent` argument should be used to remove leading white
+space from your source code.
+
+## Writing a C++ Snippet
+
+Each snippet source file contains a set of
+[googletest](https://github.com/google/googletest) tests. Feel free to
+use any googletest features needed to help setup and verify your test.
+To reference a snippet you need to surround it in `BeginRecipe` and
+`EndRecipe` calls. For example:
+
+```
+StartRecipe("CreatingArrays");
+arrow::Int32Builder builder;
+ASSERT_OK(builder.Append(1));
+ASSERT_OK(builder.Append(2));
+ASSERT_OK(builder.Append(3));
+ASSERT_OK_AND_ASSIGN(shared_ptr<arrow::Array> arr, builder.Finish())
+rout << arr->ToString() << endl;
+EndRecipe("CreatingArrays");
+```
+
+The variable `rout` is set to a `std::ostream` instance that is used to
+capture test output. Anything output to `rout` will show up in the recipe
+output block when the recipe is rendered into the cookbook.
+
+## Referencing Arrow C++ Documentation
+
+The Arrow project has its own documentation for the C++ implementation that
+is hosted at https://arrow.apache.org/docs/cpp/index.html. Fortunately,
+this documentation is also built with Sphinx and so we can use the extension
+`intersphinx` to reference sections of this documentation. To do so simply
+write a standard Sphinx reference like so:
+
+```
+Typed subclasses of :cpp:class:`arrow::ArrayBuilder` make it easy
+to efficiently create Arrow arrays from existing C++ data
+```
+
+A helpful command is
+`python -msphinx.ext.intersphinx https://arrow.apache.org/docs/objects.inv`
+which will list all of the possible targets to link to.
+
+# Development Workflow
+
+Running `make` at the top level can be rather slow as it will rebuild the
+entire environment each time. It is primarily intended for use in CI and
+requires you to have conda installed.
+
+For recipe development you are encouraged to create your own out-of-source
+cmake build. For example:
+
+```
+mkdir cpp/code/build
+cd cpp/code/build
+cmake ../code -DCMAKE_BUILD_TYPE=Debug
+cmake --build .
+ctest
+```
+
+Then you can rerun all of the tests with `ctest` and you can rebuild and
+rerun individual tests much more quickly with something like
+`cmake --build . --target creating_arrow_objects && ctest 
creating_arrow_objects`.
+Everytime the cmake build is run it will update the recipe output file
+referenced by the sphinx build so after rerunning a test you can visualize the
+output by running `make html` in the `cpp` directory.
+
+## Using Conda
+
+If you are using conda then there is file `cpp/requirements.yml` which can be
+used to create an environment for recipe development with the command:
+
+```
+conda env create -n cookbook-cpp --file cpp/requirements.yml
+```
+
+# Development Philosophy
+
+## Everything is the Cookbook
+
+The entire document should serve as an example of how to use Arrow C++, not 
just the
+referenced snippets. This means that the below style rules and guidelines 
apply to
+source code that is not referenced by the cookbook itself.
+
+## Style
+
+This cookbook follows the same style rules as Arrow C++ which is the Google 
style
+guide with a few exceptions described
+[here](https://arrow.apache.org/docs/developers/cpp/development.html#code-style-linting-and-ci)
+
+## Simple
+
+The examples should be as simple as possible. If complex code (e.g. templates) 
can be
+used to do something more efficiently then there should be a simple, 
inefficient version
+alongside the more complex version.
+
+Do not use `auto` in any of the templates unless you must (e.g. lambdas). 
Cookbook
+viewers will be using a browser, not an IDE, and it is not always simple to 
determine
+the inferred type.
+
+# The Custom Recipe Directive
+
+C++ is not, at the moment, a "notebook friendly" language and it does lend 
itself well
+to being embedded inside an RST file. As such, we use a custom directive to 
link the
+Googletest source files and the RST prose. The directive works with the helper 
methods
+`BeginRecipe` and `EndRecipe` defined in `common.h`.
+
+The helper method `BeginRecipe` will begin capturing output to `rout`. The 
helper method
+`EndRecipe` will append the captured output and recipe name to string arrays. 
There is code
+in `main.cc` which runs after the tests run to dump these arrays to a .arrow 
file (i.e. the
+arrays will be serialized as a table using the Arrow IPC format).
+
+When the sphinx build runs the directive `recipe` (defined in `cpp/ext`) will 
be loaded.
+During this load the dataset of test outputs will be read. These test outputs 
will be used
+whenever a recipe is referenced.
+
+# Code of Conduct
+
+All participation in the Apache Arrow project is governed by the Apache
+Software Foundation’s
+`code of conduct <https://www.apache.org/foundation/policies/conduct.html>`\_.
diff --git a/cpp/Makefile b/cpp/Makefile
new file mode 100644
index 0000000..a023ec1
--- /dev/null
+++ b/cpp/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?= -jauto
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = source
+BUILDDIR      = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+       @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+       @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/cpp/code/.clang-format b/cpp/code/.clang-format
new file mode 100644
index 0000000..06453df
--- /dev/null
+++ b/cpp/code/.clang-format
@@ -0,0 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+---
+BasedOnStyle:  Google
+DerivePointerAlignment: false
+ColumnLimit: 90
diff --git a/cpp/code/.gitignore b/cpp/code/.gitignore
new file mode 100644
index 0000000..78d1dfe
--- /dev/null
+++ b/cpp/code/.gitignore
@@ -0,0 +1 @@
+*-build*/
\ No newline at end of file
diff --git a/cpp/code/CMakeLists.txt b/cpp/code/CMakeLists.txt
new file mode 100644
index 0000000..213d48a
--- /dev/null
+++ b/cpp/code/CMakeLists.txt
@@ -0,0 +1,47 @@
+cmake_minimum_required(VERSION 3.19)
+project(arrow-cookbook)
+
+set(CMAKE_CXX_STANDARD 17)
+
+# Add googletest
+include(FetchContent)
+FetchContent_Declare(
+  googletest
+  GIT_REPOSITORY https://github.com/google/googletest.git
+  GIT_TAG        e2239ee6043f73722e7aa812a459f54a28552929 # release-1.11.0
+)
+# For Windows: Prevent overriding the parent project's compiler/linker settings
+set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
+FetchContent_MakeAvailable(googletest)
+
+# Add Arrow
+find_package(Arrow REQUIRED)
+
+# Create test targets
+enable_testing()
+include(GoogleTest)
+add_executable(
+        creating_arrow_objects
+        creating_arrow_objects.cc
+        common.cc
+        main.cc
+)
+target_link_libraries(
+        creating_arrow_objects
+        arrow_shared
+        gtest
+)
+gtest_discover_tests(creating_arrow_objects)
+
+add_executable(
+        basic_arrow
+        basic_arrow.cc
+        common.cc
+        main.cc
+)
+target_link_libraries(
+        basic_arrow
+        arrow_shared
+        gtest
+)
+gtest_discover_tests(basic_arrow)
diff --git a/cpp/code/basic_arrow.cc b/cpp/code/basic_arrow.cc
new file mode 100644
index 0000000..9af8f41
--- /dev/null
+++ b/cpp/code/basic_arrow.cc
@@ -0,0 +1,59 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include <arrow/api.h>
+#include <gtest/gtest.h>
+
+#include "common.h"
+
+TEST(BasicArrow, ReturnNotOkNoMacro) {
+  StartRecipe("ReturnNotOkNoMacro");
+  std::function<arrow::Status()> test_fn = [] {
+    arrow::NullBuilder builder;
+    arrow::Status st = builder.Reserve(2);
+    // Tedious return value check
+    if (!st.ok()) {
+      return st;
+    }
+    st = builder.AppendNulls(-1);
+    // Tedious return value check
+    if (!st.ok()) {
+      return st;
+    }
+    rout << "Appended -1 null values?" << std::endl;
+    return arrow::Status::OK();
+  };
+  arrow::Status st = test_fn();
+  rout << st << std::endl;
+  EndRecipe("ReturnNotOkNoMacro");
+  ASSERT_FALSE(st.ok());
+}
+
+TEST(BasicArrow, ReturnNotOk) {
+  StartRecipe("ReturnNotOk");
+  std::function<arrow::Status()> test_fn = [] {
+    arrow::NullBuilder builder;
+    ARROW_RETURN_NOT_OK(builder.Reserve(2));
+    ARROW_RETURN_NOT_OK(builder.AppendNulls(-1));
+    rout << "Appended -1 null values?" << std::endl;
+    return arrow::Status::OK();
+  };
+  arrow::Status st = test_fn();
+  rout << st << std::endl;
+  EndRecipe("ReturnNotOk");
+  ASSERT_FALSE(st.ok());
+}
diff --git a/cpp/code/common.cc b/cpp/code/common.cc
new file mode 100644
index 0000000..0024c4c
--- /dev/null
+++ b/cpp/code/common.cc
@@ -0,0 +1,161 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include <sstream>
+#include <unordered_map>
+
+#include "arrow/api.h"
+#include "arrow/filesystem/api.h"
+#include "arrow/ipc/api.h"
+#include "gtest/gtest.h"
+
+#include "common.h"
+
+static arrow::StringBuilder test_names_builder;
+static arrow::StringBuilder test_output_builder;
+static std::string current_recipe;
+
+void StartRecipe(const std::string& recipe_name) {
+  if (!current_recipe.empty()) {
+    FAIL() << "Attempt to start a recipe " << recipe_name << " but the recipe "
+           << current_recipe << " has not been marked finished";
+  }
+  if (recipe_name.empty()) {
+    FAIL() << "Invalid empty recipe name";
+  }
+  current_recipe = recipe_name;
+  rout = std::stringstream();
+}
+
+void EndRecipe(const std::string& recipe_name) {
+  if (current_recipe != recipe_name) {
+    FAIL() << "Attempt to end a recipe " << recipe_name
+           << " but the recipe was not in progress";
+  }
+  std::string recipe_output = rout.str();
+
+  ASSERT_OK(test_names_builder.Append(recipe_name));
+  ASSERT_OK(test_output_builder.Append(recipe_output));
+
+  current_recipe = "";
+}
+
+std::shared_ptr<arrow::Schema> RecipesTableSchema() {
+  return arrow::schema({arrow::field("Recipe Name", arrow::utf8()),
+                        arrow::field("Recipe Output", arrow::utf8())});
+}
+
+std::shared_ptr<arrow::Array> MakeEmptyStringArray() {
+  arrow::StringBuilder builder;
+  return builder.Finish().ValueOrDie();
+}
+
+arrow::Result<std::shared_ptr<arrow::Table>> MakeEmptyRecipesTable() {
+  std::shared_ptr<arrow::Schema> schema = RecipesTableSchema();
+  std::shared_ptr<arrow::RecordBatch> batch = arrow::RecordBatch::Make(
+      schema, 0, {MakeEmptyStringArray(), MakeEmptyStringArray()});
+  return arrow::Table::FromRecordBatches({batch});
+}
+
+arrow::Result<std::shared_ptr<arrow::Table>> ReadRecipeTable(
+    const std::shared_ptr<arrow::io::RandomAccessFile>& in_file) {
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::ipc::RecordBatchStreamReader> 
reader,
+                        arrow::ipc::RecordBatchStreamReader::Open(in_file));
+  std::shared_ptr<arrow::Table> table;
+  ARROW_RETURN_NOT_OK(reader->ReadAll(&table));
+  return table;
+}
+
+arrow::Result<std::shared_ptr<arrow::Table>> LoadExistingRecipeOutputTable(
+    const std::string& filename) {
+  std::shared_ptr<arrow::fs::FileSystem> fs =
+      std::make_shared<arrow::fs::LocalFileSystem>();
+  arrow::Result<std::shared_ptr<arrow::io::RandomAccessFile>> maybe_in =
+      fs->OpenInputFile(filename);
+  if (!maybe_in.ok()) {
+    return MakeEmptyRecipesTable();
+  }
+  std::shared_ptr<arrow::io::RandomAccessFile> in = *maybe_in;
+  return ReadRecipeTable(in);
+}
+
+arrow::Result<std::shared_ptr<arrow::Table>> CreateRecipeOutputTable() {
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> test_names,
+                        test_names_builder.Finish());
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> test_outputs,
+                        test_output_builder.Finish());
+  std::shared_ptr<arrow::Schema> schema =
+      arrow::schema({arrow::field("Recipe Name", arrow::utf8()),
+                     arrow::field("Recipe Output", arrow::utf8())});
+  std::shared_ptr<arrow::RecordBatch> batch =
+      arrow::RecordBatch::Make(schema, test_names->length(), {test_names, 
test_outputs});
+  return arrow::Table::FromRecordBatches({batch});
+}
+
+void PopulateMap(const arrow::Table& table,
+                 std::unordered_map<std::string, std::string>* values) {
+  if (table.num_rows() == 0) {
+    return;
+  }
+  std::shared_ptr<arrow::StringArray> table_names =
+      std::dynamic_pointer_cast<arrow::StringArray>(table.column(0)->chunk(0));
+  std::shared_ptr<arrow::StringArray> table_outputs =
+      std::dynamic_pointer_cast<arrow::StringArray>(table.column(1)->chunk(0));
+  for (int64_t i = 0; i < table.num_rows(); i++) {
+    values->insert({table_names->GetString(i), table_outputs->GetString(i)});
+  }
+}
+
+arrow::Result<std::shared_ptr<arrow::Table>> MergeRecipeTables(
+    std::shared_ptr<arrow::Table> old_table, std::shared_ptr<arrow::Table> 
new_table) {
+  std::unordered_map<std::string, std::string> values;
+  PopulateMap(*old_table, &values);
+  PopulateMap(*new_table, &values);
+  arrow::StringBuilder names_builder;
+  arrow::StringBuilder outputs_builder;
+  for (auto pair : values) {
+    ARROW_RETURN_NOT_OK(names_builder.Append(pair.first));
+    ARROW_RETURN_NOT_OK(outputs_builder.Append(pair.second));
+  }
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> names_arr, 
names_builder.Finish());
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Array> outputs_arr,
+                        outputs_builder.Finish());
+  std::shared_ptr<arrow::Schema> schema = RecipesTableSchema();
+  std::shared_ptr<arrow::RecordBatch> batch =
+      arrow::RecordBatch::Make(schema, names_arr->length(), {names_arr, 
outputs_arr});
+  return arrow::Table::FromRecordBatches({batch});
+}
+
+bool HasRecipeOutput() { return test_names_builder.length() > 0; }
+
+arrow::Status DumpRecipeOutput(const std::string& output_filename) {
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Table> new_table,
+                        CreateRecipeOutputTable());
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Table> old_table,
+                        LoadExistingRecipeOutputTable(output_filename));
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Table> merged_table,
+                        MergeRecipeTables(old_table, new_table));
+  std::shared_ptr<arrow::fs::FileSystem> fs =
+      std::make_shared<arrow::fs::LocalFileSystem>();
+  ARROW_ASSIGN_OR_RAISE(std::shared_ptr<arrow::io::OutputStream> out_stream,
+                        fs->OpenOutputStream(output_filename));
+  ARROW_ASSIGN_OR_RAISE(
+      std::shared_ptr<arrow::ipc::RecordBatchWriter> writer,
+      arrow::ipc::MakeStreamWriter(out_stream.get(), merged_table->schema()));
+  RETURN_NOT_OK(writer->WriteTable(*merged_table));
+  return writer->Close();
+}
\ No newline at end of file
diff --git a/cpp/code/common.h b/cpp/code/common.h
new file mode 100644
index 0000000..f7fef1a
--- /dev/null
+++ b/cpp/code/common.h
@@ -0,0 +1,52 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef ARROW_COOKBOOK_COMMON_H
+#define ARROW_COOKBOOK_COMMON_H
+
+#include <sstream>
+#include <string>
+
+#include <arrow/result.h>
+#include <arrow/status.h>
+
+#define ARROW_STRINGIFY(x) #x
+#define ARROW_CONCAT(x, y) x##y
+
+#define ARROW_ASSIGN_OR_RAISE_NAME(x, y) ARROW_CONCAT(x, y)
+
+#define ASSERT_OK(expr)                                                        
      \
+  for (::arrow::Status _st = ::arrow::internal::GenericToStatus((expr)); 
!_st.ok();) \
+  FAIL() << "'" ARROW_STRINGIFY(expr) "' failed with " << _st.ToString()
+
+#define ASSIGN_OR_HANDLE_ERROR_IMPL(handle_error, status_name, lhs, rexpr) \
+  auto&& status_name = (rexpr);                                            \
+  handle_error(status_name.status());                                      \
+  lhs = std::move(status_name).ValueOrDie();
+
+#define ASSERT_OK_AND_ASSIGN(lhs, rexpr) \
+  ASSIGN_OR_HANDLE_ERROR_IMPL(           \
+      ASSERT_OK, ARROW_ASSIGN_OR_RAISE_NAME(_error_or_value, __COUNTER__), 
lhs, rexpr);
+
+inline std::stringstream rout;
+
+void StartRecipe(const std::string& recipe_name);
+void EndRecipe(const std::string& recipe_name);
+arrow::Status DumpRecipeOutput(const std::string& output_filename);
+bool HasRecipeOutput();
+
+#endif  // ARROW_COOKBOOK_COMMON_H
diff --git a/cpp/code/creating_arrow_objects.cc 
b/cpp/code/creating_arrow_objects.cc
new file mode 100644
index 0000000..7e44b61
--- /dev/null
+++ b/cpp/code/creating_arrow_objects.cc
@@ -0,0 +1,55 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include <arrow/api.h>
+#include <gtest/gtest.h>
+
+#include "common.h"
+
+TEST(CreatingArrowObjects, CreateArrays) {
+  StartRecipe("CreatingArrays");
+  arrow::Int32Builder builder;
+  ASSERT_OK(builder.Append(1));
+  ASSERT_OK(builder.Append(2));
+  ASSERT_OK(builder.Append(3));
+  ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::Array> arr, builder.Finish())
+  rout << arr->ToString() << std::endl;
+  EndRecipe("CreatingArrays");
+
+  StartRecipe("CreatingArraysPtr");
+  // Raw pointers
+  arrow::Int64Builder long_builder = arrow::Int64Builder();
+  std::array<int64_t, 4> values = {1, 2, 3, 4};
+  ASSERT_OK(long_builder.AppendValues(values.data(), values.size()));
+  ASSERT_OK_AND_ASSIGN(arr, long_builder.Finish());
+  rout << arr->ToString() << std::endl;
+
+  // Vectors
+  arrow::StringBuilder str_builder = arrow::StringBuilder();
+  std::vector<std::string> strvals = {"x", "y", "z"};
+  ASSERT_OK(str_builder.AppendValues(strvals));
+  ASSERT_OK_AND_ASSIGN(arr, str_builder.Finish());
+  rout << arr->ToString() << std::endl;
+
+  // Iterators
+  arrow::DoubleBuilder dbl_builder = arrow::DoubleBuilder();
+  std::set<double> dblvals = {1.1, 1.1, 2.3};
+  ASSERT_OK(dbl_builder.AppendValues(dblvals.begin(), dblvals.end()));
+  ASSERT_OK_AND_ASSIGN(arr, dbl_builder.Finish());
+  rout << arr->ToString() << std::endl;
+  EndRecipe("CreatingArraysPtr");
+}
diff --git a/cpp/code/main.cc b/cpp/code/main.cc
new file mode 100644
index 0000000..3fbe3ea
--- /dev/null
+++ b/cpp/code/main.cc
@@ -0,0 +1,42 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include <iostream>
+
+#include <filesystem>
+
+#include <arrow/status.h>
+#include "gtest/gtest.h"
+
+#include "common.h"
+
+int main(int argc, char** argv) {
+  testing::InitGoogleTest(&argc, argv);
+  int retval = RUN_ALL_TESTS();
+  if (retval == 0 && HasRecipeOutput()) {
+    arrow::Status st = DumpRecipeOutput("recipes_out.arrow");
+    if (!st.ok()) {
+      std::cerr << "Tests ran successfully but failed to dump recipe output: " 
<< st
+                << std::endl;
+      return -1;
+    }
+    std::cout << "Created recipe file "
+              << 
std::filesystem::current_path().append("recipes_out.arrow").string()
+              << std::endl;
+  }
+  return retval;
+}
diff --git a/cpp/environment.yml b/cpp/environment.yml
new file mode 100644
index 0000000..690182a
--- /dev/null
+++ b/cpp/environment.yml
@@ -0,0 +1,115 @@
+name: cookbook-cpp
+channels:
+  - conda-forge
+dependencies:
+  - _libgcc_mutex=0.1=conda_forge
+  - _openmp_mutex=4.5=1_gnu
+  - abseil-cpp=20210324.2=h9c3ff4c_0
+  - alabaster=0.7.12=py_0
+  - arrow-cpp=5.0.0=py39h3d6947c_1_cpu
+  - aws-c-cal=0.5.11=h95a6274_0
+  - aws-c-common=0.6.2=h7f98852_0
+  - aws-c-event-stream=0.2.7=h3541f99_13
+  - aws-c-io=0.10.5=hfb6a706_0
+  - aws-checksums=0.1.11=ha31a3da_7
+  - aws-sdk-cpp=1.8.186=hb4091e7_3
+  - babel=2.9.1=pyh44b312d_0
+  - binutils_impl_linux-64=2.36.1=h193b22a_2
+  - brotlipy=0.7.0=py39h3811e60_1001
+  - bzip2=1.0.8=h7f98852_4
+  - c-ares=1.17.1=h7f98852_1
+  - ca-certificates=2021.5.30=ha878542_0
+  - certifi=2021.5.30=py39hf3d152e_0
+  - cffi=1.14.6=py39he32792d_0
+  - chardet=4.0.0=py39hf3d152e_1
+  - charset-normalizer=2.0.0=pyhd8ed1ab_0
+  - clang=11.1.0=ha770c72_1
+  - clang-11=11.1.0=default_ha53f305_1
+  - clangxx=11.1.0=default_ha53f305_1
+  - cmake=3.21.1=h8897547_0
+  - colorama=0.4.4=pyh9f0ad1d_0
+  - cryptography=3.4.7=py39hbca0aa6_0
+  - docutils=0.17.1=py39hf3d152e_0
+  - expat=2.4.1=h9c3ff4c_0
+  - gcc_impl_linux-64=11.1.0=h6b5115b_8
+  - gflags=2.2.2=he1b5a44_1004
+  - glog=0.5.0=h48cff8f_0
+  - grpc-cpp=1.39.0=h36ce80c_1
+  - idna=3.1=pyhd3deb0d_0
+  - imagesize=1.2.0=py_0
+  - jinja2=3.0.1=pyhd8ed1ab_0
+  - kernel-headers_linux-64=2.6.32=he073ed8_14
+  - krb5=1.19.2=hcc1bbae_0
+  - ld_impl_linux-64=2.36.1=hea4e1c9_2
+  - libblas=3.9.0=10_openblas
+  - libbrotlicommon=1.0.9=h7f98852_5
+  - libbrotlidec=1.0.9=h7f98852_5
+  - libbrotlienc=1.0.9=h7f98852_5
+  - libcblas=3.9.0=10_openblas
+  - libclang-cpp11.1=11.1.0=default_ha53f305_1
+  - libcurl=7.78.0=h2574ce0_0
+  - libedit=3.1.20191231=he28a2e2_2
+  - libev=4.33=h516909a_1
+  - libevent=2.1.10=hcdb4288_3
+  - libffi=3.3=h58526e2_2
+  - libgcc-devel_linux-64=11.1.0=h80e7780_8
+  - libgcc-ng=11.1.0=hc902ee8_8
+  - libgfortran-ng=11.1.0=h69a702a_8
+  - libgfortran5=11.1.0=h6c583b3_8
+  - libgomp=11.1.0=hc902ee8_8
+  - liblapack=3.9.0=10_openblas
+  - libllvm11=11.1.0=hf817b99_2
+  - libnghttp2=1.43.0=h812cca2_0
+  - libopenblas=0.3.17=pthreads_h8fe5266_1
+  - libprotobuf=3.16.0=h780b84a_0
+  - libsanitizer=11.1.0=h56837e0_8
+  - libssh2=1.9.0=ha56f1ee_6
+  - libstdcxx-ng=11.1.0=h56837e0_8
+  - libthrift=0.14.2=he6d91bd_1
+  - libutf8proc=2.6.1=h7f98852_0
+  - libuv=1.42.0=h7f98852_0
+  - lz4-c=1.9.3=h9c3ff4c_1
+  - make=4.3=hd18ef5c_1
+  - markupsafe=2.0.1=py39h3811e60_0
+  - ncurses=6.2=h58526e2_4
+  - numpy=1.21.1=py39hdbf815f_0
+  - openssl=1.1.1k=h7f98852_0
+  - orc=1.6.9=h58a87f1_0
+  - packaging=21.0=pyhd8ed1ab_0
+  - parquet-cpp=1.5.1=2
+  - pip=21.2.3=pyhd8ed1ab_0
+  - pyarrow=5.0.0=py39h3ebc44c_1_cpu
+  - pycparser=2.20=pyh9f0ad1d_2
+  - pygments=2.9.0=pyhd8ed1ab_0
+  - pyopenssl=20.0.1=pyhd8ed1ab_0
+  - pyparsing=2.4.7=pyh9f0ad1d_0
+  - pysocks=1.7.1=py39hf3d152e_3
+  - python=3.9.6=h49503c6_1_cpython
+  - python_abi=3.9=2_cp39
+  - pytz=2021.1=pyhd8ed1ab_0
+  - re2=2021.06.01=h9c3ff4c_0
+  - readline=8.1=h46c0cb4_0
+  - requests=2.26.0=pyhd8ed1ab_0
+  - rhash=1.4.1=h7f98852_0
+  - s2n=1.0.10=h9b69904_0
+  - setuptools=49.6.0=py39hf3d152e_3
+  - six=1.16.0=pyh6c4a22f_0
+  - snappy=1.1.8=he1b5a44_3
+  - snowballstemmer=2.1.0=pyhd8ed1ab_0
+  - sphinx=4.0.2=pyh6c4a22f_1
+  - sphinxcontrib-applehelp=1.0.2=py_0
+  - sphinxcontrib-devhelp=1.0.2=py_0
+  - sphinxcontrib-htmlhelp=2.0.0=pyhd8ed1ab_0
+  - sphinxcontrib-jsmath=1.0.1=py_0
+  - sphinxcontrib-qthelp=1.0.3=py_0
+  - sphinxcontrib-serializinghtml=1.1.5=pyhd8ed1ab_0
+  - sqlite=3.36.0=h9cd32fc_0
+  - sysroot_linux-64=2.12=he073ed8_14
+  - tk=8.6.10=h21135ba_1
+  - tzdata=2021a=he74cb21_1
+  - urllib3=1.26.6=pyhd8ed1ab_0
+  - wheel=0.36.2=pyhd3deb0d_0
+  - xz=5.2.5=h516909a_1
+  - zlib=1.2.11=h516909a_1010
+  - zstd=1.5.0=ha95c52a_0
+prefix: /home/pace/anaconda3/envs/cookbook
diff --git a/cpp/ext/recipeext.py b/cpp/ext/recipeext.py
new file mode 100644
index 0000000..618d4e8
--- /dev/null
+++ b/cpp/ext/recipeext.py
@@ -0,0 +1,102 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from pathlib import Path
+import os
+import pyarrow as pa
+import pyarrow.ipc as ipc
+
+from docutils.nodes import literal_block, caption, container
+from sphinx.util.docutils import SphinxDirective
+from sphinx.directives.code import LiteralInclude
+from sphinx.util import logging
+
+logger = logging.getLogger(__name__)
+test_names_to_output = {}
+
+
+class RecipeDirective(SphinxDirective):
+
+    required_arguments = 2
+    optional_arguments = 0
+    option_spec = LiteralInclude.option_spec
+
+    def run(self):
+        global test_names_to_output
+        filename, recipe_name = self.arguments
+        if recipe_name not in test_names_to_output:
+            raise Exception(
+                f'Could not locate recipe output for the recipe 
{filename}:{recipe_name}')
+        recipe_output = test_names_to_output[recipe_name]
+
+        self.options['start-after'] = f'StartRecipe("{recipe_name}")'
+        self.options['end-before'] = f'EndRecipe("{recipe_name}")'
+        self.options['language'] = 'cpp'
+
+        out_nodes = LiteralInclude.run(self)
+
+        output_container = container('', literal_block=True, classes=[
+                                     'literal-block-wrapper'])
+        literal_node = literal_block(recipe_output, recipe_output)
+        caption_node = caption('Code Output', 'Code Output')
+        output_container += caption_node
+        output_container += literal_node
+
+        return out_nodes + [output_container]
+
+
+def load_recipe_output(path):
+    global test_names_to_output
+    with ipc.open_stream(path) as reader:
+        table = reader.read_all()
+    recipe_names = table.column('Recipe Name').to_pylist()
+    recipe_outputs = table.column('Recipe Output').to_pylist()
+    for name, output in zip(recipe_names, recipe_outputs):
+        test_names_to_output[name] = output
+
+
+def locate_latest_recipe_outputs():
+    base_dir = os.path.join(os.path.dirname(__file__), '..')
+    matches = list(Path(base_dir).rglob('recipes_out.arrow'))
+    if len(matches) == 0:
+        raise Exception(
+            f"Could not find any recipes_out.arrow files in {base_dir}.  Have 
you run the C++ tests/recipes?")
+
+    matches_with_mtimes = [
+        {'path': str(match), 'mtime': os.path.getmtime(str(match))} for match 
in matches]
+    sorted_matches = [match['path'] for match in sorted(
+        matches_with_mtimes, key=lambda x: x['mtime'])]
+    for match_with_mtime in matches_with_mtimes:
+        path = match_with_mtime['path']
+        mtime = match_with_mtime['mtime']
+        logger.info(f'Considering recipe file {path} last updated at {mtime}')
+    return sorted_matches[-1]
+
+
+def setup(app):
+
+    recipe_outputs_path = locate_latest_recipe_outputs()
+    logger.info(f'Located recipes file: {recipe_outputs_path}')
+
+    load_recipe_output(recipe_outputs_path)
+
+    app.add_directive('recipe', RecipeDirective)
+
+    return {
+        'version': '0.1',
+        'parallel_read_safe': True,
+        'parallel_write_safe': True,
+    }
diff --git a/cpp/make.bat b/cpp/make.bat
new file mode 100644
index 0000000..6247f7e
--- /dev/null
+++ b/cpp/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+       set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+       echo.
+       echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+       echo.installed, then set the SPHINXBUILD environment variable to point
+       echo.to the full path of the 'sphinx-build' executable. Alternatively 
you
+       echo.may add the Sphinx directory to PATH.
+       echo.
+       echo.If you don't have Sphinx installed, grab it from
+       echo.http://sphinx-doc.org/
+       exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/cpp/requirements.txt b/cpp/requirements.txt
new file mode 100644
index 0000000..4b9f125
--- /dev/null
+++ b/cpp/requirements.txt
@@ -0,0 +1,2 @@
+Sphinx>=4.0.2
+pyarrow>=4.0.0
diff --git a/cpp/source/basic.rst b/cpp/source/basic.rst
new file mode 100644
index 0000000..913781a
--- /dev/null
+++ b/cpp/source/basic.rst
@@ -0,0 +1,49 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+.. or more contributor license agreements.  See the NOTICE file
+.. distributed with this work for additional information
+.. regarding copyright ownership.  The ASF licenses this file
+.. to you under the Apache License, Version 2.0 (the
+.. "License"); you may not use this file except in compliance
+.. with the License.  You may obtain a copy of the License at
+
+..   http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+.. software distributed under the License is distributed on an
+.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+.. KIND, either express or implied.  See the License for the
+.. specific language governing permissions and limitations
+.. under the License.
+===================================
+Working with the C++ Implementation
+===================================
+
+This section of the cookbook goes over basic concepts
+that will be needed regardless of how you intend to use
+the Arrow C++ implementation.
+
+.. contents::
+
+Working with Status and Result
+==============================
+
+C++ libraries often have to choose between throwing exceptions and
+returning error codes.  Arrow chooses to return Status and Result
+objects as a middle ground.  This makes it clear when a function
+can fail and is easier to use than integer arrow codes.
+
+It is important to always check the value of a returned Status object to
+ensure that the operation succeeded.  However, this can quickly become
+tedious:
+
+.. recipe:: ../code/basic_arrow.cc ReturnNotOkNoMacro
+  :caption: Checking the status of every function manually
+  :dedent: 2
+
+The macro :c:macro:`ARROW_RETURN_NOT_OK` will take care of some of this
+boilerplate for you.  It will run the contained expression and check the 
resulting
+``Status`` or ``Result`` object.  If it failed then it will return the failure.
+
+.. recipe:: ../code/basic_arrow.cc ReturnNotOk
+  :caption: Using ARROW_RETURN_NOT_OK to check the status
+  :dedent: 2
diff --git a/cpp/source/conf.py b/cpp/source/conf.py
new file mode 100644
index 0000000..fc5bf82
--- /dev/null
+++ b/cpp/source/conf.py
@@ -0,0 +1,72 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.append(os.path.abspath("../ext"))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'Apache Arrow C++ Cookbook'
+copyright = '2021, Apache Software Foundation'
+author = 'The Apache Software Foundation'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    "sphinx.ext.intersphinx", "recipeext"
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = []
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = []
+
+
+intersphinx_mapping = {'cpparrow': ('https://arrow.apache.org/docs/', None)}
diff --git a/cpp/source/create.rst b/cpp/source/create.rst
new file mode 100644
index 0000000..5e5483c
--- /dev/null
+++ b/cpp/source/create.rst
@@ -0,0 +1,49 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+.. or more contributor license agreements.  See the NOTICE file
+.. distributed with this work for additional information
+.. regarding copyright ownership.  The ASF licenses this file
+.. to you under the Apache License, Version 2.0 (the
+.. "License"); you may not use this file except in compliance
+.. with the License.  You may obtain a copy of the License at
+
+..   http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+.. software distributed under the License is distributed on an
+.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+.. KIND, either express or implied.  See the License for the
+.. specific language governing permissions and limitations
+.. under the License.
+======================
+Creating Arrow Objects
+======================
+
+Recipes related to the creation of Arrays, Tables,
+Tensors and all other Arrow entities.
+
+.. contents::
+
+Create Arrays from Standard C++
+===============================
+
+Typed subclasses of :cpp:class:`arrow::ArrayBuilder` make it easy
+to efficiently create Arrow arrays from existing C++ data:
+
+.. recipe:: ../code/creating_arrow_objects.cc CreatingArrays
+  :caption: Creating an array from C++ primitives
+  :dedent: 2
+
+.. note::
+
+    Builders will allocate data as needed and insertion should
+    have constant amortized time.
+
+Builders can also consume standard C++ containers:
+
+.. recipe:: ../code/creating_arrow_objects.cc CreatingArraysPtr
+  :dedent: 2
+
+.. note::
+    
+    Builders will not take ownership of data in containers and will make a
+    copy of the underlying data.
\ No newline at end of file
diff --git a/cpp/source/index.rst b/cpp/source/index.rst
new file mode 100644
index 0000000..023f6c8
--- /dev/null
+++ b/cpp/source/index.rst
@@ -0,0 +1,37 @@
+.. Licensed to the Apache Software Foundation (ASF) under one
+.. or more contributor license agreements.  See the NOTICE file
+.. distributed with this work for additional information
+.. regarding copyright ownership.  The ASF licenses this file
+.. to you under the Apache License, Version 2.0 (the
+.. "License"); you may not use this file except in compliance
+.. with the License.  You may obtain a copy of the License at
+
+..   http://www.apache.org/licenses/LICENSE-2.0
+
+.. Unless required by applicable law or agreed to in writing,
+.. software distributed under the License is distributed on an
+.. "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+.. KIND, either express or implied.  See the License for the
+.. specific language governing permissions and limitations
+.. under the License.
+Apache Arrow C++ Cookbook
+=========================
+
+The Apache Arrow Cookbook is a collection of recipes which demonstrate
+how to solve many common tasks that users might need to perform
+when working with arrow data.  The examples in this cookbook will also
+serve as robust and well performing solutions to those tasks.
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+
+   basic
+   create
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`

Reply via email to