diff options
Diffstat (limited to 'gnuradio-core/src/lib/runtime/pmx_helper.hpp')
-rw-r--r-- | gnuradio-core/src/lib/runtime/pmx_helper.hpp | 268 |
1 files changed, 268 insertions, 0 deletions
diff --git a/gnuradio-core/src/lib/runtime/pmx_helper.hpp b/gnuradio-core/src/lib/runtime/pmx_helper.hpp new file mode 100644 index 000000000..44cc2997c --- /dev/null +++ b/gnuradio-core/src/lib/runtime/pmx_helper.hpp @@ -0,0 +1,268 @@ +/* + * Copyright 2012-2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_LIBGRAS_PMX_HELPER_HPP +#define INCLUDED_LIBGRAS_PMX_HELPER_HPP + +#include <PMC/PMC.hpp> +#include <PMC/Containers.hpp> +#include <gruel/pmt.h> +#include <boost/foreach.hpp> + +namespace pmt +{ + +inline pmt_t pmc_to_pmt(const PMCC &p) +{ + //the container is null + if (not p) return pmt::pmt_t(); + + #define decl_pmc_to_pmt(type, conv) if (p.is<type >()) return conv(p.as<type >()) + + //bool + decl_pmc_to_pmt(bool, pmt_from_bool); + + //string + decl_pmc_to_pmt(std::string, pmt_string_to_symbol); + + //numeric types + decl_pmc_to_pmt(int8_t, pmt_from_long); + decl_pmc_to_pmt(int16_t, pmt_from_long); + decl_pmc_to_pmt(int32_t, pmt_from_long); + decl_pmc_to_pmt(uint8_t, pmt_from_long); + decl_pmc_to_pmt(uint16_t, pmt_from_long); + decl_pmc_to_pmt(uint32_t, pmt_from_long); + decl_pmc_to_pmt(int64_t, pmt_from_uint64); + decl_pmc_to_pmt(uint64_t, pmt_from_uint64); + decl_pmc_to_pmt(float, pmt_from_double); + decl_pmc_to_pmt(double, pmt_from_double); + #define pmt_from_complex(x) pmt_make_rectangular((x).real(), (x).imag()) + decl_pmc_to_pmt(std::complex<float>, pmt_from_complex); + decl_pmc_to_pmt(std::complex<double>, pmt_from_complex); + + //pair container + if (p.is<PMCPair>()) + { + const PMCPair &pr = p.as<PMCPair>(); + return pmt_cons(pmc_to_pmt(pr.first), pmc_to_pmt(pr.second)); + } + + //fucking tuples +/* +for i in range(11): + args = list() + for j in range(i): + args.append('pmc_to_pmt(p.as<PMCTuple<%d> >()[%d])'%(i, j)) + print ' if (p.is<PMCTuple<%d> >())'%i + print ' return pmt_make_tuple(%s);'%(', '.join(args),) +*/ + if (p.is<PMCTuple<0> >()) + return pmt_make_tuple(); + if (p.is<PMCTuple<1> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<1> >()[0])); + if (p.is<PMCTuple<2> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<2> >()[0]), pmc_to_pmt(p.as<PMCTuple<2> >()[1])); + if (p.is<PMCTuple<3> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<3> >()[0]), pmc_to_pmt(p.as<PMCTuple<3> >()[1]), pmc_to_pmt(p.as<PMCTuple<3> >()[2])); + if (p.is<PMCTuple<4> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<4> >()[0]), pmc_to_pmt(p.as<PMCTuple<4> >()[1]), pmc_to_pmt(p.as<PMCTuple<4> >()[2]), pmc_to_pmt(p.as<PMCTuple<4> >()[3])); + if (p.is<PMCTuple<5> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<5> >()[0]), pmc_to_pmt(p.as<PMCTuple<5> >()[1]), pmc_to_pmt(p.as<PMCTuple<5> >()[2]), pmc_to_pmt(p.as<PMCTuple<5> >()[3]), pmc_to_pmt(p.as<PMCTuple<5> >()[4])); + if (p.is<PMCTuple<6> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<6> >()[0]), pmc_to_pmt(p.as<PMCTuple<6> >()[1]), pmc_to_pmt(p.as<PMCTuple<6> >()[2]), pmc_to_pmt(p.as<PMCTuple<6> >()[3]), pmc_to_pmt(p.as<PMCTuple<6> >()[4]), pmc_to_pmt(p.as<PMCTuple<6> >()[5])); + if (p.is<PMCTuple<7> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<7> >()[0]), pmc_to_pmt(p.as<PMCTuple<7> >()[1]), pmc_to_pmt(p.as<PMCTuple<7> >()[2]), pmc_to_pmt(p.as<PMCTuple<7> >()[3]), pmc_to_pmt(p.as<PMCTuple<7> >()[4]), pmc_to_pmt(p.as<PMCTuple<7> >()[5]), pmc_to_pmt(p.as<PMCTuple<7> >()[6])); + if (p.is<PMCTuple<8> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<8> >()[0]), pmc_to_pmt(p.as<PMCTuple<8> >()[1]), pmc_to_pmt(p.as<PMCTuple<8> >()[2]), pmc_to_pmt(p.as<PMCTuple<8> >()[3]), pmc_to_pmt(p.as<PMCTuple<8> >()[4]), pmc_to_pmt(p.as<PMCTuple<8> >()[5]), pmc_to_pmt(p.as<PMCTuple<8> >()[6]), pmc_to_pmt(p.as<PMCTuple<8> >()[7])); + if (p.is<PMCTuple<9> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<9> >()[0]), pmc_to_pmt(p.as<PMCTuple<9> >()[1]), pmc_to_pmt(p.as<PMCTuple<9> >()[2]), pmc_to_pmt(p.as<PMCTuple<9> >()[3]), pmc_to_pmt(p.as<PMCTuple<9> >()[4]), pmc_to_pmt(p.as<PMCTuple<9> >()[5]), pmc_to_pmt(p.as<PMCTuple<9> >()[6]), pmc_to_pmt(p.as<PMCTuple<9> >()[7]), pmc_to_pmt(p.as<PMCTuple<9> >()[8])); + if (p.is<PMCTuple<10> >()) + return pmt_make_tuple(pmc_to_pmt(p.as<PMCTuple<10> >()[0]), pmc_to_pmt(p.as<PMCTuple<10> >()[1]), pmc_to_pmt(p.as<PMCTuple<10> >()[2]), pmc_to_pmt(p.as<PMCTuple<10> >()[3]), pmc_to_pmt(p.as<PMCTuple<10> >()[4]), pmc_to_pmt(p.as<PMCTuple<10> >()[5]), pmc_to_pmt(p.as<PMCTuple<10> >()[6]), pmc_to_pmt(p.as<PMCTuple<10> >()[7]), pmc_to_pmt(p.as<PMCTuple<10> >()[8]), pmc_to_pmt(p.as<PMCTuple<10> >()[9])); + + //vector container + if (p.is<PMCList>()) + { + const PMCList &l = p.as<PMCList>(); + pmt_t v = pmt_make_vector(l.size(), pmt_t()); + for (size_t i = 0; i < l.size(); i++) + { + pmt_vector_set(v, i, pmc_to_pmt(l[i])); + } + return v; + } + + //numeric arrays + #define decl_pmc_to_pmt_numeric_array(type, suffix) \ + if (p.is<std::vector<type> >()) return pmt_init_ ## suffix ## vector(p.as<std::vector<type> >().size(), &p.as<std::vector<type> >()[0]) + decl_pmc_to_pmt_numeric_array(uint8_t, u8); + decl_pmc_to_pmt_numeric_array(uint16_t, u16); + decl_pmc_to_pmt_numeric_array(uint32_t, u32); + decl_pmc_to_pmt_numeric_array(uint64_t, u64); + decl_pmc_to_pmt_numeric_array(int8_t, s8); + decl_pmc_to_pmt_numeric_array(int16_t, s16); + decl_pmc_to_pmt_numeric_array(int32_t, s32); + decl_pmc_to_pmt_numeric_array(int64_t, s64); + decl_pmc_to_pmt_numeric_array(float, f32); + decl_pmc_to_pmt_numeric_array(double, f64); + decl_pmc_to_pmt_numeric_array(std::complex<float>, c32); + decl_pmc_to_pmt_numeric_array(std::complex<double>, c64); + + //dictionary container + if (p.is<PMCDict>()) + { + const PMCDict &m = p.as<PMCDict>(); + pmt_t d = pmt_make_dict(); + BOOST_FOREACH(const PMCPair &pr, m) + { + d = pmt_dict_add(d, pmc_to_pmt(pr.first), pmc_to_pmt(pr.second)); + } + return d; + } + + //set container + if (p.is<PMCSet>()) + { + const PMCSet &s = p.as<PMCSet>(); + pmt_t l = PMT_NIL; + BOOST_FOREACH(const PMCC &elem, s) + { + l = pmt_list_add(l, pmc_to_pmt(elem)); + } + return l; + } + + //is it already a pmt? + if (p.is<pmt_t>()) return p.as<pmt_t>(); + + //backup plan... boost::any + return pmt_make_any(p); + +} + +inline PMCC pmt_to_pmc(const pmt_t &p) +{ + //if the container null? + if (not p) return PMC(); + + #define decl_pmt_to_pmc(check, conv) if (check(p)) return PMC_M(conv(p)) + + //bool + decl_pmt_to_pmc(pmt_is_bool, pmt_to_bool); + + //string (do object interning for strings) + decl_pmt_to_pmc(pmt_is_symbol, pmt_symbol_to_string).intern(); + + //numeric types + decl_pmt_to_pmc(pmt_is_integer, pmt_to_long); + decl_pmt_to_pmc(pmt_is_uint64, pmt_to_uint64); + decl_pmt_to_pmc(pmt_is_real, pmt_to_double); + decl_pmt_to_pmc(pmt_is_complex, pmt_to_complex); + + //is it a boost any holding a PMCC? + if (pmt_is_any(p)) + { + const boost::any a = pmt_any_ref(p); + if (a.type() == typeid(PMCC)) return boost::any_cast<PMCC>(a); + } + + //pair container + if (pmt_is_pair(p)) + { + PMCPair pr(pmt_to_pmc(pmt_car(p)), pmt_to_pmc(pmt_cdr(p))); + return PMC_M(pr); + } + + //fucking tuples + #define decl_pmt_to_pmc_tuple(n) \ + if (pmt_is_tuple(p) and pmt_length(p) == n) \ + { \ + PMCTuple<n> t; \ + for (size_t i = 0; i < n; i++) t[i] = pmt_to_pmc(pmt_tuple_ref(p, i)); \ + return PMC_M(t); \ + } + decl_pmt_to_pmc_tuple(0); + decl_pmt_to_pmc_tuple(1); + decl_pmt_to_pmc_tuple(2); + decl_pmt_to_pmc_tuple(3); + decl_pmt_to_pmc_tuple(4); + decl_pmt_to_pmc_tuple(5); + decl_pmt_to_pmc_tuple(6); + decl_pmt_to_pmc_tuple(7); + decl_pmt_to_pmc_tuple(8); + decl_pmt_to_pmc_tuple(9); + decl_pmt_to_pmc_tuple(10); + + //vector container + if (pmt_is_vector(p)) + { + PMCList l(pmt_length(p)); + for (size_t i = 0; i < l.size(); i++) + { + l[i] = pmt_to_pmc(pmt_vector_ref(p, i)); + } + return PMC_M(l); + } + + //numeric arrays + #define decl_pmt_to_pmc_numeric_array(type, suffix) \ + if (pmt_is_ ## suffix ## vector(p)) \ + { \ + size_t n; const type* i = pmt_ ## suffix ## vector_elements(p, n); \ + return PMC_M(std::vector<type>(i, i+n)); \ + } + decl_pmt_to_pmc_numeric_array(uint8_t, u8); + decl_pmt_to_pmc_numeric_array(uint16_t, u16); + decl_pmt_to_pmc_numeric_array(uint32_t, u32); + decl_pmt_to_pmc_numeric_array(uint64_t, u64); + decl_pmt_to_pmc_numeric_array(int8_t, s8); + decl_pmt_to_pmc_numeric_array(int16_t, s16); + decl_pmt_to_pmc_numeric_array(int32_t, s32); + decl_pmt_to_pmc_numeric_array(int64_t, s64); + decl_pmt_to_pmc_numeric_array(float, f32); + decl_pmt_to_pmc_numeric_array(double, f64); + decl_pmt_to_pmc_numeric_array(std::complex<float>, c32); + decl_pmt_to_pmc_numeric_array(std::complex<double>, c64); + + //dictionary container + if (pmt_is_dict(p)) + { + PMCDict m; + pmt_t items = pmt_dict_items(p); + for (size_t i = 0; i < pmt_length(items); i++) + { + pmt_t item = pmt_nth(i, items); + PMCC key = pmt_to_pmc(pmt_car(item)); + PMCC val = pmt_to_pmc(pmt_cdr(item)); + m[key] = val; + } + return PMC_M(m); + } + + //set container + //FIXME no pmt_is_list... + + //backup plan... store the pmt + return PMC_M(p); +} + +} + +#endif /*INCLUDED_LIBGRAS_PMX_HELPER_HPP*/ |