Trim NA values from left and right of Rcpp::NumericVector I receive data with NA values. I would like to trim off the leading and trailing NA values, but to leave the interior NA values in place. 

I've written the below in Rcpp, but it is very much a hand rolled solution -- and i'm alive to the fact that i'm going to make mistakes doing things this way. 

What is the idiomatic cpp / Rcpp (sugar?) way of doing  something like this? 

#include&lt;Rcpp.h&gt;
using namespace Rcpp;

// [[Rcpp::export]]
Rcpp::NumericVector trimNA(Rcpp::NumericVector X) {

    // find first and last non-NA value

    double * F = X.begin();
    double * pBegin = X.begin();
    double * pEnd = X.end();
    double * L = X.end() - 1; // note you must decrement by one as .end() is AFTER

    // look for the values
    while( F &lt; pEnd &amp;&amp; NumericVector::is_na(*F)) F++;
    while( L &gt; pBegin &amp;&amp; NumericVector::is_na(*L)) L--;


    // create trimmed X vector
    Rcpp::NumericVector Xtrim(L - F + 1);

    for( int i = 0; i &lt; Xtrim.size(); i++) {
        Xtrim[i] = *(F + i);
    }

    return Xtrim;
}


/*** R

x &lt;- c(NA, NA, NA, 1:4, NA, 6:8, NA, 10, NA, NA, NA)
trimNA(x)
*/
Code Review

Code is good, except the naming. There are some pieces which could be improved

Use auto for iterators, as exact iterator type is not important, but it's properties are. Iterator properties are usually inherited from container it came from.

Use better constructor, there seems to be one which accepts pair of iterators, and in this case, pair of pointers denoting contiguous range.

Better (?) approach

The problem seems to be somewhat specific case of trimming in general. Note that trimming from the right and trimming from the left are symmetric, and std::reverse_iterator "normalizes" trimming from right (great improvements thanks to @Toby).

template &lt;typename BidirIterator,
          typename Predicate&gt;
auto trim(BidirIterator first, BidirIterator last, Predicate predicate) {
    auto left_edge = std::find_if_not(first, last, predicate);
    auto right_edge = std::find_if_not(std::reverse_iterator(last),
                                       std::reverse_iterator(left_edge),
                                       predicate).base();

    return std::pair{left_edge, right_edge};
}


When reversing a range, first becomes last, and vice versa, that is why std::reverse_iterator arguments were swapped. There is also C++17 feature in play (template class argument deduction).



Full code:

#include &lt;utility&gt;
#include &lt;iterator&gt;
#include &lt;algorithm&gt;

template &lt;typename BidirIterator,
          typename Predicate&gt;
auto trim(BidirIterator first, BidirIterator last, Predicate predicate) {
    auto left_edge = std::find_if_not(first, last, predicate);
    auto right_edge = std::find_if_not(std::reverse_iterator(last),
                                       std::reverse_iterator(left_edge),
                                       predicate).base();

    return std::pair{left_edge, right_edge};
}

#include &lt;vector&gt;
#include &lt;stdexcept&gt;

int main() {
    std::vector&lt;int&gt; initial_values{2, 2, 3, 4, 5, 6};
    auto predicate = [](int x) { return x % 2 == 0; };
    auto [new_first, new_last] = trim(initial_values.begin(),
                                      initial_values.end(),
                                      predicate);
    std::vector&lt;int&gt; resulting_values(new_first, new_last);
    std::vector&lt;int&gt; correct_result{3, 4, 5};
    if (resulting_values != correct_result) {
        throw std::logic_error("incorrect trimming occured");
    }
}


Demo on Wandbox.



To make trimming a little bit easier to use, one might write something like this:

template &lt;typename Container, typename Predicate&gt;
Container trim_copy(Container&amp;&amp; container, Predicate predicate) {
    auto [new_first, new_last] = trim(container.begin(), container.end(),
                                      predicate);
    return Container(new_first, new_last);
}


and pass a lambda calling the NumericVector::is_na:

auto predicate = [](auto x) { return NumericVector::is_na(x); };


or may be pointer to the function directly.