summaryrefslogtreecommitdiff
path: root/lib/pmc_to_ptree.cpp
blob: 6565fa6939f273e4d301c941c5d7ecf70bcafd39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Copyright (C) by Josh Blum. See LICENSE.txt for licensing information.

#include "gras_impl/query_common.hpp"
#include "gras_impl/debug.hpp"
#include <PMC/PMC.hpp>
#include <PMC/Containers.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <complex>
#include <sstream>

using namespace boost::property_tree;

PMCC gras::ptree_to_pmc(const ptree &value, const std::type_info &hint)
{
    //if the type is PMCC - educated guess and recursively call
    if (hint == typeid(PMCC) or hint == typeid(PMC))
    {
        //single child
        if (value.size() == 0)
        {
            //can we cast to number?
            try{return ptree_to_pmc(value, typeid(double));}
            catch(...){}

            //can we cast to complex?
            try{return ptree_to_pmc(value, typeid(std::complex<double>));}
            catch(...){}

            //then string
            return ptree_to_pmc(value, typeid(std::string));
        }
        //array
        else
        {
            //TODO more if statements - w/ define
            return ptree_to_pmc(value, typeid(std::vector<double>));
        }
    }

    #define ptree_to_pmc_try(type) \
    if (hint == typeid(type)) return PMC_M(value.get_value<type>());

    //determine number
    ptree_to_pmc_try(char);
    ptree_to_pmc_try(signed char);
    ptree_to_pmc_try(unsigned char);
    ptree_to_pmc_try(signed short);
    ptree_to_pmc_try(unsigned short);
    ptree_to_pmc_try(signed int);
    ptree_to_pmc_try(unsigned int);
    ptree_to_pmc_try(signed long);
    ptree_to_pmc_try(unsigned long);
    ptree_to_pmc_try(signed long long);
    ptree_to_pmc_try(unsigned long long);
    ptree_to_pmc_try(float);
    ptree_to_pmc_try(double);

    //complex number
    std::istringstream ss(value.get_value<std::string>());
    if (hint == typeid(std::complex<double>))
    {
        std::complex<double> c; ss >> c; return PMC_M(c);
    }
    if (hint == typeid(std::complex<float>))
    {
        std::complex<float> c; ss >> c; return PMC_M(c);
    }

    //string
    ptree_to_pmc_try(std::string);

    //determine number vector
    std::vector<long> vec;
    BOOST_FOREACH(const ptree::value_type &elem, value)
    {
        vec.push_back(elem.second.get_value<long>());
    }
    return PMC_M(vec);

    //otherwise null -- will crap out
    return PMC();
}

ptree gras::pmc_to_ptree(const PMCC &value)
{
    ptree v;
    #define pmc_to_ptree_try(type) \
    if (value.is<type>()) {v.put_value(value.as<type>()); return v;}

    //determine number
    pmc_to_ptree_try(char);
    pmc_to_ptree_try(signed char);
    pmc_to_ptree_try(unsigned char);
    pmc_to_ptree_try(signed short);
    pmc_to_ptree_try(unsigned short);
    pmc_to_ptree_try(signed int);
    pmc_to_ptree_try(unsigned int);
    pmc_to_ptree_try(signed long);
    pmc_to_ptree_try(unsigned long);
    pmc_to_ptree_try(signed long long);
    pmc_to_ptree_try(unsigned long long);
    pmc_to_ptree_try(float);
    pmc_to_ptree_try(double);

    //derermine complex
    if (value.is<std::complex<double> >())
    {
        std::ostringstream oss;
        oss << value.as<std::complex<double> >();
        v.put_value(oss.str()); return v;
    }
    if (value.is<std::complex<float> >())
    {
        std::ostringstream oss;
        oss << value.as<std::complex<float> >();
        v.put_value(oss.str()); return v;
    }

    //determine string
    pmc_to_ptree_try(std::string);

    //try numeric vector
    #define pmc_to_ptree_tryv(type) \
    if (value.is<std::vector<type> >()) \
    { \
        BOOST_FOREACH(const type &elem, value.as<std::vector<type> >()) \
        { \
            ptree t; t.put_value(elem); \
            v.push_back(std::make_pair("", t)); \
        } \
    }
    pmc_to_ptree_tryv(char);
    pmc_to_ptree_tryv(signed char);
    pmc_to_ptree_tryv(unsigned char);
    pmc_to_ptree_tryv(signed short);
    pmc_to_ptree_tryv(unsigned short);
    pmc_to_ptree_tryv(signed int);
    pmc_to_ptree_tryv(unsigned int);
    pmc_to_ptree_tryv(signed long);
    pmc_to_ptree_tryv(unsigned long);
    pmc_to_ptree_tryv(signed long long);
    pmc_to_ptree_tryv(unsigned long long);
    pmc_to_ptree_tryv(float);
    pmc_to_ptree_tryv(double);

    return v;
}