From b5745033a7eda45225750820e864bde24af69c05 Mon Sep 17 00:00:00 2001 From: Matej Kenda Date: Wed, 17 Jan 2024 14:13:24 +0100 Subject: [PATCH] gcc/clang (-fvisibility=hidden): corrections to compile and work properly (#4394) * fix(ActiveRecord): missing ActiveRecordLib_API definitions for clang/gcc. * fix(FPEnvironment): export FPEnvironmentImpl classes (#4393, #3331) * fix(Crypto): export *Impl classes used from inlines (#4393, #3331) * fix(Dynamic): explicitly instantiate and export Dynamic::Struct for string and int (-fvisibility=hidden) (#4393, #3331) * fix(JSON): explicitly instantiate and export SharedPtr for JSON::Array and JSON::Object (-fvisibility=hidden) (#4393, #3331) * enh(CMake): Set symbol visibility to hidden (#4393, #3331) * enh(configure): user c++17 standard for iphone, Darwin and ARM-Linux. * fix(UTF): explicitly instantiate and export 16 and 32-bit strings (-fvisibility=hidden) (#4393, #3331) * fix(RecordSet): make Extraction.h internal and instantiate RecordsSet::column template functions only for supported types. (-fvisibility=hidden) (#4393, #3331) * fix(UTF): fix explicitly instantiation on Windows (-fvisibility=hidden) (#4393, #3331) * enh(CMake): Add github jobs for macOS with visibility set to hidden (#4393, #3331) * fix(CppParser): Add missing declarations for CppParser_API (#4393, #3331) * enh(CMake): Enable more options in github jobs for macOS with visibility set to hidden (#4393, #3331) * fix(MongoDB): Add missing MongoDB_API (#4393, #3331) --- .github/workflows/ci.yml | 55 ++++ .../Poco/ActiveRecord/ActiveRecordLib.h | 6 +- CMakeLists.txt | 1 + CppParser/include/Poco/CppParser/CppParser.h | 6 +- Crypto/include/Poco/Crypto/CipherKeyImpl.h | 2 +- Crypto/include/Poco/Crypto/ECKeyImpl.h | 2 +- Crypto/include/Poco/Crypto/KeyPairImpl.h | 2 +- Crypto/include/Poco/Crypto/RSAKeyImpl.h | 2 +- Data/include/Poco/Data/RecordSet.h | 86 +----- Data/src/RecordSet.cpp | 253 ++++++++++++++++++ Foundation/include/Poco/Dynamic/Struct.h | 23 +- Foundation/include/Poco/FPEnvironment_C99.h | 2 +- Foundation/include/Poco/FPEnvironment_DEC.h | 2 +- Foundation/include/Poco/FPEnvironment_QNX.h | 2 +- Foundation/include/Poco/FPEnvironment_SUN.h | 2 +- Foundation/include/Poco/UTFString.h | 14 + Foundation/src/UTF8String.cpp | 13 + Foundation/src/VarHolder.cpp | 20 ++ Foundation/testsuite/src/VarTest.cpp | 2 +- JSON/include/Poco/JSON/Array.h | 15 ++ JSON/include/Poco/JSON/Object.h | 14 + JSON/src/Array.cpp | 9 + JSON/src/Object.cpp | 10 + MongoDB/include/Poco/MongoDB/Document.h | 2 +- MongoDB/include/Poco/MongoDB/UpdateRequest.h | 2 +- build/config/ARM-Linux | 2 +- build/config/Darwin-clang-libc++ | 2 +- build/config/iPhone | 2 +- 28 files changed, 453 insertions(+), 100 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ef4fd9734..15bd1015fc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -220,6 +220,36 @@ jobs: EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF" ./ci/runtests.sh + macos-clang-make-visibility-hidden: + runs-on: macos-12 + steps: + - uses: actions/checkout@v3 + - run: brew install openssl@1.1 mysql-client unixodbc libpq + - run: >- + ./configure --everything --no-prefix --cflags="-fvisibility=hidden" --omit=PDF + --odbc-include=/usr/local/opt/unixodbc/include --odbc-lib=/usr/local/opt/unixodbc/lib + --mysql-include=/usr/local/opt/mysql-client/include --mysql-lib=/usr/local/opt/mysql-client/lib + --include-path="/usr/local/opt/openssl@1.1/include" --library-path="/usr/local/opt/openssl@1.1/lib" && + make all -s -j4 + - uses: ./.github/actions/retry-action + with: + timeout_minutes: 90 + max_attempts: 3 + retry_on: any + command: >- + sudo -s + CPPUNIT_IGNORE=" + CppUnit::TestCaller.testTrySleep, + CppUnit::TestCaller.testTimestamp, + CppUnit::TestCaller.testExpireN, + CppUnit::TestCaller.testAccessExpireN, + CppUnit::TestCaller.testExpireN, + CppUnit::TestCaller.testAccessExpireN, + CppUnit::TestCaller.testOldBSD, + CppUnit::TestCaller.testPollClosedServer" + EXCLUDE_TESTS="Redis Data/MySQL Data/ODBC Data/PostgreSQL MongoDB PDF" + ./ci/runtests.sh + macos-clang-cmake-openssl: runs-on: macos-12 steps: @@ -270,6 +300,31 @@ jobs: PWD=`pwd` ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)" + macos-clang-cmake-openssl3-visibility-hidden: + runs-on: macos-12 + steps: + - uses: actions/checkout@v3 + - run: brew install openssl@3 mysql-client unixodbc libpq + - run: cmake -S. -Bcmake-build -DCMAKE_CXX_VISIBILITY_PRESET=hidden -DENABLE_ENCODINGS_COMPILER=ON -DENABLE_PDF=ON -DENABLE_SEVENZIP=ON -DENABLE_CPPPARSER=ON -DENABLE_TESTS=ON -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl@3 -DMYSQL_ROOT_DIR=/usr/local/opt/mysql-client && cmake --build cmake-build --target all + - uses: ./.github/actions/retry-action + with: + timeout_minutes: 90 + max_attempts: 3 + retry_on: any + command: >- + cd cmake-build && + sudo -s + CPPUNIT_IGNORE=" + CppUnit::TestCaller.testTrySleep, + CppUnit::TestCaller.testTimestamp, + CppUnit::TestCaller.testExpireN, + CppUnit::TestCaller.testAccessExpireN, + CppUnit::TestCaller.testExpireN, + CppUnit::TestCaller.testAccessExpireN, + CppUnit::TestCaller.testPollClosedServer" + PWD=`pwd` + ctest --output-on-failure -E "(DataMySQL)|(DataODBC)|(PostgreSQL)|(MongoDB)|(Redis)" + macos-clang-make-openssl3-tsan: runs-on: macos-12 steps: diff --git a/ActiveRecord/include/Poco/ActiveRecord/ActiveRecordLib.h b/ActiveRecord/include/Poco/ActiveRecord/ActiveRecordLib.h index c737d92417..3c1f861cce 100644 --- a/ActiveRecord/include/Poco/ActiveRecord/ActiveRecordLib.h +++ b/ActiveRecord/include/Poco/ActiveRecord/ActiveRecordLib.h @@ -41,7 +41,11 @@ #if !defined(ActiveRecordLib_API) - #define ActiveRecordLib_API + #if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4) + #define ActiveRecordLib_API __attribute__ ((visibility ("default"))) + #else + #define ActiveRecordLib_API + #endif #endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 460e5ae433..522a099701 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -557,6 +557,7 @@ message(STATUS "[cmake] Build type: ${CMAKE_BUILD_TYPE}") string(TOUPPER "${CMAKE_BUILD_TYPE}" BUILD_TYPE) message(STATUS "[cmake] Build with cxx flags: ${CMAKE_CXX_FLAGS_${BUILD_TYPE}} ${CMAKE_CXX_FLAGS}") message(STATUS "[cmake] Build with c flags: ${CMAKE_C_FLAGS_${BUILD_TYPE}} ${CMAKE_C_FLAGS}") +message(STATUS "[cmake] C++ symbol visibility: ${CMAKE_CXX_VISIBILITY_PRESET}") foreach(component ${Poco_COMPONENTS}) message(STATUS "Building: ${component}") diff --git a/CppParser/include/Poco/CppParser/CppParser.h b/CppParser/include/Poco/CppParser/CppParser.h index ea7125e900..faf9fcf2f3 100644 --- a/CppParser/include/Poco/CppParser/CppParser.h +++ b/CppParser/include/Poco/CppParser/CppParser.h @@ -41,7 +41,11 @@ #if !defined(CppParser_API) - #define CppParser_API + #if !defined(POCO_NO_GCC_API_ATTRIBUTE) && defined (__GNUC__) && (__GNUC__ >= 4) + #define CppParser_API __attribute__ ((visibility ("default"))) + #else + #define CppParser_API + #endif #endif diff --git a/Crypto/include/Poco/Crypto/CipherKeyImpl.h b/Crypto/include/Poco/Crypto/CipherKeyImpl.h index 75b3bdadb2..839745289f 100644 --- a/Crypto/include/Poco/Crypto/CipherKeyImpl.h +++ b/Crypto/include/Poco/Crypto/CipherKeyImpl.h @@ -33,7 +33,7 @@ namespace Poco { namespace Crypto { -class CipherKeyImpl: public RefCountedObject +class Crypto_API CipherKeyImpl: public RefCountedObject /// An implementation of the CipherKey class for OpenSSL's crypto library. { public: diff --git a/Crypto/include/Poco/Crypto/ECKeyImpl.h b/Crypto/include/Poco/Crypto/ECKeyImpl.h index f9c1b1d42f..394cee8581 100644 --- a/Crypto/include/Poco/Crypto/ECKeyImpl.h +++ b/Crypto/include/Poco/Crypto/ECKeyImpl.h @@ -40,7 +40,7 @@ class X509Certificate; class PKCS12Container; -class ECKeyImpl: public KeyPairImpl +class Crypto_API ECKeyImpl: public KeyPairImpl /// Elliptic Curve key clas implementation. { public: diff --git a/Crypto/include/Poco/Crypto/KeyPairImpl.h b/Crypto/include/Poco/Crypto/KeyPairImpl.h index 50718ce374..046c31b8b0 100644 --- a/Crypto/include/Poco/Crypto/KeyPairImpl.h +++ b/Crypto/include/Poco/Crypto/KeyPairImpl.h @@ -31,7 +31,7 @@ namespace Poco { namespace Crypto { -class KeyPairImpl: public Poco::RefCountedObject +class Crypto_API KeyPairImpl: public Poco::RefCountedObject /// Class KeyPairImpl { public: diff --git a/Crypto/include/Poco/Crypto/RSAKeyImpl.h b/Crypto/include/Poco/Crypto/RSAKeyImpl.h index f0397381ce..f325d958a0 100644 --- a/Crypto/include/Poco/Crypto/RSAKeyImpl.h +++ b/Crypto/include/Poco/Crypto/RSAKeyImpl.h @@ -43,7 +43,7 @@ class X509Certificate; class PKCS12Container; -class RSAKeyImpl: public KeyPairImpl +class Crypto_API RSAKeyImpl: public KeyPairImpl /// class RSAKeyImpl { public: diff --git a/Data/include/Poco/Data/RecordSet.h b/Data/include/Poco/Data/RecordSet.h index 9d363d42d5..35b064190d 100644 --- a/Data/include/Poco/Data/RecordSet.h +++ b/Data/include/Poco/Data/RecordSet.h @@ -20,7 +20,6 @@ #include "Poco/Data/Data.h" #include "Poco/Data/Session.h" -#include "Poco/Data/Extraction.h" #include "Poco/Data/BulkExtraction.h" #include "Poco/Data/Statement.h" #include "Poco/Data/RowIterator.h" @@ -166,100 +165,23 @@ class Data_API RecordSet: private Statement /// Returns the number of columns in the recordset. template - const Column& column(const std::string& name) const + const Column& column(const std::string& name) const; /// Returns the reference to the first Column with the specified name. - { - if (isBulkExtraction()) - { - using E = InternalBulkExtraction; - return columnImpl(name); - } - else - { - using E = InternalExtraction; - return columnImpl(name); - } - } template - const Column& column(std::size_t pos) const - /// Returns the reference to column at specified position. - { - if (isBulkExtraction()) - { - using E = InternalBulkExtraction; - return columnImpl(pos); - } - else - { - using E = InternalExtraction; - return columnImpl(pos); - } - } + const Column& column(std::size_t pos) const; Row& row(std::size_t pos); /// Returns reference to row at position pos. /// Rows are lazy-created and cached. template - const T& value(std::size_t col, std::size_t row, bool useFilter = true) const + const T& value(std::size_t col, std::size_t row, bool useFilter = true) const; /// Returns the reference to data value at [col, row] location. - { - if (useFilter && isFiltered() && !isAllowed(row)) - throw InvalidAccessException("Row not allowed"); - - switch (storage()) - { - case STORAGE_VECTOR: - { - using C = typename std::vector; - return column(col).value(row); - } - case STORAGE_LIST: - { - using C = typename std::list; - return column(col).value(row); - } - case STORAGE_DEQUE: - case STORAGE_UNKNOWN: - { - using C = typename std::deque; - return column(col).value(row); - } - default: - throw IllegalStateException("Invalid storage setting."); - } - } template - const T& value(const std::string& name, std::size_t row, bool useFilter = true) const + const T& value(const std::string& name, std::size_t row, bool useFilter = true) const; /// Returns the reference to data value at named column, row location. - { - if (useFilter && isFiltered() && !isAllowed(row)) - throw InvalidAccessException("Row not allowed"); - - switch (storage()) - { - case STORAGE_VECTOR: - { - using C = typename std::vector; - return column(name).value(row); - } - case STORAGE_LIST: - { - using C = typename std::list; - return column(name).value(row); - } - case STORAGE_DEQUE: - case STORAGE_UNKNOWN: - { - using C = typename std::deque; - return column(name).value(row); - } - default: - throw IllegalStateException("Invalid storage setting."); - } - } Poco::Dynamic::Var value(std::size_t col, std::size_t row, bool checkFiltering = true) const; /// Returns the data value at column, row location. diff --git a/Data/src/RecordSet.cpp b/Data/src/RecordSet.cpp index cb0987837b..3fe1293ff6 100644 --- a/Data/src/RecordSet.cpp +++ b/Data/src/RecordSet.cpp @@ -13,6 +13,7 @@ #include "Poco/Data/RecordSet.h" +#include "Poco/Data/Extraction.h" #include "Poco/Data/RowFilter.h" #include "Poco/Data/Date.h" #include "Poco/Data/Time.h" @@ -132,6 +133,258 @@ void RecordSet::reset(const Statement& stmt) } +template +const Column& RecordSet::column(const std::string& name) const + /// Returns the reference to the first Column with the specified name. +{ + if (isBulkExtraction()) + { + using E = InternalBulkExtraction; + return columnImpl(name); + } + else + { + using E = InternalExtraction; + return columnImpl(name); + } +} + + +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; + +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; + +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; +template Data_API const Column>& RecordSet::column>(const std::string& name) const; + + +template +const Column& RecordSet::column(std::size_t pos) const + /// Returns the reference to column at specified position. +{ + if (isBulkExtraction()) + { + using E = InternalBulkExtraction; + return columnImpl(pos); + } + else + { + using E = InternalExtraction; + return columnImpl(pos); + } +} + + +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; + +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; + +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; +template Data_API const Column>& RecordSet::column>(std::size_t pos) const; + + +template +const T& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const + /// Returns the reference to data value at [col, row] location. +{ + if (useFilter && isFiltered() && !isAllowed(row)) + throw InvalidAccessException("Row not allowed"); + + switch (storage()) + { + case STORAGE_VECTOR: + { + using C = typename std::vector; + return column(col).value(row); + } + case STORAGE_LIST: + { + using C = typename std::list; + return column(col).value(row); + } + case STORAGE_DEQUE: + case STORAGE_UNKNOWN: + { + using C = typename std::deque; + return column(col).value(row); + } + default: + throw IllegalStateException("Invalid storage setting."); + } +} + + +template Data_API const bool& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const UInt8& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const Int16& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const UInt16& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const Int32& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const UInt32& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const Int64& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const UInt64& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const float& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const double& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const std::string& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const UTF16String& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const BLOB& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const CLOB& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const Date& RecordSet::value(std::size_t col, std::size_t row, bool useFilter) const; +template Data_API const Time& RecordSet::value