title: CountDownLatch in C++ using Boost Mutexes and Condition
body: <p>I tried to implement CountDownLatch using boost mutexes and condition variable. Below is the code and would like to know if I need to add anything else.</p>
  
  <p>How can I unit test this code as well?</p>
  
  <pre><code>template&lt; class TypeVal &gt;
      class AtomicCounter
      {
      public:
          AtomicCounter( TypeVal val ) : m_typeVal( val ) 
          {
          }
  
          AtomicCounter() : m_typeVal(0)
          {
          }
  
          AtomicCounter(const AtomicCounter&amp; cpy) : m_typeVal(cpy.m_typeVal)
          {   
              boost::mutex::scoped_lock scoped_lock(cpy.m_atomicMutex);
              m_typeVal = cpy.m_typeVal;
          }
  
          const AtomicCounter&amp; operator=(const AtomicCounter&amp; other)
          {
             if (this == &amp;other)
                return *this;
             boost::mutex::scoped_lock lock1(&amp;m_atomicMutex &lt; &amp;other.m_atomicMutex ? m_atomicMutex : other.m_atomicMutex);
             boost::mutex::scoped_lock lock2(&amp;m_atomicMutex &gt; &amp;other.m_atomicMutex ? m_atomicMutex : other.m_atomicMutex);
             m_typeVal = other.m_typeVal;
             return *this;
          }
  
          virtual ~AtomicCounter() 
          {
          }
  
          const TypeVal&amp; getCount() const
          { 
              boost::mutex::scoped_lock lock( m_atomicMutex ); 
              return m_typeVal; 
          }
  
          const TypeVal&amp; setCount( const TypeVal &amp;val ) 
          { 
              boost::mutex::scoped_lock lock( m_atomicMutex ); 
              m_typeVal = val; 
              return m_typeVal; 
          }
  
          const TypeVal&amp; increment() 
          { 
              boost::mutex::scoped_lock lock( m_atomicMutex ); 
              m_typeVal++ ; 
              return m_typeVal; 
          }
  
          const TypeVal&amp; decrement() 
          { 
              boost::mutex::scoped_lock lock( m_atomicMutex ); 
              m_typeVal-- ; 
              return m_typeVal; 
          }
  
          const TypeVal&amp; increment(const TypeVal&amp; t) 
          { 
              boost::mutex::scoped_lock lock( m_atomicMutex ); 
              m_typeVal+=t ; 
              return m_typeVal; 
          }
  
          const TypeVal&amp; decrement(const TypeVal&amp; t) 
          { 
              boost::mutex::scoped_lock lock( m_atomicMutex ); 
              m_typeVal-=t ; 
              return m_typeVal; 
          }
  
  
      private:
          mutable boost::mutex m_atomicMutex;
          TypeVal m_typeVal;
      };
  
             class CountDownLatch
      {
      public:
          CountDownLatch( int count ): m_cdlCount( count ) 
          {
          }
  
          CountDownLatch(const CountDownLatch&amp; cpy)
          {
               boost::unique_lock&lt;boost::mutex&gt;::unique_lock(const_cast&lt;boost::mutex&amp;&gt;(cpy.m_cdlMutex));
              m_cdlCount = cpy.m_cdlCount;
          }
  
          const CountDownLatch&amp; operator=(const CountDownLatch&amp; other)
          {
             if (this == &amp;other)
                return *this;
             boost::mutex::scoped_lock lock1(const_cast&lt;boost::mutex&amp;&gt;(&amp;m_cdlMutex &lt; &amp;other.m_cdlMutex ? m_cdlMutex : other.m_cdlMutex));
             boost::mutex::scoped_lock lock2(const_cast&lt;boost::mutex&amp;&gt;(&amp;m_cdlMutex &gt; &amp;other.m_cdlMutex ? m_cdlMutex : other.m_cdlMutex));
             m_cdlCount = other.m_cdlCount;
             return *this;
          }
  
          virtual ~CountDownLatch() 
          {
          }
          void wait() 
          { 
              boost::mutex::scoped_lock lock( m_cdlMutex ); 
              if( m_cdlCount.getCount() &gt; 0 ) 
              { 
                  m_cdlCondition.wait( lock ); 
              } 
          }
          void wait( uint64_t timeoutMicros ) 
          { 
              boost::mutex::scoped_lock lock( m_cdlMutex ); 
              if( m_cdlCount.getCount() &gt; 0 ) 
              {
                  boost::posix_time::time_duration td = boost::posix_time::milliseconds( timeoutMicros ); 
                  m_cdlCondition.timed_wait( lock, td ); 
              } 
          }
          void countDown() 
          {  
              boost::mutex::scoped_lock lock( m_cdlMutex ); 
              if( m_cdlCount.decrement() == 0 ) 
              { 
                  m_cdlCondition.notify_all(); 
              } 
          }
  
          int getCount()
          {
              return m_cdlCount.getCount();
          }
  
  
      private:
          boost::mutex m_cdlMutex;
          boost::condition_variable m_cdlCondition;
          AtomicCounter&lt; int &gt;  m_cdlCount;           
      };
  </code></pre>