00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __OMNI_CALC_HPP_
00018 #define __OMNI_CALC_HPP_
00019
00020 #include <omni/defs.hpp>
00021
00022 #include <stdexcept>
00023 #include <iomanip>
00024 #include <istream>
00025 #include <sstream>
00026 #include <limits>
00027 #include <string>
00028 #include <map>
00029
00030 #include <assert.h>
00031
00032 namespace omni
00033 {
00034
00035 namespace calc
00036 {
00037
00038
00039 template<typename T>
00040 class Calculator;
00041 template<typename T>
00042 class FuncTable;
00043
00044 template<typename T>
00045 class UserFunc;
00046 template<typename T, long>
00047 class Multiplier;
00048 template<typename T, long>
00049 class Divider;
00050
00051
00052
00053 namespace err
00054 {
00055 class Failure;
00056 class SyntaxError;
00057 class UnknownFunctionCall;
00058 class CalculationError;
00059 class DivisionByZero;
00060 class InvalidFunctionName;
00061 }
00062
00063
00064
00065 namespace details
00066 {
00067 template<typename T, typename Ch, typename Tr>
00068 T eval(std::basic_istream<Ch, Tr>&, const Calculator<T>&);
00069 template<typename T, typename Ch, typename Tr, typename Ax>
00070 T eval(const std::basic_string<Ch, Tr, Ax>&, const Calculator<T>&);
00071 template<typename T, typename Ch>
00072 T eval(const Ch*, const Calculator<T>&);
00073 bool check_func_name(const std::wstring &name);
00074 }
00075
00076
00077 }
00078
00079
00080
00081 namespace calc
00082 {
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 template<typename T>
00099 class Calculator {
00100 public:
00101 typedef FuncTable<T> TableType;
00102 typedef T ValueType;
00103
00104
00105
00106
00107
00108 public:
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 template<typename Ch, typename Tr>
00126 ValueType operator()(std::basic_istream<Ch, Tr> &expression) const
00127 {
00128 return details::eval(expression, *this);
00129 }
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 template<typename Ch, typename Tr, typename Ax>
00146 ValueType operator()(const std::basic_string<Ch, Tr, Ax> &expression) const
00147 {
00148 return details::eval(expression, *this);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165 template<typename Ch>
00166 ValueType operator()(const Ch *expression) const
00167 {
00168 return details::eval(expression, *this);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 public:
00178
00179
00180
00181
00182
00183
00184 const TableType& prefix() const
00185 {
00186 return m_prefix;
00187 }
00188
00189
00190
00191
00192
00193
00194
00195 TableType& prefix()
00196 {
00197 return m_prefix;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 const TableType& suffix() const
00207 {
00208 return m_suffix;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217 TableType& suffix()
00218 {
00219 return m_suffix;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228 public:
00229
00230
00231
00232
00233
00234
00235
00236
00237 bool is_integer() const
00238 {
00239 assert(std::numeric_limits<ValueType>::is_specialized);
00240 return std::numeric_limits<ValueType>::is_integer;
00241 }
00242
00243
00244
00245
00246 private:
00247 TableType m_prefix;
00248 TableType m_suffix;
00249 };
00250
00251 }
00252
00253
00254
00255 namespace calc
00256 {
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 template<typename Ch, typename Tr, typename Ax> inline
00273 double evalf(const std::basic_string<Ch, Tr, Ax> &expression)
00274 {
00275 Calculator<double> x;
00276 return x(expression);
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 template<typename Ch> inline
00294 double evalf(const Ch *expression)
00295 {
00296 Calculator<double> x;
00297 return x(expression);
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 template<typename Ch, typename Tr, typename Ax> inline
00315 long evali(const std::basic_string<Ch, Tr, Ax> &expression)
00316 {
00317 Calculator<long> x;
00318 return x(expression);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335 template<typename Ch> inline
00336 long evali(const Ch *expression)
00337 {
00338 Calculator<long> x;
00339 return x(expression);
00340 }
00341
00342
00343 const Calculator<double>& sci();
00344
00345
00346 template<typename Ch, typename Tr, typename Ax> inline
00347 double sci(const std::basic_string<Ch, Tr, Ax> &expression)
00348 {
00349 return sci()(expression);
00350 }
00351
00352
00353 template<typename Ch> inline
00354 double sci(const Ch *expression)
00355 {
00356 return sci()(expression);
00357 }
00358
00359
00360
00361 const Calculator<double>& ratio();
00362
00363 template<typename Ch, typename Tr, typename Ax> inline
00364 double ratio(const std::basic_string<Ch, Tr, Ax> &expression)
00365 {
00366 return ratio()(expression);
00367 }
00368
00369
00370 template<typename Ch> inline
00371 double ratio(const Ch *expression)
00372 {
00373 return ratio()(expression);
00374 }
00375
00376
00377
00378 const Calculator<double>& power();
00379
00380 template<typename Ch, typename Tr, typename Ax> inline
00381 double power(const std::basic_string<Ch, Tr, Ax> &expression)
00382 {
00383 return power()(expression);
00384 }
00385
00386
00387 template<typename Ch> inline
00388 double power(const Ch *expression)
00389 {
00390 return power()(expression);
00391 }
00392
00393
00394
00395 const Calculator<double>& time();
00396
00397 template<typename Ch, typename Tr, typename Ax> inline
00398 double time(const std::basic_string<Ch, Tr, Ax> &expression)
00399 {
00400 return time()(expression);
00401 }
00402
00403
00404 template<typename Ch> inline
00405 double time(const Ch *expression)
00406 {
00407 return time()(expression);
00408 }
00409
00410
00411 const Calculator<double>& freq();
00412
00413 template<typename Ch, typename Tr, typename Ax> inline
00414 double freq(const std::basic_string<Ch, Tr, Ax> &expression)
00415 {
00416 return freq()(expression);
00417 }
00418
00419
00420 template<typename Ch> inline
00421 double freq(const Ch *expression)
00422 {
00423 return freq()(expression);
00424 }
00425
00426
00427
00428 const Calculator<double>& bits();
00429
00430 template<typename Ch, typename Tr, typename Ax> inline
00431 double bits(const std::basic_string<Ch, Tr, Ax> &expression)
00432 {
00433 return bits()(expression);
00434 }
00435
00436
00437 template<typename Ch> inline
00438 double bits(const Ch *expression)
00439 {
00440 return bits()(expression);
00441 }
00442
00443
00444
00445 const Calculator<double>& dist();
00446
00447 template<typename Ch, typename Tr, typename Ax> inline
00448 double dist(const std::basic_string<Ch, Tr, Ax> &expression)
00449 {
00450 return dist()(expression);
00451 }
00452
00453
00454 template<typename Ch> inline
00455 double dist(const Ch *expression)
00456 {
00457 return dist()(expression);
00458 }
00459
00460 }
00461
00462
00463
00464
00465 namespace calc
00466 {
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 template<typename T>
00480 class UserFunc {
00481 public:
00482 typedef T (*Function)(T);
00483 typedef T Argument;
00484 typedef T Result;
00485
00486 friend class FuncTable<T>;
00487
00488 private:
00489
00490
00491
00492 UserFunc()
00493 : m_func(0)
00494 {}
00495
00496 public:
00497
00498
00499
00500
00501
00502
00503
00504
00505 explicit UserFunc(Function f)
00506 : m_func(f)
00507 {}
00508
00509
00510 public:
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 Result operator()(Argument x) const
00521 {
00522 return m_func(x);
00523 }
00524
00525 private:
00526 Function m_func;
00527 };
00528
00529
00530
00531
00532
00533
00534
00535
00536 template<typename T>
00537 class FuncTable {
00538 public:
00539 typedef UserFunc<T> Function;
00540
00541 public:
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 void insert(const std::wstring &name, const Function &f)
00557 {
00558 if (!details::check_func_name(name))
00559 throw err::InvalidFunctionName("invalid function name", name);
00560
00561 if (m_table.find(name) != m_table.end())
00562 throw err::InvalidFunctionName("function already exists", name);
00563
00564 m_table.insert(std::make_pair(name, f));
00565 }
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577 void remove(const std::wstring &name)
00578 {
00579 typename Table::iterator found = m_table.find(name);
00580 if (found == m_table.end())
00581 throw err::InvalidFunctionName("function not exists", name);
00582
00583 m_table.erase(found);
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 bool exists(const std::wstring &name) const
00596 {
00597 return (m_table.find(name) != m_table.end());
00598 }
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 T operator()(const std::wstring &name, T arg) const
00614 {
00615 typename Table::const_iterator found = m_table.find(name);
00616 if (found == m_table.end())
00617 throw err::UnknownFunctionCall(name);
00618
00619 return (*found).second(arg);
00620 }
00621
00622 private:
00623 typedef std::map<std::wstring, Function> Table;
00624 Table m_table;
00625 };
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 template<typename T, long SCALE>
00645 class Multiplier: public UserFunc<T> {
00646 typedef UserFunc<T> inherited;
00647
00648 public:
00649 typedef typename inherited::Argument Argument;
00650 typedef typename inherited::Result Result;
00651
00652 enum { scale = SCALE };
00653
00654 public:
00655
00656
00657
00658 Multiplier()
00659 : inherited(func)
00660 {}
00661
00662 private:
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 static Result func(Argument x)
00673 {
00674 return x * SCALE;
00675 }
00676 };
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 template<typename T, long SCALE>
00696 class Divider: public UserFunc<T> {
00697 typedef UserFunc<T> inherited;
00698
00699 public:
00700 typedef typename inherited::Argument Argument;
00701 typedef typename inherited::Result Result;
00702
00703 enum { scale = SCALE };
00704
00705 public:
00706
00707
00708
00709 Divider()
00710 : inherited(func)
00711 {}
00712
00713 private:
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 static Result func(Argument x)
00724 {
00725 return x / SCALE;
00726 }
00727 };
00728
00729 }
00730
00731
00732
00733
00734 namespace calc
00735 {
00736 namespace err
00737 {
00738
00739
00740
00741
00742
00743
00744 class Failure: public std::runtime_error {
00745 typedef std::runtime_error inherited;
00746
00747 protected:
00748 explicit Failure(const std::string &msg);
00749 explicit Failure(const char *msg);
00750 virtual ~Failure() OMNI_THROW0() {}
00751 };
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763 class SyntaxError: public Failure {
00764 typedef Failure inherited;
00765
00766 public:
00767 explicit SyntaxError(const std::string &msg);
00768 explicit SyntaxError(const char *msg);
00769 virtual ~SyntaxError() OMNI_THROW0() {}
00770 };
00771
00772
00773
00774
00775
00776
00777
00778
00779 class UnknownFunctionCall: public SyntaxError {
00780 typedef SyntaxError inherited;
00781
00782 public:
00783 explicit UnknownFunctionCall(const std::wstring &func_name);
00784 virtual ~UnknownFunctionCall() OMNI_THROW0() {}
00785
00786 public:
00787 const std::wstring& funcName() const;
00788
00789 private:
00790 std::wstring m_func_name;
00791 };
00792
00793
00794
00795
00796
00797
00798
00799 class CalculationError: public Failure {
00800 typedef Failure inherited;
00801
00802 protected:
00803 explicit CalculationError(const std::string &msg);
00804 explicit CalculationError(const char *msg);
00805 virtual ~CalculationError() OMNI_THROW0() {}
00806 };
00807
00808
00809
00810
00811
00812
00813
00814
00815 class DivisionByZero: public CalculationError {
00816 typedef CalculationError inherited;
00817 public:
00818 DivisionByZero();
00819 virtual ~DivisionByZero() OMNI_THROW0() {}
00820 };
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 class InvalidFunctionName: public Failure {
00832 typedef Failure inherited;
00833
00834 public:
00835 explicit InvalidFunctionName(const std::wstring &func_name);
00836 InvalidFunctionName(const std::string &msg, const std::wstring &func_name);
00837 InvalidFunctionName(const char *msg, const std::wstring &func_name);
00838 virtual ~InvalidFunctionName() OMNI_THROW0() {}
00839
00840 public:
00841 const std::wstring& funcName() const;
00842
00843 private:
00844 std::wstring m_func_name;
00845 };
00846
00847 }
00848 }
00849
00850
00851
00852 namespace calc
00853 {
00854
00855 namespace details
00856 {
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883 template<typename Ch>
00884 class CharConst {
00885 public:
00886 typedef Ch Char;
00887
00888 public:
00889 static const Char FLOAT_CHARS[];
00890 static const Char INT_CHARS[];
00891
00892 public:
00893 static const Char OCT_INDICATOR;
00894 static const Char HEX_INDICATOR1;
00895 static const Char HEX_INDICATOR2;
00896
00897 static const Char BRACE_OPEN;
00898 static const Char BRACE_CLOSE;
00899 static const Char OP_ADD;
00900 static const Char OP_SUB;
00901 static const Char OP_MUL;
00902 static const Char OP_DIV;
00903
00904 public:
00905 static bool is_float_digit(Char cx);
00906 static bool is_int_digit(Char cx);
00907 static wchar_t widen(Char cx,
00908 const std::ctype<Char> &fac);
00909 };
00910
00911 }
00912
00913 }
00914
00915
00916
00917 namespace calc
00918 {
00919
00920 namespace details
00921 {
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 template<typename Ch, typename Tr>
00935 std::wstring get_func_name(std::basic_istream<Ch, Tr> &is)
00936 {
00937 typedef std::basic_istream<Ch, Tr> istream_type;
00938 typedef std::basic_string<Ch, Tr> string_type;
00939 typedef istream_type::traits_type traits_type;
00940 typedef CharConst<Ch> calc_traits;
00941 typedef std::ctype<Ch> facet_type;
00942
00943 std::ios::iostate state = std::ios::goodbit;
00944 const istream_type::sentry ok(is);
00945
00946 std::wstring func_name;
00947
00948
00949 if (ok)
00950 {
00951 const facet_type &fac = OMNI_USE_FACET(is.getloc(), facet_type);
00952
00953 for (bool first_char = true;; first_char = false)
00954 {
00955 typename traits_type::int_type meta = is.peek();
00956
00957 if (traits_type::eq_int_type(meta, traits_type::eof()))
00958 {
00959 state |= std::ios::eofbit;
00960 break;
00961 }
00962
00963 typename traits_type::char_type cx = traits_type::to_char_type(meta);
00964 if (first_char)
00965 {
00966 if (!fac.is(facet_type::alpha, cx))
00967 break;
00968
00969 if (calc_traits::is_float_digit(cx)
00970 || calc_traits::is_int_digit(cx))
00971 break;
00972 }
00973
00974 if (!fac.is(facet_type::alnum, cx))
00975 break;
00976
00977 func_name += calc_traits::widen(cx, fac);
00978 is.ignore();
00979 }
00980 }
00981
00982 is.setstate(state);
00983 return func_name;
00984 }
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 template<typename T, typename Ch, typename Tr>
00999 bool get_num(std::basic_istream<Ch, Tr> &is, T &x, bool is_integer)
01000 {
01001 typedef std::basic_istream<Ch, Tr> istream_type;
01002 typedef std::basic_string<Ch, Tr> string_type;
01003 typedef istream_type::traits_type traits_type;
01004 typedef CharConst<Ch> calc_traits;
01005
01006 typename traits_type::int_type meta = is.peek();
01007 if (!traits_type::eq_int_type(meta, traits_type::eof()))
01008 {
01009 typename traits_type::char_type cx = traits_type::to_char_type(meta);
01010
01011 if (is_integer)
01012 {
01013 if (calc_traits::is_int_digit(cx))
01014 {
01015 if (traits_type::eq(cx, calc_traits::OCT_INDICATOR))
01016 {
01017 meta = is.ignore().peek();
01018
01019 if (!traits_type::eq_int_type(meta, traits_type::eof()))
01020 {
01021 cx = traits_type::to_char_type(meta);
01022
01023 if (traits_type::eq(cx, calc_traits::HEX_INDICATOR1)
01024 || traits_type::eq(cx, calc_traits::HEX_INDICATOR2))
01025 {
01026 if (is.ignore() >> std::hex >> x)
01027 return true;
01028 }
01029 else if (calc_traits::is_int_digit(cx))
01030 {
01031 if (is >> std::oct >> x)
01032 return true;
01033 }
01034 else
01035 {
01036 x = T();
01037 return true;
01038 }
01039 }
01040 else
01041 {
01042 is.clear();
01043 is.putback(cx);
01044 }
01045 }
01046
01047
01048 if (is >> std::dec >> x)
01049 return true;
01050 }
01051 }
01052 else
01053 {
01054 if (calc_traits::is_float_digit(cx))
01055 {
01056 if (is >> x)
01057 return true;
01058 }
01059 }
01060 }
01061
01062 return false;
01063 }
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083 template<typename T, typename Ch, typename Tr>
01084 T level_3(std::basic_istream<Ch, Tr> &is, const Calculator<T> &calculator, bool enable_suffix)
01085 {
01086 T x = T();
01087
01088 if (!get_num(is >> std::ws, x, calculator.is_integer()))
01089 {
01090 typedef std::basic_istream<Ch, Tr> istream_type;
01091 typedef istream_type::traits_type traits_type;
01092 typedef CharConst<Ch> calc_traits;
01093
01094 typename traits_type::int_type meta = is.peek();
01095 if (!traits_type::eq_int_type(meta, traits_type::eof()))
01096 {
01097 typename traits_type::char_type cx = traits_type::to_char_type(meta);
01098
01099 if (traits_type::eq(cx, calc_traits::OP_ADD))
01100 x = +level_3(is.ignore(), calculator, false);
01101 else if (traits_type::eq(cx, calc_traits::OP_SUB))
01102 x = -level_3(is.ignore(), calculator, false);
01103 else if (traits_type::eq(cx, calc_traits::BRACE_OPEN))
01104 {
01105 x = level_1(is.ignore(), calculator);
01106
01107
01108 meta = (is >> std::ws).peek();
01109 cx = traits_type::to_char_type(meta);
01110 if (traits_type::eq_int_type(meta, traits_type::eof())
01111 || !traits_type::eq(cx, calc_traits::BRACE_CLOSE))
01112 throw err::SyntaxError("expected \")\" char");
01113 else
01114 is.ignore();
01115 }
01116 else
01117 {
01118 std::wstring func_name = get_func_name(is);
01119 if (!func_name.empty())
01120 {
01121
01122 meta = (is >> std::ws).peek();
01123 cx = traits_type::to_char_type(meta);
01124 if (traits_type::eq_int_type(meta, traits_type::eof())
01125 || !traits_type::eq(cx, calc_traits::BRACE_OPEN))
01126 throw err::SyntaxError("expected \"(\" char");
01127 else
01128 is.ignore();
01129
01130 T z = level_1(is, calculator);
01131
01132
01133 meta = (is >> std::ws).peek();
01134 cx = traits_type::to_char_type(meta);
01135 if (traits_type::eq_int_type(meta, traits_type::eof())
01136 || !traits_type::eq(cx, calc_traits::BRACE_CLOSE))
01137 throw err::SyntaxError("expected \")\" char");
01138 else
01139 is.ignore();
01140
01141 x = calculator.prefix()(func_name, z);
01142 }
01143 else
01144 throw err::SyntaxError("expected value or function call");
01145 }
01146 }
01147 else
01148 throw err::SyntaxError("unexpected end of input stream");
01149 }
01150
01151
01152 if (enable_suffix)
01153 {
01154 std::wstring func_name = get_func_name(is);
01155 if (!func_name.empty())
01156 x = calculator.suffix()(func_name, x);
01157 }
01158
01159 return x;
01160 }
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 template<typename T, typename Ch, typename Tr>
01176 T level_2(std::basic_istream<Ch, Tr> &is, const Calculator<T> &calculator)
01177 {
01178 T x = level_3(is, calculator, true);
01179
01180 while ((is >> std::ws) && !is.eof())
01181 {
01182 typedef std::basic_istream<Ch, Tr> istream_type;
01183 typedef istream_type::traits_type traits_type;
01184 typedef CharConst<Ch> calc_traits;
01185
01186 typename traits_type::int_type meta = is.peek();
01187 typename traits_type::char_type cx = traits_type::to_char_type(meta);
01188 if (traits_type::eq(cx, calc_traits::OP_MUL))
01189 {
01190 x *= level_3(is.ignore(1), calculator, true);
01191 }
01192 else if (traits_type::eq(cx, calc_traits::OP_DIV))
01193 {
01194 T z = level_3(is.ignore(1), calculator, true);
01195 if (calculator.is_integer() && (T() == z))
01196 throw err::DivisionByZero();
01197 x /= z;
01198 }
01199 else
01200 break;
01201 }
01202
01203 return x;
01204 }
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216 template<typename T, typename Ch, typename Tr>
01217 T level_1(std::basic_istream<Ch, Tr> &is, const Calculator<T> &calculator)
01218 {
01219 T x = level_2(is, calculator);
01220
01221 while ((is >> std::ws) && !is.eof())
01222 {
01223 typedef std::basic_istream<Ch, Tr> istream_type;
01224 typedef istream_type::traits_type traits_type;
01225 typedef CharConst<Ch> calc_traits;
01226
01227 typename traits_type::int_type meta = is.peek();
01228 typename traits_type::char_type cx = traits_type::to_char_type(meta);
01229 if (traits_type::eq(cx, calc_traits::OP_ADD))
01230 x += level_2(is.ignore(1), calculator);
01231 else if (traits_type::eq(cx, calc_traits::OP_SUB))
01232 x -= level_2(is.ignore(1), calculator);
01233 else
01234 break;
01235 }
01236
01237 return x;
01238 }
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256 template<typename T, typename Ch, typename Tr>
01257 T eval(std::basic_istream<Ch, Tr> &expression, const Calculator<T> &calculator)
01258 {
01259 return level_1(expression, calculator);
01260 }
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277 template<typename T, typename Ch, typename Tr, typename Ax>
01278 T eval(const std::basic_string<Ch, Tr, Ax> &expression, const Calculator<T> &calculator)
01279 {
01280 std::basic_istringstream<Ch, Tr> is(expression);
01281 T x = eval(is, calculator);
01282
01283 if (!(is >> std::ws).eof())
01284 throw err::SyntaxError("expression not fully parsed");
01285
01286 return x;
01287 }
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303 template<typename T, typename Ch>
01304 T eval(const Ch *expression, const Calculator<T> &calculator)
01305 {
01306 return eval(std::basic_string<Ch>(expression), calculator);
01307 }
01308
01309 }
01310
01311 }
01312
01313
01314 }
01315
01316 #endif // __OMNI_CALC_HPP_