| 
					
				 | 
			
			
				@@ -59,6 +59,9 @@ void FillMetadataMap(grpc_metadata_array* arr, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 grpc_metadata* FillMetadataArray( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const std::multimap<grpc::string, grpc::string>& metadata); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Default argument for CallOpSet. I is unused by the class, but can be 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// used for generating multiple names for the same thing. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <int I> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class CallNoOp { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  protected: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void AddOp(grpc_op* ops, size_t* nops) {} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -344,9 +347,16 @@ class CallOpClientRecvStatus { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   size_t status_details_capacity_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// An abstract collection of call ops, used to generate the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// grpc_call_op structure to pass down to the lower layers, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// and as it is-a CompletionQueueTag, also massages the final 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// completion into the correct form for consumption in the C++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// API. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class CallOpSetInterface : public CompletionQueueTag { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CallOpSetInterface() : max_message_size_(0) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// Fills in grpc_op, starting from ops[*nops] and moving 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /// upwards. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   virtual void FillOps(grpc_op* ops, size_t* nops) = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void set_max_message_size(int max_message_size) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -357,36 +367,39 @@ class CallOpSetInterface : public CompletionQueueTag { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   int max_message_size_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-template <class T, int I> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-class WrapAndDerive : public T {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-template <class Op1 = CallNoOp, class Op2 = CallNoOp, class Op3 = CallNoOp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class Op4 = CallNoOp, class Op5 = CallNoOp, class Op6 = CallNoOp> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Primary implementaiton of CallOpSetInterface. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Since we cannot use variadic templates, we declare slots up to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// the maximum count of ops we'll need in a set. We leverage the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// empty base class optimization to slim this class (especially 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// when there are many unused slots used). To avoid duplicate base classes, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// the template parmeter for CallNoOp is varied by argument position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>, class Op3 = CallNoOp<3>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          class Op4 = CallNoOp<4>, class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class CallOpSet : public CallOpSetInterface, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  public WrapAndDerive<Op1, 1>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  public WrapAndDerive<Op2, 2>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  public WrapAndDerive<Op3, 3>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  public WrapAndDerive<Op4, 4>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  public WrapAndDerive<Op5, 5>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  public WrapAndDerive<Op6, 6> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  public Op1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  public Op2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  public Op3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  public Op4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  public Op5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  public Op6 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  public: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   CallOpSet() : return_tag_(this) {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void FillOps(grpc_op* ops, size_t* nops) GRPC_OVERRIDE { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op1, 1>::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op2, 2>::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op3, 3>::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op4, 4>::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op5, 5>::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op6, 6>::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op1::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op2::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op3::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op4::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op5::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op6::AddOp(ops, nops); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op1, 1>::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op2, 2>::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op3, 3>::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op4, 4>::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op5, 5>::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this->WrapAndDerive<Op6, 6>::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op1::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op2::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op3::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op4::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op5::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this->Op6::FinishOp(status, max_message_size_); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     *tag = return_tag_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -397,9 +410,12 @@ class CallOpSet : public CallOpSetInterface, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   void* return_tag_; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// SneakyCallOpBuffer does not post completions to the completion queue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-template <class Op1 = CallNoOp, class Op2 = CallNoOp, class Op3 = CallNoOp, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          class Op4 = CallNoOp, class Op5 = CallNoOp, class Op6 = CallNoOp> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// A CallOpSet that does not post completions to the completion queue. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Allows hiding some completions that the C core must generate from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// C++ users. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+template <class Op1 = CallNoOp<1>, class Op2 = CallNoOp<2>, class Op3 = CallNoOp<3>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          class Op4 = CallNoOp<4>, class Op5 = CallNoOp<5>, class Op6 = CallNoOp<6>> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class SneakyCallOpSet GRPC_FINAL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     : public CallOpSet<Op1, Op2, Op3, Op4, Op5, Op6> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  public: 
			 |