- 论坛徽章:
- 7
|
- //
- // Copyright (C) 2004-2008 Maciej Sobczak, Stephen Hutton
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef SOCI_USE_TYPE_H_INCLUDED
- #define SOCI_USE_TYPE_H_INCLUDED
- #include "soci-backend.h"
- #include "type-ptr.h"
- #include "exchange-traits.h"
- #include <string>
- #include <vector>
- namespace soci
- {
- namespace details
- {
- class statement_impl;
- // this is intended to be a base class for all classes that deal with
- // binding input data (and OUT PL/SQL variables)
- class SOCI_DECL use_type_base
- {
- public:
- virtual ~use_type_base() {}
- virtual void bind(statement_impl & st, int & position) = 0;
- virtual void pre_use() = 0;
- virtual void post_use(bool gotData) = 0;
- virtual void clean_up() = 0;
- virtual std::size_t size() const = 0; // returns the number of elements
- };
- typedef type_ptr<use_type_base> use_type_ptr;
- class SOCI_DECL standard_use_type : public use_type_base
- {
- public:
- standard_use_type(void * data, exchange_type type,
- bool readOnly, std::string const & name = std::string())
- : data_(data), type_(type), ind_(NULL),
- readOnly_(readOnly), name_(name), backEnd_(NULL) {}
- standard_use_type(void * data, exchange_type type, indicator & ind,
- bool readOnly, std::string const & name = std::string())
- : data_(data), type_(type), ind_(&ind),
- readOnly_(readOnly), name_(name), backEnd_(NULL) {}
- virtual ~standard_use_type();
- virtual void bind(statement_impl & st, int & position);
- std::string get_name() const {return name_;}
- virtual void * get_data() {return data_;}
- // conversion hook (from arbitrary user type to base type)
- virtual void convert_to_base() {}
- virtual void convert_from_base() {}
- protected:
- virtual void pre_use();
- private:
- virtual void post_use(bool gotData);
- virtual void clean_up();
- virtual std::size_t size() const { return 1; }
- void * data_;
- exchange_type type_;
- indicator * ind_;
- bool readOnly_;
- std::string name_;
- standard_use_type_backend * backEnd_;
- };
- class SOCI_DECL vector_use_type : public use_type_base
- {
- public:
- vector_use_type(void * data, exchange_type type,
- std::string const & name = std::string())
- : data_(data), type_(type), ind_(NULL),
- name_(name), backEnd_(NULL) {}
- vector_use_type(void * data, exchange_type type,
- std::vector<indicator> const & ind,
- std::string const & name = std::string())
- : data_(data), type_(type), ind_(&ind),
- name_(name), backEnd_(NULL) {}
- ~vector_use_type();
- private:
- virtual void bind(statement_impl & st, int & position);
- virtual void pre_use();
- virtual void post_use(bool) { /* nothing to do */ }
- virtual void clean_up();
- virtual std::size_t size() const;
- void * data_;
- exchange_type type_;
- std::vector<indicator> const * ind_;
- std::string name_;
- vector_use_type_backend * backEnd_;
- virtual void convert_to_base() {}
- };
- // implementation for the basic types (those which are supported by the library
- // out of the box without user-provided conversions)
- template <typename T>
- class use_type : public standard_use_type
- {
- public:
- use_type(T & t, std::string const & name = std::string())
- : standard_use_type(&t,
- static_cast<exchange_type>(exchange_traits<T>::x_type),
- false, name) {}
- use_type(T const & t, std::string const & name = std::string())
- : standard_use_type(const_cast<T *>(&t),
- static_cast<exchange_type>(exchange_traits<T>::x_type),
- true, name) {}
- use_type(T & t, indicator & ind,
- std::string const & name = std::string())
- : standard_use_type(&t,
- static_cast<exchange_type>(exchange_traits<T>::x_type),
- ind, false, name) {}
- use_type(T const & t, indicator & ind,
- std::string const & name = std::string())
- : standard_use_type(const_cast<T *>(&t),
- static_cast<exchange_type>(exchange_traits<T>::x_type),
- ind, false, name) {}
- };
- // special cases for char* and char[]
- template <>
- class use_type<char *> : public standard_use_type
- {
- public:
- use_type(char * str, std::size_t bufSize,
- std::string const & name = std::string())
- : standard_use_type(&str_, x_cstring, false, name), str_(str, bufSize) {}
- use_type(char const * str, std::size_t bufSize,
- std::string const & name = std::string())
- : standard_use_type(&str_, x_cstring, true, name),
- str_(const_cast<char *>(str), bufSize) {}
- use_type(char * str, indicator & ind, std::size_t bufSize,
- std::string const & name = std::string())
- : standard_use_type(&str_, x_cstring, ind, false, name), str_(str, bufSize) {}
- use_type(char const * str, indicator & ind, std::size_t bufSize,
- std::string const & name = std::string())
- : standard_use_type(&str_, x_cstring, ind, true, name),
- str_(const_cast<char *>(str), bufSize) {}
- private:
- cstring_descriptor str_;
- };
- template <std::size_t N>
- class use_type<char[N]> : public use_type<char *>
- {
- public:
- use_type(char str[], std::string const & name = std::string())
- : use_type<char *>(str, N, name) {}
- use_type(char const str[], std::string const & name = std::string())
- : use_type<char *>(str, N, name) {}
- use_type(char str[], indicator & ind,
- std::string const & name = std::string())
- : use_type<char *>(str, ind, N, name) {}
- use_type(char const str[], indicator & ind,
- std::string const & name = std::string())
- : use_type<char *>(str, ind, N, name) {}
- };
- template <std::size_t N>
- class use_type<const char[N]> : public use_type<char *>
- {
- public:
- use_type(char str[], std::string const & name = std::string())
- : use_type<char *>(str, N, name) {}
- use_type(char const str[], std::string const & name = std::string())
- : use_type<char *>(str, N, name) {}
- use_type(char str[], indicator & ind,
- std::string const & name = std::string())
- : use_type<char *>(str, ind, N, name) {}
- use_type(char const str[], indicator & ind,
- std::string const & name = std::string())
- : use_type<char *>(str, ind, N, name) {}
- };
- // helper dispatchers for basic types
- template <typename T>
- use_type_ptr do_use(T & t, std::string const & name, basic_type_tag)
- {
- return use_type_ptr(new use_type<T>(t, name));
- }
- template <typename T>
- use_type_ptr do_use(T const & t, std::string const & name, basic_type_tag)
- {
- return use_type_ptr(new use_type<T>(t, name));
- }
- template <typename T>
- details::use_type_ptr use(T & t, std::string const & name = std::string())
- {
- return details::do_use(t, name,
- typename details::exchange_traits<T>::type_family());
- }
- template <typename T>
- details::use_type_ptr use(T const & t, std::string const & name = std::string())
- {
- return details::do_use(t, name,
- typename details::exchange_traits<T>::type_family());
- }
- } // namespace details
- } // namesapce soci
- #endif // SOCI_USE_TYPE_H_INCLUDED
复制代码 相关代码如上,如果我定义变量const char s[] = "Hello,CONST",并且调用use(s)或者use<const char[sizeof(s)]>(s)时,AIX的xlC编译器并不会选择特化的use_type<char[N]>或者use_type<const char[N]>,而是选择了最基本的use_type(即118行的版本),但是exchange_traits<char[N]>并没有声明x_type,造成编译错误(并且也违反了设计的思路)。
但是如果我调用use<char[sizeof(s)]>(s),xlC却会选择use_type<char[N]>特化版本,能够正确编译,生成的代码测试也正常。
请问为什么调用use(s)或者use<const char[sizeof(s)]>(s)时,xlC为什么不选择use_type<const char[N]>呢?如何让他选择use_type<const char[N]>呢?
谢谢!! |
|