00001
00002 #ifndef mbl_mask_h_
00003 #define mbl_mask_h_
00004
00005
00006
00007
00008
00009 #include <vcl_algorithm.h>
00010 #include <vcl_vector.h>
00011 #include <vcl_stdexcept.h>
00012 #include <vcl_iterator.h>
00013 #include <vcl_string.h>
00014 #include <vcl_iosfwd.h>
00015
00016
00017 class mbl_mask : public vcl_vector<bool>
00018 {
00019 public:
00020 mbl_mask() : vcl_vector<bool>() {}
00021 mbl_mask(unsigned n, bool val = false) : vcl_vector<bool>(n, val) {}
00022 };
00023
00024
00025
00026
00027
00028
00029 void mbl_masks_from_index_set(const vcl_vector<unsigned> & indices,
00030 vcl_vector<mbl_mask> & masks);
00031
00032
00033
00034 void mbl_mask_on_mask(const mbl_mask & A, mbl_mask & B);
00035
00036
00037
00038 template <typename ForwardIterator>
00039 void mbl_mask_merge_values(const mbl_mask & mask,
00040 ForwardIterator first1, ForwardIterator last1,
00041 ForwardIterator first2, ForwardIterator last2,
00042 ForwardIterator result)
00043 {
00044 if (vcl_distance(first1, last1) != (int)mask.size() || vcl_distance(first2, last2) != (int)mask.size())
00045 throw vcl_out_of_range("Values and mask lengths differ");
00046
00047 for (unsigned n = 0 ; first1 != last1 ; ++first1, ++first2, ++n)
00048 *result++ = mask[n] ? *first2 : *first1;
00049 }
00050
00051
00052 void mbl_mask_logic(const mbl_mask & A, mbl_mask & B, const vcl_string & operation);
00053
00054
00055 void mbl_mask_logic_and(const mbl_mask & A, mbl_mask & B);
00056
00057
00058 void mbl_mask_logic_or(const mbl_mask & A, mbl_mask & B);
00059
00060
00061 void mbl_mask_logic_xor(const mbl_mask & A, mbl_mask & B);
00062
00063
00064 void mbl_mask_logic_nor(const mbl_mask & A, mbl_mask & B);
00065
00066
00067 void mbl_mask_logic_xnor(const mbl_mask & A, mbl_mask & B);
00068
00069
00070 void mbl_mask_logic_nand(const mbl_mask & A, mbl_mask & B);
00071
00072
00073 template <typename ForwardIterator, typename OutputIterator>
00074 void mbl_apply_mask(const mbl_mask & mask, ForwardIterator first, ForwardIterator last, OutputIterator target)
00075 {
00076 if (vcl_distance(first, last) != (int)mask.size())
00077 throw vcl_out_of_range("Values and mask lengths differ");
00078
00079 for (unsigned n = 0; first != last ; ++first, ++n)
00080 if (mask[n]) *target++ = *first;
00081 }
00082
00083
00084
00085 template <typename T>
00086 vcl_vector<T> mbl_apply_mask(const mbl_mask & mask, const vcl_vector<T> & values)
00087 {
00088 vcl_vector<T> retval(values);
00089 mbl_apply_mask(mask, retval);
00090 return retval;
00091 }
00092
00093
00094
00095
00096
00097 template <typename T>
00098 void mbl_apply_mask(const mbl_mask & mask, const vcl_vector<T> & src, vcl_vector<T> & dst)
00099 {
00100 const unsigned n_in = src.size();
00101 if (mask.size() != n_in)
00102 throw vcl_out_of_range("src and mask lengths differ");
00103
00104 dst.clear();
00105 dst.reserve(n_in);
00106 for (unsigned i=0; i<n_in; ++i)
00107 {
00108 if (mask[i])
00109 {
00110 dst.push_back(src[i]);
00111 }
00112 }
00113 }
00114
00115
00116
00117
00118
00119
00120 template <typename T>
00121 void mbl_replace_using_mask(const mbl_mask & mask, const vcl_vector<T> & src1, const vcl_vector<T> & src2, vcl_vector<T> & dst)
00122 {
00123 const unsigned n_in = src1.size();
00124 if (mask.size() != n_in)
00125 throw vcl_out_of_range("src1 and mask lengths differ");
00126
00127 unsigned n_true = vcl_count( mask.begin(), mask.end(), true );
00128 if ( n_true != src2.size() )
00129 throw vcl_out_of_range("src2 and mask are not compatible");
00130
00131 vcl_vector<T> dst_tmp;
00132 dst_tmp.clear();
00133 dst_tmp.reserve(n_in);
00134 unsigned j = 0;
00135 for (unsigned i=0; i<n_in; ++i)
00136 {
00137 if (mask[i])
00138 {
00139 dst_tmp.push_back(src2[j]);
00140 ++j;
00141 }
00142 else
00143 dst_tmp.push_back(src1[i]);
00144 }
00145 dst = dst_tmp;
00146 }
00147
00148
00149 template <typename T>
00150 void mbl_apply_mask(const mbl_mask & mask, vcl_vector<T> & values)
00151 {
00152 const unsigned n_in = values.size();
00153 if (mask.size() != n_in)
00154 throw vcl_out_of_range("Values and mask lengths differ");
00155
00156 unsigned n_out = 0;
00157 for (unsigned i = 0 ; i < n_in ; ++i)
00158 {
00159 if (mask[i])
00160 {
00161 values[n_out] = values[i];
00162 ++n_out;
00163 }
00164 }
00165 values.resize(n_out);
00166 }
00167
00168
00169 void mbl_save_mask(const mbl_mask & mask, vcl_ostream & stream);
00170
00171
00172 void mbl_save_mask(const mbl_mask & mask, const char * filename);
00173
00174
00175 void mbl_save_mask(const mbl_mask & mask, const vcl_string &filename);
00176
00177
00178 void mbl_load_mask(mbl_mask & mask, vcl_istream & stream);
00179
00180
00181 void mbl_load_mask(mbl_mask & mask, const char * filename);
00182
00183
00184 void mbl_load_mask(mbl_mask & mask, const vcl_string &filename);
00185
00186
00187
00188
00189 void mbl_mask_to_indices(const mbl_mask& mask, vcl_vector<unsigned>& inds);
00190
00191
00192
00193
00194
00195 void mbl_indices_to_mask(const vcl_vector<unsigned>& inds,
00196 const unsigned n,
00197 mbl_mask& mask);
00198
00199
00200 #endif // mbl_mask_h_