123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- // Copyright (c) 2013-2018 Josh Blum
- // SPDX-License-Identifier: BSL-1.0
- #include <Pothos/Callable/CallableImpl.hpp>
- #include <Pothos/Callable/Exception.hpp>
- #include <Pothos/Object/Exception.hpp>
- #include <Pothos/Util/TypeInfo.hpp>
- #include <Poco/Format.h>
- #include <cassert>
- #include <algorithm> //min/max
- Pothos::Callable::Callable(void)
- {
- assert(not *this);
- }
- Pothos::Object Pothos::Callable::opaqueCall(const Object *inputArgs, const size_t numArgs) const
- {
- if (_impl == nullptr)
- {
- throw Pothos::CallableNullError("Pothos::Callable::call()", "null Callable");
- }
- //Create callArgs which is a combination of inputArgs and boundArgs
- std::vector<Object> callArgs(_impl->getNumArgs());
- size_t inputArgsIndex = 0;
- for (size_t i = 0; i < callArgs.size(); i++)
- {
- //is there a binding? if so use it
- if (_boundArgs.size() > i and _boundArgs[i])
- {
- callArgs[i] = _boundArgs[i];
- }
- //otherwise, use the next available input argument
- else
- {
- if (numArgs <= inputArgsIndex)
- {
- throw Pothos::CallableArgumentError("Pothos::Callable::call()", Poco::format(
- "expected input argument at %z", inputArgsIndex));
- }
- callArgs[i] = inputArgs[inputArgsIndex++];
- }
- //perform conversion on arg to get an Object of the exact type
- try
- {
- callArgs[i] = callArgs[i].convert(_impl->type(int(i)));
- }
- catch(const Pothos::ObjectConvertError &ex)
- {
- throw Pothos::CallableArgumentError("Pothos::Callable::call()", Poco::format(
- "failed to convert arg%z\n%s", i, std::string(ex.displayText())));
- }
- }
- return _impl->call(callArgs.data());
- }
- size_t Pothos::Callable::getNumArgs(void) const
- {
- if (_impl == nullptr)
- {
- throw Pothos::CallableNullError("Pothos::Callable::getNumArgs()", "null Callable");
- }
- size_t numArgs = _impl->getNumArgs();
- //remove bound args from the count
- for (size_t i = 0; i < std::min(_impl->getNumArgs(), _boundArgs.size()); i++)
- {
- if (_boundArgs[i]) numArgs--;
- }
- return numArgs;
- }
- const std::type_info &Pothos::Callable::type(const int argNo) const
- {
- if (_impl == nullptr)
- {
- throw Pothos::CallableNullError("Pothos::Callable::type()", "null Callable");
- }
- if (argNo < -1)
- {
- throw Pothos::CallableArgumentError("Pothos::Callable::type()", Poco::format(
- "unexpected argNo %d", argNo));
- }
- if (argNo >= int(this->getNumArgs()))
- {
- throw Pothos::CallableArgumentError("Pothos::Callable::type()", Poco::format(
- "unexpected argNo %d but call takes %z arguments", argNo, this->getNumArgs()));
- }
- if (argNo == -1) return _impl->type(-1);
- //add bound args into the actual arg number
- int skippedIndexes = 0;
- for (size_t i = 0; i < _boundArgs.size(); i++)
- {
- if (_boundArgs[i]) skippedIndexes++;
- else if (int(i) == argNo + skippedIndexes) break;
- }
- return _impl->type(argNo + skippedIndexes);
- }
- Pothos::Callable &Pothos::Callable::bind(Object &&val, const size_t argNo)
- {
- if (_boundArgs.size() <= argNo) _boundArgs.resize(argNo+1);
- _boundArgs[argNo] = val;
- return *this;
- }
- Pothos::Callable &Pothos::Callable::unbind(const size_t argNo)
- {
- return this->bind(Object(), argNo);
- }
- std::string Pothos::Callable::toString(void) const
- {
- if (_impl == nullptr) return "null";
- std::string output;
- output += Util::typeInfoToString(this->type(-1));
- output += "(";
- for (size_t i = 0; i < this->getNumArgs(); i++)
- {
- if (i != 0) output += ", ";
- output += Util::typeInfoToString(this->type(int(i)));
- }
- output += ")";
- return output;
- }
- Pothos::Detail::CallableContainer::CallableContainer(void)
- {
- return;
- }
- Pothos::Detail::CallableContainer::~CallableContainer(void)
- {
- return;
- }
- Pothos::Callable::operator bool(void) const
- {
- return bool(_impl);
- }
- bool Pothos::operator==(const Callable &lhs, const Callable &rhs)
- {
- return (lhs._impl == rhs._impl) and (lhs._boundArgs == rhs._boundArgs);
- }
- #include <Pothos/Managed.hpp>
- static auto managedCallable = Pothos::ManagedClass()
- .registerConstructor<Pothos::Callable>()
- .registerOpaqueMethod("()", &Pothos::Callable::opaqueCall)
- .commit("Pothos/Callable");
|