PARQUET-1233: Enable option to switch between stl classes and boost c…

…lasses for thrift header

Author: Deepak Majeti <deepak.majeti@hpe.com>
Author: Wes McKinney <wes.mckinney@twosigma.com>

Closes #443 from majetideepak/PARQUET-1233 and squashes the following commits:

8d56f96 [Wes McKinney] Add PARQUET_THRIFT_USE_BOOST CMake option
37318dd [Deepak Majeti] Pin Thrift version 0.10.0 to toolchain
d065f80 [Deepak Majeti] PARQUET-1233: Enable option to switch between stl classes and boost classes for thrift header
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bca8478..304f3fb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -151,6 +151,11 @@
   option(PARQUET_MINIMAL_DEPENDENCY
     "Depend only on Thirdparty headers to build libparquet. Always OFF if building binaries"
     OFF)
+
+  option(PARQUET_THRIFT_USE_BOOST
+    "Enable if Thirdparty Thrift uses boost::shared_ptr (Apache Thrift < 0.11)"
+    OFF)
+
   if (MSVC)
     set(ARROW_MSVC_STATIC_LIB_SUFFIX "_static" CACHE STRING
       "Arrow static lib suffix used on Windows with MSVC (default _static)")
diff --git a/ci/travis_script_static.sh b/ci/travis_script_static.sh
index 6da7a33..b76ced8 100755
--- a/ci/travis_script_static.sh
+++ b/ci/travis_script_static.sh
@@ -40,7 +40,7 @@
 conda info -a
 
 conda create -y -q -p $CPP_TOOLCHAIN \
-      boost-cpp thrift-cpp cmake git \
+      boost-cpp thrift-cpp=0.10.0 cmake git \
       -c conda-forge
 
 source activate $CPP_TOOLCHAIN
@@ -70,6 +70,7 @@
       -DPARQUET_ARROW_LINKAGE="static" \
       -DPARQUET_BUILD_SHARED=OFF \
       -DPARQUET_BOOST_USE_SHARED=OFF \
+      -DPARQUET_THRIFT_USE_BOOST=ON \
       -DPARQUET_BUILD_BENCHMARKS=ON \
       -DPARQUET_BUILD_EXAMPLES=ON \
       -DPARQUET_GENERATE_COVERAGE=1 \
diff --git a/ci/travis_script_toolchain.sh b/ci/travis_script_toolchain.sh
index 7db9658..036ab3c 100755
--- a/ci/travis_script_toolchain.sh
+++ b/ci/travis_script_toolchain.sh
@@ -40,7 +40,7 @@
 conda info -a
 
 conda create -y -q -p $CPP_TOOLCHAIN \
-      boost-cpp thrift-cpp cmake git \
+      boost-cpp thrift-cpp=0.11.0 cmake git \
       -c conda-forge
 
 # ----------------------------------------------------------------------
diff --git a/cmake_modules/ThirdpartyToolchain.cmake b/cmake_modules/ThirdpartyToolchain.cmake
index 3c197dd..690fd0b 100644
--- a/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cmake_modules/ThirdpartyToolchain.cmake
@@ -17,7 +17,7 @@
 
 set(GTEST_VERSION "1.8.0")
 set(GBENCHMARK_VERSION "1.1.0")
-set(THRIFT_VERSION "0.11.0")
+set(THRIFT_VENDOR_VERSION "0.11.0")
 
 string(TOUPPER ${CMAKE_BUILD_TYPE} UPPERCASE_BUILD_TYPE)
 
@@ -244,7 +244,7 @@
   endif()
 
   ExternalProject_Add(thrift_ep
-    URL "http://archive.apache.org/dist/thrift/${THRIFT_VERSION}/thrift-${THRIFT_VERSION}.tar.gz"
+    URL "http://archive.apache.org/dist/thrift/${THRIFT_VENDOR_VERSION}/thrift-${THRIFT_VENDOR_VERSION}.tar.gz"
     BUILD_BYPRODUCTS "${THRIFT_STATIC_LIB}" "${THRIFT_COMPILER}"
     CMAKE_ARGS ${THRIFT_CMAKE_ARGS}
     DEPENDS ${THRIFT_DEPENDENCIES}
@@ -259,6 +259,7 @@
 message(STATUS "Thrift include dir: ${THRIFT_INCLUDE_DIR}")
 message(STATUS "Thrift static library: ${THRIFT_STATIC_LIB}")
 message(STATUS "Thrift compiler: ${THRIFT_COMPILER}")
+message(STATUS "Thrift version: ${THRIFT_VERSION}")
 add_library(thriftstatic STATIC IMPORTED)
 set_target_properties(thriftstatic PROPERTIES IMPORTED_LOCATION ${THRIFT_STATIC_LIB})
 
@@ -266,6 +267,11 @@
   add_dependencies(thriftstatic thrift_ep)
 endif()
 
+if (PARQUET_THRIFT_USE_BOOST)
+  add_definitions(-DPARQUET_THRIFT_USE_BOOST)
+  message(STATUS "Using Boost in Thrift header")
+endif()
+
 ## GTest
 if(PARQUET_BUILD_TESTS AND NOT IGNORE_OPTIONAL_PACKAGES)
   add_custom_target(unittest ctest -L unittest)
diff --git a/src/parquet/thrift.h b/src/parquet/thrift.h
index d2915a9..ec7ac90 100644
--- a/src/parquet/thrift.h
+++ b/src/parquet/thrift.h
@@ -19,7 +19,13 @@
 #define PARQUET_THRIFT_UTIL_H
 
 #include <cstdint>
+// Check if thrift version < 0.11.0
+// or if FORCE_BOOST_SMART_PTR is defined. Ref: https://thrift.apache.org/lib/cpp
+#if defined(PARQUET_THRIFT_USE_BOOST) || defined(FORCE_BOOST_SMART_PTR)
+#include <boost/shared_ptr.hpp>
+#else
 #include <memory>
+#endif
 
 // TCompactProtocol requires some #defines to work right.
 #define SIGNED_RIGHT_SHIFT_IS 1
@@ -39,6 +45,14 @@
 
 namespace parquet {
 
+// Check if thrift version < 0.11.0
+// or if FORCE_BOOST_SMART_PTR is defined. Ref: https://thrift.apache.org/lib/cpp
+#if defined(PARQUET_THRIFT_USE_BOOST) || defined(FORCE_BOOST_SMART_PTR)
+using ::boost::shared_ptr;
+#else
+using ::std::shared_ptr;
+#endif
+
 // ----------------------------------------------------------------------
 // Convert Thrift enums to / from parquet enums
 
@@ -94,12 +108,12 @@
 template <class T>
 inline void DeserializeThriftMsg(const uint8_t* buf, uint32_t* len, T* deserialized_msg) {
   // Deserialize msg bytes into c++ thrift msg using memory transport.
-  std::shared_ptr<apache::thrift::transport::TMemoryBuffer> tmem_transport(
+  shared_ptr<apache::thrift::transport::TMemoryBuffer> tmem_transport(
       new apache::thrift::transport::TMemoryBuffer(const_cast<uint8_t*>(buf), *len));
   apache::thrift::protocol::TCompactProtocolFactoryT<
       apache::thrift::transport::TMemoryBuffer>
       tproto_factory;
-  std::shared_ptr<apache::thrift::protocol::TProtocol> tproto =
+  shared_ptr<apache::thrift::protocol::TProtocol> tproto =
       tproto_factory.getProtocol(tmem_transport);
   try {
     deserialized_msg->read(tproto.get());
@@ -117,12 +131,12 @@
 // the expected size of the serialized object
 template <class T>
 inline int64_t SerializeThriftMsg(T* obj, uint32_t len, OutputStream* out) {
-  std::shared_ptr<apache::thrift::transport::TMemoryBuffer> mem_buffer(
+  shared_ptr<apache::thrift::transport::TMemoryBuffer> mem_buffer(
       new apache::thrift::transport::TMemoryBuffer(len));
   apache::thrift::protocol::TCompactProtocolFactoryT<
       apache::thrift::transport::TMemoryBuffer>
       tproto_factory;
-  std::shared_ptr<apache::thrift::protocol::TProtocol> tproto =
+  shared_ptr<apache::thrift::protocol::TProtocol> tproto =
       tproto_factory.getProtocol(mem_buffer);
   try {
     mem_buffer->resetBuffer();