Posts Tagged ‘c#’

C++ test for within

Thursday, August 26th, 2010

I found myself having to right a bunch of range checking code like this:

if (val  1.0)
    val = 1.0;

so I wrote this simple function.

#include "algorithm"
template
const Type & within (const Type &lower, const Type &val, const Type &upper)
{
    return std::min (std::max (lower, val), upper);
}

So the above code gets simplified to:

val = within(0.0, val, 1.0);

I wasn’t happy about the extra copy being created but was willing to live with it.

Then I ran across this fragment which is so similar but ended up changing the final design:

if (val == 10)
    val = 5;

The difference is the above check sets an arbitrary value if it wasn’t within the range instead of just assigning one of the bounds to the value. That caused me to split it into a test, within(), to handle this case and a setwithin() to handle the earlier cases.

Splitting it also let me do a minor optimization. The typical case is that being out of bounds is rather exceptional and it’d be nice to avoid doing a copy. Accordingly, setwithin() checks if the dest has the same address as the replacement value and avoids doing the assignment.

template
int within (const Type & lower, const Type & val, const Type & upper)
{
    if (val < lower)
        return -1;
    if (upper < val)
        return 1;
    return 0;
}

template
int setwithin (const Type & lower, const Type & val, const Type & upper, Type & dest)
{
    int res = within (lower, val, upper);
    switch (res)
    {
    case -1:
        if (&lower != &dest)
            dest = lower;
        break;
    case 0:
        if (&val != &dest)
            dest = val;
        break;
    case 1:
        if (&upper != &dest)
            dest = upper;
        break;
    }
    return res;
}

Switching keys in values in a map

Sunday, July 4th, 2010

A functor that reverses a pair: first becomes second, second becomes first. Useful for switching from a map to another map (or multimap in this example) where the value becomes the key and the key the value.

  std::map m;
  std::multimap m2;
  m["a"] = 0;
  m["b"] = 1;
  m["c"] = 0;
  std::transform (m.begin(), m.end(), std::inserter (m2, m2.begin()),
                  pair_switch<std::map::value_type> ());

And the actual code:

template
struct pair_switch : public std::unary_function<
    std::pair,
    std::pair >
{
    typedef std::pair argument_type;
    typedef std::pair argument_type2;
    typedef std::pair argument_type3;
    typedef std::pair result_type;

result_type operator()(const argument_type3 &amp;p) const
{
    return result_type (p.second, p.first);
}

};

Xcode: notes

Sunday, November 29th, 2009

To reset Xcode to the default settings:

$ defaults delete com.apple.Xcode
$ rm -rf ~/Library/Application\ Support/Xcode

First, I dislike having a lot of popup windows so I set the layout to “All-In-One” to keep most things within a single window:

grab-001.png

And my usual indentation style:

grab-003.png

I like having the files autosaved on build:

=grab-007.png

sqlite3 rocks

Friday, August 21st, 2009

I’d been using the sqlite3 that came installed on Mac OS X but I ran into some portability issues — not every system has it installed. So I decided to bite the bullet and include it with my code.

It was trivial! I downloaded a zip with 3 files (sqlite3.c,sqlite3.h, and sqlite3ext.h). Added sqlite3.c to my list of sources and it just compiled! No configuration, no trickly flags, it just worked!

Getting the keys from a std::map

Thursday, May 21st, 2009

So last week I wrote about initializing a std::map from two std::vectors. How about doing the reverse? How do I get a list of the keys or a list of the values into a vector?

So I wrote a functor, based on std::unary_function, that returns the pair.first and another that returns the pair.second:

include

include

/**
 * A functor that returns the first in a pair
 */
template<typename PairType>
struct first: public std::unary_function<PairType, typename PairType::first_type>
{
typedef typename PairType::first_type result_type;
typedef PairType argument_type;

result_type operator()(argument_type &p) const
{
    return p.first;
}

result_type operator()(const argument_type &p) const
{
    return p.first;
}
};

/**
 * A functor that returns the second in a pair
 */
template<typename PairType>
struct second: public std::unary_function<PairType, typename PairType::second_type>
{
typedef typename PairType::second_type result_type;
typedef PairType argument_type;

result_type operator()(argument_type &p) const
{
    return p.second;
}
result_type operator()(const argument_type &p) const
{
    return p.second;
}
};

The first() template functor (from above) is used as the functor that returns the key to the std::transform() alogrithm. Here is a little fragment code that uses first(). (The test code part of a larger CPPUNIT test suite):

void TestUtils::testFirst()
{
    typedef std::map String2StringMap;
    String2StringMap m;

m["a"] = "0";
m["z"] = "1";
m["x"] = "2";

std::vector<std::string>    keys;
std::transform (m.begin(), m.end(),
        std::back_inserter (keys),
        first<String2StringMap::value_type>());
CPPUNIT_ASSERT_EQUAL (m.size(), keys.size());
CPPUNIT_ASSERT_EQUAL (std::string ("x"), keys[1]);

}

Functor for deleting objects

Wednesday, May 20th, 2009

In a destructor for a class, I had a std::vector of pointers that I wanted to delete. I started to write the usual for(;;) loop and realized I do this often enough I should make it easy to use std::for_each().

Here’s the functor (based on std::unary_function):

    #include 

template<typename Type>
struct deleter: public std::unary_function<Type *, bool>
{
bool operator()(Type * ptr) const
{
    delete ptr;
    return true;
}
};

And here’s some sample code using it:

std::vector m_symbols;
// ...
std::for_each (m_symbols.begin(), m_symbols.end(), deleter());

I added a return of true because some other template code wasn’t happy about “return void” — supposedly something fixed in recent compilers.

A better output_iterator

Tuesday, May 19th, 2009

I was using the std::stream_iterator, for example:

    std::vector    vals;
    vals.push_back (12);
    vals.push_back (22);
    vals.push_back (5);
    vals.push_back (30);

// The std::ostream_iterator appends the ","
std::ostringstream  str3;
std::copy (vals.begin(), vals.end(), std::ostream_iterator<int> (str3, ","));
CPPUNIT_ASSERT_EQUAL (std::string ("12,22,5,30,"), str3.str());

It has the “,” after the last item.

So here’s an implementation that doesn’t append the seperator after the last one:

ifndef INCLUDED_OUTITER_H

define INCLUDED_OUTITER_H

include

/** * A replacement for std::ostream_iterator that doesn't put the * seperator after the last item. */ template > class outiter : public std::iterator { public: typedef CharType char_type; typedef Traits traits_type; typedef std::basic_ostream ostream_type;

/// Initialize from a stream
outiter (ostream_type &stream)
: m_stream (&stream),
  m_string (0),
  m_started (false)
{}

/// Copy constructor
outiter (const outiter &copy)
: m_stream (copy.m_stream),
  m_string (copy.m_string),
  m_started (copy.m_started)
{}

/// Initialize from a stream and the seperator 
outiter (ostream_type &stream, const CharType *str)
: m_stream (&stream),
  m_string (str),
  m_started (false)
{}

/// Assignment actually does the output
outiter &
operator=(const Type &value)
{
if (!m_started)
{
    m_started = true;
}
else if (m_string)
{
    (*m_stream) << m_string;
}

(*m_stream) << value;
return *this;
}

/// Just return a reference to this
outiter &
operator*()
{
return *this;
}

/// Just return a reference to this
outiter &
operator++()
{
return *this;
}

/// Just return a reference to this
outiter &
operator++(int)
{
return *this;
}

private: /// The stream to write to ostream_type * m_stream; /// The seperator (may be NULL) const char_type * m_string; /// Flag to indicate if we've output anything bool m_started; };

endif /* INCLUDED_OUTITER_H */

And here’s the corresponding code to use it:

    std::ostringstream  str;
    std::copy (vals.begin(), vals.end(), outiter (str, ","));
    CPPUNIT_ASSERT_EQUAL (std::string ("12,22,5,30"), str.str());

Copying a std::vector into a std::map

Friday, May 8th, 2009

I had two vector’s with the first being the keys and the second being the values. It took a couple tries before I got the STL working for me!

The first thing was to check if the std::map constructors had something useful. It certainly seems like taking two sets of iterators would be a great way to initialize a map. No such luck.

So how about one of the std algorithms to copy the keys and values into the map? std::copy seemed likely but it only takes a single sequence. A little more digging and std::transform. The second version of std::transform takes two sequences, an output iterator, and a binary function to convert the two values from the two sequences into something that can be inserted into the output iterator. Perfect.

So how to turn the two values into a pair suitable for std::map? The std::make_pair is exactly what is needed. The hard part is getting the syntax so you can pass it as a function: make_pair<std::string,int> in this example.

So the code finally looks like:

include

include

include

include

include

include

void test() { std::map m; std::vector keys; std::vector values;

    std::transform (keys.begin(), keys.end(),
                    values.begin(), 
                    std::inserter (m, m.begin()),
                    std::make_pair<std::string,int>);

}