// // Binding.h // // Library: Data // Package: DataCore // Module: Binding // // Definition of the Binding class. // // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. // and Contributors. // // SPDX-License-Identifier: BSL-1.0 // #ifndef Data_Binding_INCLUDED #define Data_Binding_INCLUDED #include "Poco/Data/Data.h" #include "Poco/Data/AbstractBinding.h" #include "Poco/Data/DataException.h" #include "Poco/Data/TypeHandler.h" #include "Poco/SharedPtr.h" #include "Poco/MetaProgramming.h" #include "Poco/Bugcheck.h" #include #include #include #include #include #include namespace Poco { namespace Data { template class Binding: public AbstractBinding /// Binding maps a value or multiple values (see Binding specializations for STL containers as /// well as type handlers) to database column(s). Values to be bound can be either mapped /// directly (by reference) or a copy can be created, depending on the value of the copy argument. /// To pass a reference to a variable, it is recommended to pass it to the intermediate /// utility function use(), which will create the proper binding. In cases when a reference /// is passed to binding, the storage it refers to must be valid at the statement execution time. /// To pass a copy of a variable, constant or string literal, use utility function bind(). /// Variables can be passed as either copies or references (i.e. using either use() or bind()). /// Constants, however, can only be passed as copies. this is best achieved using bind() utility /// function. An attempt to pass a constant by reference shall result in compile-time error. { public: using ValType = T; using ValPtr = SharedPtr; using Type = Binding; using Ptr = SharedPtr; explicit Binding(T& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _bound(false) /// Creates the Binding using the passed reference as bound value. /// If copy is true, a copy of the value referred to is created. { } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return 1u; } bool canBind() const { return !_bound; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); TypeHandler::bind(pos, _val, getBinder(), getDirection()); _bound = true; } void reset () { _bound = false; AbstractBinder::Ptr pBinder = getBinder(); poco_assert_dbg (!pBinder.isNull()); pBinder->reset(); } private: const T& _val; bool _bound; }; template class CopyBinding: public AbstractBinding /// Binding maps a value or multiple values (see Binding specializations for STL containers as /// well as type handlers) to database column(s). Values to be bound can be either mapped /// directly (by reference) or a copy can be created, depending on the value of the copy argument. /// To pass a reference to a variable, it is recommended to pass it to the intermediate /// utility function use(), which will create the proper binding. In cases when a reference /// is passed to binding, the storage it refers to must be valid at the statement execution time. /// To pass a copy of a variable, constant or string literal, use utility function bind(). /// Variables can be passed as either copies or references (i.e. using either use() or bind()). { public: using ValType = T; using ValPtr = SharedPtr; using Type = CopyBinding; using Ptr = SharedPtr; explicit CopyBinding(T& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new T(val)), _bound(false) /// Creates the Binding using the passed reference as bound value. /// If copy is true, a copy of the value referred to is created. { } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return 1; } bool canBind() const { return !_bound; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); TypeHandler::bind(pos, *_pVal, getBinder(), getDirection()); _bound = true; } void reset () { _bound = false; AbstractBinder::Ptr pBinder = getBinder(); poco_assert_dbg (!pBinder.isNull()); pBinder->reset(); } private: //typedef typename TypeWrapper::TYPE ValueType; ValPtr _pVal; bool _bound; }; template <> class Binding: public AbstractBinding /// Binding const char* specialization wraps char pointer into string. { public: using ValType = const char*; using ValPtr = SharedPtr; using Type = Binding; using Ptr = SharedPtr; explicit Binding(const char* pVal, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(pVal ? pVal : throw NullPointerException() ), _bound(false) /// Creates the Binding by copying the passed string. { } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return 1u; } std::size_t numOfRowsHandled() const { return 1u; } bool canBind() const { return !_bound; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); TypeHandler::bind(pos, _val, getBinder(), getDirection()); _bound = true; } void reset () { _bound = false; AbstractBinder::Ptr pBinder = getBinder(); poco_assert_dbg (!pBinder.isNull()); pBinder->reset(); } private: std::string _val; bool _bound; }; template <> class CopyBinding: public AbstractBinding /// Binding const char* specialization wraps char pointer into string. { public: using ValType = const char*; using ValPtr = SharedPtr; using Type = CopyBinding; using Ptr = SharedPtr; explicit CopyBinding(const char* pVal, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(pVal ? pVal : throw NullPointerException() ), _bound(false) /// Creates the Binding by copying the passed string. { } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return 1u; } std::size_t numOfRowsHandled() const { return 1u; } bool canBind() const { return !_bound; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); TypeHandler::bind(pos, _val, getBinder(), getDirection()); _bound = true; } void reset () { _bound = false; AbstractBinder::Ptr pBinder = getBinder(); poco_assert_dbg (!pBinder.isNull()); pBinder->reset(); } private: std::string _val; bool _bound; }; template class Binding>: public AbstractBinding /// Specialization for std::vector. { public: using ValType = std::vector; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::vector& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return static_cast(_val.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::vector. { public: using ValType = std::vector; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(std::vector& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::vector(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; template <> class Binding>: public AbstractBinding /// Specialization for std::vector. /// This specialization is necessary due to the nature of std::vector. /// For details, see the standard library implementation of std::vector /// or /// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001), /// Item 18: "Avoid using vector." /// /// The workaround employed here is using std::deque as an /// internal replacement container. /// /// IMPORTANT: /// Only IN binding is supported. { public: using ValType = std::vector; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = ValType::const_iterator; explicit Binding(const std::vector& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _deq(_val.begin(), _val.end()), _begin(), _end() /// Creates the Binding. { if (PD_IN != direction) throw BindingException("Only IN direction is legal for std:vector binding."); if (numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return 1u; } std::size_t numOfRowsHandled() const { return static_cast(_val.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _deq.begin(); _end = _deq.end(); } private: const std::vector& _val; std::deque _deq; std::deque::const_iterator _begin; std::deque::const_iterator _end; }; template <> class CopyBinding>: public AbstractBinding /// Specialization for std::vector. /// This specialization is necessary due to the nature of std::vector. /// For details, see the standard library implementation of std::vector /// or /// S. Meyers: "Effective STL" (Copyright Addison-Wesley 2001), /// Item 18: "Avoid using vector." /// /// The workaround employed here is using std::deque as an /// internal replacement container. /// /// IMPORTANT: /// Only IN binding is supported. { public: using ValType = std::vector; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = ValType::const_iterator; explicit CopyBinding(const std::vector& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _deq(val.begin(), val.end()), _begin(), _end() /// Creates the Binding. { if (PD_IN != direction) throw BindingException("Only IN direction is legal for std:vector binding."); if (numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return 1u; } std::size_t numOfRowsHandled() const { return static_cast(_deq.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _deq.begin(); _end = _deq.end(); } private: std::deque _deq; std::deque::const_iterator _begin; std::deque::const_iterator _end; }; template class Binding>: public AbstractBinding /// Specialization for std::list. { public: using ValType = std::list; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::list& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _val.size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::list. { public: using ValType = typename std::list; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(ValType& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::list(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; template class Binding>: public AbstractBinding /// Specialization for std::deque. { public: using ValType = std::deque; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::deque& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _val.size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::deque. { public: using ValType = std::deque; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(std::deque& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::deque(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; template class Binding>: public AbstractBinding /// Specialization for std::set. { public: using ValType = std::set; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::set& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return static_cast(_val.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::set. { public: using ValType = std::set; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(std::set& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::set(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; template class Binding>: public AbstractBinding /// Specialization for std::multiset. { public: using ValType = std::multiset; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::multiset& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return static_cast(_val.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::multiset. { public: using ValType = std::multiset; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(std::multiset& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::multiset(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, *_begin, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; template class Binding>: public AbstractBinding /// Specialization for std::map. { public: using ValType = std::map; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::map& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return static_cast(_val.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, _begin->second, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::map. { public: using ValType = std::map; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(std::map& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::map(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, _begin->second, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; template class Binding>: public AbstractBinding /// Specialization for std::multimap. { public: using ValType = std::multimap; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit Binding(std::multimap& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _val(val), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~Binding() /// Destroys the Binding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return static_cast(_val.size()); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, _begin->second, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _val.begin(); _end = _val.end(); } private: const ValType& _val; Iterator _begin; Iterator _end; }; template class CopyBinding>: public AbstractBinding /// Specialization for std::multimap. { public: using ValType = std::multimap; using ValPtr = SharedPtr; using Ptr = SharedPtr>; using Iterator = typename ValType::const_iterator; explicit CopyBinding(std::multimap& val, const std::string& name = "", Direction direction = PD_IN): AbstractBinding(name, direction), _pVal(new std::multimap(val)), _begin(), _end() /// Creates the Binding. { if (PD_IN == direction && numOfRowsHandled() == 0) throw BindingException("It is illegal to bind to an empty data collection"); reset(); } ~CopyBinding() /// Destroys the CopyBinding. { } std::size_t numOfColumnsHandled() const { return TypeHandler::size(); } std::size_t numOfRowsHandled() const { return _pVal->size(); } bool canBind() const { return _begin != _end; } void bind(std::size_t pos) { poco_assert_dbg(!getBinder().isNull()); poco_assert_dbg(canBind()); TypeHandler::bind(pos, _begin->second, getBinder(), getDirection()); ++_begin; } void reset() { _begin = _pVal->begin(); _end = _pVal->end(); } private: ValPtr _pVal; Iterator _begin; Iterator _end; }; namespace Keywords { template inline AbstractBinding::Ptr use(T& t, const std::string& name = "") /// Convenience function for a more compact Binding creation. { // If this fails to compile, a const ref was passed to use(). // This can be resolved by either (a) using bind (which will copy the value), // or (b) if the const ref is guaranteed to exist when execute is called // (which can be much later!), by using the "useRef" keyword instead poco_static_assert (!IsConst::VALUE); return new Binding(t, name, AbstractBinding::PD_IN); } inline AbstractBinding::Ptr use(const NullData& t, const std::string& name = "") /// NullData overload. { return new Binding(const_cast(t), name, AbstractBinding::PD_IN); } template inline AbstractBinding::Ptr useRef(T& t, const std::string& name = "") /// Convenience function for a more compact Binding creation. { return new Binding(t, name, AbstractBinding::PD_IN); } template inline AbstractBinding::Ptr in(T& t, const std::string& name = "") /// Convenience function for a more compact Binding creation. { return use(t, name); } inline AbstractBinding::Ptr in(const NullData& t, const std::string& name = "") /// NullData overload. { return use(t, name); } template inline AbstractBinding::Ptr out(T& t) /// Convenience function for a more compact Binding creation. { poco_static_assert (!IsConst::VALUE); return new Binding(t, "", AbstractBinding::PD_OUT); } template inline AbstractBinding::Ptr io(T& t) /// Convenience function for a more compact Binding creation. { poco_static_assert (!IsConst::VALUE); return new Binding(t, "", AbstractBinding::PD_IN_OUT); } inline AbstractBindingVec& use(AbstractBindingVec& bv) /// Convenience dummy function (for syntax purposes only). { return bv; } inline AbstractBindingVec& in(AbstractBindingVec& bv) /// Convenience dummy function (for syntax purposes only). { return bv; } inline AbstractBindingVec& out(AbstractBindingVec& bv) /// Convenience dummy function (for syntax purposes only). { return bv; } inline AbstractBindingVec& io(AbstractBindingVec& bv) /// Convenience dummy function (for syntax purposes only). { return bv; } template inline AbstractBinding::Ptr bind(T t, const std::string& name) /// Convenience function for a more compact Binding creation. /// This funtion differs from use() in its value copy semantics. { return new CopyBinding(t, name, AbstractBinding::PD_IN); } template inline AbstractBinding::Ptr bind(T t) /// Convenience function for a more compact Binding creation. /// This funtion differs from use() in its value copy semantics. { return Poco::Data::Keywords::bind(t, ""); } } // namespace Keywords } } // namespace Poco::Data #endif // Data_Binding_INCLUDED