simplified type converting constructor
diff --git a/kll/include/kll_sketch.hpp b/kll/include/kll_sketch.hpp
index d1e11d6..ef6146b 100644
--- a/kll/include/kll_sketch.hpp
+++ b/kll/include/kll_sketch.hpp
@@ -217,13 +217,6 @@
     uint16_t get_k() const;
 
     /**
-     * Returns min_k, which is an internal parameter for error estimation
-     * after merging sketches with different k.
-     * @return parameter min_k
-     */
-    uint16_t get_min_k() const;
-
-    /**
      * Returns the length of the input stream.
      * @return stream length
      */
@@ -236,13 +229,6 @@
     uint32_t get_num_retained() const;
 
     /**
-     * Returns the current capacity in items allocated by the sketch.
-     * For internal use.
-     * @return the capacity
-     */
-    uint32_t get_capacity() const;
-
-    /**
      * Returns true if this sketch is in estimation mode.
      * @return estimation mode flag
      */
@@ -653,6 +639,9 @@
       return true;
     }
 
+    // for type converting constructor
+    template<typename TT, typename CC, typename SS, typename AA>
+    friend class kll_sketch;
 };
 
 template<typename T, typename C, typename S, typename A>
diff --git a/kll/include/kll_sketch_impl.hpp b/kll/include/kll_sketch_impl.hpp
index 703a940..8b620ad 100644
--- a/kll/include/kll_sketch_impl.hpp
+++ b/kll/include/kll_sketch_impl.hpp
@@ -152,46 +152,27 @@
 template<typename TT, typename CC, typename SS, typename AA>
 kll_sketch<T, C, S, A>::kll_sketch(const kll_sketch<TT, CC, SS, AA>& other, const A& allocator):
 allocator_(allocator),
-k_(other.get_k()),
-m_(DEFAULT_M),
-min_k_(other.get_min_k()),
-n_(other.get_n()),
-num_levels_(1),
-levels_(2, 0, allocator),
+k_(other.k_),
+m_(other.m_),
+min_k_(other.min_k_),
+n_(other.n_),
+num_levels_(other.num_levels_),
+levels_(other.levels_, allocator_),
 items_(nullptr),
-items_size_(other.get_capacity()),
+items_size_(other.items_size_),
 min_value_(nullptr),
 max_value_(nullptr),
-is_level_zero_sorted_(false)
+is_level_zero_sorted_(other.is_level_zero_sorted_)
 {
   static_assert(
     std::is_constructible<T, TT>::value,
     "Type converting constructor requires new type to be constructible from existing type"
   );
   items_ = allocator_.allocate(items_size_);
-  levels_[0] = items_size_ - other.get_num_retained();
-  levels_[1] = items_size_;
-
-  if (!other.is_empty()) {
-    min_value_ = new (allocator_.allocate(1)) T(other.get_min_value());
-    max_value_ = new (allocator_.allocate(1)) T(other.get_max_value());
-    size_t index = levels_[0];
-    for (auto pair: other) {
-      new (&items_[index]) T(pair.first);
-      const uint8_t level = count_trailing_zeros_in_u64(pair.second);
-      if (level == num_levels_) {
-        ++num_levels_;
-        levels_.resize(num_levels_ + 1);
-        levels_[level] = index;
-        levels_[num_levels_] = items_size_;
-      } else if (level < num_levels_ - 1 || level > num_levels_) {
-        throw std::invalid_argument("corrupt source sketch");
-      }
-      ++index;
-    }
-  }
+  for (auto i = levels_[0]; i < levels_[num_levels_]; ++i) new (&items_[i]) T(other.items_[i]);
+  if (other.min_value_ != nullptr) min_value_ = new (allocator_.allocate(1)) T(*other.min_value_);
+  if (other.max_value_ != nullptr) max_value_ = new (allocator_.allocate(1)) T(*other.max_value_);
   check_sorting();
-  assert_correct_total_weight();
 }
 
 template<typename T, typename C, typename S, typename A>
@@ -258,11 +239,6 @@
 }
 
 template<typename T, typename C, typename S, typename A>
-uint16_t kll_sketch<T, C, S, A>::get_min_k() const {
-  return min_k_;
-}
-
-template<typename T, typename C, typename S, typename A>
 uint64_t kll_sketch<T, C, S, A>::get_n() const {
   return n_;
 }
@@ -273,11 +249,6 @@
 }
 
 template<typename T, typename C, typename S, typename A>
-uint32_t kll_sketch<T, C, S, A>::get_capacity() const {
-  return items_size_;
-}
-
-template<typename T, typename C, typename S, typename A>
 bool kll_sketch<T, C, S, A>::is_estimation_mode() const {
   return num_levels_ > 1;
 }