// // Copyright 2012 Josh Blum // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program 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 Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . #ifndef INCLUDED_LIBGRAS_PMX_HELPER_HPP #define INCLUDED_LIBGRAS_PMX_HELPER_HPP #include #include #include #include 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()) return conv(p.as()) //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, pmt_from_complex); decl_pmc_to_pmt(std::complex, pmt_from_complex); //pair container if (p.is()) { const PMCPair &pr = p.as(); 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 >()[%d])'%(i, j)) print ' if (p.is >())'%i print ' return pmt_make_tuple(%s);'%(', '.join(args),) */ if (p.is >()) return pmt_make_tuple(); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3]), pmc_to_pmt(p.as >()[4])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3]), pmc_to_pmt(p.as >()[4]), pmc_to_pmt(p.as >()[5])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3]), pmc_to_pmt(p.as >()[4]), pmc_to_pmt(p.as >()[5]), pmc_to_pmt(p.as >()[6])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3]), pmc_to_pmt(p.as >()[4]), pmc_to_pmt(p.as >()[5]), pmc_to_pmt(p.as >()[6]), pmc_to_pmt(p.as >()[7])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3]), pmc_to_pmt(p.as >()[4]), pmc_to_pmt(p.as >()[5]), pmc_to_pmt(p.as >()[6]), pmc_to_pmt(p.as >()[7]), pmc_to_pmt(p.as >()[8])); if (p.is >()) return pmt_make_tuple(pmc_to_pmt(p.as >()[0]), pmc_to_pmt(p.as >()[1]), pmc_to_pmt(p.as >()[2]), pmc_to_pmt(p.as >()[3]), pmc_to_pmt(p.as >()[4]), pmc_to_pmt(p.as >()[5]), pmc_to_pmt(p.as >()[6]), pmc_to_pmt(p.as >()[7]), pmc_to_pmt(p.as >()[8]), pmc_to_pmt(p.as >()[9])); //vector container if (p.is()) { const PMCList &l = p.as(); 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 >()) return pmt_init_ ## suffix ## vector(p.as >().size(), &p.as >()[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, c32); decl_pmc_to_pmt_numeric_array(std::complex, c64); //dictionary container if (p.is()) { const PMCDict &m = p.as(); 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()) { const PMCSet &s = p.as(); 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()) return p.as(); //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(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 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(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, c32); decl_pmt_to_pmc_numeric_array(std::complex, 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*/