|
libpsynth 0.2.1
|
00001 00014 /* 00015 * Copyright (C) 2010 Juan Pedro Bolivar Puente 00016 * 00017 * This file is part of Psychosynth. 00018 * 00019 * Psychosynth is free software: you can redistribute it and/or modify 00020 * it under the terms of the GNU General Public License as published by 00021 * the Free Software Foundation, either version 3 of the License, or 00022 * (at your option) any later version. 00023 * 00024 * Psychosynth is distributed in the hope that it will be useful, 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00027 * GNU General Public License for more details. 00028 * 00029 * You should have received a copy of the GNU General Public License 00030 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00031 * 00032 */ 00033 00034 #ifndef PSYNTH_BASE_META_H_ 00035 #define PSYNTH_BASE_META_H_ 00036 00037 #include <boost/mpl/find_if.hpp> 00038 #include <boost/mpl/quote.hpp> 00039 #include <boost/mpl/apply.hpp> 00040 #include <boost/mpl/begin_end.hpp> 00041 #include <boost/mpl/not.hpp> 00042 #include <boost/mpl/equal_to.hpp> 00043 #include <boost/mpl/empty_sequence.hpp> 00044 #include <boost/mpl/copy.hpp> 00045 #include <boost/mpl/pair.hpp> 00046 #include <boost/mpl/reverse.hpp> 00047 #include <boost/mpl/transform.hpp> 00048 #include <boost/mpl/front_inserter.hpp> 00049 00050 namespace psynth 00051 { 00052 namespace base 00053 { 00054 00055 namespace mpl = boost::mpl; 00056 00057 template <class Seq, class Default = mpl::list<> > 00058 struct safe_front : 00059 public mpl::eval_if<typename mpl::empty<Seq>::type, 00060 Default, 00061 mpl::front<Seq> > {}; 00062 00063 template <class Seq, class Default = mpl::list<> > 00064 struct safe_pop_front : 00065 public mpl::eval_if<typename mpl::empty<Seq>::type, 00066 Default, 00067 mpl::pop_front<Seq> > {}; 00068 00069 template <class Seq1, class Seq2> 00070 struct concat 00071 { 00072 typedef typename mpl::copy< 00073 typename mpl::reverse<Seq1>::type, 00074 typename mpl::front_inserter<Seq2> >::type type; 00075 }; 00076 00077 template <class Sequence, class Pred> 00078 struct every_p 00079 { 00080 template <class X> 00081 struct not_pred : public mpl::not_<typename mpl::apply<Pred, X>::type> {}; 00082 00083 typedef typename boost::is_same< 00084 typename mpl::find_if<Sequence, mpl::quote1<not_pred> >::type, 00085 typename mpl::end<Sequence>::type>::type type; 00086 }; 00087 00088 template<class Sequence, class Pred> 00089 struct any_p 00090 { 00091 typedef typename mpl::not_< 00092 boost::is_same< 00093 typename mpl::find_if<Sequence, Pred>::type, 00094 typename mpl::end<Sequence>::type> >::type type; 00095 }; 00096 00097 struct join 00098 { 00099 template <class Seq1, class Seq2> 00100 struct apply 00101 { 00102 typedef typename mpl::reverse< 00103 typename boost::mpl::copy< 00104 Seq2, 00105 boost::mpl::front_inserter<Seq1> 00106 >::type >::type type; 00107 }; 00108 }; 00109 00114 template<class Sequence> 00115 struct flatten 00116 { 00117 typedef typename boost::mpl::fold< 00118 Sequence, 00119 typename boost::mpl::clear<Sequence>::type, 00120 join 00121 >::type type; 00122 }; 00123 00124 template <class Element, class Sequence> 00125 struct pair_seq : public mpl::transform< 00126 Sequence, 00127 mpl::lambda<typename mpl::pair<Element, mpl::_1> > 00128 >::type {}; 00129 00130 00131 } /* namespace base */ 00132 } /* namespace psynth */ 00133 00134 #endif /* PSYNTH_BASE_META_H_ */ 00135
1.7.4